From 38f2343a3183e110cb107e139cdf8a5dca209e40 Mon Sep 17 00:00:00 2001
From: ROBBE Patrick <robbe@lal.in2p3.fr>
Date: Sun, 27 Jan 2019 17:00:45 +0100
Subject: [PATCH] add Si534x file

---
 Python/components/si534x_comp.py | 1165 ++++++++++++++++++++++++++++++
 1 file changed, 1165 insertions(+)
 create mode 100644 Python/components/si534x_comp.py

diff --git a/Python/components/si534x_comp.py b/Python/components/si534x_comp.py
new file mode 100644
index 0000000..b2f8348
--- /dev/null
+++ b/Python/components/si534x_comp.py
@@ -0,0 +1,1165 @@
+#!/usr/bin/python
+# -*- coding: iso-8859-1 -*-
+"""
+   si534x_comp.py -- module for programming and monitoring Silicon Si5344/Si5345 PLL components
+
+   Note:
+      This code will be running on FC
+      No Firmware today
+   Author
+      MJ 18/10/2017
+      JPC 06/12/2017 added an exhaustive test of the 3 PLLs in Main
+      JPC 22/01/2018 suppressed prints to simplify display
+      JPC 22/0/12018 corrected bug in read_loss_of_lock (bad address)
+      JPC 22/01/2018 corrected bug in clear_lol_flg_bit (wrong bit)
+      JPC 13/04/2018 corrected bug in read_free_run (bad address)
+      JPC 04/05/2018 added methods for enabling/disabling outputs
+      JPC 12/09/2018 added hard reset method
+      JPC 11/10/2018 added bit handling methods
+      JPC 15/11/2018 added patch to correct OOF and LOS flag issue in rev B chip
+                     added speed grade detection
+
+"""
+
+import sys
+import os
+import time
+# from string import find, split
+from string import find
+from string import split
+
+# dummy_i2c instead i2c from lli
+sys.path.append("./dummy_lli")
+from lli import i2c
+#import i2c
+from fpga_comp import Arria10
+
+class Si534x(object):
+    """
+    Note: Register Address of the Si534x Device Table Register
+      PAGE : There is the “Page Register” which is located at address 0x01 on every page.
+             When read, it will indicate the current page. When written, it will change the page
+             to the value entered. There is a page register at address 0x0001, 0x0101, 0x0201,…
+      PN_BASE_LSB, PN_BASE_MSB: Base Part Number (ex:"5345")
+      INTERNAL_STATUS_BITS :
+        INTERNAL_STATUS_BITS[0]: SYSINCAL (1 if device is calibrating)
+        INTERNAL_STATUS_BITS[1]: LOSXAXB  (1 if there is no signal at the XAXB pins)
+        INTERNAL_STATUS_BITS[5]: SMBBUS_TIMEOUT  (1 if there is an SMBus timeout error)
+      LOS_OOF_ALARMS : Loss-Of-Signals (LOS) and Out-Of-Frequency (OOF) inputs alarms
+        LOS_OOF_ALARMS[0] : LOS_IN0 1 if the clock input0 is currently loss
+        LOS_OOF_ALARMS[1] : LOS_IN1 1 if the clock input1 is currently loss
+        LOS_OOF_ALARMS[2] : LOS_IN2 1 if the clock input2 is currently loss
+        LOS_OOF_ALARMS[3] : LOS_IN3 1 if the clock input3 is currently loss
+        LOS_OOF_ALARMS[4] : OOF_IN0 1 if the clock input0 is currently oof
+        LOS_OOF_ALARMS[5] : OOF_IN1 1 if the clock input1 is currently oof
+        LOS_OOF_ALARMS[6] : OOF_IN2 1 if the clock input2 is currently oof
+        LOS_OOF_ALARMS[7] : OOF_IN3 1 if the clock input3 is currently oof
+      HOLDOVER_LOS_STATUS :
+        HOLDOVER_LOS_STATUS[1] : LOL  1 if the DSPLL (output) is out of lock
+        HOLDOVER_LOS_STATUS[5] : HOLD 1 if the DSPLL (output) is in holdover (or free run mode)
+      CALIBRATION_STATUS :
+        CALIBRATION_STATUS[5] : CAL_PLL 1 if the DSPLL internal calibration is busy
+      CLOCK_OUTPUT_DRIVER[9..0] :
+        CLOCK_OUTPUT_DRIVER[i][1] : OUTi_OE 1 if Ouput0 is enabled, 0 if disabled
+      INTERNAL_STATUS_BITS_FLG : Sticky version of INTERNAL_STATUS_BITS_FLG
+        INTERNAL_STATUS_BITS_FLG[0]: SYSINCAL_FLG,write a 0 to this bit to clear
+        INTERNAL_STATUS_BITS_FLG[1]: LOSXAXB_FLG,write a 0 to this bit to clear
+        INTERNAL_STATUS_BITS_FLG[5]: SMBBUS_TIMEOUT_FLG,write 0 to this bit to clear
+      LOS_OOF_ALARMS_FLG : Sticky version of LOS_OOF_ALARMS
+         LOS_OOF_ALARMS_FLG[0] : LOS_IN0_FLG,write a 0 to this bit to clear
+         LOS_OOF_ALARMS_FLG[1] : LOS_IN1_FLG,write a 0 to this bit to clear
+         LOS_OOF_ALARMS_FLG[2] : LOS_IN2_FLG,write a 0 to this bit to clear
+         LOS_OOF_ALARMS_FLG[3] : LOS_IN3_FLG,write a 0 to this bit to clear
+         LOS_OOF_ALARMS_FLG[4] : OOF_IN0_FLG,write a 0 to this bit to clear
+         LOS_OOF_ALARMS_FLG[5] : OOF_IN1_FLG,write a 0 to this bit to clear
+         LOS_OOF_ALARMS_FLG[6] : OOF_IN2_FLG,write a 0 to this bit to clear
+         LOS_OOF_ALARMS_FLG[7] : OOF_IN3_FLG,write a 0 to this bit to clear
+      HOLDOVER_LOS_STATUS_FLG : Sticky version of HOLDOVER_LOS_STATUS
+         HOLDOVER_LOS_STATUS[1] : LOL_FLG,write a 0 to this bit to clear
+         HOLDOVER_LOS_STATUS[5] : HOLD_FLG,write a 0 to this bit to clear
+      CALIBRATION_STATUS_FLG : Sticky version of CALIBRATION_STATUS
+         CALIBRATION_STATUS_FLG[5] : CAL_PLL_FLG,write a 0 to this bit to clear
+      HOLD_HIST_VALID :
+         HOLD_HIST_VALID[1] : HOLD_HIST_VALID bit, 1 if History data is valid
+    """
+    PAGE = 0x0001
+    PN_BASE_LSB = 0x0002
+    PN_BASE_MSB = 0x0003
+    DEVICE_REVISION = 0x0005
+    
+
+    INTERNAL_STATUS_BITS = 0x000C
+    # Position Bits of INTERNAL_STATUS_BITS:
+    SYSINCAL = 0
+    LOSXAXB = 1
+    SMBBUS_TIMEOUT = 5
+
+    LOS_OOF_ALARMS = 0x000D
+    # Position Bits of LOS_OOF_ALARMS:
+    LOS_IN0 = 0
+    LOS_IN1 = 1
+    LOS_IN2 = 2
+    LOS_IN3 = 3
+    OOF_IN0 = 4
+    OOF_IN1 = 5
+    OOF_IN2 = 6
+    OOF_IN3 = 7
+
+    STATUS_FLAGS_MASKS = 0X0017
+    # Position Bits of STATUS_FLAGS_MASKS:
+    SYSINCAL_INTR_MSK      = 0
+    LOSXAXB_INTR_MSK       = 1
+    SMBUS_TIMEOUT_INTR_MSK = 5
+
+    LOS_OOF_FLAGS_MASKS = 0x0018
+    # Position Bits of LOS_OOF_FLAGS_MASKS:
+    LOS_INTR_MSK0 = 0
+    LOS_INTR_MSK1 = 1
+    LOS_INTR_MSK2 = 2
+    LOS_INTR_MSK3 = 3
+    OOF_INTR_MSK0 = 4
+    OOF_INTR_MSK1 = 5
+    OOF_INTR_MSK2 = 6
+    OOF_INTR_MSK3 = 7
+
+    HOLDOVER_LOL_MASKS = 0x0019
+    # Position Bits of HOLDOVER_LOL_MASKS:
+    LOL_INTR_MSK  = 1
+    HOLD_INTR_MSK = 5
+
+    SOFT_RESET_CAL = 0x001C
+    # Position Bits of SOFT_RESET_CAL
+    SOFT_RST_ALL = 0
+    SOFT_RST = 1
+
+    PWR_DOWN_HARD_RESET = 0x001E
+    # Position Bits of PWR_DOWN_HARD_RESET
+    PDN      = 0
+    HARD_RST = 1
+    SYNC     = 2
+
+    LOS_ENABLE = 0x002C
+    # Position Bits of LOS_ENABLE
+    LOS_EN0 = 0
+    LOS_EN1 = 1
+    LOS_EN2 = 2
+    LOS_EN3 = 3
+    LOSXAXB_DIS = 4
+
+    OOF_ENABLE = 0x003F
+    # Position Bits of OOF_ENABLE
+    OOF_EN0 = 0
+    OOF_EN1 = 1
+    OOF_EN2 = 2
+    OOF_EN3 = 3
+    FAST_OOF_EN0 = 4
+    FAST_OOF_EN1 = 5
+    FAST_OOF_EN2 = 6
+    FAST_OOF_EN3 = 7
+
+    HOLDOVER_LOS_STATUS = 0x000E
+    # Position Bits of HOLDOVER_LOS_STATUSHOLDOVER_LOS_STATUS:
+    LOL = 1
+    HOLD = 5
+
+    CALIBRATION_STATUS = 0x000F
+    # Position Bits of CALIBRATION_STATUS:
+    CALL_PLL = 5
+
+    CLOCK_OUTPUT_DRIVER = [0x0108, 0x010D, 0x0112, 0x0117, 0x011C, 0x121, 0x126, 0x12B, 0x130, 0x13A]
+    # Position Bits of CLOCK_OUTPUT_DRIVER[]:
+    OUT_OE = 1
+
+
+    #-------------Sticky registers---------------------------------
+
+    INTERNAL_STATUS_BITS_FLG = 0x0011
+    # Position Bits of INTERNAL_STATUS_BITS_FLG:
+    SYSINCAL_FLG = 0
+    LOSXAXB_FLG = 1
+    SMBBUS_TIMEOUT_FLG = 5
+
+    LOS_OOF_ALARMS_FLG = 0x0012
+    # Position Bits of LOS_OOF_ALARMS_FLG:
+    LOS_IN0_FLG = 0
+    LOS_IN1_FLG = 1
+    LOS_IN2_FLG = 2
+    LOS_IN3_FLG = 3
+    OOF_IN0_FLG = 4
+    OOF_IN1_FLG = 5
+    OOF_IN2_FLG = 6
+    OOF_IN3_FLG = 7
+
+    HOLDOVER_LOS_STATUS_FLG = 0x0013
+    # Position Bits of HOLDOVER_LOS_STATUS_FLG:
+    LOL_FLG = 1
+    HOLD_FLG = 5
+
+    CALIBRATION_STATUS_FLG = 0x0014
+    # Position Bits of CALIBRATION_STATUS:
+    CALL_PLL_FLG = 5
+
+    # Set and clear thehold for LOL signal
+    LOL_SET_THR = 0x009E
+    LOL_CLR_THR = 0x00A0
+
+    HOLD_HIST_VALID = 0x053F
+    # Position Bits of HOLD_HIST_VALID:
+    ENOUGH_HISTORICAL_FREQUENCY_DATA = 1
+
+    def __init__(self, dev, bus, add):
+        """
+        Args:
+          dev (int): board identifier
+          bus (int): selected i2c bus on the board
+          add (int): address of device on the i2c bus
+        """
+        self.dev = dev
+        self.bus = bus
+        self.add = add
+
+    def test_bit(self, reg, offset):
+        """ Test a bit
+        Args:
+            reg : register address
+            offset : bit number
+        returns:
+            a nonzero result, 2**offset, if the bit at 'offset' is one.
+        """
+        status, val = self.read_pagined_register(reg)
+        mask = 1 << offset
+        return (val & mask) >> offset
+
+    def set_bit(self, reg, offset):
+        """ Set a bit
+            Args:
+                reg : register address
+                offset : bit number
+
+            """
+        status, val = self.read_pagined_register(reg)
+        mask = 1 << offset
+        status = self.write_pagined_register(reg, val | mask)
+
+    def clear_bit(self, reg, offset):
+        """ Clear a bit
+            Args:
+                reg : register address
+                offset : bit number
+
+                """
+        status, val = self.read_pagined_register(reg)
+        mask = ~(1 << offset)
+        status = self.write_pagined_register(reg, val & mask)
+
+    def toggle_bit(self, reg, offset):
+        """ Togle a bit
+            Args:
+                reg : register address
+                offset : bit number
+
+        """
+        status, val = self.read_pagined_register(reg)
+        mask = 1 << offset
+        status = self.write_pagined_register(reg, val ^ mask)
+
+
+    def write_pagined_register(self, register_address, value_to_write):
+        """ write one register of the Device Table Register
+        Args:
+           register_address (int): 16 bits register address of the Device Table Register
+                                   bit[11..8] contains the page of the table
+           value_to_write (int)  : 16 bits value to write on the device at register_address
+
+        Returns:
+           status (int) : 0 if successfull, -1 if error
+
+        Notes: about pagination
+          I2C use only 8 bits for address, so there is a pagination on Si534x register space:
+            0x0000-0x0FF : page 0
+            0x0100-0x1FF : page 1
+            0x0200-0x2FF : page 2
+            0x0300-0x3FF : page 3 .....
+        There is the “Page Register” which is located at address 0x01 on every page.
+        When read, it will indicate the current page. When written, it will change the page to the
+        value entered. There is a page register at address 0x0001, 0x0101, 0x0201, 0x0301, … etc.
+        To write "value_to_write" at "register_adress", we must perform the steps:
+            1) Extract from "register_address" the "msbyte_register_address" that gives the page
+            2) Extract from "register_address" the "lsbyte_register_address" that gives the 8 bits
+               address to transmit with I2C
+            3) read the current page with a read I2C on the device at adresse 0x0001
+            4) if the current page is not equal to "msbyte_register_address", then write I2C the
+               value "msbyte_register_address" at adresse 0x0001 on the device
+            5) then write I2C the value "value_to_write" at address "lsbyte_register_address"
+              on the device
+        """
+        msbyte_register_address = register_address >> 8
+        lsbyte_register_address = 0xFF & register_address
+        page_register_address = self.PAGE
+        (status1, current_page) = i2c.read(self.dev, self.bus, self.add, page_register_address)
+        if current_page != msbyte_register_address:
+            (status2, value) = i2c.write(self.dev, self.bus, self.add, page_register_address, msbyte_register_address)
+        else:
+            status2 = 0
+        (status3, value) = i2c.write(self.dev, self.bus, self.add, lsbyte_register_address, value_to_write)
+        status = 0
+        if status1 == -1 or status2 == -1 or status3 == -1:
+            status = -1
+        return status
+
+    def read_pagined_register(self, register_address):
+        """read one register of the Device Table Register
+        Args:
+          register_address (int): 16 bits register address of the Device Table Register
+                                  bit[11..8] contains the page of the table
+
+        Returns:
+          tuple:
+            (status(int), val(int))
+              status  : 0 if successfull, -1 if error
+              val     : read value on the device
+
+        Notes: about pagination
+               see read_pagined_register() notes
+        """
+        msbyte_register_address = register_address >> 8
+        lsbyte_register_address = 0xFF & register_address
+        page_register_address = self.PAGE
+        (status1, current_page) = i2c.read(self.dev, self.bus, self.add, page_register_address)
+        if current_page != msbyte_register_address:
+            (status2, value) = i2c.write(self.dev, self.bus, self.add, page_register_address, msbyte_register_address)
+        else:
+            status2 = 0
+        (status3, val) = i2c.read(self.dev, self.bus, self.add, lsbyte_register_address)
+        status = 0
+        if status1 == -1 or status2 == -1 or status3 == -1:
+            status = -1
+        return (status, val)
+
+    def si534x_programming(self, filename):
+        """programming the device with a wizard files
+        Args:
+          filename (string) = wizard file CBPro, example: "Si5345-RevD-5345EVB1-Registers.txt"
+
+        Returns:
+          status (int) : 0 if successfull, -1 if error
+
+        Notes: about si534x_programming (Si5345-44-42-D-RM.pdf page 16 Dynamic PLL Changes)
+          1) in first preamble (we assume we have a Revision D circuit)
+             0x0B24,0xC0
+             0x0B25,0x00
+             0x0540,0x01 ????
+             0x540 register is in the wizard files of CBPro
+             but in Si5345-44-42-D-RM.pdf 0x540 register doesn't exist...
+          2) Wait 300 ms
+          3) Then perform the desired register modifications
+             (write all the register map of the wizard file)
+          4) Write the post-amble and SOFT_RST
+             0x0514, 0x01 ????
+             0x514 register programmation is in preamble of wizard files of CBPro but not in
+             Si5345-44-42-D-RM.pdf...0x514 is "BW_UPDATE_PLL"
+             0x001C,0x01 ( SOFT_RST : set bit 0 of Register 0x001C x001C[0] = 1 )
+             0x0540,0x00  ????
+             0x540 register is in the wizard files of CBPro
+             but in Si5345-44-42-D-RM.pdf 0x540 register doesn't exist...
+             0x0B24,0xC3
+             0x0B25,0x02
+          the wizard files merges the steps "Write post-amble" and ""SOFT_RST"
+          the wizard files appends the programming of registers 0x540 and 0x514 in preamble and
+          postamble
+        """
+        try:
+            #print os.path.join(os.environ.get('LLI_DAT')+filename)
+ #           fic = open(os.path.join(os.environ.get('LLI_DAT'), filename), "r")
+            fic = open(os.path.join("../data", filename), "r")
+        except IOError:
+            print 'file not found'
+            exit(0)
+	      # **********************************1) in first preamble***********************************
+        # header suppress
+        indice_entete = 0
+        while find(fic.readline(), 'Start configuration preamble') == -1:
+            indice_entete += 1
+        # indice_entete is dummy....
+        # typical data line  : "0x0B24,0xC0"
+        # last line of preamble is "# End configuration preamble"
+        #print 'hostname'  # JEVAUD PRINT DEBUG A EFFACER EN FINAL
+        while 1:
+            current_line = fic.readline()
+            if find(current_line, 'End configuration preamble') <> -1:
+                #print 'End of preamble' # JEVAUD PRINT DEBUG A EFFACER EN FINAL
+                break
+            [current_regstr, current_valstr] = split(current_line, ',')
+            current_reg = int(current_regstr, 16)
+            current_val = int((current_valstr), 16)
+            status1 = self.write_pagined_register(current_reg, current_val)
+
+        # **********************************2) wait 300ms *****************************************
+        #print 'wait 300ms'  #JEVAUD PRINT DEBUG A EFFACER EN FINAL
+        time.sleep(0.3)
+
+        # ********************3) Then perform the desired register modifications ******************
+        # text suppress
+        indice_entete = 0
+        while find(fic.readline(), 'Start configuration registers') == -1:
+            indice_entete += 1
+        # indice_entete is dummy....
+        # typical data line  : "0x000B,0x68"
+        # last line of configuration registers is "End configuration registers"
+        #print 'Start of configuration registers'  # JEVAUD PRINT DEBUG A EFFACER EN FINAL
+        while 1:
+            current_line = fic.readline()
+            if find(current_line, 'End configuration registers') <> -1:
+                #print 'End of configuration registers' # JEVAUD PRINT DEBUG A EFFACER EN FINAL
+                break
+            [current_regstr, current_valstr] = split(current_line, ',')
+            current_reg = int(current_regstr, 16)
+            current_val = int((current_valstr), 16)
+            status2 = self.write_pagined_register(current_reg, current_val)
+
+        # ********************4) Write the post-amble and SOFT_RST ********************************
+        # text suppress
+        indice_entete = 0
+        while find(fic.readline(), 'Start configuration postamble') == -1:
+            indice_entete += 1
+        # indice_entete is dummy....
+        # typical data line  : "0x0514,0x01"
+        # last line of configuration registers is "End configuration postamble"
+        #print 'Start configuration postamble'  # JEVAUD PRINT DEBUG A EFFACER EN FINAL
+        while 1:
+            current_line = fic.readline()
+            if find(current_line, 'End configuration postamble') <> -1:
+                #print 'End configuration postamble' # JEVAUD PRINT DEBUG A EFFACER EN FINAL
+                break
+            [current_regstr, current_valstr] = split(current_line, ',')
+            current_reg = int(current_regstr, 16)
+            current_val = int((current_valstr), 16)
+            status3 = self.write_pagined_register(current_reg, current_val)
+
+        fic.close()
+        status = 0
+        if status1 == -1 or status2 == -1 or status3 == -1:
+            status = -1
+        return status
+
+    def read_part_number(self):
+        """read part number from the device : "5345" for a Si5345
+        No Args
+
+        Returns:
+          tuple:
+            (status(int), part_number(int))
+             status  : 0 if successfull, -1 if error
+             val     : 16 bit integer (0x5345 for a Si5345)
+        """
+        register_address = self.PN_BASE_LSB
+        (status1, lsbyte_part_number) = self.read_pagined_register(register_address)
+        register_address = self.PN_BASE_MSB
+        (status2, msbyte_part_number) = self.read_pagined_register(register_address)
+        status = 0
+        if status1 == -1 or status2 == -1:
+            status = -1
+        part_number = (msbyte_part_number<<8) + lsbyte_part_number
+        return (status, part_number)
+
+    def read_device_revision(self):
+        """read device grade from the device : 0=A, 1=B, 2=C, 3=D
+        No Args
+
+        Returns:
+             status(int)  : 0 if successfull, -1 if error
+             val(string)  : "A" if 0, "B" if 1, "C"cif 2, "D" if 3
+        """
+        (status, val) = self.read_pagined_register(self.DEVICE_REVISION)
+        if val == 0:
+            revision = "A"
+        elif val == 1:
+            revision = "B"
+        elif val == 2:
+            revision = "C"
+        elif val == 3:
+            revision = "D"
+        else:
+            revision = "Not found : " + str(val)
+        return (status, revision)
+
+    def hard_reset(self):
+        """sends a hard reset to the chip
+        No Args
+        """
+        status = self.set_bit(self.PWR_DOWN_HARD_RESET, self.PDN)
+        status = self.clear_bit(self.PWR_DOWN_HARD_RESET, self.PDN)
+        status = self.set_bit(self.PWR_DOWN_HARD_RESET, self.HARD_RST)
+        status = self.clear_bit(self.PWR_DOWN_HARD_RESET, self.HARD_RST)
+        return
+
+    def soft_reset(self):
+        """sends a hard reset to the chip
+        No Args
+        """
+        status = self.set_bit(self.SOFT_RESET_CAL, self.SOFT_RST_ALL)
+        status = self.clear_bit(self.SOFT_RESET_CAL, self.SOFT_RST_ALL)
+        return
+
+    def read_mask_values(self):
+        """ Read all interrupt mask values
+        Args:
+            none
+        Returns:
+            masks: a dictionary with all the flags values
+
+    """
+        masks ={}
+        masks["SysInCal mask"] = self.test_bit(self.STATUS_FLAGS_MASKS,  self.SYSINCAL_INTR_MSK)
+        masks["LOS XAXB"]      = self.test_bit(self.STATUS_FLAGS_MASKS,  self.LOSXAXB_INTR_MSK)
+        masks["SMBbusTimeout"] = self.test_bit(self.STATUS_FLAGS_MASKS,  self.SMBUS_TIMEOUT_INTR_MSK)
+        masks["LOS input 0"]   = self.test_bit(self.LOS_OOF_FLAGS_MASKS, self.LOS_INTR_MSK0)
+        masks["LOS input 1"]   = self.test_bit(self.LOS_OOF_FLAGS_MASKS, self.LOS_INTR_MSK1)
+        masks["LOS input 2"]   = self.test_bit(self.LOS_OOF_FLAGS_MASKS, self.LOS_INTR_MSK2)
+        masks["LOS input 3"]   = self.test_bit(self.LOS_OOF_FLAGS_MASKS, self.LOS_INTR_MSK3)
+        masks["OOF input 0"]   = self.test_bit(self.LOS_OOF_FLAGS_MASKS, self.OOF_INTR_MSK0)
+        masks["OOF input 1"]   = self.test_bit(self.LOS_OOF_FLAGS_MASKS, self.OOF_INTR_MSK1)
+        masks["OOF input 2"]   = self.test_bit(self.LOS_OOF_FLAGS_MASKS, self.OOF_INTR_MSK2)
+        masks["OOF input 3"]   = self.test_bit(self.LOS_OOF_FLAGS_MASKS, self.OOF_INTR_MSK3)
+        masks["LOL outputs"]   = self.test_bit(self.HOLDOVER_LOL_MASKS,  self.LOL_INTR_MSK)
+        masks["Hold Over"]     = self.test_bit(self.HOLDOVER_LOL_MASKS,  self.HOLD_INTR_MSK)
+        return masks
+
+    def init_mask_values(self):
+        """ sett all interrupt mask values to 1 except input 0
+        Args:
+            none
+        Returns:
+            masks: a dictionary with all the flags values
+
+    """
+        masks ={}
+        masks["SysInCal mask"] = self.set_bit(self.STATUS_FLAGS_MASKS,  self.SYSINCAL_INTR_MSK)
+        masks["LOS XAXB"]      = self.set_bit(self.STATUS_FLAGS_MASKS,  self.LOSXAXB_INTR_MSK)
+        masks["SMBbusTimeout"] = self.set_bit(self.STATUS_FLAGS_MASKS,  self.SMBUS_TIMEOUT_INTR_MSK)
+        masks["LOS input 0"]   = self.clear_bit(self.LOS_OOF_FLAGS_MASKS, self.LOS_INTR_MSK0)
+        masks["LOS input 1"]   = self.set_bit(self.LOS_OOF_FLAGS_MASKS, self.LOS_INTR_MSK1)
+        masks["LOS input 2"]   = self.set_bit(self.LOS_OOF_FLAGS_MASKS, self.LOS_INTR_MSK2)
+        masks["LOS input 3"]   = self.set_bit(self.LOS_OOF_FLAGS_MASKS, self.LOS_INTR_MSK3)
+        masks["OOF input 0"]   = self.clear_bit(self.LOS_OOF_FLAGS_MASKS, self.OOF_INTR_MSK0)
+        masks["OOF input 1"]   = self.set_bit(self.LOS_OOF_FLAGS_MASKS, self.OOF_INTR_MSK1)
+        masks["OOF input 2"]   = self.set_bit(self.LOS_OOF_FLAGS_MASKS, self.OOF_INTR_MSK2)
+        masks["OOF input 3"]   = self.set_bit(self.LOS_OOF_FLAGS_MASKS, self.OOF_INTR_MSK3)
+        masks["LOL outputs"]   = self.set_bit(self.HOLDOVER_LOL_MASKS,  self.LOL_INTR_MSK)
+        masks["Hold Over"]     = self.set_bit(self.HOLDOVER_LOL_MASKS,  self.HOLD_INTR_MSK)
+        return masks
+
+    def read_loss_of_lock(self):
+        """read loss_of_lock from the device
+        No Args
+
+        Returns:
+          tuple:
+            (status(int), loss_of_lock(boolean))
+             status       : 0 if successfull, -1 if error
+             loss_of_lock : boolean true if the DSPLL is out of lock, false if not
+        """
+        register_address = self.HOLDOVER_LOS_STATUS
+        bit_position = self.LOL
+        loss_of_lock = False
+        (status, value) = self.read_pagined_register(register_address)
+        if (value >> bit_position) & 1:
+            loss_of_lock = True
+        return (status, loss_of_lock)
+
+    def write_LOL_thresholf_values(self):
+        """set default loss_of_lock thresholds
+        No Args
+
+        Returns:
+          status(int) : 0 if successfull, -1 if error
+
+        Notes:
+          set_value = 100 ppm
+	  clr_value = 30 ppm
+        """
+
+	thresholds = \
+          {0 : "0.1 ppm",
+           1 : "0.3 ppm",
+           2 : "1 ppm",
+           3 : "3 ppm",
+           4 : "10 ppm",
+           5 : "30 ppm",
+           6 : "100 ppm",
+           7 : "300 ppm",
+           8 : "1000 ppm",
+           9 : "3000 ppm",
+           10 : "10000 ppm"
+          }
+        register_address = self.LOL_SET_THR
+	print hex(6<<4)
+        status1 = self.write_pagined_register(register_address, 6<<4)
+	print status1
+	register_address = self.LOL_CLR_THR
+	print hex(5<<4)
+        status2 = self.write_pagined_register(register_address, 5<<4)
+	print status2
+        status = 0
+        if (status1 == -1) or (status2 == -1):
+            status = -1
+        return status
+
+    def read_LOL_threshold_values(self):
+        """read loss_of_lock set and clear thresholds in ppm  from the device
+        No Args
+
+        Returns:
+          tuple:
+            (status(int), set_threshold(str), clear_threshold(str))
+             status           : 0 if successfull, -1 if error
+             set_threshold : value in ppm
+             clear_threhold : value in ppm
+        """
+        thresholds = \
+          {0 : "0.1 ppm",
+           1 : "0.3 ppm",
+           2 : "1 ppm",
+           3 : "3 ppm",
+           4 : "10 ppm",
+           5 : "30 ppm",
+           6 : "100 ppm",
+           7 : "300 ppm",
+           8 : "1000 ppm",
+           9 : "3000 ppm",
+           10 : "10000 ppm"
+          }
+        register_address = self.LOL_SET_THR
+        (status, set_threshold) = self.read_pagined_register(register_address)
+        register_address = self.LOL_CLR_THR
+        (status, clr_threshold) = self.read_pagined_register(register_address)
+        return (status, thresholds[set_threshold>>4], thresholds[clr_threshold>>4])
+
+
+    def read_loss_of_lock_flg(self):
+        """read loss_of_lock_flg (sticky bit of loss_of_lock) from the device
+        No Args
+
+        Returns:
+          tuple:
+            (status(int), loss_of_lock_flg(boolean))
+             status           : 0 if successfull, -1 if error
+             loss_of_lock_flg : boolean true if loss_of_lock_flg = 1, false if not
+        """
+        register_address = self.HOLDOVER_LOS_STATUS_FLG
+        bit_position = self.LOL_FLG
+        loss_of_lock_flg = False
+        (status, value) = self.read_pagined_register(register_address)
+        if (value >> bit_position) & 1:
+            loss_of_lock_flg = True
+        return (status, loss_of_lock_flg)
+
+    def read_run_mode(self):
+        """read_run_mode which is the image of the state machine
+        No Args
+
+        Returns:
+          tuple:
+            (status(int), free_run_mode(boolean))
+             status                 : 0 if successfull, -1 if error
+             free_run_holdover_mode : boolean true if the DSPLL is in free-run or holdover mode,
+                                      false if not
+        """
+        register_address = self.HOLDOVER_LOS_STATUS
+        bit_position = self.HOLD
+        mode = "Normal"
+        (status, value) = self.read_pagined_register(register_address)
+        if (value >> bit_position) & 1:
+            register_address = self.HOLD_HIST_VALID
+            bit_position = self.ENOUGH_HISTORICAL_FREQUENCY_DATA
+            (status, value) = self.read_pagined_register(register_address)
+            if (value >> bit_position) & 1:
+                mode = "Hold over"
+            else:
+                mode = "Free run"
+        else:
+            mode = "Normal"
+        return (status, mode)
+
+    def read_free_run_mode_flg(self):
+        """read free_run_holdover_mode_flg (sticky bit of free_run_mode) from the device
+        No Args
+
+        Returns:
+          tuple:
+            (status(int), mode (string)
+             status                     : 0 if successfull, -1 if error
+             mode: sting = "Free run" if free run mode
+                         = "Hold over" if hold over mode
+                         = "Normal" is normal mode
+        """
+        register_address = self.HOLDOVER_LOS_STATUS_FLG
+        bit_position = self.HOLD_FLG
+        free_run_mode_flg = False
+        (status, value) = self.read_pagined_register(register_address)
+        if (value >> bit_position) & 1:
+            free_run_mode_flg = True
+        return (status, free_run_mode_flg)
+
+    def read_hold_hist_valid(self):
+        """read hold_hist_valid bit (1 when history data is valid) from the device
+        No Args
+
+        Returns:
+          tuple:
+            (status(int), hold_hist_valid(boolean))
+             status          : 0 if successfull, -1 if error
+             hold_hist_valid : boolean true if hold_hist_valid = 1, false if not
+        """
+        register_address = self.HOLD_HIST_VALID
+        bit_position = self.ENOUGH_HISTORICAL_FREQUENCY_DATA
+        hold_hist_valid = False
+        (status, value) = self.read_pagined_register(register_address)
+        if (value >> bit_position) & 1:
+            hold_hist_valid = True
+        return (status, hold_hist_valid)
+
+    def clear_lol_flg_bit(self):
+        """clear LOL_FLG sticky bit of Loss of Lock LOL
+        No Args
+
+        Returns:
+          status(int) : 0 if successfull, -1 if error
+
+        Notes:
+          to clear LOL_FLG bit:
+            -- read HOLDOVER_LOS_STATUS_FLG register
+            -- in value_read, clear only the bit 1 (LOL_FLG)
+            -- write the result in HOLDOVER_LOS_STATUS_FLG register
+        """
+        register_address = self.HOLDOVER_LOS_STATUS_FLG
+        (status1, value) = self.read_pagined_register(register_address)
+        value = value & ~(1 << self.LOL_FLG)
+        status2 = self.write_pagined_register(register_address, value)
+        (status1, value) = self.read_pagined_register(register_address)
+        status = 0
+        if (status1 == -1) or (status2 == -1):
+            status = -1
+        return status
+
+    def clear_hold_flg_bit(self):
+        """clear HOLD_FLG sticky bit of Holdover mode HOLD
+        No Args
+
+        Returns:
+          status(int): 0 if successfull, -1 if error
+
+        Notes:
+          to clear HOD_FLG bit:
+            -- read HOLDOVER_LOS_STATUS_FLG register
+            -- in value_read, clear only the bit 5 (HOLD_FLG)
+            -- write the result in HOLDOVER_LOS_STATUS_FLG register
+        """
+        register_address = self.HOLDOVER_LOS_STATUS_FLG
+        (status1, value) = self.read_pagined_register(register_address)
+        value = value & ~(1<<self.HOLD_FLG)
+        status2 = self.write_pagined_register(register_address, value)
+        status = 0
+        if (status1 == -1) or (status2 == -1):
+            status = -1
+        return status
+
+    def read_output_enable(self, num_output):
+        """read the output enable of the output num_ouput
+        Args
+          num_output(int) : number of the ouput 0 to 9
+
+        Returns:
+          tuple:
+            (status(int), output_enable(boolean))
+              status        : 0 if successfull, -1 if error
+              output_enable : True if output of num_output is enabled, False otherwise
+        """
+        if num_output > 9:
+            num_output = 9
+        register_address = self.CLOCK_OUTPUT_DRIVER[num_output]
+        bit_position = self.OUT_OE
+        output_enable = False
+        (status, value) = self.read_pagined_register(register_address)
+        if (value >> bit_position) & 1:
+            output_enable = True
+        return (status, output_enable)
+
+    def write_output_enable(self, num_output, output_enable):
+        """write the output enable of the output num_ouput
+        Args
+          num_output(int) : number of the ouput 0 to 9
+          output_enable (boolean) : True if one wants output enabled, False otherwise
+
+        Returns:
+          status (int) : 0 if successfull, -1 if error
+
+        Notes:
+          to write output_enable bit:
+            -- read CLOCK_OUTPUT_DRIVER[num_output] register
+            -- in value_read, clear only the bit 5 (HOLD_FLG)
+            -- write the result in HOLDOVER_LOS_STATUS_FLG register
+        """
+        if num_output > 9:
+            num_output = 9
+        register_address = self.CLOCK_OUTPUT_DRIVER[num_output]
+        (status1, value) = self.read_pagined_register(register_address)
+        if output_enable:
+            value = value | (1<<self.OUT_OE)
+        else:
+            value = value & ~(1<<self.OUT_OE)
+        status2 = self.write_pagined_register(register_address, value)
+        if (status1 == -1) or (status2 == -1):
+            status = -1
+        else:
+            status = 0
+        return status
+
+    def disable_outputs(self):
+        """disable all the outputs
+
+        """
+        status = self.write_pagined_register(0x102, 0)
+        return
+
+    def enable_outputs(self):
+        """enable all the outputs
+
+        """
+        status = self.write_pagined_register(0x102, 1)
+        return
+
+    def read_loss_of_signal(self, num_input):
+        """read loss_of_signal LOS bit of num_input given in argument
+        Args:
+          num_input(int) : number of the input 0 to 3  
+
+        Returns:
+          tuple:
+            (status(int), loss_of_signal(boolean))
+             status         : 0 if successfull, -1 if error
+             loss_of_signal : boolean true if the Loss Of Signal LOS is 1, false if not
+        """
+        if num_input > 3:
+            num_input = 3
+            print "wrong input number"         
+        register_address = self.LOS_OOF_ALARMS
+        los_in_list = [self.LOS_IN0, self.LOS_IN1, self.LOS_IN2, self.LOS_IN3]
+        bit_position = los_in_list[num_input]        
+        (status, value) = self.read_pagined_register(register_address)
+        if (value >> bit_position) & 1:
+            loss_of_signal = True
+        else:
+            loss_of_signal = False
+        return (status, loss_of_signal)
+
+    def enable_los(self, num_input):
+        """enable out of LOS bits
+        """
+        status = self.set_bit(self.LOS_ENABLE, num_input)
+        return status
+
+    def disable_los(self, num_input):
+        """disable out of LOS bits
+        """
+        status = self.clear_bit(self.LOS_ENABLE, num_input)
+        return status
+
+    def enable_oof(self, num_input):
+        """enable out of OOF bits
+        """
+        status = self.set_bit(self.OOF_ENABLE, num_input)
+        return (status)
+
+    def disable_oof(self, num_input):
+        """disable out of OOF bits
+        """
+        status = self.clear_bit(self.OOF_ENABLE, num_input)
+        return (status)
+
+
+    def read_out_of_frequency(self, num_input):
+        """read out_of_frequency OOF bit of num_input given in argument
+        Args:
+          num_input(int) : number of the input 0 to 3  
+
+        Returns:
+          tuple:
+            (status(int), out_of_frequency(boolean))
+             status           : 0 if successfull, -1 if error
+             out_of_frequency : boolean true if the Out Of Frequency OOF is 1, false if not
+        """
+        if num_input > 3:
+            num_input = 3 
+            print "wrong input number"        
+        register_address = self.LOS_OOF_ALARMS
+        oof_in_list = [self.OOF_IN0, self.OOF_IN1, self.OOF_IN2, self.OOF_IN3]
+        bit_position = oof_in_list[num_input]        
+        (status, value) = self.read_pagined_register(register_address)
+        if (value >> bit_position) & 1:
+            out_of_frequency = True
+        else:
+            out_of_frequency = False
+        return (status, out_of_frequency)
+
+    def read_loss_of_signal_flg(self, num_input):
+        """read loss_of_signal_flg LOS_FLG bit of num_input given in argument
+           (sticky bit of loss_of_signal LOS)
+        Args:
+          num_input(int) : number of the input 0 to 3  
+
+        Returns:
+          tuple:
+            (status(int), loss_of_signal_flg(boolean))
+             status             : 0 if successfull, -1 if error
+             loss_of_signal_flg : boolean true if the LOS_FLG is 1, false if not
+        """
+        # if num_input > 3:
+        #     num_input = 3
+        #     print "wrong input number"
+        # register_address = self.LOS_OOF_ALARMS_FLG
+        # los_in_flg_list = [self.LOS_IN0_FLG, self.LOS_IN1_FLG, self.LOS_IN2_FLG, self.LOS_IN3_FLG]
+        # bit_position = los_in_flg_list[num_input]
+        # (status, value) = self.read_pagined_register(register_address)
+        # if (value >> bit_position) & 1:
+        #     loss_of_signal_flg = True
+        # else:
+        #     loss_of_signal_flg = False
+        if self.test_bit(self.LOS_OOF_ALARMS_FLG, num_input) == 1:
+            loss_of_signal_flg = True
+        else:
+            loss_of_signal_flg = False
+        status = 0
+        return (status, loss_of_signal_flg)
+
+    def read_out_of_frequency_flg(self, num_input):
+        """read out_of_frequency_flg OOF_FLG bit of num_input given in argument
+           (sticky bit of out_of_frequency OOF)
+        Args:
+          num_input(int) : number of the input 0 to 3  
+
+        Returns:
+          tuple:
+            (status(int), out_of_frequency_flg(boolean))
+             status               : 0 if successfull, -1 if error
+             out_of_frequency_flg : boolean true if the OOF_FLG is 1, false if not
+        """
+        if num_input > 3:
+            num_input = 3
+            print "wrong input number"         
+        register_address = self.LOS_OOF_ALARMS_FLG
+        oof_in_flg_list = [self.OOF_IN0_FLG, self.OOF_IN1_FLG, self.OOF_IN2_FLG, self.OOF_IN3_FLG]
+        bit_position = oof_in_flg_list[num_input]        
+        (status, value) = self.read_pagined_register(register_address)
+        if (value >> bit_position) & 1:
+            out_of_frequency_flg = True
+        else:
+            out_of_frequency_flg = False
+        return (status, out_of_frequency_flg)
+
+    def clear_los_flg_bit(self, num_input):
+        """clear the sticky bit LOS_FLG of num_input given in argument
+           (sticky bit of loss of signal LOS)
+        Args:
+          num_input(int) : number of the input 0 to 3  
+
+        Returns:
+          status (int) : 0 if successfull, -1 if error
+
+        Notes:
+          to clear LOS_FLG bit:
+            -- read LOS_OOF_ALARMS_FLG register
+            -- in value_read, clear only the bit: 
+                --0 (LOS_IN0_FLG) if num_input = 0
+                --1 (LOS_IN1_FLG) if num_input = 1
+                --2 (LOS_IN2_FLG) if num_input = 2
+                --3 (LOS_IN3_FLG) if num_input = 3
+            -- write the result in LOS_OOF_ALARMS_FLG register
+        """
+
+        # if num_input > 3:
+        #     num_input = 3
+        #     print "wrong input number"
+        # los_in_flg_list = [self.LOS_IN0_FLG, self.LOS_IN1_FLG, self.LOS_IN2_FLG, self.LOS_IN3_FLG]
+        # register_address = self.LOS_OOF_ALARMS_FLG
+        # (status1, value) = self.read_pagined_register(register_address)
+        # value = value & ~(1<<los_in_flg_list[num_input])
+        # status2 = self.write_pagined_register(register_address, value)
+        # status = 0
+        # if (status1 == -1) or (status2 == -1):
+        #     status = -1
+        return status
+
+
+
+
+
+    def clear_oof_flg_bit(self, num_input):
+        """clear the sticky bit OOF_FLG of num_input given in argument
+           (sticky bit of out of frequency OOF)
+        Args:
+          num_input(int) : number of the input 0 to 3  
+
+        Returns:
+          status (int) : 0 if successfull, -1 if error
+
+        Notes:
+          to clear OOF_FLG bit:
+            -- read LOS_OOF_ALARMS_FLG register
+            -- in value_read, clear only the bit: 
+                --4 (OOF_IN0_FLG) if num_input = 0
+                --5 (OOF_IN1_FLG) if num_input = 1
+                --6 (OOF_IN2_FLG) if num_input = 2
+                --7 (OOF_IN3_FLG) if num_input = 3
+            -- write the result in LOS_OOF_ALARMS_FLG register
+        """
+        if num_input > 3:
+            num_input = 3  
+            print "wrong input number"       
+        oof_in_flg_list = [self.OOF_IN0_FLG, self.OOF_IN1_FLG, self.OOF_IN2_FLG, self.OOF_IN3_FLG]
+        register_address = self.LOS_OOF_ALARMS_FLG     
+        (status1, value) = self.read_pagined_register(register_address)
+        value = value & ~(1<<oof_in_flg_list[num_input])
+        status2 = self.write_pagined_register(register_address, value)
+        status = 0
+        if (status1 == -1) or (status2 == -1):
+            status = -1
+        return status
+
+    def clear_los_oof_flg_reg(self):
+        dic ={}
+        # Read raised flags
+        status, current_alarms = self.read_pagined_register(self.LOS_OOF_ALARMS)
+        # Read enabled alarms
+        status, enabled_alarms = self.read_pagined_register(self.LOS_ENABLE)
+        # Disable all alarms with raised flags
+        status = self.write_pagined_register(self.LOS_ENABLE, enabled_alarms & ~(current_alarms & 0xF))
+        # Clear sticky bits
+        status = self.write_pagined_register(self.LOS_OOF_ALARMS_FLG, 0x00)
+        # Re-enable alarms with a raised flag
+        status = self.write_pagined_register(self.LOS_ENABLE, enabled_alarms | (current_alarms & 0xF))
+        dic["1_los_oof_alarms : "] = str(hex(current_alarms))
+        dic["2_enabled alarms: "] = str(hex(enabled_alarms))
+        dic["3_disable raised alarms : "] = str(hex(enabled_alarms & ~(current_alarms & 0xF)))
+        dic["4_restored enabled : "] = str(hex(enabled_alarms | (current_alarms & 0xF)))
+        return dic
+
+    def dump_registers(self):
+        print "===== Dumping registers ====="
+        for register_address in (0xC, 0xD, 0xE, 0xF, 0x12, 0x13, 0x2C, 0x536, 0x52A):
+            (status, value) = self.read_pagined_register(register_address)
+            print "Address = ",hex(register_address),", Value = ", hex(value)
+
+    def program_with_file(self, filename, device):
+        """programs the targeted device with a file
+
+        Args:
+            filename: name of the file
+            device : name of the device (SI5345_U23, SI5345_U48 or SI5344_U54)
+
+        """
+
+        print "..... Configuration file is ", filename
+        (status, part_number) = self.read_part_number()
+        print "..... Part number detected is : ", hex(part_number)
+        print "..... Programming device"
+        self.si534x_programming(filename)
+
+
+
+    def test(self, filename, device, port):
+        """hardtest() only for local debug
+        Notes:
+           to launch hardtest from the current directorie (FC0/devices_lli/components)
+           enter "./si534x_comp.py dev"
+        """
+        print "..... Hard resetting PLL"
+        self.hard_reset()
+        print "..... Configuration file is ",filename
+        (status, part_number) = self.read_part_number()
+        print "..... Part number detected is : ",hex(part_number)
+        print "===== Programming device"
+        self.si534x_programming(filename)
+        time.sleep(1.0)  # wait 1 second to allow frequency measurement to stabilize
+        fpga = Arria10(0)
+        start = time.time()
+        store = fpga.read_pll_port_frequency(device, 0)[1]
+        print "..... Clearing LOL_Flag"
+        self. clear_lol_flg_bit()
+        print "..... Clearing Cal_busy_Flag"
+        self.write_pagined_register(0x14, 0x00)
+        while time.time() - start < 10 :
+            if fpga.read_pll_port_frequency(device, 0)[1] != store:
+                end = time.time()
+                (status, value) = self.read_pagined_register(0x14)
+                print "..... Cal busy =", hex(value),
+                (status, loss_of_lock) = self.read_loss_of_lock()
+                print ", LOL =",loss_of_lock,
+                (status, loss_of_lock_flg) = self.read_loss_of_lock_flg()
+                print ", LOL_flag =", loss_of_lock_flg,
+                (status, value) = self.read_pagined_register(0xC)
+                print ", Reg", hex(0xC), "=", hex(value),
+                for port_number in port:
+                    print "|",fpga.read_pll_port_frequency(device, port_number)[1],
+                print "|Time =", end - start
+                store = fpga.read_pll_port_frequency(device, 0)[1]
+        print "..... Output status :"
+        (status, free_run_mode) = self.read_free_run_mode()
+        print ".....   Free run mode is : ", free_run_mode
+        (status) = self.clear_lol_flg_bit()  			# clears lol flag
+        (status, loss_of_lock) = self.read_loss_of_lock()	# read lol flag
+        print ".....   Loss of lock flag is ",loss_of_lock
+        print "..... Input status :"
+        for input in range(0, 4):
+            (status, loss_of_signal)   = self.read_loss_of_signal(input)
+            print ".....   pll input :", input, " loss of lock is     : ", loss_of_signal
+            (status, out_of_frequency) = self.read_out_of_frequency(input)
+            print ".....   pll input :", input," out of frequency is : ",out_of_frequency
+        #self.dump_registers()
+
+
+        return 0
+
+
+def main(device):
+    """ Main function
+    instanciation of Class Si534x()
+    execute hard test for all 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]
+        }
+    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"
+        }
+
+    dev = device		# Creates a list of objects with the 3 PLLs
+    add = 0x68
+    pll = [Si534x(dev, bus, add) for bus in devices.keys()]
+
+    for i in devices.keys():	# Tests the 3 PLLs
+        print "=========== Testing PLL ", devices[i], "============"
+        pll[i-1].test(files[i], devices[i], ports[i])  # i-1 because list index starts with 0
+        # pll[i-1].clear_lol_flg_bit()
+        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
+
+
+
+if __name__ == "__main__":
+    if (len(sys.argv) > 1):
+        main(int(sys.argv[1]))
+    else :
+        main(0)
-- 
GitLab