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

# Copyright CERN, 2012 (Seven Solutions S.L.)
# Author: Tomasz?
# Author: Richard Carrillo <rcarrillo(AT)sevensols.com>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Website: http://www.sevensols.com
# Version: 1.0 (Last modifications: 29/4/2012)

from ptsexcept import *
from dio_fmc import *

import rr
import os


"""
test02: Check fmc-dio-5chttl-board EEPROM presence and operation
Conditions: Mezzanine presence line asserted
User intervention required: No
Procedure details:
- Load firmware
- Test mezzanine presence line.
- Initialize the board
- Check that I2C device EEPROM (24AA64T) is present
- Check writing and reading operation of EEPROM
"""

class test02:
   def __init__(self, spec):
      """ Initialize the board, check PRESENT pin state and look for I2C devices """
      try:
         self.dio = CFmcDio(spec, 0x80000, False, True, False) # Init EEPROM I2C device
      except CFmcDioError as e:
         err_msg="While fmc-dio-5chttla initialization: "+str(e)
         if e.bus_name == "FMC":
            raise PtsCritical(err_msg) # Critical error: the fmc-dio-5chttl-board is apparently not present
         else:
            raise PtsError(err_msg) # Non-critical error: further tests could be performed successfully

   def test_eeprom(self):
      """ Check EEPROM I.C. operation """

      wr_pattern_length=8 # length of the testing byte pattern
      wr_pattern_addr=20 # address at which the pattern is written
      wr_pattern=list() # List of patterns to verify
      wr_pattern.append([0xFF for n in range(wr_pattern_length)]) # first testing pattern
      wr_pattern.append([2**n for n in range(wr_pattern_length)]) # second testing pattern

      try:
         ret_error=None
         oldedata=self.dio.rd_eeprom(wr_pattern_addr,wr_pattern_length) # Save EEPROM content before testing
         time.sleep(0.01)

         for pattern in wr_pattern:
            self.dio.wr_eeprom(wr_pattern_addr,pattern)
            time.sleep(0.01)
            edata=self.dio.rd_eeprom(wr_pattern_addr,wr_pattern_length)
            time.sleep(0.01)
            if edata <> pattern: # If writen data is not correctly recovered
               ret_error="TSTERR07: Correct data not read when verifying EEPROM (24AA64T) writting operation"
               print ret_error
               break
         self.dio.wr_eeprom(wr_pattern_addr,oldedata)  # Restore EEPROM content before exiting
      except CFmcDioError as e:
         print str(e)
         ret_error="While verifying operation of EEPROM (24AA64T): "+str(e)
      return ret_error

def main(default_directory="."):
   # Configure the FPGA using the program fpga_loader
   path_fpga_loader = '../firmwares/fpga_loader'
   path_firmware = '../firmwares/spec_top.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 )

   # Load board library and open the corresponding device
   print "Loading hardware access library and opening device\n"
   spec = rr.Gennum()

   print "Test02 Start"

   init_test_time = time.time()
   print "Checking fmc-dio-5chttla board and I2C devices"
   test=test02(spec)
   print "\nChecking EEPROM I.C. writing and reading operation (24AA64T)"
   ret_error=test.test_eeprom()

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

   if ret_error:
      raise PtsError(ret_error)


if __name__ == "__main__":
    main(".")

