#!   /usr/bin/env   python
#    coding: utf8
##_________________________________________________________________________________________________
##                                                                                                |
##                                           |TDC PTS|                                            |
##                                                                                                |
##                                         CERN,BE/CO-HT                                          |
##________________________________________________________________________________________________|

##-------------------------------------------------------------------------------------------------
##                                                                                                |
##                                       TDC Presence test                                        |
##                                                                                                |
##-------------------------------------------------------------------------------------------------
##                                                                                                |
## Description  Testing of the presence of the TDC board on the SPEC carrier.                     |
##                                                                                                |
##              The test retrieves information on the carrier board: pcb version, carrier type,   |
##              status, control, mezzzanine presence.                                             |
##              Note that the mezzanine presence flag comes from the FMC pin prsnt_m2c_n_i.       |
##                                                                                                |
##              The WISHBONE master can be accessed at PCIe base address xC0000.                  |
##                                                                                                |
##                                                                                                |
## FW to load   .bin                                                                              |
## Authors      Evangelia Gousiou (Evangelia.Gousiou@cern.ch)                                     |
## Website      http://www.ohwr.org/projects/pts                                                  |
## Date         11/01/2013                                                                        |
##-------------------------------------------------------------------------------------------------

##-------------------------------------------------------------------------------------------------
##                               GNU LESSER GENERAL PUBLIC LICENSE                                |
##                              ------------------------------------                              |
## This source file is free software; you can redistribute it and/or modify it under the terms of |
## the GNU Lesser General Public License as published by the Free Software Foundation; either     |
## version 2.1 of the License, or (at your option) any later version.                             |
## This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;       |
## without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.      |
## See the GNU Lesser General Public License for more details.                                    |
## You should have received a copy of the GNU Lesser General Public License along with this       |
## source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html                     |
##-------------------------------------------------------------------------------------------------

##-------------------------------------------------------------------------------------------------
##                                            Import                                             --
##-------------------------------------------------------------------------------------------------


# Import system modules
import sys
import time
import os

# Add common modules location tp path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')

# Import common modules
from ptsexcept import *
import rr
import csr

# Import specific modules
import fmc_tdc


def main (default_directory='.'):

    # Constants declaration
    FMC_TDC_ADDR            = '1a39:0004/1a39:0004@0001:0000'#'1a39:0004/1a39:0004@000B:0000'
    FMC_TDC_BITSTREAM_PATH  = '../firmwares/tdc_pts_presence.bit'#top_tdc.bit'
    FPGA_LOADER_PATH        = '../../../gnurabbit/user/fpga_loader'

    # Addressing for the retrieval of carrier csr information
    CARRIER_CSR          = 0x00000 # base address
    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)
   
    # SPEC object declaration
    spec = rr.Gennum()

    # Bind SPEC object to FMC TDC card
    print "\n-------------------------------------------------------------------"
    print "---------------------------- FMC TDC ---------------------------- "
    print "-------------------- Mezzanine presence test --------------------\n"
    print ("Test of the presence of the mezzanine, on the SPEC carrier.\n") 

    print "\n_______________________________Info______________________________\n"
    print "FMC TDC address to parse: %s"%(FMC_TDC_ADDR)
    for name, value in spec.parse_addr(FMC_TDC_ADDR).iteritems():
        print "%s:0x%04X"%(name, value)
    spec.bind(FMC_TDC_ADDR)
    carrier_csr = csr.CCSR(spec, CARRIER_CSR)
    tdc         = fmc_tdc.CFMCTDC(spec)

    print "\n_________________________Initialisations_________________________\n"
    # Load FMC TDC firmware
    print "Loading FMC TDC firmware...",
    firmware_loader = os.path.join(default_directory, FPGA_LOADER_PATH)
    bitstream = os.path.join(default_directory, FMC_TDC_BITSTREAM_PATH)
    os.system(firmware_loader + ' ' + bitstream )
    time.sleep(1)
    os.system(firmware_loader + ' ' + bitstream )
    time.sleep(1)
    print "Firmware loaded!"

    # Check bitsteam type
    bitstream_type = carrier_csr.rd_reg(CSR_BSTM_TYPE)
    print('Bitstream type     :%.8X') % bitstream_type
    if(bitstream_type == 0xFFFFFFFF):
        msg = ("FATAL ERROR: Wrong bitstream type loaded")
        os.close(spec.fd)
        print (msg)
        raise PtsCritical (msg)
    if(bitstream_type != 0x1):
        msg = ("FATAL ERROR: Wrong bitstream type loaded")
        os.close(spec.fd)
        print (msg)
        raise PtsCritical (msg) 


    # Carrier Information
    print "\n___________________________Carrier info__________________________\n"
    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
    print "\n__________________________Presence test__________________________\n"
    status = carrier_csr.rd_reg(CSR_STATUS)
    if(status & STATUS_FMC_PRES):
        print('Carrier csr status :%.8X') % status
        msg = ("ERROR: Mezzanine appears missing.")
        os.close(spec.fd)
        print (msg)
        raise PtsCritical (msg)

    else:
        print("Mezzanine present OK\n")

    os.close(spec.fd)
    print "\n\n-----------------------------------------------------------------"

if __name__ == '__main__' :
    main()
