diff --git a/README.md b/README.md index 23ec5e0a9d302f8159fd7b5fadf5bc64cd5faf19..8d3049d04c269813aeaaec2c14ac75a224bba56a 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # PyPCC Python OPC-UA server to control the I2C devices in the LTS. -+ opcuserv.py: OPC-UA server that expose (visible) variables and methods. ++ pypcc2.py: OPC-UA server that expose (visible) variables and methods. # Prerequisites @@ -34,7 +34,7 @@ python3 -m pip install -r requirements.txt # Execute it -The software can be simply executed with Python3: `python3 opcuaserv.py` +The software can be simply executed with Python3: `python3 pypcc2.py -c RCY,CLK,UNB2` Optional parameters are explained when the `-h` or `--help` parameter is supplied: @@ -47,7 +47,8 @@ usage: pypcc2.py [-h] [-s] [--no-lib-hack] [-p PORT] optional arguments: -h, --help show this help message and exit -s, --simulator Do not connect to I2c, but simulate behaviour. - --no-lib-hack Do not require a hacked opcua library. Breaks behaviour. -p PORT, --port PORT Port number to listen on [4842]. + -c .. + -t ... ``` diff --git a/clk/CLK.py b/clk/CLK.py deleted file mode 100644 index 37d9b6f4565e64896914a1c52758965a2dd08be6..0000000000000000000000000000000000000000 --- a/clk/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.CLK_Stat1,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/clk/HWconf.py b/clk/HWconf.py deleted file mode 100644 index e6f2f6f3195f22279433b96ff6c92465bd453104..0000000000000000000000000000000000000000 --- a/clk/HWconf.py +++ /dev/null @@ -1,31 +0,0 @@ -#from collections import namedtuple -#from enum import Enum -from pcctypes import * - -#Mid plane address -RCU_MPaddr=MPaddr(1,[1],1,[7]) - -CLK_IO3_OUT1=DevReg(0x20,0,2,1) -CLK_IO3_OUT2=DevReg(0x20,1,3,2) -CLK_IO3_CONF1=DevReg(0x20,6,6,3) -CLK_IO3_CONF2=DevReg(0x20,7,7,4) - -RCU_storeReg=4; #Number of stored registers - - - -SPIBB_PLL=BBdev(4,[CLK_IO3_OUT1,CLK_IO3_OUT1,CLK_IO3_OUT1,CLK_IO3_OUT1],[4,7,5,6],0) #CLK,SDI,SDO,CS - -CLK_PLL_lock =DevReg(SPIBB_PLL,0X00,0X00,0) # PLL locked status -CLK_PLL_div =DevReg(SPIBB_PLL,0X0D,0X0D,0) # PLL divide -CLK_PLL_pwr =DevReg(SPIBB_PLL,0X03,0X03,0) # PLL divide -CLK_PLL_5 =DevReg(SPIBB_PLL,0X05,0X05,0) # PLL divide -CLK_PLL_6 =DevReg(SPIBB_PLL,0X06,0X06,0) # PLL divide -CLK_PLL_7 =DevReg(SPIBB_PLL,0X07,0X07,0) # PLL divide -CLK_PLL_8 =DevReg(SPIBB_PLL,0X08,0X08,0) # PLL divide -CLK_PLL_9 =DevReg(SPIBB_PLL,0X09,0X09,0) # PLL divide -CLK_PLL_A =DevReg(SPIBB_PLL,0X0A,0X0A,0) # PLL divide -CLK_PLL_D =DevReg(SPIBB_PLL,0X0D,0X0D,0) # PLL divide -CLK_PLL_F =DevReg(SPIBB_PLL,0X0F,0X0F,0) # PLL divide -CLK_PLL_11 =DevReg(SPIBB_PLL,0X11,0X11,0) # PLL divide -CLK_PLL_13 =DevReg(SPIBB_PLL,0X13,0X13,0) # PLL divide diff --git a/clk/Vars.py b/clk/Vars.py deleted file mode 100644 index 75c45b19b9158ad60b35a85b38132a0ade42ea03..0000000000000000000000000000000000000000 --- a/clk/Vars.py +++ /dev/null @@ -1,74 +0,0 @@ -from .HWconf import * - -CLKmod=I2Cmodules.CLK - - -CLK_IGNORE_PPS= VarArray("CLK_Ignore_PPS",1,[Var2dev("",CLKmod,DevType.I2C,CLK_IO3_OUT1,1 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) -CLK_Enable_PWR= VarArray("CLK_Enable_PWR",1,[Var2dev("",CLKmod,DevType.I2C,CLK_IO3_OUT1,1 ,1,1)],RW.ReadOnly,datatype.dInt,1,None,None) -CLK_Stat1 = VarArray("CLK_Stat" ,1,[Var2dev("",CLKmod,DevType.I2C,CLK_IO3_OUT1,2 ,2,1)],RW.ReadOnly,datatype.dInt,1,None,None) -CLK_lock1 = VarArray("CLK_Lock" ,1,[Var2dev("",CLKmod,DevType.SPIbb,CLK_PLL_lock,8 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) -CLK_div1 = VarArray("CLK_Div" ,1,[Var2dev("",CLKmod,DevType.SPIbb,CLK_PLL_div,8 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) -CLK_pwr1 = VarArray("CLK_Pwr" ,1,[Var2dev("",CLKmod,DevType.SPIbb,CLK_PLL_pwr,8 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) -CLK_5 = VarArray("CLK_PLL_5" ,1,[Var2dev("",CLKmod,DevType.SPIbb,CLK_PLL_5,8 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) -CLK_6 = VarArray("CLK_PLL_6" ,1,[Var2dev("",CLKmod,DevType.SPIbb,CLK_PLL_6,8 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) -CLK_7 = VarArray("CLK_PLL_7" ,1,[Var2dev("",CLKmod,DevType.SPIbb,CLK_PLL_7,8 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) -CLK_8 = VarArray("CLK_PLL_8" ,1,[Var2dev("",CLKmod,DevType.SPIbb,CLK_PLL_8,8 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) -CLK_9 = VarArray("CLK_PLL_9" ,1,[Var2dev("",CLKmod,DevType.SPIbb,CLK_PLL_9,8 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) -CLK_A = VarArray("CLK_PLL_A" ,1,[Var2dev("",CLKmod,DevType.SPIbb,CLK_PLL_A,8 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) -CLK_D = VarArray("CLK_PLL_D" ,1,[Var2dev("",CLKmod,DevType.SPIbb,CLK_PLL_D,8 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) -CLK_F = VarArray("CLK_PLL_F" ,1,[Var2dev("",CLKmod,DevType.SPIbb,CLK_PLL_F,8 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) -CLK_11 = VarArray("CLK_PLL_11" ,1,[Var2dev("",CLKmod,DevType.SPIbb,CLK_PLL_11,8 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) -CLK_13 = VarArray("CLK_PLL_13" ,1,[Var2dev("",CLKmod,DevType.SPIbb,CLK_PLL_13,8 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) - - -#OPC_devvars=[CLK_Enable_PWR,CLK_Stat1,CLK_5,CLK_6,CLK_7,CLK_8,CLK_9,CLK_A,CLK_D,CLK_F,CLK_11,CLK_13] #,CLK_lock1,CLK_Stat1,CLK_div1,CLK_pwr1,CLK_IGNORE_PPS] -OPC_devvars=[CLK_Enable_PWR,CLK_Stat1] #,CLK_lock1,CLK_Stat1,CLK_div1,CLK_pwr1,CLK_IGNORE_PPS] - -RCU_init=Instrs("CLK_update",2,[ -# Instr(DevType.VarUpdate,CLK_IGNORE_PPS,1,[0]), - Instr(DevType.VarUpdate,CLK_Enable_PWR,1,[0]), - Instr(DevType.VarUpdate,CLK_Stat1,1,[0]) -]) - -CLK_on=Instrs("CLK_on",3,[ - Instr(DevType.I2C,CLK_IO3_CONF1,1,[0x2C]),#0010 1100 PPS/PWR output, SCLK,CS,SDI - Instr(DevType.I2C,CLK_IO3_OUT1 ,1,[0x42]),#0100 0010 high:PWR enable, CS -# Instr(DevType.VarUpdate,CLK_lock1,1,[0]), - Instr(DevType.VarUpdate,CLK_Stat1,1,[0]), - Instr(DevType.VarUpdate,CLK_Enable_PWR,1,[0]) -]) - -CLK_off=Instrs("CLK_off",3,[ - Instr(DevType.I2C,CLK_IO3_CONF1,1,[0x2C]), - Instr(DevType.I2C,CLK_IO3_OUT1 ,1,[0x40]), - Instr(DevType.VarUpdate,CLK_Enable_PWR,1,[0]) -]) - -def SPIinst(reg,value): - return Instr(DevType.SPIbb,DevReg(SPIBB_PLL,0,reg,0),1,[value]) - -CLK_PLL_setup=Instrs("CLK_PLL_setup",15,[ -# SPIinst(0x03,0x08), -# Instr(DevType.I2C,CLK_IO3_CONF1,1,[0x2C]), - SPIinst(0x05,0x17),#was 97 - SPIinst(0x06,0x10), - - SPIinst(0x07,0x04), - SPIinst(0x08,0x01), - SPIinst(0x07,0x00), - - SPIinst(0x09,0x10), - SPIinst(0x0A,0x14), - SPIinst(0x09,0x00), - - SPIinst(0x0D,0x01),#was 2 - SPIinst(0x0F,0x01), - SPIinst(0x11,0x01), - SPIinst(0x13,0x01), - # Instr(DevType.VarUpdate,CLK_lock1,1,[0]), - # Instr(DevType.VarUpdate,CLK_div1,1,[0]), - Instr(DevType.VarUpdate,CLK_Stat1,1,[0]) -]) - - -OPC_methods=[CLK_on,CLK_off,CLK_PLL_setup,RCU_init] diff --git a/clk/spibitbang2.py b/clk/spibitbang2.py deleted file mode 100644 index d312d5b6560f7bfaaaa75a9cef2773bc9b636f71..0000000000000000000000000000000000000000 --- a/clk/spibitbang2.py +++ /dev/null @@ -1,84 +0,0 @@ -from enum import Enum -import logging -import numpy as np - -class SPIBB_pins(Enum): - CLK = 0 - SDI = 1 - SDO = 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.SDO.value] - SDOpin=dev.Addr.pins[SPIBB_pins.SDO.value] - SDIdev=dev.Addr.devs[SPIBB_pins.SDI.value] - SDIpin=dev.Addr.pins[SPIBB_pins.SDI.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))) - -# dev_rw = 0x00 # 0 for write, 1 for read -# data2 = ( reg_address << 9 ) + ( dev_rw << 8 ) + value[0] - data2 = ( ADC_address << 9 ) + value[0] - - bit_array = "{0:{fill}16b}".format(data2, fill='0') - # print(bit_array) - SetI2C(RCUi,CSdev,1,CSpin,[1]) #disable - SetI2C(RCUi,CSdev,1,CSpin,[0]) #enable - for bit in bit_array: - SetI2C(RCUi,CLKdev,1,CLKpin,[0]) - SetI2C(RCUi,SDIdev,1,SDIpin,[int(bit)]) - SetI2C(RCUi,CLKdev,1,CLKpin,[1]) - SetI2C(RCUi,CLKdev,1,CLKpin,[0])#Why? - SetI2C(RCUi,CLKdev,1,CLKpin,[1]) - SetI2C(RCUi,CSdev,1,CSpin,[1]) #disable - # SetI2C(RCUi,SDIdev,1,SDIpin,[1]) #high when finished - return True; - -def GetSPIbb(SetI2C,GetI2C,RCUi,dev,value): - ADC_reg_address=dev.Register_R - CSdev=dev.Addr.devs[SPIBB_pins.CS.value] - CSpin=dev.Addr.pins[SPIBB_pins.CS.value] - SDOdev=dev.Addr.devs[SPIBB_pins.SDO.value] - SDOpin=dev.Addr.pins[SPIBB_pins.SDO.value] - SDIdev=dev.Addr.devs[SPIBB_pins.SDI.value] - SDIpin=dev.Addr.pins[SPIBB_pins.SDI.value] - CLKdev=dev.Addr.devs[SPIBB_pins.CLK.value] - CLKpin=dev.Addr.pins[SPIBB_pins.CLK.value] - - logging.info(str(("SPIbb get",ADC_reg_address))) - ADC_bytes = 0x00 - # ADC_rw = 0x01 # 0 for write, 1 for read - data = (ADC_reg_address << 1) + 1 #was 7?? - - SetI2C(RCUi,CSdev,1,CSpin,[1]) #disable - SetI2C(RCUi,CSdev,1,CSpin,[0]) #enable - - - bit_array = "{0:{fill}8b}".format(data, fill='0') - for bit in bit_array: - SetI2C(RCUi,SDIdev,1,SDIpin,[int(bit)]) - SetI2C(RCUi,CLKdev,1,CLKpin,[0]) - SetI2C(RCUi,CLKdev,1,CLKpin,[1]) - - # SetI2C(RCUi,SDIdev,1,SDIpin,[1]) #high when finished - - # print("read byte") - a=[0] - N=1 #len(value) - ret_value=[0] - for i in range(N): value[i]=0 - for cnt in range(8*(ADC_bytes+1)): - SetI2C(RCUi,CLKdev,1,CLKpin,[0]) - SetI2C(RCUi,CLKdev,1,CLKpin,[1]) #read after rising - GetI2C(RCUi,SDOdev,1,SDOpin,ret_value) - for i in range(N): value[i]=(value[i]<<1)+ ret_value[i] - SetI2C(RCUi,CLKdev,1,CLKpin,[0]) - SetI2C(RCUi,CSdev,1,CSpin,[1]) #disable - return True; - - diff --git a/config/CLK.yaml b/config/CLK.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5bd902124c20314573e3759649cc728fb6ff2b78 --- /dev/null +++ b/config/CLK.yaml @@ -0,0 +1,167 @@ +version: "1.0" +description: "1234" + +drivers: + - name: I2C + type: i2c + parameters: [4] #I2C port number + - name: I2C_CLK + type: i2c_dev #I2C devices + parent: I2C + status: CLK_I2C_STATUS + - name: SPIbb1 + type: spibitbang2 #SPI bitbang via GPIO expander: CLK, SDI,SDO,CS + parent: I2C_CLK + devreg: [IO1.GPIO1,IO1.GPIO1,IO1.GPIO1,IO1.GPIO1] + parameters: [4,7,5,6] + +#This is the I2C devices in the RCU +device_registers: + - name: IO1 + description: IO-Expander + address: 0x20 + driver: I2C_CLK + registers: + - name: CONF1 + description: Direction of port1 + address: 6 + store: True + - name: GPIO1 + description: Input/Ouput port 1 + address: [0,2] #Read / Write address different + store: True + + - name: PLL + driver: SPIbb1 + registers: + - name: PLL_stat + description: PLL locked status + address: 0x0 + - {name: r3, address: 0x03} + - {name: r5, address: 0x05} + - {name: r6, address: 0x06} + + +variables: + - name: CLK_I2C_STATUS + driver: I2C_CLK + rw: ro #server RW variable, not linked to IO + dtype: uint8 + + - name: CLK_translator_busy + description: False when idle + rw: ro #server variable, not linked to IO + dtype: boolean + dim: 1 + + - name: CLK_Enable_PWR + description: Power enabled + rw: ro + dtype: boolean + driver: I2C_CLK + devreg: IO1.GPIO1 + bitoffset: 1 + width: 1 + + + - name: CLK_PLL_locked + description: First status pin give lock status + rw: ro + dtype: boolean + monitor: true + driver: I2C_CLK + devreg: IO1.GPIO1 + bitoffset: 2 + width: 1 + + - name: CLK_PLL_error + description: Second status pin give error + rw: ro + dtype: boolean + monitor: true + driver: I2C_CLK + devreg: IO1.GPIO1 + bitoffset: 3 + width: 1 + + - name: CLK_PLL_locked_SPI + description: 0x81=locked + driver: I2C_CLK + devreg: PLL.PLL_stat + width: 8 + rw: ro + dtype: uint8 + debug: True + + - name: [CLK_PLL_r3,CLK_PLL_r5,CLK_PLL_r6] + driver: I2C_CLK + devreg: [PLL.r3,PLL.r5,PLL.r6] + width: 8 + rw: ro + dtype: uint8 + debug: True + + - name: RCU_IO1_GPIO1 + driver: I2C_CLK + devreg: IO1.GPIO1 + width: 8 + rw: ro + dtype: uint8 + mask: RCU_mask + debug: True + +methods: + - name: CLK_Init #Called after startup to load. Should have all stored registers + driver: I2C_CLK + debug: True + instructions: + - CLK_I2C_STATUS : 0 + - RCU_IO1_GPIO1 : Update + - IO1.CONF1: Update + - CLK_Enable_PWR: Update + - CLK_PLL_locked: Update + - CLK_PLL_error: Update + + - name: CLK_on + driver: I2C_CLK + instructions: + - CLK_I2C_STATUS : 0 + - IO1.CONF1: 0x2C #0010 1100 PPS/PWR output, SCLK,CS,SDI + - IO1.GPIO1: 0x42 #0100 0010 high:PWR enable, CS + - CLK_Enable_PWR: Update + - WAIT: 200 #ms to wait before checking lock + - CLK_PLL_setup: 0 + - WAIT: 100 #ms to wait before checking lock + - CLK_PLL_locked: Update + + - name: CLK_off + driver: I2C_CLK + instructions: + - CLK_I2C_STATUS : 0 + - IO1.CONF1: 0x2C #0010 1100 PPS/PWR output, SCLK,CS,SDI + - IO1.GPIO1: 0x00 #all low + - CLK_Enable_PWR: Update + - CLK_PLL_locked: Update + + - name: CLK_PLL_setup + driver: I2C_CLK + debug: true + instructions: +# - PLL.0x03: 0x08 #Set power, this is default + - PLL.0x05: 0x17 #was 97, set lock time + - PLL.0x06: 0x10 + + - PLL.0x07: 0x04 #Stop R divider + - PLL.0x08: 0x01 #Set R divider + - PLL.0x07: 0x00 #Start R divider + + - PLL.0x09: 0x10 #Stop N divider + - PLL.0x0A: 0x14 #Set N divider=20, 200MHz/20=10MHz = input clock + - PLL.0x09: 0x00 #Start N divider + + - PLL.0x0D: 0x01 #Divider output 1=1 + - PLL.0x0F: 0x01 #Divider output 2=1 + - PLL.0x11: 0x01 #Divider output 3=1 + - PLL.0x13: 0x01 #Divider output 4=1 + + diff --git a/config/RCU.yaml b/config/RCU.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f1c28ddb334ea76076ff2cc4a94904b2d4b26531 --- /dev/null +++ b/config/RCU.yaml @@ -0,0 +1,488 @@ +version: "1.0" +description: "1234" + +drivers: + - 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: [0,31] #start,number of RCUs + status: RCU_I2C_STATUS + - name: I2C_HBAT + type: hba1 #Special driver to manage HBAT1s. + parent: I2C_RCU + - name: I2Cbb1 + type: i2cbitbang1 #I2C bitbang via GPIO expander + devreg: [IO1.GPIO1,IO2.GPIO2,IO2.CONF2] + parameters: [6,3,3] #pins + parent: I2C_RCU + - name: I2Cbb2 + type: i2cbitbang1 + devreg: [IO1.GPIO2,IO2.GPIO1,IO1.CONF1] + parameters: [7,7,7] + parent: I2C_RCU + - name: I2Cbb3 + type: i2cbitbang1 + devreg: [IO1.GPIO2,IO2.GPIO1,IO1.CONF1] + parameters: [7,7,7] + parent: I2C_RCU + - name: SPIbb1 + type: spibitbang1 #SPI bitbang via GPIO expander: CLK, SDIO, SDIOdir,CS + devreg: [IO3.GPIO1,IO3.GPIO1,IO3.CONF1,IO3.GPIO2] + parameters: [1,0,0,0] + parent: I2C_RCU + - name: SPIbb2 + type: spibitbang1 + devreg: [IO3.GPIO1,IO3.GPIO1,IO3.CONF1,IO3.GPIO2] + parameters: [3,2,2,1] + parent: I2C_RCU + - name: SPIbb3 + type: spibitbang1 + devreg: [IO3.GPIO1,IO3.GPIO1,IO3.CONF1,IO3.GPIO2] + parameters: [5,4,4,2] + parent: I2C_RCU + - name: HBA_trigger + type: gpio_hba_trigger + devreg: [0x40.0x10] #I2C broadcast register + parameters: [15] #PPS GPIO pin + parent: I2C_RCU + +#This is the I2C devices in the RCU +device_registers: + - name: IO + dim: 3 + description: [IO-Expander for filter selection,IO-Expander for ON/OFF, Band, BUFx2,IO-Expander for ADC control] + address: [0x75,0x76,0x20] + device: [TCA9539,TCA9539,TCA6416] + driver: I2C1 + registers: + - name: CONF1 + description: Direction of port1 + address: 6 + store: True + - name: CONF2 + description: Direction of port2 + address: 7 + store: True + - name: GPIO1 + description: Input/Ouput port 1 + address: [0,2] #Read / Write address different + store: True + - name: GPIO2 + description: Input/Ouput port 2 + address: [1,3] + store: True + + - name: ROM + description: IO-Expander for filter selection + address: 0x50 + driver: I2C1 + registers: + - name: ID + description: Random + address: 0xfc + - name: Version + description: Set in production + address: 0 + + - name: AN + description: Monitor ADC on RCU + address: 0x14 + device: LTC2495 + driver: I2C1 + registers: + - name: V_1v8 + address: 0xB080 + - name: V_2v5 + address: 0xB880 + - name: V_3v3 + address: 0xB180 + - name: I_Ant0 + address: 0xB980 + - name: I_Ant1 + address: 0xB280 + - name: I_Ant2 + address: 0xBA80 + - name: V_Ant0 + address: 0xB380 + - name: V_Ant1 + address: 0xBB80 + - name: Temp + address: 0xA0C0 + +#This 'special' devices that uses I2C + + - name: HB_UC + description: RCU microcontroller + address: 0x40 + driver: I2C1 + registers: + - name: ID + description: Device ID + address: 0 + + - name: HB_UC_update + description: RCU microcontroller + address: 0x40 + driver: HBA_trigger + registers: + - name: wait_pps + address: 10 + + - name: HBAT + dim: 3 + address: [0x41,0x42,0x43] + description: Virtual HBAT0 interface + driver: I2C_HBAT + registers: + - name: XY + address: 0x10 + description: XY delay register + store: True + - name: Version + address: 127 + description: HBAT server version + + - name: ADC + dim: 3 + description: ADC SPI control + device: AD9683 + driver: [SPIbb1,SPIbb2,SPIbb3] + registers: + - name: PLL_stat + description: PLL locked status + address: 0x0A + - name: JESD_control1 + description: JESD link control + address: 0x5F + - name: SYNC_control + address: 0x3A + - name: CML_level + description: CML output adjust + address: 0x15 + - name: Update + description: Global device uptate + address: 0xFF + + - name: DTH + dim: 3 + description: CW dither source + device: SI4012 + driver: [I2Cbb1,I2Cbb1,I2Cbb1] + address: 0x70 + registers: + - name: Freq + description: Frequency + address: [0x1140,0x1141] + - name: Property + description: Properties + address: [0x11,0x11] + - name: Start + description: Start CW + address: [0x62,0x62] + - name: Stop + description: Stop CW + address: [0x67,0x67] + +variables: + - name: Ant_mask + description: Only masked RF chains are updated + driver: I2C_RCU + rw: variable #server RW variable, not linked to IO + dtype: boolean + dim: 96 + + - name: RCU_mask + description: Only masked RCUs are updated + driver: I2C_RCU + rw: variable #server RW variable, not linked to IO + dtype: boolean + dim: 32 + + - name: RCU_I2C_STATUS + description: 0=Good, 1=No communication, 2=error + driver: I2C_RCU + rw: ro #server RW variable, not linked to IO + dtype: uint8 + mask: RCU_mask + dim: 32 + +# - name: RCU_state +# description: State of RCUs 0=unknown, 1=ready, 2=busy, 3= wait PPS, 4=error +# driver: I2C_RCU +# rw: ro #server variable, not linked to IO +# dtype: uint8 +# dim: 1 + + - name: RCU_translator_busy + description: False when idle + rw: ro #server variable, not linked to IO + dtype: boolean + dim: 1 + + - name: RCU_attenuator + description: Attenuator before ADC + driver: I2C_RCU + devreg: [IO1.GPIO1,IO1.GPIO2,IO2.GPIO1] + bitoffset: [0,0,0] + width: 5 + rw: rw + dtype: uint8 + dim: 96 + mask: Ant_mask + + - name: RCU_band + description: Band select switch 1=10MHz,2=30MHz + driver: I2C_RCU + devreg: [IO2.GPIO2,IO2.GPIO2,IO2.GPIO2] + bitoffset: [0,2,4] + width: 2 + rw: rw + dtype: uint8 + dim: 96 + mask: Ant_mask + + - name: [RCU_IO1_GPIO1,RCU_IO1_GPIO2,RCU_IO2_GPIO1,RCU_IO2_GPIO2,RCU_IO3_GPIO1,RCU_IO3_GPIO2] + driver: I2C_RCU + devreg: [IO1.GPIO1,IO1.GPIO2,IO2.GPIO1,IO2.GPIO2,IO3.GPIO1,IO3.GPIO2] + width: 8 + rw: ro + dtype: uint8 + dim: 32 + mask: RCU_mask + debug: True + + - name: RCU_LED0 + driver: I2C_RCU + description: LED on RCU + devreg: IO2.GPIO2 + bitoffset: 6 + width: 1 + rw: rw + dtype: boolean + dim: 32 + mask: RCU_mask + + - name: RCU_LED1 + driver: I2C_RCU + description: LED on RCU + devreg: IO2.GPIO2 + bitoffset: 7 + width: 1 + rw: rw + dtype: boolean + dim: 32 + mask: RCU_mask + + - name: RCU_temperature + description: Temperature sensor on RCU + driver: I2C_RCU + devreg: AN.Temp + width: 23 + scale: 4.21e-3 + rw: ro + dtype: double + dim: 32 + monitor: true + mask: RCU_I2C_STATUS + + - name: RCU_Pwr_dig + description: Enable LDOs + driver: I2C_RCU + devreg: IO2.GPIO1 + width: 1 + bitoffset: 6 + rw: ro + dtype: boolean + dim: 32 + mask: RCU_mask + + - name: HBA_element_beamformer_delays + description: Delays of each frontend + driver: I2C_HBAT + devreg: [HBAT1.XY,HBAT2.XY,HBAT3.XY] + bitoffset: [2,2,2] + width: 5 + rw: rw + dtype: uint8 + dim: 3072 + mask: Ant_mask + wait: 100 #ms + + - name: [HBA_element_led,HBA_element_pwr,HBA_element_LNA_pwr] + description: LED, power, frontend power of each frontend + driver: I2C_HBAT + devreg: [HBAT1.XY,HBAT2.XY,HBAT3.XY] + bitoffset: [0,7,1] + width: 1 + rw: rw + dtype: boolean + dim: 3072 + mask: Ant_mask + wait: 100 #ms + + - name: RCU_ID + description: Unique RCU ID + driver: I2C_RCU + devreg: ROM.ID + width: 32 + rw: ro + dtype: uint32 + dim: 32 + mask: RCU_mask + + - name: RCU_version + description: RCU version number + driver: I2C_RCU + devreg: ROM.Version + width: 80 #10 characters + rw: ro + dtype: string + dim: 32 + mask: RCU_mask + + - name: RCU_ADC_lock + description: 0x81=locked + driver: I2C_RCU + devreg: [ADC1.PLL_stat,ADC2.PLL_stat,ADC3.PLL_stat] + width: 8 + rw: ro + dtype: uint8 + dim: 96 + monitor: true + + - name: RCU_ADC_sync + description: 0x81=locked + driver: I2C_RCU + devreg: [ADC1.SYNC_control,ADC2.SYNC_control,ADC3.SYNC_control] + width: 8 + rw: ro + dtype: uint8 + dim: 96 + debug: true + +# - name: RCU_dth1_freq +# driver: I2C_RCU +# devreg: [DTH1.Freq,DTH2.Freq,DTH3.Freq] +# width: 32 +# rw: rw +# dtype: uint32 +# dim: 96 +# mask: Ant_mask + +methods: + - name: RCU_Init #Called after startup to load. Should have all stored registers + driver: I2C_RCU + debug: True + instructions: + - RCU_IO1_GPIO1: Update + - RCU_IO1_GPIO2: Update + - RCU_IO2_GPIO1: Update + - RCU_IO2_GPIO2: Update + - RCU_IO3_GPIO1: Update + - RCU_IO3_GPIO2: Update +# - IO1.GPIO2: Update +# - IO2.GPIO1: Update +# - IO2.GPIO2: Update +# - IO3.GPIO1: Update +# - IO3.GPIO2: Update + - IO3.CONF1: Update + - RCU_update: 0 + + - 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 + - IO2.GPIO1: 0x4A + - IO2.GPIO2: 0x55 + - IO3.GPIO1: 0x15 + - IO3.GPIO2: 0x47 + - IO1.GPIO1: 0xCA + - IO1.GPIO2: 0xCA + - IO2.CONF2: 0 + - IO3.CONF1: 0 + - IO3.CONF2: 0 + - IO1.CONF1: 0 + - IO1.CONF1: 0 +# - RCU_GPIO1: Update +# - RCU_GPIO2: Update +# - RCU_attenuator: [10,10,10] #Set OPC-UA variable + - WAIT: 500 #ms to wait + - ADC1_on: 0 #call another opc-ua method + - ADC2_on: 0 + - ADC3_on: 0 + - WAIT: 500 #ms to wait + - RCU_update: 0 + + - name: RCU_update + driver: I2C_RCU + mask: RCU_mask + debug: True + instructions: + - RCU_Pwr_dig: Update #Read value and update the OPC-UA variable + - RCU_ID: Update + - RCU_version: Update + - RCU_LED0: Update + - RCU_attenuator: Update + - RCU_band: Update + - RCU_ADC_lock: Update + - RCU_ADC_sync: Update + + + - name: ADC1_on + driver: I2C_RCU + debug: True +# rw: hidden + instructions: + - ADC1.JESD_control1 : 0x14 + - ADC1.SYNC_control: 1 #Setup ADCs + - ADC1.CML_level: 0x7 + - ADC1.Update: 1 #Needed to update ADC registers + + - name: ADC2_on + driver: I2C_RCU + debug: True +# rw: hidden + instructions: + - ADC2.JESD_control1 : 0x14 + - ADC2.SYNC_control: 1 #Setup ADCs + - ADC2.CML_level: 0x7 + - ADC2.Update: 1 #Needed to update ADC registers + + - name: ADC3_on + driver: I2C_RCU + debug: True +# rw: hidden + instructions: + - ADC3.JESD_control1 : 0x14 + - ADC3.SYNC_control: 1 #Setup ADCs + - ADC3.CML_level: 0x7 + - ADC3.Update: 1 #Needed to update ADC registers + + - name: RCU_off + driver: I2C_RCU + mask: RCU_mask + instructions: + - RCU_Pwr_dig: 0 #Switch power off + - IO2.GPIO1: 0 + - IO2.GPIO2: 0 + - IO3.GPIO1: 0 + - IO3.GPIO2: 0 + - IO1.GPIO1: 0 + - IO1.GPIO2: 0 + - RCU_update: 0 + #todo, also make all GPIO pins (except power enables) inputs to remove all power from devices. + + - name: RCU_HBAT_WAIT_PPS + driver: I2C_RCU + mask: RCU_mask + debug: True + instructions: + - RCU_state: 3 + - HB_UC_update.wait_pps : 1 + - RCU_state: 1 + diff --git a/config/UNB2.yaml b/config/UNB2.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5ac65152df724826fc6d31bd083adf5d8d630d2f --- /dev/null +++ b/config/UNB2.yaml @@ -0,0 +1,296 @@ +version: "0.0" +description: "UNB2 DTS first draft" + +drivers: + - name: I2C1 + type: i2c_switch2 + devreg: [APSCT_SWITCH.MASK,UB2_SWITCH1.MASK,UB2_SWITCH2.MASK] + parameters: [3,0,0,0] #I2C port number, 3x switch reset pins + + - name: switch_UNB2 + type: i2c_array + parent: I2C1 + parameters: [0,1] + status: UNB2_I2C_bus_STATUS + + - name: switch_PS + type: i2c_array2 + parent: I2C1 + parameters: [0,1, 4,4] + status: UNB2_I2C_bus_PS_STATUS + + - name: switch_FP + type: i2c_array2 + parent: I2C1 + parameters: [0,1, 5,5] + status: UNB2_I2C_bus_FP_STATUS + + - name: switch_QSFP + type: i2c_array2 #An array of similar devices connected to an I2C switch + parent: I2C1 + parameters: [0,1, 0,3, 0,3, 6,7] #Parameters: APSCT_Switch, main switch, 2nd switch, 2nd switch + status: UNB2_I2C_bus_QSFP_STATUS + + - name: switch_DDR4 + type: i2c_array2 + parent: I2C1 + parameters: [0,1, 0,3, 4,4] + status: UNB2_I2C_bus_DDR4_STATUS + + - name: switch_FPGA_PS + type: i2c_array2 + parent: I2C1 + parameters: [0,1, 0,3, 5,5] + status: UNB2_I2C_bus_FPGA_PS_STATUS + + - name: GPIO + type: gpio + + +#This is the I2C devices in the RCU +device_registers: +- name: APSCT_SWITCH #not in LTS + description: Uniboard select switch on APSCT + address: 0x70 + device: TCA9548 + driver: I2C1 + registers: + - name: MASK +- name: UB2_SWITCH1 + description: UNB2 primary switch + address: 0x71 + device: TCA9548 + driver: I2C1 + registers: + - name: MASK +- name: UB2_SWITCH2 + description: UNB2 secondary switch + address: 0x72 + device: TCA9548 + driver: I2C1 + registers: + - name: MASK + +- name: FP_IO + description: IO-Expander for front panel + address: 0x41 + device: PCA9536 + driver: d_front_panel + registers: + - name: CONF #default 0xff = all input + description: Direction of GPIO + address: 3 + - name: GPIO + description: Input/Ouput port + address: [0,1] #Read / Write address different + store: True + + +variables: + +#When I2C bus timeout, bus_STATUS set to False. Can we set to True again to retry. + - name: UNB2_I2C_bus_STATUS + driver: switch_UNB2 + rw: ro + dtype: uint8 + dim: 2 + - name: UNB2_I2C_bus_FP_STATUS + driver: switch_UNB2 + rw: hidden + dtype: uint8 + dim: 2 + - name: UNB2_I2C_bus_QSFP_STATUS + driver: switch_QSFP + rw: ro + dtype: uint8 + dim: 48 + - name: UNB2_I2C_bus_DDR4_STATUS + driver: switch_QSFP + rw: ro + dtype: uint8 + dim: 8 + - name: UNB2_I2C_bus_FPGA_PS_STATUS + driver: switch_FPGA_PS + rw: ro + dtype: uint8 + dim: 8 + - name: UNB2_I2C_bus_PS_STATUS + driver: switch_PS + rw: ro + dtype: uint8 + dim: 2 + + - name: UNB2_translator_busy + description: False when idle + rw: ro #server variable, not linked to IO + dtype: boolean + dim: 1 + +##Central MP for whole Uniboard2 + - name: UNB2_mask + rw: variable #translator variable + dtype: boolean + dim: 2 + + - name: UNB2_Power_ON_OFF + driver: GPIO + mask: UNB2_mask + width: 1 + rw: ro + dtype: boolean + dim: 2 + + - name: UNB2_Front_Panel_LED + description: bit 0=Red, 1=Blue, 2=Green + mask: UNB2_mask + driver: switch_FP + devreg: FP_IO.GPIO + bitoffset: 4 + width: 3 + rw: rw + dtype: uint8 + dim: 2 + + - name: UNB2_EEPROM_Serial_Number + driver: switch_UNB2 + devreg: 0x50.0 + width: 80 #10 characters + rw: ro + dtype: string + dim: 2 + + - name: UNB2_EEPROM_Unique_ID + driver: switch_UNB2 + devreg: 0x50.0xFC + width: 32 + rw: ro + dtype: uint32 + dim: 2 + + - name: [UNB2_DC_DC_48V_12V_VIN,UNB2_DC_DC_48V_12V_VOUT,UNB2_DC_DC_48V_12V_IOUT,UNB2_DC_DC_48V_12V_TEMP] + driver: switch_PS + devreg: [0x2C.0x88,0x2C.0x8B,0x2C.0x8C,0x2C.0x8D] + width: 16 + rw: ro + dtype: double + scale: 1.2207e-4 #2^-13 + dim: 2 + monitor: true + + - name: [UNB2_POL_QSFP_N01_VOUT,UNB2_POL_QSFP_N01_IOUT,UNB2_POL_QSFP_N01_TEMP,UNB2_POL_QSFP_N23_VOUT,UNB2_POL_QSFP_N23_IOUT,UNB2_POL_QSFP_N23_TEMP] + driver: switch_PS + devreg: [0x2.0x8B,0x2.0x8C,0x2.0x8D,0x1.0x8B,0x1.0x8C,0x1.0x8D] + width: 16 + rw: ro + dtype: double + scale: 1.2207e-4 #2^-13 + dim: 2 + monitor: true + + - name: [UNB2_POL_SWITCH_1V2_VOUT,UNB2_POL_SWITCH_1V2_IOUT,UNB2_POL_SWITCH_1V2_TEMP,UNB2_POL_SWITCH_PHY_VOUT,UNB2_POL_SWITCH_PHY_IOUT,UNB2_POL_SWITCH_PHY_TEMP] + driver: switch_PS + devreg: [0xF.0x8B,0xF.0x8C,0xF.0x8D,0xE.0x8B,0xE.0x8C,0xE.0x8D] + width: 16 + rw: ro + dtype: double + scale: 1.2207e-4 #2^-13 + dim: 2 + monitor: true + + - name: [UNB2_POL_CLOCK_VOUT,UNB2_POL_CLOCK_IOUT,UNB2_POL_CLOCK_TEMP] + driver: switch_PS + devreg: [0xD.0x8B,0xD.0x8C,0xD.0x8D] + width: 16 + rw: ro + dtype: double + scale: 1.2207e-4 #2^-13 + dim: 2 + monitor: true + +##Local MP per FPGA node + - name: UNB2_FPGA_DDR4_SLOT_TEMP + description: Signed I2C! + driver: switch_DDR4 + devreg: [0x18.0x5,0x19.0x5] + width: 13 + rw: ro + dtype: double + scale: 0.0625 + dim: 16 + monitor: true + + - name: UNB2_FPGA_DDR4_SLOT_PART_NUMBER + driver: switch_DDR4 + devreg: [0x18.0x149,0x19.0x149] + width: 160 + rw: ro + dtype: string + dim: 16 + monitor: true + + - name: [UNB2_POL_FPGA_CORE_VOUT,UNB2_FPGA_POL_CORE_IOUT,UNB2_FPGA_POL_CORE_TEMP,UNB2_FPGA_POL_ERAM_VOUT,UNB2_FPGA_POL_ERAM_IOUT,UNB2_FPGA_POL_ERAM_TEMP] + driver: switch_FPGA_PS + devreg: [0x1.0x8B,0x1.0x8C,0x1.0x8D,0xD.0x8B,0xD.0x8C,0xD.0x8D] + width: 16 + rw: ro + dtype: double + scale: 1.2207e-4 #2^-13 + dim: 8 + monitor: true + + - name: [UNB2_FPGA_POL_RXGXB_VOUT,UNB2_FPGA_POL_RXGXB_IOUT,UNB2_FPGA_POL_RXGXB_TEMP,UNB2_FPGA_POL_TXGXB_VOUT,UNB2_FPGA_POL_TXGXB_IOUT,UNB2_POL_FPGA_TXGXB_TEMP] + driver: switch_FPGA_PS + devreg: [0xE.0x8B,0xE.0x8C,0xE.0x8D,0xF.0x8B,0xF.0x8C,0xF.0x8D] + width: 16 + rw: ro + dtype: double + scale: 1.2207e-4 #2^-13 + dim: 8 + monitor: true + + - name: [UNB2_FPGA_POL_HGXB_VOUT,UNB2_FPGA_POL_HGXB_IOUT,UNB2_FPGA_POL_HGXB_TEMP,UNB2_FPGA_POL_PGM_VOUT,UNB2_FPGA_POL_PGM_IOUT,UNB2_FPGA_POL_PGM_TEMP] + driver: switch_FPGA_PS + devreg: [0x10.0x8B,0x10.0x8C,0x10.0x8D,0x11.0x8B,0x11.0x8C,0x11.0x8D] + width: 16 + rw: ro + dtype: double + scale: 1.2207e-4 #2^-13 + dim: 8 + monitor: true + + + +##Local MP per FPGA node, QSFP cage + - name: UNB2_FPGA_QSFP_CAGE_TEMP + description: Signed I2C! + driver: switch_QSFP + devreg: 0x50.0x16 + width: 16 + rw: ro + dtype: double + scale: 0.0625 #TBC + dim: 48 + monitor: true + + - name: UNB2_FPGA_QSFP_CAGE_LOS + description: Bits for 4 TX, 4 RX channels + driver: switch_QSFP + devreg: 0x50.0x03 + width: 8 + rw: ro + dtype: uint8 + dim: 48 + monitor: true + + +methods: + - name: UNB2_on + mask: UNB2_mask + instructions: + - FP_IO.CONF: 0xff #TODO: setup correctly + - UNB2_Front_Panel_LED: 1 + + - name: UNB2_off + mask: UNB2_mask + instructions: + - UNB2_Front_Panel_LED: 2 diff --git a/config/apsctl.schema.json b/config/apsctl.schema.json new file mode 100644 index 0000000000000000000000000000000000000000..07c6b82a4866a48c4d4f4b3166af321404950a95 --- /dev/null +++ b/config/apsctl.schema.json @@ -0,0 +1,83 @@ +{ + "$id": "http://git.astron.nl/lofar2.0/pypcc/apsctl.schema.json", + "$schema": "http://json-schema.org/draft-07/schema", + "title": "apsctl", + "description": "APSCTL yaml schema", + "type" : "object", + "properties": { + "version": {"type":"string"}, + "description":{"type":"string"}, + "drivers": { "type":"array", "items": { "$ref": "#/$defs/drivers"}}, + "device_registers":{ "type":"array", "items": { "$ref": "#/$defs/dev_regs"}}, + "variables":{ "type":"array", "items": { "$ref": "#/$defs/variables"}}, + "methods":{ "type":"array", "items": { "$ref": "#/$defs/methods"}} + }, + "additionalProperties" : false, + "$defs":{ + "drivers" : { + "type" : "object", + "properties": { + "name" : {"type":"string"}, + "type" : {"enum":["i2c","RCU_switch","UNB2_switch","i2c_devs","i2c_array","i2c_array2","hba1","i2cbitbang1","spibitbang1","spibitbang2"]}, + "parent" : {"type":"string"}, + "parameters" : {"type":"array","items":{"type":"integer"}} , + "devreg" : {"type":"array","items":{"type":"string"}} + }, + "additionalProperties" : false + }, + "dev_regs" : { + "type" : "object", + "properties": { + "name" : {"type":"string"}, + "dim" : {"type":"integer"}, + "description" : {}, + "address" : {"anyOf":[{"type":"integer"},{"type":"array","items":{"type":"integer"}}]}, + "device" : {}, + "driver" : {}, + "registers":{ "type":"array", "items": { "$ref": "#/$defs/registers"}} + }, + "additionalProperties" : false + }, + "registers" : { + "type" : "object", + "properties": { + "name" : {"type":"string"}, + "description" : {"type":"string"}, + "address" : {}, + "store" : {"type":"boolean"} + }, + "additionalProperties" : false + }, + "variables" : { + "type" : "object", + "properties": { + "name" : {"type":"string"}, + "description" : {"type":"string"}, + "dim" : {"type":"integer"}, + "dtype" : {"enum":["uint64","uint32","uint16","uint8","double","boolean","string"]}, + "driver" : {"type":"string"}, + "rw" : {"enum":["variable","rw","ro","hidden"]}, + "scale" : {"type":"number"}, + "bitoffset" : {}, + "width" : {"type":"integer"}, + "devreg" : {}, + "mask" : {"type":"string"} + }, + "additionalProperties" : false + }, + "methods" : { + "type" : "object", + "properties": { + "name" : {"type":"string"}, + "mask" : {"type":"string"}, + "instructions" : {"type":"array"}, + "rw" : {"enum":["visible","hidden"]} + }, + "additionalProperties" : false + } + + } + +} + + diff --git a/i2c/I2C.py b/i2c/I2C.py deleted file mode 100644 index 10eddc5245bd9025c220b178d007402d9058eca2..0000000000000000000000000000000000000000 --- a/i2c/I2C.py +++ /dev/null @@ -1,71 +0,0 @@ -#import os -#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; - diff --git a/i2c/I2C.py.old b/i2c/I2C.py.old deleted file mode 100644 index 1982b43c9c0e13bf33d61d4bf48e8c2b940b5d06..0000000000000000000000000000000000000000 --- a/i2c/I2C.py.old +++ /dev/null @@ -1,70 +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): -# 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() - print("I2C4 error") -# data[0]=0xff - return False; - diff --git a/i2c/I2C_dummy.py b/i2c/I2C_dummy.py deleted file mode 100644 index ba39c1a5d6e1df962bc6f5e1eab79140cd5ec122..0000000000000000000000000000000000000000 --- a/i2c/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.debug(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/i2c/I2Cswitch1.py b/i2c/I2Cswitch1.py deleted file mode 100644 index 187456b1d6cc9eb2d15330d216ff89e72fe42a18..0000000000000000000000000000000000000000 --- a/i2c/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/i2c/I2Cv2.py b/i2c/I2Cv2.py deleted file mode 100644 index 1627b362488d3a250654c41856f4ecfe1baa41ad..0000000000000000000000000000000000000000 --- a/i2c/I2Cv2.py +++ /dev/null @@ -1,62 +0,0 @@ -#import pylibi2c; -#import -from periphery import I2C; - -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; - - -i2c1=I2C("/dev/i2c-1") - -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))) - if read==1: - if not(reg is None): i2c1.transfer(addr,[I2C.Message([reg])]) - msgs=[I2C.Message(data,read=True)] - i2c1.transfer(addr,msgs) - data[:]=msgs[0].data - else: - if reg is None: - msgs=[I2C.Message(data)] - else: - msgs=[I2C.Message([reg]+data)] - i2c1.transfer(addr,msgs) - return True; - except: - return False; - -i2c4=I2C("/dev/i2c-4") - -def I2C4server(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))) - - if read==1: - if not(reg is None): i2c4.transfer(addr,[I2C.Message([reg])]) - msgs=[I2C.Message(data,read=True)] - i2c4.transfer(addr,msgs) - data[:]=msgs[0].data - else: - if reg is None: - msgs=[I2C.Message(data)] - else: - msgs=[I2C.Message([reg]+data)] - i2c4.transfer(addr,msgs) - return True; - except: - return False; diff --git a/i2c/setRCUversion.py b/i2c/setRCUversion.py deleted file mode 100644 index 4771de66e197be6a9f94861bcf39c8c4b2baa3ce..0000000000000000000000000000000000000000 --- a/i2c/setRCUversion.py +++ /dev/null @@ -1,34 +0,0 @@ -from I2C import * -import time -RCU=1 -Ver="RCU2H v0.2" -R1=0 -ROM=0x50 - -#Set switch -print("Set switch") -if not(I2C1server(0x70,[1<<RCU],reg=None,read=0)): exit() #select RCU -#exit() -#Get ID -print("Get ID") -ID=[0]*4 -if not(I2C1server(ROM,ID,reg=0xFC,read=1)): exit() #select RCU -print(ID) -exit() - -#Upload version -Ver2=[(c.encode('utf-8')[0]) for c in Ver] -print(len(Ver),Ver,Ver2) -V2=[0] -for i,v in enumerate(Ver2): - time.sleep(0.1) - I2C1server(ROM,[v],reg=R1+i,read=0) #select RCU -# I2C1server(ROM,[v],reg=None,read=0) #select RCU - time.sleep(0.1) - I2C1server(ROM,V2,reg=R1+i,read=1) #select RCU - print(i,v,V2) - -#Download version -Ver2=[0]*10 -I2C1server(ROM,Ver2,reg=R1,read=1) #select RCU -print(Ver2) diff --git a/i2c/setswitch.py b/i2c/setswitch.py deleted file mode 100644 index 45f43942a9b3dc1fc7cde1b4efa5a06b674bde92..0000000000000000000000000000000000000000 --- a/i2c/setswitch.py +++ /dev/null @@ -1,36 +0,0 @@ -from I2C import * -import time -RCU=3 -Ver="RCU2H v0.2" -R1=0 -ROM=0x50 - -#Set switch -print("Set switch") -if not(I2C1server(0x70,[1<<RCU],reg=None,read=0)): - print("Error setting switch!") - exit() #select RCU -exit() -#Get ID -print("Get ID") -ID=[0]*4 -if not(I2C1server(ROM,ID,reg=0xFC,read=1)): exit() #select RCU -print(ID) -exit() - -#Upload version -Ver2=[(c.encode('utf-8')[0]) for c in Ver] -print(len(Ver),Ver,Ver2) -V2=[0] -for i,v in enumerate(Ver2): - time.sleep(0.1) - I2C1server(ROM,[v],reg=R1+i,read=0) #select RCU -# I2C1server(ROM,[v],reg=None,read=0) #select RCU - time.sleep(0.1) - I2C1server(ROM,V2,reg=R1+i,read=1) #select RCU - print(i,v,V2) - -#Download version -Ver2=[0]*10 -I2C1server(ROM,Ver2,reg=R1,read=1) #select RCU -print(Ver2) diff --git a/i2c/test.py b/i2c/test.py deleted file mode 100644 index 92ee093a8b833322558341cd664855f643f57dd1..0000000000000000000000000000000000000000 --- a/i2c/test.py +++ /dev/null @@ -1,37 +0,0 @@ -from I2C import * -import time -RCU=1 -Ver="RCU2H v0.2" -R1=0 -ROM=0x50 - -ID=[0]*7 -I2C1server(0x20,ID,reg=2,read=1) -print(ID) -I2C1server(0x20,ID,reg=2,read=1) -print(ID) -exit() -#0=0 -#1=0 #debug? -#2=21 #spd1 -#3=7 #spd2 -#4=175 #TXspeed -#5=0 -#6=0 - -#Upload version -Ver2=[(c.encode('utf-8')[0]) for c in Ver] -print(len(Ver),Ver,Ver2) -V2=[0] -for i,v in enumerate(Ver2): - time.sleep(0.1) - I2C1server(ROM,[v],reg=R1+i,read=0) #select RCU -# I2C1server(ROM,[v],reg=None,read=0) #select RCU - time.sleep(0.1) - I2C1server(ROM,V2,reg=R1+i,read=1) #select RCU - print(i,v,V2) - -#Download version -Ver2=[0]*10 -I2C1server(ROM,Ver2,reg=R1,read=1) #select RCU -print(Ver2) diff --git a/clk/__init__.py b/i2cserv/__init__.py similarity index 100% rename from clk/__init__.py rename to i2cserv/__init__.py diff --git a/i2cserv/gpio.py b/i2cserv/gpio.py new file mode 100644 index 0000000000000000000000000000000000000000..20e38ab4a1161a435ee7c202bf5786a10510660a --- /dev/null +++ b/i2cserv/gpio.py @@ -0,0 +1,7 @@ +#import numpy as np +from .hwdev import hwdev; +import logging +class gpio(hwdev): + def __init__(self,config): + hwdev.__init__(self,config); + logging.info("gpio todo") diff --git a/i2cserv/gpio_hba_trigger.py b/i2cserv/gpio_hba_trigger.py new file mode 100644 index 0000000000000000000000000000000000000000..452f5630af6bde50e9e1f6daeba798e6fd22634e --- /dev/null +++ b/i2cserv/gpio_hba_trigger.py @@ -0,0 +1,28 @@ +from .hwdev import hwdev; +import logging +import signal +try: + import RPi.GPIO as GPIO +except: + GPIO=False; + +class gpio_hba_trigger(hwdev): + def __init__(self,config): + hwdev.__init__(self,config); + self.pin=config['parameters'][0]; + logging.info("HBAT wait for PPS on pin %i",self.pin) + if GPIO: + GPIO.setmode(GPIO.BCM) + GPIO.setup(self.pin,GPIO.IN) + else: + logging.warn("RPi GPIO module not found, PPS input disable!") + + def i2csetget(self,addr,data,reg=None,read=0): + if (read==0) and GPIO: + channel=GPIO.wait_for_edge(self.pin,GPIO.RISING,timeout=1500) + if channel is None: + logging.info("PPS not received!"); + return False; + self.conf['parentcls'].i2csetget(addr,data,reg,read) + + diff --git a/i2cserv/hba1.py b/i2cserv/hba1.py new file mode 100644 index 0000000000000000000000000000000000000000..1a0524b35767457a6b60a237ab7775bfcf3e2fb1 --- /dev/null +++ b/i2cserv/hba1.py @@ -0,0 +1,51 @@ +import numpy as np +from .hwdev import hwdev +import logging +from .i2c_array import ApplyMask +from time import sleep +from queuetypes import * + +class hba1(hwdev): + def __init__(self,config): + hwdev.__init__(self,config); + logging.info("HBA1 driver loaded") +# self.previousHBA=np.zeros([32,3,32],dtype='int') + + def OPCUASetVariable(self,varid,var1,data,mask): + logging.info(str(("HBA set Var",var1['name'],data[:32*3],mask[:12]))) + self.conf['parentcls'].SetGetVarValueMask(var1,data,mask,getalso=False) + #Wait for PPS if required else wait a bit + if var1.get('wait'): + logging.debug("Wait %i ms",var1.get('wait')) + sleep(var1['wait']/100.) + data,mask2=self.conf['parentcls'].GetVarValueMask(var1,mask) + Data=OPCUAset(varid,InstType.varSet,data.copy(),mask2.copy()) + return [Data] + + def i2csetget(self,addr,data,reg=None,read=0): + if read==0: return self.sethba(addr,reg,data) + elif read==1: return self.gethba(addr,reg,data) + else: logging.warn("Not implemented!") + return False; + + def sethba(self,addr,reg,data): + logging.debug("SetHba addr=0x%x reg=0x%x",addr,reg) + I2Ccallback=self.conf['parentcls'].i2csetget + I2Ccallback(0x40,[0],read=1)#wakeup, do nothing + sleep(0.01) + I2Ccallback(addr,data[:16],reg=reg) + if len(data)>16: + sleep(0.01) + I2Ccallback(addr,data[16:],reg=reg+16) + sleep(0.01) + return True + + def gethba(self,addr,reg,data): + I2Ccallback=self.conf['parentcls'].i2csetget +# logging.debug("getHba addr=0x%x reg=0x%x",addr,reg) + if not(I2Ccallback(addr,data,read=1)): return False; +# I2Ccallback(addr,data,read=1); + logging.debug("getHba addr=0x%x reg=0x%x data=%s",addr,reg,str((data))) + if data is None: return False +# data[:]=[255]*len(data) + return True; \ No newline at end of file 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..3eb98b2e5b2709666b647b370600ac8f6fc27a61 --- /dev/null +++ b/i2cserv/i2c.py @@ -0,0 +1,52 @@ +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): +# logging.debug(str(("I2C",addr,reg,data,read))) + bus=None; + try: +# if True: + if read==3: + time.sleep(data[0]/1000.) + return True + +# 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,bytes(bytearray([reg]))) + data[:]=[int(x) for x in bus.ioctl_read(0,length)] + logging.debug(str(("I2C get",addr,reg,data,read))) +# print("I2C read",addr,reg,data,read) + else: + if reg is None: + bus.iaddr_bytes=0 + reg=0; + logging.debug(str(("I2C set",addr,reg,bytes(bytearray(data)),read))) + bus.ioctl_write(reg,bytes(bytearray(data))) + bus.close() + return True; + except: +# else: + if bus: bus.close() + logging.debug("I2C failed!") +# data[0]=0xff + return False; + diff --git a/i2cserv/i2c_array.py b/i2cserv/i2c_array.py new file mode 100644 index 0000000000000000000000000000000000000000..60fed98e8b6247608a9c99ba03605d8a4e7c7696 --- /dev/null +++ b/i2cserv/i2c_array.py @@ -0,0 +1,216 @@ +import numpy as np +import logging +from .spibitbang1 import spibitbang1 +from queuetypes import * +from .hwdev import hwdev +from .i2c_dev import * + +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_array(i2c_dev): + def __init__(self,config): + i2c_dev.__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.I2Cmask=[0]*self.N + +# 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 OPCUAReadVariable(self,varid,var1,mask): + if len(mask)==0: mask=[True]*self.N; + return i2c_dev.OPCUAReadVariable(self,varid,var1,mask) + + 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]) and (self.I2Cmask[RCUi]==0): + m|=1<<self.RCU_Switch1[RCUi]; + self.conf['parentcls'].SetChannel(m); + + def SetGetVarValueMask(self,var1,data,mask,getalso=True): + 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); +# logging.debug(str(("Step=",Step,"Mask=",mask))) + for RCUi in range(self.N): + for Vari in range(Step): + if not(mask[RCUi*Step+Vari]): continue + if not(self.I2Cmask[RCUi]==0): + mask[RCUi*Step+Vari]=False; + 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; + res=self.SetVarValue(devreg,width,bitoffset,data[i0:i1]) + if not(res): + self.I2Cmask[RCUi]=1; + mask[RCUi*Step+Vari]=False; + continue; + if getalso: + value2=value1[i0:i1] + res=self.GetVarValue(devreg,width,bitoffset,value2) + if not(res): + self.I2Cmask[RCUi]=1; + 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; + 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']; +# logging.debug(str(("Step=",Step,"Mask=",mask))) + for RCUi in range(self.N): + for Vari in range(Step): + if not(mask[RCUi*Step+Vari]): continue + if not(self.I2Cmask[RCUi]==0): + mask[RCUi*Step+Vari]=False; + 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; + res=self.GetVarValue(devreg,width,bitoffset,value2) + if not(res): + self.I2Cmask[RCUi]=1; + 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): + devreg['storearray']=([0] if N==1 else [[0]*N])*self.N; + storearray=devreg.get('storearray'); + return storearray; + + 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]) and (self.I2Cmask[RCUi]==0): + storearray[RCUi]=value[0] + self.RCUi=RCUi; + logging.debug(str(("Stored values:",self.getstorearray(devreg)))) + 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]==0): 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))) + #self.parentcls.SetChannel(1<<RCU_Switch[RCUi]); + if devreg['store']: + storearray=self.getstorearray(devreg); + previous=storearray[self.RCUi]; + for x in range(len(value)): + value[x]=ApplyMask(value[x],width,bitoffset,previous); + storearray[self.RCUi]=(value[0] if len(value)==1 else value[:]) + logging.debug("Stored value:"+str(storearray[self.RCUi])) + # 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']: + storearray=self.getstorearray(devreg,len(value)); + storearray[self.RCUi]=(value[0] if len(value)==1 else value[:]) + logging.debug(str(("Store buffer",self.RCUi,storearray[self.RCUi]))) + # print("Stored values:",self.getstorearray(devreg)) + if (width!=l1*8) or (bitoffset>0): + if (width<8): + for i in range(len(value)): + value[i]=UnMask(value[i],width,bitoffset) + else: + value[0]=UnMask(value[0],width-(l1-1)*8,bitoffset) + else: value[0]=value2[0] + return True; + + diff --git a/i2cserv/i2c_array2.py b/i2cserv/i2c_array2.py new file mode 100644 index 0000000000000000000000000000000000000000..ef71eb3661414a3d1683c74950bf9d82a83dbabf --- /dev/null +++ b/i2cserv/i2c_array2.py @@ -0,0 +1,43 @@ +import logging +from .i2c_array import i2c_array; +from .hwdev import hwdev +from .i2c_dev import i2c_dev + + +class i2c_array2(i2c_array): + def __init__(self,config): + i2c_dev.__init__(self,config); + +# Make array of switch states + pars=config['parameters']; + self.Nswitch=(len(pars)+1)//2; + sw1=list(range(pars[0],pars[1]+1)); + sw2=([] if len(pars)<4 else list(range(pars[2],pars[3]+1))) + sw3=([] if len(pars)<6 else list(range(pars[4],pars[5]+1))) + sw4=([] if len(pars)<8 else list(range(pars[6],pars[7]+1))) + sw3=sw3+sw4 + if self.Nswitch>3: self.Nswitch=3; + self.RCU_Switch1=range(pars[0],pars[1]+1); + self.N=len(sw1) + if len(sw2)>0: self.N*=len(sw2) + if len(sw3)>0: self.N*=len(sw3) + self.I2Cmask=[0]*self.N + self.sw1=[x for x in sw1 for i in range(self.N//len(sw1))] + self.sw2=[x for x in sw2 for i in range(self.N//len(sw1)//len(sw2))]*len(sw1) + self.sw3=[x for x in sw3]*len(sw1)*len(sw2) + logging.debug(str(("Init",config['name'],' len=',self.N,'Nswitch=',self.Nswitch,self.sw1,self.sw2,self.sw3))) + + def SetSwitch(self,RCUi): + #print("Set switch element",RCUi,'=',self.sw1[RCUi],self.sw2[RCUi],(self.sw3[RCUi] if len(self.sw3)<0 else 'x')) + self.conf['parentcls'].SetSW1(self.sw1[RCUi]); + self.conf['parentcls'].SetSW2(self.sw2[RCUi]); + if len(self.sw3)>0: + self.conf['parentcls'].SetSW3(self.sw3[RCUi]); + + def SetSwitchMask(self,mask): + logging.warn("Not implemented!!") +# m=0; +# for RCUi in range(self.N): +# if mask[RCUi]: m|=1<<self.RCU_Switch1[RCUi]; +# self.conf['parentcls'].SetChannel(m); + diff --git a/i2cserv/i2c_dev.py b/i2cserv/i2c_dev.py new file mode 100644 index 0000000000000000000000000000000000000000..2f73afaad2f28220342175219b4b1ad2d80c8de4 --- /dev/null +++ b/i2cserv/i2c_dev.py @@ -0,0 +1,266 @@ +import numpy as np +import logging +from .spibitbang1 import spibitbang1 +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 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_dev(hwdev): + def __init__(self,config): + hwdev.__init__(self,config); + self.I2Cmask=[0] + self.I2Cmaskid=config.get('maskid',None) + if self.I2Cmaskid is None: logging.warn(config['name']+" I2C mask not found!") + + def OPCUASetVariable(self,varid,var1,data,mask): + logging.info(str(("Set Var",var1['name'],data,mask))) + if (var1['rw']=='variable') or not(var1.get('devreg')): + if varid==self.I2Cmaskid: + if len(mask)==0: mask=[True]*len(data); + if len(data)!=len(mask): + logging.warn("Trying to set I2C OK with wrong mask length!") + return [] + for x,m in enumerate(mask): + if m: self.I2Cmask[x]=data[x]; + return [OPCUAset(self.I2Cmaskid,InstType.varSet,self.I2Cmask.copy(),[])] + return [OPCUAset(varid,InstType.varSet,data,mask)]; + oldmask=self.I2Cmask.copy() + data,mask2=self.SetGetVarValueMask(var1,data,mask); +# if len(mask)==len(mask2): mask[:]=mask2[:]; +# elif len(mask)==0: (mask.append(x) for x in mask2); + Data=OPCUAset(varid,InstType.varSet,data.copy(),mask2.copy()) + if list_different(self.I2Cmask,oldmask): + Data=[Data,OPCUAset(self.I2Cmaskid,InstType.varSet,self.I2Cmask.copy(),[])] + else: Data=[Data] + return Data + + def OPCUAReadVariable(self,varid,var1,mask): + logging.info(str(("Read Var",var1['name'],mask))) + if not(var1.get('devreg')): return [] + #data=self.GetVarValueAll(var1) + #else: + oldmask=self.I2Cmask.copy() + data,mask2=self.GetVarValueMask(var1,mask); +# if len(mask)==len(mask2): mask[:]=mask2[:]; +# elif len(mask)==0: (mask.append(x) for x in mask2); + Data=OPCUAset(varid,InstType.varSet,data.copy(),mask2.copy()) + if list_different(self.I2Cmask,oldmask): + Data=[Data,OPCUAset(self.I2Cmaskid,InstType.varSet,self.I2Cmask.copy(),[])] + else: Data=[Data] + return Data + +# def OPCUAcallMethod(self,var1,data,mask): +# print("Call Method",var1) + + def i2csetget(self,*args,**kwargs): + return self.conf['parentcls'].i2csetget(*args,**kwargs) + + def SetGetVarValueMask(self,var1,data,mask): + Step=(len(var1['devreg']) if isinstance(var1['devreg'],list) else 1) + value1=[0]*Step + if not(len(data)==Step): + print("Check data length!"); + return; + if (len(mask)==1): + mask=[mask[0] for x in range(Step)] + if (len(mask)==0): + mask=[True for x in range(Step)] + if not(len(mask)==Step): + print("Check mask length!"); + return; + for Vari in range(Step): + if not(mask[Vari]): continue + if not(self.I2Cmask[0]==0): + mask[Vari]=False; + continue; + i0=(Vari)*Step + i1=(Vari+1)*Step + devreg=var1['devreg'][Vari]; + width=var1.get('width',8) + bitoffset=GetField(var1,'bitoffset',Vari,0) + res=self.SetVarValue(devreg,width,bitoffset,data[i0:i1]) + if not(res): + self.I2Cmask[0]=1; + mask[Vari]=False; + continue; + value2=value1[i0:i1] + res=self.GetVarValue(devreg,width,bitoffset,value2) + if not(res): + self.I2Cmask[0]=1; + mask[Vari]=False; + continue; + value1[i0:i1]=value2 + return value1,mask + + + def GetVarValueMask(self,var1,mask): + Step=(len(var1['devreg']) if isinstance(var1['devreg'],list) else 1) + value1=[0]*Step; + if (len(mask)==1): + mask=[mask[0] for x in range(Step)] + if (len(mask)==0): + mask=[True for x in range(Step)] + if not(len(mask)==Step): + print("Check mask length!"); + return; + for Vari in range(Step): + if not(mask[Vari]): continue + if not(self.I2Cmask[0]==0): + mask[Vari]=False; + continue; + i0=( Vari)*Step + i1=(Vari+1)*Step + devreg=var1['devreg'][Vari]; + width=var1.get('width',8) + bitoffset=GetField(var1,'bitoffset',Vari,0) + value2=value1[i0:i1] + res=self.GetVarValue(devreg,width,bitoffset,value2) + if not(res): + self.I2Cmask[0]=1; + mask[Vari]=False; + continue; + value1[i0:i1]=value2 + return value1,mask + + + def getstoreval(self,devreg): + storeval=devreg.get('storeval') + if not(storeval): + devreg['storeval']=0; + storeval=devreg.get('storeval'); + return storeval; + + def Setdevreg(self,devreg,value,mask=[]): +# if devreg.get('store'): logging.debug("Stored") +# print(devreg['store']) + if not(self.I2Cmask[0]==0): return False; + res=self.SetVarValue(devreg,8,0,value) + if not(res): + self.I2Cmask[0]=1; + return False; + if devreg.get('store'): + devreg['storeval']=value[0]; + return True; + + def Getdevreg(self,devreg,mask=[]): + value=[0]; + if not(self.I2Cmask[0]==0): return False; + res=self.GetVarValue(devreg,8,0,value) + if not(res): + self.I2Cmask[0]=1; + return False; + 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 + logging.debug(str(("I2C Set ",devreg['addr'],value))) + #self.parentcls.SetChannel(1<<RCU_Switch[RCUi]); + if devreg['store']: + previous=self.getstoreval(devreg); + for x in range(len(value)): + value[x]=ApplyMask(value[x],width,bitoffset,previous); + devreg['storeval']=value[0]; + logging.debug("Stored value:"+str(value[0])) + # 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 ",devreg['addr'],value))) + callback=devreg['drivercls'].i2csetget; + value2=value + reg=devreg['register_R'] + if not(callback(devreg['addr'],value2,reg=reg,read=1)): return False; + if value2[0] is None: return False + value[:]=value2[:]; + if devreg['store']: + devreg['storeval']=value[0]; + l1=int(np.floor((width+bitoffset+7)/8)) + #print(value[0],width,bitoffset,l1) + if (width!=l1*8) or (bitoffset>0): + if (width<8): + for i in range(len(value)): + value[i]=UnMask(value[i],width,bitoffset) + else: + value[0]=UnMask(value[0],width-(l1-1)*8,bitoffset) + else: value[0]=value2[0] + return True; + diff --git a/i2cserv/i2c_switch.py b/i2cserv/i2c_switch.py new file mode 100644 index 0000000000000000000000000000000000000000..6863b5ad2688fc7aacb2d1898575cd200a191617 --- /dev/null +++ b/i2cserv/i2c_switch.py @@ -0,0 +1,28 @@ +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 SetSW1(self,channelbit): + channel=(0 if (channelbit>5) else 1<<(channelbit)) #LTS + if (channel)==self.CurrentChannel: return True; + logging.debug("SetChannelbit=%i" % channelbit) + self.CurrentChannel=channel + return self.i2csetget(self.SWaddr,[channel]) + + def SetChannel(self,channel): + channel&=0x3F;#LTS + if (channel)==self.CurrentChannel: return True; + logging.debug("SetChannel=%i" % channel) + self.CurrentChannel=channel + 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/i2c_switch2.py b/i2cserv/i2c_switch2.py new file mode 100644 index 0000000000000000000000000000000000000000..e86b47cff9fa12144433358100be54c006260fb0 --- /dev/null +++ b/i2cserv/i2c_switch2.py @@ -0,0 +1,39 @@ +#3 switches of UNB2 +import logging +from .i2c import i2c + +class i2c_switch2(i2c): + def __init__(self,config): + i2c.__init__(self,config) + self.SWaddr1=config['devreg'][0]['addr'] + self.SWaddr2=config['devreg'][1]['addr'] + self.SWaddr3=config['devreg'][2]['addr'] + self.channel1=0 + self.channel2=0 + self.channel3=0 + logging.info("i2c switch2 at address %i,%i,%i" % (self.SWaddr1,self.SWaddr2,self.SWaddr3)) + + def SetSW1(self,channelbit): + channel=1<<(channelbit) + if (channel)==self.channel1: return True; + logging.debug("SetChannel1=%i" % channelbit) + self.channel1=channel + self.channel2=0 + self.channel3=0 + return self.i2csetget(self.SWaddr1,[channel]) + + def SetSW2(self,channelbit): + channel=1<<(channelbit) + if (channel)==self.channel2: return True; + logging.debug("SetChannel2=%i" % channelbit) + self.channel2=channel + self.channel3=0 + return self.i2csetget(self.SWaddr2,[channel]) + + def SetSW3(self,channelbit): + channel=1<<(channelbit) + if (channel)==self.channel3: return True; + logging.debug("SetChannel3=%i" % channelbit) + self.channel3=channel + return self.i2csetget(self.SWaddr3,[channel]) + diff --git a/rcu/spibitbang1.py b/i2cserv/i2cbitbang1.py similarity index 80% rename from rcu/spibitbang1.py rename to i2cserv/i2cbitbang1.py index ca8fd300bdb46cd1463318a9ea9b727d1c323580..8aacf743f7fe6f395dfdfb6ab6d1fc7238da1bbb 100644 --- a/rcu/spibitbang1.py +++ b/i2cserv/i2cbitbang1.py @@ -1,13 +1,24 @@ 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] @@ -78,30 +89,26 @@ def GetSPIbb(SetI2C,GetI2C,RCUi,dev,value): SetI2C(RCUi,SDIOdirdev,1,SDIOdirpin,[0]) #output return True; -def GetSPIbb2(SetI2C,GetI2C,RCUi,devs,value): - ADC_reg_address=devs[0].Register_R +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 dev in devs: - dev1=dev.Addr.devs[pintype.value] - pin1=dev.Addr.pins[pintype.value] - SetI2C(RCUi,dev1,1,pin1,[value],buffer=True) - SetI2C(RCUi,dev1,1,pin1,[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) - step=len(devs) - dev1=devs[0].Addr.devs[pintype.value] - pin1=devs[0].Addr.pins[pintype.value] - retvalue[0::step]=GetI2C(RCUi,dev1,1,pin1) - for i,dev in enumerate(devs[1:]): - dev1=dev.Addr.devs[pintype.value] - pin1=dev.Addr.pins[pintype.value] - retvalue[i+1::step]=GetI2C(RCUi,dev1,1,pin1,buffer=True) + 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 - CS=SPIBB_pins.CS - SDIO=SPIBB_pins.SDIO - CLK=SPIBB_pins.CLK - SDIOdir=SPIBB_pins.SDIOdir + CLK=0 + SDIO=1 + SDIOdir=2 + CS=3 logging.debug(str(("SPIbb get",ADC_reg_address))) diff --git a/i2cserv/i2cthread.py b/i2cserv/i2cthread.py new file mode 100644 index 0000000000000000000000000000000000000000..d4066a059f7ce397e2b2df10d6c91a4257749fcf --- /dev/null +++ b/i2cserv/i2cthread.py @@ -0,0 +1,147 @@ +#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 RCU +#from i2cserv import CLK + +import yamlconfig as yc + +import yaml +class AttrDict(object): + def __init__(self, dct): + self.dict = dct + + def __repr__(self): + return repr(self.dict) + + def __getattr__(self, attr): + try: + val = self.dict[attr] + if isinstance(val, dict): + val = AttrDict(val) + return val + 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,mask))); + if mask is None: mask=[] + if (key=='WAIT'): + sleep(value[0]/1000.) + continue; + v1=conf.getvarid(key) + if not(v1 is None): + if value[0]=='Update': + #mask= + getvar(conf,Qout,v1,mask) + else: + #mask= + setvar(conf,Qout,v1,value,mask) + continue; + v1=conf.getmethodid(key) + if v1: + #mask= + runmethod(conf,Qout,v1,mask) + continue; + v1=conf.getdevreg(key) + if v1: + drv2=v1.get('drivercls') + 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) +# 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) + return mask + +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): + if len(mask)==len(data.mask): mask[:]=data.mask[:]; + elif len(mask)==0: mask=data.mask.copy(); + Qout.put(data) + return mask; + +def getvar(conf,Qout,varid,mask): + var1=conf.getvars()[varid] + drv=var1.get('drivercls'); + if not(drv): + logging.warn(var1['name']+" driver not found!") + return; + for data in drv.OPCUAReadVariable(varid,var1,mask): + if len(mask)==len(data.mask): mask[:]=data.mask[:]; + elif len(mask)==0: mask=data.mask.copy(); + Qout.put(data) + return mask; + + +def I2Cserver(Qin,Qout,name): + logging.info("New i2c process "+name) + conf=yc.yamlconfig(name) + conf.linkdevices() + conf.loaddrivers() + conf.linkdrivers() + statusid=conf.getvarid(name+"_translator_busy"); + 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) and not(statusid is None): Qout.put(OPCUAset(statusid,InstType.varSet,[0],[])) + 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 new file mode 100644 index 0000000000000000000000000000000000000000..4bbfb01c0c31fc3cc548979dc9bac574c85e5ac6 --- /dev/null +++ b/i2cserv/spibitbang1.py @@ -0,0 +1,159 @@ +from enum import Enum +import logging +import numpy as np +from .hwdev import hwdev + +class SPIBB_pins(Enum): + CLK = 0 + SDIO = 1 + SDIOdir = 2 + CS = 3 + +class spibitbang1(hwdev): + def __init__(self,config): + hwdev.__init__(self,config) +# logging.info("spibitbang todo") + + def i2csetget(self,addr,data,reg=None,read=0): + if read==0: return self.SetSPIbb(reg,data) + elif read==1: return self.GetSPIbb(reg,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.debug(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) + if not(SetI2C(CSdev,1,CSpin,[0])): return False #enable + for bit in bit_array: + SetI2C(SDOdev,1,SDOpin,[int(bit)]) + SetI2C(CLKdev,1,CLKpin,[1]) + SetI2C(CLKdev,1,CLKpin,[0]) + SetI2C(CSdev,1,CSpin,[1]) #disable + SetI2C(SDOdev,1,SDOpin,[1]) #high when finished + return True; + + 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] +# print("SPI registers") +# print("CS",CSdev,CSpin) +# print("SDO",SDOdev,SDOpin) +# print("CLK",CLKdev,CLKpin) +# print("DIR",SDIOdirdev,SDIOdirpin) + 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 + + SetI2C=self.conf['parentcls'].SetVarValue + GetI2C=self.conf['parentcls'].GetVarValue + if not(SetI2C(CSdev,1,CSpin,[0])): return False #enable + + + bit_array = "{0:{fill}16b}".format(data, fill='0') + #print("SPI TX bits",bit_array) + for bit in bit_array: + SetI2C(SDOdev,1,SDOpin,[int(bit)]) + SetI2C(CLKdev,1,CLKpin,[1]) + SetI2C(CLKdev,1,CLKpin,[0]) + + SetI2C(CSdev,1,CSpin,[1]) #disable + + # print("read byte") + SetI2C(SDIOdirdev,1,SDIOdirpin,[1]) #input + SetI2C(CSdev,1,CSpin,[0]) #enable + a=[0] + N=1;#len(value) + ret_value=[0]; + for i in range(N): value[i]=0 + for cnt in range(8*(ADC_bytes+1)): + GetI2C(SDOdev,1,SDOpin,ret_value) #enable +# logging.debug("Got bit"+str((ret_value))) + for i in range(N): value[i]=(value[i]<<1)+ ret_value[i] + SetI2C(CLKdev,1,CLKpin,[1]) + SetI2C(CLKdev,1,CLKpin,[0]) #read after falling edge + SetI2C(CSdev,1,CSpin,[1]) #disable + SetI2C(SDIOdirdev,1,SDIOdirpin,[0]) #output +# logging.debug(str(("SPIbb got",value))) + return True; + +def GetSPIbb2(SetI2C,GetI2C,RCUi,SPIdev,I2Cdev,I2Cpins,value): +#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/spibitbang2.py b/i2cserv/spibitbang2.py new file mode 100644 index 0000000000000000000000000000000000000000..0dedef82fcb86ed04e8e82420143ab22411878e3 --- /dev/null +++ b/i2cserv/spibitbang2.py @@ -0,0 +1,95 @@ +from enum import Enum +import logging +import numpy as np +from .hwdev import hwdev + +class SPIBB_pins(Enum): + CLK = 0 + SDI = 1 + SDO = 2 + CS = 3 + + +class spibitbang2(hwdev): + def __init__(self,config): + hwdev.__init__(self,config) + + def i2csetget(self,addr,data,reg=None,read=0): + if read==0: return self.SetSPIbb(reg,data) + elif read==1: return self.GetSPIbb(reg,data) + else: logging.warn("Not implemented!") + return False; + + def SetSPIbb(self,address,value): + + CSdev=self.conf['devreg'][SPIBB_pins.CS.value] + CSpin=self.conf['parameters'][SPIBB_pins.CS.value] + SDIdev=self.conf['devreg'][SPIBB_pins.SDI.value] + SDIpin=self.conf['parameters'][SPIBB_pins.SDI.value] + CLKdev=self.conf['devreg'][SPIBB_pins.CLK.value] + CLKpin=self.conf['parameters'][SPIBB_pins.CLK.value] + + logging.info(str(("SPIbb2 set",address,value))) + + data2 = ( address << 9 ) + value[0] + SetI2C=self.conf['parentcls'].SetVarValue + + bit_array = "{0:{fill}16b}".format(data2, fill='0') + # print(bit_array) + SetI2C(CSdev,1,CSpin,[1]) #disable + SetI2C(CSdev,1,CSpin,[0]) #enable + for bit in bit_array: + SetI2C(CLKdev,1,CLKpin,[0]) + SetI2C(SDIdev,1,SDIpin,[int(bit)]) + SetI2C(CLKdev,1,CLKpin,[1]) + SetI2C(CLKdev,1,CLKpin,[0])#Why? + SetI2C(CLKdev,1,CLKpin,[1]) + SetI2C(CSdev,1,CSpin,[1]) #disable + # SetI2C(RCUi,SDIdev,1,SDIpin,[1]) #high when finished + return True; + + def GetSPIbb(self,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.SDO.value] + SDOpin=self.conf['parameters'][SPIBB_pins.SDO.value] + SDIdev=self.conf['devreg'][SPIBB_pins.SDI.value] + SDIpin=self.conf['parameters'][SPIBB_pins.SDI.value] + CLKdev=self.conf['devreg'][SPIBB_pins.CLK.value] + CLKpin=self.conf['parameters'][SPIBB_pins.CLK.value] + + + logging.info(str(("SPIbb2 get",reg_address))) + SetI2C=self.conf['parentcls'].SetVarValue + GetI2C=self.conf['parentcls'].GetVarValue + + ADC_bytes = 0x00 + # ADC_rw = 0x01 # 0 for write, 1 for read + data = (reg_address << 1) + 1 #was 7?? + + SetI2C(CSdev,1,CSpin,[1]) #disable + SetI2C(CSdev,1,CSpin,[0]) #enable + + + bit_array = "{0:{fill}8b}".format(data, fill='0') + for bit in bit_array: + SetI2C(SDIdev,1,SDIpin,[int(bit)]) + SetI2C(CLKdev,1,CLKpin,[0]) + SetI2C(CLKdev,1,CLKpin,[1]) + + + # print("read byte") + a=[0] + N=1 #len(value) + ret_value=[0] + for i in range(N): value[i]=0 + for cnt in range(8*(ADC_bytes+1)): + SetI2C(CLKdev,1,CLKpin,[0]) + SetI2C(CLKdev,1,CLKpin,[1]) #read after rising + GetI2C(SDOdev,1,SDOpin,ret_value) + for i in range(N): value[i]=(value[i]<<1)+ ret_value[i] + SetI2C(CLKdev,1,CLKpin,[0]) + SetI2C(CSdev,1,CSpin,[1]) #disable + return True; + + diff --git a/i2c/__init__.py b/opcuaserv/__init__.py similarity index 100% rename from i2c/__init__.py rename to opcuaserv/__init__.py diff --git a/opcuaserv/i2client.py b/opcuaserv/i2client.py new file mode 100644 index 0000000000000000000000000000000000000000..b00d227a52297b16e43c29ff4962a926804b1427 --- /dev/null +++ b/opcuaserv/i2client.py @@ -0,0 +1,46 @@ +#This is the OPC-UA side of the pipes to I2Cserver + +from multiprocessing import Queue +from queuetypes import * + + +class i2client(): + def __init__(self,name='RCU'): + self.Qin=Queue() + self.Qout=Queue() + self.name=name; + + def GetInfo(self): + return self.Qin,self.Qout,self.name + + def stop(self): + self.Qout.put(None); + self.Qin.put(None); +# self.thread1.join(); +# os.close(self.Output) +# self.Input.close() + + def readvar(self,id1,mask=[]): + Data=OPCUAset(id1,InstType.varRead,[],mask) + self.Qout.put(Data); + + def setvar(self,id1,data=[],mask=[]): + Data=OPCUAset(id1,InstType.varSet,data,mask) + self.Qout.put(Data); + + def QoutLength(self): + return self.Qout.qsize() + + def callmethod(self,id1,mask=[]): + Data=OPCUAset(id1,InstType.method,[],mask) + self.Qout.put(Data); + + def data_waiting(self): + return (self.Qin.qsize()>0); + + def readdata(self): + message=self.Qin.get() + if message is None: return None + return message.id,message.data,message.mask + + diff --git a/opcuaserv.py b/opcuaserv/opcuaserv.py similarity index 72% rename from opcuaserv.py rename to opcuaserv/opcuaserv.py index f38b8acb5a4ced13f3e49bb6d45c1897de1de520..63763e875fbcf4c302c1a22dc2f9610d55b990cc 100644 --- a/opcuaserv.py +++ b/opcuaserv/opcuaserv.py @@ -8,7 +8,7 @@ from datetime import datetime; import logging #import Vars #import HWconf -from pcctypes import * +#from pcctypes import * Vars_R={} Vars_W={} @@ -21,14 +21,15 @@ class SubHandler(object): def datachange_notification(self, node, val, data): # print("Python: New data change event", node, val,data) if not(running): return - vname,myvar,VarD,Q1=Vars_W[node.nodeid.Identifier] + vname,myvar,v,reader=Vars_W[node.nodeid.Identifier] # val=(val if isinstance(val, list) else [val] ) logging.info(str(("Datachange callback",vname,val))) # myvar2.Value.Value=val # myvar2.SourceTimestamp = datetime.utcnow() + reader.setvar(v,val) - Inst=Instr(DevType.Var,VarD,len(val),val) - Q1.put(Inst) +# Inst=Instr(DevType.Var,VarD,len(val),val) +# Q1.put(Inst) # P1.SetVarValue(vname,val) #readback # if True: @@ -46,7 +47,7 @@ class SubHandler(object): def CallMethod(ObjectID,name,Inst1,Q1): logging.info(str(("Callmethod",ObjectID,name))) # Inst1=Vars.Instr(Vars.DevType.Instr,instrs,0,[]) - Q1.put(Inst1) + Q1.callMethod(Inst1) # P1.CallMethod(name,None) @@ -55,29 +56,32 @@ def AddVar(name,value): myvar2.set_writable() return myvar2 -def AddVarR(vname,varvalue2,v): - myvar = PCCobj.add_variable(idx, vname, varvalue2) - logging.info(str(("Variable added: ",vname,len(varvalue2)))) - Vars_R[myvar.nodeid.Identifier]=[v.name,myvar.get_data_value(),varvalue2,v] +def AddVarR(vname,varvalue2,v,debug): + obj=(DEBUGobj if debug else PCCobj) + myvar = obj.add_variable(idx, vname, varvalue2) + logging.info(str(("Variable added: ",vname,(len(varvalue2) if isinstance(varvalue2,list) else '')))) + Vars_R[myvar.nodeid.Identifier]=[vname,myvar.get_data_value(),varvalue2,v] return myvar -def AddVarW(vname,varvalue2,v,Q1): +def AddVarW(vname,varvalue2,v,Q1,debug): logging.info(str(("Variable added: ",vname)))#,'=',varvalue2) - myvar2 = PCCobj.add_variable(idx, vname, varvalue2) + obj=(DEBUGobj if debug else PCCobj) + myvar2 = obj.add_variable(idx, vname, varvalue2) myvar2.set_writable() - Vars_W[myvar2.nodeid.Identifier]=[v.name,myvar2.get_data_value(),v,Q1] - handle = sub.subscribe_data_change(myvar2) + if v: + Vars_W[myvar2.nodeid.Identifier]=[vname,myvar2.get_data_value(),v,Q1] + handle = sub.subscribe_data_change(myvar2) return myvar2 - -def Addmethod(vname,v,Q1): - myvar = PCCobj.add_method(idx, vname, lambda ObjectId,name=vname,inst=v,Q1=Q1 : CallMethod(ObjectId,name,inst,Q1), [],[] ) +def Addmethod(vname,v,Q1,debug): + obj=(DEBUGobj if debug else PCCobj) + myvar = obj.add_method(idx, vname, lambda ObjectId,name=vname,inst=v,Q1=Q1 : CallMethod(ObjectId,name,inst,Q1), [],[] ) logging.info(str(("AddMethod:",vname))) def InitServer(port=4840): # setup our server - global server,running,PCCobj,idx,sub; + global server,running,PCCobj,DEBUGobj,idx,sub; server = Server() server.set_endpoint("opc.tcp://0.0.0.0:{}/PCC/".format(port)) @@ -89,6 +93,7 @@ def InitServer(port=4840): # populating our address space PCCobj = objects.add_object(idx, "PCC") + DEBUGobj = PCCobj.add_object(idx, "DEBUG") # self.PCCobj=PCCobj # starting! diff --git a/opcuaserv/yamlreader.py b/opcuaserv/yamlreader.py new file mode 100644 index 0000000000000000000000000000000000000000..e0c3873729830e1d99f4322c022398b43a012c06 --- /dev/null +++ b/opcuaserv/yamlreader.py @@ -0,0 +1,225 @@ +import yaml +import struct +import time +from yamlconfig import * +import logging +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; + + +class yamlreader(yamlconfig): + def __init__(self,i2cserver,yamlfile='RCU'): + self.yamlfile=yamlfile; + yamlconfig.__init__(self,yamlfile) + self.server=i2cserver; + self.timecount=0; + self.monitorvarcnt=0; + self.statusid=self.getvarid(yamlfile+"_translator_busy"); + + def SetBusy(self): + if self.statusid is None: return + self.OPCset(self.statusid,[1],[]) + + def AddVars(self,AddVarR,AddVarW): + self.monitorvar=AddVarW(self.yamlfile+"_monitor_rate_RW",60,None,None,None) + for v in self.conf['variables']: +# print(v) + dim1=v.get('dim',1); + name=v.get('name'); + datatype=v.get('dtype','integer') +# 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 datatype in ['uint8','uint16','uint32','uint64']: varvalue2=dim1*[0] + elif datatype=='double': varvalue2=dim1*[0.0] + elif datatype=='boolean': varvalue2=dim1*[False] + elif datatype=='string': varvalue2=dim1*[""] + if len(varvalue2)==1: varvalue2=varvalue2[0]; +# print(len(varvalue2),varvalue2) + if v.get('rw') in ['ro','rw']: + var1=AddVarR(name+"_R",varvalue2,v['id'],v.get('debug')) + v['OPCR']=var1 + logging.debug("Var added:"+name+"_R") +# self.server.readvar(v['id']) +# time.sleep(0.1); +# Inst=Vars.Instr(Vars.DevType.VarUpdate,v,dim2,varvalue2) +# Q1.put(Inst) + + if v.get('rw') in ['wo','rw','variable']: + var1=AddVarW(name+"_RW",varvalue2,v['id'],self,v.get('debug')) + v['OPCW']=var1 + logging.debug("Var added:"+name+"_RW") + for v in self.conf['variables']: + mask=v.get('mask'); + if not(mask): continue; + mask=Find(self.conf['variables'],'name',mask) + if not(mask): continue; + mask=mask.get('OPCW',None) + if (mask==None): continue; + v['maskOPC']=mask + + def AddMethod(self,Addmethod): + for v in self.conf['methods']: + if v.get('hidden'): continue; +# print(v) +# Inst1=Vars.Instr(Vars.DevType.Instr,v,0,[]) + Addmethod(v['name'],v['id'],self,v.get('debug')) + mask=v.get('mask'); + if not(mask): continue; + mask=Find(self.conf['variables'],'name',mask) + if not(mask): continue; + mask=mask.get('OPCW',None) + if (mask==None): continue; + v['maskOPC']=mask + + def callMethod(self,id1): + v=self.conf['methods'][id1]; + logging.debug("Method called!"+v['name']) + mask=v.get('maskOPC',None); + mask=mask.get_value() if (mask!=None) else []; + self.SetBusy() + self.server.callmethod(id1,mask) + + def CallInit(self): + v=Find(self.conf['methods'],'name',self.yamlfile+'_Init'); + if not(v): + logging.warn(self.yamlfile+"_Init method not found for initialisation!") + return; + self.server.callmethod(v['id'],[]) + + def setvar(self,id1,data=[]): + v=self.conf['variables'][id1]; + if v['rw']=='variable': return; + mask=v.get('maskOPC',None); + mask=mask.get_value() if (mask!=None) else []; +# print("M2:",mask) + dtype=v.get('dtype','integer'); + width=(v.get('width',8)-1)//8+1 + if not(isinstance(data,list)): data=[data]; + if (dtype=="double"): + scale=v.get('scale',1.) + data=[int(d/scale) for d in data] + if (dtype=="boolean"): + data2=bytearray(data*1); + elif (dtype in ['uint8','uint16','uint32','uint64','double']): + if width<=1: + data2=bytearray(data) + elif width==2: + data2 = struct.pack('>%sH' % len(data), *data) + elif width==3: + data2=bytearray() + for a in data: data2.extend(struct.pack('>L',a)[1:]) + elif width==4: + data2 = struct.pack('>%sL' % len(data), *data) + elif width==8: + data2 = struct.pack('>%sQ' % len(data), *data) + else: + 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: + logging.warn("setvar unsupported type"); + return; + data2=[d for d in data2] + logging.debug(str(("setvar ",v['name'],data2,mask))); + self.SetBusy() + self.server.setvar(id1,data2,mask) + + def getvar(self): +# if not(self.server.data_waiting()): return; +# print("getvar ...") + while True: +# while (self.server.data_waiting()): +# try: + item=self.server.readdata() + if item is None: break; + id1,data,mask=item; + logging.debug(str(("**getvar",id1,data,mask))); + if len(data)==0: continue; +# except: +# print('finished') +# return; + self.OPCset(id1,data,mask); + + def OPCset(self,id1,data,mask): + v=self.conf['variables'][id1]; + dtype=v.get('dtype','integer'); + width=(v.get('width',8)-1)//8+1 + logging.debug(str(("OPCset",width,data))) + if dtype=="boolean": + data2=[d==1 for d in data]; + elif (dtype in ['uint8','uint16','uint32','uint64','double']): + data=bytearray(data) + if width<=1: + data2=[d for d in data] + elif width==2: + data2 = struct.unpack('>%sH' % (len(data)//2), data) + elif width==3: + data2 = [struct.unpack('>L' ,bytearray([0])+data[x*3:x*3+3])[0] for x in range(len(data)//3)] + elif width==4: + data2 = struct.unpack('>%sL' % (len(data)//4), data) + elif width==8: + data2 = struct.unpack('>%sQ' % (len(data)//8), data) + else: + 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: + logging.warn("OPCset unsupported type"); + return; + if dtype=="double": + scale=float(v.get('scale',1.)) + data2=[(d*scale) for d in data2] + var1=v.get('OPCR') + if not(var1): var1=v.get('OPCW') + if not(var1): + logging.warn("OPC variable not found!!"); + return; + data3=var1.get_value(); + if not(isinstance(data3,list)): data3=[data3]; +# print("OPCset",v['name'],data3,mask) + if mask: #Only update masked values + step=len(data2)//len(mask) + #print("mask step=",step) + for i in range(len(data2)): + if mask[i//step]: data3[i]=data2[i] + else: + data3=data2; + if len(data3)==1: data3=data3[0]; + logging.info(str(("OPCset",v['name'],data3))) + var1.set_value(data3); + + def Monitor(self): + T1=self.monitorvar.get_value()*10; + if T1<=0: return; + self.timecount+=1; + while self.timecount>=T1: + if self.server.QoutLength()>3: return; + v=self.conf['variables'][self.monitorvarcnt]; + if v.get('monitor'): + mask=(v['maskOPC'].get_value() if v.get('maskOPC') else []) +# print("monitor",v['name'],mask) + self.server.readvar(self.monitorvarcnt,mask=mask) + self.monitorvarcnt+=1; + if self.monitorvarcnt>=len(self.conf['variables']): + self.monitorvarcnt=0; + self.timecount=0; + diff --git a/pcctypes.py b/pcctypes.py deleted file mode 100644 index 56c4bc7da636ed670e6d4bfcfc69adda86a663d8..0000000000000000000000000000000000000000 --- a/pcctypes.py +++ /dev/null @@ -1,81 +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 b7b716828ce4778cc51c23b4322e85ea8bc4a9d4..0fb7bef0ac7814141f692a3933ef244c2c2ca388 100644 --- a/pypcc2.py +++ b/pypcc2.py @@ -1,25 +1,21 @@ -import opcuaserv -try: - import queue -except ImportError: - import Queue as queue; -from rcu import RCU -from clk import CLK -from i2c import I2Cswitch1 -import threading -import signal -import sys -import time -#import Vars import logging import argparse - -NRCU=32 +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 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') args = parser.parse_args() # set log level @@ -29,106 +25,66 @@ if not isinstance(loglevel_nr, int): #logging.basicConfig(level=loglevel_nr, format="%(asctime)s [%(levelname)8s] %(message)s") logging.basicConfig(level=loglevel_nr,format='%(asctime)s [%(levelname)-8s,%(filename)-20s:%(lineno)-3d] %(message)s') -if args.simulator: - from i2c import I2C_dummy as I2C -else: - from i2c import I2C -# from i2c import I2Cv2 as I2C - -#Queue used to pass instructions from opc-ua server to RCU -Q1=queue.Queue() #RCUs -Q2=queue.Queue() #CLK - -#Setup OPCUA server (running in its own thread) -opcuaserv.InitServer(port=args.port) -logging.info("OPC-UA Server started") - -SW1=I2Cswitch1.I2Cswitch1(I2C.I2C1server) -SW0=I2Cswitch1.I2Cswitch0(None) #Dummy switch as their is no switch on LTS - -RCU=RCU.RCU1(NRCU,I2C.I2C1server,SW1.SetChannel) -RCU.AddVars(Q1,opcuaserv.AddVarR,opcuaserv.AddVarW,opcuaserv.AddVar) -RCU.AddMethod(Q1,opcuaserv.Addmethod) -RCU.load() #Load current register values from HW - -CLK=CLK.RCU1(1,I2C.I2C4server,SW0.SetChannel) -CLK.AddVars(Q2,opcuaserv.AddVarR,opcuaserv.AddVarW) -CLK.AddMethod(Q2,opcuaserv.Addmethod) -CLK.load() #Load current register values from HW - -#logging.debug(str(("I2C bytes=",I2C.I2Ccounter))) - -if False: - opcuaserv.server.stop() - exit() - -RCUthread1=RCU.start(Q1) -CLKthread1=CLK.start(Q2) - RunTimer=True; - -def TimerThread(Q1,RCU): - V1=opcuaserv.AddVar("RCU_monitor_rate_RW",30) - cnt=0;#Count second ticks - while RunTimer: - time.sleep(1) - T1=V1.get_data_value().Value.Value - if T1==0: - continue; - cnt+=1; - if cnt>=T1: - if Q1.qsize()>3: continue; - cnt=0; - logging.debug(str(("I2C bytes=",I2C.I2Ccounter," Qlength=",Q1.qsize()))) - RCU.Queue_Monitor(Q1,NRCU) - - logging.info("End Timer thread") - -Timerthread1 = threading.Thread(target=TimerThread, args=(Q1,RCU)) -Timerthread1.start() - - -def Timer2Thread(Q1,RCU): - V1=opcuaserv.AddVar("CLK_monitor_rate_RW",10) - cnt=0;#Count second ticks - while RunTimer: - time.sleep(1) - T1=V1.get_data_value().Value.Value - if T1==0: - continue; - cnt+=1; - if cnt>=T1: - if Q1.qsize()>3: continue; - cnt=0; - logging.debug(str(("I2C bytes=",I2C.I2Ccounter," Qlength=",Q1.qsize()))) - RCU.Queue_Monitor(Q1,1) - - logging.info("End Timer thread") - -Timerthread2 = threading.Thread(target=Timer2Thread, args=(Q2,CLK)) -Timerthread2.start() - -# on SIGINT: stop thread(s) by adding None to instruction queue(s) def signal_handler(sig, frame): - logging.info('Stop RCU thread') - Q1.put(None) - Q2.put(None) - logging.info('Stop timer thread') + logging.warn('Stop signal received!') global RunTimer; RunTimer=False signal.signal(signal.SIGINT, signal_handler) -time.sleep(1) -opcuaserv.start() +#Start i2c processes as soon as possible to have minimum duplication +logging.info("Start I2C processes") +#I2Cports=['UNB2','RCU','CLK'] +#I2Cports=['RCU'] +I2Cports=[x for x in args.config.split(',')] +threads=[] +I2Cclients=[] +for name in I2Cports: + RCU_I2C=i2client.i2client(name=name) + if not(args.simulator): + thread1=i2cthread.start(*RCU_I2C.GetInfo()) + threads.append(thread1) + I2Cclients.append(RCU_I2C) + +#Initialise OPCUA server and load variables +logging.info("Initialised OPC-UA Server") +configs=[] +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) + RCU_conf.CallInit(); + configs.append(RCU_conf); + + 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() +logging.getLogger().setLevel("WARNING") + +if False: + opcuaserv.server.stop() + exit() + try: -#Do nothing. while RunTimer: - time.sleep(1) + time.sleep(0.1); + for c in configs: + c.Monitor(); finally: - logging.info("Stop OPC-UA server") - opcuaserv.server.stop() - RCUthread1.join() - CLKthread1.join() - Timerthread1.join() - Timerthread2.join() + if not(args.test): + logging.info("Stop OPC-UA server") + opcuaserv.server.stop() + +logging.info("Stop threads") +for i2c in I2Cclients: + i2c.stop() +for thread1 in threads: + thread1.join() diff --git a/queuetypes.py b/queuetypes.py new file mode 100644 index 0000000000000000000000000000000000000000..f10f7b1a4b52e651b5c7af3be933c592a53cb096 --- /dev/null +++ b/queuetypes.py @@ -0,0 +1,9 @@ +from enum import Enum +from recordclass import recordclass + +class InstType (Enum): + varSet = 0 + varRead = 1 + method = 2 + +OPCUAset=recordclass("OPCUAset","id type data mask") diff --git a/rcu/HWconf.py b/rcu/HWconf.py deleted file mode 100644 index 44b75df15fe7bc8caef46d1986a452fe154e5703..0000000000000000000000000000000000000000 --- a/rcu/HWconf.py +++ /dev/null @@ -1,108 +0,0 @@ -#from collections import namedtuple -#from enum import Enum -from pcctypes import * -#Mid plane address -#MPaddr=namedtuple("MPaddr","nI2C I2C nSwitch Switch"); -RCU_MPaddr=MPaddr(1,[1],32,[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]) -#RCU_MPaddr=MPaddr(1,[1],2,[0,1]) -#RCU_MPaddr=MPaddr(1,[1],1,[0]) -#CLK_MPaddr=MPaddr(1,[1],1,[7]) - -#DevReg=namedtuple("DevReg","Addr Register_R Register_W store"); -#I2C:Addr=I2C addr (int) -#BBdev: Addr=BBdev (pointer) - -#Control board switch -#dev: TCA9548 -SW1_ch=DevReg(0x70,0,0,0) -#I2C IO-Expanders -#Device: TCA9539 -RCU_IO1_OUT1=DevReg(0x75,0,2,1) -RCU_IO1_OUT2=DevReg(0x75,1,3,2) -RCU_IO1_CONF1=DevReg(0x75,6,6,3) -RCU_IO1_CONF2=DevReg(0x75,7,7,4) -#Device: TCA9539 -RCU_IO2_OUT1=DevReg(0x76,0,2,5) -RCU_IO2_OUT2=DevReg(0x76,1,3,6) -RCU_IO2_CONF1=DevReg(0x76,6,6,7) -RCU_IO2_CONF2=DevReg(0x76,7,7,8) -#Device: TCA6416 -RCU_IO3_OUT1=DevReg(0x20,0,2,9) -RCU_IO3_OUT2=DevReg(0x20,1,3,10) -RCU_IO3_CONF1=DevReg(0x20,6,6,11) -RCU_IO3_CONF2=DevReg(0x20,7,7,12) - -RCU_storeReg=13; #Number of stored registers - -#I2C monitor ADC -RCU_AN_Ch0=DevReg(0x14,0xB080,-1,0) -RCU_AN_Ch1=DevReg(0x14,0xB880,-1,0) -RCU_AN_Ch2=DevReg(0x14,0xB180,-1,0) -#etc -RCU_AN_Temp=DevReg(0x14,0xA0C0,-1,0) - -#HBA1 -RCU_HBA1=DevReg(0x41,0x10,0x10,1) -RCU_HBA2=DevReg(0x42,0x10,0x10,2) -RCU_HBA3=DevReg(0x43,0x10,0x10,3) - - - -RCU_ROM_ID =DevReg(0x50,0xfc,0xfc,0) #32 bit ID=4 bytes -RCU_ROM_Ver=DevReg(0x50,0,0,0) #String - -#Bitbang devices -#BBdev=namedtuple("BBdev","nPins devs pins addr") -I2CBB_dth3=BBdev(3,[RCU_IO1_OUT1,RCU_IO2_OUT2,RCU_IO2_CONF2],[6,3,3],0x70); #SCL,SDIO,SDIOdir -I2CBB_dth2=BBdev(3,[RCU_IO1_OUT2,RCU_IO2_OUT1,RCU_IO1_CONF1],[7,7,7],0x70); -I2CBB_dth1=BBdev(3,[RCU_IO1_OUT2,RCU_IO2_OUT1,RCU_IO1_CONF1],[7,7,7],0x70); -SPIBB_ADC1=BBdev(4,[RCU_IO3_OUT1,RCU_IO3_OUT1,RCU_IO3_CONF1,RCU_IO3_OUT2],[1,0,0,0],0) #CLK,SDIO,SDIOdir,CS -SPIBB_ADC2=BBdev(4,[RCU_IO3_OUT1,RCU_IO3_OUT1,RCU_IO3_CONF1,RCU_IO3_OUT2],[3,2,2,1],0) #CLK,SDIO,SDIOdir,CS -SPIBB_ADC3=BBdev(4,[RCU_IO3_OUT1,RCU_IO3_OUT1,RCU_IO3_CONF1,RCU_IO3_OUT2],[5,4,4,2],0) #CLK,SDIO,SDIOdir,CS - -#SPI ADC -#Dev: AD9683 -RCU_ADC1_PLL_stat =DevReg(SPIBB_ADC1,0X0A,0X0A,0) # PLL locked status -RCU_ADC1_PLL_enc =DevReg(SPIBB_ADC1,0X21,0X21,0) # PLL low encode -RCU_ADC1_JESD_ctr =DevReg(SPIBB_ADC1,0X5F,0X5F,0) #JESD link control, ILAS mode -RCU_ADC1_CML_level=DevReg(SPIBB_ADC1,0X15,0X15,0) #CML output adjust -RCU_ADC1_SYNC_ctr =DevReg(SPIBB_ADC1,0X3A,0X3A,0) #SYNC / SYSREF control -RCU_ADC1_update =DevReg(SPIBB_ADC1,0XFF,0xFF,0) # Global device update - -RCU_ADC2_PLL_stat =DevReg(SPIBB_ADC2,0X0A,0X0A,0) # PLL locked status -RCU_ADC2_PLL_enc =DevReg(SPIBB_ADC2,0X21,0X21,0) # PLL low encode -RCU_ADC2_JESD_ctr =DevReg(SPIBB_ADC2,0X5F,0X5F,0) #JESD link control, ILAS mode -RCU_ADC2_CML_level=DevReg(SPIBB_ADC2,0X15,0X15,0) #CML output adjust -RCU_ADC2_SYNC_ctr =DevReg(SPIBB_ADC2,0X3A,0X3A,0) #SYNC / SYSREF control -RCU_ADC2_update =DevReg(SPIBB_ADC2,0XFF,0xFF,0) # Global device update - -RCU_ADC3_PLL_stat =DevReg(SPIBB_ADC3,0X0A,0X0A,0) # PLL locked status -RCU_ADC3_PLL_enc =DevReg(SPIBB_ADC3,0X21,0X21,0) # PLL low encode -RCU_ADC3_JESD_ctr =DevReg(SPIBB_ADC3,0X5F,0X5F,0) #JESD link control, ILAS mode -RCU_ADC3_CML_level=DevReg(SPIBB_ADC3,0X15,0X15,0) #CML output adjust -RCU_ADC3_SYNC_ctr =DevReg(SPIBB_ADC3,0X3A,0X3A,0) #SYNC / SYSREF control -RCU_ADC3_update =DevReg(SPIBB_ADC3,0XFF,0xFF,0) # Global device update - -#I2C_dither -#Dev: SI4010 -RCU_Dth1_Freq =DevReg(I2CBB_dth1,0x1140,0x1141,0) ##TBC -RCU_Dth1_Prop =DevReg(I2CBB_dth1,0x11 ,0x11,0) -RCU_Dth1_Start=DevReg(I2CBB_dth1,0x62 ,0x62,0) -RCU_Dth1_Stop =DevReg(I2CBB_dth1,0x67 ,0x67,0) -RCU_Dth2_Freq =DevReg(I2CBB_dth2,0x1140,0x1141,0) ##TBC -RCU_Dth2_Prop =DevReg(I2CBB_dth2,0x11 ,0x11,0) -RCU_Dth2_Start=DevReg(I2CBB_dth2,0x62 ,0x62,0) -RCU_Dth2_Stop =DevReg(I2CBB_dth2,0x67 ,0x67,0) -RCU_Dth3_Freq =DevReg(I2CBB_dth3,0x1140,0x1141,0) ##TBC -RCU_Dth3_Prop =DevReg(I2CBB_dth3,0x11 ,0x11,0) -RCU_Dth3_Start=DevReg(I2CBB_dth3,0x62 ,0x62,0) -RCU_Dth3_Stop =DevReg(I2CBB_dth3,0x67 ,0x67,0) - -#class DevType(Enum): -# Var = 0 -# I2C = 1 -# SPIbb= 2 -# I2Cbb= 3 -# Instr =4 -# VarUpdate = 5 -# Internal = 6 diff --git a/rcu/RCU.py b/rcu/RCU.py deleted file mode 100644 index 886790cf945f9dd559b906472e3aaaec535d5d70..0000000000000000000000000000000000000000 --- a/rcu/RCU.py +++ /dev/null @@ -1,424 +0,0 @@ -from . import Vars -import numpy as np -import logging -from .spibitbang1 import * -import threading -import time - - -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 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() - 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 -# 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() - 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 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: - logging.error("SPIbb Implemented") - 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] -# self.SWcallback(mask) -# self.SetI2CAddr(self,DevReg) - for RCUi in range(self.N): - self.SWcallback(1<<Vars.RCU_MPaddr.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) - 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; - 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 start(self,Q1): - def RCUthread(Q1): - while True: - item = Q1.get() - if item is None: break; - self.statevar.set_value("busy"); - self.SetVar(item) - if Q1.qsize()==0: self.statevar.set_value("ready"); - 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,AddVar): - self.statevar=AddVar("RCU_state_R","busy") - 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/rcu/Vars.py b/rcu/Vars.py deleted file mode 100644 index 7467d6bafa94a9ba86698e6e6f566a09d7dee1bd..0000000000000000000000000000000000000000 --- a/rcu/Vars.py +++ /dev/null @@ -1,200 +0,0 @@ -#from collections import namedtuple -from recordclass import recordclass -#from enum import Enum -from .HWconf import * - -#OPCUA variables -RCUmod=I2Cmodules.RCU - -#Var2dev=namedtuple("Var2dev","name MPaddr type devreg width bitoffset Scale") -#VarArray=recordclass("VarArray","name nVars Vars RW type OPCR OPCW") #OPCR and OPCW linked at runtime -RCU_att1= Var2dev("RCU_att1" ,RCUmod,DevType.I2C,RCU_IO1_OUT1,5 ,0,1) -RCU_att2= Var2dev("RCU_att2" ,RCUmod,DevType.I2C,RCU_IO1_OUT2,5 ,0,1) -RCU_att3= Var2dev("RCU_att3" ,RCUmod,DevType.I2C,RCU_IO2_OUT1,5 ,0,1) -RCU_band1=Var2dev("RCU_band1",RCUmod,DevType.I2C,RCU_IO2_OUT2,2 ,0,1) -RCU_band2=Var2dev("RCU_band2",RCUmod,DevType.I2C,RCU_IO2_OUT2,2 ,2,1) -RCU_band3=Var2dev("RCU_band3",RCUmod,DevType.I2C,RCU_IO2_OUT2,2 ,4,1) -RCU_led0= Var2dev("RCU_led0" ,RCUmod,DevType.I2C,RCU_IO2_OUT2,2 ,6,1) -RCU_pwrd1=Var2dev("RCU_pwrd1",RCUmod,DevType.I2C,RCU_IO2_OUT1,1 ,6,1) -RCU_temp1=Var2dev("RCU_temp1",RCUmod,DevType.I2C,RCU_AN_Temp ,23,0,4.21e-3) - -dummy=Var2dev("Dummy",RCUmod,DevType.Internal,None,8,0,1) - - -Ant_mask=VarArray("Ant_mask" ,3,[dummy,dummy,dummy] ,RW.WriteOnly,datatype.dbool,3,None,None) -RCU_att =VarArray("RCU_attenuator" ,3,[RCU_att1 ,RCU_att2 ,RCU_att3] ,RW.ReadWrite,datatype.dInt,3,None,None) -RCU_band=VarArray("RCU_band" ,3,[RCU_band1,RCU_band2,RCU_band3],RW.ReadWrite,datatype.dInt,3,None,None) - -RCU_mask=VarArray("RCU_mask" ,1,[dummy] ,RW.WriteOnly,datatype.dbool ,1,None,None) -RCU_temp=VarArray("RCU_temperature",1,[RCU_temp1],RW.ReadOnly ,datatype.dfloat,1,None,None) -RCU_pwrd=VarArray("RCU_Pwr_dig" ,1,[RCU_pwrd1],RW.ReadOnly ,datatype.dInt ,1,None,None) -RCU_LED =VarArray("RCU_LED0" ,1,[RCU_led0] ,RW.ReadWrite,datatype.dInt ,1,None,None) - -RCU_Dth3_freq=Var2dev("RCU_dth1_freq",RCUmod,DevType.I2Cbb,RCU_Dth3_Freq,32,0,1e-6) -RCU_Dth2_freq=Var2dev("RCU_dth1_freq",RCUmod,DevType.I2Cbb,RCU_Dth2_Freq,32,0,1e-6) -RCU_Dth1_freq=Var2dev("RCU_dth1_freq",RCUmod,DevType.I2Cbb,RCU_Dth1_Freq,32,0,1e-6) -RCU_dth_freq=VarArray("RCU_dither_freq",3,[RCU_Dth1_freq,RCU_Dth2_freq,RCU_Dth3_freq],RW.ReadWrite,datatype.dfloat,3,None,None) - -HBA1_Delay=Var2dev("",RCUmod,DevType.HBA1,RCU_HBA1,5,2,1) -HBA2_Delay=Var2dev("",RCUmod,DevType.HBA1,RCU_HBA2,5,2,1) -HBA3_Delay=Var2dev("",RCUmod,DevType.HBA1,RCU_HBA3,5,2,1) -HBA1_led =Var2dev("",RCUmod,DevType.HBA1,RCU_HBA1,1,0,1) -HBA2_led =Var2dev("",RCUmod,DevType.HBA1,RCU_HBA2,1,0,1) -HBA3_led =Var2dev("",RCUmod,DevType.HBA1,RCU_HBA3,1,0,1) -HBA1_pwr =Var2dev("",RCUmod,DevType.HBA1,RCU_HBA1,1,7,1) -HBA2_pwr =Var2dev("",RCUmod,DevType.HBA1,RCU_HBA2,1,7,1) -HBA3_pwr =Var2dev("",RCUmod,DevType.HBA1,RCU_HBA3,1,7,1) -HBA1_pwr2 =Var2dev("",RCUmod,DevType.HBA1,RCU_HBA1,1,1,1) -HBA2_pwr2 =Var2dev("",RCUmod,DevType.HBA1,RCU_HBA2,1,1,1) -HBA3_pwr2 =Var2dev("",RCUmod,DevType.HBA1,RCU_HBA3,1,1,1) -HBA_Delay=VarArray("HBA_element_beamformer_delays",3,[HBA1_Delay,HBA2_Delay,HBA3_Delay],RW.ReadWrite,datatype.dInt,96,None,None) -HBA_led =VarArray("HBA_element_led" ,3,[HBA1_led ,HBA2_led ,HBA3_led ],RW.ReadWrite,datatype.dInt,96,None,None) -HBA_pwr =VarArray("HBA_element_pwr" ,3,[HBA1_pwr ,HBA2_pwr ,HBA3_pwr ],RW.ReadWrite,datatype.dInt,96,None,None) -HBA_pwr2 =VarArray("HBA_element_pwr2" ,3,[HBA1_pwr2 ,HBA2_pwr2 ,HBA3_pwr2 ],RW.ReadWrite,datatype.dInt,96,None,None) - -#RCU_ID0=Var2dev("",RCUmod,DevType.I2C,RCU_ROM,8,0,1) -#RCU_ID=VarArray("RCU_ID",1,[RCU_ID0],RW.ReadOnly,datatype.dInt,4,None,None) - -RCU_ID0=Var2dev("",RCUmod,DevType.I2C,RCU_ROM_ID,32,0,1) -RCU_ID=VarArray("RCU_ID",1,[RCU_ID0],RW.ReadOnly,datatype.dInt,1,None,None) -RCU_Ver0=Var2dev("",RCUmod,DevType.I2C,RCU_ROM_Ver,7,0,1) -RCU_VER=VarArray("RCU_version",1,[RCU_Ver0],RW.ReadOnly,datatype.dstring,10,None,None) - - -RCU_uCV_ID =VarArray("uC_ID" ,1,[Var2dev("",RCUmod,DevType.I2C,DevReg(0x40,0,0,0),8 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) -RCU_uCV_spd0 =VarArray("uC_spd0" ,1,[Var2dev("",RCUmod,DevType.I2C,DevReg(0x40,1,1,0),8 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) -RCU_uCV_debug =VarArray("uC_debug" ,1,[Var2dev("",RCUmod,DevType.I2C,DevReg(0x40,2,2,0),8 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) -RCU_uCV_RXspd1=VarArray("uC_RXspd1",1,[Var2dev("",RCUmod,DevType.I2C,DevReg(0x40,3,3,0),8 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) -RCU_uCV_RXspd2=VarArray("uC_RXspd2",1,[Var2dev("",RCUmod,DevType.I2C,DevReg(0x40,4,4,0),8 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) -RCU_uCV_TXspd1=VarArray("uC_TXspd1",1,[Var2dev("",RCUmod,DevType.I2C,DevReg(0x40,6,6,0),8 ,0,1)],RW.ReadOnly,datatype.dInt,1,None,None) - - -RCU_ADC1_lock=Var2dev("RCU_ADC1_lock",RCUmod,DevType.SPIbb,RCU_ADC1_PLL_stat,8,0,1) -RCU_ADC2_lock=Var2dev("RCU_ADC2_lock",RCUmod,DevType.SPIbb,RCU_ADC2_PLL_stat,8,0,1) -RCU_ADC3_lock=Var2dev("RCU_ADC3_lock",RCUmod,DevType.SPIbb,RCU_ADC3_PLL_stat,8,0,1) -RCU_ADC_lock=VarArray("RCU_ADC_lock",3,[RCU_ADC1_lock,RCU_ADC2_lock,RCU_ADC3_lock],RW.ReadOnly,datatype.dInt,3,None,None) - -RCU_ADC1_SYNC=Var2dev("RCU_ADC1_SYNC",RCUmod,DevType.SPIbb,RCU_ADC1_SYNC_ctr,8,0,1) -RCU_ADC2_SYNC=Var2dev("RCU_ADC2_SYNC",RCUmod,DevType.SPIbb,RCU_ADC2_SYNC_ctr,8,0,1) -RCU_ADC3_SYNC=Var2dev("RCU_ADC3_SYNC",RCUmod,DevType.SPIbb,RCU_ADC3_SYNC_ctr,8,0,1) -RCU_ADC_SYNC=VarArray("RCU_ADC_SYNC",3,[RCU_ADC1_SYNC,RCU_ADC2_SYNC,RCU_ADC3_SYNC],RW.ReadOnly,datatype.dInt,3,None,None) - -RCU_ADC1_JESD=Var2dev("RCU_ADC1_SYNC",RCUmod,DevType.SPIbb,RCU_ADC1_JESD_ctr,8,0,1) -RCU_ADC2_JESD=Var2dev("RCU_ADC2_SYNC",RCUmod,DevType.SPIbb,RCU_ADC2_JESD_ctr,8,0,1) -RCU_ADC3_JESD=Var2dev("RCU_ADC3_SYNC",RCUmod,DevType.SPIbb,RCU_ADC3_JESD_ctr,8,0,1) -RCU_ADC_JESD=VarArray("RCU_ADC_JESD",3,[RCU_ADC1_JESD,RCU_ADC2_JESD,RCU_ADC3_JESD],RW.ReadOnly,datatype.dInt,3,None,None) - -RCU_ADC1_CML=Var2dev("RCU_ADC1_SYNC",RCUmod,DevType.SPIbb,RCU_ADC1_CML_level,8,0,1) -RCU_ADC2_CML=Var2dev("RCU_ADC2_SYNC",RCUmod,DevType.SPIbb,RCU_ADC2_CML_level,8,0,1) -RCU_ADC3_CML=Var2dev("RCU_ADC3_SYNC",RCUmod,DevType.SPIbb,RCU_ADC3_CML_level,8,0,1) -RCU_ADC_CML=VarArray("RCU_ADC_CML",3,[RCU_ADC1_CML,RCU_ADC2_CML,RCU_ADC3_CML],RW.ReadOnly,datatype.dInt,3,None,None) - - -RCU_IO1_1= Var2dev("" ,RCUmod,DevType.I2C,RCU_IO1_OUT1,8,0,1) -RCU_IO1_2= Var2dev("" ,RCUmod,DevType.I2C,RCU_IO1_OUT2,8,0,1) -#RCU_IO1_3= Var2dev("" ,RCUmod,DevType.I2C,RCU_IO1_CONF1,8,0,1) -#RCU_IO1_4= Var2dev("" ,RCUmod,DevType.I2C,RCU_IO1_CONF2,8,0,1) -#RCU_IO1=VarArray("RCU_IO1",3,[RCU_IO1_1,RCU_IO1_2,RCU_IO1_3],RW.ReadOnly,datatype.dInt,None,None) -RCU_IO2_1= Var2dev("" ,RCUmod,DevType.I2C,RCU_IO2_OUT1,8,0,1) -RCU_IO2_2= Var2dev("" ,RCUmod,DevType.I2C,RCU_IO2_OUT2,8,0,1) -#RCU_IO2_3= Var2dev("" ,RCUmod,DevType.I2C,RCU_IO2_CONF1,8,0,1) -#RCU_IO2_4= Var2dev("" ,RCUmod,DevType.I2C,RCU_IO2_CONF2,8,0,1) -#RCU_IO2=VarArray("RCU_IO2",3,[RCU_IO2_1,RCU_IO2_2,RCU_IO2_3],RW.ReadOnly,datatype.dInt,None,None) -RCU_IO3_1= Var2dev("" ,RCUmod,DevType.I2C,RCU_IO3_OUT1,8,0,1) -RCU_IO3_2= Var2dev("" ,RCUmod,DevType.I2C,RCU_IO3_OUT2,8,0,1) -#RCU_IO3_3= Var2dev("" ,RCUmod,DevType.I2C,RCU_IO3_CONF1,8,0,1) -#RCU_IO3_4= Var2dev("" ,RCUmod,DevType.I2C,RCU_IO3_CONF2,8,0,1) -#RCU_IO3=VarArray("RCU_IO3",3,[RCU_IO3_1,RCU_IO3_2,RCU_IO3_3],RW.ReadOnly,datatype.dInt,None,None) - -RCU_OUT1=VarArray("RCU_OUT1",3,[RCU_IO1_1,RCU_IO2_1,RCU_IO3_1],RW.ReadOnly,datatype.dInt,3,None,None) -RCU_OUT2=VarArray("RCU_OUT2",3,[RCU_IO1_2,RCU_IO2_2,RCU_IO3_2],RW.ReadOnly,datatype.dInt,3,None,None) -#RCU_CNF1=VarArray("RCU_CONF1",3,[RCU_IO1_3,RCU_IO2_3,RCU_IO3_3],RW.ReadOnly,datatype.dInt,None,None) -#RCU_CNF2=VarArray("RCU_CONF2",3,[RCU_IO1_4,RCU_IO2_4,RCU_IO3_4],RW.ReadOnly,datatype.dInt,None,None) - -#OPC_devvars=[RCU_mask,Ant_mask,RCU_att,RCU_band,RCU_temp,RCU_pwrd,RCU_LED,RCU_ID,RCU_VER,HBA_Delay,HBA_led] -#OPC_devvars=[RCU_mask,Ant_mask,RCU_att,RCU_band,RCU_temp,RCU_pwrd,RCU_LED,RCU_ID,RCU_VER,HBA_Delay,HBA_led,RCU_uCV_ID] -OPC_devvars=[RCU_mask,Ant_mask,RCU_att,RCU_band,RCU_temp,RCU_pwrd,RCU_LED,RCU_ADC_lock,RCU_ADC_SYNC,RCU_ADC_JESD,RCU_ADC_CML,RCU_OUT1,RCU_OUT2,RCU_ID,RCU_VER,HBA_Delay,HBA_led,HBA_pwr,HBA_pwr2,RCU_uCV_ID] -#OPC_devvars=[RCU_mask,Ant_mask,RCU_att,RCU_band,RCU_temp,RCU_pwrd,RCU_LED,RCU_uCV_ID,RCU_uCV_spd0,RCU_uCV_RXspd1,RCU_uCV_RXspd2,RCU_uCV_TXspd1,RCU_uCV_debug ]#,HBA1_Pwr]#,RCU_CNF1,RCU_CNF2] -#Instr=namedtuple("DevInstr","type dev nvalue value") -#Instrs=namedtuple("Instr","name ninstr instr") - -#OPCUA methods - -RCU_init=Instrs("ReadRegisters",2,[ - Instr(DevType.VarUpdate,RCU_OUT1,3,[0,0,0]), - Instr(DevType.VarUpdate,RCU_OUT2,3,[0,0,0]) -]) - -ADC_on=Instrs("ADC_on",17,[ - Instr(DevType.SPIbb,RCU_ADC1_JESD_ctr,1,[0x14]), - Instr(DevType.SPIbb,RCU_ADC1_CML_level,1,[0x7]), - Instr(DevType.SPIbb,RCU_ADC1_SYNC_ctr,1,[1]), - Instr(DevType.SPIbb,RCU_ADC1_PLL_enc,1,[0x8]), - Instr(DevType.SPIbb,RCU_ADC1_update,1,[1]), - Instr(DevType.Wait,0,0,[100]), - Instr(DevType.SPIbb,RCU_ADC2_JESD_ctr,1,[0x14]), - Instr(DevType.SPIbb,RCU_ADC2_CML_level,1,[0x7]), - Instr(DevType.SPIbb,RCU_ADC2_SYNC_ctr,1,[1]), - Instr(DevType.SPIbb,RCU_ADC2_PLL_enc,1,[0x8]), - Instr(DevType.SPIbb,RCU_ADC2_update,1,[1]), - Instr(DevType.Wait,0,0,[100]), - Instr(DevType.SPIbb,RCU_ADC3_JESD_ctr,1,[0x14]), - Instr(DevType.SPIbb,RCU_ADC3_CML_level,1,[0x7]), - Instr(DevType.SPIbb,RCU_ADC3_SYNC_ctr,1,[1]), - Instr(DevType.SPIbb,RCU_ADC3_PLL_enc,1,[0x8]), - Instr(DevType.SPIbb,RCU_ADC3_update,1,[1]), - Instr(DevType.Wait,0,0,[500]), - Instr(DevType.VarUpdate,RCU_ADC_SYNC,3,[0,0,0]), - Instr(DevType.VarUpdate,RCU_ADC_JESD,3,[0,0,0]), - Instr(DevType.VarUpdate,RCU_ADC_CML,3,[0,0,0]), - Instr(DevType.VarUpdate,RCU_ADC_lock,3,[0,0,0]) -]) - -RCU_on=Instrs("RCU_on",20,[ - Instr(DevType.I2C,RCU_IO2_CONF1,1,[0]), - Instr(DevType.I2C,RCU_IO2_CONF2,1,[0]), - Instr(DevType.I2C,RCU_IO2_OUT1,1,[0x4A]), - Instr(DevType.I2C,RCU_IO2_OUT2,1,[0x55]), - Instr(DevType.Wait,0,0,[300]), - Instr(DevType.I2C,RCU_IO3_CONF1,1,[0]), - Instr(DevType.I2C,RCU_IO3_CONF2,1,[0]), - Instr(DevType.I2C,RCU_IO1_CONF1,1,[0]), - Instr(DevType.I2C,RCU_IO1_CONF2,1,[0]), - Instr(DevType.I2C,RCU_IO3_OUT1,1,[0x15]), - Instr(DevType.I2C,RCU_IO3_OUT2,1,[0x47]), - Instr(DevType.I2C,RCU_IO1_OUT1,1,[0xCA]), - Instr(DevType.I2C,RCU_IO1_OUT2,1,[0xCA]), - Instr(DevType.Wait,0,0,[200]), - Instr(DevType.VarUpdate,RCU_att,3,[0,0,0]), - Instr(DevType.VarUpdate,RCU_pwrd,1,[0]), - Instr(DevType.VarUpdate,RCU_OUT1,3,[0,0,0]), - Instr(DevType.VarUpdate,RCU_OUT2,3,[0,0,0]) -# Instr(DevType.Wait,0,0,[300]), -# Instr(DevType.Instr,ADC_on,0,[]) -]) - -RCU_off=Instrs("RCU_off",1,[ -# Instr(DevType.Var,RCU_mask,4,[1,1,1,1]), - Instr(DevType.Var,RCU_pwrd,32,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]), - Instr(DevType.I2C,RCU_IO3_OUT1,1,[0x0]), - Instr(DevType.I2C,RCU_IO3_OUT2,1,[0x0]), -# Instr(DevType.Var,RCU_mask,4,[0,0,0,0]) -]) - -RCU_update=Instrs("RCU_update",11,[ - Instr(DevType.VarUpdate,RCU_pwrd,1,[0]), - Instr(DevType.VarUpdate,RCU_OUT1,3,[0,0,0]), - Instr(DevType.VarUpdate,RCU_OUT2,3,[0,0,0]), - Instr(DevType.VarUpdate,RCU_ID,1,[0]), -# Instr(DevType.VarUpdate,RCU_VER,1,[0]*10), - Instr(DevType.VarUpdate,RCU_att,3,[0,0,0]), - Instr(DevType.VarUpdate,RCU_band,3,[0,0,0]), - Instr(DevType.VarUpdate,RCU_LED,1,[0]), - Instr(DevType.VarUpdate,RCU_ADC_SYNC,3,[0,0,0]), - Instr(DevType.VarUpdate,RCU_ADC_JESD,3,[0,0,0]), - Instr(DevType.VarUpdate,RCU_ADC_CML,3,[0,0,0]), - Instr(DevType.VarUpdate,RCU_ADC_lock,3,[0,0,0]) -]) - - -OPC_methods=[RCU_on,RCU_off,ADC_on,RCU_update] diff --git a/rcu/__init__.py b/rcu/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/requirements.txt b/requirements.txt index a60ca7ecbd7bfebc36f787dd6425b771587835b1..4a48e3de1ad782a2e988ed6a11bf604165d3a733 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,4 @@ git+https://github.com/amaork/libi2c.git; platform_system == "linux" opcua numpy recordclass +pyyaml diff --git a/scripts/ADCreset.py b/scripts/ADCreset.py index e42c94acc4acadf705c19747f1f63955e81d6814..7cb6d6e2201c508110731f166f2d2fe911affb63 100644 --- a/scripts/ADCreset.py +++ b/scripts/ADCreset.py @@ -3,10 +3,20 @@ from test_common import * RCUs=[0,1,2,3]; setRCUmask(RCUs) -#callmethod("RCU_off") +def wait(var1="RCU_translator_busy_R"): + for x in range(20): + busy=get_value(var1) +# print(busy) + if not(busy): break + time.sleep(0.1) + print("Time=",x*0.1,"s") + +callmethod("RCU_off") +wait() #exit() #time.sleep(2) callmethod("RCU_on") +wait() #callmethod("RCU_on") #time.sleep(1) #callmethod("ADC_on") diff --git a/scripts/CLK.py b/scripts/CLK.py index 4dbf2b4179174154d421998068cee27faa7108cb..19c524bed4db0b8a5765a96752682c058c9fbe5c 100644 --- a/scripts/CLK.py +++ b/scripts/CLK.py @@ -4,8 +4,14 @@ from test_common import * #time.sleep(1) callmethod("CLK_on") -time.sleep(1) -callmethod("CLK_PLL_setup") +for x in range(10): + busy=get_value("CLK_translator_busy_R") + print(busy) + if not(busy): break + time.sleep(0.1) + +#time.sleep(1) +#callmethod("CLK_PLL_setup") #exit() #time.sleep(1) #callmethod("RCU_on") diff --git a/scripts/HBA_wait_PPS.py b/scripts/HBA_wait_PPS.py new file mode 100644 index 0000000000000000000000000000000000000000..d1d8d74e5553befc000d4e3fec87fbb0c5b8c1d9 --- /dev/null +++ b/scripts/HBA_wait_PPS.py @@ -0,0 +1,10 @@ +from test_common import * + +RCUs=[0,1,2,3]; +setRCUmask(RCUs) +#for RCU in RCUs: +#setAntmask(RCUs,[True,True,True]) + +callmethod("RCU_HBAT_WAIT_PPS") + +disconnect(); \ No newline at end of file diff --git a/testCLK.py b/testCLK.py new file mode 100644 index 0000000000000000000000000000000000000000..52db37dd6c6826e96d19a44ea1dd0547b14a9629 --- /dev/null +++ b/testCLK.py @@ -0,0 +1,63 @@ +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="DEBUG",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) +RCU_conf.CallInit() + +var1=RCU_conf.getvarid('CLK_I2C_OK') +#RCU_I2C.setvar(var1,[True]) + +var1=RCU_conf.getvarid('CLK_PLL_locked') +RCU_I2C.readvar(var1,[]) + + +var1=RCU_conf.getvarid('CLK_PLL_locked_SPI') +#var1=RCU_conf.getvarid('CLK_PLL_r3') +#RCU_I2C.readvar(var1,[]) + + +#var1=RCU_conf.getmethodid('CLK_on'); +var1=RCU_conf.getmethodid('CLK_PLL_setup'); +#RCU_I2C.callmethod(var1,[]) + +time.sleep(2); + +while RCU_I2C.data_waiting(): + varid,data,mask=RCU_I2C.readdata() + print("Results:",RCU_conf.getvar1(varid)['name'],data,mask) + + +logging.info("Stop threads") +for i2c in I2Cclients: + i2c.stop() +for thread1 in threads: + thread1.join() diff --git a/testHBA.py b/testHBA.py new file mode 100644 index 0000000000000000000000000000000000000000..f61c8d588241ff56c2e59a782e71127c35a7b788 --- /dev/null +++ b/testHBA.py @@ -0,0 +1,61 @@ +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="DEBUG",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) +#RCU_conf.CallInit() + +var1=RCU_conf.getmethodid('RCU_update'); +#var1=RCU_conf.getmethodid('RCU_on'); +#N=32; +#mask=[i<2 for i in range(N)]; +#RCU_I2C.callmethod(var1,[]) + +var1=RCU_conf.getvarid('HBA_element_beamformer_delays'); +N=32*3; +data=list(range(32))*N; +mask=[i<1*3 for i in range(N)]; +RCU_I2C.setvar(var1,data,mask); +#RCU_I2C.readvar(var1,mask); + + +time.sleep(5); + +while RCU_I2C.data_waiting(): + varid,data,mask=RCU_I2C.readdata() + print("Results:",RCU_conf.getvar1(varid)['name'],data[:12],mask[:12]) + + +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..27ca7ddeea6cb93e54d9b82739315644eb0a6371 --- /dev/null +++ b/testRCU.py @@ -0,0 +1,95 @@ +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) +RCU_conf.CallInit() + +var1=RCU_conf.getmethodid('RCU_update'); +#var1=RCU_conf.getmethodid('RCU_on'); +#N=32; +#mask=[i<2 for i in range(N)]; +#RCU_I2C.callmethod(var1,[]) + +if False: + var1=RCU_conf.getvarid('RCU_LED0'); + N=32; + mask=[i<8 for i in range(N)]; + data=[0]*N; +elif True: + var1=RCU_conf.getvarid('RCU_ADC_lock'); + N=32*3; + mask=[i<5*3 for i in range(N)]; +elif False: + 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] +else: + var1=RCU_conf.getvarid('HBA_element_beamformer_delays'); + N=32*3; + mask=[i<4*3 for i in range(N)]; + data=[1]*(N*32); +#print(var1) +#print("mask=",mask); +#print("data=",data); +#RCU_I2C.setvar(var1,data,mask); +RCU_I2C.readvar(var1,mask); + +var1=RCU_conf.getvarid('RCU_temperature'); +N=32; +mask=[i<2 for i in range(N)]; +#RCU_I2C.readvar(var1,mask); + +#data=[0]*N; +#RCU_I2C.setvar(var1,data,mask); +#def setvar(self,id1,data=[],mask=[]): + +#var1=RCU_conf.getmethodid('RCU_on'); +var1=RCU_conf.getmethodid('RCU_HBAT_WAIT_PPS'); +N=32; +mask=[i<7 for i in range(N)]; +#RCU_I2C.callmethod(var1,mask) + + +time.sleep(5); + +while RCU_I2C.data_waiting(): + varid,data,mask=RCU_I2C.readdata() + print("Results:",RCU_conf.getvar1(varid)['name'],data[:12],mask[:12]) + + +logging.info("Stop threads") +for i2c in I2Cclients: + i2c.stop() +for thread1 in threads: + thread1.join() diff --git a/testUNB2.py b/testUNB2.py new file mode 100644 index 0000000000000000000000000000000000000000..a6e3530a84a32db8644c76e8258a8f93bae81b75 --- /dev/null +++ b/testUNB2.py @@ -0,0 +1,68 @@ +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="DEBUG",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='UNB2' +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) +var1=RCU_conf.getvarid('UNB2_EEPROM_Unique_ID'); +N=2; +mask=[i<1 for i in range(N)]; +print("mask=",mask); +RCU_I2C.readvar(var1,mask); + + +var1=RCU_conf.getvarid('UNB2_DC_DC_48V_12V_VIN'); +N=2; +mask=[i<2 for i in range(N)]; +print("mask=",mask); +RCU_I2C.readvar(var1,mask); + +var1=RCU_conf.getvarid('UNB2_FPGA_QSFP_CAGE_LOS'); +N=48; +mask=[i<8 for i in range(N)]; +print("mask=",mask); +RCU_I2C.readvar(var1,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..2114bb1eef8dfb8c5ec013444fe89e9c64f23d1b --- /dev/null +++ b/yamlconfig.py @@ -0,0 +1,227 @@ +import yaml +import struct +import time +import logging + +def Find(L,name,value,default=False): + for x in L: + if x[name]==value: + return x; + return default; + + +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,None); + return (var1['id'] if not(var1 is None) else None); + + 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])) + logging.debug("New devreg! %s",str((name2))) + if len(name2)==2: + dev1=Find(self.conf['device_registers'],'name',name2[0]) + if dev1: + store=dev1.get('store',False) + devcls=dev1.get('driver'); + if not(devcls): logging.error("Can not find driver for register "+name2[0]); + else: + devcls=Find(self.conf['drivers'],'name',devcls) + if not(devcls): logging.error("Can not find device for register "+name2[0]); + else: + devcls=devcls.get('obj') +# print(dev1) + return {"addr":dev1.get('address',0),"register_R":str2int(name2[1]),"register_W":str2int(name2[1]),"store":store,"drivercls":devcls}; + else: 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)] + + for D in drivers: + mask=D.get('status'); + if mask is None: continue; + mask=self.getvarid(mask) + if mask is None: + 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) +# 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']; + +