diff --git a/config/CLK.yaml b/config/CLK.yaml index 5d702976b2f9f88e96d7ec6fe29a2cdc1cffeaa1..00eaa2824e8bc4011d631f7e3a171e629355a7d6 100644 --- a/config/CLK.yaml +++ b/config/CLK.yaml @@ -6,9 +6,9 @@ drivers: type: i2c parameters: [1] #I2C port number - name: I2C_CLK - type: i2c_devs #I2C devices + type: i2c_array #I2C devices parent: I2C - parameters: [32] #number of RCUs + parameters: [0,0] #number of RCUs - name: SPIbb1 type: spibitbang2 #SPI bitbang via GPIO expander: CLK, SDI,SDO,CS parent: I2C_CLK diff --git a/config/RCU.yaml b/config/RCU.yaml index c63bd7074ef20db17a1eee1544912290079b78ca..aac519d77a8d804ab74e462509ce18479d2d8c43 100644 --- a/config/RCU.yaml +++ b/config/RCU.yaml @@ -2,18 +2,14 @@ version: "1.0" description: "1234" drivers: - - name: I2C1 - type: RCU_switch - devreg: [SWITCH.MASK] + - name: I2C1 #TCA9548 + type: i2c_switch + devreg: [0x70] parameters: [1] #I2C port number - 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 - - name: I2C_RFCHAIN - type: i2c_array2 #Array of similar devices with different address on same I2C line e.g. 3 rf chains on 1 RCU - parameters: [3] #number of RCUs - parent: I2C_RCU - name: I2C_HBAT type: hba1 #Special driver to manage HBAT1s. parent: I2C_RCU @@ -74,15 +70,6 @@ device_registers: address: [1,3] store: True - - name: SWITCH - description: RCU selection switch - address: 0x70 - device: TCA9548 - driver: I2C1 - registers: - - name: MASK - description: I2C select mask - - name: ROM description: IO-Expander for filter selection address: 0x50 @@ -187,7 +174,7 @@ device_registers: variables: - name: Ant_mask description: Only masked RF chains are updated - driver: I2C_RFCHAIN + driver: I2C_RCU rw: variable #server RW variable, not linked to IO dtype: boolean dim: 96 @@ -208,7 +195,7 @@ variables: - name: RCU_attenuator description: Attenuator before ADC - driver: I2C_RFCHAIN + driver: I2C_RCU devreg: [IO1.GPIO1,IO1.GPIO2,IO2.GPIO1] bitoffset: [0,0,0] width: 5 @@ -219,7 +206,7 @@ variables: - name: RCU_band description: Band select switch 1=10MHz,2=30MHz - driver: I2C_RFCHAIN + driver: I2C_RCU devreg: [IO2.GPIO2,IO2.GPIO2,IO2.GPIO2] bitoffset: [0,2,4] width: 2 @@ -229,7 +216,7 @@ variables: mask: Ant_mask - name: RCU_GPIO1 - driver: I2C_RFCHAIN + driver: I2C_RCU devreg: [IO1.GPIO1,IO2.GPIO1,IO3.GPIO1] width: 8 rw: ro @@ -239,7 +226,7 @@ variables: debug: True - name: RCU_GPIO2 - driver: I2C_RFCHAIN + driver: I2C_RCU devreg: [IO1.GPIO2,IO2.GPIO2,IO3.GPIO2] width: 8 rw: ro @@ -324,7 +311,7 @@ variables: - name: RCU_ADC_lock description: 0x81=locked - driver: I2C_RFCHAIN + driver: I2C_RCU devreg: [ADC1.PLL_stat,ADC2.PLL_stat,ADC3.PLL_stat] width: 8 rw: ro @@ -333,7 +320,7 @@ variables: mask: Ant_mask - name: RCU_dth1_freq - driver: I2C_RFCHAIN + driver: I2C_RCU devreg: [DTH1.Freq,DTH2.Freq,DTH3.Freq] width: 32 rw: rw @@ -349,6 +336,7 @@ methods: - RCU_ADC_lock: Update - name: RCU_on + driver: I2C_RCU mask: RCU_mask instructions: - IO2.CONF1: 0 #Set device register, can also specify a register adress direction e.g. OIO2.0: 0 @@ -370,7 +358,9 @@ methods: - ADC2_on: 0 - WAIT: 500 #ms to wait - RCU_ADC_lock: Update + - name: ADC1_on + driver: I2C_RCU debug: True # rw: hidden instructions: @@ -379,6 +369,7 @@ methods: # - ADC1.CML_level: 0x7 - ADC1.Update: 1 #Needed to update ADC registers - name: ADC2_on + driver: I2C_RCU debug: True # rw: hidden instructions: diff --git a/i2cserv/CLK.py b/i2cserv/CLK.py deleted file mode 100644 index a775b70b969ee2b37b7bd070c07139be2021b3a3..0000000000000000000000000000000000000000 --- a/i2cserv/CLK.py +++ /dev/null @@ -1,414 +0,0 @@ -#from . import Vars -import numpy as np -import logging -from .spibitbang2 import * -#import threading - - -def ApplyMask(value,width=8,bitoffset=0,previous=0): - mask=(1<<width)-1 - if bitoffset>0: - value<<=bitoffset; - mask<<=bitoffset; - return (value & mask) + (previous - (previous & mask)); -def UnMask(value,width=8,bitoffset=0): - mask=(1<<width)-1 - if bitoffset>0: - value>>=bitoffset; - value=value&mask; - return value; - -def bytes2int(bts): - x=0; - for b in bts: - x=x*256+b; - return x; -def int2bytes(i): - b=[]; - while i>255: - b=[i%256]+b; - 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 [ord(c.encode('utf-8')[0]) for s in var for c in s] - return [c.encode('utf-8')[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 [(bytearray(var[i*step:(i+1)*step]).decode("utf-8")) for i in range(cnt)] - -class RCU1(): - def __init__(self,number,I2Ccallback,Switchcallback): - self.N=number; - self.I2Ccallback=I2Ccallback - self.SWcallback=Switchcallback - self.previous =np.zeros([number,Vars.RCU_storeReg],dtype='int') - self.previousHBA=np.zeros([number,3,32],dtype='int') - - def load(self): - Inst1=Vars.Instr(Vars.DevType.Instr,Vars.RCU_init,0,[]) #Read the current status of GPIO IOs - self.SetVar(Inst1) -#Vars.RCU_mask.OPCW.get_data_value().Value.Value=[1,1,0,0] -#Vars.Ant_mask.OPCW.get_data_value().Value.Value=[1,1,0,0,0,0,0,0,0,0,1,0] - -#Inst1=Vars.Instr(Vars.DevType.Instr,Vars.RCU_init,0,[]) #Read the current status of GPIO IOs -#RCU.SetVar(Inst1) - -#Inst1=Vars.Instr(Vars.DevType.Var,Vars.RCU_att,12,[0,1,2,3,4,5,6,7,8,9,11]) -#RCU.SetVar(Inst1) - -#Inst1=Vars.Instr(Vars.DevType.Instr,Vars.RCU_off,0,[]) -#RCU.SetVar(Inst1) - -#Inst1=Vars.Instr(Vars.DevType.Instr,Vars.RCU_on,0,[]) -#RCU.SetVar(Inst1) - -#Inst1=Vars.Instr(Vars.DevType.Instr,Vars.ADC1_on,0,[]) -#RCU.SetVar(Inst1) - -#print(Vars.RCU) - - def SetVar(self,Instr,Mask=[]): -# Instr.value=strs2bytes(Instr.value) #Alwast be an array of bytes - if (self.N==1): Mask=[True] - if Instr.type==Vars.DevType.Instr: - #Execute instructions - Iset=Instr.dev; - if len(Mask)==0: Mask=Vars.RCU_mask.OPCW.get_value() - for i in Iset.instr: - logging.debug(str(("Inst",i))) - self.SetVar(i,Mask=Mask) - return; - if Instr.type in [Vars.DevType.I2C,Vars.DevType.SPIbb,Vars.DevType.I2Cbb]: - if len(Mask)==0: Mask=Vars.RCU_mask.OPCW.get_value() - mask=0; - RCU0=-1; - for RCUi in range(self.N): - if (Mask[RCUi]): - mask|=1<<Vars.RCU_MPaddr.Switch[RCUi] - if RCU0<0: RCU0=RCUi; - if RCU0<0: return; #Mask all zero - 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,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,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,strs2bytes(Instr.value)) - return; - V1=Instr.dev - 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: - Instr.dev.OPCW.set_value(Instr.value) - logging.debug("Update internal variable") - return -# if V1.Vars[0].type==Vars.DevType.Internal: return; - Step=V1.nVars - Step2=int(V1.size/V1.nVars) - if (self.N>1): - Mask=(Vars.RCU_mask if Step==1 else Vars.Ant_mask) - Mask=Mask.OPCW.get_value() - value1=strs2bytes(Instr.value) if V1.OPCR is None else strs2bytes(V1.OPCR.get_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 - 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[i0:i1]=value2 - if not(V1.OPCR is None): V1.OPCR.set_value(bytes2strs(value1,Step2,V1.type)) - - elif Instr.type==Vars.DevType.VarUpdate: - if self.N==1: - for Vari in range(Step): - i0=(Vari)*Step2 - i1=(Vari+1)*Step2 - value2=value1[i0:i1] - self.GetVarValue(0,V1.Vars[Vari],value2) - value1[i0:i1]=value2 - if not(V1.OPCR is None): V1.OPCR.set_value(bytes2strs(value1,Step2,V1.type)) - else: - self.GetVarValueAll(V1,value1) -# if not(V1.OPCR is None): V1.OPCR.get_data_value().Value.Value=bytes2strs(value1,Step2,V1.type) - if not(V1.OPCR is None): V1.OPCR.set_value(bytes2strs(value1,Step2,V1.type)) -# V1.OPCR.get_data_value().Value.Value=value1 - - logging.info(str(('** Readback:',V1.name,value1))) - - def GetVarValue(self,RCUi,var,value): - logging.info(str(("RCU1 Get ",RCUi,var,value))) - if var.type==Vars.DevType.I2C: - self.SWcallback(1<<Vars.RCU_MPaddr.Switch[RCUi]) - self.GetI2C(RCUi,var.devreg,var.width,var.bitoffset,value) - elif var.type==Vars.DevType.HBA1: - self.SWcallback(1<<Vars.RCU_MPaddr.Switch[RCUi]) - self.GetI2CHBA1(RCUi,var.devreg,var.width,var.bitoffset,value) - elif var.type==Vars.DevType.I2Cbb: - logging.error("I2Cbb Implemented") - elif var.type==Vars.DevType.SPIbb: - self.SWcallback(1<<Vars.RCU_MPaddr.Switch[RCUi]) - GetSPIbb(self.SetI2C,self.GetI2C,RCUi,var.devreg,value) - else: - logging.error("Not Implemented") - - def GetVarValueAll(self,V1,value1): - mask=0; - 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 - self.SWcallback(mask) - self.SetI2CAddr(self,DevReg) - 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]) - 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) -# print(value2) - if (var.Scale!=0): value2[0]*=var.Scale; - value1[i0:i1]=value2 - elif V1.Vars[0].type==Vars.DevType.SPIbb: - self.GetBBValueAll(V1,value1,mask) -# logging.info("SPIbb all not implemented yet") - elif V1.Vars[0].type==Vars.DevType.HBA1: - for Vari in range(Step): - var=V1.Vars[Vari] - for RCUi in range(self.N): - self.SWcallback(1<<Vars.RCU_MPaddr.Switch[RCUi]) -# print(Step,Step2,len(value1),V1.size) - i0=(RCUi*Step+ Vari)*Step2 - i1=(RCUi*Step+(Vari+1))*Step2 - value2=value1[i0:i1] - self.GetI2CHBA1(RCUi,var.devreg,var.width,var.bitoffset,value2) - value1[i0:i1]=value2 -# i0=(RCUi*Step+ Vari)*Step2+16 -# i1=(RCUi*Step+(Vari+1))*Step2 -# value2=value1[i0:i1] -# self.GetI2Cnoreg(RCUi,var.devreg,var.width,var.bitoffset,value2) -# value1[i0:i1]=value2 - else: - logging.error("Type not implemented") -# print(value1) - def GetBBValueAll(self,V1,value1,mask): - def SetBit(RCUi,dev,width,bitoffset,value,buffer=False): - if not(buffer): self.SWcallback(mask) - self.SetI2C(RCUi,dev,width,bitoffset,value,buffer=buffer) - def GetBit(RCUixx,dev,width,bitoffset,buffer=False): - value=[0 for RCUi in range(self.N)] - value2=[0] - if buffer: - for RCUi in range(self.N): - self.GetI2Cbuffer(RCUi,dev,width,bitoffset,value2) - value[RCUi]=value2[0] - return value - self.SWcallback(mask) - self.SetI2CAddr(self,dev) - for RCUi in range(self.N): - self.SWcallback(1<<Vars.RCU_MPaddr.Switch[RCUi]) - #for i in range(len(value2)): value2[i]*=0; - value2[0]=0 - self.GetI2Cnoreg(RCUi,dev,width,bitoffset,value2) - value[RCUi]=value2[0] - return value; - devs=[V1.Vars[Vari].devreg for Vari in range(V1.nVars)] - GetSPIbb2(SetBit,GetBit,0,devs,value1) - - - def SetVarValue(self,RCUi,var,value): - if var.devreg.Register_W==-1: return True; #We can not set it, only read it e.g. temperature - logging.debug(str(("RCU1 Set ",RCUi,var,value))) - if var.type==Vars.DevType.I2C: - self.SWcallback(1<<Vars.RCU_MPaddr.Switch[RCUi]) - self.SetI2C(RCUi,var.devreg,var.width,var.bitoffset,value) - elif var.type==Vars.DevType.HBA1: - self.SWcallback(1<<Vars.RCU_MPaddr.Switch[RCUi]) - self.SetHBA1I2C(RCUi,var.devreg,var.width,var.bitoffset,value) -# print("RCU1 Set",RCUi,var,value) - elif var.type==Vars.DevType.I2Cbb: - logging.error("I2Cbb Implemented") - elif var.type==Vars.DevType.SPIbb: - logging.error("SPIbb Implemented") - else: - logging.error("Not Implemented") - - def SetI2C(self,RCUi,dev,width,bitoffset,value,buffer=False): - if dev.store>0: - previous=self.previous[RCUi,dev.store-1]; - value[0]=ApplyMask(value[0],width,bitoffset,previous); - self.previous[RCUi,dev.store-1]=value[0] -# logging.debug(str(('masked to',value))) -# logging.debug(str(("Store buffer",RCUi,dev.store,value[0]))) - if buffer: return True; - return self.I2Ccallback(dev.Addr,value,reg=dev.Register_W) - - def SetHBA1I2C(self,RCUi,dev,width,bitoffset,value,buffer=False): -# if dev.store>0: - previous=self.previousHBA[RCUi,dev.store-1]; - L=len(value) - for i in range(L): - value[i]=ApplyMask(value[i],width,bitoffset,previous[i]); - self.previousHBA[RCUi,dev.store-1]=value -# if buffer: return True; - self.I2Ccallback(dev.Addr,value[:16],reg=dev.Register_W) - if L>16: self.I2Ccallback(dev.Addr,value[16:],reg=dev.Register_W+16) - self.I2Ccallback(dev.Addr,[500],reg=dev.Register_W,read=3) #Wait 500ms - return True -# return self.I2Ccallback(dev.Addr,value,reg=dev.Register_W) - - def GetI2Cbuffer(self,RCUi,dev,width,bitoffset,value): - if not(dev.store>0): return False; - value[0]=self.previous[RCUi,dev.store-1]; -# logging.debug(str(("GetI2Cbuffer",RCUi,dev.store,value))) - l1=int(np.floor((width+bitoffset+7)/8)) - if (width!=l1*8) or (bitoffset>0): - for i in range(len(value)): - value[i]=UnMask(value[i],width,bitoffset) - return True - - def GetI2C(self,RCUi,dev,width,bitoffset,value): -# if dev.store>0: -# value[0]=self.previous[RCUi,dev.store-1] -# return True - l1=int(np.floor((width+bitoffset+7)/8)) -# print(width,bitoffset,l1) - makesinglevalue=((len(value)==1) and (l1>1)); - if makesinglevalue: value2=[0 for x in range(l1)] - else: value2=value - reg=dev.Register_R - if reg>255: #This is for the monitor ADC - if not(self.I2Ccallback(dev.Addr,int2bytes(reg),read=2)): return False; - I2Ccallback(Addr,[250],read=3) - if not(self.I2Ccallback(dev.Addr,value2,read=1)): return False; - else: - if not(self.I2Ccallback(dev.Addr,value2,reg=reg,read=1)): return False; - if value2[0] is None: return False - if makesinglevalue: value[0]=bytes2int(value2) - else: value[:]=value2[:]; - if dev.store>0: - self.previous[RCUi,dev.store-1]=value[0] -# logging.debug(str(("Store buffer",RCUi,dev.store,value[0]))) - if (width!=l1*8) or (bitoffset>0): - for i in range(len(value)): - value[i]=UnMask(value[i],width,bitoffset) - else: value[0]=value2[0] - return True; - def GetI2Cbit(self,RCUi,dev,pin): - value2=[value] - self.I2CGet(RCUi,dev,1,1<<pin,value2) - return value2[0] - - - def SetI2CAddr(self,RCUi,dev): - return self.I2Ccallback(dev.Addr,int2bytes(dev.Register_R),read=2) - - - - def GetI2Cnoreg(self,RCUi,dev,width,bitoffset,value): - #print(width,len(value)) - l1=int(np.floor((width+bitoffset+7)/8)) - makesinglevalue=((len(value)==1) and (l1>1)); - if makesinglevalue: value2=[0 for x in range(l1)] - else: value2=value - reg=dev.Register_R - if not(self.I2Ccallback(dev.Addr,value2,read=1)): return False; - if value2[0] is None: return False - if makesinglevalue: value[0]=bytes2int(value2) - else: value[:]=value2[:]; - if dev.store>0: - self.previous[RCUi,dev.store-1]=value[0] -# logging.debug(str(("Store buffer",RCUi,dev.store,value[0]))) -# if width<8: - if (width!=l1*8) or (bitoffset>0): - for i in range(len(value)): - value[i]=UnMask(value[i],width,bitoffset) -# value[0]=UnMask(value[0],width,bitoffset) - #else: value[0]=value2[0] - #if (len(value)>1) and (width<8): print value - return True; - - def GetI2CHBA1(self,RCUi,dev,width,bitoffset,value): - #print(width,len(value)) - value2=value - reg=dev.Register_R - if not(self.I2Ccallback(dev.Addr,value2,read=1)): return False; - if value2[0] is None: return False - value[:]=value2[:]; - if dev.store>0: - self.previousHBA[RCUi,dev.store-1]=value - for i in range(len(value)): - value[i]=UnMask(value[i],width,bitoffset) - return True; - - - def start(self,Q1): - def RCUthread(Q1): - while True: - item = Q1.get() - if item is None: break; - self.SetVar(item) - logging.info("End RCU thread") - - RCUthread1 = threading.Thread(target=RCUthread, args=(Q1,)) - RCUthread1.start() - - return RCUthread1 - - def Queue_Monitor(self,Q1,NRCU): -# Inst1=Vars.Instr(Vars.DevType.VarUpdate,Vars.RCU_temp,NRCU,[0]*NRCU) -# Q1.put(Inst1) -# Inst1=Vars.Instr(Vars.DevType.VarUpdate,Vars.RCU_ADC_lock,96,[0]*96) -# Q1.put(Inst1) - return - def AddVars(self,Q1,AddVarR,AddVarW): - for v in Vars.OPC_devvars: - 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=0 - if v.type==Vars.datatype.dInt: varvalue2=dim2*[0] - elif v.type==Vars.datatype.dbool: varvalue2=dim2*[False] - 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,dim2,varvalue2) - Q1.put(Inst) - - if v.RW in [Vars.RW.WriteOnly,Vars.RW.ReadWrite]: - var1=AddVarW(v.name+"_RW",varvalue2,v,Q1) - v.OPCW=var1 - - def AddMethod(self,Q1,Addmethod): - for v in Vars.OPC_methods: - Inst1=Vars.Instr(Vars.DevType.Instr,v,0,[]) - Addmethod(v.name,Inst1,Q1) diff --git a/i2cserv/I2C.py b/i2cserv/I2C.py deleted file mode 100644 index d3a60c9655f3b77cb094800511f99f5b6b41dd3b..0000000000000000000000000000000000000000 --- a/i2cserv/I2C.py +++ /dev/null @@ -1,100 +0,0 @@ -if os.sys.platform is 'linux': - import pylibi2c; -import time -import logging -#bus = pylibi2c.I2CDevice('/dev/i2c-1' -#read=0: write to register -#read=1: read from register -#read=2: write to register (common in group) -#read=3: wait ms second -I2Ccounter=0; - -def I2C1server(addr,data,reg=None,read=0): -# print("I2C",addr,reg,data,read) - try: - if read==3: - time.sleep(data[0]/1000.) - return True - logging.debug(str(("I2C",addr,reg,data,read))) - -# return True; - bus=pylibi2c.I2CDevice('/dev/i2c-1',addr) - if read==1: - length=len(data) - bus.iaddr_bytes=0 - if not(reg is None): - bus.ioctl_write(0,str(bytearray([reg]))) - data[:]=[int(x) for x in bus.ioctl_read(0,length)] -# 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))) - bus.close() - return True; - except: - if bus: bus.close() -# data[0]=0xff - return False; - -def I2C4server(addr,data,reg=None,read=0): -# print("I2C4",addr,reg,data,read) - try: - if read==3: - time.sleep(data[0]/1000.) - return True - logging.debug(str(("I2C",addr,reg,data,read))) - -# print("I2C",addr,reg,data,read) -# return True; - bus=pylibi2c.I2CDevice('/dev/i2c-4',addr) - if read==1: - length=len(data) - bus.iaddr_bytes=0 - if not(reg is None): - bus.ioctl_write(0,str(bytearray([reg]))) - data[:]=[int(x) for x in bus.ioctl_read(0,length)] -# print(data) - else: - if reg is None: - bus.iaddr_bytes=0 - reg=0; - bus.ioctl_write(reg,str(bytearray(data))) - bus.close() - return True; - except: - if bus: bus.close() -# data[0]=0 - return False; - - -def I2C2server(addr,data,reg=None,read=0): - try: - if read==3: - time.sleep(data[0]/1000.) - return True - logging.debug(str(("I2C2",addr,reg,data,read))) - -# print("I2C",addr,reg,data,read) -# return True; - bus=pylibi2c.I2CDevice('/dev/i2c-2',addr) - if read==1: - length=len(data) - bus.iaddr_bytes=0 - if not(reg is None): - bus.ioctl_write(0,str(bytearray([reg]))) - data[:]=[int(x) for x in bus.ioctl_read(0,length)] - else: - if reg is None: - bus.iaddr_bytes=0 - reg=0; - bus.ioctl_write(reg,str(bytearray(data))) - bus.close() - return True; - except: - if bus: bus.close() - print("I2C4 error") -# data[0]=0xff - return False; - diff --git a/i2cserv/I2C_dummy.py b/i2cserv/I2C_dummy.py deleted file mode 100644 index a085ae1eed655c14d45a6ca19687d78c16060659..0000000000000000000000000000000000000000 --- a/i2cserv/I2C_dummy.py +++ /dev/null @@ -1,34 +0,0 @@ -#import pylibi2c; -import time -import logging -#bus = pylibi2c.I2CDevice('/dev/i2c-1' -#read=0: write to register -#read=1: read from register -#read=2: write to register (common in group) -#read=3: wait ms second -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 - if read==1: - data[0]=0 - if reg: I2Ccounter+=1; - I2Ccounter+=len(data) - logging.warn(str(("I2C",addr,reg,data,read))) - return True - -def I2C4server(addr,data,reg=None,read=0): - global I2Ccounter; - logging.debug(str(("I2C4",addr,reg,data,read))) - if read==3: - time.sleep(data[0]/1000.) - return True - if read==1: - data[0]=0 - if reg: I2Ccounter+=1; - I2Ccounter+=len(data) -# logging.debug(str(("I2C",addr,reg,data,read))) - return True diff --git a/i2cserv/I2Cswitch1.py b/i2cserv/I2Cswitch1.py deleted file mode 100644 index 187456b1d6cc9eb2d15330d216ff89e72fe42a18..0000000000000000000000000000000000000000 --- a/i2cserv/I2Cswitch1.py +++ /dev/null @@ -1,27 +0,0 @@ -import numpy as np -import logging -#import HWconf -SWaddr=0x70 -class I2Cswitch1(): - def __init__(self,callback1): - self.callback1=callback1; - self.CurrentChannel=0; - - def SetChannel(self,channel): - if (channel)==self.CurrentChannel: return True; - logging.debug(str(("SetChannel",channel,self.CurrentChannel))) - self.CurrentChannel=channel - return self.callback1(SWaddr,[channel]) - - def I2Ccallback(self,RCU,addr,data,reg=None,read=0): - self.callback1(addr,data,reg,read) - -class I2Cswitch0(): - def __init__(self,callback1): - return - - def SetChannel(self,channel): - return True - - def I2Ccallback(self,RCU,addr,data,reg=None,read=0): - return \ No newline at end of file diff --git a/i2cserv/RCU.py b/i2cserv/RCU.py deleted file mode 100644 index b0678b8ccb7213ca7babe3c34f7eba40ea3941dd..0000000000000000000000000000000000000000 --- a/i2cserv/RCU.py +++ /dev/null @@ -1,535 +0,0 @@ -#from . import Vars -import numpy as np -import logging -from .spibitbang1 import * -#import threading -import time -#from multiprocessing import Process -from pcctypes import * -from queuetypes import * - -RCU_Switch=[0,1,2,3,4,5,6,7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5] - -def ApplyMask(value,width=8,bitoffset=0,previous=0): - mask=(1<<width)-1 - if bitoffset>0: - value<<=bitoffset; - mask<<=bitoffset; - return (value & mask) + (previous - (previous & mask)); -def UnMask(value,width=8,bitoffset=0): - mask=(1<<width)-1 - if bitoffset>0: - value>>=bitoffset; - value=value&mask; - return value; - -def bytes2int(bts): - x=0; - for b in bts: - x=x*256+b; - return x; -def int2bytes(i): - b=[]; - while i>255: - b=[i%256]+b; - 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 [ord(c.encode('utf-8')[0]) for s in var for c in s] - return [c.encode('utf-8')[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 [(bytearray(var[i*step:(i+1)*step]).decode("utf-8")) for i in range(cnt)] -def GetField(D,name,dev_number,default=None): - X=D.get(name,default) - return X[dev_number] if isinstance(X,list) else X; -def Find(L,name,value): - for x in L: - if x[name]==value: - return x; - return False; - -class AttrDict(dict): - def __init__(self,*args,**kwargs): - super(AttrDict,self).__init__(*args,**kwargs) - self.__dict__=self - -def DevRegList(D): - for i,dev in enumerate(D.drivers): - dev['drv_id']=i; - devreglist={} - store=0; - for dev in D.device_registers: - N=dev.get('dim',1) - name=dev['name'] - for n in range(N): - addr=GetField(dev,'address',n,0) - devtype=GetField(dev,'driver',n) - print(addr,devtype) - devid=0; - if devtype: - devid=Find(D.drivers,'name',devtype)['drv_id'] - devtype=Find(D.drivers,'name',devtype)['type'] - else: devtype=0; - if N>1: name2=name+str(n+1) - else: name2=name; - for reg in dev['registers']: - regR=GetField(reg,'address',0,0) - regW=GetField(reg,'address',1,0) - if reg.get('store',False): - store+=1; - storex=store - else: - storex=0 -# hf.write("const devreg %s {%i,%i,%i,%i,%i};\n" % (name2+'_'+reg['name'],addr,regR,regW,storex,devtype) ) - devregname=name2+'.'+reg['name']; - devreglist[devregname]=AttrDict({"Addr":addr,"Register_R":regR,"Register_W":regW,"store":storex,"devtype":devtype,"devid":devid}); - print(devregname,devreglist[devregname]); -# 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) -# print(devreglist) - return devreglist,store - -def GetSteps(V1): - if isinstance(V1['devreg'],list): Step=len(V1['devreg']) - else: Step=1; #V1.nVars - Step2=V1['dim']*((V1.get('width',8)+7)//8)//Step #int(V1.size/V1.nVars) - print(Step,Step2,V1); - return Step,Step2 - - -class RCU1(): - def __init__(self,number,I2Ccallback,Switchcallback,config,Qin,Qout): - self.Qout=Qout; - self.Qin=Qin; - self.conf=config - self.devregs,RCU_storeReg=DevRegList(config) - self.N=number; - self.I2Ccallback=I2Ccallback - self.SWcallback=Switchcallback - self.previous =np.zeros([number,RCU_storeReg],dtype='int') - self.previousHBA=np.zeros([number,3,32],dtype='int') - - def load(self): - print("TODO: load") - #Inst1=Vars.Instr(Vars.DevType.Instr,Vars.RCU_init,0,[]) #Read the current status of GPIO IOs - #self.SetVar(Inst1) -#Vars.RCU_mask.OPCW.get_data_value().Value.Value=[1,1,0,0] -#Vars.Ant_mask.OPCW.get_data_value().Value.Value=[1,1,0,0,0,0,0,0,0,0,1,0] - -#Inst1=Vars.Instr(Vars.DevType.Instr,Vars.RCU_init,0,[]) #Read the current status of GPIO IOs -#RCU.SetVar(Inst1) - -#Inst1=Vars.Instr(Vars.DevType.Var,Vars.RCU_att,12,[0,1,2,3,4,5,6,7,8,9,11]) -#RCU.SetVar(Inst1) - -#Inst1=Vars.Instr(Vars.DevType.Instr,Vars.RCU_off,0,[]) -#RCU.SetVar(Inst1) - -#Inst1=Vars.Instr(Vars.DevType.Instr,Vars.RCU_on,0,[]) -#RCU.SetVar(Inst1) - -#Inst1=Vars.Instr(Vars.DevType.Instr,Vars.ADC1_on,0,[]) -#RCU.SetVar(Inst1) - -#print(Vars.RCU) - def OPCUASetVariable(self,varid,var1,data,mask): - if var1['rw']=='variable': return; - print("Set Var",var1) - data=self.SetGetVarValueMask(var1,data,mask); - Data=OPCUAset(varid,InstType.varSet,data,mask) - self.Qout.put(Data); - - def OPCUAReadVariable(self,varid,var1,data,mask): - print("Read Var",var1,data,mask) - if len(mask)==0: data=self.GetVarValueAll(var1) - else: data=self.GetVarValueMask(var1,mask); - Data=OPCUAset(varid,InstType.varSet,data,mask) - self.Qout.put(Data); - - def OPCUAcallMethod(self,var1,data,mask): - print("Call Method",var1) - - def SetGetVarValueMask(self,var1,data,mask): - Step,Step2=GetSteps(var1); - value1=[0]*Step*Step2; - if not(len(data)==Step*Step2): - print("Check data length!"); - return; - Step2//=self.N - if not(len(mask)==Step*self.N): - print("Check mask length!"); - return; -# if (len(value1)==V1.nVars) and (self.N>1): value1=(value1*self.N); - for RCUi in range(self.N): - for Vari in range(Step): - if not(mask[RCUi*Step+Vari]): continue - i0=(RCUi*Step+ Vari)*Step2 - i1=(RCUi*Step+(Vari+1))*Step2 - devreg=self.GetDevReg(var1['devreg'],Vari); - width=var1.get('width',8) - bitoffset=GetField(var1,'bitoffset',Vari,0) - self.SetVarValue(RCUi,devreg,width,bitoffset,data[i0:i1]) - value2=value1[i0:i1] - self.GetVarValue(RCUi,devreg,width,bitoffset,value2) - value1[i0:i1]=value2 - return value1 - - def SetVarValue(self,RCUi,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 ",RCUi,devreg,value))) - if devreg.devid==0: - self.SWcallback(1<<RCU_Switch[RCUi]) - self.SetI2C(RCUi,devreg,width,bitoffset,value) - elif devreg.devtype[:3]=='hba': - self.SWcallback(1<<RCU_Switch[RCUi]) - self.SetHBA1I2C(RCUi,devreg,width,bitoffset,value) -# print("RCU1 Set",RCUi,var,value) - elif devreg.devtype[:4]=='i2cb': - logging.error("I2Cbb Implemented") - elif devreg.devtype[:3]=='spi': - logging.error("SPIbb Implemented") - else: - logging.error("Not Implemented") - - def GetVarValue(self,RCUi,devreg,width,bitoffset,value): - logging.info(str(("RCU1 Get ",RCUi,devreg,value))) - if devreg.devid==0: - self.SWcallback(1<<RCU_Switch[RCUi]) - self.GetI2C(RCUi,devreg,width,bitoffset,value) - elif devreg.devtype[:3]=='hba': - self.SWcallback(1<<RCU_Switch[RCUi]) - self.GetI2CHBA1(RCUi,devreg,width,bitoffset,value) - elif devreg.devtype[:4]=='i2cb': - logging.error("I2Cbb Implemented") - elif devreg.devtype[:3]=='spi': - logging.error("SPIbb Implemented") - else: - logging.error("Not Implemented") - - - def SetVar(self,Instr,Mask=[]): -# Instr.value=strs2bytes(Instr.value) #Alwast be an array of bytes - if Instr.type==Vars.DevType.Wait: -# time.sleep(Instr.value[0]/1000.) - print("Sleep",Instr.value[0]/1000.,"s") - return; - if Instr.type==Vars.DevType.Instr: - #Execute instructions - Iset=Instr.dev; - #if len(Mask)==0: Mask=Vars.RCU_mask.OPCW.get_value() - print("TODO: Lenmask=0"); - for i in Iset.instr: - logging.debug(str(("Inst",i))) - self.SetVar(i,Mask=Mask) - return; - if Instr.type in [Vars.DevType.I2C,Vars.DevType.SPIbb,Vars.DevType.I2Cbb]: -## if len(Mask)==0: Mask=Vars.RCU_mask.OPCW.get_value() - print("TODO: Lenmask=0"); - mask=0; - RCU0=-1; - for RCUi in range(self.N): - if (Mask[RCUi]): - mask|=1<<RCU_Switch[RCUi] - if RCU0<0: RCU0=RCUi; - if RCU0<0: return; #Mask all zero - 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,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,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,strs2bytes(Instr.value)) - return; - V1=Instr.dev -# print(Instr.nvalue,V1.nVars,V1.size) - 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: - Instr.dev.OPCW.set_value(Instr.value) - logging.debug("Update internal variable") - 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_value() - print("TODO: check mask"); - value1=strs2bytes(Instr.value) if V1.OPCR is None else strs2bytes(V1.OPCR.get_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 - 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[i0:i1]=value2 - if not(V1.OPCR is None): V1.OPCR.set_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=bytes2strs(value1,Step2,V1.type) - if not(V1.OPCR is None): V1.OPCR.set_value(bytes2strs(value1,Step2,V1.type)) -# V1.OPCR.get_data_value().Value.Value=value1 - - logging.info(str(('** Readback:',V1.name,value1))) - - - def GetDevReg(self,devreg1,n): - if isinstance(devreg1,list): devreg1=devreg1[n]; - devreg=self.devregs[devreg1]; -# print(devreg); - return(devreg); -# devreg=Find(self.conf.device_registers,'name',devreg) -# if devreg: return devreg; -# devreg=Find(self.conf.device_registers,'name',devreg[-1]) - - - def GetVarValueAll(self,V1): - mask=0; - for RCUi in range(self.N): - mask|=1<<RCU_Switch[RCUi] - Step,Step2=GetSteps(V1); - value1=[0]*Step*Step2; - Step2//=self.N - devreg1=self.GetDevReg(V1['devreg'],0); -# return - if devreg1.devid==0: #I2C - for Vari in range(Step): - DevReg=self.GetDevReg(V1['devreg'],Vari); - self.SWcallback(mask) - self.SetI2CAddr(self,DevReg) - if DevReg.Register_R>255: self.I2Ccallback(DevReg.Addr,[250],read=3) #Wait for ADC - for RCUi in range(self.N): - self.SWcallback(1<<RCU_Switch[RCUi]) - 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,DevReg,V1.get('width',8),GetField(V1,'bitoffset',Vari,0),value2) - #print(value2) - value1[i0:i1]=value2 - elif devreg1.devtype[:3]=='spi': - self.GetBBValueAll(V1,value1,mask) -# logging.info("SPIbb all not implemented yet") - elif devreg1.devtype=='hba1': - logging.info("HBA1 all not implemented yet") - return - for Vari in range(Step): - var=V1.Vars[Vari] -# self.SWcallback(mask) -# self.SetI2CAddr(self,DevReg) - for RCUi in range(self.N): - self.SWcallback(1<<RCU_Switch[RCUi]) -# print(Step,Step2,len(value1),V1.size) - WX=[0] - self.I2Ccallback(0x40,WX,reg=0,read=1)#wakeup, do nothing - self.I2Ccallback(0x40,[10],read=3) - i0=(RCUi*Step+ Vari)*Step2 - i1=(RCUi*Step+(Vari+1))*Step2 - value2=value1[i0:i1] - self.GetI2CHBA1(RCUi,var.devreg,var.width,var.bitoffset,value2) - value1[i0:i1]=value2 -# i0=(RCUi*Step+ Vari)*Step2+16 -# i1=(RCUi*Step+(Vari+1))*Step2 -# value2=value1[i0:i1] -# self.GetI2Cnoreg(RCUi,var.devreg,var.width,var.bitoffset,value2) -# value1[i0:i1]=value2 - else: - logging.error("Type not implemented") -# print(value1) - return value1; - - def GetBBValueAll(self,V1,value1,mask): - def SetBit(RCUi,dev,width,bitoffset,value,buffer=False): - if not(buffer): self.SWcallback(mask) - self.SetI2C(RCUi,dev,width,bitoffset,value,buffer=buffer) - def GetBit(RCUixx,dev,width,bitoffset,buffer=False): - value=[0 for RCUi in range(self.N)] - value2=[0] - if buffer: - for RCUi in range(self.N): - self.GetI2Cbuffer(RCUi,dev,width,bitoffset,value2) - value[RCUi]=value2[0] - return value - self.SWcallback(mask) - self.SetI2CAddr(self,dev) - for RCUi in range(self.N): - self.SWcallback(1<<RCU_Switch[RCUi]) - #for i in range(len(value2)): value2[i]*=0; - value2[0]=0 - self.GetI2Cnoreg(RCUi,dev,width,bitoffset,value2) - value[RCUi]=value2[0] - return value; - Step,Step2=GetSteps(V1); - SPIdevs=[self.GetDevReg(V1['devreg'],Vari) for Vari in range(Step)] - I2Cdevs=[self.conf.drivers[d['devid']]['devreg'] for d in SPIdevs] - I2Cpins=[self.conf.drivers[d['devid']]['parameters'] for d in SPIdevs] - I2Cdevs=[[self.devregs[dr1] for dr1 in dr2] for dr2 in I2Cdevs] -# I2Cpins=np.array(I2Cpins).T - #for parallel acces, we assume devs and devs2 are the same, only pins are different - GetSPIbb2(SetBit,GetBit,0,SPIdevs,I2Cdevs,I2Cpins,value1) - - def SetI2C(self,RCUi,dev,width,bitoffset,value,buffer=False): - if dev.store>0: - previous=self.previous[RCUi,dev.store-1]; - value[0]=ApplyMask(value[0],width,bitoffset,previous); - self.previous[RCUi,dev.store-1]=value[0] -# logging.debug(str(('masked to',value))) -# logging.debug(str(("Store buffer",RCUi,dev.store,value[0]))) - if buffer: return True; - return self.I2Ccallback(dev.Addr,value,reg=dev.Register_W) - - def SetHBA1I2C(self,RCUi,dev,width,bitoffset,value,buffer=False): -# if dev.store>0: - previous=self.previousHBA[RCUi,dev.store-1]; - L=len(value) - for i in range(L): - value[i]=ApplyMask(value[i],width,bitoffset,previous[i]); - self.previousHBA[RCUi,dev.store-1]=value -# if buffer: return True; - print("HBA set:",value); - XX=[0] - self.I2Ccallback(0x40,XX,reg=0,read=1)#wakeup, do nothing - self.I2Ccallback(dev.Addr,[10],read=3) - self.I2Ccallback(dev.Addr,value[:16],reg=dev.Register_W) - if L>16: - self.I2Ccallback(dev.Addr,[10],read=3) - self.I2Ccallback(dev.Addr,value[16:],reg=dev.Register_W+16) - self.I2Ccallback(dev.Addr,[600],read=3) #Wait 500ms - return True -# return self.I2Ccallback(dev.Addr,value,reg=dev.Register_W) - - def GetI2Cbuffer(self,RCUi,dev,width,bitoffset,value): - if not(dev.store>0): return False; - value[0]=self.previous[RCUi,dev.store-1]; -# logging.debug(str(("GetI2Cbuffer",RCUi,dev.store,value))) - l1=int(np.floor((width+bitoffset+7)/8)) - if (width!=l1*8) or (bitoffset>0): - for i in range(len(value)): - value[i]=UnMask(value[i],width,bitoffset) - return True - - def GetI2C(self,RCUi,dev,width,bitoffset,value): -# if dev.store>0: -# value[0]=self.previous[RCUi,dev.store-1] -# return True - l1=int(np.floor((width+bitoffset+7)/8)) -# print(width,bitoffset,l1) - makesinglevalue=((len(value)==1) and (l1>1)); - if makesinglevalue: value2=[0 for x in range(l1)] - else: value2=value - reg=dev.Register_R - if reg>255: #This is for the monitor ADC - if not(self.I2Ccallback(dev.Addr,int2bytes(reg),read=2)): return False; - I2Ccallback(Addr,[250],read=3) - if not(self.I2Ccallback(dev.Addr,value2,read=1)): return False; - else: - if not(self.I2Ccallback(dev.Addr,value2,reg=reg,read=1)): return False; - if value2[0] is None: return False - if makesinglevalue: value[0]=bytes2int(value2) - else: value[:]=value2[:]; - if dev.store>0: - self.previous[RCUi,dev.store-1]=value[0] -# logging.debug(str(("Store buffer",RCUi,dev.store,value[0]))) - if (width!=l1*8) or (bitoffset>0): - for i in range(len(value)): - value[i]=UnMask(value[i],width,bitoffset) - else: value[0]=value2[0] - return True; - def GetI2Cbit(self,RCUi,dev,pin): - value2=[value] - self.I2CGet(RCUi,dev,1,1<<pin,value2) - return value2[0] - - - def SetI2CAddr(self,RCUi,dev): - return self.I2Ccallback(dev.Addr,int2bytes(dev.Register_R),read=2) - - - - def GetI2Cnoreg(self,RCUi,dev,width,bitoffset,value): - #print(width,len(value)) - l1=int(np.floor((width+bitoffset+7)/8)) - makesinglevalue=((len(value)==1) and (l1>1)); - if makesinglevalue: value2=[0 for x in range(l1)] - else: value2=value - reg=dev.Register_R - if not(self.I2Ccallback(dev.Addr,value2,read=1)): return False; - if value2[0] is None: return False - if makesinglevalue: value[0]=bytes2int(value2) - else: value[:]=value2[:]; - if dev.store>0: - self.previous[RCUi,dev.store-1]=value[0] -# logging.debug(str(("Store buffer",RCUi,dev.store,value[0]))) -# if width<8: - if (width!=l1*8) or (bitoffset>0): - for i in range(len(value)): - value[i]=UnMask(value[i],width,bitoffset) -# value[0]=UnMask(value[0],width,bitoffset) - #else: value[0]=value2[0] - #if (len(value)>1) and (width<8): print value - return True; - - def GetI2CHBA1(self,RCUi,dev,width,bitoffset,value): - #print(width,len(value)) - value2=value - reg=dev.Register_R -# if not(self.I2Ccallback(dev.Addr,[],reg=0x0)): return False; - if not(self.I2Ccallback(dev.Addr,value2,read=1)): return False; - if value2[0] is None: return False - value[:]=value2[:]; - print("HBA ",RCUi,dev.Addr," received:",value); -# if dev.store>0: #This is disabled due to noise on readback -# self.previousHBA[RCUi,dev.store-1]=value[:] - for i in range(len(value)): - value[i]=UnMask(value[i],width,bitoffset) - return True; - - - def RCUthread(self,Qin): - while True: - item = Qin.get() - if item is None: break; -# print("TODO: Set busy") -# self.statevar.set_value("busy"); - print("RCU SetVar",item)#,self.conf.variables[item.id]) - if (item.type==InstType.varSet): - var1=self.conf.variables[item.id] - self.OPCUASetVariable(item.id,var1,item.data,item.mask) - elif (item.type==InstType.varRead): - var1=self.conf.variables[item.id] - self.OPCUAReadVariable(item.id,var1,item.data,item.mask) - elif (item.type==InstType.method): - var1=self.conf.methods[item.id] - self.OPCUACallMethod(var1,item.data,item.mask) - else: print("Unknown OPCUA call"); -# print("TODO: Set ready") -# if Qin.qsize()==0: self.statevar.set_value("ready"); - logging.info("End RCU thread") - - def Queue_Monitor(self,Q1,NRCU): - Inst1=Vars.Instr(Vars.DevType.VarUpdate,Vars.RCU_temp,NRCU,[0]*NRCU) - Q1.put(Inst1) - Inst1=Vars.Instr(Vars.DevType.VarUpdate,Vars.RCU_ADC_lock,96,[0]*96) - Q1.put(Inst1) - return diff --git a/i2cserv/hba1.py b/i2cserv/hba1.py new file mode 100644 index 0000000000000000000000000000000000000000..41637ccc1e9d86d2a81351db05bd1839a4215580 --- /dev/null +++ b/i2cserv/hba1.py @@ -0,0 +1,8 @@ +import numpy as np +from .hwdev import hwdev; +import logging +class hba1(hwdev): + def __init__(self,config): + hwdev.__init__(self,config); + logging.info("HBA1 todo") + self.previousHBA=np.zeros([32,3,32],dtype='int') diff --git a/i2cserv/hwdev.py b/i2cserv/hwdev.py new file mode 100644 index 0000000000000000000000000000000000000000..a365a1c16a3508e729ef86f2d9101d338b78c4a8 --- /dev/null +++ b/i2cserv/hwdev.py @@ -0,0 +1,17 @@ + +import logging +class hwdev(): + def __init__(self,config): + #print("Init",config['name']) + self.conf=config + + def OPCUASetVariable(self,varid,var1,data,mask): + logging.warn(self.conf['name']+" OPCUASetVariable Not implemented!") + + def OPCUAReadVariable(self,varid,var1,mask): + logging.warn(self.conf['name']+" OPCUAReadVariable Not implemented!") + return [] + + def OPCUAcallMethod(self,var1,data,mask): + logging.warn(self.conf['name']+" OPCUAcallVariable Not implemented!") + return [] diff --git a/i2cserv/i2c.py b/i2cserv/i2c.py new file mode 100644 index 0000000000000000000000000000000000000000..490d20cbc71f8f17c7caad7826a54a499483af61 --- /dev/null +++ b/i2cserv/i2c.py @@ -0,0 +1,48 @@ +import os +if os.sys.platform is 'linux': + import pylibi2c; +import time +import logging +#read=0: write to register +#read=1: read from register +#read=2: write to register (common in group) +#read=3: wait ms second +from .hwdev import hwdev; + +class i2c(hwdev): + def __init__(self,config): + hwdev.__init__(self,config); + self.I2Cdev='/dev/i2c-'+str(config['parameters'][0]); + logging.info("i2c driver on port "+str(self.I2Cdev)) + self.I2Ccounter=0 + + def i2csetget(self,addr,data,reg=None,read=0): +# print("I2C",addr,reg,data,read) + bus=None; + try: + 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) + if read==1: + length=len(data) + bus.iaddr_bytes=0 + if not(reg is None): + bus.ioctl_write(0,str(bytearray([reg]))) + data[:]=[int(x) for x in bus.ioctl_read(0,length)] +# 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))) + bus.close() + return True; + except: + if bus: bus.close() +# data[0]=0xff + return False; + diff --git a/i2cserv/i2c_array.py b/i2cserv/i2c_array.py new file mode 100644 index 0000000000000000000000000000000000000000..a134256d1c97c3f8ef1abb85e47abc26c6d396a5 --- /dev/null +++ b/i2cserv/i2c_array.py @@ -0,0 +1,282 @@ +#from . import Vars +import numpy as np +import logging +from .spibitbang1 import * +#import threading +import time +#from multiprocessing import Process +#from pcctypes import * +from queuetypes import * +from .hwdev import hwdev; + +def ApplyMask(value,width=8,bitoffset=0,previous=0): + mask=(1<<width)-1 + if bitoffset>0: + value<<=bitoffset; + mask<<=bitoffset; + return (value & mask) + (previous - (previous & mask)); +def UnMask(value,width=8,bitoffset=0): + mask=(1<<width)-1 + if bitoffset>0: + value>>=bitoffset; + value=value&mask; + return value; + +def int2bytes(i): + b=[]; + while i>255: + b=[i%256]+b; + i>>=8; + return [i]+b; + +def GetField(D,name,dev_number,default=None): + X=D.get(name,default) + return X[dev_number] if isinstance(X,list) else X; +def Find(L,name,value): + for x in L: + if x[name]==value: + return x; + return False; + +class AttrDict(dict): + def __init__(self,*args,**kwargs): + super(AttrDict,self).__init__(*args,**kwargs) + self.__dict__=self + +def DevRegList(D): + #todo only count the drivers registers!! + for i,dev in enumerate(D.drivers): + dev['drv_id']=i; + devreglist={} + store=0; + for dev in D.device_registers: + N=dev.get('dim',1) + name=dev['name'] + for n in range(N): + addr=GetField(dev,'address',n,0) + devtype=GetField(dev,'driver',n) +# print(addr,devtype) + devid=0; + if devtype: + devid=Find(D.drivers,'name',devtype)['drv_id'] + devtype=Find(D.drivers,'name',devtype)['type'] + else: devtype=0; + if N>1: name2=name+str(n+1) + else: name2=name; + for reg in dev['registers']: + regR=GetField(reg,'address',0,0) + regW=GetField(reg,'address',1,0) + if reg.get('store',False): + store+=1; + storex=store + else: + storex=0 +# hf.write("const devreg %s {%i,%i,%i,%i,%i};\n" % (name2+'_'+reg['name'],addr,regR,regW,storex,devtype) ) + devregname=name2+'.'+reg['name']; + devreglist[devregname]=AttrDict({"Addr":addr,"Register_R":regR,"Register_W":regW,"store":storex,"devtype":devtype,"devid":devid}); +# print(devregname,devreglist[devregname]); +# 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) +# print(devreglist) + return devreglist,store + +def GetSteps(V1): + if isinstance(V1['devreg'],list): Step=len(V1['devreg']) + else: Step=1; #V1.nVars + Step2=V1['dim']*((V1.get('width',8)+7)//8)//Step #int(V1.size/V1.nVars) + #print(Step,Step2,V1); + return Step,Step2 + + +class i2c_array(hwdev): + def __init__(self,config): + hwdev.__init__(self,config); +# self.Qout=Qout; +# self.Qin=Qin; +# self.I2Ccallback=I2Ccallback +# self.SWcallback=Switchcallback +# self.previousHBA=np.zeros([number,3,32],dtype='int') + pars=config['parameters']; + self.RCU_Switch1=range(pars[0],pars[1]+1); + self.N=len(self.RCU_Switch1); +# 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 load(self): + print("TODO: load") + #Inst1=Vars.Instr(Vars.DevType.Instr,Vars.RCU_init,0,[]) #Read the current status of GPIO IOs + #self.SetVar(Inst1) +#Vars.RCU_mask.OPCW.get_data_value().Value.Value=[1,1,0,0] +#Vars.Ant_mask.OPCW.get_data_value().Value.Value=[1,1,0,0,0,0,0,0,0,0,1,0] + +#Inst1=Vars.Instr(Vars.DevType.Instr,Vars.RCU_init,0,[]) #Read the current status of GPIO IOs +#RCU.SetVar(Inst1) + +#Inst1=Vars.Instr(Vars.DevType.Var,Vars.RCU_att,12,[0,1,2,3,4,5,6,7,8,9,11]) +#RCU.SetVar(Inst1) + +#Inst1=Vars.Instr(Vars.DevType.Instr,Vars.RCU_off,0,[]) +#RCU.SetVar(Inst1) + +#Inst1=Vars.Instr(Vars.DevType.Instr,Vars.RCU_on,0,[]) +#RCU.SetVar(Inst1) + +#Inst1=Vars.Instr(Vars.DevType.Instr,Vars.ADC1_on,0,[]) +#RCU.SetVar(Inst1) + +#print(Vars.RCU) + 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) + return [Data] + + def OPCUAReadVariable(self,varid,var1,mask): + logging.info(str(("Read Var",var1['name'],mask))) + 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) + return [Data] + + def OPCUAcallMethod(self,var1,data,mask): + print("Call Method",var1) + + def SetSwitch(self,RCUi): + self.conf['parentcls'].SetChannel(1<<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]; + self.conf['parentcls'].SetChannel(m); + + def SetGetVarValueMask(self,var1,data,mask): + Step,Step2=GetSteps(var1); + value1=[0]*Step*Step2; + if len(data)==Step: + data=data*self.N; + if not(len(data)==Step*Step2): + print("Check data length!"); + return; + Step2//=self.N + if (len(mask)==self.N): + mask=[m for m in mask for x in range(Step)] + if not(len(mask)==Step*self.N): + print("Check mask length!"); + return; +# if (len(value1)==V1.nVars) and (self.N>1): value1=(value1*self.N); + i2c=self.conf['parentcls']; + for RCUi in range(self.N): + for Vari in range(Step): + if not(mask[RCUi*Step+Vari]): continue + i0=(RCUi*Step+ Vari)*Step2 + i1=(RCUi*Step+(Vari+1))*Step2 + devreg=var1['devreg'][Vari]; + width=var1.get('width',8) + bitoffset=GetField(var1,'bitoffset',Vari,0) + self.SetSwitch(RCUi); + self.RCUi=RCUi; + self.SetVarValue(devreg,width,bitoffset,data[i0:i1]) + value2=value1[i0:i1] + self.GetVarValue(devreg,width,bitoffset,value2) + value1[i0:i1]=value2 + return value1 + + + + def GetVarValueMask(self,var1,mask): + Step,Step2=GetSteps(var1); + value1=[0]*Step*Step2; + Step2//=self.N + if (len(mask)==self.N): + mask=[m for m in mask for x in range(Step)] + if not(len(mask)==Step*self.N): + print("Check mask length!"); + return; +# if (len(value1)==V1.nVars) and (self.N>1): value1=(value1*self.N); + i2c=self.conf['parentcls']; + for RCUi in range(self.N): + for Vari in range(Step): + if not(mask[RCUi*Step+Vari]): continue + i0=(RCUi*Step+ Vari)*Step2 + i1=(RCUi*Step+(Vari+1))*Step2 + devreg=var1['devreg'][Vari]; + width=var1.get('width',8) + bitoffset=GetField(var1,'bitoffset',Vari,0) + self.SetSwitch(RCUi); + value2=value1[i0:i1] + self.RCUi=RCUi; + self.GetVarValue(devreg,width,bitoffset,value2) + value1[i0:i1]=value2 + return value1 + + + def getstorearray(self,devreg): + storearray=devreg.get('storearray') + if not(storearray): + devreg['storearray']=[0]*self.N; + storearray=devreg.get('storearray'); + 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: + 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)) + self.SetSwitchMask(mask) + self.SetVarValue(devreg,8,0,value) + 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))) + #self.parentcls.SetChannel(1<<RCU_Switch[RCUi]); + if devreg['store']>0: + 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)) + # devreg['drivercls'].i2csetget + return devreg['drivercls'].i2csetget(devreg['addr'],value,reg=devreg['register_W']) + + def GetVarValue(self,devreg,width,bitoffset,value): + logging.debug(str(("RCU1 Get ",self.RCUi,devreg['addr'],value))) +# self.GetI2C(RCUi,devreg,width,bitoffset,value) +# if dev.store>0: +# value[0]=self.previous[RCUi,dev.store-1] +# return True + callback=devreg['drivercls'].i2csetget; + l1=int(np.floor((width+bitoffset+7)/8)) +# print(width,bitoffset,l1) + value2=value + reg=devreg['register_R'] + if reg>255: #This is for the monitor ADC + if not(callback(devreg['addr'],int2bytes(reg),read=2)): return False; + callback(0,[250],read=3) + if not(callback(devreg['addr'],value2,read=1)): return False; + else: + 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: + 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) + else: value[0]=value2[0] + return True; + + diff --git a/i2cserv/i2c_switch.py b/i2cserv/i2c_switch.py new file mode 100644 index 0000000000000000000000000000000000000000..1574fc41c6b770297aa48da440a1f2872a57ba4a --- /dev/null +++ b/i2cserv/i2c_switch.py @@ -0,0 +1,20 @@ +import logging +from .i2c import i2c + +#import HWconf +#SWaddr=0x70 +class i2c_switch(i2c): + def __init__(self,config): + i2c.__init__(self,config) + self.SWaddr=config['devreg'][0]['addr'] + self.CurrentChannel=0 + logging.info("i2c switch at address "+str(self.SWaddr)) + + def SetChannel(self,channel): + if (channel)==self.CurrentChannel: return True; + logging.debug("SetChannel=%i" % channel) + self.CurrentChannel=channel + return self.i2csetget(self.SWaddr,[channel]) + +# def I2Ccallback(self,RCU,addr,data,reg=None,read=0): +# self.callback1(addr,data,reg,read) diff --git a/i2cserv/i2cbitbang1.py b/i2cserv/i2cbitbang1.py new file mode 100644 index 0000000000000000000000000000000000000000..8aacf743f7fe6f395dfdfb6ab6d1fc7238da1bbb --- /dev/null +++ b/i2cserv/i2cbitbang1.py @@ -0,0 +1,147 @@ +from enum import Enum +import logging +import numpy as np +from .hwdev import hwdev +#This is copy of spibitbang. Need to be updated!! +class SPIBB_pins(Enum): + CLK = 0 + SDIO = 1 + SDIOdir = 2 + CS = 3 + +class i2cbitbang1(hwdev): + def __init__(self,config): + hwdev.__init__(self,config) + logging.info("i2cbitbang todo") + + def i2csetget(self,addr,data,reg=None,read=0): + logging.info("i2cbitbang todo") + return False; + + +def SetSPIbb(SetI2C,RCUi,dev,value): + ADC_address=dev.Register_W + CSdev=dev.Addr.devs[SPIBB_pins.CS.value] + CSpin=dev.Addr.pins[SPIBB_pins.CS.value] + SDOdev=dev.Addr.devs[SPIBB_pins.SDIO.value] + SDOpin=dev.Addr.pins[SPIBB_pins.SDIO.value] + CLKdev=dev.Addr.devs[SPIBB_pins.CLK.value] + CLKpin=dev.Addr.pins[SPIBB_pins.CLK.value] + + logging.info(str(("SPIbb set",ADC_address,value))) + + ADC_bytes = 0x00 + ADC_rw = 0x00 # 0 for write, 1 for read + data2 = ( ADC_rw << 23 ) + ( ADC_bytes << 21 ) + ( ADC_address << 8 ) + value[0] + + bit_array = "{0:{fill}24b}".format(data2, fill='0') + # print(bit_array) + SetI2C(RCUi,CSdev,1,CSpin,[0]) #enable + for bit in bit_array: + SetI2C(RCUi,SDOdev,1,SDOpin,[int(bit)]) + SetI2C(RCUi,CLKdev,1,CLKpin,[1]) + SetI2C(RCUi,CLKdev,1,CLKpin,[0]) + SetI2C(RCUi,CSdev,1,CSpin,[1]) #disable + SetI2C(RCUi,SDOdev,1,SDOpin,[1]) #high when finished + return True; + +def GetSPIbb(SetI2C,GetI2C,RCUi,dev,value): + ADC_reg_address=dev.Register_R + CSdev=dev.Addr.devs[Vars.SPIBB_pins.CS.value] + CSpin=dev.Addr.pins[Vars.SPIBB_pins.CS.value] + SDOdev=dev.Addr.devs[Vars.SPIBB_pins.SDIO.value] + SDOpin=dev.Addr.pins[Vars.SPIBB_pins.SDIO.value] + CLKdev=dev.Addr.devs[Vars.SPIBB_pins.CLK.value] + CLKpin=dev.Addr.pins[Vars.SPIBB_pins.CLK.value] + SDIOdirdev=dev.Addr.devs[Vars.SPIBB_pins.SDIOdir.value] + SDIOdirpin=dev.Addr.pins[Vars.SPIBB_pins.SDIOdir.value] + + logging.info(str(("SPIbb get",ADC_reg_address))) + + ADC_bytes = 0x00 + ADC_rw = 0x01 # 0 for write, 1 for read + + data = ( ADC_rw << 15) + ( ADC_bytes << 13 ) + ADC_reg_address + + SetI2C(RCUi,CSdev,1,CSpin,[0]) #enable + + + bit_array = "{0:{fill}16b}".format(data, fill='0') + for bit in bit_array: + SetI2C(RCUi,SDOdev,1,SDOpin,[int(bit)]) + SetI2C(RCUi,CLKdev,1,CLKpin,[1]) + SetI2C(RCUi,CLKdev,1,CLKpin,[0]) + + SetI2C(RCUi,CSdev,1,CSpin,[1]) #disable + + # print("read byte") + SetI2C(RCUi,SDIOdirdev,1,SDIOdirpin,[1]) #input + SetI2C(RCUi,CSdev,1,CSpin,[0]) #enable + a=[0] + N=len(value) + for i in range(N): value[i]=0 + for cnt in range(8*(ADC_bytes+1)): + ret_value=GetI2C(RCUi,SDOdev,1,SDOpin) #enable + for i in range(N): value[i]=(value[i]<<1)+ ret_value[i] + SetI2C(RCUi,CLKdev,1,CLKpin,[1]) + SetI2C(RCUi,CLKdev,1,CLKpin,[0]) #read after falling edge + SetI2C(RCUi,CSdev,1,CSpin,[1]) #disable + SetI2C(RCUi,SDIOdirdev,1,SDIOdirpin,[0]) #output + return True; + +def GetSPIbb2(SetI2C,GetI2C,RCUi,SPIdev,I2Cdev,I2Cpins,value): +#Read 3 SPI devices in parallel from same IOexpander + ADC_reg_address=SPIdev[0].Register_R + Nv=len(SPIdev) + def Setbit(pintype,value): + for i in range(1,Nv): + SetI2C(RCUi,I2Cdev[i][pintype],1,I2Cpins[i][pintype],[value],buffer=True) + SetI2C(RCUi,I2Cdev[0][pintype],1,I2Cpins[0][pintype],[value]) + def Getbit(pintype): + print("N=",Nv,len(value)) + retvalue=np.zeros_like(value) + retvalue[0::Nv]=GetI2C(RCUi,I2Cdev[0][pintype],1,I2Cpins[0][pintype]) + for i in range(1,Nv): + retvalue[i::Nv]=GetI2C(RCUi,I2Cdev[i][pintype],1,I2Cpins[i][pintype],buffer=True) + return retvalue + + CLK=0 + SDIO=1 + SDIOdir=2 + CS=3 + + logging.debug(str(("SPIbb get",ADC_reg_address))) + + ADC_bytes = 0x00 + ADC_rw = 0x01 # 0 for write, 1 for read + + data = ( ADC_rw << 15) + ( ADC_bytes << 13 ) + ADC_reg_address + Setbit(CLK,0) + + Setbit(CS,0) #enable + + bit_array = "{0:{fill}16b}".format(data, fill='0') + logging.debug(str(("SPI TX",bit_array))) + for bit in bit_array: + Setbit(CLK,0) + Setbit(SDIO,int(bit)) + Setbit(CLK,1) + +# Setbit(CS,1) #disable + Setbit(SDIOdir,1) #input + Setbit(CLK,0) + + # print("read byte") +# Setbit(CS,0) #enable + a=[0] + N=len(value) + for i in range(N): value[i]=0 + for cnt in range(8*(ADC_bytes+1)): + ret_value=Getbit(SDIO) + for i in range(N): value[i]=(value[i]<<1)+ ret_value[i] + Setbit(CLK,1) + Setbit(CLK,0) #read after falling edge + Setbit(CS,1) #disable + Setbit(SDIO,1)#High when finished + Setbit(SDIOdir,0) #output + return True; \ No newline at end of file diff --git a/i2cserv/i2cthread.py b/i2cserv/i2cthread.py index 308c5a3815aae45c4c33b21bded791244fcd1ec2..c76a1ece5da3c7022ceb77b404c302b36eeaf438 100644 --- a/i2cserv/i2cthread.py +++ b/i2cserv/i2cthread.py @@ -1,13 +1,15 @@ #Start the correct I2C server connect to the pipes on a new process import logging from multiprocessing import Process +from queuetypes import * +from time import sleep +#from i2cserv import I2Cswitch1 +#from i2cserv import I2C_dummy as I2C -from i2cserv import I2Cswitch1 -from i2cserv import I2C_dummy as I2C - -from i2cserv import RCU -from i2cserv import CLK +#from i2cserv import RCU +#from i2cserv import CLK +import yamlconfig as yc import yaml class AttrDict(object): @@ -26,25 +28,101 @@ class AttrDict(object): except KeyError: raise AttributeError +def runmethod(conf,Qout,methodid,mask): +# print("Run method",methodid,mask) + var1=conf.getmethod(methodid) + drv=var1.get('drivercls'); + 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))); + if (key=='WAIT'): + sleep(value[0]/1000.) + continue; + v1=conf.getvarid(key) + if v1: + if value[0]=='Update': + getvar(conf,Qout,v1,mask) + else: + setvar(conf,Qout,v1,value,mask) + continue; + v1=conf.getmethodid(key) + if v1: + runmethod(conf,Qout,v1,mask) + continue; + v1=conf.getdevreg(key) + if v1: + drv2=v1['drivercls'] + 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) +# drv=var1.get('drivercls'); +# if not(drv): +# logging.warn(var1['name']+" driver not found!") +# continue; +# for data in drv.OPCUAcallMethod(item.id,var1,item.data,item.mask): +# Qout.put(data) +def setvar(conf,Qout,varid,data,mask): + var1=conf.getvars()[varid] + drv=var1.get('drivercls'); + if not(drv): + logging.warn(var1['name']+" driver not found!") + return; + for data in drv.OPCUASetVariable(varid,var1,data,mask): + Qout.put(data) + +def getvar(conf,Qout,varid,mask): + var1=conf.getvars()[varid] + drv=var1.get('drivercls'); + if not(drv): + logging.warn(var1['name']+" driver not found!") + return; + for data in drv.OPCUAReadVariable(varid,var1,mask): + Qout.put(data) + + def I2Cserver(Qin,Qout,name): - logging.info(str(("New thread",name))) - with open("config/RCU.yaml", "r") as f: - settings = AttrDict(yaml.load(f)) - if name=='RCU': - SW1=I2Cswitch1.I2Cswitch1(I2C.I2C1server) - RCU1=RCU.RCU1(32,I2C.I2C1server,SW1.SetChannel,settings,Qin,Qout) - elif name=='CLK': - SW0=I2Cswitch1.I2Cswitch0(None) #Dummy switch as their is no switch on LTS - RCU1=CLK.RCU1(1,I2C.I2C4server,SW0.SetChannel) - else: - logging.warn(str(("Unknown name",name," thread stopping"))) - return - RCU1.load() #Load current register values from HW - RCU1.RCUthread(Qin) + logging.info("New i2c process "+name) + conf=yc.yamlconfig(name) + conf.linkdevices() + conf.loaddrivers() + conf.linkdrivers() + while True: + item = Qin.get() + if item is None: break; +# print("TODO: Set busy") +# self.statevar.set_value("busy"); + #print("SetVar",item)#,self.conf.variables[item.id]) + if (item.type==InstType.varSet): + setvar(conf,Qout,item.id,item.data,item.mask) + # self.OPCUASetVariable(item.id,var1,item.data,item.mask) + elif (item.type==InstType.varRead): + getvar(conf,Qout,item.id,item.mask) + # var1=self.conf.variables[item.id] + # self.OPCUAReadVariable(item.id,var1,item.data,item.mask) + elif (item.type==InstType.method): runmethod(conf,Qout,item.id,item.mask) + else: print("OPCUA call not implemented!"); +# print("TODO: Set ready") +# if Qin.qsize()==0: self.statevar.set_value("ready"); + logging.info("End i2c process "+name) + +# if name=='RCU': +# SW1=I2Cswitch1.I2Cswitch1(I2C.I2C1server) +# RCU1=RCU.RCU1(32,I2C.I2C1server,SW1.SetChannel,settings,Qin,Qout) +# elif name=='CLK': +# SW0=I2Cswitch1.I2Cswitch0(None) #Dummy switch as their is no switch on LTS +# RCU1=CLK.RCU1(1,I2C.I2C4server,SW0.SetChannel) +# else: +# logging.warn(str(("Unknown name",name," thread stopping"))) +# return +# RCU1.load() #Load current register values from HW +# RCU1.RCUthread(Qin) def start(Qout,Qin,name): thread1 = Process(target=I2Cserver, args=(Qin,Qout,name)) thread1.start() return thread1 - diff --git a/i2cserv/spibitbang1.py b/i2cserv/spibitbang1.py index 7b5f4e6dbb93d80e427f529c82a9b974dc8379b7..7db2517fba2567c8da1b509dda61d6d08ca0a3c9 100644 --- a/i2cserv/spibitbang1.py +++ b/i2cserv/spibitbang1.py @@ -1,6 +1,7 @@ from enum import Enum import logging import numpy as np +from .hwdev import hwdev class SPIBB_pins(Enum): CLK = 0 @@ -8,42 +9,54 @@ class SPIBB_pins(Enum): SDIOdir = 2 CS = 3 -def SetSPIbb(SetI2C,RCUi,dev,value): - ADC_address=dev.Register_W - CSdev=dev.Addr.devs[SPIBB_pins.CS.value] - CSpin=dev.Addr.pins[SPIBB_pins.CS.value] - SDOdev=dev.Addr.devs[SPIBB_pins.SDIO.value] - SDOpin=dev.Addr.pins[SPIBB_pins.SDIO.value] - CLKdev=dev.Addr.devs[SPIBB_pins.CLK.value] - CLKpin=dev.Addr.pins[SPIBB_pins.CLK.value] +class spibitbang1(hwdev): + def __init__(self,config): + hwdev.__init__(self,config) +# logging.info("spibitbang todo") - logging.info(str(("SPIbb set",ADC_address,value))) + 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) + else: logging.warn("Not implemented!") + return False; + + def SetSPIbb(self,ADC_address,value): + + CSdev=self.conf['devreg'][SPIBB_pins.CS.value] + CSpin=self.conf['parameters'][SPIBB_pins.CS.value] + SDOdev=self.conf['devreg'][SPIBB_pins.SDIO.value] + SDOpin=self.conf['parameters'][SPIBB_pins.SDIO.value] + CLKdev=self.conf['devreg'][SPIBB_pins.CLK.value] + CLKpin=self.conf['parameters'][SPIBB_pins.CLK.value] +# SDIOdirdev=self.conf['devreg'][SPIBB_pins.SDIOdir.value] +# SDIOdirpin=self.conf['parameters'][SPIBB_pins.SDIOdir.value] + logging.info(str(("SPIbb set",ADC_address,value))) + SetI2C=self.conf['parentcls'].SetVarValue ADC_bytes = 0x00 ADC_rw = 0x00 # 0 for write, 1 for read data2 = ( ADC_rw << 23 ) + ( ADC_bytes << 21 ) + ( ADC_address << 8 ) + value[0] bit_array = "{0:{fill}24b}".format(data2, fill='0') # print(bit_array) - SetI2C(RCUi,CSdev,1,CSpin,[0]) #enable + SetI2C(CSdev,1,CSpin,[0]) #enable for bit in bit_array: - SetI2C(RCUi,SDOdev,1,SDOpin,[int(bit)]) - SetI2C(RCUi,CLKdev,1,CLKpin,[1]) - SetI2C(RCUi,CLKdev,1,CLKpin,[0]) - SetI2C(RCUi,CSdev,1,CSpin,[1]) #disable - SetI2C(RCUi,SDOdev,1,SDOpin,[1]) #high when finished + SetI2C(SDOdev,1,SDOpin,[int(bit)]) + SetI2C(CLKdev,1,CLKpin,[1]) + SetI2C(CLKdev,1,CLKpin,[0]) + SetI2C(CSdev,1,CSpin,[1]) #disable + SetI2C(SDOdev,1,SDOpin,[1]) #high when finished return True; -def GetSPIbb(SetI2C,GetI2C,RCUi,dev,value): - ADC_reg_address=dev.Register_R - CSdev=dev.Addr.devs[Vars.SPIBB_pins.CS.value] - CSpin=dev.Addr.pins[Vars.SPIBB_pins.CS.value] - SDOdev=dev.Addr.devs[Vars.SPIBB_pins.SDIO.value] - SDOpin=dev.Addr.pins[Vars.SPIBB_pins.SDIO.value] - CLKdev=dev.Addr.devs[Vars.SPIBB_pins.CLK.value] - CLKpin=dev.Addr.pins[Vars.SPIBB_pins.CLK.value] - SDIOdirdev=dev.Addr.devs[Vars.SPIBB_pins.SDIOdir.value] - SDIOdirpin=dev.Addr.pins[Vars.SPIBB_pins.SDIOdir.value] + def GetSPIbb(self,ADC_reg_address,value): + CSdev=self.conf['devreg'][SPIBB_pins.CS.value] + CSpin=self.conf['parameters'][SPIBB_pins.CS.value] + SDOdev=self.conf['devreg'][SPIBB_pins.SDIO.value] + SDOpin=self.conf['parameters'][SPIBB_pins.SDIO.value] + CLKdev=self.conf['devreg'][SPIBB_pins.CLK.value] + CLKpin=self.conf['parameters'][SPIBB_pins.CLK.value] + SDIOdirdev=self.conf['devreg'][SPIBB_pins.SDIOdir.value] + SDIOdirpin=self.conf['parameters'][SPIBB_pins.SDIOdir.value] logging.info(str(("SPIbb get",ADC_reg_address))) @@ -51,31 +64,34 @@ def GetSPIbb(SetI2C,GetI2C,RCUi,dev,value): ADC_rw = 0x01 # 0 for write, 1 for read data = ( ADC_rw << 15) + ( ADC_bytes << 13 ) + ADC_reg_address - - SetI2C(RCUi,CSdev,1,CSpin,[0]) #enable + + SetI2C=self.conf['parentcls'].SetVarValue + GetI2C=self.conf['parentcls'].GetVarValue + SetI2C(CSdev,1,CSpin,[0]) #enable bit_array = "{0:{fill}16b}".format(data, fill='0') for bit in bit_array: - SetI2C(RCUi,SDOdev,1,SDOpin,[int(bit)]) - SetI2C(RCUi,CLKdev,1,CLKpin,[1]) - SetI2C(RCUi,CLKdev,1,CLKpin,[0]) + SetI2C(SDOdev,1,SDOpin,[int(bit)]) + SetI2C(CLKdev,1,CLKpin,[1]) + SetI2C(CLKdev,1,CLKpin,[0]) - SetI2C(RCUi,CSdev,1,CSpin,[1]) #disable + SetI2C(CSdev,1,CSpin,[1]) #disable # print("read byte") - SetI2C(RCUi,SDIOdirdev,1,SDIOdirpin,[1]) #input - SetI2C(RCUi,CSdev,1,CSpin,[0]) #enable + SetI2C(SDIOdirdev,1,SDIOdirpin,[1]) #input + SetI2C(CSdev,1,CSpin,[0]) #enable a=[0] - N=len(value) + N=1;#len(value) + ret_value=[0]; for i in range(N): value[i]=0 for cnt in range(8*(ADC_bytes+1)): - ret_value=GetI2C(RCUi,SDOdev,1,SDOpin) #enable + GetI2C(SDOdev,1,SDOpin,ret_value) #enable for i in range(N): value[i]=(value[i]<<1)+ ret_value[i] - SetI2C(RCUi,CLKdev,1,CLKpin,[1]) - SetI2C(RCUi,CLKdev,1,CLKpin,[0]) #read after falling edge - SetI2C(RCUi,CSdev,1,CSpin,[1]) #disable - SetI2C(RCUi,SDIOdirdev,1,SDIOdirpin,[0]) #output + 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 return True; def GetSPIbb2(SetI2C,GetI2C,RCUi,SPIdev,I2Cdev,I2Cpins,value): diff --git a/opcuaserv/i2client.py b/opcuaserv/i2client.py index e644ecdcf988fc8a795963942ebbcf26d04022a2..813700b0ad658f85389b9ff6126efac8f38c8491 100644 --- a/opcuaserv/i2client.py +++ b/opcuaserv/i2client.py @@ -29,7 +29,7 @@ class i2client(): self.Qout.put(Data); def callmethod(self,id1,mask=[]): - Data=OPCUAset(id1,InstType.method,[],[]) + Data=OPCUAset(id1,InstType.method,[],mask) self.Qout.put(Data); def data_waiting(self): diff --git a/opcuaserv/yamlconfig.py b/opcuaserv/yamlconfig.py deleted file mode 100644 index bd2bf4481a610a08af41f529957438bd327a9f4b..0000000000000000000000000000000000000000 --- a/opcuaserv/yamlconfig.py +++ /dev/null @@ -1,42 +0,0 @@ -import yaml -import struct -import time - -def Find(L,name,value): - for x in L: - if x[name]==value: - return x; - return False; - - -def GetField(D,name,dev_number,default=None): - X=D.get(name,default) - return X[dev_number] if isinstance(X,list) else X; - - -class yamlconfig(): - def __init__(self,yamlfile='RCU'): - self.conf=yaml.load(open("config/"+yamlfile+'.yaml')) - var1=self.conf['variables'] - N=len(var1) -# print([v['name'] for v in self.conf['variables']]) - for i in range(N-1,-1,-1): - #print(var1[i]) - if isinstance(var1[i]['name'],list): - for x,name in enumerate(var1[i]['name']): - var2=var1[i].copy() - var2['name']=name - var2['devreg']=GetField(var1[i],'devreg',x) - var2['scale']=GetField(var1[i],'scale',x,1) - var1.append(var2) - N+=1; - var1.remove(var1[i]) - N-=1; -# print([[v['name'],v.get('devreg')] for v in var1]) -# print(len(self.conf['variables']),N) - for i,v in enumerate(self.conf['variables']): - v['id']=i - for i,v in enumerate(self.conf['methods']): - v['id']=i - - diff --git a/opcuaserv/yamlreader.py b/opcuaserv/yamlreader.py index 1c51537ecf3e6eb02d3f6f0bb9cc64418ae32717..0697006a22c737e684938826379ae4e29bba01f9 100644 --- a/opcuaserv/yamlreader.py +++ b/opcuaserv/yamlreader.py @@ -1,8 +1,8 @@ import yaml import struct import time -from opcuaserv.yamlconfig import * - +from yamlconfig import * +import logging def bytes2int(bts): x=0; for b in bts: @@ -25,7 +25,7 @@ class yamlreader(yamlconfig): def AddVars(self,AddVarR,AddVarW): for v in self.conf['variables']: - print(v) +# print(v) dim1=v.get('dim',1); name=v.get('name'); datatype=v.get('dtype','integer') @@ -42,7 +42,7 @@ class yamlreader(yamlconfig): if v.get('rw') in ['ro','rw']: var1=AddVarR(name+"_R",varvalue2,v['id'],v.get('debug')) v['OPCR']=var1 - print("Var added:"+name+"_R") + logging.debug("Var added:"+name+"_R") self.server.readvar(v['id']) time.sleep(0.1); # Inst=Vars.Instr(Vars.DevType.VarUpdate,v,dim2,varvalue2) @@ -51,7 +51,7 @@ class yamlreader(yamlconfig): if v.get('rw') in ['wo','rw','variable']: var1=AddVarW(name+"_RW",varvalue2,v['id'],self,v.get('debug')) v['OPCW']=var1 - print("Var added:"+name+"_RW") + logging.debug("Var added:"+name+"_RW") for v in self.conf['variables']: mask=v.get('mask'); if not(mask): continue; @@ -64,7 +64,7 @@ class yamlreader(yamlconfig): def AddMethod(self,Addmethod): for v in self.conf['methods']: if v.get('rw','')=='hidden': continue; - print(v) +# print(v) # Inst1=Vars.Instr(Vars.DevType.Instr,v,0,[]) Addmethod(v['name'],v['id'],self,v.get('debug')) mask=v.get('mask'); @@ -77,7 +77,7 @@ class yamlreader(yamlconfig): def callMethod(self,id1): v=self.conf['methods'][id1]; - print("Method called!",v['name']) + logging.debug("Method called!"+v['name']) mask=v.get('maskOPC',None); mask=mask.get_value() if (mask!=None) else []; self.server.callmethod(id1,mask) @@ -87,7 +87,7 @@ class yamlreader(yamlconfig): if v['rw']=='variable': return; mask=v.get('maskOPC',None); mask=mask.get_value() if (mask!=None) else []; - print("M2:",mask) +# print("M2:",mask) dtype=v.get('dtype','integer'); width=(v.get('width',8)-1)//8+1 if (dtype=="double"): @@ -108,17 +108,17 @@ class yamlreader(yamlconfig): elif width==8: data2 = struct.pack('>%sQ' % len(data), *data) else: - print("setvar",v['name']," unsupported width!",width) + logging.warn("setvar"+v['name']+" unsupported width!"+str(width)) return; elif (dtype=="string"): data2=bytearray() for s in data: data2.extend('{s:>{width}'.format(s=s[:width],width=width).encode('ascii')); else: - print("setvar unsupported type"); + logging.warn("setvar unsupported type"); return; data2=[d for d in data2] - print("setvar ",v['name'],data2,mask); + logging.debug(str(("setvar ",v['name'],data2,mask))); self.server.setvar(id1,data2,mask) def getvar(self): @@ -130,7 +130,7 @@ class yamlreader(yamlconfig): item=self.server.readdata() if item is None: break; id1,data,mask=item; - print("**getvar",id1,data,mask); + logging.debug(str(("**getvar",id1,data,mask))); if len(data)==0: continue; # except: # print('finished') @@ -141,7 +141,7 @@ class yamlreader(yamlconfig): v=self.conf['variables'][id1]; dtype=v.get('dtype','integer'); width=(v.get('width',8)-1)//8+1 - print("OPCset",width,data) + logging.debug(str(("OPCset",width,data))) if dtype=="boolean": data2=[d==1 for d in data]; elif (dtype in ['uint8','uint16','uint32','uint64','double']): @@ -157,14 +157,14 @@ class yamlreader(yamlconfig): elif width==8: data2 = struct.unpack('>%sQ' % (len(data)//8), data) else: - print("OPCset",v['name']," unsupported width!",width) + logging.warn("OPCset"+v['name']+" unsupported width!"+str(width)) return; elif dtype=="string": cnt=int(len(data)/width) # data2=[(bytearray(data[i*width:(i+1)*width]).decode("utf-8")) for i in range(cnt)] data2=[bytearray(data)[i*width:(i+1)*width].decode("utf-8") for i in range(cnt)] else: - print("OPCset unsupported type"); + logging.warn("OPCset unsupported type"); return; if dtype=="double": scale=float(v.get('scale',1.)) @@ -173,11 +173,11 @@ class yamlreader(yamlconfig): # print("OPCset",v['name'],data3,mask) if mask: #Only update masked values step=len(data2)//len(mask) - print("mask step=",step) + #print("mask step=",step) for i in range(len(data2)): if mask[i//step]: data3[i]=data2[i] else: data3=data2; - print("OPCset",v['name'],data3) + logging.debug(str(("OPCset",v['name'],data3))) v['OPCR'].set_value(data3); diff --git a/pcctypes.py b/pcctypes.py deleted file mode 100644 index a980fdd5602787d7d6944ca80197b6b74b379ca3..0000000000000000000000000000000000000000 --- a/pcctypes.py +++ /dev/null @@ -1,83 +0,0 @@ - -#For capnproto -from collections import namedtuple -from enum import Enum -from recordclass import recordclass - - -#I2C ports & Switch addresses of device -MPaddr=namedtuple("MPaddr","nI2C I2C nSwitch Switch"); - -#Device registers -DevReg=namedtuple("DevReg","Addr Register_R Register_W store"); -#Addr: Byte (I2C) or *BBdev -#Register_R/W: Byte (I2C register) -#store: Byte 0=not stored else store index - -#Bitbang devices -BBdev=namedtuple("BBdev","nPins devs pins addr") -# devs: *DevReg[nPins] -# pins: Byte[nPins] -# addr: Byte (SPI device address) - - -class I2Cmodules(Enum): - Switch = 0 - RCU = 1 - CLK = 2 - UNB2 = 3 - -class DevType(Enum): - Var = 0 - I2C = 1 - SPIbb= 2 - I2Cbb= 3 - Instr =4 - VarUpdate = 5 - Internal = 6 - HBA1 = 7 - HBA2 = 8 - Wait = 9 - -class RW(Enum): - Hidden = 0 #Not an OPC_UA variable - ReadOnly = 1 #OPC_variable name_R - WriteOnly = 2 #OPC_variable name_RW - ReadWrite = 3 #both of above - -class datatype(Enum): - dInt = 0 - dfloat = 1 - dstring = 2 - dbool = 3 - -#Variable two device link -Var2dev=namedtuple("Var2dev","name module type devreg width bitoffset Scale") -#name: string (Currently unused!) -#module: I2Cmodules -#Type: DevType -#DevReg: *DevReg -#Width: Byte (# of bits) -#Bitoffset: Byte -#Scale: Float (=1 means no scaling i.e. integer) - -#OPC-UA variable: Array of similar variables -VarArray=recordclass("VarArray","name nVars Vars RW type size OPCR OPCW") #OPCR and OPCW linked at runtime -#name: string -#Vars: *Var2dev[nVars] -#RW: RW -#type: datatype -#size: =nVars (default), but x16/32 for HBA antennas -#OPCR/W: pointer to variable in OPC-UA server (linked during runtime) - -#Instruction -Instr=namedtuple("DevInstr","type dev nvalue value") -#Type: DevType -#dev: pointer to vararray / DevReg / etc depending on type -#value: Bytes[nvalue] - -#List of instructions -Instrs=namedtuple("Instr","name ninstr instr") -#name: string -#inst: Instr[ninstr] - diff --git a/pypcc2.py b/pypcc2.py index 6bc05a25f2fd464fbf55d8ff7c647a5b0743c572..2fadc3efd85a2db5c4681d7a5c54a8b59ccf6970 100644 --- a/pypcc2.py +++ b/pypcc2.py @@ -12,6 +12,7 @@ import signal parser = argparse.ArgumentParser() parser.add_argument("-s", "--simulator", help="Do not connect to I2c, but simulate behaviour.", action="store_true") +parser.add_argument("-t", "--test", help="Do not start OPC-UA server.", action="store_true") parser.add_argument("-p", "--port", help="Port number to listen on [%(default)s].", type=int, default=4842) parser.add_argument("-l", "--loglevel", help="Log level [%(default)s].", type=str, choices=["DEBUG","INFO","WARNING","ERROR"], default="INFO") parser.add_argument("-c", "--config", help="YAML config files, comma seperated [%(default)s]",type=str, default='RCU') @@ -45,35 +46,37 @@ for name in I2Cports: thread1=i2cthread.start(*RCU_I2C.GetInfo()) threads.append(thread1) I2Cclients.append(RCU_I2C) -#Initialise OPCUA server -logging.info("Initialised OPC-UA Server") -opcuaserv.InitServer(port=args.port) -logging.info("Load OPCUA variables & start i2c listing thread") -for i,name in enumerate(I2Cports): - RCU_I2C=I2Cclients[i] - RCU_conf=yamlreader.yamlreader(RCU_I2C,yamlfile=name) - RCU_conf.AddVars(opcuaserv.AddVarR,opcuaserv.AddVarW) - RCU_conf.AddMethod(opcuaserv.Addmethod) +#Initialise OPCUA server and load variables +logging.info("Initialised OPC-UA Server") +if not(args.test): + opcuaserv.InitServer(port=args.port) + logging.info("Load OPCUA variables & start i2c listing thread") + for i,name in enumerate(I2Cports): + RCU_I2C=I2Cclients[i] + RCU_conf=yamlreader.yamlreader(RCU_I2C,yamlfile=name) + RCU_conf.AddVars(opcuaserv.AddVarR,opcuaserv.AddVarW) + RCU_conf.AddMethod(opcuaserv.Addmethod) - thread2=threading.Thread(target=RCU_conf.getvar); #Thread on OPC-UA side of pipe - thread2.start() - threads.append(thread2) + thread2=threading.Thread(target=RCU_conf.getvar); #Thread on OPC-UA side of pipe + thread2.start() + threads.append(thread2) + time.sleep(1) + logging.info("Start OPC-UA server") + opcuaserv.start() if False: opcuaserv.server.stop() exit() -time.sleep(1) -logging.info("Start OPC-UA server") -opcuaserv.start() try: while RunTimer: time.sleep(1) finally: - logging.info("Stop OPC-UA server") - opcuaserv.server.stop() + if not(args.test): + logging.info("Stop OPC-UA server") + opcuaserv.server.stop() logging.info("Stop threads") for i2c in I2Cclients: diff --git a/testCLK.py b/testCLK.py new file mode 100644 index 0000000000000000000000000000000000000000..392732524bc94e3cef27ebe02493ecbfe433d4c8 --- /dev/null +++ b/testCLK.py @@ -0,0 +1,69 @@ +import logging +import argparse +from opcuaserv import opcuaserv +from opcuaserv import i2client +from opcuaserv import yamlreader +#from opcuaserv import pypcc2 +from i2cserv import i2cthread +import threading +import time +import sys +import signal +from yamlconfig import Find; + +logging.basicConfig(level="INFO",format='%(asctime)s [%(levelname)-8s,%(filename)-20s:%(lineno)-3d] %(message)s') + +RunTimer=True; +#def signal_handler(sig, frame): +# logging.warn('Stop signal received!') +# global RunTimer; +# RunTimer=False +#signal.signal(signal.SIGINT, signal_handler) + +logging.info("Start I2C processes") +threads=[] +I2Cclients=[] +name='CLK' +RCU_I2C=i2client.i2client(name=name) +thread1=i2cthread.start(*RCU_I2C.GetInfo()) +threads.append(thread1) +I2Cclients.append(RCU_I2C) + +#Load yaml so that we know the variable names +RCU_conf=yamlreader.yamlreader(RCU_I2C,yamlfile=name) + +if True: + var1=RCU_conf.getvarid('RCU_LED0'); + N=32; + mask=[i<2 for i in range(N)]; + data=[0]*N; +elif True: + var1=RCU_conf.getvarid('RCU_attenuator'); + N=32*3; + mask=[i<6 for i in range(N)]; + data=[10]*N; + data[:6]=[0,1,2,3,4,5] +#print(var1) +print("mask=",mask); +print("data=",data); +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) + + +time.sleep(2); + +while RCU_I2C.data_waiting(): + varid,data,mask=RCU_I2C.readdata() + print("Results:",RCU_conf.getvar1(varid)['name'],data) + + +logging.info("Stop threads") +for i2c in I2Cclients: + i2c.stop() +for thread1 in threads: + thread1.join() diff --git a/testRCU.py b/testRCU.py new file mode 100644 index 0000000000000000000000000000000000000000..0ced60e8ab3e83f74879d5a737f545c64660500f --- /dev/null +++ b/testRCU.py @@ -0,0 +1,69 @@ +import logging +import argparse +from opcuaserv import opcuaserv +from opcuaserv import i2client +from opcuaserv import yamlreader +#from opcuaserv import pypcc2 +from i2cserv import i2cthread +import threading +import time +import sys +import signal +from yamlconfig import Find; + +logging.basicConfig(level="INFO",format='%(asctime)s [%(levelname)-8s,%(filename)-20s:%(lineno)-3d] %(message)s') + +RunTimer=True; +#def signal_handler(sig, frame): +# logging.warn('Stop signal received!') +# global RunTimer; +# RunTimer=False +#signal.signal(signal.SIGINT, signal_handler) + +logging.info("Start I2C processes") +threads=[] +I2Cclients=[] +name='RCU' +RCU_I2C=i2client.i2client(name=name) +thread1=i2cthread.start(*RCU_I2C.GetInfo()) +threads.append(thread1) +I2Cclients.append(RCU_I2C) + +#Load yaml so that we know the variable names +RCU_conf=yamlreader.yamlreader(RCU_I2C,yamlfile=name) + +if True: + var1=RCU_conf.getvarid('RCU_LED0'); + N=32; + mask=[i<2 for i in range(N)]; + data=[0]*N; +elif True: + var1=RCU_conf.getvarid('RCU_attenuator'); + N=32*3; + mask=[i<6 for i in range(N)]; + data=[10]*N; + data[:6]=[0,1,2,3,4,5] +#print(var1) +print("mask=",mask); +print("data=",data); +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) + + +time.sleep(2); + +while RCU_I2C.data_waiting(): + varid,data,mask=RCU_I2C.readdata() + print("Results:",RCU_conf.getvar1(varid)['name'],data) + + +logging.info("Stop threads") +for i2c in I2Cclients: + i2c.stop() +for thread1 in threads: + thread1.join() diff --git a/yamlconfig.py b/yamlconfig.py new file mode 100644 index 0000000000000000000000000000000000000000..fb3201338e2fdd4b3e1c45a78b96ae8ac1c5cc32 --- /dev/null +++ b/yamlconfig.py @@ -0,0 +1,205 @@ +import yaml +import struct +import time +import logging + +def Find(L,name,value): + for x in L: + if x[name]==value: + return x; + return False; + + +def GetField(D,name,dev_number,default=None): + X=D.get(name,default) + return X[dev_number] if isinstance(X,list) else X; + +#class AttrDict(dict): +# def __init__(self,*args,**kwargs): +# super(AttrDict,self).__init__(*args,**kwargs) +# self.__dict__=self + +def str2int(x): + return (int(x,16) if x.find('x')>0 else int(x)); + +class yamlconfig(): + def __init__(self,yamlfile='RCU'): + self.conf=yaml.load(open("config/"+yamlfile+'.yaml')) + self.expand_variables() +# print([[v['name'],v.get('devreg')] for v in var1]) +# print(len(self.conf['variables']),N) + for i,v in enumerate(self.conf['variables']): + v['id']=i + for i,v in enumerate(self.conf['methods']): + v['id']=i + + def getvars(self): + return self.conf['variables']; + def getvar1(self,varid): + return self.conf['variables'][varid]; + def getvarid(self,name): + var1=Find(self.conf['variables'],'name',name); + return (var1['id'] if var1 else var1); + + def getmethod(self,methodid): + return self.conf['methods'][methodid]; +# return Find(self.conf['methods'],'id',methodid); + def getmethodid(self,name): + var1=Find(self.conf['methods'],'name',name); + return (var1['id'] if var1 else var1); + + def expand_variables(self): + #expand variables that are combined in single array + var1=self.conf['variables'] + N=len(var1) +# print([v['name'] for v in self.conf['variables']]) + for i in range(N-1,-1,-1): + #print(var1[i]) + if isinstance(var1[i]['name'],list): + for x,name in enumerate(var1[i]['name']): + var2=var1[i].copy() + var2['name']=name + var2['devreg']=GetField(var1[i],'devreg',x) + var2['scale']=GetField(var1[i],'scale',x,1) + var1.append(var2) + N+=1; + var1.remove(var1[i]) + N-=1; + + def getdevreg(self,name): + try: + dr=self.devreglist.get(name); + if dr: return dr; + if isinstance(name,int): return {"addr":name} + name2=name.split('.') +# print(name2,str2int(name2[0]),str2int(name2[1])) + 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)); + except: + logging.error("Can not find device register "+str(name)); + return None; + def linkdevices(self): + #replace devreg reference with (pointer to) devreg dict + devreglist={} + drivers=self.conf['drivers'] + for dev in self.conf['device_registers']: + N=dev.get('dim',1) + name=dev['name'] + for n in range(N): + addr=GetField(dev,'address',n,0) + devtype=GetField(dev,'driver',n) +# print(addr) + if devtype: + devid=Find(drivers,'name',devtype) + #devtype=Find(D.drivers,'name',devtype)['type'] + else: devtype=None; + if N>1: name2=name+str(n+1) + else: name2=name; + for reg in dev['registers']: + regR=GetField(reg,'address',0,0) + regW=GetField(reg,'address',1,0) + store=reg.get('store',False) + devregname=name2+'.'+reg['name']; + devreglist[devregname]={"addr":addr,"register_R":regR,"register_W":regW,"store":store,"driver":devid}; +# print(devregname,devreglist[devregname]['addr'],devreglist[devregname]['register_R'],devreglist[devregname]['register_W']); + self.devreglist=devreglist; + for D in drivers: + devreg=D.get('devreg'); + if not(devreg): continue; + for i,dr in enumerate(devreg): + #print(dr,self.getdevreg(dr)) + devreg[i]=self.getdevreg(dr) + + for D in self.conf['variables']: + devreg=D.get('devreg'); + if not(devreg): continue; + if isinstance(devreg,list): + for i,dr in enumerate(devreg): + #print("linkdev",dr,self.getdevreg(dr)) + devreg[i]=self.getdevreg(dr) + else: + D['devreg']=[self.getdevreg(devreg)] + #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) +# print(devreglist) +# return devreglist,store + + def loaddrivers(self): + import importlib + import sys, inspect + for c in self.conf['drivers']: +# print("loading",c['name'],c['type']); +# try: + i = importlib.import_module("i2cserv."+c['type']) + # except: + # logging.warn("No driver for "+c['type']) + # c['obj']=None; + # continue; + for name, obj in inspect.getmembers(i,inspect.isclass): + if name==c['type']: + # print(" Load child:",name) + c['obj']=obj(c) + if not(c.get('obj')): + logging.warn((("Driver "+c['type']+" not found!"))) + + def linkdrivers(self): + drivers=self.conf['drivers'] + for c in drivers: + name=c.get('parent'); + if not(name): continue; + p=Find(drivers,'name',name); + if not(p): + logging.error("Can not find driver "+str(name)) + continue; + c['parentcls']=p['obj']; +# print("link ",c['name'],name," to ",p['obj']) + #devregs=c.get('devreg') + #if not(devregs): continue; + #for dr in devregs: + # if not(dr): continue; + # name=dr.get('driver') + # if not(name): #Give it the parents driver + # dr["drivercls"]=p['obj'] + # drv=dr.get("drivercls") + # if drv is None: logging.warn("variable "+c['name']+" register driver not found") + + + + for name,c in self.devreglist.items(): + drv=c['driver']; + if not(drv): continue; +# print(drv) + c['drivercls']=drv.get('obj'); +# print("link ",name,drv['name']," to ",c.driverobj) + for c in self.conf['variables']: + name=c.get('driver'); + if not(name): continue; + p=Find(drivers,'name',name); + if not(p): + logging.error("Can not find driver "+str(name)) + continue; + c['drivercls']=p['obj']; +# print("link ",c['name'],name," to ",p['obj']) + + devregs=c.get('devreg') + if not(devregs): continue; + for dr in devregs: + if not(dr): continue; + name=dr.get('driver') + if not(name): #Give it the parents driver + dr["drivercls"]=p['obj'] + drv=dr.get("drivercls") + if drv is None: logging.warn("variable "+c['name']+" register driver not found") + + for c in self.conf['methods']: + name=c.get('driver'); + if not(name): continue; + p=Find(drivers,'name',name); + if not(p): + logging.error("Can not find driver "+str(name)) + continue; + c['drivercls']=p['obj']; + +