diff --git a/config/APSPUTL.yaml b/config/APSPUTL.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5767c34bc7c269eb4e94e5b59e0054b7fe86d7af --- /dev/null +++ b/config/APSPUTL.yaml @@ -0,0 +1,125 @@ +version: "1.0" +description: "1234" + +drivers: + - name: I2C + type: i2c_smbus + parameters: [5] #I2C port number + - name: I2C_PU + type: i2c_dev #I2C devices + parent: I2C + status: APSPU_I2C_STATUS + +#This is the I2C devices in the RCU +device_registers: + - name: ROM + address: 0x50 + driver: I2C_PU + registers: + - name: ID + description: Random + address: 0xfc + - name: Version + description: Set in production + address: 0 + + + - name: MAX + description: MAX6620 fan speed controller + address: 0x29 + driver: I2C_PU + registers: + - name: GLOBAL + address: 0x00 + - name: TACH1 + address: 0x10 + - name: TACH2 + address: 0x12 + - name: TACH3 + address: 0x14 + + +variables: + - name: APSPU_I2C_STATUS + driver: I2C_PU + rw: ro #server RW variable, not linked to IO + dtype: uint8 + + - name: APSPUTL_translator_busy + description: False when idle + rw: ro #server variable, not linked to IO + dtype: boolean + + - name: APSPU_ID + description: Unique PCB ID + driver: I2C_PU + devreg: ROM.ID + width: 32 + rw: ro + dtype: uint32 + + - name: APSPU_version + description: Version number + driver: I2C_PU + devreg: ROM.Version + width: 80 #10 characters + rw: ro + dtype: string + + + - name: [APSPU_LBA_VOUT,APSPU_RCU2A_VOUT,APSPU_RCU2D_VOUT] + driver: I2C_PU + devreg: [0x3C.0x8B,0x3D.0x8B,0x3E.0x8B] + width: 16 + rw: ro + dtype: double + endian: "<" + scale: 4.8828e-4 #2^-11 + monitor: true + + - name: [APSPU_LBA_IOUT,APSPU_RCU2A_IOUT,APSPU_RCU2D_IOUT] + driver: I2C_PU + devreg: [0x3C.0x8C,0x3D.0x8C,0x3E.0x8C] + width: 16 + rw: ro + dtype: double + scale: smbus_2bytes_to_float + monitor: true + + - name: [APSPU_LBA_TEMP,APSPU_RCU2A_TEMP,APSPU_RCU2D_TEMP] + driver: I2C_PU + devreg: [0x3C.0x8D,0x3D.0x8D,0x3E.0x8D] + width: 16 + rw: ro + dtype: double + scale: smbus_2bytes_to_float + monitor: true + + - name: [APSPU_FAN_period1,APSPU_FAN_period2,APSPU_FAN_period3] + driver: I2C_PU + devreg: [MAX.TACH1,MAX.TACH2,MAX.TACH3] + bitoffset: 4 + width: 12 + rw: ro + dtype: double + scale: 7.629395e-6 #FAN_TACHS/TACH_COUNT_FREQ/TACH_PERIODS = 1/8192/16 + monitor: true + +methods: + - name: APSPUTL_Init #Called after startup to load. Should have all stored registers + driver: I2C_PU + debug: True + instructions: + - APSPU_ID : Update + - APSPU_version : Update + + - name: APSPU_FanOn + driver: I2C_PU + instructions: + - MAX.GLOBAL : 0x02; #Run monitor + - MAX.0x02 : 0x88; + - MAX.0x06 : 0x80; # int((math.log(TACH_PERIODS{16}) / math.log(2))) << 5, + - MAX.0x03 : 0x88; + - MAX.0x07 : 0x80; + - MAX.0x04 : 0x88; + - MAX.0x08 : 0x80; diff --git a/i2cserv/i2c_array.py b/i2cserv/i2c_array.py index a2177c9cbdf38acd992639c77bf9b2874a42b911..89ef667741f0333a90ad404d4cf6d3ab7a042ca3 100644 --- a/i2cserv/i2c_array.py +++ b/i2cserv/i2c_array.py @@ -5,12 +5,6 @@ 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): diff --git a/i2cserv/i2c_dev.py b/i2cserv/i2c_dev.py index 2dc3673acf358a757a4bb94bfc5d02974a325d77..1def8f3d105969074bbb52f23acb2773de9d3d26 100644 --- a/i2cserv/i2c_dev.py +++ b/i2cserv/i2c_dev.py @@ -81,6 +81,14 @@ def list_different(A,B): if not(m==A[i]): return True return False +def GetSteps(V1): + if isinstance(V1['devreg'],list): Step=len(V1['devreg']) + else: Step=1; #V1.nVars + Step2=V1.get('dim',1)*((V1.get('width',8)+7)//8)//Step #int(V1.size/V1.nVars) + logging.debug(str(("GetStep",Step,Step2))); + return Step,Step2 + + class i2c_dev(hwdev): def __init__(self,config): hwdev.__init__(self,config); @@ -111,6 +119,7 @@ class i2c_dev(hwdev): return Data def OPCUAReadVariable(self,varid,var1,mask): + if len(mask)==0: mask=[True]; logging.info(str(("Read Var",var1['name'],mask))) if not(var1.get('devreg')): return [] #data=self.GetVarValueAll(var1) @@ -132,9 +141,13 @@ class i2c_dev(hwdev): 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): + Step,Step2=GetSteps(var1); + value1=[0]*Step*Step2; +# Step=(len(var1['devreg']) if isinstance(var1['devreg'],list) else 1) +# value1=[0]*Step; + + if not(len(data)==Step*Step2): +# if not(len(data)==Step): print("Check data length!"); return; if (len(mask)==1): @@ -149,8 +162,8 @@ class i2c_dev(hwdev): if not(self.I2Cmask[0]==0): mask[Vari]=False; continue; - i0=(Vari)*Step - i1=(Vari+1)*Step + i0=(Vari)*Step2 + i1=(Vari+1)*Step2 devreg=var1['devreg'][Vari]; width=var1.get('width',8) bitoffset=GetField(var1,'bitoffset',Vari,0) @@ -170,8 +183,10 @@ class i2c_dev(hwdev): def GetVarValueMask(self,var1,mask): - Step=(len(var1['devreg']) if isinstance(var1['devreg'],list) else 1) - value1=[0]*Step; + Step,Step2=GetSteps(var1); + value1=[0]*Step*Step2; +# 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): @@ -184,8 +199,8 @@ class i2c_dev(hwdev): if not(self.I2Cmask[0]==0): mask[Vari]=False; continue; - i0=( Vari)*Step - i1=(Vari+1)*Step + i0=( Vari)*Step2 + i1=(Vari+1)*Step2 devreg=var1['devreg'][Vari]; width=var1.get('width',8) bitoffset=GetField(var1,'bitoffset',Vari,0) @@ -234,7 +249,7 @@ class i2c_dev(hwdev): 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']: + if devreg.get('store'): previous=self.getstoreval(devreg); for x in range(len(value)): value[x]=ApplyMask(value[x],width,bitoffset,previous); @@ -244,14 +259,14 @@ class i2c_dev(hwdev): 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))) + logging.debug(str(("i2c_dev 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']: + if devreg.get('store'): devreg['storeval']=value[0]; l1=int(np.floor((width+bitoffset+7)/8)) #print(value[0],width,bitoffset,l1) diff --git a/opcuaserv/smbus_float.py b/opcuaserv/smbus_float.py index 87bafce16c1290ede4a5a9bd3bd59cbb85bd07e3..03798560155257fbc812205c1aaa4feea1a711ce 100644 --- a/opcuaserv/smbus_float.py +++ b/opcuaserv/smbus_float.py @@ -1,5 +1,7 @@ def smbus_2bytes_to_float(data): expo = ((data & 0xf8)>>3) + if expo == 1: + expo = -7 if expo > 2**4: expo = expo-2**5 mantisse = ((data & 0x7)<<8) + ((data & 0xff00) >> 8)