#!   /usr/bin/env   python
#    coding: utf8

# Copyright CERN, 2011
# Author: Matthieu Cattin <matthieu.cattin@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org

import sys
import time
import os

sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')

from ptsexcept import *

import rr
import csr


"""
rr_loader_lib test
"""

CARRIER_CSR = 0x30000

CSR_TYPE_VER = 0x00
CSR_BSTM_TYPE = 0x04
CSR_BSTM_DATE = 0x08
CSR_STATUS = 0x0C
CSR_CTRL = 0x10

PCB_VER_MASK = 0x000F
CARRIER_TYPE_MASK = 0xFFFF0000

STATUS_FMC_PRES = (1<<0)
STATUS_P2L_PLL_LCK = (1<<1)
STATUS_SYS_PLL_LCK = (1<<2)
STATUS_DDR3_CAL_DONE = (1<<3)

CTRL_LED_GREEN = (1<<0)
CTRL_LED_RED = (1<<1)
CTRL_DAC_CLR_N = (1<<2)

def main (default_directory='.'):

    # Old way of loading the firmware
    """
    path_fpga_loader = '../../../gnurabbit/user/fpga_loader';
    path_firmware = '../firmwares/spec_fmcadc100m14b4cha.bin';

    firmware_loader = os.path.join(default_directory, path_fpga_loader)
    bitstream = os.path.join(default_directory, path_firmware)
    print firmware_loader + ' ' + bitstream
    os.system( firmware_loader + ' ' + bitstream )

    time.sleep(2);
    """

    fmc_adc_addr = '1a39:0004/1a39:0004@000b:0000'
    fmc_adc_firmware = '../firmwares/spec_fmcadc100m14b4cha.bin'

    # SPEC object declaration
    spec = rr.Gennum()

    # Binds SPEC object to board
    print "Binding spec object to board"
    for name, value in spec.parse_addr(fmc_adc_addr).iteritems():
        print "%10s: 0x%04X"%(name, value)
    spec.bind(fmc_adc_addr)

    # Loads firmware
    print "Loading firmware"
    spec.load_firmware(fmc_adc_firmware)
    time.sleep(2);

    # Others objects declaration
    carrier_csr = csr.CCSR(spec, CARRIER_CSR)

    # Check bitsteam type
    bitstream_type = carrier_csr.rd_reg(CSR_BSTM_TYPE)
    print('bitstream type:%.8X') % bitstream_type
    if(bitstream_type == 0xFFFFFFFF):
        raise PtsCritical ("Firmware not properly loaded.")
    if(bitstream_type != 0x1):
        raise PtsCritical ("Wrong bitstream type.")

    # Dump carrier CSR to log
    print("PCB version    : %d") % (PCB_VER_MASK & carrier_csr.rd_reg(CSR_TYPE_VER))
    print("Carrier type   : %d") % ((CARRIER_TYPE_MASK & carrier_csr.rd_reg(CSR_TYPE_VER))>>16)
    print("Bitstream type : 0x%.8X") % (carrier_csr.rd_reg(CSR_BSTM_TYPE))
    print("Bitstream date : 0x%.8X") % (carrier_csr.rd_reg(CSR_BSTM_DATE))
    print("Status         : 0x%.8X") % (carrier_csr.rd_reg(CSR_STATUS))
    print("Control        : 0x%.8X") % (carrier_csr.rd_reg(CSR_CTRL))

    # Check mezzanine presence flag
    status = carrier_csr.rd_reg(CSR_STATUS)
    print('carrier csr:%.8X') % status
    if(status & STATUS_FMC_PRES):
        raise PtsCritical ("Mezzanine not present or PRSNT_M2C_L faulty.")


if __name__ == '__main__' :
    main()
