diff --git a/config/CLK.yaml b/config/CLK.yaml index ffd4b8a9b1e5ba274e9d0309c70d01560b7ef6d0..2470e5dfc325bb7a92ca79e5ca892b92be76ad01 100644 --- a/config/CLK.yaml +++ b/config/CLK.yaml @@ -95,6 +95,12 @@ variables: methods: + - name: Init #Called after startup to load. Should have all stored registers + driver: I2C_CLK + hidden: True + instructions: + - IO1.GPIO1: Update + - name: CLK_on driver: I2C_CLK instructions: diff --git a/config/RCU.yaml b/config/RCU.yaml index ef0371fbf1a43f561406336f0b423ee59e6ece35..4507b0ded90c4408b1c2a23a8bbd963aa14b0595 100644 --- a/config/RCU.yaml +++ b/config/RCU.yaml @@ -10,6 +10,7 @@ drivers: type: i2c_array #An array of similar devices connected to an I2C switch parent: I2C1 parameters: [0,31] #start,number of RCUs + mask: RCU_I2C_OK - name: I2C_HBAT type: hba1 #Special driver to manage HBAT1s. parent: I2C_RCU @@ -344,6 +345,17 @@ variables: methods: + - name: Init #Called after startup to load. Should have all stored registers + driver: I2C_RCU + hidden: True + instructions: + - RCU_IO1_GPIO1: Update + - IO1.GPIO2: Update + - IO2.GPIO1: Update + - IO2.GPIO2: Update + - IO3.GPIO1: Update + - IO3.GPIO2: Update + - name: RCU_on driver: I2C_RCU mask: RCU_mask diff --git a/i2cserv/i2c_array.py b/i2cserv/i2c_array.py index db157cb85429abe056de85113339e0d1758136aa..a9c3a2aec20bf76f902592865b22b504e85c0090 100644 --- a/i2cserv/i2c_array.py +++ b/i2cserv/i2c_array.py @@ -11,7 +11,11 @@ def GetSteps(V1): Step2=V1.get('dim',1)*((V1.get('width',8)+7)//8)//Step #int(V1.size/V1.nVars) logging.debug(str(("GetStep",Step,Step2))); return Step,Step2 - +def list_different(A,B): + if not(len(A)==len(B)): return True; + for i,m in enumerate(B): + if not(m==A[i]): return True + return False class i2c_array(i2c_dev): def __init__(self,config): @@ -24,19 +28,36 @@ class i2c_array(i2c_dev): pars=config['parameters']; self.RCU_Switch1=range(pars[0],pars[1]+1); self.N=len(self.RCU_Switch1); + self.I2Cmask=[True]*self.N + self.I2Cmaskid=config.get('maskid') + if not(self.I2Cmaskid): logging.warn(config['name']+" I2C mask not found!") # self.devregs,RCU_storeReg=DevRegList(yaml) # print("Init",config['name'],'len=',len(self.RCU_Switch1),' stored reg=',RCU_storeReg) # self.previous =np.zeros([self.N,RCU_storeReg],dtype='int') + def OPCUASetVariable(self,varid,var1,data,mask): + oldmask=self.I2Cmask.copy() + Data=i2c_dev.OPCUASetVariable(self,varid,var1,data,mask) + if list_different(self.I2Cmask,oldmask): + Data.append(OPCUAset(varid,InstType.varSet,self.I2Cmask,[])) + return Data def OPCUAReadVariable(self,varid,var1,mask): if len(mask)==0: mask=[True]*self.N; - return i2c_dev.OPCUAReadVariable(self,varid,var1,mask) + oldmask=self.I2Cmask.copy() + Data=i2c_dev.OPCUAReadVariable(self,varid,var1,mask) + if list_different(self.I2Cmask,oldmask): + if self.I2Cmaskid: + Data.append(OPCUAset(self.I2Cmaskid,InstType.varSet,self.I2Cmask,[])) + return Data + + def SetSwitch(self,RCUi): + self.conf['parentcls'].SetSW1(self.RCU_Switch1[RCUi]); - def SetSwitchMask(self,mask): m=0; for RCUi in range(self.N): - if mask[RCUi]: m|=1<<self.RCU_Switch1[RCUi]; + if (mask[RCUi]) and (self.I2Cmask[RCUi]): + m|=1<<self.RCU_Switch1[RCUi]; self.conf['parentcls'].SetChannel(m); def SetGetVarValueMask(self,var1,data,mask): @@ -55,10 +76,12 @@ class i2c_array(i2c_dev): 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): if not(mask[RCUi*Step+Vari]): continue + if not(self.I2Cmask[RCUi]): + mask[RCUi*Step+Vari]=False; + continue; i0=(RCUi*Step+ Vari)*Step2 i1=(RCUi*Step+(Vari+1))*Step2 devreg=var1['devreg'][Vari]; @@ -66,15 +89,21 @@ class i2c_array(i2c_dev): bitoffset=GetField(var1,'bitoffset',Vari,0) self.SetSwitch(RCUi); self.RCUi=RCUi; - mask[RCUi*Step+Vari]=self.SetVarValue(devreg,width,bitoffset,data[i0:i1]) - if not(mask[RCUi*Step+Vari]): continue + res=self.SetVarValue(devreg,width,bitoffset,data[i0:i1]) + if not(res): + self.I2Cmask[RCUi]=res; + mask[RCUi*Step+Vari]=False; + continue; value2=value1[i0:i1] - mask[RCUi*Step+Vari]=self.GetVarValue(devreg,width,bitoffset,value2) + res=self.GetVarValue(devreg,width,bitoffset,value2) + if not(res): + self.I2Cmask[RCUi]=False; + mask[RCUi*Step+Vari]=False; + continue; value1[i0:i1]=value2 return value1,mask - def GetVarValueMask(self,var1,mask): Step,Step2=GetSteps(var1); value1=[0]*Step*Step2; @@ -90,6 +119,9 @@ class i2c_array(i2c_dev): for RCUi in range(self.N): for Vari in range(Step): if not(mask[RCUi*Step+Vari]): continue + if not(self.I2Cmask[RCUi]): + mask[RCUi*Step+Vari]=False; + continue; i0=(RCUi*Step+ Vari)*Step2 i1=(RCUi*Step+(Vari+1))*Step2 devreg=var1['devreg'][Vari]; @@ -98,11 +130,14 @@ class i2c_array(i2c_dev): self.SetSwitch(RCUi); value2=value1[i0:i1] self.RCUi=RCUi; - mask[RCUi*Step+Vari]=self.GetVarValue(devreg,width,bitoffset,value2) + res=self.GetVarValue(devreg,width,bitoffset,value2) + if not(res): + self.I2Cmask[RCUi]=False; + mask[RCUi*Step+Vari]=False; + continue; value1[i0:i1]=value2 return value1,mask - def getstorearray(self,devreg,N=1): storearray=devreg.get('storearray') if not(storearray): @@ -113,18 +148,40 @@ class i2c_array(i2c_dev): def Setdevreg(self,devreg,value,mask=[]): # if devreg.get('store'): logging.debug("Stored") # print(devreg['store']) + self.SetSwitchMask(mask) + if not(self.SetVarValue(devreg,8,0,value)): return False; if devreg.get('store'): storearray=self.getstorearray(devreg); for RCUi in range(self.N): - if mask[RCUi]: + if (mask[RCUi]) and (self.I2Cmask[RCUi]): storearray[RCUi]=value[0] self.RCUi=RCUi; logging.debug(str(("Stored values:",self.getstorearray(devreg)))) - self.SetSwitchMask(mask) - self.SetVarValue(devreg,8,0,value) return True; + def Getdevreg(self,devreg,mask=[]): + value1=[0]*self.N + mask=[True]*self.N + if devreg.get('store'): + storearray=self.getstorearray(devreg); + i2c=self.conf['parentcls']; + for RCUi in range(self.N): + if not(mask[RCUi]): continue + if not(self.I2Cmask[RCUi]): continue + self.SetSwitch(RCUi); + value2=[value1[RCUi]] + self.RCUi=RCUi; + res=self.GetVarValue(devreg,8,0,value2) + if not(res): + self.I2Cmask[RCUi]=False; + value1[RCUi]=value2[0] + if devreg.get('store'): + if mask[RCUi]: + storearray[RCUi]=value2[0] + logging.debug(str(("Stored values:",self.getstorearray(devreg)))) + return True; + def SetVarValue(self,devreg,width,bitoffset,value): 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))) diff --git a/i2cserv/i2c_dev.py b/i2cserv/i2c_dev.py index 4e701fdff7faea111cf82cf304c899f36e9bb883..17be113387d560db73fd5bcc1b007c588f5d60a5 100644 --- a/i2cserv/i2c_dev.py +++ b/i2cserv/i2c_dev.py @@ -75,12 +75,6 @@ def DevRegList(D): # print(devreglist) return devreglist,store -def GetSteps(V1): - if isinstance(V1['devreg'],list): Step=len(V1['devreg']) - else: Step=1; #V1.nVars - Step2=V1.get('dim',1)*((V1.get('width',8)+7)//8)//Step #int(V1.size/V1.nVars) - logging.debug(str(("GetStep",Step,Step2))); - return Step,Step2 class i2c_dev(hwdev): @@ -112,9 +106,6 @@ class i2c_dev(hwdev): def i2csetget(self,*args,**kwargs): return self.conf['parentcls'].i2csetget(*args,**kwargs) - def SetSwitch(self,RCUi): - self.conf['parentcls'].SetSW1(self.RCU_Switch1[RCUi]); - def SetGetVarValueMask(self,var1,data,mask): Step=(len(var1['devreg']) if isinstance(var1['devreg'],list) else 1) value1=[0]*Step @@ -180,7 +171,14 @@ class i2c_dev(hwdev): devreg['storeval']=value[0]; self.SetVarValue(devreg,8,0,value) return True; - + + def Getdevreg(self,devreg,mask=[]): + value=[0]; + mask=self.GetVarValue(devreg,8,0,value) + if devreg.get('store'): + devreg['storeval']=value[0]; + logging.debug("Stored value:"+str(value[0])) + return True; def SetVarValue(self,devreg,width,bitoffset,value): if devreg['register_W']==-1: return True; #We can not set it, only read it e.g. temperature diff --git a/i2cserv/i2cthread.py b/i2cserv/i2cthread.py index e3540efd46303cb25366a7fecfe879e76ccd4086..2d4bd445375c3bdbbf2eea31a004ac87d5230d19 100644 --- a/i2cserv/i2cthread.py +++ b/i2cserv/i2cthread.py @@ -53,9 +53,15 @@ def runmethod(conf,Qout,methodid,mask): v1=conf.getdevreg(key) if v1: drv2=v1.get('drivercls') - if drv: drv.Setdevreg(v1,value,mask) - elif drv2: drv2.Setdevreg(v1,value,mask) - else: logging.warn("Driver not specified for instruction"+key) + if value[0]=='Update': + if drv: drv.Getdevreg(v1,mask) + elif drv2: drv2.Getdevreg(v1,mask) + else: logging.warn("Driver not specified for instruction"+key) + else: + if drv: drv.Setdevreg(v1,value,mask) + elif drv2: drv2.Setdevreg(v1,value,mask) + else: logging.warn("Driver not specified for instruction"+key) + continue; # def Setdevreg(self,devreg,value,mask=[],width=8,bitoffset=0): logging.warn("Unknown instruction "+key) diff --git a/opcuaserv/yamlreader.py b/opcuaserv/yamlreader.py index cd4b6a89a1d334939b5b5b0db37c21d4cab130e6..ba203186d084f1cc7e979e72dc6c5d21a3694b29 100644 --- a/opcuaserv/yamlreader.py +++ b/opcuaserv/yamlreader.py @@ -86,6 +86,11 @@ class yamlreader(yamlconfig): mask=mask.get_value() if (mask!=None) else []; self.server.callmethod(id1,mask) + def CallInit(self): + v=Find(self.conf['methods'],'name','Init'); + if not(v): return; + self.server.callmethod(v['id'],[]) + def setvar(self,id1,data=[]): v=self.conf['variables'][id1]; if v['rw']=='variable': return; diff --git a/pypcc2.py b/pypcc2.py index e4bdd2ab111c2530261e72a1f368a5c9dc225e09..0fb7bef0ac7814141f692a3933ef244c2c2ca388 100644 --- a/pypcc2.py +++ b/pypcc2.py @@ -57,6 +57,7 @@ if not(args.test): RCU_conf=yamlreader.yamlreader(RCU_I2C,yamlfile=name) RCU_conf.AddVars(opcuaserv.AddVarR,opcuaserv.AddVarW) RCU_conf.AddMethod(opcuaserv.Addmethod) + RCU_conf.CallInit(); configs.append(RCU_conf); thread2=threading.Thread(target=RCU_conf.getvar); #Thread on OPC-UA side of pipe diff --git a/testCLK.py b/testCLK.py index 4b6f11c941f87dc8f54e1452d8c23c1d47f2f326..bc522458e010b02f703fadcb09517348f565cffc 100644 --- a/testCLK.py +++ b/testCLK.py @@ -31,9 +31,11 @@ I2Cclients.append(RCU_I2C) #Load yaml so that we know the variable names RCU_conf=yamlreader.yamlreader(RCU_I2C,yamlfile=name) +RCU_conf.CallInit() + var1=RCU_conf.getvarid('CLK_PLL_locked') -RCU_I2C.readvar(var1,[]) +#RCU_I2C.readvar(var1,[]) var1=RCU_conf.getvarid('CLK_PLL_locked_SPI') #var1=RCU_conf.getvarid('CLK_PLL_r3') diff --git a/testRCU.py b/testRCU.py index 584cf586455a46047bf8fd79b97f1111f8fe9fae..146ff23133340c08ec83a4faad5ade27cd66fba6 100644 --- a/testRCU.py +++ b/testRCU.py @@ -31,6 +31,7 @@ I2Cclients.append(RCU_I2C) #Load yaml so that we know the variable names RCU_conf=yamlreader.yamlreader(RCU_I2C,yamlfile=name) +RCU_conf.CallInit() var1=RCU_conf.getmethodid('RCU_update'); #var1=RCU_conf.getmethodid('RCU_on'); @@ -55,10 +56,10 @@ else: mask=[i<4*3 for i in range(N)]; data=[1]*(N*32); #print(var1) -print("mask=",mask); -print("data=",data); +#print("mask=",mask); +#print("data=",data); #RCU_I2C.setvar(var1,data,mask); -RCU_I2C.readvar(var1,mask); +#RCU_I2C.readvar(var1,mask); var1=RCU_conf.getvarid('RCU_temperature'); N=32; @@ -73,7 +74,7 @@ mask=[i<2 for i in range(N)]; var1=RCU_conf.getmethodid('RCU_HBAT_WAIT_PPS'); N=32; mask=[i<7 for i in range(N)]; -RCU_I2C.callmethod(var1,mask) +#RCU_I2C.callmethod(var1,mask) time.sleep(2); diff --git a/yamlconfig.py b/yamlconfig.py index 521fc82c6b43639d6a018694280f3b444c2413b2..3f17a3d6f09c0311855805026a4b4f836278f69e 100644 --- a/yamlconfig.py +++ b/yamlconfig.py @@ -133,6 +133,15 @@ class yamlconfig(): devreg[i]=self.getdevreg(dr) else: D['devreg']=[self.getdevreg(devreg)] + + for D in drivers: + mask=D.get('mask'); + if not(mask): continue; + mask=self.getvarid(mask) + if not(mask): + logging.warn("Variable %s not found",mask) + continue; + D['maskid']=mask #print(D['name'],devreg) # hf.write("inline const t_devreg %s {.address=%i,.register_R=%i,.register_W=%i,.store=%i,.driver=%i};\n" % (devregname,addr,regR,regW,storex,devtype) ) #hf.write("#define NumberStoreReg %i"%store)