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

##-------------------------------------------------------------------------------------------------
##                                                                                                |
##                                        TDC EEPROM test                                         |
##                                                                                                |
##-------------------------------------------------------------------------------------------------
##                                                                                                |
## Description  Testing of the "EEPROM 24AA64" chip on the TDC board (IC5). The firmware loaded   |
##              to the FPGA on the carrier implements the interface for the communication between |
##              the PCIe bus and the I2C of the EEPROM; this interface is an I2C WISHBONE master, |
##              running with a system clock of 50MHz.                                             |
##                                                                                                |
##              The I2C WISHBONE master can be accessed at base address 0x60000.                  |
##              The I2C address of the EEPROM is x50, predefined in the part number.              |
##                                                                                                |
##              The test attempts several writings and readbacks on different EEPROM locations.   |
##                                                                                                |
## 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
from binascii import unhexlify
import array

# 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 specific modules
import fmc_tdc

##-------------------------------------------------------------------------------------------------
##                                             main                                              --
##-------------------------------------------------------------------------------------------------

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_allothertests.bit'#tdc_counters.bit'
    FPGA_LOADER_PATH        = '../../../gnurabbit/user/fpga_loader'
    EEPROM_ADDR             = 0x50
    
    # SPEC object declaration
    spec = rr.Gennum()

    # Bind SPEC object to FMC TDC card
    print "\n-------------------------------------------------------------------"
    print "----------------------------- TDC PTS -----------------------------"
    print "------------------------- EEPROM IC5 test -------------------------\n"
    print ("Testing of the the EEPROM IC5. The test checks the communication\n"
           "with the EEPROM, writes data to it and then reads them back.\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)

    # Load FMC TDC firmware
    print "\n_________________________Initialisations_________________________\n"
    print "Loading FMC Fine Delay 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)
    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)
    print "Firmware loaded!"

    # TDC object declaration
    tdc = fmc_tdc.CFMCTDC(spec)

    # Check bitsteam type
    bitstream_type = tdc.read_bitstream_type()
    if(bitstream_type == 0xFFFFFFFF):
        msg = ("FATAL ERROR: No access to TDC core")
        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)
    else:
        print('Access to TDC core OK')

    print "\n__________________________EEPROM IC10 test_______________________\n"
    # Scan FMC I2C bus
    try:
        periph_addr = tdc.mezz_i2c_scan()
    except:
        msg = ("ERROR: EEPROM IC5: No peripheral detected")
        os.close(spec.fd)
        print (msg)
        raise PtsError (msg)

    # Check that the EEPROM is detected on the I2C bus
    if(0 == len(periph_addr)):
        msg = ("ERROR: EEPROM IC5: No peripheral detected on system management I2C bus")
        os.close(spec.fd)
        print (msg)
        raise PtsError (msg)
    else:
        if(1 != len(periph_addr)):
            msg = ("ERROR: EEPROM IC5: Signal integrity problem detected on system management I2C bus, %d devices detected instead of 1"%(len(periph_addr)))
            os.close(spec.fd)
            print (msg)
            raise PtsError (msg)
        else:
            if(EEPROM_ADDR != periph_addr[0]):
                msg = ("ERROR: EEPROM IC5: Wrong device mounted on system management I2C bus, address is:0x%.2X expected:0x%.2X"%(periph_addr[0],EEPROM_ADDR))

                os.close(spec.fd)
                print (msg)
                raise PtsError (msg)

    # Write, read back and compare
    addr    = 0x00

    wr_data2 = [0x55, 0xAA, 0x00, 0xFF]
    byte_to_write = (wr_data2[0])
    print byte_to_write
    print("0x%08X") %byte_to_write
    print wr_data2



    wr_data_float = [-15324.48, 43631.41, 34323.48, 26359.30]

    wr_data_int =   []
    for k in range(0,len(wr_data_float),1):
        print ("ch%d float: %20.2f fs")%(k+2, wr_data_float[k])
        wr_data_int.append(int(wr_data_float[k]))
        print ("ch%d int: %20d fs")%(k+2, wr_data_int[k])

    print wr_data_int

    wr_data_hex =   []
    for k in range(0,len(wr_data_int),1):
        hex_value = (wr_data_int[k] & 0xffffffff)#hex (wr_data_int[k] & 0xffffffff)[:-1]#
        wr_data_hex.append(hex_value)

    print wr_data_hex
    byte_to_write = (wr_data_hex[0])
    print byte_to_write
    print("0x%08X") %byte_to_write


    if byte_to_write == 0xFFFFc424:
        print("OK!!")
    else:
        print("notOK!")

    byte_to_write_hex = hex(byte_to_write)
    print byte_to_write_hex

    wr_data = []

    bytes = array.array('B', byte_to_write_hex.decode("hex"))
    for i in range(0,len(bytes),1):
        print result[i]
        wr_data.append(bytes[i])

    print wr_data


    #wr_data = [0x55, 0xAA, 0x00, 0xFF]
    #wr_data = [0xffffc424, 0xAA, 0x00, 0xFF]
    #wr_data = [0xFF, 0xFF, 0xC4, 0x24]#ffffc424]#, 0xaa6f]#, 0x8613, 0x66f7]

    rd_data = []

    print('EEPROM IC5: Writting data at EEPROM address 0x%.2X: ')%addr,
    print wr_data
    tdc.mezz_i2c_eeprom_write(addr, wr_data)

    time.sleep(0.1)

    tdc.mezz_i2c_eeprom_write(addr, wr_data)

    time.sleep(0.1)
    print('EEPROM IC5: Reading data from EEPROM address 0x%.2X:')%addr,
    rd_data = tdc.mezz_i2c_eeprom_read(0x01, 4)#len(wr_data))
    print rd_data
    if(rd_data != wr_data):
        msg = ("ERROR: EEPROM IC5: Data reading/ writing failed")
        os.close(spec.fd)
        print (msg)
        raise PtsError (msg)
    else:
        print('\nEEPROM IC5: Data comparison OK')

    os.close(spec.fd)

    print "\n\n-----------------------------------------------------------------"


if __name__ == '__main__' :
    main()
