"""
   config_PLLs.py -- module to initialize the internal and external PLLs

   Author
      JPC : 17/04/2018
      JPC : 18/09/18 passed number of card as parameter

      

"""
import time
import os
import pathtocomponents
import sys


from fpga_comp import Arria10
from si534x_comp import Si534x
from xcvr_comp import xcvr


def main():
   if (len(sys.argv) != 2):
      print "Missing argument"
      print "Syntax : config_PLLs <Nb_of_card> where Nb_of_pcie_slot = 0 or 2"
      exit()
   elif (sys.argv[1] == "0"):
      print
      print "===== Target board = 0"
      dev = 0
   elif (sys.argv[1] == "2"):
      print
      print "===== Target board = 2"
      dev = 2
   else:
      print "Wrong argument"
      print "Syntax : config_PLLs <Nb_of_card> where Nb_of_pcie_slot = 0 or 2"
      exit()

   # Program PLLs
   devices = \
       {1: "SI5345_U23",
        2: "SI5345_U48",
        3: "SI5344_U54"
        }
   ports = \
       {1: [0, 1, 2, 3],
        2: [0, 1, 3, 4, 8],
        3: [0, 1]
        }
   # EJ os.chdir("../../../FC0/devices_lli/components")
   os.chdir("../Python/components")
   # print os.getcwd()

   # Modif 17-01-2019 EJ EP changement des 3 fichiers programmation PLL
   #files = \
       #{1: "../data/Si5345-RevD-JIT1_40_jitter1_input0_40MHz-Registers.txt",
       #2: "../data/Si5345-RevD-JIT2_40_jitter2_input0_40MHz-Registers.txt",
       #3: "../data/Si5344-RevD-TFC_40-Registers.txt"
       #}

   files = \
        {1: "../data/Si5345-RevB-JIT1_255-JIT1_240_jitter1_input1_255MHz_new-Registers.txt",
         2: "../data/Si5345-RevB-JIT2_255-JIT2_240_jitter2_input1_255MHz_new-Registers.txt",
         3: "../data/Si5344-RevB-TFC_127-Registers.txt"
         }
   expected_frequency = \
       {1: ["40.0789 MHz", "240.4734 MHz", "Undefined", "40.0789 MHz"],
        2: ["40.0789 MHz", "240.4734 MHz", "Undefined", "40.0789 MHz"],
        3: ["40.0789 MHz", "Undefined", "Undefined", "Undefined"]
        }

   freq = {"SI5344_U54": {
           0: "tfc_refclk",
           1: "sys_clk_40"},
       "SI5345_U23": {
           0: "gbt_refclk0",
           1: "gbt_refclk1",
           2: "gbt_refclk2",
           3: "gbt_refclk3"},
       "SI5345_U48": {
           0: "gbt_refclk4",
           1: "gbt_refclk5",
           3: "gbt_refclk6",
           4: "gbt_refclk7",
           8: "sys_clk_240"},
       "SI53344": {
           0: "ext_refclk0",
           1: "ext_refclk1",
           2: "ext_refclk2",
           3: "ext_refclk3",
           4: "ext_refclk4",
           5: "ext_refclk5",
           6: "ext_refclk6",
           7: "ext_refclk7",
           8: "ext_sys_clk"},
       "SI5340": {
           0: "oscillator or face plate clock"}
   }
        
   #dev = 0  # Creates a list of objects with the 3 PLLs
   add = 0x68
   pll = [Si534x(dev, bus, add) for bus in devices.keys()]
   print

   # Set reset for transceivers
   print "===== Setting GBT reset"
   fpga = Arria10(0)
   fpga.init_reset_gbt()
   print
   time.sleep(5)
   
   for i in devices.keys():  # programs the 3 PLLs
       print "===== Programming PLL ", devices[i], "====="
       pll[i - 1].program_with_file(files[i], devices[i])  # i-1 because list index starts with 0
       print "..... wait to stabilize"
       time.sleep(7)
       for input in range(0, 4):
           pll[i-1].enable_los(input)
           pll[i-1].enable_oof(input)
       for j in range(0,4):
           status, loss_of_signal = pll[i - 1].read_loss_of_signal(j)
           print "..... Input ", j," :",
           if loss_of_signal == True:
               print "Loss of signal, ",
           else:
               print "Input clock present, ",
           status, oof = pll[i - 1].read_out_of_frequency(j)
           if oof == True:
               print "Out of frequency"
           else:
               print "Nominal frequency", "(", expected_frequency[i][j],")"
       print
       status, val = pll[i-1].read_run_mode()
       print "..... PLL mode =", val
       status, val = pll[i - 1].read_loss_of_lock()  # i-1 because list index starts with 0
       print ".....",devices[i],
       if val == True:
           print "Loss of lock"
       else:
           print "Locked"
       print

   # Measure clocks

   for key, value in sorted(freq.iteritems()):  # scan frequencies
       print "===== Measuring frequencies generated by device ", key, "====="
       for port in value.keys():
           status, frequency_read = fpga.read_pll_port_frequency(key, port)
           print " Port ", port, " : ", frequency_read, "(", value[port], ")"

   # Calibrate all fPLLs
   print "===== Calibrating fPLLs ====="
   trans = xcvr(dev)
   trans.calibrate_pll_all()
   print "..... fPLL calibrations done"
   print

   # Calibrate all PHYs
   print "===== Calibrating PHYs ====="
   trans.calibrate_phy_all()
   print "..... PHY calibrations done"
   print

   # Clear reset for transceivers
   print "===== Clearing GBT reset"
   fpga.clear_reset_gbt()
   print







if __name__ == "__main__":
    main()