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

# Copyright CERN, 2011 - 2013 (INCAA Computers BV)
# Author: Samuel Iglesias Gonsalvez <siglesia@cern.ch>
# Author: INCAA Computers BV (info@incaacomputers.com)
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Website: http://www.incaacomputers.com
# Version: 2.0 (Last modifications: 13/06/2013)
#
# FPGA firmware: spec_pts_sfpeeprom.bin
#
# Description
#  Testing of the "SFP EEPROM" chip on the SPEC board (SFP J7). The firmware loaded
#  to the FPGA implements the interface for the communication with the I2C of the 
#  SFP EEPROM
#
#  The test checks the presence of the SFP connector, reads the connector type and
#  verifies the received value.

import sys
import rr
import time
import os

from i2c import COpenCoresI2C

from ptsexcept import *

"""
test04: checks the presence of the SFP connector and reads the type of connector
"""

##-------------------------------------------------------------------------------------------------
##                                       SFP I2C EEPROM class                                    --
##-------------------------------------------------------------------------------------------------

class EEPROM_SFP:
    def __init__(self, i2c, addr):
        self.i2c = i2c;
        self.addr = addr;

    def wr_reg16(self, addr, value):
        self.i2c.start(self.addr, True);
        self.i2c.write(addr, False);
        tmp = (value >> 8) & 0xFF;
        self.i2c.write(value, False);
        tmp = value & 0xFF;
        self.i2c.write(value, True)

    def wr_reg8(self, addr, value):
        self.i2c.start(self.addr, True); # write cycle
        self.i2c.write(addr, False);
        self.i2c.write(value, True);

    def rd_reg16(self, addr):
        self.i2c.start(self.addr, True);
        self.i2c.write(addr, False);
        self.i2c.start(self.addr, False);
        tmp_MSB = self.i2c.read(False);
        tmp_LSB = self.i2c.read(True);
        value = (tmp_MSB << 8) | tmp_LSB;
        return value;

    def rd_reg8(self, addr):
        self.i2c.start(self.addr, True);
        self.i2c.write(addr, False);
        self.i2c.start(self.addr, False);
        return self.i2c.read(True);    

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

def main (default_directory='.'):
    # Configure the FPGA using the program fpga_loader
    path_fpga_loader = '../firmwares/fpga_loader';
    path_firmware = '../firmwares/spec_pts_sfpeeprom.bin';
    firmware_loader = os.path.join(default_directory, path_fpga_loader)
    bitstream = os.path.join(default_directory, path_firmware)
    print "Loading firmware: %s" % (firmware_loader + ' ' + bitstream)
    os.system( firmware_loader + ' ' + bitstream)
    #time.sleep(2);

    # Load board library and open the corresponding device
    print "Loading hardware access library and opening devices\n"
    spec = rr.Gennum();
    i2c = COpenCoresI2C(spec, 0x40000, 99); # Prescaler value calculated using 50 MHz clock
    eeprom = EEPROM_SFP(i2c, 0x50);

    print "Test04 Start"
    init_test_time = time.time()
    ret_error = None

    type = eeprom.rd_reg8(0x0); 
    print "Type of serial transceiver: " + hex(type)
    if (type == 3) :
        print "Type is correct"
    else :
        ret_error = "Wrong type of connector. It should be 0x3"

    end_test_time = time.time()
    print "End of Test04"
    print "RESULT: [{}]".format("FAIL" if ret_error else "OK")
    print 'Test04 elapsed time: {:.2f} seconds'.format(end_test_time-init_test_time)
    if ret_error:
        raise PtsError(ret_error)

if __name__ == '__main__' :
    main();

