Skip to content
Snippets Groups Projects
Commit 42d0c3ac authored by Paulus Kruger's avatar Paulus Kruger
Browse files

Faster (parallel) i2c and spi bitbang

parent c62ebf53
No related branches found
No related tags found
No related merge requests found
Pipeline #27326 passed
...@@ -21,20 +21,25 @@ drivers: ...@@ -21,20 +21,25 @@ drivers:
devreg: [0x40.0xFF] #I2C broadcast register devreg: [0x40.0xFF] #I2C broadcast register
parameters: [24] #PPS GPIO pin parameters: [24] #PPS GPIO pin
- name: I2Cbb1 - name: I2Cbb1
type: i2cbitbang1 #I2C bitbang via GPIO expander type: i2cbitbangp #I2C bitbang via GPIO expander
devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2] devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2]
parameters: [5,6,6] #pins parameters: [5,6,6] #pins
parent: I2C_RCU parent: I2C_RCU
- name: I2Cbb2 - name: I2Cbb2
type: i2cbitbang1 type: i2cbitbangp
devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2] devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2]
parameters: [4,6,6] parameters: [4,6,6]
parent: I2C_RCU parent: I2C_RCU
- name: I2Cbb3 - name: I2Cbb3
type: i2cbitbang1 type: i2cbitbangp
devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2] devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2]
parameters: [3,6,6] parameters: [3,6,6]
parent: I2C_RCU parent: I2C_RCU
# - name: I2Cbbp
# type: i2cbitbangp
# devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2]
# parameters: [5,4,3,6,6,6,6,6,6]
# parent: I2C_RCU
- name: SPIbb1 - name: SPIbb1
type: spibitbang1 #SPI bitbang via GPIO expander: CLK, SDIO, SDIOdir,CS type: spibitbang1 #SPI bitbang via GPIO expander: CLK, SDIO, SDIOdir,CS
devreg: [IO3.GPIO1,IO3.GPIO1,IO3.CONF1,IO3.GPIO2] devreg: [IO3.GPIO1,IO3.GPIO1,IO3.CONF1,IO3.GPIO2]
...@@ -50,6 +55,12 @@ drivers: ...@@ -50,6 +55,12 @@ drivers:
devreg: [IO3.GPIO1,IO3.GPIO1,IO3.CONF1,IO3.GPIO2] devreg: [IO3.GPIO1,IO3.GPIO1,IO3.CONF1,IO3.GPIO2]
parameters: [5,4,4,2] parameters: [5,4,4,2]
parent: I2C_RCU parent: I2C_RCU
# - name: SPI3bb
# type: spibitbang3 #SPI bitbang via GPIO expander: CLK, SDIO, SDIOdir,CS
# devreg: [IO3.GPIO1,IO3.GPIO1,IO3.CONF1,IO3.GPIO2]
# parameters: [1,3,5, 0,2,4, 0,2,4, 0,1,2]
# parent: I2C_RCU
# - name: HBA_trigger # - name: HBA_trigger
# type: gpio_hba_trigger # type: gpio_hba_trigger
# parameters: [15] #PPS GPIO pin # parameters: [15] #PPS GPIO pin
...@@ -459,7 +470,7 @@ variables: ...@@ -459,7 +470,7 @@ variables:
dim: 96 dim: 96
dim2: [3,32] dim2: [3,32]
read_parallel: true read_parallel: true
monitor: true # monitor: true
mask: RECVTR_I2C_error mask: RECVTR_I2C_error
- name: RCU_PWR_ANT2_VIN - name: RCU_PWR_ANT2_VIN
...@@ -473,7 +484,7 @@ variables: ...@@ -473,7 +484,7 @@ variables:
dim: 96 dim: 96
dim2: [3,32] dim2: [3,32]
read_parallel: true read_parallel: true
monitor: true # monitor: true
mask: RECVTR_I2C_error mask: RECVTR_I2C_error
...@@ -512,12 +523,12 @@ variables: ...@@ -512,12 +523,12 @@ variables:
mask: RCU_mask mask: RCU_mask
- name: RCU_DTH_shutdown - name: RCU_DTH_shutdown
description: False means dither source powered on. Controlled by TBD description: False means dither source & ADC powered on.
driver: I2C_RCU driver: I2C_RCU
devreg: [IO3.GPIO1,IO3.GPIO1,IO3.GPIO2] devreg: [IO3.GPIO1,IO3.GPIO1,IO3.GPIO2]
width: 1 width: 1
bitoffset: [7,6,7] bitoffset: [7,6,7]
rw: rw rw: ro
dtype: boolean dtype: boolean
dim: 96 dim: 96
dim2: [3,32] dim2: [3,32]
...@@ -639,6 +650,7 @@ variables: ...@@ -639,6 +650,7 @@ variables:
dim: 96 dim: 96
dim2: [3,32] dim2: [3,32]
# monitor: true # monitor: true
read_parallel: true
- name: RCU_ADC_sync - name: RCU_ADC_sync
driver: I2C_RCU driver: I2C_RCU
...@@ -680,6 +692,7 @@ variables: ...@@ -680,6 +692,7 @@ variables:
dim: 96 dim: 96
dim2: [3,32] dim2: [3,32]
mask: ANT_mask mask: ANT_mask
read_parallel: all
- name: RCU_DTH_PWR - name: RCU_DTH_PWR
description: RCU Dither source power description: RCU Dither source power
...@@ -692,30 +705,33 @@ variables: ...@@ -692,30 +705,33 @@ variables:
dim: 96 dim: 96
dim2: [3,32] dim2: [3,32]
mask: ANT_mask mask: ANT_mask
read_parallel: all
# debug: true # debug: true
- name: RCU_DTH_tune # - name: RCU_DTH_tune
driver: I2C_RCU # driver: I2C_RCU
devreg: [DTH1.Tune,DTH2.Tune,DTH3.Tune] # devreg: [DTH1.Tune,DTH2.Tune,DTH3.Tune]
width: 16 # width: 16
rw: rw # rw: rw
dtype: uint32 # dtype: uint32
dim: 96 # dim: 96
dim2: [3,32] # dim2: [3,32]
mask: ANT_mask # mask: ANT_mask
debug: true # debug: true
# read_parallel: all
- name: RCU_DTH_config # - name: RCU_DTH_config
driver: I2C_RCU # driver: I2C_RCU
devreg: [DTH1.CONF,DTH2.CONF,DTH3.CONF] # devreg: [DTH1.CONF,DTH2.CONF,DTH3.CONF]
width: 8 # width: 8
rw: rw # rw: rw
dtype: uint32 # dtype: uint32
dim: 96 # dim: 96
dim2: [3,32] # dim2: [3,32]
mask: ANT_mask # mask: ANT_mask
debug: true # debug: true
# read_parallel: all
- name: RCU_DTH_on - name: RCU_DTH_on
description: RCU Dither on. Controlled by RCU_DTH_on/off description: RCU Dither on. Controlled by RCU_DTH_on/off
...@@ -728,17 +744,19 @@ variables: ...@@ -728,17 +744,19 @@ variables:
dim: 96 dim: 96
dim2: [3,32] dim2: [3,32]
mask: ANT_mask mask: ANT_mask
read_parallel: all
- name: RCU_DTH_Rev # - name: RCU_DTH_Rev
driver: I2C_RCU # driver: I2C_RCU
devreg: [DTH1.Rev,DTH2.Rev,DTH3.Rev] # devreg: [DTH1.Rev,DTH2.Rev,DTH3.Rev]
width: 88 # width: 88
rw: rw # rw: rw
dtype: uint32 # dtype: uint32
dim: 96 # dim: 96
dim2: [3,32] # dim2: [3,32]
mask: ANT_mask # mask: ANT_mask
debug: true # debug: true
# read_parallel: all
methods: methods:
- name: RECVTR_Init #Called after startup to load. Should have all stored registers - name: RECVTR_Init #Called after startup to load. Should have all stored registers
...@@ -758,6 +776,8 @@ methods: ...@@ -758,6 +776,8 @@ methods:
# - IO3.GPIO2: Update # - IO3.GPIO2: Update
- IO3.CONF1: Update - IO3.CONF1: Update
- RCU_update: 0 - RCU_update: 0
- RCU_ADC_locked: Update #check if not also in RCU_update
- RCU_DTH_on: Update #check if not also in RCU_update
- RCU_IO4_GPIO1: Update #should be last, as it will fail for low-band - RCU_IO4_GPIO1: Update #should be last, as it will fail for low-band
- RCU_IO4_GPIO2: Update - RCU_IO4_GPIO2: Update
...@@ -770,30 +790,39 @@ methods: ...@@ -770,30 +790,39 @@ methods:
- IO2.CONF1: 0x80 #Pgood on 0x80 - IO2.CONF1: 0x80 #Pgood on 0x80
- IO2.GPIO1: 0x4A #0x40 Dig on, 0x0a =10dB att - IO2.GPIO1: 0x4A #0x40 Dig on, 0x0a =10dB att
- IO2.GPIO2: 0x55 #0x15 #Band0 (or 0x2a band 1) #LED green=on=low - IO2.GPIO2: 0x55 #0x15 #Band0 (or 0x2a band 1) #LED green=on=low
- IO3.GPIO1: 0xD5 #ADC_SDIO=high, clk=low, DTH_EN=high - IO3.GPIO1: 0x15 #ADC_SDIO=high, clk=low, DTH_EN=low
- IO3.GPIO2: 0xC7 #ADC SC=high, DTH_SDA=high, DTH_EN=high - IO3.GPIO2: 0x47 #ADC SC=high, DTH_SDA=high, DTH_EN=low
- IO1.GPIO1: 0x0A #0x0a = 10dB att - IO1.GPIO1: 0x0A #0x0a = 10dB att
- IO1.GPIO2: 0x8A #0x80 Analog on, 0x0a=10dB att - IO1.GPIO2: 0x8A #0x80 Analog on, 0x0a=10dB att
- IO2.CONF2: 0 - IO2.CONF2: 0
- IO3.CONF1: 0 - IO3.CONF1: 0
- IO3.CONF2: 0 - IO3.CONF2: 0
- IO3.DIR1: 0
- IO3.DIR2: 0
- IO1.CONF1: 0 - IO1.CONF1: 0
- IO1.CONF2: 0 - IO1.CONF2: 0
# - RCU_GPIO1: Update # - RCU_GPIO1: Update
# - RCU_GPIO2: Update # - RCU_GPIO2: Update
# - RCU_attenuator: [10,10,10] #Set OPC-UA variable # - RCU_attenuator: [10,10,10] #Set OPC-UA variable
#name="RCU_DTH_shutdown" #name="RCU_DTH_shutdown"
- IO3.GPIO1: 0x55 #enable ADC 0 (DTH_EN=low) - RCU_update: 0
- IO3.GPIO1: 0x15 #enable ADC 1
- IO3.GPIO2: 0x47 #enable ADC 2
- WAIT: 500 #ms to wait - WAIT: 500 #ms to wait
- ADC1_on: 0 #call another opc-ua method - ADC1_on: 0 #call another opc-ua method
- WAIT: 1000 #ms to wait # - WAIT: 1000 #ms to wait
- ADC2_on: 0 - ADC2_on: 0
- WAIT: 1000 #ms to wait # - WAIT: 1000 #ms to wait
- ADC3_on: 0 - ADC3_on: 0
- WAIT: 500 #ms to wait # - WAIT: 500 #ms to wait
- RCU_update: 0 #Toggle enable pin
- IO3.GPIO1: 0xD5 #ADC_SDIO=high, clk=low, DTH_EN=high
- IO3.GPIO2: 0xC7 #ADC SC=high, DTH_SDA=high, DTH_EN=high
- WAIT: 100 #ms to wait #todo: test if necessary
- IO3.GPIO1: 0x15 #enable ADC 0,1
- IO3.GPIO2: 0x47 #enable ADC 2
- RCU_DTH_on: Update #check dither while giving ADCs some time to lock
# - WAIT: 500 #ms to wait
- RCU_ADC_locked: Update #disabled for testing
- name: RCU_on2 - name: RCU_on2
description: Initialize RCU and it in the ON state description: Initialize RCU and it in the ON state
...@@ -857,11 +886,11 @@ methods: ...@@ -857,11 +886,11 @@ methods:
- RCU_LED_green_on: Update - RCU_LED_green_on: Update
- RCU_attenuator_dB: Update - RCU_attenuator_dB: Update
- RCU_band_select: Update - RCU_band_select: Update
- RCU_ADC_locked: Update # - RCU_ADC_locked: Update #disabled for testing
- RCU_ADC_sync: Update # - RCU_ADC_sync: Update #disabled for testing
- RCU_DTH_shutdown: Update # - RCU_DTH_shutdown: Update
# - RCU_DTH_freq: Update # - RCU_DTH_freq: Update
# - RCU_DTH_on: Update # - RCU_DTH_on: Update #disabled for testing
- RCU_hband_select: Update - RCU_hband_select: Update
- RCU_DAB_select: Update - RCU_DAB_select: Update
- RCU_firmware_version: Update - RCU_firmware_version: Update
...@@ -883,6 +912,7 @@ methods: ...@@ -883,6 +912,7 @@ methods:
- ADC1.JESD_control1 : 0x14 - ADC1.JESD_control1 : 0x14
- ADC1.SYNC_control: 1 #Setup ADCs - ADC1.SYNC_control: 1 #Setup ADCs
- ADC1.CML_level: 0x7 - ADC1.CML_level: 0x7
- ADC1.dither : 0x00
- ADC1.Update: 1 #Needed to update ADC registers - ADC1.Update: 1 #Needed to update ADC registers
- name: ADC2_on - name: ADC2_on
...@@ -893,6 +923,7 @@ methods: ...@@ -893,6 +923,7 @@ methods:
- ADC2.JESD_control1 : 0x14 - ADC2.JESD_control1 : 0x14
- ADC2.SYNC_control: 1 #Setup ADCs - ADC2.SYNC_control: 1 #Setup ADCs
- ADC2.CML_level: 0x7 - ADC2.CML_level: 0x7
- ADC2.dither : 0x00
- ADC2.Update: 1 #Needed to update ADC registers - ADC2.Update: 1 #Needed to update ADC registers
- name: ADC3_on - name: ADC3_on
...@@ -903,6 +934,7 @@ methods: ...@@ -903,6 +934,7 @@ methods:
- ADC3.JESD_control1 : 0x14 - ADC3.JESD_control1 : 0x14
- ADC3.SYNC_control: 1 #Setup ADCs - ADC3.SYNC_control: 1 #Setup ADCs
- ADC3.CML_level: 0x7 - ADC3.CML_level: 0x7
- ADC3.dither : 0x00
- ADC3.Update: 1 #Needed to update ADC registers - ADC3.Update: 1 #Needed to update ADC registers
- name: RCU_off - name: RCU_off
...@@ -938,8 +970,11 @@ methods: ...@@ -938,8 +970,11 @@ methods:
mask: RCU_mask mask: RCU_mask
# rw: hidden # rw: hidden
instructions: instructions:
- RCU_DTH_config : [0,0,0] # - RCU_DTH_config : [0,0,0]
# - RCU_DTH_config: Update #debug # - RCU_DTH_config: Update #debug
- DTH1.CONF : [0,0,0]
- DTH2.CONF : [0,0,0]
- DTH3.CONF : [0,0,0]
- DTH1.Tune : [0,0] #no tuning - DTH1.Tune : [0,0] #no tuning
- DTH2.Tune : [0,0] #no tuning - DTH2.Tune : [0,0] #no tuning
- DTH3.Tune : [0,0] #no tuning - DTH3.Tune : [0,0] #no tuning
...@@ -965,7 +1000,7 @@ methods: ...@@ -965,7 +1000,7 @@ methods:
# - DTH1.State : [0,0] # - DTH1.State : [0,0]
# - DTH2.State : [0,0] # - DTH2.State : [0,0]
# - DTH3.State : [0,0] # - DTH3.State : [0,0]
- RCU_DTH_on: Update - RCU_DTH_on: Update
- name: RCU_DTH_restart #restart to update frequency - name: RCU_DTH_restart #restart to update frequency
driver: I2C_RCU driver: I2C_RCU
...@@ -979,20 +1014,20 @@ methods: ...@@ -979,20 +1014,20 @@ methods:
- DTH2.Start : [0,1,0,0,1] - DTH2.Start : [0,1,0,0,1]
- DTH3.Start : [0,1,0,0,1] - DTH3.Start : [0,1,0,0,1]
- name: RCU_DTH_shutdown # - name: RCU_DTH_shutdown
description: shutdown dither source # description: shutdown dither source
driver: I2C_RCU # driver: I2C_RCU
debug: True # debug: True
mask: RCU_mask # mask: RCU_mask
# rw: hidden # rw: hidden
instructions: # instructions:
# - RCU_DTH_SHUTDOWN : [1,1,1] # - RCU_DTH_SHUTDOWN : [1,1,1]
# - WAIT: 100 # - WAIT: 100
# - RCU_DTH_SHUTDOWN : [0,0,0] # - RCU_DTH_SHUTDOWN : [0,0,0]
# - RCU_DTH_SHUTDOWN : 1 # - RCU_DTH_SHUTDOWN : 1
- DTH1.State : [1,0] # - DTH1.State : [1,0]
- DTH2.State : [1,0] # - DTH2.State : [1,0]
- DTH3.State : [1,0] # - DTH3.State : [1,0]
- name: ADC0_test - name: ADC0_test
driver: I2C_RCU driver: I2C_RCU
......
...@@ -16,6 +16,7 @@ class i2c_array(i2c_dev): ...@@ -16,6 +16,7 @@ class i2c_array(i2c_dev):
# self.previousHBA=np.zeros([number,3,32],dtype='int') # self.previousHBA=np.zeros([number,3,32],dtype='int')
pars=config['parameters']; pars=config['parameters'];
self.RCU_Switch1=pars; #range(pars[0],pars[1]+1); self.RCU_Switch1=pars; #range(pars[0],pars[1]+1);
self.RCUorder=sorted(range(len(pars)),key=lambda k:pars[k])
self.N=len(self.RCU_Switch1); self.N=len(self.RCU_Switch1);
self.I2Cmask=[0]*self.N self.I2Cmask=[0]*self.N
self.I2Ccut=config.get('I2Ccut',5);#pars[2]; self.I2Ccut=config.get('I2Ccut',5);#pars[2];
...@@ -33,11 +34,13 @@ class i2c_array(i2c_dev): ...@@ -33,11 +34,13 @@ class i2c_array(i2c_dev):
def SetSwitchMask(self,mask): def SetSwitchMask(self,mask):
m=0; m=0;
self.mask=[]
self.conf['parentcls'].ClearNewChannel(); self.conf['parentcls'].ClearNewChannel();
for RCUi in range(self.N): for RCUi in self.RCUorder:
if (mask[RCUi]) and (self.I2Cmask[RCUi]<=self.I2Ccut): if (mask[RCUi]) and (self.I2Cmask[RCUi]<=self.I2Ccut):
self.conf['parentcls'].AddNewChannel(self.RCU_Switch1[RCUi]); self.conf['parentcls'].AddNewChannel(self.RCU_Switch1[RCUi]);
self.RCUi=RCUi self.RCUi=RCUi
self.mask+=[RCUi]
self.conf['parentcls'].UpdateNewChannel(); self.conf['parentcls'].UpdateNewChannel();
def SetGetVarValueMask(self,var1,data,mask,getalso=True): def SetGetVarValueMask(self,var1,data,mask,getalso=True):
...@@ -56,7 +59,41 @@ class i2c_array(i2c_dev): ...@@ -56,7 +59,41 @@ class i2c_array(i2c_dev):
return; return;
# if (len(value1)==V1.nVars) and (self.N>1): value1=(value1*self.N); # if (len(value1)==V1.nVars) and (self.N>1): value1=(value1*self.N);
# logging.debug(str(("Step=",Step,"Mask=",mask))) # logging.debug(str(("Step=",Step,"Mask=",mask)))
for RCUi in range(self.N): if var1.get('read_parallel')=='all':
for Vari in range(Step):
devreg=var1['devreg'][Vari];
width=var1.get('width',8)
bitoffset=GetField(var1,'bitoffset',Vari,0)
mask2=[mask[RCUi*Step+Vari] & (self.I2Cmask[RCUi]<=self.I2Ccut) for RCUi in range(self.N)]
#self.mask=mask2;
isthesame=True;
self.SetSwitchMask(mask2);
for RCUi in self.mask:
# if not(mask2[RCUi]): continue;
for i in range(Step2):
if data[(Vari+RCUi*Step)*Step2+i]!=data[(Vari+self.RCUi*Step)*Step2+i]:
isthesame=False;
if isthesame:
data2=data[(Vari+self.RCUi*Step)*Step2:(Vari+self.RCUi*Step+1)*Step2]
res=self.SetVarValue(devreg,width,bitoffset,data2)
else:
for RCUi in self.RCUorder:
if not(mask[RCUi*Step+Vari]): continue
self.mask=[RCUi];
self.SetSwitch(RCUi);
self.RCUi=RCUi;
i0=(RCUi*Step+ Vari)*Step2
i1=(RCUi*Step+(Vari+1))*Step2
res=self.SetVarValue(devreg,width,bitoffset,data[i0:i1])
if getalso:
self.SetSwitchMask(mask2);
value2=[0]*self.N*Step2;
res=self.GetVarValue(devreg,width,bitoffset,value2,0)
# print(Vari,mask2,value2)
for r in range(self.N): value1[(Vari+r*Step)*Step2:(Vari+r*Step+1)*Step2]=value2[r*Step2:(r+1)*Step2]
# print(len(value1),value1)
return value1,mask
for RCUi in self.RCUorder:
for Vari in range(Step): for Vari in range(Step):
if not(mask[RCUi*Step+Vari]): continue if not(mask[RCUi*Step+Vari]): continue
if not(self.I2Cmask[RCUi]<=self.I2Ccut): if not(self.I2Cmask[RCUi]<=self.I2Ccut):
...@@ -86,6 +123,10 @@ class i2c_array(i2c_dev): ...@@ -86,6 +123,10 @@ class i2c_array(i2c_dev):
self.I2Cmask[RCUi]=0; self.I2Cmask[RCUi]=0;
return value1,mask return value1,mask
# def GetVarValueParallel(self,var1,mask):
# mask2=[mask[RCUi*Step] & (self.I2Cmask[RCUi]<=self.I2Ccut) for RCUi in range(self.N)]
# self.SetSwitchMask(mask2);
# def
def GetVarValueMask(self,var1,mask): def GetVarValueMask(self,var1,mask):
Step,Step2=GetSteps(var1); Step,Step2=GetSteps(var1);
...@@ -99,6 +140,24 @@ class i2c_array(i2c_dev): ...@@ -99,6 +140,24 @@ class i2c_array(i2c_dev):
# if (len(value1)==V1.nVars) and (self.N>1): value1=(value1*self.N); # if (len(value1)==V1.nVars) and (self.N>1): value1=(value1*self.N);
i2c=self.conf['parentcls']; i2c=self.conf['parentcls'];
# logging.debug(str(("Step=",Step,"Mask=",mask))) # logging.debug(str(("Step=",Step,"Mask=",mask)))
# if var1.get('read_parallel')=='all':
# return self.GetVarValueParallel(self,var1,mask)
# print(Step,Step2,len(mask),len(value1))
if var1.get('read_parallel')=='all':
for Vari in range(Step):
devreg=var1['devreg'][Vari];
width=var1.get('width',8)
bitoffset=GetField(var1,'bitoffset',Vari,0)
mask2=[mask[RCUi*Step+Vari] & (self.I2Cmask[RCUi]<=self.I2Ccut) for RCUi in range(self.N)]
self.SetSwitchMask(mask2);
# self.mask=mask2;
value2=[0]*self.N*Step2;
res=self.GetVarValue(devreg,width,bitoffset,value2,0)
# print(Vari,mask2,value2)
for r in range(self.N): value1[(Vari+r*Step)*Step2:(Vari+r*Step+1)*Step2]=value2[r*Step2:(r+1)*Step2]
# print(len(value1),value1)
return value1,mask
mode=(1 if var1.get('read_parallel') else 0) mode=(1 if var1.get('read_parallel') else 0)
for Vari in range(Step): for Vari in range(Step):
if mode==1: if mode==1:
...@@ -114,7 +173,7 @@ class i2c_array(i2c_dev): ...@@ -114,7 +173,7 @@ class i2c_array(i2c_dev):
res=self.GetVarValue(devreg,width,bitoffset,[],mode=3) #wait if needed res=self.GetVarValue(devreg,width,bitoffset,[],mode=3) #wait if needed
# for Vari in range(Step): # for Vari in range(Step):
# else: # else:
for RCUi in range(self.N): for RCUi in self.RCUorder:
# for Vari in range(Step): # for Vari in range(Step):
if not(mask[RCUi*Step+Vari]): continue if not(mask[RCUi*Step+Vari]): continue
i0=(RCUi*Step+ Vari)*Step2 i0=(RCUi*Step+ Vari)*Step2
...@@ -152,6 +211,7 @@ class i2c_array(i2c_dev): ...@@ -152,6 +211,7 @@ class i2c_array(i2c_dev):
if len(mask)==0: if len(mask)==0:
mask=[True]*self.N; mask=[True]*self.N;
self.RCUi=0; self.RCUi=0;
# self.mask=mask;
self.SetSwitchMask(mask) self.SetSwitchMask(mask)
if not(self.SetVarValue(devreg,8,0,value)): return False; if not(self.SetVarValue(devreg,8,0,value)): return False;
if devreg.get('store'): if devreg.get('store'):
...@@ -170,7 +230,7 @@ class i2c_array(i2c_dev): ...@@ -170,7 +230,7 @@ class i2c_array(i2c_dev):
if devreg.get('store'): if devreg.get('store'):
storearray=self.getstorearray(devreg); storearray=self.getstorearray(devreg);
i2c=self.conf['parentcls']; i2c=self.conf['parentcls'];
for RCUi in range(self.N): for RCUi in self.RCUorder:
if not(mask[RCUi]): continue if not(mask[RCUi]): continue
if not(self.I2Cmask[RCUi]<=self.I2Ccut): continue if not(self.I2Cmask[RCUi]<=self.I2Ccut): continue
self.SetSwitch(RCUi); self.SetSwitch(RCUi);
...@@ -187,6 +247,8 @@ class i2c_array(i2c_dev): ...@@ -187,6 +247,8 @@ class i2c_array(i2c_dev):
logging.debug(str(("Stored values:",self.getstorearray(devreg)))) logging.debug(str(("Stored values:",self.getstorearray(devreg))))
return True; return True;
def SetVarValue(self,devreg,width,bitoffset,value): 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 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))) logging.debug(str(("RCU1 Set ",self.RCUi,devreg['addr'],value)))
...@@ -250,3 +312,65 @@ class i2c_array(i2c_dev): ...@@ -250,3 +312,65 @@ class i2c_array(i2c_dev):
return True; return True;
def GetVarValuePar(self,devreg,width,bitoffset,value,buffer=False):
#setup self.mask, switch channels and self.RCUi before
logging.debug(str(("GetVarValueP",self.RCUi,devreg['addr'],value,buffer)))
# 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;
reg=devreg['register_R']
step2=len(value);
value2=[0]*self.N;
l1=int(np.floor((width+bitoffset+7)/8))
# print(width,bitoffset,l1)
#for x in range(self.N):
# value2[x*step2]=None; #default
if buffer:
if devreg.get('store'):
storearray=self.getstorearray(devreg,step2);
for x in self.mask:
value2[x*step2:(x+1)*step2]=storearray[x]
else:
if len(self.mask)<1: self.conf['parentcls'].UpdateNewChannel();
callback(devreg['addr'],int2bytes(reg),read=2)
for x in self.mask:
value3=value2[x*step2:(x+1)*step2]
self.SetSwitch(x);
callback(devreg['addr'],value3,read=1)
if devreg.get('store')==True:
storearray=self.getstorearray(devreg,step2);
storearray[x]=(value3[0] if step2==1 else value3[:])
value2[x*step2:(x+1)*step2]=value3;
# logging.debug(str(("Store buffer",self.RCUi,storearray[self.RCUi])))
# print("Stored values:",self.getstorearray(devreg))
logging.debug(str(("GetVarValueP",value2)))
if (width!=l1*8) or (bitoffset>0):
if (width<8):
for i in range(len(value2)):
value2[i]=UnMask(value2[i],width,bitoffset)
else:
value2[0]=UnMask(value2[0],width-(l1-1)*8,bitoffset) #not implemented correctly!!
logging.debug(str(("GetVarValueP2",value2)))
return value2;
def SetVarValuePar(self,devreg,width,bitoffset,value,buffer=False):
#setup self.mask, switch channels and self.RCUi before
if devreg['register_W']==-1: return True; #We can not set it, only read it e.g. temperature
logging.debug(str(("RCU1 Set Par ",self.RCUi,devreg['addr'],value)))
#self.parentcls.SetChannel(1<<RCU_Switch[RCUi]);
if devreg['store']:
storearray=self.getstorearray(devreg);
previous=storearray[self.RCUi];
# print(value,previous)
for x in range(len(value)):
value[x]=ApplyMask(value[x],width,bitoffset,(previous[x] if isinstance(previous,list) else previous));
for x in self.mask:
storearray[x]=(value[0] if len(value)==1 else value[:])
#print("buffer",devreg['addr'],devreg['register_W'],x,storearray[x])
# devreg['drivercls'].i2csetget
if buffer: return True;
if len(self.mask)>1: self.conf['parentcls'].UpdateNewChannel();
return devreg['drivercls'].i2csetget(devreg['addr'],value,reg=devreg['register_W'])
from enum import Enum
import logging
import numpy as np
from .hwdev import hwdev
import time
#This is copy of spibitbang. Need to be updated!!
class SPIBB_pins(Enum):
CLK = 0
SDA = 1
SDAdir = 2
class i2cbitbangp(hwdev):
def __init__(self,config):
hwdev.__init__(self,config)
self.N=len(self.conf['parameters'])//3;
def i2csetget(self,addr,data,reg=None,read=0):
logging.debug(str(("I2Cbbpset",addr,data,reg,read)));
if read==0:
if not(reg is None):
if reg>255: data=[reg//256,reg%256]+data;
else: data=[reg]+data;
if not(self.SetI2Cbb(addr,data)): return False;
return self.GetI2Cbb(addr,[]);
if read==2: return self.SetI2Cbb(addr,data)
elif read==1:
if not(reg is None):
if reg>255: reg=[reg//256,reg%256];
else: reg=[reg];
self.SetI2Cbb(addr,reg)
return self.GetI2Cbb(addr,data)
elif read==3:
time.sleep(data[0]/1000);
return True
else: logging.warn("Not implemented!")
return False;
def SetI2Cbb(self,address,value):
SDAdev=self.conf['devreg'][SPIBB_pins.SDA.value]
SDApin=[self.conf['parameters'][SPIBB_pins.SDA.value*self.N+x] for x in range(self.N)]
CLKdev=self.conf['devreg'][SPIBB_pins.CLK.value]
CLKpin=[self.conf['parameters'][SPIBB_pins.CLK.value*self.N+x] for x in range(self.N)]
DIRdev=self.conf['devreg'][SPIBB_pins.SDAdir.value]
DIRpin=[self.conf['parameters'][SPIBB_pins.SDAdir.value*self.N+x] for x in range(self.N)]
SetI2C=self.conf['parentcls'].SetVarValuePar
GetI2C=self.conf['parentcls'].GetVarValuePar
def SetReg(dev,pin,value):
# print("SetReg",pin,value)
for x in range(1,self.N):
SetI2C(dev,1,pin[x],value,buffer=True)
SetI2C(dev,1,pin[0],value,buffer=False)
def GetReg(dev,pin):
# print("SetReg",pin,value)
value=GetI2C(dev,1,pin[0],[0],buffer=False);
for x in range(1,self.N):
value+=GetI2C(dev,1,pin[x],[0],buffer=True)
# value=np.array(value).T
# print(value.shape)
return value
# ADC_address=dev.Register_W<<1; #Write
ADC_address=address<<1;#dev.Register_W<<1; #Write
logging.debug(str(("I2Cbb set",hex(ADC_address),value)))
SetReg(DIRdev,DIRpin,[1]) #Input = high
SetReg(CLKdev,CLKpin,[1]) #Should be high for start
#start
SetReg(SDAdev,SDApin,[0]) #Output = low
SetReg(DIRdev,DIRpin,[0]) #Output = low
SetReg(CLKdev,CLKpin,[0])
# ack=[0];
def TXbyte(b):
for bit in "{0:{fill}8b}".format(b, fill='0'):
SetReg(DIRdev,DIRpin,[int(bit)])
SetReg(CLKdev,CLKpin,[1])
SetReg(CLKdev,CLKpin,[0])
SetReg(DIRdev,DIRpin,[1]) #input
# GetI2C(SDAdev,1,SDApin,ack)
# print("Ack=",ack[0]);
SetReg(CLKdev,CLKpin,[1])
ack=GetReg(SDAdev,SDApin)
# print("Ack=",ack[0]);
SetReg(CLKdev,CLKpin,[0])
return ack;
ack=TXbyte(ADC_address);
#print(len(ack),ack)
for v in value:
TXbyte(v);
#stop
SetReg(DIRdev,DIRpin,[0]) #low
SetReg(CLKdev,CLKpin,[1]) #Should be high
SetReg(DIRdev,DIRpin,[1]) #Input = high
SetReg(CLKdev,CLKpin,[0]) #keep low between transmission to not generate stop/start when other i2c actice
return True;
def GetI2Cbb(self,reg_address,value):
SDAdev=self.conf['devreg'][SPIBB_pins.SDA.value]
SDApin=[self.conf['parameters'][SPIBB_pins.SDA.value*self.N+x] for x in range(self.N)]
CLKdev=self.conf['devreg'][SPIBB_pins.CLK.value]
CLKpin=[self.conf['parameters'][SPIBB_pins.CLK.value*self.N+x] for x in range(self.N)]
DIRdev=self.conf['devreg'][SPIBB_pins.SDAdir.value]
DIRpin=[self.conf['parameters'][SPIBB_pins.SDAdir.value*self.N+x] for x in range(self.N)]
SetI2C=self.conf['parentcls'].SetVarValuePar
GetI2C=self.conf['parentcls'].GetVarValuePar
def SetReg(dev,pin,value):
# print("SetReg",pin,value)
for x in range(1,self.N):
SetI2C(dev,1,pin[x],value,buffer=True)
SetI2C(dev,1,pin[0],value,buffer=False)
def GetReg(dev,pin):
# print("SetReg",pin,value)
value=[GetI2C(dev,1,pin[0],[0],buffer=False)];
for x in range(1,self.N):
value.append(GetI2C(dev,1,pin[x],[0],buffer=True))
value=np.array(value).T
#print(value.shape)
return value.flatten();
ADC_address=1+(reg_address<<1); #Read
logging.debug(str(("I2Cbb get",hex(ADC_address),len(value),value)))
SetReg(DIRdev,DIRpin,[1]) #Input = high
SetReg(CLKdev,CLKpin,[1]) #Should be high for start bit
#start
SetReg(SDAdev,SDApin,[0]) #Output = low
SetReg(DIRdev,DIRpin,[0]) #Output = low
SetReg(CLKdev,CLKpin,[0])
ack=[0];
def TXbyte(b):
for bit in "{0:{fill}8b}".format(b, fill='0'):
SetReg(DIRdev,DIRpin,[int(bit)])
SetReg(CLKdev,CLKpin,[1])
SetReg(CLKdev,CLKpin,[0])
SetReg(DIRdev,DIRpin,[1]) #input
# GetI2C(SDAdev,1,SDApin,ack)
# print("Ack=",ack[0]);
SetReg(CLKdev,CLKpin,[1])
ack=GetReg(SDAdev,SDApin)
# print("Ack=",ack[0]);
SetReg(SDAdev,SDApin,[0])
SetReg(CLKdev,CLKpin,[0])
return ack;
def RXbyte(last=False):
b=None;
for i in range(8):
SetReg(CLKdev,CLKpin,[1])
ack=GetReg(SDAdev,SDApin)
# print(ack[0])
# if ack[0] is None: b=None
# elif not b is None: b=(b<<1)+ack[0];
if b is None:
b=ack
else:
b=[(b[i]<<1)+ack[i] for i in range(len(ack))]
# print("RX step",b,ack)
SetReg(CLKdev,CLKpin,[0])
# print("RXbyte",hex(b));
SetReg(SDAdev,SDApin,[0])
SetReg(DIRdev,DIRpin,[1 if last else 0]) #outout = low = ack
SetReg(CLKdev,CLKpin,[1])
SetReg(CLKdev,CLKpin,[0])
SetReg(DIRdev,DIRpin,[1])
return b;
TXbyte(ADC_address);
status=RXbyte(last=(len(value)==0))
step=len(status);
step2=len(value)//step
# print("step=",step);
# if not(RXbyte()==0x80): return False;
for i in range(step2):
value2=RXbyte(last=(i==step2-1))
for j in range(step):
value[i+j*step2]=value2[j];
logging.debug(str(("si status:",[hex(s) for s in status],[hex(v) for v in value])))#should be 0x80 - will fail for None!!
#stop
#SetI2C(DIRdev,1,DIRpin,[0]) #low
SetReg(CLKdev,CLKpin,[1])
SetReg(DIRdev,DIRpin,[1]) #Input = high
SetReg(CLKdev,CLKpin,[0]) #keep low between transmission to not generate stop/start when other i2c actice
return True;
\ No newline at end of file
...@@ -15,8 +15,10 @@ class spibitbang1(hwdev): ...@@ -15,8 +15,10 @@ class spibitbang1(hwdev):
# logging.info("spibitbang todo") # logging.info("spibitbang todo")
def i2csetget(self,addr,data,reg=None,read=0): def i2csetget(self,addr,data,reg=None,read=0):
logging.debug(str(("spibitbang:",addr,data,reg,read)))
if read==0: return self.SetSPIbb(reg,data) if read==0: return self.SetSPIbb(reg,data)
elif read==1: return self.GetSPIbb(reg,data) elif read==1: return self.GetSPIbb(reg,data)
elif read==2: return self.GetSPIbb(data[0],None) #Set register in parallel
else: logging.warn("Not implemented!") else: logging.warn("Not implemented!")
return False; return False;
...@@ -62,35 +64,36 @@ class spibitbang1(hwdev): ...@@ -62,35 +64,36 @@ class spibitbang1(hwdev):
# print("SDO",SDOdev,SDOpin) # print("SDO",SDOdev,SDOpin)
# print("CLK",CLKdev,CLKpin) # print("CLK",CLKdev,CLKpin)
# print("DIR",SDIOdirdev,SDIOdirpin) # print("DIR",SDIOdirdev,SDIOdirpin)
logging.debug(str(("SPIbb get",ADC_reg_address))) logging.debug(str(("SPIbb get",ADC_reg_address,value)))
SetI2C=self.conf['parentcls'].SetVarValue
GetI2C=self.conf['parentcls'].GetVarValue
ADC_bytes = 0x00 ADC_bytes = 0x00
ADC_rw = 0x01 # 0 for write, 1 for read if not(ADC_reg_address is None):
ADC_rw = 0x01 # 0 for write, 1 for read
data = ( ADC_rw << 15) + ( ADC_bytes << 13 ) + ADC_reg_address data = ( ADC_rw << 15) + ( ADC_bytes << 13 ) + ADC_reg_address
SetI2C=self.conf['parentcls'].SetVarValue if not(SetI2C(CSdev,1,CSpin,[0])): return False #enable
GetI2C=self.conf['parentcls'].GetVarValue
if not(SetI2C(CSdev,1,CSpin,[0])): return False #enable
bit_array = "{0:{fill}16b}".format(data, fill='0') bit_array = "{0:{fill}16b}".format(data, fill='0')
#print("SPI TX bits",bit_array) #print("SPI TX bits",bit_array)
for bit in bit_array: for bit in bit_array:
SetI2C(SDOdev,1,SDOpin,[int(bit)]) SetI2C(SDOdev,1,SDOpin,[int(bit)])
SetI2C(CLKdev,1,CLKpin,[1]) SetI2C(CLKdev,1,CLKpin,[1])
SetI2C(CLKdev,1,CLKpin,[0]) SetI2C(CLKdev,1,CLKpin,[0])
SetI2C(CSdev,1,CSpin,[1]) #disable SetI2C(CSdev,1,CSpin,[1]) #disable
# print("read byte") # print("read byte")
SetI2C(SDIOdirdev,1,SDIOdirpin,[1]) #input if not(value is None):
SetI2C(CSdev,1,CSpin,[0]) #enable SetI2C(SDIOdirdev,1,SDIOdirpin,[1]) #input
a=[0] SetI2C(CSdev,1,CSpin,[0]) #enable
N=1;#len(value) a=[0]
ret_value=[0]; N=1;#len(value)
for i in range(N): value[i]=0 ret_value=[0];
for cnt in range(8*(ADC_bytes+1)): for i in range(N): value[i]=0
for cnt in range(8*(ADC_bytes+1)):
GetI2C(SDOdev,1,SDOpin,ret_value) #enable GetI2C(SDOdev,1,SDOpin,ret_value) #enable
# logging.debug("Got bit"+str((ret_value))) # logging.debug("Got bit"+str((ret_value)))
for i in range(N): for i in range(N):
...@@ -98,9 +101,9 @@ class spibitbang1(hwdev): ...@@ -98,9 +101,9 @@ class spibitbang1(hwdev):
elif not value[i] is None: value[i]=(value[i]<<1)+ ret_value[i] elif not value[i] is None: value[i]=(value[i]<<1)+ ret_value[i]
SetI2C(CLKdev,1,CLKpin,[1]) SetI2C(CLKdev,1,CLKpin,[1])
SetI2C(CLKdev,1,CLKpin,[0]) #read after falling edge SetI2C(CLKdev,1,CLKpin,[0]) #read after falling edge
SetI2C(CSdev,1,CSpin,[1]) #disable SetI2C(CSdev,1,CSpin,[1]) #disable
SetI2C(SDIOdirdev,1,SDIOdirpin,[0]) #output SetI2C(SDIOdirdev,1,SDIOdirpin,[0]) #output
# logging.debug(str(("SPIbb got",value))) logging.debug(str(("SPIbb got",value)))
return True; return True;
def GetSPIbb2(SetI2C,GetI2C,RCUi,SPIdev,I2Cdev,I2Cpins,value): def GetSPIbb2(SetI2C,GetI2C,RCUi,SPIdev,I2Cdev,I2Cpins,value):
......
...@@ -38,7 +38,7 @@ def si4012_6bytes_to_pwr_inv(data): ...@@ -38,7 +38,7 @@ def si4012_6bytes_to_pwr_inv(data):
pwr=(pwr-Reg0)/M pwr=(pwr-Reg0)/M
pwr-=Step/M*(pwr>75) pwr-=Step/M*(pwr>75)
pwr=int(pwr) pwr=int(pwr)
print(pwr) # print(pwr)
if pwr>=128: pwr+=128; if pwr>=128: pwr+=128;
pwr<<=32 pwr<<=32
# pwr+=0<<16 #Cap # pwr+=0<<16 #Cap
......
...@@ -201,6 +201,7 @@ class yamlreader(yamlconfig): ...@@ -201,6 +201,7 @@ class yamlreader(yamlconfig):
# print(notvalid) # print(notvalid)
for x in range(len(data)): for x in range(len(data)):
if data[x] is None: data[x]=0; if data[x] is None: data[x]=0;
# print(data)
if dtype=="boolean": if dtype=="boolean":
data2=[d==1 for d in data]; data2=[d==1 for d in data];
convert=v.get("convert_unit") convert=v.get("convert_unit")
...@@ -250,11 +251,12 @@ class yamlreader(yamlconfig): ...@@ -250,11 +251,12 @@ class yamlreader(yamlconfig):
logging.warn("OPC variable not found!!"); logging.warn("OPC variable not found!!");
return; return;
data3=var1.get_value(); data3=var1.get_value();
datatype=var1.get_data_value().Value.VariantType
if not(isinstance(data3,list)): data3=[data3]; if not(isinstance(data3,list)): data3=[data3];
# print("OPCset",v['name'],data2[:64],mask) # print("OPCset",v['name'],data2[:64],mask)
if mask: #Only update masked values if mask: #Only update masked values
step=len(data2)//len(mask) step=len(data2)//len(mask)
#print("mask step=",step) # print("mask step=",step,len(mask),len(data2),len(data3),data2)
for i in range(len(data2)): for i in range(len(data2)):
if mask[i//step]: data3[i]=data2[i] if mask[i//step]: data3[i]=data2[i]
else: else:
...@@ -263,7 +265,7 @@ class yamlreader(yamlconfig): ...@@ -263,7 +265,7 @@ class yamlreader(yamlconfig):
logging.info(str(("OPCset",v['name'],data3[:64]))) logging.info(str(("OPCset",v['name'],data3[:64])))
# if v['name']=='UNB2_FPGA_POL_ERAM_IOUT': logging.warn(str((data3,data2,mask,var1.get_value(),[hex(d) for d in data]))); # if v['name']=='UNB2_FPGA_POL_ERAM_IOUT': logging.warn(str((data3,data2,mask,var1.get_value(),[hex(d) for d in data])));
if len(data3)==1: data3=data3[0]; if len(data3)==1: data3=data3[0];
var1.set_value(data3); var1.set_value(data3,datatype);
def Monitor(self): def Monitor(self):
if self.monitorvar is None: return; if self.monitorvar is None: return;
...@@ -278,7 +280,7 @@ class yamlreader(yamlconfig): ...@@ -278,7 +280,7 @@ class yamlreader(yamlconfig):
if v.get('monitor'): if v.get('monitor'):
mask=(v['maskOPC'].get_value() if v.get('maskOPC') else []) mask=(v['maskOPC'].get_value() if v.get('maskOPC') else [])
# print("monitor",v['name'],mask) # print("monitor",v['name'],mask)
self.SetBusy() # self.SetBusy()
self.server.readvar(self.monitorvarcnt,mask=mask) self.server.readvar(self.monitorvarcnt,mask=mask)
self.monitorvarcnt+=1; self.monitorvarcnt+=1;
if self.monitorvarcnt>=len(self.conf['variables']): if self.monitorvarcnt>=len(self.conf['variables']):
......
from test_common import *
import numpy as np
RCU=[0,1,2,3,4,5,6,7,8,9,10];
connect()
setAntmask(RCU)
setRCUmask(RCU)
callmethod("RCU_DTH_stop")
disconnect()
\ No newline at end of file
from test_common import * from test_common import *
import numpy as np import numpy as np
RCU=[0]; RCU=[0,1,2,3,4,5,6,7,8,9,10];
connect() connect()
setAntmask(RCU) setAntmask(RCU)
setRCUmask(RCU) setRCUmask(RCU)
#call_debug_method("DTH_off") #call_debug_method("DTH_off")
FRCU=0.05; FRCU=0.05*0;
FCH=0.425; FCH=0.425*0;
#F0=101.0 #F0=101.0
F0=97.0 F0=97.0
name="RCU_DTH_freq" name="RCU_DTH_freq"
if False: if True:
att=get_value(name+"_R") att=get_value(name+"_R")
print("freq old:",att[3*RCU[0]:3*RCU[-1]+3]) print("freq old:",att[3*RCU[0]:3*RCU[-1]+3])
...@@ -29,7 +29,7 @@ if False: ...@@ -29,7 +29,7 @@ if False:
name="RCU_DTH_PWR" name="RCU_DTH_PWR"
Pwr=-40.0 Pwr=-40.0
if False: if True:
att=get_value(name+"_R") att=get_value(name+"_R")
print("pwr old:",att[3*RCU[0]:3*RCU[-1]+3]) print("pwr old:",att[3*RCU[0]:3*RCU[-1]+3])
...@@ -42,7 +42,7 @@ if False: ...@@ -42,7 +42,7 @@ if False:
att=get_value(name+"_R") att=get_value(name+"_R")
print("pwr new :",att[3*RCU[0]:3*RCU[-1]+3]) print("pwr new :",att[3*RCU[0]:3*RCU[-1]+3])
#callmethod("RCU_DTH_on") callmethod("RCU_DTH_on")
callmethod("RCU_DTH_off") #callmethod("RCU_DTH_stop")
disconnect() disconnect()
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment