From 0a01ae8fa73ebfc5ec3fb3a8af70a782108d1412 Mon Sep 17 00:00:00 2001
From: kruger <kruger@astron.nl>
Date: Wed, 13 Jan 2021 11:17:09 +0100
Subject: [PATCH] Added RCU ID+version

---
 i2c/I2C_dummy.py |  3 ++-
 pcctypes.py      |  1 +
 rcu/HWconf.py    |  3 +++
 rcu/RCU.py       | 59 +++++++++++++++++++++++++++++++++++-------------
 rcu/Vars.py      | 10 +++++++-
 5 files changed, 58 insertions(+), 18 deletions(-)

diff --git a/i2c/I2C_dummy.py b/i2c/I2C_dummy.py
index 09214ba..63000d0 100644
--- a/i2c/I2C_dummy.py
+++ b/i2c/I2C_dummy.py
@@ -9,6 +9,7 @@ import logging
 I2Ccounter=0;
 def I2C1server(addr,data,reg=None,read=0):
        global I2Ccounter;
+       logging.debug(str(("I2C",addr,reg,data,read)))
        if read==3:
            time.sleep(data[0]/1000.)
            return True
@@ -16,5 +17,5 @@ def I2C1server(addr,data,reg=None,read=0):
            data[0]=0
        if reg: I2Ccounter+=1;
        I2Ccounter+=len(data)
-       logging.debug(str(("I2C",addr,reg,data,read)))
+#       logging.debug(str(("I2C",addr,reg,data,read)))
        return True
diff --git a/pcctypes.py b/pcctypes.py
index 02b266a..1450ec4 100644
--- a/pcctypes.py
+++ b/pcctypes.py
@@ -45,6 +45,7 @@ class RW(Enum):
 class datatype(Enum):
    dInt = 0
    dfloat = 1
+   dstring = 2
 
 #Variable two device link
 Var2dev=namedtuple("Var2dev","name module type devreg width bitoffset Scale")
diff --git a/rcu/HWconf.py b/rcu/HWconf.py
index ebb642c..30ffd75 100644
--- a/rcu/HWconf.py
+++ b/rcu/HWconf.py
@@ -45,6 +45,9 @@ RCU_HBA2=DevReg(0x42,0,0,2)
 RCU_HBA3=DevReg(0x43,0,0,3)
 
 
+RCU_ROM_ID =DevReg(0x50,0,0,0) #32 bit ID=4 bytes
+RCU_ROM_Ver=DevReg(0x50,4,4,0) #String
+
 #Bitbang devices
 #BBdev=namedtuple("BBdev","nPins devs pins addr")
 I2CBB_dth3=BBdev(3,[RCU_IO1_OUT1,RCU_IO2_OUT2,RCU_IO2_CONF2],[6,3,3],0x70); #SCL,SDIO,SDIOdir
diff --git a/rcu/RCU.py b/rcu/RCU.py
index 248790c..b8eea88 100644
--- a/rcu/RCU.py
+++ b/rcu/RCU.py
@@ -30,6 +30,19 @@ def int2bytes(i):
         i>>=8;
    return [i]+b;
 
+def strs2bytes(var):
+#    print("str2bytes",var)
+    if len(var)==0: return var;
+    if isinstance(var[0],str): #make string a byte array
+            return [c.encode('ascii')[0] for s in var for c in s]
+    return var
+
+def bytes2strs(var,step,dtype):
+    if not(dtype==Vars.datatype.dstring): return var
+    cnt=int(len(var)/step)
+    print(var)
+    return [(bytes(var[i*step:(i+1)*step]).decode("ascii")) for i in range(cnt)]
+
 class RCU1():
     def __init__(self,number,I2Ccallback,Switchcallback):
         self.N=number;
@@ -61,6 +74,7 @@ class RCU1():
 #print(Vars.RCU)
 
     def SetVar(self,Instr,Mask=[]):
+#        Instr.value=strs2bytes(Instr.value) #Alwast be an array of bytes
         if Instr.type==Vars.DevType.Instr:
               #Execute instructions
               Iset=Instr.dev;
@@ -81,18 +95,18 @@ class RCU1():
             self.SWcallback(mask)
             if Instr.type==Vars.DevType.I2C:
               logging.info(str(('** Set I2C:',Instr.dev,Instr.value)))
-              self.SetI2C(RCU0,Instr.dev,8,0,Instr.value)
+              self.SetI2C(RCU0,Instr.dev,8,0,strs2bytes(Instr.value))
               return;
             elif Instr.type==Vars.DevType.SPIbb:
               logging.debug(str(('** Set SPIbb:',Instr.dev,Instr.value)))
-              SetSPIbb(self.SetI2C,RCU0,Instr.dev,Instr.value)
+              SetSPIbb(self.SetI2C,RCU0,Instr.dev,strs2bytes(Instr.value))
               return;
             elif Instr.type==Vars.DevType.I2Cbb:
               logging.info(str(('** Set I2Cbb:',Instr.dev,Instr.value)))
-#              self.SetI2C(RCUi,Instr.dev,8,0,Instr.value)
+#              self.SetI2C(RCUi,Instr.dev,8,0,strs2bytes(Instr.value))
               return;
         V1=Instr.dev
-        if not((Instr.nvalue==V1.nVars) and (Instr.type==Vars.DevType.VarUpdate)) and not(Instr.nvalue==V1.nVars*self.N):
+        if not((Instr.nvalue==V1.nVars) and (Instr.type==Vars.DevType.VarUpdate)) and not(Instr.nvalue==V1.size*self.N):
              logging.error("Wrong size of value")
              return False
         if V1.Vars[0].type==Vars.DevType.Internal:
@@ -101,24 +115,27 @@ class RCU1():
           return
 #        if V1.Vars[0].type==Vars.DevType.Internal: return;
         Step=V1.nVars
+        Step2=int(V1.size/V1.nVars)
         Mask=(Vars.RCU_mask if Step==1 else Vars.Ant_mask)
         Mask=Mask.OPCW.get_data_value().Value.Value
-        value1=Instr.value if V1.OPCR is None else V1.OPCR.get_data_value().Value.Value
+        value1=strs2bytes(Instr.value) if V1.OPCR is None else strs2bytes(V1.OPCR.get_data_value().Value.Value)
         if (len(value1)==V1.nVars) and (self.N>1):  value1=(value1*self.N);
         if Instr.type==Vars.DevType.Var:
           logging.info(str(('** Set Var:',V1.name,value1)))
           for RCUi in range(self.N):
             for Vari in range(Step):
                 if not(Mask[RCUi*Step+Vari]): continue
-                self.SetVarValue(RCUi,V1.Vars[Vari],Instr.value[RCUi*Step+Vari:RCUi*Step+Vari+1])
-                value2=value1[RCUi*Step+Vari:RCUi*Step+Vari+1]
+                i0=(RCUi*Step+    Vari)*Step2
+                i1=(RCUi*Step+(Vari+1))*Step2
+                self.SetVarValue(RCUi,V1.Vars[Vari],Instr.value[i0:i1])
+                value2=value1[i0:i1]
                 self.GetVarValue(RCUi,V1.Vars[Vari],value2)
-                value1[RCUi*Step+Vari:RCUi*Step+Vari+1]=value2
-          if not(V1.OPCR is None): V1.OPCR.get_data_value().Value.Value=value1
+                value1[i0:i1]=value2
+          if not(V1.OPCR is None): V1.OPCR.get_data_value().Value.Value=bytes2strs(value1,Step2,V1.type)
 
         elif Instr.type==Vars.DevType.VarUpdate:
           self.GetVarValueAll(V1,value1)
-          if not(V1.OPCR is None): V1.OPCR.get_data_value().Value.Value=value1
+          if not(V1.OPCR is None): V1.OPCR.get_data_value().Value.Value=bytes2strs(value1,Step2,V1.type)
 #          V1.OPCR.get_data_value().Value.Value=value1
 
         logging.info(str(('** Readback:',V1.name,value1)))
@@ -140,6 +157,7 @@ class RCU1():
             for RCUi in range(self.N):
                 mask|=1<<Vars.RCU_MPaddr.Switch[RCUi]
             Step=V1.nVars
+            Step2=int(V1.size/V1.nVars)
             if V1.Vars[0].type==Vars.DevType.I2C:
               for Vari in range(Step):  
                 DevReg=V1.Vars[Vari].devreg
@@ -148,11 +166,14 @@ class RCU1():
                 if DevReg.Register_R>255: self.I2Ccallback(DevReg.Addr,[250],read=3) #Wait for ADC
                 for RCUi in range(self.N):
                     self.SWcallback(1<<Vars.RCU_MPaddr.Switch[RCUi])
-                    value2=value1[RCUi*Step+Vari:RCUi*Step+Vari+1]
+                    i0=(RCUi*Step+    Vari)*Step2
+                    i1=(RCUi*Step+(Vari+1))*Step2
+                    value2=value1[i0:i1]
                     var=V1.Vars[Vari]
+#                    print(Step,Step2,i0,i1,value2,len(value1))
                     self.GetI2Cnoreg(RCUi,var.devreg,var.width,var.bitoffset,value2)
                     if (var.Scale!=0): value2[0]*=var.Scale;
-                    value1[RCUi*Step+Vari:RCUi*Step+Vari+1]=value2
+                    value1[i0:i1]=value2
             elif V1.Vars[0].type==Vars.DevType.SPIbb:
               self.GetBBValueAll(V1,value1,mask)
 #              logging.info("SPIbb all not implemented yet")
@@ -287,16 +308,22 @@ class RCU1():
          Inst1=Vars.Instr(Vars.DevType.VarUpdate,Vars.RCU_ADC_lock,96,[0]*96)
          Q1.put(Inst1)
 
-
     def AddVars(self,Q1,AddVarR,AddVarW):
      for v in Vars.OPC_devvars:
-        dim=Vars.RCU_MPaddr.nI2C*Vars.RCU_MPaddr.nSwitch*v.size
+        dim1=Vars.RCU_MPaddr.nI2C*Vars.RCU_MPaddr.nSwitch*v.nVars
+        dim2=Vars.RCU_MPaddr.nI2C*Vars.RCU_MPaddr.nSwitch*v.size
+        dim3=int(v.size/v.nVars)
         #print(v.name,dim)
-        varvalue2=(dim*[0.0] if v.type==Vars.datatype.dfloat else dim*[0])
+        varvalue2=0
+        if   v.type==Vars.datatype.dInt:    varvalue2=dim2*[0]
+        elif v.type==Vars.datatype.dfloat:  varvalue2=dim2*[0.0] 
+        elif v.type==Vars.datatype.dstring: varvalue2=dim1*[" "*dim3]
+        print(len(varvalue2),varvalue2)
         if v.RW in [Vars.RW.ReadOnly,Vars.RW.ReadWrite]:
             var1=AddVarR(v.name+"_R",varvalue2,v)
+#            print(len(varvalue1),len(varvalue2),v.size,dim2)
             v.OPCR=var1
-            Inst=Vars.Instr(Vars.DevType.VarUpdate,v,dim,varvalue2)
+            Inst=Vars.Instr(Vars.DevType.VarUpdate,v,dim2,varvalue2)
             Q1.put(Inst)
 
         if v.RW in [Vars.RW.WriteOnly,Vars.RW.ReadWrite]:
diff --git a/rcu/Vars.py b/rcu/Vars.py
index 8b3877c..94dc921 100644
--- a/rcu/Vars.py
+++ b/rcu/Vars.py
@@ -44,6 +44,14 @@ HBA3_Pwr  =Var2dev("",RCUmod,DevType.HBA1,RCU_HBA3,1,1,1)
 HBA1_Delay=VarArray("HBA_element_beamformer_delays",3,[HBA1_Delay,HBA2_Delay,HBA3_Delay],RW.ReadWrite,datatype.dInt,96,None,None)
 HBA1_Pwr  =VarArray("HBA_element_pwr"  ,3,[HBA1_Pwr  ,HBA2_Pwr  ,HBA3_Pwr  ],RW.ReadWrite,datatype.dInt,96,None,None)
 
+#RCU_ID0=Var2dev("",RCUmod,DevType.I2C,RCU_ROM,8,0,1)
+#RCU_ID=VarArray("RCU_ID",1,[RCU_ID0],RW.ReadOnly,datatype.dInt,4,None,None)
+
+RCU_ID0=Var2dev("",RCUmod,DevType.I2C,RCU_ROM_ID,32,0,1)
+RCU_ID=VarArray("RCU_ID",1,[RCU_ID0],RW.ReadOnly,datatype.dInt,1,None,None)
+RCU_Ver0=Var2dev("",RCUmod,DevType.I2C,RCU_ROM_Ver,32,0,1)
+RCU_VER=VarArray("RCU_version",1,[RCU_ID0],RW.ReadOnly,datatype.dstring,10,None,None)
+
 
 RCU_ADC1_lock=Var2dev("RCU_ADC1_lock",RCUmod,DevType.SPIbb,RCU_ADC1_PLL_stat,8,0,1)
 RCU_ADC2_lock=Var2dev("RCU_ADC2_lock",RCUmod,DevType.SPIbb,RCU_ADC2_PLL_stat,8,0,1)
@@ -89,7 +97,7 @@ RCU_OUT2=VarArray("RCU_OUT2",3,[RCU_IO1_2,RCU_IO2_2,RCU_IO3_2],RW.ReadOnly,datat
 
 
 
-OPC_devvars=[RCU_mask,Ant_mask,RCU_att,RCU_band,RCU_temp,RCU_pwrd,RCU_LED,RCU_ADC_lock,RCU_ADC_SYNC,RCU_ADC_JESD,RCU_ADC_CML,RCU_OUT1,RCU_OUT2,HBA1_Delay,HBA1_Pwr]#,RCU_CNF1,RCU_CNF2]
+OPC_devvars=[RCU_mask,Ant_mask,RCU_att,RCU_band,RCU_temp,RCU_pwrd,RCU_LED,RCU_ADC_lock,RCU_ADC_SYNC,RCU_ADC_JESD,RCU_ADC_CML,RCU_OUT1,RCU_OUT2,RCU_ID,RCU_VER]#,HBA1_Delay,HBA1_Pwr]#,RCU_CNF1,RCU_CNF2]
 
 
 
-- 
GitLab