#!   /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
# Last modifications: 23/5/2012

# Import system modules
import sys
import time
import os

# Add common modules and libraries location to path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')

# Import common modules
from ptsexcept import *
import rr

# Import specific modules
from fmc_adc_spec import *
from fmc_adc import *


"""
test02: Test EEPROM access

Note: Requires test00.py to run first to load the firmware!
"""

def pattern_compare(fmc, pattern):
    print "Write data pattern to EEPROM\n"
    #print [hex(a) for a in pattern]
    fmc.sys_i2c_eeprom_write(pattern)
    print "Read back data from EEPROM\n"
    rd_pattern = fmc.sys_i2c_eeprom_read(0x0, len(pattern))
    #print [hex(a) for a in rd_pattern]
    print "Data comparison:"
    print "written read => result"
    mismatch = 0
    for i in range(len(pattern)):
        if(rd_pattern[i] != pattern[i]):
            check = "MISMATCH"
            mismatch += 1
        else:
            check = "OK"
        print "0x%02X 0x%02X => %s" % (pattern[i], rd_pattern[i], check)
    print ""
    return mismatch

def main (default_directory='.'):

    # Constants declaration
    TEST_NB = 2
    EXPECTED_BITSTREAM_TYPE = 0x1
    EEPROM_ADDR = 0x50
    PATTERN_A = [0x55, 0xAA, 0x00, 0xFF]
    PATTERN_B = [0xAA, 0x55, 0xFF, 0x00]


    start_test_time = time.time()
    print "================================================================================"
    print "Test%02d start\n" % TEST_NB

    # SPEC object declaration
    print "Loading hardware access library and opening device.\n"
    spec = rr.Gennum()

    # Carrier object declaration (SPEC board specific part)
    # Used to check that the firmware is loaded.
    try:
        carrier = CFmcAdc100mSpec(spec, EXPECTED_BITSTREAM_TYPE)
    except FmcAdc100mSpecOperationError as e:
        raise PtsCritical("Carrier init failed, test stopped: %s" % e)

    # Mezzanine object declaration (FmcAdc100m14b4cha board specific part)
    try:
        fmc = CFmcAdc100m(spec)
    except FmcAdc100mOperationError as e:
        raise PtsCritical("Mezzanine init failed, test stopped: %s" % e)

    # Scan FMC system i2c bus
    periph_addr = fmc.sys_i2c_scan()
    print ""

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

    # Write, read back and compare two different patterns
    try:
        mismatch = 0
        mismatch += pattern_compare(fmc, PATTERN_A)
        mismatch += pattern_compare(fmc, PATTERN_B)
    except FmcAdc100mOperationError as e:
        raise PtsError("EEPROM write/read/compare test failed:  %s" % e)

    if(mismatch != 0):
        raise PtsError("EEPROM data comparison mismatch!")
    else:
        print('Data comparison OK.')


    print ""
    print "==> End of test%02d" % TEST_NB
    print "================================================================================"
    end_test_time = time.time()
    print "Test%02d elapsed time: %.2f seconds\n" % (TEST_NB, end_test_time-start_test_time)


if __name__ == '__main__' :
    main()
