From c6176f9e0734f7d531ae05e42665fbcc8b4cb8dd Mon Sep 17 00:00:00 2001
From: Paulus <kruger@astron.nl>
Date: Thu, 23 Sep 2021 10:29:11 +0100
Subject: [PATCH] Working RCU2L QM on LTS

---
 config/RCU.yaml         | 299 +++++++++++++++++++++++++++++++++++-----
 i2cserv/i2c_array.py    |   1 -
 i2cserv/i2cbitbang1.py  |   4 +-
 opcuaserv/yamlreader.py |   7 +-
 scripts/ADCreset.py     |   4 +-
 scripts/Ant_Pwr.py      |  25 ++++
 scripts/Att.py          |   7 +-
 scripts/Band.py         |   4 +-
 scripts/DTH_test.py     |  23 ++++
 scripts/SetMonitor.py   |   2 +-
 scripts/Startup.py.old  |  50 +++++++
 scripts/test_common.py  |   7 +
 12 files changed, 390 insertions(+), 43 deletions(-)
 create mode 100644 scripts/Ant_Pwr.py
 create mode 100644 scripts/DTH_test.py
 create mode 100644 scripts/Startup.py.old

diff --git a/config/RCU.yaml b/config/RCU.yaml
index 84d2d70..7e70e59 100644
--- a/config/RCU.yaml
+++ b/config/RCU.yaml
@@ -9,7 +9,7 @@ drivers:
  - name: I2C_RCU 
    type: i2c_array #An array of similar devices connected to an I2C switch
    parent: I2C1
-   parameters: [0,31,5] #start,number of RCUs, error count to disable I2C
+   parameters: [0,31,14] #start,number of RCUs, error count to disable I2C
    status: RCU_I2C_STATUS
  - name: I2C_HBAT
    type: hba1 #Special driver to manage HBAT1s.
@@ -18,18 +18,18 @@ drivers:
    parameters: [15] #PPS GPIO pin
  - name: I2Cbb1 
    type: i2cbitbang1 #I2C bitbang via GPIO expander
-   devreg: [IO1.GPIO1,IO2.GPIO2,IO2.CONF2]
-   parameters: [6,3,3] #pins
+   devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2]
+   parameters: [5,6,6] #pins
    parent: I2C_RCU
  - name: I2Cbb2
    type: i2cbitbang1
-   devreg: [IO1.GPIO2,IO2.GPIO1,IO1.CONF1]
-   parameters: [7,7,7]
+   devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2]
+   parameters: [4,6,6]
    parent: I2C_RCU
  - name: I2Cbb3
    type: i2cbitbang1
-   devreg: [IO1.GPIO2,IO2.GPIO1,IO1.CONF1]
-   parameters: [7,7,7]
+   devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2]
+   parameters: [3,6,6]
    parent: I2C_RCU
  - name: SPIbb1 
    type: spibitbang1 #SPI bitbang via GPIO expander: CLK, SDIO, SDIOdir,CS
@@ -92,7 +92,7 @@ device_registers:
  
  - name: AN
    description: Monitor ADC on RCU
-   address: 0x14
+   address: 0x74 #was 0x14 on RCU2-DIG PCBs
    device: LTC2495
    driver: I2C1
    registers:
@@ -108,10 +108,18 @@ device_registers:
      address: 0xB280
    - name: I_Ant2
      address: 0xBA80
-   - name: V_Ant0
+   - name: V_Ant_I0
      address: 0xB380
-   - name: V_Ant1
+   - name: V_Ant_O0
      address: 0xBB80
+   - name: V_Ant_I1
+     address: 0xB480
+   - name: V_Ant_O1
+     address: 0xBC80
+   - name: V_Ant_I2
+     address: 0xB580
+   - name: V_Ant_O2
+     address: 0xBD80
    - name: Temp
      address: 0xA0C0
 
@@ -178,16 +186,24 @@ device_registers:
    registers:
     - name: Freq
       description: Frequency
-      address: [0x1140,0x1141]
+      address: [0x1240,0x1140]
     - name: Property
       description: Properties
-      address: [0x11,0x11]
+      address: [0x12,0x11]
+    - name: State
+      address: [0x61,0x60]
     - name: Start
       description: Start CW
       address: [0x62,0x62]
     - name: Stop
       description: Stop CW
       address: [0x67,0x67]
+    - name: Rev
+      address: 0x10
+    - name: Tune
+      address: [0x1221,0x1121]
+    - name: CONF
+      address: [0x1210,0x1110]
 
 variables:
    - name: Ant_mask
@@ -230,7 +246,7 @@ variables:
      driver: I2C_RCU
      devreg:  [IO1.GPIO1,IO1.GPIO2,IO2.GPIO1]
      bitoffset: [0,0,0]
-     width: 5
+     width: 6
      rw:  rw
      dtype: uint8
      dim: 96
@@ -291,8 +307,73 @@ variables:
      monitor: true
      mask: RCU_I2C_STATUS
 
-   - name: RCU_Pwr_dig
-     description: Enable LDOs
+   - name: RCU_3V3
+     driver: I2C_RCU
+     devreg:  AN.V_3v3
+     width: 23
+     scale: 1.463e-6
+     rw:  ro
+     dtype: double
+     dim: 32
+     monitor: true
+     mask: RCU_I2C_STATUS
+
+   - name: RCU_1V8
+     driver: I2C_RCU
+     devreg:  AN.V_1v8
+     width: 23
+     scale: 7.1526e-7
+     rw:  ro
+     dtype: double
+     dim: 32
+     monitor: true
+     mask: RCU_I2C_STATUS
+
+   - name: RCU_2V5
+     driver: I2C_RCU
+     devreg:  AN.V_2v5
+     width: 23
+     scale: 7.1526e-7
+     rw:  ro
+     dtype: double
+     dim: 32
+     monitor: true
+     mask: RCU_I2C_STATUS
+
+   - name: RCU_V_ANT
+     driver: I2C_RCU
+     devreg:  [AN.V_Ant_O0,AN.V_Ant_O1,AN.V_Ant_O2]
+     width: 23
+     scale: 2.7895e-6
+     rw:  ro
+     dtype: double
+     dim: 96
+     monitor: true
+     mask: RCU_I2C_STATUS
+
+   - name: ANT_V
+     driver: I2C_RCU
+     devreg:  [AN.V_Ant_I0,AN.V_Ant_I1,AN.V_Ant_I2]
+     width: 23
+     scale: 2.7895e-6
+     rw:  ro
+     dtype: double
+     dim: 96
+     monitor: true
+     mask: RCU_I2C_STATUS
+
+   - name: ANT_I
+     driver: I2C_RCU
+     devreg:  [AN.I_Ant0,AN.I_Ant1,AN.I_Ant2]
+     width: 23
+     scale: 7.1526e-8
+     rw:  ro
+     dtype: double
+     dim: 96
+     monitor: true
+     mask: RCU_I2C_STATUS
+
+   - name: RCU_PWR_DIGITAL_ON
      driver: I2C_RCU
      devreg:  IO2.GPIO1
      width: 1
@@ -302,6 +383,47 @@ variables:
      dim: 32
      mask: RCU_mask
 
+   - name: RCU_PWR_GOOD
+     driver: I2C_RCU
+     devreg:  IO2.GPIO1
+     width: 1
+     bitoffset: 7
+     rw:  ro
+     dtype: boolean
+     dim: 32
+     monitor: true
+     mask: RCU_I2C_STATUS
+
+   - name: RCU_PWR_ANALOG_ON
+     driver: I2C_RCU
+     devreg:  IO1.GPIO2
+     width: 1
+     bitoffset: 7
+     rw:  ro
+     dtype: boolean
+     dim: 32
+     mask: RCU_mask
+
+   - name: RCU_DTH_SHUTDOWN
+     driver: I2C_RCU
+     devreg:  [IO3.GPIO1,IO3.GPIO1,IO3.GPIO2]
+     width: 1
+     bitoffset: [7,6,7]
+     rw:  ro
+     dtype: boolean
+     dim: 96
+     mask: ANT_mask
+
+   - name: ANT_PWR_ON
+     driver: I2C_RCU
+     devreg:  [IO1.GPIO1,IO1.GPIO1,IO1.GPIO2]
+     width: 1
+     bitoffset: [6,7,6]
+     rw:  rw
+     dtype: boolean
+     dim: 96
+     mask: Ant_mask
+
    - name: HBA_element_beamformer_delays
      description: Delays of each frontend
      driver: I2C_HBAT
@@ -366,14 +488,72 @@ variables:
      dim: 96
      debug: true
 
-#   - name: RCU_dth1_freq
-#     driver: I2C_RCU
-#     devreg:  [DTH1.Freq,DTH2.Freq,DTH3.Freq]
-#     width: 32
-#     rw:  rw
-#     dtype: uint32
-#     dim: 96
-#     mask: Ant_mask
+   - name: RCU_ADC_JESD
+     driver: I2C_RCU
+     devreg:  [ADC1.JESD_control1,ADC2.JESD_control1,ADC3.JESD_control1]
+     width: 8
+     rw:  ro
+     dtype: uint8
+     dim: 96
+     debug: true
+
+   - name: RCU_ADC_CML_level
+     driver: I2C_RCU
+     devreg:  [ADC1.CML_level,ADC2.CML_level,ADC3.CML_level]
+     width: 8
+     rw:  ro
+     dtype: uint8
+     dim: 96
+     debug: true
+
+   - name: RCU_DTH_freq
+     driver: I2C_RCU
+     devreg:  [DTH1.Freq,DTH2.Freq,DTH3.Freq]
+     width: 32
+     rw:  rw
+     dtype: uint32
+     dim: 96
+     mask: Ant_mask
+
+   - name: RCU_DTH_tune
+     driver: I2C_RCU
+     devreg:  [DTH1.Tune,DTH2.Tune,DTH3.Tune]
+     width: 16
+     rw:  rw
+     dtype: uint32
+     dim: 96
+     mask: Ant_mask
+     debug: true
+
+   - name: RCU_DTH_config
+     driver: I2C_RCU
+     devreg:  [DTH1.CONF,DTH2.CONF,DTH3.CONF]
+     width: 8
+     rw:  rw
+     dtype: uint32
+     dim: 96
+     mask: Ant_mask
+     debug: true
+
+   - name: RCU_DTH_ON
+     driver: I2C_RCU
+     devreg:  [DTH1.State,DTH2.State,DTH3.State]
+     width: 1 #read only first of 2 bytes
+     bitoffset: [1,1,1]
+     rw:  ro
+     dtype: boolean
+     dim: 96
+     mask: Ant_mask
+
+   - name: RCU_DTH_Rev
+     driver: I2C_RCU
+     devreg:  [DTH1.Rev,DTH2.Rev,DTH3.Rev]
+     width: 88
+     rw:  rw
+     dtype: uint32
+     dim: 96
+     mask: Ant_mask
+     debug: true
 
 methods:
   - name: RCU_Init #Called after startup to load. Should have all stored registers  
@@ -399,13 +579,13 @@ methods:
     mask: RCU_mask
     instructions:
      - RCU_I2C_STATUS: 0
-     - IO2.CONF1: 0    #Set device register, can also specify a register adress direction e.g. OIO2.0: 0
-     - IO2.GPIO1: 0x4A
-     - IO2.GPIO2: 0x55
-     - IO3.GPIO1: 0x15
-     - IO3.GPIO2: 0x47
-     - IO1.GPIO1: 0xCA
-     - IO1.GPIO2: 0xCA
+     - IO2.CONF1: 0x80 #Pgood on 0x80
+     - IO2.GPIO1: 0x4A #0x40 Dig on, 0x0a =10dB att
+     - IO2.GPIO2: 0x55 #0x15 #Band0 (or 0x2a band 1)  #LEDS=on=low
+     - IO3.GPIO1: 0x15 #ADC_SDIO=high, clk=low, DTH_EN=low
+     - IO3.GPIO2: 0x47 #ADC SC=high, DTH_SDA=high
+     - IO1.GPIO1: 0x0A #0x0a = 10dB att
+     - IO1.GPIO2: 0x8A #0x80 Analog on, 0x0a=10dB att
      - IO2.CONF2: 0
      - IO3.CONF1: 0
      - IO3.CONF2: 0
@@ -426,15 +606,20 @@ methods:
     mask: RCU_mask
     debug: True
     instructions:
-      - RCU_Pwr_dig: Update  #Read value and update the OPC-UA variable
+      - RCU_PWR_DIGITAL_ON: Update  #Read value and update the OPC-UA variable
+      - RCU_PWR_ANALOG_ON: Update 
+      - ANT_PWR_ON: Update 
       - RCU_ID: Update
       - RCU_version: Update
       - RCU_LED0: Update
+      - RCU_LED1: Update
       - RCU_attenuator: Update
       - RCU_band: Update
       - RCU_ADC_lock: Update
       - RCU_ADC_sync: Update
-
+      - RCU_DTH_SHUTDOWN: Update
+      - RCU_DTH_freq: Update
+      - RCU_DTH_ON: Update
 
   - name: ADC1_on
     driver: I2C_RCU
@@ -471,7 +656,8 @@ methods:
     mask: RCU_mask
     instructions:
      - RCU_I2C_STATUS: 0
-     - RCU_Pwr_dig: 0 #Switch power off
+     - RCU_PWR_ANALOG_ON: 0 #Switch power off
+     - RCU_PWR_DIGITAL_ON: 0 #Switch power off
      - IO2.GPIO1: 0
      - IO2.GPIO2: 0
      - IO3.GPIO1: 0
@@ -490,3 +676,50 @@ methods:
      - HB_UC_update.wait_pps : 1
      - RCU_state: 1
 
+
+  - name: DTH_on
+    driver: I2C_RCU
+    debug: True
+    mask: RCU_mask
+#    rw: hidden
+    instructions:
+#     - RCU_DTH_SHUTDOWN : 0
+     - RCU_DTH_config : [0,0,0]
+#     - RCU_DTH_tune :   [0,0,0,0,0,0]
+#     - DTH1.CONF : 0 
+#     - DTH1.Tune :    [0,0] #no tuning
+#     - WAIT: 10
+#     - DTH1.Start :    [1,0,0,0,1,0x55]
+     - DTH1.Start :    [0,1,0,0,1]
+#     - DTH1.0x60: #PA_config...
+#     - DTH2.CONF : 0 
+#     - WAIT: 10
+#     - DTH2.Tune :    [0,0] #no tuning
+#     - WAIT: 10
+     - DTH2.Start :    [0,1,0,0,1]
+#     - DTH3.CONF : 0
+#     - WAIT: 10
+#     - DTH3.Tune :    [0,0] #no tuning
+#     - WAIT: 10
+     - DTH3.Start :    [0,1,0,0,1]
+     - RCU_DTH_ON : Update
+     - RCU_DTH_config: Update #debug
+     - RCU_DTH_tune: Update #debug
+
+  - name: DTH_off
+    driver: I2C_RCU
+    debug: True
+    mask: RCU_mask
+#    rw: hidden
+    instructions:
+#     - RCU_DTH_SHUTDOWN : [1,1,1]
+#     - WAIT: 100
+#     - RCU_DTH_SHUTDOWN : [0,0,0]
+#     - RCU_DTH_SHUTDOWN : 1
+     - DTH1.Stop :    [0,0]
+     - DTH2.Stop :    [0,0]
+     - DTH3.Stop :    [0,0]
+#     - DTH1.State :    [0,0]
+#     - DTH2.State :    [0,0]
+#     - DTH3.State :    [0,0]
+     - RCU_DTH_ON: Update
diff --git a/i2cserv/i2c_array.py b/i2cserv/i2c_array.py
index 41c4d88..a2177c9 100644
--- a/i2cserv/i2c_array.py
+++ b/i2cserv/i2c_array.py
@@ -25,7 +25,6 @@ class i2c_array(i2c_dev):
         self.N=len(self.RCU_Switch1);
         self.I2Cmask=[0]*self.N
         self.I2Ccut=pars[2];
-        print("I2Ccut=",pars[2])
         self.disableI2ConError=pars[2]>0;
 #        self.devregs,RCU_storeReg=DevRegList(yaml)
 #        print("Init",config['name'],'len=',len(self.RCU_Switch1),' stored reg=',RCU_storeReg)
diff --git a/i2cserv/i2cbitbang1.py b/i2cserv/i2cbitbang1.py
index ea1adfe..5d94cad 100644
--- a/i2cserv/i2cbitbang1.py
+++ b/i2cserv/i2cbitbang1.py
@@ -19,7 +19,8 @@ class i2cbitbang1(hwdev):
        if not(reg is None): 
             if reg>255: data=[reg//256,reg%256]+data;
             else:       data=[reg]+data;
-       return self.SetI2Cbb(addr,data)
+       if not(self.SetI2Cbb(addr,data)): return False;
+       return self.GetI2Cbb(addr,[]);
     if read==2: return self.SetI2Cbb(addr,data)
     elif read==1: 
        if not(reg is None): 
@@ -134,6 +135,7 @@ class i2cbitbang1(hwdev):
  
         TXbyte(ADC_address);
         print("si status:",hex(RXbyte()))#should be 0x80
+#        if not(RXbyte()==0x80): return False;
         for i in range(len(value)):
           value[i]=RXbyte(last=(i==len(value)-1))
         #stop
diff --git a/opcuaserv/yamlreader.py b/opcuaserv/yamlreader.py
index 7582906..1ee0836 100644
--- a/opcuaserv/yamlreader.py
+++ b/opcuaserv/yamlreader.py
@@ -26,6 +26,7 @@ class yamlreader(yamlconfig):
         self.timecount=0;
         self.monitorvarcnt=0;
         self.statusid=self.getvarid(yamlfile+"_translator_busy");
+        self.statusOPC=None
 
     def SetBusy(self):
         if self.statusid is None: return
@@ -219,15 +220,19 @@ class yamlreader(yamlconfig):
         T1=self.monitorvar.get_value()*10;
         if T1<=0: return;
         self.timecount+=1;
+        if self.statusOPC is None: self.statusOPC=self.conf['variables'][self.statusid].get('OPCR')
         while self.timecount>=T1:
-          if self.server.QoutLength()>3: return;
+          if not(self.statusOPC is None) and self.statusOPC.get_value(): return;
+          if self.server.QoutLength()>0: return;
           v=self.conf['variables'][self.monitorvarcnt];
           if v.get('monitor'):
                mask=(v['maskOPC'].get_value() if v.get('maskOPC') else [])
 #               print("monitor",v['name'],mask)
+               self.SetBusy()
                self.server.readvar(self.monitorvarcnt,mask=mask)
           self.monitorvarcnt+=1;
           if self.monitorvarcnt>=len(self.conf['variables']): 
                     self.monitorvarcnt=0;
                     self.timecount=0;              
 
+#        self.OPCset(self.statusid,[1],[])
diff --git a/scripts/ADCreset.py b/scripts/ADCreset.py
index 7cb6d6e..c41cd63 100644
--- a/scripts/ADCreset.py
+++ b/scripts/ADCreset.py
@@ -1,6 +1,6 @@
 from test_common import *
 
-RCUs=[0,1,2,3];
+RCUs=[3];
 setRCUmask(RCUs)
 
 def wait(var1="RCU_translator_busy_R"):
@@ -14,7 +14,7 @@ def wait(var1="RCU_translator_busy_R"):
 callmethod("RCU_off")
 wait()
 #exit()
-#time.sleep(2)
+time.sleep(2)
 callmethod("RCU_on")
 wait()
 #callmethod("RCU_on")
diff --git a/scripts/Ant_Pwr.py b/scripts/Ant_Pwr.py
new file mode 100644
index 0000000..16b71c9
--- /dev/null
+++ b/scripts/Ant_Pwr.py
@@ -0,0 +1,25 @@
+from test_common import *
+
+name="ANT_PWR_ON"
+RCU=[4];
+On=[True,True,True]
+#On=[False,False,False]
+#Att=[10,10,10]
+#RCU=[1,2,3];
+#Att=[0,0,0]
+
+
+setAntmask(RCU)
+
+att=get_value(name+"_R")
+print("Att old:",att[:18])
+for r in RCU:
+  att[3*r:3*r+3]=On
+print("Att set:",att[:18])
+set_value(name+"_RW",att)
+
+time.sleep(0.5)
+att=get_value(name+"_R")
+print("Att new:",att[:18])
+
+disconnect()
\ No newline at end of file
diff --git a/scripts/Att.py b/scripts/Att.py
index 65ca66b..ed75b9d 100644
--- a/scripts/Att.py
+++ b/scripts/Att.py
@@ -1,8 +1,10 @@
 from test_common import *
 
 name="RCU_attenuator"
-RCU=[0];
-Att=[1,1,1]
+RCU=[1];
+Att=[10,10,10]
+#RCU=[1,2,3];
+#Att=[0,0,0]
 
 
 setAntmask(RCU)
@@ -11,6 +13,7 @@ att=get_value(name+"_R")
 print("Att old:",att[:12])
 for r in RCU:
   att[3*r:3*r+3]=Att
+print("Att set:",att[:12])
 set_value(name+"_RW",att)
 
 time.sleep(0.5)
diff --git a/scripts/Band.py b/scripts/Band.py
index c450278..6073f45 100644
--- a/scripts/Band.py
+++ b/scripts/Band.py
@@ -1,8 +1,8 @@
 from test_common import *
 
 name="RCU_band"
-RCU=3;
-Att=[3,3,3]
+RCU=0;
+Att=[2,2,2]
 
 
 setAntmask([RCU])
diff --git a/scripts/DTH_test.py b/scripts/DTH_test.py
new file mode 100644
index 0000000..5091d03
--- /dev/null
+++ b/scripts/DTH_test.py
@@ -0,0 +1,23 @@
+from test_common import *
+
+
+RCU=4;
+setAntmask([RCU])
+setRCUmask([RCU])
+
+if False:
+ name="RCU_DTH_freq"
+ Freq=[102e6,102.1e6,102.2e6]
+# Freq=[0,0,0]
+ att=get_value(name+"_R")
+ print("freq old:",att[3*RCU:3*RCU+3])
+ att[3*RCU:3*RCU+3]=[int(x) for x in Freq]
+ set_value(name+"_RW",att)
+ time.sleep(0.5)
+ att=get_value(name+"_R")
+ print("freq new :",att[3*RCU:3*RCU+3])
+
+call_debug_method("DTH_on")
+#call_debug_method("DTH_off")
+
+disconnect()
\ No newline at end of file
diff --git a/scripts/SetMonitor.py b/scripts/SetMonitor.py
index b303a5a..76f9d2d 100644
--- a/scripts/SetMonitor.py
+++ b/scripts/SetMonitor.py
@@ -1,6 +1,6 @@
 from test_common import *
 
-rate= 10 #seconds
+rate= 0 #seconds
 name="RCU_monitor_rate_RW"
 
 print("old:",get_value(name))
diff --git a/scripts/Startup.py.old b/scripts/Startup.py.old
new file mode 100644
index 0000000..8e2395d
--- /dev/null
+++ b/scripts/Startup.py.old
@@ -0,0 +1,50 @@
+from test_common import *
+
+restart_clk=False;  #False do not restart, but only check status
+restart_rcu=True;  #False do not restart, but only check status
+RCUs=[0,1,2,3];
+#RCUs=[0,1,2,3,4,5,6,7];
+
+if restart_clk: 
+  print("Startup CLK");  
+  callmethod("CLK_off")
+  wait_not_busy("CLK_translator_busy_R")
+  callmethod("CLK_on")
+  wait_not_busy("CLK_translator_busy_R",timeout_sec=2)
+
+print("CLK status:")
+locked=get_value("CLK_PLL_locked_R")
+if locked:
+   print(" CLK working (locked)")
+else: #not locked:
+  i2c_status=get_value("CLK_I2C_STATUS_R");
+  if (i2c_status>0): print(" CLK I2C not working. Maybe power cycle subrack to restart CLK board and translator.")
+  else: print (" CLK not locked! Subrack probably do not receive clock input (or CLK PCB broken)")
+
+setRCUmask(RCUs)
+if restart_rcu: 
+  print("Startup RCUs:",RCUs);  
+  callmethod("RCU_off")
+  wait_not_busy("RCU_translator_busy_R")
+  callmethod("RCU_on")
+  wait_not_busy("RCU_translator_busy_R",timeout_sec=5)
+
+print("RCU status:")
+i2c_status=get_value("RCU_I2C_STATUS_R")
+i2c_working=[];i2c_not_working=[]
+for x in RCUs: (i2c_working.append(x) if i2c_status[x]==0 else i2c_not_working.append(x))
+if len(i2c_not_working)>0:
+  print(" RCUs not availabel",i2c_not_working)
+
+locked=get_value("RCU_ADC_lock_R")
+locklist=[];notlocklist=[]
+for x in i2c_working:
+   if (locked[x*3+0]>0) and (locked[x*3+1]>0) and (locked[x*3+2]>0):
+         locklist.append(x)
+   else: notlocklist.append(x)
+#  (locklist.append(x) if locked[x]>0 else notlocklist.append(x))
+print(" RCUs working",locklist) 
+if len(notlocklist)>0:
+   print(" RCUs with unlocked ADCs:",notlocklist)
+
+disconnect();
diff --git a/scripts/test_common.py b/scripts/test_common.py
index 4ea708f..9ac38c3 100644
--- a/scripts/test_common.py
+++ b/scripts/test_common.py
@@ -70,6 +70,13 @@ def callmethod(name):
           except:
 #            print("error")
             return None
+def call_debug_method(name):
+          try:
+            obj = root.get_child(["0:Objects", "2:PCC","2:DEBUG"])#
+            return obj.call_method("2:"+name)
+          except:
+            print("error")
+            return None
 
 def wait_not_busy(var1,timeout_sec=1):
   for x in range(int(timeout_sec*10)):
-- 
GitLab