From cb6c0105a11d965b4eddbf01bb2afda8b124c055 Mon Sep 17 00:00:00 2001 From: Paulus <kruger@astron.nl> Date: Thu, 22 Apr 2021 01:11:01 +0100 Subject: [PATCH] 1st working version --- config/RCU.yaml | 91 ++++++++++++++++++++++------------------- i2cserv/i2c.py | 16 +++++--- i2cserv/i2c_array.py | 45 ++++++++++++-------- i2cserv/i2c_switch.py | 5 ++- i2cserv/i2cthread.py | 16 ++++++-- i2cserv/spibitbang1.py | 17 +++++--- opcuaserv/yamlreader.py | 2 +- testRCU.py | 26 +++++++++--- yamlconfig.py | 1 + 9 files changed, 137 insertions(+), 82 deletions(-) diff --git a/config/RCU.yaml b/config/RCU.yaml index 338f910..258c543 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: [1,32] #start,number of RCUs + parameters: [0,31] #start,number of RCUs - name: I2C_HBAT type: hba1 #Special driver to manage HBAT1s. parent: I2C_RCU @@ -186,6 +186,13 @@ variables: dtype: boolean dim: 32 + - name: RCU_I2C_OK + description: Only OK RCUs are monitored + driver: I2C_RCU + rw: variable #server RW variable, not linked to IO + dtype: boolean + dim: 32 + - name: RCU_state description: State of RCUs 0=unknown, 1=ready, 2=busy, 3=error driver: I2C_RCU @@ -215,24 +222,14 @@ variables: dim: 96 mask: Ant_mask - - name: RCU_GPIO1 + - name: [RCU_IO1_GPIO1,RCU_IO1_GPIO2,RCU_IO2_GPIO1,RCU_IO2_GPIO2,RCU_IO3_GPIO1,RCU_IO3_GPIO2] driver: I2C_RCU - devreg: [IO1.GPIO1,IO2.GPIO1,IO3.GPIO1] + devreg: [IO1.GPIO1,IO1.GPIO2,IO2.GPIO1,IO2.GPIO2,IO3.GPIO1,IO3.GPIO2] width: 8 rw: ro dtype: uint8 - dim: 96 - mask: Ant_mask - debug: True - - - name: RCU_GPIO2 - driver: I2C_RCU - devreg: [IO1.GPIO2,IO2.GPIO2,IO3.GPIO2] - width: 8 - rw: ro - dtype: uint8 - dim: 96 - mask: Ant_mask + dim: 32 + mask: RCU_mask debug: True - name: RCU_LED0 @@ -240,22 +237,22 @@ variables: description: LED on RCU devreg: IO2.GPIO2 bitoffset: 6 - width: 1 + width: 2 rw: rw - dtype: boolean + dtype: uint8 dim: 32 mask: RCU_mask - - name: RCU_LED1 - driver: I2C_RCU - description: LED on RCU - devreg: IO2.GPIO2 - bitoffset: 7 - width: 1 - rw: rw - dtype: boolean - dim: 32 - mask: RCU_mask +# - name: RCU_LED1 +# driver: I2C_RCU +# description: LED on RCU +# devreg: IO2.GPIO2 +# bitoffset: 7 +# width: 1 +# rw: rw +# dtype: boolean +# dim: 32 +# mask: RCU_mask - name: RCU_temperature description: Temperature sensor on RCU @@ -267,6 +264,7 @@ variables: dtype: double dim: 32 monitor: true + mask: RCU_I2C_OK - name: RCU_Pwr_dig description: Enable LDOs @@ -318,7 +316,7 @@ variables: rw: ro dtype: uint8 dim: 96 - mask: Ant_mask + mask: RCU_I2C_OK monitor: true - name: RCU_dth1_freq @@ -331,12 +329,6 @@ variables: mask: Ant_mask methods: - - name: RCU_update - mask: RCU_mask - debug: True - instructions: - - RCU_ADC_lock: Update - - name: RCU_on driver: I2C_RCU mask: RCU_mask @@ -353,13 +345,30 @@ methods: - IO3.CONF2: 0 - IO1.CONF1: 0 - IO1.CONF1: 0 - - RCU_attenuator: [10,10,10] #Set OPC-UA variable - - RCU_Pwr_dig: Update #Read value and update the OPC-UA variable - - WAIT: 500 #ms to wait - - ADC1_on: 0 #call another opc-ua method - - ADC2_on: 0 - - WAIT: 500 #ms to wait - - RCU_ADC_lock: Update +# - RCU_GPIO1: Update +# - RCU_GPIO2: Update +# - RCU_attenuator: [10,10,10] #Set OPC-UA variable +# - WAIT: 500 #ms to wait +# - ADC1_on: 0 #call another opc-ua method +# - ADC2_on: 0 +# - WAIT: 500 #ms to wait + - RCU_update: 0 + + - name: RCU_update + driver: I2C_RCU + mask: RCU_mask + debug: True + instructions: +# - RCU_ADC_lock: Update + - RCU_IO1_GPIO1 : Update + - RCU_IO1_GPIO2 : Update + - RCU_IO2_GPIO1 : Update + - RCU_IO2_GPIO2 : Update + - RCU_IO3_GPIO1 : Update + - RCU_IO3_GPIO2 : Update + - RCU_Pwr_dig: Update #Read value and update the OPC-UA variable + - RCU_ADC_lock: Update + - name: ADC1_on driver: I2C_RCU diff --git a/i2cserv/i2c.py b/i2cserv/i2c.py index a12df13..3eb98b2 100644 --- a/i2cserv/i2c.py +++ b/i2cserv/i2c.py @@ -1,6 +1,6 @@ import os -if os.sys.platform is 'linux': - import pylibi2c; +#if os.sys.platform is 'linux': +import pylibi2c; import time import logging #read=0: write to register @@ -20,10 +20,10 @@ class i2c(hwdev): # logging.debug(str(("I2C",addr,reg,data,read))) bus=None; try: +# if True: if read==3: time.sleep(data[0]/1000.) return True - logging.debug(str(("I2C",addr,reg,data,read))) # return True; bus=pylibi2c.I2CDevice(self.I2Cdev,addr) @@ -31,18 +31,22 @@ class i2c(hwdev): length=len(data) bus.iaddr_bytes=0 if not(reg is None): - bus.ioctl_write(0,str(bytearray([reg]))) + bus.ioctl_write(0,bytes(bytearray([reg]))) data[:]=[int(x) for x in bus.ioctl_read(0,length)] + logging.debug(str(("I2C get",addr,reg,data,read))) # print("I2C read",addr,reg,data,read) else: if reg is None: bus.iaddr_bytes=0 - reg=0; - bus.ioctl_write(reg,str(bytearray(data))) + reg=0; + logging.debug(str(("I2C set",addr,reg,bytes(bytearray(data)),read))) + bus.ioctl_write(reg,bytes(bytearray(data))) bus.close() return True; except: +# else: if bus: bus.close() + logging.debug("I2C failed!") # data[0]=0xff return False; diff --git a/i2cserv/i2c_array.py b/i2cserv/i2c_array.py index 11b7d9f..293c5a8 100644 --- a/i2cserv/i2c_array.py +++ b/i2cserv/i2c_array.py @@ -124,8 +124,10 @@ class i2c_array(hwdev): def OPCUASetVariable(self,varid,var1,data,mask): if var1['rw']=='variable': return; logging.info(str(("Set Var",var1['name'],data,mask))) - data=self.SetGetVarValueMask(var1,data,mask); - Data=OPCUAset(varid,InstType.varSet,data,mask) + data,mask2=self.SetGetVarValueMask(var1,data,mask); +# if len(mask)==len(mask2): mask[:]=mask2[:]; +# elif len(mask)==0: (mask.append(x) for x in mask2); + Data=OPCUAset(varid,InstType.varSet,data,mask2) return [Data] def OPCUAReadVariable(self,varid,var1,mask): @@ -133,8 +135,10 @@ class i2c_array(hwdev): if len(mask)==0: mask=[True]*self.N; #data=self.GetVarValueAll(var1) #else: - data=self.GetVarValueMask(var1,mask); - Data=OPCUAset(varid,InstType.varSet,data,mask) + data,mask2=self.GetVarValueMask(var1,mask); +# if len(mask)==len(mask2): mask[:]=mask2[:]; +# elif len(mask)==0: (mask.append(x) for x in mask2); + Data=OPCUAset(varid,InstType.varSet,data,mask2) return [Data] # def OPCUAcallMethod(self,var1,data,mask): @@ -167,6 +171,7 @@ class i2c_array(hwdev): print("Check mask length!"); return; # if (len(value1)==V1.nVars) and (self.N>1): value1=(value1*self.N); +# logging.debug(str(("Step=",Step,"Mask=",mask))) i2c=self.conf['parentcls']; for RCUi in range(self.N): for Vari in range(Step): @@ -178,11 +183,12 @@ class i2c_array(hwdev): bitoffset=GetField(var1,'bitoffset',Vari,0) self.SetSwitch(RCUi); self.RCUi=RCUi; - self.SetVarValue(devreg,width,bitoffset,data[i0:i1]) + mask[RCUi*Step+Vari]=self.SetVarValue(devreg,width,bitoffset,data[i0:i1]) + if not(mask[RCUi*Step+Vari]): continue value2=value1[i0:i1] - self.GetVarValue(devreg,width,bitoffset,value2) + mask[RCUi*Step+Vari]=self.GetVarValue(devreg,width,bitoffset,value2) value1[i0:i1]=value2 - return value1 + return value1,mask @@ -197,6 +203,7 @@ class i2c_array(hwdev): return; # if (len(value1)==V1.nVars) and (self.N>1): value1=(value1*self.N); i2c=self.conf['parentcls']; +# logging.debug(str(("Step=",Step,"Mask=",mask))) for RCUi in range(self.N): for Vari in range(Step): if not(mask[RCUi*Step+Vari]): continue @@ -208,9 +215,9 @@ class i2c_array(hwdev): self.SetSwitch(RCUi); value2=value1[i0:i1] self.RCUi=RCUi; - self.GetVarValue(devreg,width,bitoffset,value2) + mask[RCUi*Step+Vari]=self.GetVarValue(devreg,width,bitoffset,value2) value1[i0:i1]=value2 - return value1 + return value1,mask def getstorearray(self,devreg): @@ -221,14 +228,15 @@ class i2c_array(hwdev): return storearray; def Setdevreg(self,devreg,value,mask=[]): - # if devreg.get('store')>0: logging.warn("Setdevreg not working correctly for stored registers!") - if devreg['store']>0: +# if devreg.get('store'): logging.debug("Stored") +# print(devreg['store']) + if devreg.get('store'): storearray=self.getstorearray(devreg); for RCUi in range(self.N): if mask[RCUi]: storearray[RCUi]=value[0] self.RCUi=RCUi; -# print("Stored values:",self.getstorearray(devreg)) + logging.debug(str(("Stored values:",self.getstorearray(devreg)))) self.SetSwitchMask(mask) self.SetVarValue(devreg,8,0,value) return True; @@ -238,12 +246,12 @@ class i2c_array(hwdev): if devreg['register_W']==-1: return True; #We can not set it, only read it e.g. temperature logging.debug(str(("RCU1 Set ",self.RCUi,devreg['addr'],value))) #self.parentcls.SetChannel(1<<RCU_Switch[RCUi]); - if devreg['store']>0: + if devreg['store']: storearray=self.getstorearray(devreg); previous=storearray[self.RCUi]; value[0]=ApplyMask(value[0],width,bitoffset,previous); storearray[self.RCUi]=value[0] -# print("Stored values:",self.getstorearray(devreg)) + logging.debug("Stored value:"+str(value[0])) # devreg['drivercls'].i2csetget return devreg['drivercls'].i2csetget(devreg['addr'],value,reg=devreg['register_W']) @@ -266,14 +274,17 @@ class i2c_array(hwdev): if not(callback(devreg['addr'],value2,reg=reg,read=1)): return False; if value2[0] is None: return False value[:]=value2[:]; - if devreg['store']>0: + if devreg['store']: storearray=self.getstorearray(devreg); storearray[self.RCUi]=value[0] logging.debug(str(("Store buffer",self.RCUi,value[0]))) # print("Stored values:",self.getstorearray(devreg)) if (width!=l1*8) or (bitoffset>0): - for i in range(len(value)): - value[i]=UnMask(value[i],width,bitoffset) + if (width<8): + for i in range(len(value)): + value[i]=UnMask(value[i],width,bitoffset) + else: + value[0]=UnMask(value[0],width-(l1-1)*8,bitoffset) else: value[0]=value2[0] return True; diff --git a/i2cserv/i2c_switch.py b/i2cserv/i2c_switch.py index f6a59b9..6863b5a 100644 --- a/i2cserv/i2c_switch.py +++ b/i2cserv/i2c_switch.py @@ -11,13 +11,14 @@ class i2c_switch(i2c): logging.info("i2c switch at address "+str(self.SWaddr)) def SetSW1(self,channelbit): - channel=1<<(channelbit) + channel=(0 if (channelbit>5) else 1<<(channelbit)) #LTS if (channel)==self.CurrentChannel: return True; - logging.debug("SetChannel=%i" % channelbit) + logging.debug("SetChannelbit=%i" % channelbit) self.CurrentChannel=channel return self.i2csetget(self.SWaddr,[channel]) def SetChannel(self,channel): + channel&=0x3F;#LTS if (channel)==self.CurrentChannel: return True; logging.debug("SetChannel=%i" % channel) self.CurrentChannel=channel diff --git a/i2cserv/i2cthread.py b/i2cserv/i2cthread.py index c76a1ec..3fa382f 100644 --- a/i2cserv/i2cthread.py +++ b/i2cserv/i2cthread.py @@ -35,20 +35,20 @@ def runmethod(conf,Qout,methodid,mask): for inst in var1['instructions']: for key,value in inst.items(): if not(isinstance(value,list)): value=[value] - logging.info(str(("Run instruction",key,value))); + logging.info(str(("Run instruction",key,value,mask))); if (key=='WAIT'): sleep(value[0]/1000.) continue; v1=conf.getvarid(key) if v1: if value[0]=='Update': - getvar(conf,Qout,v1,mask) + mask=getvar(conf,Qout,v1,mask) else: - setvar(conf,Qout,v1,value,mask) + mask=setvar(conf,Qout,v1,value,mask) continue; v1=conf.getmethodid(key) if v1: - runmethod(conf,Qout,v1,mask) + mask=runmethod(conf,Qout,v1,mask) continue; v1=conf.getdevreg(key) if v1: @@ -65,6 +65,8 @@ def runmethod(conf,Qout,methodid,mask): # continue; # for data in drv.OPCUAcallMethod(item.id,var1,item.data,item.mask): # Qout.put(data) + return mask + def setvar(conf,Qout,varid,data,mask): var1=conf.getvars()[varid] drv=var1.get('drivercls'); @@ -72,7 +74,10 @@ def setvar(conf,Qout,varid,data,mask): logging.warn(var1['name']+" driver not found!") return; for data in drv.OPCUASetVariable(varid,var1,data,mask): + if len(mask)==len(data.mask): mask[:]=data.mask[:]; + elif len(mask)==0: mask=data.mask.copy(); Qout.put(data) + return mask; def getvar(conf,Qout,varid,mask): var1=conf.getvars()[varid] @@ -81,7 +86,10 @@ def getvar(conf,Qout,varid,mask): logging.warn(var1['name']+" driver not found!") return; for data in drv.OPCUAReadVariable(varid,var1,mask): + if len(mask)==len(data.mask): mask[:]=data.mask[:]; + elif len(mask)==0: mask=data.mask.copy(); Qout.put(data) + return mask; def I2Cserver(Qin,Qout,name): diff --git a/i2cserv/spibitbang1.py b/i2cserv/spibitbang1.py index 7db2517..2148d30 100644 --- a/i2cserv/spibitbang1.py +++ b/i2cserv/spibitbang1.py @@ -15,8 +15,8 @@ class spibitbang1(hwdev): # logging.info("spibitbang todo") def i2csetget(self,addr,data,reg=None,read=0): - if read==0: return self.SetSPIbb(addr,data) - elif read==1: return self.GetSPIbb(addr,data) + if read==0: return self.SetSPIbb(reg,data) + elif read==1: return self.GetSPIbb(reg,data) else: logging.warn("Not implemented!") return False; @@ -39,7 +39,7 @@ class spibitbang1(hwdev): bit_array = "{0:{fill}24b}".format(data2, fill='0') # print(bit_array) - SetI2C(CSdev,1,CSpin,[0]) #enable + if not(SetI2C(CSdev,1,CSpin,[0])): return False #enable for bit in bit_array: SetI2C(SDOdev,1,SDOpin,[int(bit)]) SetI2C(CLKdev,1,CLKpin,[1]) @@ -57,7 +57,11 @@ class spibitbang1(hwdev): CLKpin=self.conf['parameters'][SPIBB_pins.CLK.value] SDIOdirdev=self.conf['devreg'][SPIBB_pins.SDIOdir.value] SDIOdirpin=self.conf['parameters'][SPIBB_pins.SDIOdir.value] - +# print("SPI registers") +# print("CS",CSdev,CSpin) +# print("SDO",SDOdev,SDOpin) +# print("CLK",CLKdev,CLKpin) +# print("DIR",SDIOdirdev,SDIOdirpin) logging.info(str(("SPIbb get",ADC_reg_address))) ADC_bytes = 0x00 @@ -67,10 +71,11 @@ class spibitbang1(hwdev): SetI2C=self.conf['parentcls'].SetVarValue GetI2C=self.conf['parentcls'].GetVarValue - SetI2C(CSdev,1,CSpin,[0]) #enable + if not(SetI2C(CSdev,1,CSpin,[0])): return False #enable bit_array = "{0:{fill}16b}".format(data, fill='0') + #print("SPI TX bits",bit_array) for bit in bit_array: SetI2C(SDOdev,1,SDOpin,[int(bit)]) SetI2C(CLKdev,1,CLKpin,[1]) @@ -87,11 +92,13 @@ class spibitbang1(hwdev): for i in range(N): value[i]=0 for cnt in range(8*(ADC_bytes+1)): GetI2C(SDOdev,1,SDOpin,ret_value) #enable +# logging.debug("Got bit"+str((ret_value))) for i in range(N): value[i]=(value[i]<<1)+ ret_value[i] SetI2C(CLKdev,1,CLKpin,[1]) SetI2C(CLKdev,1,CLKpin,[0]) #read after falling edge SetI2C(CSdev,1,CSpin,[1]) #disable SetI2C(SDIOdirdev,1,SDIOdirpin,[0]) #output +# logging.debug(str(("SPIbb got",value))) return True; def GetSPIbb2(SetI2C,GetI2C,RCUi,SPIdev,I2Cdev,I2Cpins,value): diff --git a/opcuaserv/yamlreader.py b/opcuaserv/yamlreader.py index 380da01..7b8e259 100644 --- a/opcuaserv/yamlreader.py +++ b/opcuaserv/yamlreader.py @@ -181,7 +181,7 @@ class yamlreader(yamlconfig): if mask[i//step]: data3[i]=data2[i] else: data3=data2; - logging.debug(str(("OPCset",v['name'],data3))) + logging.info(str(("OPCset",v['name'],data3))) v['OPCR'].set_value(data3); def Monitor(self): diff --git a/testRCU.py b/testRCU.py index 1576f31..f68c675 100644 --- a/testRCU.py +++ b/testRCU.py @@ -32,10 +32,16 @@ I2Cclients.append(RCU_I2C) #Load yaml so that we know the variable names RCU_conf=yamlreader.yamlreader(RCU_I2C,yamlfile=name) +var1=RCU_conf.getmethodid('RCU_update'); +#var1=RCU_conf.getmethodid('RCU_on'); +#N=32; +#mask=[i<2 for i in range(N)]; +#RCU_I2C.callmethod(var1,[]) + if True: var1=RCU_conf.getvarid('RCU_LED0'); N=32; - mask=[i<2 for i in range(N)]; + mask=[i<8 for i in range(N)]; data=[0]*N; elif True: var1=RCU_conf.getvarid('RCU_attenuator'); @@ -46,20 +52,28 @@ elif True: #print(var1) print("mask=",mask); print("data=",data); -RCU_I2C.setvar(var1,data,mask); +#RCU_I2C.setvar(var1,data,mask); + +var1=RCU_conf.getvarid('RCU_temperature'); +N=32; +mask=[i<2 for i in range(N)]; +RCU_I2C.readvar(var1,mask); + +#data=[0]*N; +#RCU_I2C.setvar(var1,data,mask); #def setvar(self,id1,data=[],mask=[]): var1=RCU_conf.getmethodid('RCU_on'); N=32; -mask=[i<2 for i in range(N)]; -RCU_I2C.callmethod(var1,mask) +mask=[i<7 for i in range(N)]; +#RCU_I2C.callmethod(var1,mask) -time.sleep(2); +time.sleep(5); while RCU_I2C.data_waiting(): varid,data,mask=RCU_I2C.readdata() - print("Results:",RCU_conf.getvar1(varid)['name'],data) + print("Results:",RCU_conf.getvar1(varid)['name'],data,mask) logging.info("Stop threads") diff --git a/yamlconfig.py b/yamlconfig.py index fb32013..7dd994a 100644 --- a/yamlconfig.py +++ b/yamlconfig.py @@ -73,6 +73,7 @@ class yamlconfig(): if isinstance(name,int): return {"addr":name} name2=name.split('.') # print(name2,str2int(name2[0]),str2int(name2[1])) + logging.debug("New devreg!") if len(name2)==2: return {"addr":str2int(name2[0]),"register_R":str2int(name2[1]),"register_W":str2int(name2[1])} logging.error("Can not find device register "+str(name)); -- GitLab