diff --git a/config/RCU_uC_test.yaml b/config/RCU_uC_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2e7d4cf6427dac89ba2775bd4346b7e8a42c3f6c --- /dev/null +++ b/config/RCU_uC_test.yaml @@ -0,0 +1,332 @@ +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. + devreg: [0x40.0xFF] #I2C broadcast register + parameters: [23] #PPS GPIO pin + 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.0xFF] #I2C broadcast register +# parameters: [23] #PPS GPIO pin +# parent: I2C_HBAT + +#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: HBA_uC_Timeout_RXTX + description: Time waiting for replay from tile + driver: I2C_RCU + devreg: HB_UC.8 + width: 16 + endian: "<" + rw: rw + dtype: uint16 + dim: 32 + mask: RCU_mask + debug: True + wait: 10 #ms + + - name: HBA_uC_wait_PPS + description: wait for PPS after receiving signals + driver: I2C_RCU + devreg: HB_UC.12 + width: 1 + rw: rw + dtype: boolean + dim: 32 + mask: RCU_mask + debug: True + + - 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: PPS + + - name: HBA_element_led + description: LED of each frontend + driver: I2C_HBAT + devreg: [HBAT1.XY,HBAT2.XY,HBAT3.XY] + bitoffset: 0 + width: 1 + rw: rw + dtype: boolean + dim: 3072 + mask: Ant_mask + wait: 100 #ms +# debug: True + + - name: HBA_element_pwr + description: power + driver: I2C_HBAT + devreg: [HBAT1.XY,HBAT2.XY,HBAT3.XY] + bitoffset: 7 + width: 1 + rw: rw + dtype: boolean + dim: 3072 + mask: Ant_mask + wait: 100 #ms +# debug: True + + - name: HBA_element_LNA_pwr + description: frontend power of each frontend + driver: I2C_HBAT + devreg: [HBAT1.XY,HBAT2.XY,HBAT3.XY] + bitoffset: 1 + width: 1 + rw: rw + dtype: boolean + dim: 3072 + mask: Ant_mask + wait: 100 #ms +# debug: True + + +methods: + - name: RCU_Init #Called after startup to load. Should have all stored registers + driver: I2C_RCU + debug: True + instructions: + - RCU_UC_Load: 0 + + - name: RCU_UC_Load + driver: I2C_RCU + debug: True + instructions: + - HBA_uC_Timeout_RXTX: Update + - HBA_uC_wait_PPS: Update + + - name: RCU_off + driver: I2C_RCU + mask: RCU_mask + instructions: + - RCU_I2C_STATUS: 0 +# - 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. + diff --git a/i2cserv/gpio_hba_trigger.py b/i2cserv/gpio_hba_trigger.py index 452f5630af6bde50e9e1f6daeba798e6fd22634e..cf77c9c9a2b57398c59937454e102f1469f48e54 100644 --- a/i2cserv/gpio_hba_trigger.py +++ b/i2cserv/gpio_hba_trigger.py @@ -1,4 +1,4 @@ -from .hwdev import hwdev; +from .hba1 import hba1; import logging import signal try: @@ -6,23 +6,37 @@ try: except: GPIO=False; -class gpio_hba_trigger(hwdev): +class gpio_hba_trigger(hba1): def __init__(self,config): - hwdev.__init__(self,config); + hba1.__init__(self,config); self.pin=config['parameters'][0]; - logging.info("HBAT wait for PPS on pin %i",self.pin) + self.addr=config['devreg'][0]['addr'] + self.reg=config['devreg'][0]['register_R'] + logging.info("HBAT wait for PPS on pin %i, TX=%i:%i",self.pin,self.addr,self.reg) 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) + 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 + channel=GPIO.wait_for_edge(self.pin,GPIO.RISING,timeout=1500) + self.conf['parentcls'].i2csetget(self.addr,[],self.reg,0) + if channel is None: + logging.info("PPS not received!"); +# return False; + 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) and GPIO: +# self.conf['parentcls'].i2csetget(addr,data,reg,read) diff --git a/i2cserv/hba1.py b/i2cserv/hba1.py index 1a0524b35767457a6b60a237ab7775bfcf3e2fb1..bca60ab34931d00c832568e2a9d5a3fc90c9e701 100644 --- a/i2cserv/hba1.py +++ b/i2cserv/hba1.py @@ -4,18 +4,39 @@ import logging from .i2c_array import ApplyMask from time import sleep from queuetypes import * +import signal +try: + import RPi.GPIO as GPIO +except: + GPIO=False; 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') + self.pin=config['parameters'][0]; + self.addr=config['devreg'][0]['addr'] + self.reg=config['devreg'][0]['register_R'] + if GPIO: + GPIO.setmode(GPIO.BCM) + GPIO.setup(self.pin,GPIO.IN) + logging.info("HBAT wait for PPS on pin %i, TX=%i:%i",self.pin,self.addr,self.reg) + else: + logging.warn("RPi GPIO module not found, PPS input disable!") 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'): + if var1.get('wait')=="PPS": + channel=GPIO.wait_for_edge(self.pin,GPIO.RISING,timeout=1500) + self.conf['parentcls'].i2csetget(self.addr,[],self.reg,0) + if channel is None: + logging.info("PPS not received!"); + sleep(0.5) +# return False; + elif var1.get('wait'): logging.debug("Wait %i ms",var1.get('wait')) sleep(var1['wait']/100.) data,mask2=self.conf['parentcls'].GetVarValueMask(var1,mask) diff --git a/i2cserv/i2c_dev.py b/i2cserv/i2c_dev.py index 2f73afaad2f28220342175219b4b1ad2d80c8de4..2dc3673acf358a757a4bb94bfc5d02974a325d77 100644 --- a/i2cserv/i2c_dev.py +++ b/i2cserv/i2c_dev.py @@ -89,7 +89,7 @@ class i2c_dev(hwdev): 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))) + logging.info(str(("Set Var",var1['name'],data[:32],mask))) if (var1['rw']=='variable') or not(var1.get('devreg')): if varid==self.I2Cmaskid: if len(mask)==0: mask=[True]*len(data); diff --git a/scripts/SetHBAT_BFs.py b/scripts/SetHBAT_BFs.py index 7f64d0f959f73de0e0bccbe2cce24bfa62503254..425cd6bc0baba584865969d5871b5c9ab313407f 100644 --- a/scripts/SetHBAT_BFs.py +++ b/scripts/SetHBAT_BFs.py @@ -1,11 +1,11 @@ RCU=0 -#HBAT=1 #HBAT on RCU 0..2 -#HBA=5; #HBA Element in HBAT -#BFX=11 #delay in 0.5ns -#BFY=BFX+1 name="HBA_element_beamformer_delays" AntMask=[True,True,True] -NewVal=[2]*64 +NewVal1=range(32) +NewVal2=[1]*32 +NewValues=[NewVal1,NewVal2,NewVal1,NewVal2,NewVal1,NewVal2,NewVal1,NewVal2,NewVal1,NewVal2] +#NewValues=[NewVal1,NewVal2] +DEBUG=False from test_common import * import numpy as np @@ -15,16 +15,31 @@ setAntmask([RCU],AntMask) i=(RCU*3)*32 val=get_value(name+"_R") -print("old:",val[i:i+64]) - -val[i:i+64]=NewVal - -set_value(name+"_RW",val) -print("set:",val[i:i+64]) -time.sleep(2) -val=get_value(name+"_R") -print("new:",val[i:i+64]) - +if DEBUG: + print("Current values:"); + for x in range(3): print(val[i+x*32:i+(x+1)*32]) + +for cnt,NewVal in enumerate(NewValues): + + for x in range(3): val[i+x*32:i+(x+1)*32]=NewVal + + set_value(name+"_RW",val) + if DEBUG: + print("set:") + for x in range(3): print(val[i+x*32:i+(x+1)*32]) + time.sleep(0.4) + wait_not_busy("RCU_translator_busy_R",timeout_sec=2) +# time.sleep(0.1) + val=get_value(name+"_R") + if DEBUG: + print("readback:") + for x in range(3): print(val[i+x*32:i+(x+1)*32]) + + same=True; + for x in range(3): + for y in range(32): + if not(val[i+x*32+y]==NewVal[y]): same=False; + print(cnt+1,"Success" if same else "FAILED!") #time.sleep(5) #val[i:i+64]=[0]*64 diff --git a/scripts/SetHBAT_LEDs.py b/scripts/SetHBAT_LEDs.py new file mode 100644 index 0000000000000000000000000000000000000000..a625466950f19ea008637880b570aaec19160d5c --- /dev/null +++ b/scripts/SetHBAT_LEDs.py @@ -0,0 +1,37 @@ +RCU=0 +#HBAT=1 #HBAT on RCU 0..2 +#HBA=5; #HBA Element in HBAT +#BFX=11 #delay in 0.5ns +#BFY=BFX+1 +name="HBA_element_led" +AntMask=[True,True,True] +NewVal=[True]*64 + +from test_common import * +import numpy as np + +setAntmask([RCU],AntMask) + +i=(RCU*3)*32 + +val=get_value(name+"_R") +print("old:",val[i:i+64]) + +val[i:i+64]=NewVal + +set_value(name+"_RW",val) +print("set:",val[i:i+64]) +time.sleep(2) +val=get_value(name+"_R") +print("new:",val[i:i+64]) + +#time.sleep(5) +#val[i:i+64]=[0]*64 + +#set_value(name+"_RW",val) +#print("set:",val[i:i+64]) +#time.sleep(1) +#val=get_value(name+"_R") +#print("new:",val[i:i+64]) + +disconnect() diff --git a/scripts/SetHBAT_PPS.py b/scripts/SetHBAT_PPS.py new file mode 100644 index 0000000000000000000000000000000000000000..2660fc2ce4b1bd811918a9985ca9355a903bdf6f --- /dev/null +++ b/scripts/SetHBAT_PPS.py @@ -0,0 +1,22 @@ +RCU=[0] +name="HBA_uC_wait_PPS" +NewVal=True + +from test_common import * +import numpy as np + +setRCUmask(RCU) + + +val=get_value(name+"_R") +print("old:",val) +for r in RCU: + val[r]=NewVal + +set_value(name+"_RW",val) +print("set:",val) +time.sleep(0.1) +val=get_value(name+"_R") +print("new:",val) + +disconnect() diff --git a/scripts/pps_generator.py b/scripts/pps_generator.py new file mode 100644 index 0000000000000000000000000000000000000000..8c5567fd74daa0d105148cd8abf5ee81f5263e4c --- /dev/null +++ b/scripts/pps_generator.py @@ -0,0 +1,13 @@ +import RPi.GPIO as GPIO +import time +PIN=24 + +GPIO.setmode(GPIO.BCM) +GPIO.setup(PIN,GPIO.OUT) + +while True: + GPIO.output(PIN,GPIO.LOW) + time.sleep(0.5) + GPIO.output(PIN,GPIO.HIGH) + time.sleep(0.5) +# print('*') diff --git a/scripts/pps_test.py b/scripts/pps_test.py new file mode 100644 index 0000000000000000000000000000000000000000..c1d966830e650d2654fdc268f25791e7bfc26721 --- /dev/null +++ b/scripts/pps_test.py @@ -0,0 +1,10 @@ +import RPi.GPIO as GPIO +import time +PIN=23 + +GPIO.setmode(GPIO.BCM) +GPIO.setup(PIN,GPIO.IN) + +for x in range(3): + channel=GPIO.wait_for_edge(PIN,GPIO.RISING,timeout=1500) + print("Timeout!" if channel is None else "PPS")