diff --git a/bin/recvtr b/bin/recvtr index 12b6b6bd0616d552ae9ee2e50f41894c0a337fbd..7ef1ddf8a1e6e5326189391254531cb6771495bc 100755 --- a/bin/recvtr +++ b/bin/recvtr @@ -1,2 +1,2 @@ #!/bin/bash -hwtr -p 4840 -c RECVTR,PPS +hwtr -p 4840 -c RECVTR_HB,RECVTR_LB,PPS diff --git a/pypcc/config/RECVTR_HB.yaml b/pypcc/config/RECVTR_HB.yaml index 47088dc96da97ac7f57efc4d2335522a08501005..cf1a8731f9433d0870454bb5cd3edd9eaecc917a 100644 --- a/pypcc/config/RECVTR_HB.yaml +++ b/pypcc/config/RECVTR_HB.yaml @@ -1,5 +1,6 @@ version: "1.0" description: "1234" +name: "RECVTR" drivers: - name: I2C1 #TCA9548 @@ -9,29 +10,38 @@ drivers: - name: I2C_RCU type: i2c_array #An array of similar devices connected to an I2C switch parent: I2C1 - parameters: [20,22,0,2,4,6,10,12,14,16,18,24,26,28,30,8,7,5,3,1,23,21,19,13,11,9,15,17,31,29,27,25] #RCU lookup table - I2Ccut: 5 #error count to disable I2C (14 for LTS?) +# parameters: [20,22,0,2, 4,6,10,12, 14,16,18,24, 26,28,30,8, 7,5,3,1, 23,21,19,13, 11,9,15,17, 31,29,27,25] #RCU lookup table + parameters: [32,32,32,32 ,32,32,32,32 ,32,32,32,32 ,32,32,32,32 ,7,32,32,32 ,32,32,32,32 ,32,32,32,32 ,32,32,32,32] #RCU lookup table +# parameters: [20,22,0,2,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32] #RCU lookup table +# parameters: [22,0,2,4,6,10,22,0,2,4,6,10,22,0,2,4,6,10,22,0,2,4,6,10,22,0,2,4,6,10,22,0]#repeat 1..7 for RCUH BF test +# 12,14,16,18,24,26,28,30,8,7,5,3,1,23,21,19,13,11,9,15,17,31,29,27,25] #RCU lookup table + I2Ccut: 35 #error count to disable I2C (14 for LTS?) status: RECVTR_I2C_error - name: I2C_HBAT type: hba1 #Special driver to manage HBAT1s. parent: I2C_RCU - devreg: [0x40.0x10] #I2C broadcast register + devreg: [0x40.0xFF] #I2C broadcast register parameters: [24] #PPS GPIO pin - name: I2Cbb1 - type: i2cbitbang1 #I2C bitbang via GPIO expander + type: i2cbitbangp #I2C bitbang via GPIO expander devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2] parameters: [5,6,6] #pins parent: I2C_RCU - name: I2Cbb2 - type: i2cbitbang1 + type: i2cbitbangp devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2] parameters: [4,6,6] parent: I2C_RCU - name: I2Cbb3 - type: i2cbitbang1 + type: i2cbitbangp devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2] parameters: [3,6,6] 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 type: spibitbang1 #SPI bitbang via GPIO expander: CLK, SDIO, SDIOdir,CS devreg: [IO3.GPIO1,IO3.GPIO1,IO3.CONF1,IO3.GPIO2] @@ -47,6 +57,12 @@ drivers: devreg: [IO3.GPIO1,IO3.GPIO1,IO3.CONF1,IO3.GPIO2] parameters: [5,4,4,2] 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 # type: gpio_hba_trigger # parameters: [15] #PPS GPIO pin @@ -78,6 +94,10 @@ device_registers: description: Input/Ouput port 2 address: [1,3] store: True + - name: DIR1 + address: 4 + - name: DIR2 + address: 5 - name: ROM description: IO-Expander for filter selection @@ -133,17 +153,17 @@ device_registers: 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: "waitPPS", address: 12, description: "1=wait for PPS"} + - { name: "VREF", address: 13, description: "0..15/16 ratio of Vref"} + - { name: "firmware", address: 0x10, description: "software version"} + +# - name: HB_UC_update +# description: RCU microcontroller +# address: 0x40 +# driver: HBA_trigger +# registers: +# - name: wait_pps +# address: 10 - name: HBAT dim: 3 @@ -154,7 +174,7 @@ device_registers: - name: XY address: 0x10 description: XY delay register - store: True + store: "w" #only store on write - name: Version address: 127 description: HBAT server version @@ -179,6 +199,16 @@ device_registers: - name: Update description: Global device uptate address: 0xFF + - name: testmode + address: 0x0D + - name: dither + address: 0x0C + - name: JESDscramble + address: 0x6E + - name: PDWNmodes + address: 0x08 + - name: DCcorrect + address: 0x40 - name: DTH dim: 3 @@ -207,6 +237,9 @@ device_registers: address: [0x1221,0x1121] - name: CONF address: [0x1210,0x1110] + - name: PA_CONFIG + address: [0x1260,0x1160] + store: True variables: - name: RECVTR_monitor_rate @@ -264,7 +297,7 @@ variables: mask: ANT_mask - name: RCU_band_select - description: Band select ... + description: Band select for highband 2,1,4 for 110-190,170-230,210-240 driver: I2C_RCU devreg: [IO2.GPIO2,IO2.GPIO2,IO4.GPIO2] bitoffset: [0,3,0] @@ -275,21 +308,9 @@ variables: dim2: [3,32] mask: ANT_mask - - name: RCU_DAB_select - description: Band select ... + - name: [RCU_IO1_GPIO1,RCU_IO1_GPIO2,RCU_IO2_GPIO1,RCU_IO2_GPIO2,RCU_IO3_GPIO1,RCU_IO3_GPIO2] driver: I2C_RCU - devreg: [IO4.GPIO1,IO4.GPIO1,IO4.GPIO1] - bitoffset: [0,2,4] - width: 2 - rw: rw - dtype: uint8 - dim: 96 - dim2: [3,32] - mask: ANT_mask - - - name: [RCU_IO1_GPIO1,RCU_IO1_GPIO2,RCU_IO2_GPIO1,RCU_IO2_GPIO2,RCU_IO3_GPIO1,RCU_IO3_GPIO2,RCU_IO4_GPIO1,RCU_IO4_GPIO2] - driver: I2C_RCU - devreg: [IO1.GPIO1,IO1.GPIO2,IO2.GPIO1,IO2.GPIO2,IO3.GPIO1,IO3.GPIO2,IO4.GPIO1,IO4.GPIO2] + devreg: [IO1.GPIO1,IO1.GPIO2,IO2.GPIO1,IO2.GPIO2,IO3.GPIO1,IO3.GPIO2] width: 8 rw: ro dtype: uint8 @@ -379,7 +400,7 @@ variables: driver: I2C_RCU devreg: [AN.V_Ant_O0,AN.V_Ant_O1,AN.V_Ant_O2] width: 23 - scale: 1.43051e-5 #LB: 2.7895e-6 + scale: 2.7895e-6 rw: ro dtype: double dim: 96 @@ -393,7 +414,7 @@ variables: driver: I2C_RCU devreg: [AN.V_Ant_I0,AN.V_Ant_I1,AN.V_Ant_I2] width: 23 - scale: 1.43051e-5 #LB: 2.7895e-6 + scale: 2.7895e-6 rw: ro dtype: double dim: 96 @@ -403,7 +424,7 @@ variables: mask: RECVTR_I2C_error - name: RCU_PWR_ANT_IOUT - description: Current drawn on antenna output of RCU (A) + description: Current drawn on antenna output of RCU (A). 15mA offset due to LED on RCU driver: I2C_RCU devreg: [AN.I_Ant0,AN.I_Ant1,AN.I_Ant2] width: 23 @@ -422,7 +443,7 @@ variables: devreg: IO2.GPIO1 width: 1 bitoffset: 6 - rw: ro + rw: ro #rw for testing dtype: boolean dim: 32 mask: RCU_mask @@ -451,12 +472,12 @@ variables: mask: RCU_mask - 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 devreg: [IO3.GPIO1,IO3.GPIO1,IO3.GPIO2] width: 1 bitoffset: [7,6,7] - rw: rw + rw: ro dtype: boolean dim: 96 dim2: [3,32] @@ -475,31 +496,6 @@ variables: dim2: [3,32] mask: ANT_mask - - name: HBAT_BF_delay_steps - description: HBAT1 frontend delays (0.5ns steps) - driver: I2C_HBAT - devreg: [HBAT1.XY,HBAT2.XY,HBAT3.XY] - bitoffset: [2,2,2] - width: 5 - rw: rw - dtype: uint8 - dim: 3072 - dim2: [32,96] - mask: ANT_mask - wait: PPS #1500 #ms neads to readback after send, which is after next PPS - - - name: [HBAT_LED_on,HBAT_PWR_on,HBAT_PWR_LNA_on] - description: HBA frontend control - driver: I2C_HBAT - devreg: [HBAT1.XY,HBAT2.XY,HBAT3.XY] - bitoffset: [0,7,1] - width: 1 - rw: rw - dtype: boolean - dim: 3072 - dim2: [32,96] - mask: ANT_mask - wait: 100 #ms - name: RCU_PCB_ID description: Unique PCB ID @@ -530,6 +526,7 @@ variables: dtype: string dim: 32 mask: RCU_mask + - name: RCU_ADC_locked description: RCU ADC lock status. May generated noise and polling disabled in future @@ -540,7 +537,8 @@ variables: dtype: boolean dim: 96 dim2: [3,32] - monitor: true +# monitor: true + read_parallel: true - name: RCU_ADC_sync driver: I2C_RCU @@ -582,28 +580,21 @@ variables: dim: 96 dim2: [3,32] mask: ANT_mask + read_parallel: all - - name: RCU_DTH_tune + - name: RCU_DTH_PWR + description: RCU Dither source power driver: I2C_RCU - devreg: [DTH1.Tune,DTH2.Tune,DTH3.Tune] - width: 16 + devreg: [DTH1.PA_CONFIG,DTH2.PA_CONFIG,DTH3.PA_CONFIG] + width: 48 rw: rw - dtype: uint32 - dim: 96 - dim2: [3,32] - mask: ANT_mask - debug: true - - - name: RCU_DTH_config - driver: I2C_RCU - devreg: [DTH1.CONF,DTH2.CONF,DTH3.CONF] - width: 8 - rw: rw - dtype: uint32 + dtype: double + scale: si4012_6bytes_to_pwr dim: 96 dim2: [3,32] mask: ANT_mask - debug: true + read_parallel: all +# debug: true - name: RCU_DTH_on description: RCU Dither on. Controlled by RCU_DTH_on/off @@ -616,17 +607,96 @@ variables: dim: 96 dim2: [3,32] mask: ANT_mask + read_parallel: all + - - name: RCU_DTH_Rev +#RCU2H points + - name: RCU_DAB_select + description: Band select ... driver: I2C_RCU - devreg: [DTH1.Rev,DTH2.Rev,DTH3.Rev] - width: 88 + devreg: [IO4.GPIO1,IO4.GPIO1,IO4.GPIO1] + bitoffset: [0,2,4] + width: 2 rw: rw - dtype: uint32 + dtype: uint8 dim: 96 dim2: [3,32] mask: ANT_mask - debug: true + + - name: RCU_firmware_version + description: git firmware version + driver: I2C_RCU + devreg: HB_UC.firmware + width: 32 + rw: ro + dtype: uint32 + endian: "<" + dim: 32 + mask: RCU_mask + +#HBAT points + - name: HBAT_BF_delay_steps + description: HBAT1 frontend delays (0.5ns steps) + driver: I2C_HBAT + devreg: [HBAT1.XY,HBAT2.XY,HBAT3.XY] + bitoffset: [2,2,2] + width: 5 + rw: rw + dtype: uint8 + dim: 3072 + dim2: [32,96] + mask: ANT_mask + wait: PPS +# wait: 1000 #ms + + - name: [RCU_IO4_GPIO1,RCU_IO4_GPIO2] + driver: I2C_RCU + devreg: [IO4.GPIO1,IO4.GPIO2] + width: 8 + rw: ro + dtype: uint8 + dim: 32 + mask: RCU_mask + debug: True + + + - name: HBAT_LED_on + description: HBA frontend control + driver: I2C_HBAT + devreg: [HBAT1.XY,HBAT2.XY,HBAT3.XY] + bitoffset: 0 + width: 1 + rw: rw + dtype: boolean + dim: 3072 + dim2: [32,96] + mask: ANT_mask + wait: 100 #ms + - name: HBAT_PWR_LNA_on + description: HBA frontend control + driver: I2C_HBAT + devreg: [HBAT1.XY,HBAT2.XY,HBAT3.XY] + bitoffset: 7 + width: 1 + rw: rw + dtype: boolean + dim: 3072 + dim2: [32,96] + mask: ANT_mask + wait: 100 #ms + - name: HBAT_PWR_on + description: HBA frontend control + driver: I2C_HBAT + devreg: [HBAT1.XY,HBAT2.XY,HBAT3.XY] + bitoffset: 1 + width: 1 + rw: rw + dtype: boolean + convert_unit: bool_invert + dim: 3072 + dim2: [32,96] + mask: ANT_mask + wait: 100 #ms methods: - name: RECVTR_Init #Called after startup to load. Should have all stored registers @@ -639,8 +709,6 @@ methods: - RCU_IO2_GPIO2: Update - RCU_IO3_GPIO1: Update - RCU_IO3_GPIO2: Update - - RCU_IO4_GPIO1: Update - - RCU_IO4_GPIO2: Update # - IO1.GPIO2: Update # - IO2.GPIO1: Update # - IO2.GPIO2: Update @@ -648,6 +716,10 @@ methods: # - IO3.GPIO2: Update - IO3.CONF1: Update - 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_GPIO2: Update - name: RCU_on description: Initialize RCU and it in the ON state @@ -658,6 +730,8 @@ methods: - IO2.CONF1: 0x80 #Pgood on 0x80 - IO2.GPIO1: 0x4A #0x40 Dig on, 0x0a =10dB att - IO2.GPIO2: 0x52 #0x09 #Band0 (or 0x12 or 0x24) #LED green=on=low 0x40 +# - IO3.GPIO1: 0xD5 #ADC_SDIO=high, clk=low, DTH_EN=high +# - IO3.GPIO2: 0xC7 #ADC SC=high, DTH_SDA=high - IO3.GPIO1: 0x15 #ADC_SDIO=high, clk=low, DTH_EN=low - IO3.GPIO2: 0x47 #ADC SC=high, DTH_SDA=high - IO1.GPIO1: 0x0A #0x0a = 10dB att @@ -665,21 +739,35 @@ methods: - IO2.CONF2: 0 - IO3.CONF1: 0 - IO3.CONF2: 0 + - IO3.DIR1: 0 + - IO3.DIR2: 0 - IO1.CONF1: 0 - IO1.CONF2: 0 - IO4.CONF1: 0xC0 #pin 0x40, 0x80 not used - IO4.CONF2: 0xF8 - IO4.GPIO1: 0x2A #DAB switch states: 0x2A or 0x51 - IO4.GPIO2: 0x02 #Band select + - HB_UC.waitPPS: 1 #wait for PPS + - HB_UC.VREF: 0x0C + + - RCU_update: 0 # - RCU_GPIO1: Update # - RCU_GPIO2: Update # - RCU_attenuator: [10,10,10] #Set OPC-UA variable - - WAIT: 500 #ms to wait +# - 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 +# - IO3.GPIO1: 0xD5 #DTH_EN=high -> ADCs disables +# - IO3.GPIO2: 0xC7 # + - RCU_DTH_shutdown : [1,1,1] + - WAIT: 100 #ms to wait + - RCU_DTH_shutdown : [0,0,0] +# - IO3.GPIO1: 0x15 #DTH_EN=low -> ADC enabled +# - IO3.GPIO2: 0x47 + - RCU_DTH_on: Update #check dither while giving ADCs some time to lock + - RCU_ADC_locked: Update #disabled for testing + - name: RCU_update driver: I2C_RCU @@ -696,12 +784,23 @@ methods: - RCU_LED_green_on: Update - RCU_attenuator_dB: Update - RCU_band_select: Update +# - RCU_ADC_locked: Update #disabled for testing +# - RCU_ADC_sync: Update #disabled for testing +# - RCU_DTH_shutdown: Update +# - RCU_DTH_freq: Update +# - RCU_DTH_on: Update #disabled for testing +# - RCU_hband_select: Update - RCU_DAB_select: Update - - RCU_ADC_locked: Update - - RCU_ADC_sync: Update - - RCU_DTH_shutdown: Update - - RCU_DTH_freq: Update - - RCU_DTH_on: Update + - RCU_firmware_version: Update + - RCU_IO1_GPIO1: Update #needed for debug/testing + - RCU_IO1_GPIO2: Update + - RCU_IO2_GPIO1: Update + - RCU_IO2_GPIO2: Update + - RCU_IO3_GPIO1: Update + - RCU_IO3_GPIO2: Update + - RCU_IO4_GPIO1: Update + - RCU_IO4_GPIO2: Update + - name: ADC1_on driver: I2C_RCU @@ -711,6 +810,7 @@ methods: - ADC1.JESD_control1 : 0x14 - ADC1.SYNC_control: 1 #Setup ADCs - ADC1.CML_level: 0x7 + - ADC1.dither : 0x00 - ADC1.Update: 1 #Needed to update ADC registers - name: ADC2_on @@ -721,6 +821,7 @@ methods: - ADC2.JESD_control1 : 0x14 - ADC2.SYNC_control: 1 #Setup ADCs - ADC2.CML_level: 0x7 + - ADC2.dither : 0x00 - ADC2.Update: 1 #Needed to update ADC registers - name: ADC3_on @@ -731,6 +832,7 @@ methods: - ADC3.JESD_control1 : 0x14 - ADC3.SYNC_control: 1 #Setup ADCs - ADC3.CML_level: 0x7 + - ADC3.dither : 0x00 - ADC3.Update: 1 #Needed to update ADC registers - name: RCU_off @@ -750,14 +852,14 @@ methods: - 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 +# - 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 - name: RCU_DTH_on @@ -766,12 +868,15 @@ methods: mask: RCU_mask # rw: hidden instructions: - - RCU_DTH_config : [0,0,0] - - RCU_DTH_config: Update #debug +# - RCU_DTH_config : [0,0,0] +# - 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 - DTH2.Tune : [0,0] #no tuning - DTH3.Tune : [0,0] #no tuning - - RCU_DTH_tune: Update #debug +# - RCU_DTH_tune: Update #debug - DTH1.Start : [0,1,0,0,1] - DTH2.Start : [0,1,0,0,1] - DTH3.Start : [0,1,0,0,1] @@ -793,4 +898,17 @@ methods: # - DTH1.State : [0,0] # - DTH2.State : [0,0] # - DTH3.State : [0,0] - - RCU_DTH_on: Update +# - RCU_DTH_on: Update + + - name: RCU_DTH_restart #restart to update frequency + driver: I2C_RCU + mask: RCU_mask + debug: True + instructions: + - DTH1.Stop : [0,0] + - DTH2.Stop : [0,0] + - DTH3.Stop : [0,0] + - DTH1.Start : [0,1,0,0,1] + - DTH2.Start : [0,1,0,0,1] + - DTH3.Start : [0,1,0,0,1] + diff --git a/pypcc/config/RECVTR_LB.yaml b/pypcc/config/RECVTR_LB.yaml index dfd4251299bc28c18498ac74b31c38d736903cf7..5f73fcbd3c7711c59948a49373ec1b2986c2663f 100644 --- a/pypcc/config/RECVTR_LB.yaml +++ b/pypcc/config/RECVTR_LB.yaml @@ -1,5 +1,6 @@ version: "1.0" description: "1234" +name: "RECVTR" drivers: - name: I2C1 #TCA9548 @@ -9,29 +10,33 @@ drivers: - name: I2C_RCU type: i2c_array #An array of similar devices connected to an I2C switch parent: I2C1 - parameters: [20,22,0,2,4,6,10,12,14,16,18,24,26,28,30,8,7,5,3,1,23,21,19,13,11,9,15,17,31,29,27,25] #RCU lookup table - I2Ccut: 5 #error count to disable I2C (14 for LTS?) +# parameters: [20,22,0,2, 4,6,10,12, 14,16,18,24, 26,28,30,8, 7,5,3,1, 23,21,19,13, 11,9,15,17, 31,29,27,25] #RCU lookup table + parameters: [32,32,32,32 ,32,32,32,32 ,32,32,32,32 ,32,32,32,32 ,32,32,32,1 ,32,32,32,32 ,32,32,32,32 ,32,32,32,32] #RCU lookup table +# parameters: [20,22,0,2,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32] #RCU lookup table +# parameters: [22,0,2,4,6,10,22,0,2,4,6,10,22,0,2,4,6,10,22,0,2,4,6,10,22,0,2,4,6,10,22,0]#repeat 1..7 for RCUH BF test +# 12,14,16,18,24,26,28,30,8,7,5,3,1,23,21,19,13,11,9,15,17,31,29,27,25] #RCU lookup table + I2Ccut: 35 #error count to disable I2C (14 for LTS?) status: RECVTR_I2C_error - - name: I2C_HBAT - type: hba1 #Special driver to manage HBAT1s. - parent: I2C_RCU - devreg: [0x40.0x10] #I2C broadcast register - parameters: [15] #PPS GPIO pin - name: I2Cbb1 - type: i2cbitbang1 #I2C bitbang via GPIO expander + type: i2cbitbangp #I2C bitbang via GPIO expander devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2] parameters: [5,6,6] #pins parent: I2C_RCU - name: I2Cbb2 - type: i2cbitbang1 + type: i2cbitbangp devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2] parameters: [4,6,6] parent: I2C_RCU - name: I2Cbb3 - type: i2cbitbang1 + type: i2cbitbangp devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2] parameters: [3,6,6] 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 type: spibitbang1 #SPI bitbang via GPIO expander: CLK, SDIO, SDIOdir,CS devreg: [IO3.GPIO1,IO3.GPIO1,IO3.CONF1,IO3.GPIO2] @@ -47,11 +52,7 @@ drivers: devreg: [IO3.GPIO1,IO3.GPIO1,IO3.CONF1,IO3.GPIO2] parameters: [5,4,4,2] parent: I2C_RCU -# - name: HBA_trigger -# type: gpio_hba_trigger -# parameters: [15] #PPS GPIO pin -# devreg: [0x40.0x10] #I2C broadcast register -# parent: I2C_RCU + #This is the I2C devices in the RCU device_registers: @@ -78,6 +79,10 @@ device_registers: description: Input/Ouput port 2 address: [1,3] store: True + - name: DIR1 + address: 4 + - name: DIR2 + address: 5 - name: ROM description: IO-Expander for filter selection @@ -128,37 +133,6 @@ device_registers: #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 @@ -181,10 +155,14 @@ device_registers: address: 0xFF - name: testmode address: 0x0D + - name: dither + address: 0x0C - name: JESDscramble address: 0x6E - name: PDWNmodes address: 0x08 + - name: DCcorrect + address: 0x40 - name: DTH dim: 3 @@ -213,6 +191,9 @@ device_registers: address: [0x1221,0x1121] - name: CONF address: [0x1210,0x1110] + - name: PA_CONFIG + address: [0x1260,0x1160] + store: True variables: - name: RECVTR_monitor_rate @@ -397,7 +378,7 @@ variables: mask: RECVTR_I2C_error - name: RCU_PWR_ANT_IOUT - description: Current drawn on antenna output of RCU (A) + description: Current drawn on antenna output of RCU (A). 15mA offset due to LED on RCU driver: I2C_RCU devreg: [AN.I_Ant0,AN.I_Ant1,AN.I_Ant2] width: 23 @@ -416,7 +397,7 @@ variables: devreg: IO2.GPIO1 width: 1 bitoffset: 6 - rw: rw #rw for testing + rw: ro #rw for testing dtype: boolean dim: 32 mask: RCU_mask @@ -445,12 +426,12 @@ variables: mask: RCU_mask - 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 devreg: [IO3.GPIO1,IO3.GPIO1,IO3.GPIO2] width: 1 bitoffset: [7,6,7] - rw: rw + rw: ro dtype: boolean dim: 96 dim2: [3,32] @@ -469,32 +450,6 @@ variables: dim2: [3,32] mask: ANT_mask - - name: HBAT_BF_delay_steps - description: HBAT1 frontend delays (0.5ns steps) - driver: I2C_HBAT - devreg: [HBAT1.XY,HBAT2.XY,HBAT3.XY] - bitoffset: [2,2,2] - width: 5 - rw: rw - dtype: uint8 - dim: 3072 - dim2: [32,96] - mask: ANT_mask - wait: 100 #ms - - - name: [HBAT_LED_on,HBAT_PWR_on,HBAT_PWR_LNA_on] - description: HBA frontend control - driver: I2C_HBAT - devreg: [HBAT1.XY,HBAT2.XY,HBAT3.XY] - bitoffset: [0,7,1] - width: 1 - rw: rw - dtype: boolean - dim: 3072 - dim2: [32,96] - mask: ANT_mask - wait: 100 #ms - - name: RCU_PCB_ID description: Unique PCB ID driver: I2C_RCU @@ -524,7 +479,7 @@ variables: dtype: string dim: 32 mask: RCU_mask - + - name: RCU_ADC_locked description: RCU ADC lock status. May generated noise and polling disabled in future driver: I2C_RCU @@ -535,6 +490,7 @@ variables: dim: 96 dim2: [3,32] # monitor: true + read_parallel: true - name: RCU_ADC_sync driver: I2C_RCU @@ -576,28 +532,46 @@ variables: dim: 96 dim2: [3,32] mask: ANT_mask + read_parallel: all - - name: RCU_DTH_tune + - name: RCU_DTH_PWR + description: RCU Dither source power driver: I2C_RCU - devreg: [DTH1.Tune,DTH2.Tune,DTH3.Tune] - width: 16 + devreg: [DTH1.PA_CONFIG,DTH2.PA_CONFIG,DTH3.PA_CONFIG] + width: 48 rw: rw - dtype: uint32 + dtype: double + scale: si4012_6bytes_to_pwr dim: 96 dim2: [3,32] mask: ANT_mask - debug: true + read_parallel: all +# debug: true - - name: RCU_DTH_config - driver: I2C_RCU - devreg: [DTH1.CONF,DTH2.CONF,DTH3.CONF] - width: 8 - rw: rw - dtype: uint32 - dim: 96 - dim2: [3,32] - mask: ANT_mask - debug: true + +# - name: RCU_DTH_tune +# driver: I2C_RCU +# devreg: [DTH1.Tune,DTH2.Tune,DTH3.Tune] +# width: 16 +# rw: rw +# dtype: uint32 +# dim: 96 +# dim2: [3,32] +# mask: ANT_mask +# debug: true +# read_parallel: all + +# - name: RCU_DTH_config +# driver: I2C_RCU +# devreg: [DTH1.CONF,DTH2.CONF,DTH3.CONF] +# width: 8 +# rw: rw +# dtype: uint32 +# dim: 96 +# dim2: [3,32] +# mask: ANT_mask +# debug: true +# read_parallel: all - name: RCU_DTH_on description: RCU Dither on. Controlled by RCU_DTH_on/off @@ -610,17 +584,19 @@ variables: dim: 96 dim2: [3,32] mask: ANT_mask + read_parallel: all - - name: RCU_DTH_Rev - driver: I2C_RCU - devreg: [DTH1.Rev,DTH2.Rev,DTH3.Rev] - width: 88 - rw: rw - dtype: uint32 - dim: 96 - dim2: [3,32] - mask: ANT_mask - debug: true +# - name: RCU_DTH_Rev +# driver: I2C_RCU +# devreg: [DTH1.Rev,DTH2.Rev,DTH3.Rev] +# width: 88 +# rw: rw +# dtype: uint32 +# dim: 96 +# dim2: [3,32] +# mask: ANT_mask +# debug: true +# read_parallel: all methods: - name: RECVTR_Init #Called after startup to load. Should have all stored registers @@ -640,6 +616,8 @@ methods: # - IO3.GPIO2: Update - IO3.CONF1: Update - 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 - name: RCU_on description: Initialize RCU and it in the ON state @@ -651,25 +629,38 @@ methods: - IO2.GPIO1: 0x4A #0x40 Dig on, 0x0a =10dB att - IO2.GPIO2: 0x55 #0x15 #Band0 (or 0x2a band 1) #LED green=on=low - IO3.GPIO1: 0x15 #ADC_SDIO=high, clk=low, DTH_EN=low - - IO3.GPIO2: 0x47 #ADC SC=high, DTH_SDA=high + - IO3.GPIO2: 0x47 #ADC SC=high, DTH_SDA=high, DTH_EN=low - IO1.GPIO1: 0x0A #0x0a = 10dB att - IO1.GPIO2: 0x8A #0x80 Analog on, 0x0a=10dB att - IO2.CONF2: 0 - IO3.CONF1: 0 - IO3.CONF2: 0 + - IO3.DIR1: 0 + - IO3.DIR2: 0 - IO1.CONF1: 0 - IO1.CONF2: 0 # - RCU_GPIO1: Update # - RCU_GPIO2: Update # - RCU_attenuator: [10,10,10] #Set OPC-UA variable +#name="RCU_DTH_shutdown" + - RCU_update: 0 - WAIT: 500 #ms to wait - ADC1_on: 0 #call another opc-ua method - - WAIT: 1000 #ms to wait +# - WAIT: 1000 #ms to wait - ADC2_on: 0 - - WAIT: 1000 #ms to wait +# - WAIT: 1000 #ms to wait - ADC3_on: 0 - - WAIT: 500 #ms to wait - - RCU_update: 0 +# - WAIT: 500 #ms to wait +#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_update driver: I2C_RCU @@ -686,11 +677,18 @@ methods: - RCU_LED_green_on: Update - RCU_attenuator_dB: Update - RCU_band_select: Update - - RCU_ADC_locked: Update - - RCU_ADC_sync: Update - - RCU_DTH_shutdown: Update - - RCU_DTH_freq: Update - - RCU_DTH_on: Update +# - RCU_ADC_locked: Update #disabled for testing +# - RCU_ADC_sync: Update #disabled for testing +# - RCU_DTH_shutdown: Update +# - RCU_DTH_freq: Update +# - RCU_DTH_on: Update #disabled for testing + - RCU_IO1_GPIO1: Update #needed for debug/testing + - RCU_IO1_GPIO2: Update + - RCU_IO2_GPIO1: Update + - RCU_IO2_GPIO2: Update + - RCU_IO3_GPIO1: Update + - RCU_IO3_GPIO2: Update + - name: ADC1_on driver: I2C_RCU @@ -700,6 +698,7 @@ methods: - ADC1.JESD_control1 : 0x14 - ADC1.SYNC_control: 1 #Setup ADCs - ADC1.CML_level: 0x7 + - ADC1.dither : 0x00 - ADC1.Update: 1 #Needed to update ADC registers - name: ADC2_on @@ -710,6 +709,7 @@ methods: - ADC2.JESD_control1 : 0x14 - ADC2.SYNC_control: 1 #Setup ADCs - ADC2.CML_level: 0x7 + - ADC2.dither : 0x00 - ADC2.Update: 1 #Needed to update ADC registers - name: ADC3_on @@ -720,6 +720,7 @@ methods: - ADC3.JESD_control1 : 0x14 - ADC3.SYNC_control: 1 #Setup ADCs - ADC3.CML_level: 0x7 + - ADC3.dither : 0x00 - ADC3.Update: 1 #Needed to update ADC registers - name: RCU_off @@ -739,28 +740,21 @@ methods: - 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 - - - name: RCU_DTH_on description: Switch dither source on driver: I2C_RCU mask: RCU_mask # rw: hidden instructions: - - RCU_DTH_config : [0,0,0] - - RCU_DTH_config: Update #debug +# - RCU_DTH_config : [0,0,0] +# - 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 - DTH2.Tune : [0,0] #no tuning - DTH3.Tune : [0,0] #no tuning - - RCU_DTH_tune: Update #debug +# - RCU_DTH_tune: Update #debug - DTH1.Start : [0,1,0,0,1] - DTH2.Start : [0,1,0,0,1] - DTH3.Start : [0,1,0,0,1] @@ -782,64 +776,5 @@ methods: # - DTH1.State : [0,0] # - DTH2.State : [0,0] # - DTH3.State : [0,0] - - RCU_DTH_on: Update - - - name: ADC0_test - driver: I2C_RCU - debug: True - mask: RCU_mask - instructions: - - ADC1.testmode : 0x05 - - ADC1.Update: 1 #Needed to update ADC registers - - - name: ADC1_test - driver: I2C_RCU - debug: True - mask: RCU_mask - instructions: - - ADC2.testmode : 0x05 - - ADC2.Update: 1 #Needed to update ADC registers - - - name: ADC2_test - driver: I2C_RCU - debug: True - mask: RCU_mask - instructions: - - ADC3.testmode : 0x05 - - ADC3.Update: 1 #Needed to update ADC registers - - - name: ADC_test_off - driver: I2C_RCU - debug: True - mask: RCU_mask - instructions: - - ADC1.testmode : 0x00 - - ADC1.Update: 1 #Needed to update ADC registers - - ADC2.testmode : 0x00 - - ADC2.Update: 1 #Needed to update ADC registers - - ADC3.testmode : 0x00 - - ADC3.Update: 1 #Needed to update ADC registers - - - name: ADC_scramble_off - driver: I2C_RCU - debug: True - mask: RCU_mask - instructions: - - ADC1.JESDscramble : 0x00 - - ADC1.Update: 1 #Needed to update ADC registers - - ADC2.JESDscramble : 0x00 - - ADC2.Update: 1 #Needed to update ADC registers - - ADC3.JESDscramble : 0x00 - - ADC3.Update: 1 #Needed to update ADC registers +# - RCU_DTH_on: Update - - name: ADC_scramble_on - driver: I2C_RCU - debug: True - mask: RCU_mask - instructions: - - ADC1.JESDscramble : 0x80 - - ADC1.Update: 1 #Needed to update ADC registers - - ADC2.JESDscramble : 0x80 - - ADC2.Update: 1 #Needed to update ADC registers - - ADC3.JESDscramble : 0x80 - - ADC3.Update: 1 #Needed to update ADC registers diff --git a/pypcc/i2cserv/hwdev.py b/pypcc/i2cserv/hwdev.py index a365a1c16a3508e729ef86f2d9101d338b78c4a8..96a87ab2980cf2f0d494ae19cde99cfd43593268 100644 --- a/pypcc/i2cserv/hwdev.py +++ b/pypcc/i2cserv/hwdev.py @@ -1,9 +1,14 @@ import logging + +#import multiprocessing as mp +#hwdevlock=mp.Lock() + class hwdev(): def __init__(self,config): #print("Init",config['name']) self.conf=config +# print("Make lock",hwdevlock) def OPCUASetVariable(self,varid,var1,data,mask): logging.warn(self.conf['name']+" OPCUASetVariable Not implemented!") diff --git a/pypcc/i2cserv/i2c_array.py b/pypcc/i2cserv/i2c_array.py index c10d07dde5ca7b73be0ffbfc0564724838a144ab..2f1d023d6b297e5464e0ad84144ad0a76eca2b53 100644 --- a/pypcc/i2cserv/i2c_array.py +++ b/pypcc/i2cserv/i2c_array.py @@ -18,15 +18,17 @@ class i2c_array(i2c_dev): 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.I2Cmask=[0]*self.N self.I2Ccut=config.get('I2Ccut',5);#pars[2]; + self.enablemask=[p<self.N for p in pars] + print("enable mask",self.enablemask) + self.I2Cmask=[0]*self.N self.disableI2ConError=self.I2Ccut>0; # 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; + if len(mask)==0: mask=self.enablemask.copy(); return i2c_dev.OPCUAReadVariable(self,varid,var1,mask) def SetSwitch(self,RCUi): @@ -56,7 +58,12 @@ class i2c_array(i2c_dev): mask=[m for m in mask for x in range(Step)] if not(len(mask)==Step*self.N): print("Check mask length!",len(mask),Step,self.N); - return; + return + else: + for x,enanbled in enumerate(self.enablemask): + if enanbled: continue; + for y in range(Step): mask[x*Step+y]=False; + self.conf['parentcls'].clearSwitch(); # if (len(value1)==V1.nVars) and (self.N>1): value1=(value1*self.N); # logging.debug(str(("Step=",Step,"Mask=",mask))) if var1.get('read_parallel')=='all': @@ -137,8 +144,14 @@ class i2c_array(i2c_dev): if not(len(mask)==Step*self.N): print("Check mask length!",len(mask),Step,self.N); return; + else: + for x,enanbled in enumerate(self.enablemask): + if enanbled: continue; + for y in range(Step): mask[x*Step+y]=False; +# mask[x*Step:(x+1)*Step]=False; # if (len(value1)==V1.nVars) and (self.N>1): value1=(value1*self.N); i2c=self.conf['parentcls']; + self.conf['parentcls'].clearSwitch(); # logging.debug(str(("Step=",Step,"Mask=",mask))) # if var1.get('read_parallel')=='all': # return self.GetVarValueParallel(self,var1,mask) @@ -209,15 +222,17 @@ class i2c_array(i2c_dev): # if devreg.get('store'): logging.debug("Stored") # print(devreg['store']) if len(mask)==0: - mask=[True]*self.N; + mask=self.enablemask.copy() +# mask=[True]*self.N; self.RCUi=0; # self.mask=mask; + self.conf['parentcls'].clearSwitch(); 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]<=self.I2Ccut) and not(value[0] is None): + if (mask[RCUi]) and (self.I2Cmask[RCUi]<=self.I2Ccut) and (self.enablemask[RCUi]) and not(value[0] is None): storearray[RCUi]=value[0] self.RCUi=RCUi; logging.debug(str(("Stored values:",self.getstorearray(devreg)))) @@ -226,10 +241,11 @@ class i2c_array(i2c_dev): def Getdevreg(self,devreg,mask=[]): value1=[0]*self.N - mask=[True]*self.N + mask=self.enablemask.copy() if devreg.get('store'): storearray=self.getstorearray(devreg); i2c=self.conf['parentcls']; + self.conf['parentcls'].clearSwitch(); for RCUi in self.RCUorder: if not(mask[RCUi]): continue if not(self.I2Cmask[RCUi]<=self.I2Ccut): continue diff --git a/pypcc/i2cserv/i2c_switch.py b/pypcc/i2cserv/i2c_switch.py index ad8df3163c3aaae9b17576c896b1faacffb0e2c1..4180f2ce17243c32ad4b9f4b2dae3a3e2d99ac42 100644 --- a/pypcc/i2cserv/i2c_switch.py +++ b/pypcc/i2cserv/i2c_switch.py @@ -17,6 +17,9 @@ class i2c_switch(i2c): if self.NoSwitch: logging.warn("i2c switch disabled!") + def clearSwitch(self): + for x in range(self.SWcnt): self.CurrentChannel[x]=-1; + def SetSW1(self,channelbit): # channel=(0 if (channelbit>5) else 1<<(channelbit)) #LTS if self.NoSwitch: return True; @@ -36,10 +39,10 @@ class i2c_switch(i2c): return True def ClearNewChannel(self): - self.newChannel=[0 for x in self.SWaddrs]; + self.newChannel=[0 for x in self.SWaddrs]+[0];#last one is a dummy def AddNewChannel(self,channelbit): - SWn=channelbit>>3; + SWn=(channelbit>>3); channel=1<<(channelbit & 0x07) self.newChannel[SWn]|=channel; diff --git a/pypcc/i2cserv/i2cthread.py b/pypcc/i2cserv/i2cthread.py index ee4d9d72bc1cd61875dad9721cb3037b3584041e..9d9d9bd36d712f8f5b1c913ef64b88a9b85527b3 100644 --- a/pypcc/i2cserv/i2cthread.py +++ b/pypcc/i2cserv/i2cthread.py @@ -103,7 +103,7 @@ def getvar(conf,Qout,varid,mask): return mask; -def I2Cserver(Qin,Qout,name): +def I2Cserver(Qin,Qout,name,lock=None): logging.info("New i2c process "+name) conf=yc.yamlconfig(name) conf.linkdevices() @@ -111,7 +111,8 @@ def I2Cserver(Qin,Qout,name): for c in conf.conf['drivers']: c['Qout']=Qout; conf.linkdrivers() - statusid=conf.getvarid(name+"_translator_busy"); + basename=conf.conf.get("name",name) + statusid=conf.getvarid(basename+"_translator_busy"); while True: item = Qin.get() if item is None: @@ -121,15 +122,23 @@ def I2Cserver(Qin,Qout,name): # print("TODO: Set busy") # self.statevar.set_value("busy"); #print("SetVar",item)#,self.conf.variables[item.id]) - if (item.type==InstType.varSet): + if not(lock is None): + lock.acquire() +# print('lock'); + try: + 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): + 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!"); + elif (item.type==InstType.method): runmethod(conf,Qout,item.id,item.mask) + else: print("OPCUA call not implemented!"); + finally: + if not(lock is None): + lock.release() +# print('unlock'); # 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) @@ -146,8 +155,8 @@ def I2Cserver(Qin,Qout,name): # RCU1.load() #Load current register values from HW # RCU1.RCUthread(Qin) -def start(Qout,Qin,name): - thread1 = Process(target=I2Cserver, args=(Qin,Qout,name)) +def start(Qout,Qin,name,lock=None): + thread1 = Process(target=I2Cserver, args=(Qin,Qout,name,lock)) thread1.start() return thread1 diff --git a/pypcc/opcuaserv/i2client.py b/pypcc/opcuaserv/i2client.py index 80024fe10b647970824c4b21f557c38117f972fe..680f0f04dc7b200b8d2523ddef1aeb6976498c2a 100644 --- a/pypcc/opcuaserv/i2client.py +++ b/pypcc/opcuaserv/i2client.py @@ -21,18 +21,18 @@ class i2client(): # self.Input.close() def readvar(self,id1,mask=[]): - Data=OPCUAset(id1,InstType.varRead,[],mask) + Data=OPCUAset(id1,InstType.varRead,[],mask.copy()) self.Qout.put(Data); def setvar(self,id1,data=[],mask=[]): - Data=OPCUAset(id1,InstType.varSet,data,mask) + Data=OPCUAset(id1,InstType.varSet,data.copy(),mask.copy()) self.Qout.put(Data); def QoutLength(self): return self.Qout.qsize() def callmethod(self,id1,mask=[]): - Data=OPCUAset(id1,InstType.method,[],mask) + Data=OPCUAset(id1,InstType.method,[],mask.copy()) self.Qout.put(Data); def data_waiting(self): diff --git a/pypcc/opcuaserv/opcuaserv.py b/pypcc/opcuaserv/opcuaserv.py index 65eedc4fc9f14aca260c7d485f10fc3d340a0509..6c284cdf5561a0bdf1c90fbce13aa1842fce0b6f 100644 --- a/pypcc/opcuaserv/opcuaserv.py +++ b/pypcc/opcuaserv/opcuaserv.py @@ -12,6 +12,7 @@ import logging Vars_R={} Vars_W={} +methodDict={} running=False class SubHandler(object): @@ -21,10 +22,11 @@ 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,v,reader=Vars_W[node.nodeid.Identifier] + vname,myvar,v,reader,opcvar=Vars_W[node.nodeid.Identifier] # val=(val if isinstance(val, list) else [val] ) logging.info(str(("Datachange callback",vname,val))) - reader.setvar(v,val) + for r in reader: + r.setvar(v,val) # myvar2.Value.Value=val # myvar2.SourceTimestamp = datetime.utcnow() @@ -44,11 +46,11 @@ class SubHandler(object): logging.info(str(("Python: New event", event))) -def CallMethod(ObjectID,name,Inst1,Q1): +def CallMethod(ObjectID,name,Inst1): logging.info(str(("Callmethod",ObjectID,name))) # Inst1=Vars.Instr(Vars.DevType.Instr,instrs,0,[]) - Q1.callMethod(Inst1) - + for Q1 in methodDict[name]: + Q1.callMethod(Inst1) # P1.CallMethod(name,None) def AddVar(name,value): @@ -57,25 +59,43 @@ def AddVar(name,value): return myvar2 def AddVarR(vname,varvalue2,v,debug): + for id0,vx in Vars_R.items(): + if vx[0]==vname: + logging.info("Duplicate %s "%vname) +# Vars_W[id0][3]+=[Q1] + if vx[3]!=v: logging.error("Duplicate %s with different IDs!"%vname) + return vx[4] +# else: print(vx[0],vname) 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] + Vars_R[myvar.nodeid.Identifier]=[vname,myvar.get_data_value(),varvalue2,v,myvar] return myvar def AddVarW(vname,varvalue2,v,Q1,debug): + for id0,vx in Vars_W.items(): + if vx[0]==vname: + logging.info("Duplicate %s "%vname) + Vars_W[id0][3]+=[Q1] + if vx[2]!=v: logging.error("Duplicate %s with different IDs!"%vname) + return vx[4] logging.info(str(("Variable added: ",vname)))#,'=',varvalue2) obj=(DEBUGobj if debug else PCCobj) myvar2 = obj.add_variable(idx, vname, varvalue2) myvar2.set_writable() if not v is None: - Vars_W[myvar2.nodeid.Identifier]=[vname,myvar2.get_data_value(),v,Q1] + Vars_W[myvar2.nodeid.Identifier]=[vname,myvar2.get_data_value(),v,[Q1],myvar2] handle = sub.subscribe_data_change(myvar2) return myvar2 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), [],[] ) + try: + methodDict[vname]+=[Q1] + logging.info("Duplicate method %s "%vname) + except: + methodDict[vname]=[Q1]; + myvar = obj.add_method(idx, vname, lambda ObjectId,name=vname,inst=v : CallMethod(ObjectId,name,inst), [],[] ) logging.info(str(("AddMethod:",vname))) def InitServer(port=4840): diff --git a/pypcc/opcuaserv/yamlreader.py b/pypcc/opcuaserv/yamlreader.py index 29d4f7bd189d0a90aedf7615ee59606a2f474a1c..5319e69f791c342f0c0defdad0dee88341df93cb 100644 --- a/pypcc/opcuaserv/yamlreader.py +++ b/pypcc/opcuaserv/yamlreader.py @@ -23,11 +23,12 @@ class yamlreader(yamlconfig): def __init__(self,i2cserver,yamlfile='RCU'): self.yamlfile=yamlfile; yamlconfig.__init__(self,yamlfile) + self.basename=self.conf.get("name",yamlfile); self.server=i2cserver; self.timecount=1000; #0 start a 0, 1000 first point immediate self.monitorvarcnt=0; - self.statusid=self.getvarid(yamlfile+"_translator_busy"); - self.monitorvarid=self.getvarid(yamlfile+"_monitor_rate"); + self.statusid=self.getvarid(self.basename+"_translator_busy"); + self.monitorvarid=self.getvarid(self.basename+"_monitor_rate"); self.statusOPC=None def SetBusy(self): @@ -53,8 +54,9 @@ class yamlreader(yamlconfig): # print(len(varvalue2),varvalue2) if v.get('rw') in ['ro','rw','variable']: var1=AddVarR(name+"_R",varvalue2,v['id'],v.get('debug')) - v['OPCR']=var1 - logging.debug("Var added:"+name+"_R") + if not(var1 is None): + 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) @@ -62,8 +64,9 @@ class yamlreader(yamlconfig): if v.get('rw') in ['wo','rw','variable']: var1=AddVarW(name+"_RW",varvalue2,v['id'],self,v.get('debug')) - v['OPCW']=var1 - logging.debug("Var added:"+name+"_RW") + if not(var1 is None): + v['OPCW']=var1 + logging.debug("Var added:"+name+"_RW") for v in self.conf['variables']: mask=v.get('mask'); if not(mask): continue; @@ -108,9 +111,9 @@ class yamlreader(yamlconfig): self.server.callmethod(id1,mask) def CallInit(self): - v=Find(self.conf['methods'],'name',self.yamlfile+'_Init'); + v=Find(self.conf['methods'],'name',self.basename+'_Init'); if not(v): - logging.warn(self.yamlfile+"_Init method not found for initialisation!") + logging.warn(self.basename+"_Init method not found for initialisation!") return; self.callMethod(v['id']) @@ -169,7 +172,7 @@ class yamlreader(yamlconfig): logging.warn("setvar unsupported type"); return; data2=[d for d in data2] - logging.debug(str(("setvar ",v['name'],data2,mask))); + logging.warning(str(("setvar ",v['name'],data2,mask))); self.SetBusy() self.server.setvar(id1,data2,mask) @@ -262,7 +265,7 @@ class yamlreader(yamlconfig): else: data3=data2; # print("OPCset",v['name'],data3[:64],mask) - logging.info(str(("OPCset",v['name'],data3[:64]))) + logging.warning(str(("OPCset",v['name'],data3[:64],mask))) # 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]; var1.set_value(data3,datatype); diff --git a/pypcc/pypcc.py b/pypcc/pypcc.py index 10df5acc2a6df4f2cff97f688fd8780c7b0f78f0..b23c71f88b0b913ec1347163c1e48b6e282a60fd 100755 --- a/pypcc/pypcc.py +++ b/pypcc/pypcc.py @@ -29,6 +29,7 @@ args = parser.parse_args() # "lofar_id": f"pypcc - {args.config}", #} #configure_logger(logstash_host=args.loghost,level=args.loglevel, log_extra=log_extra) +logging.getLogger().setLevel(args.loglevel) RunTimer=True; def signal_handler(sig, frame): @@ -39,6 +40,13 @@ signal.signal(signal.SIGINT, signal_handler) #Start i2c processes as soon as possible to have minimum duplication logging.info("Start I2C processes") + +if True: + logging.info("Make I2C lock") + import multiprocessing as mp + lock=mp.Lock() +else: + lock=None; #I2Cports=['UNB2','RCU','CLK'] #I2Cports=['RCU'] I2Cports=[x for x in args.config.split(',')] @@ -47,10 +55,9 @@ I2Cclients=[] for name in I2Cports: RCU_I2C=i2client.i2client(name=name) if not(args.simulator): - thread1=i2cthread.start(*RCU_I2C.GetInfo()) + thread1=i2cthread.start(*RCU_I2C.GetInfo(),lock=lock) threads.append(thread1) I2Cclients.append(RCU_I2C) - #Initialise OPCUA server and load variables logging.info("Initialised OPC-UA Server") configs=[]