diff --git a/address_table/ETROC2_example.yaml b/address_table/ETROC2_example.yaml
index fa8077f3204cb6e295db67c73820fff49a083039..094f795c0b0cffec2d96032bef1c4f3c65ab98db 100644
--- a/address_table/ETROC2_example.yaml
+++ b/address_table/ETROC2_example.yaml
@@ -1,10 +1,15 @@
+############################################
+##### In-Pixel Configuration Registers #####
+############################################
+
 CLSel:
-  doc:      "Select of load capacitance of the preamp first stage.
-  2‘b00: 0 fC;
-  2‘b01–> 80 fC;
-  2‘b10–> 80 fC;
-  2‘b01–> 160 fC.
-  Debugging use only."
+  doc: |-
+    Select of load capacitance of the preamp first stage.
+    2‘b00: 0 fC;
+    2‘b01: 80 fC;
+    2‘b10: 80 fC;
+    2‘b01: 160 fC.
+    Debugging use only.
   address:
     - 0
   mask:
@@ -13,8 +18,158 @@ CLSel:
   stat:     0
   default:  0x0
 
+IBSel:
+  doc: |-
+    Bias current selection of the input transistor in the preamp.
+    3'b000: I1;
+    3'b001, 3'b010, 3'b100: I2;
+    3'b011, 3'b110, 3'b101: I3;
+    3'b111: I4
+    I1 > I2 > I3 > I4.
+  address:
+    - 0
+  mask:
+    - 0x1C
+  pixel:    1
+  stat:     0
+  default:  0x7
+
+RfSel:
+  doc: |-
+    Feedback resistance selection.
+    2'b00: 20 kOHm
+    2'b01: 10 kOHm
+    2'b10: 5.7 kOHm
+    2'b11: 4.4 kOHm
+  address:
+    - 0
+  mask:
+    - 0x60
+  pixel:    1
+  stat:     0
+  default:  0x2
+
+HysSel:
+  doc: |-
+    Hysteresis voltage selection.
+    4'b0000: Vhys1
+    4'b0001: Vhys2
+    4'b0011: Vhys3
+    4'b0111: Vhys4
+    4'b1111: Vhys5
+    Vhys1 > Vhys2 > Vhys3 > Vhys4 = Vhys5 = 0
+  address:
+    - 2
+  mask:
+    - 0xF
+  pixel:    1
+  stat:     0
+  default:  0xF
+
+PD_DACDiscri:
+  doc: |-
+    Power down the DAC and the discriminator in pixels.
+    When PD_DACDiscri is 1, the DAC and the discriminator are powered down.
+  address:
+    - 2
+  mask:
+    - 0x10
+  pixel:    1
+  stat:     0
+  default:  0x0
+
+QSel:
+  doc: "Select injected charge, from 1 fC (5'b00000) to 32 fC (5'b11111)."
+  address:
+    - 1
+  mask:
+    - 0x1F
+  pixel:    1
+  stat:     0
+  default:  0x6
+
+QInjEn:
+  doc: "Enable the charge injection of the specified pixel. Active high."
+  address:
+    - 1
+  mask:
+    - 0x20
+  pixel:    1
+  stat:     0
+  default:  0x0
+
+autoReset_TDC:
+  doc: "TDC automatically reset controller for every clock period."
+  address:
+    - 6
+  mask:
+    - 0x20
+  pixel:    1
+  stat:     0
+  default:  0x0
+
+enable_TDC:
+  doc: |-
+    TDC enable.
+    1'b1: enable TDC conversion
+    1'b0: disable TDC conversion
+  address:
+    - 6
+  mask:
+    - 0x80
+  pixel:    1
+  stat:     0
+  default:  0x1
+
+level_TDC:
+  doc: "The bit width of bubble tolerant in TDC encode. It is up to 3'b011"
+  address:
+    - 6
+  mask:
+    - 0xE
+  pixel:    1
+  stat:     0
+  default:  0x1
+
+resetn_TDC:
+  doc: "Reset TDC encoder, active low."
+  address:
+    - 6
+  mask:
+    - 0x40
+  pixel:    1
+  stat:     0
+  default:  0x1
+
+testMode_TDC:
+  doc: |-
+    Test mode enable of TDC, active high. In test mode, TDC generates
+    a fixed test pulse as input signal for test for every 25 ns.
+  address:
+    - 6
+  mask:
+    - 0x10
+  pixel:    1
+  stat:     0
+  default:  0x0
+
+Bypass_THCal:
+  doc: |-
+    Bypass control of the in-pixel threshold calibration block.
+    1: Bypassing the in-pixel threshold calibration block. DAC is applied to TH.
+    Users can control the threshold voltage through DAC.
+    0: Calibrated threshold is applied to TH.
+    TH = BL + TH_offset.
+  address:
+    - 3
+  mask:
+    - 0x4
+  pixel:    1
+  stat:     0
+  default:  0x1
+
 DAC:
-  doc:      "threshold"
+  doc: "When THCal_Bypass==1'b1, TH = DAC."
   address:
     - 4
     - 5
@@ -26,7 +181,7 @@ DAC:
   default:  0x0
 
 TH_offset:
-  doc:      "Threshold offset for the calibrated baseline.
+  doc: "Threshold offset for the calibrated baseline.
   TH = BL + TH_offset"
   address:
     - 5
@@ -36,8 +191,203 @@ TH_offset:
   stat:     0
   default:  0xa
 
+RSTn_THCal:
+  doc: "Reset of threshold calibration block, active low."
+  address:
+    - 3
+  mask:
+    - 0x1
+  pixel:    1
+  stat:     0
+  default:  0x1
+
+ScanStart_THCal:
+  doc: "A rising edge of ScanStart_THCal initializes the threshold calibration."
+  address:
+    - 3
+  mask:
+    - 0x10
+  pixel:    1
+  stat:     0
+  default:  0x0
+
+BufEn_THCal:
+  doc: |-
+    Threshold calibration buffer enable.
+    1: enabling the buffer between discriminator output and the TH_Ctrl.
+    0: disabling the buffer between discriminator output and the TH_Ctrl.
+  address:
+    - 3
+  mask:
+    - 0x2
+  pixel:    1
+  stat:     0
+  default:  0x0
+
+CLKEn_THCal:
+  doc: |-
+    This register is only used when the threshold calibration clock is bypassed.
+    1: enabling the clock for measuring average discriminator output.
+    0: disabling the clock. Measurement of the average discriminator output is not available.
+  address:
+    - 3
+  mask:
+    - 0x8
+  pixel:    1
+  stat:     0
+  default:  0x0
+
+workMode:
+  doc: |-
+    Readout work mode selection.
+    2'b00: normal,
+    2'b01: self test, periodic trigger fixed TDC data,
+    2'b10: self test, random TDC data,
+    2'b11: reservered.
+  address:
+    - 7
+  mask:
+    - 0x18
+  pixel:    1
+  stat:     0
+  default:  0x0
+
+L1Adelay:
+  doc: "L1A latency"
+  address:
+    - 8
+    - 9
+  mask:
+    - 0x80
+    - 0xFF
+  pixel:    1
+  stat:     0
+  default:  0x1F5
+
+disDataReadout:
+  doc: |-
+    Disable signal of the TDC data readout.
+    1: disabling the TDC data readout of the current pixel.
+    0: enabling the TDC data readout fo the current pixel.
+  address:
+    - 7
+  mask:
+    - 0x2
+  pixel:    1
+  stat:     0
+  default:  0x0
+
+disTrigPath:
+  doc: |-
+    Disable signal of the trigger readout.
+    1: disabling the trigger readout of the current pixel.
+    0: enabling the trigger readout of the current pixel.
+  address:
+    - 7
+  mask:
+    - 0x4
+  pixel:    1
+  stat:     0
+  default:  0x0
+
+upperTOATrig:
+  doc: "TOA upper threshold for the trigger readout"
+  address:
+    - 21
+    - 22
+  mask:
+    - 0xFF
+    - 0x3
+  pixel:    1
+  stat:     0
+  default:  0x200
+
+lowerTOATrig:
+  doc: "TOA lower threshold for the trigger readout"
+  address:
+    - 19
+    - 20
+  mask:
+    - 0xC0
+    - 0xFF
+  pixel:    1
+  stat:     0
+  default:  0x20
+
+upperTOTTrig:
+  doc: "TOT upper threshold for the trigger readout" # Potential mismatch between register table default (p.62) and address register table default (p. 63) in Users Manual.
+  address:
+    - 23
+    - 24
+  mask:
+    - 0xF8
+    - 0xF
+  pixel:    1
+  stat:     0
+  default:  0x40
+
+lowerTOTTrig:
+  doc: "TOT lower threshold for the trigger readout"
+  address:
+    - 22
+    - 23
+  mask:
+    - 0xFC
+    - 0x7
+  pixel:    1
+  stat:     0
+  default:  0x10
+
+upperCalTrig:
+  doc: "Cal upper threshold for the trigger readout"
+  address:
+    - 18
+    - 19
+  mask:
+    - 0xF0
+    - 0x3F
+  pixel:    1
+  stat:     0
+  default:  0x200
+
+lowerCalTrig:
+  doc: "Cal lower threshold for the trigger readout"
+  address:
+    - 17
+    - 18
+  mask:
+    - 0xFC
+    - 0xF
+  pixel:    1
+  stat:     0
+  default:  0x10
+
+upperTOA:
+  doc: "TOA upper threshold for the TDC data readout"
+  address:
+    - 13
+    - 14
+  mask:
+    - 0xC0
+    - 0xFF
+  pixel:    1
+  stat:     0
+  default:  0x200
+
+lowerTOA:
+  doc: "TOA lower threshold for the TDC data readout"
+  address:
+    - 12
+    - 13
+  mask:
+    - 0xF0
+    - 0x3F
+  pixel:    1
+  stat:     0
+  default:  0x20
+
 upperTOT:
-  doc:      "please add doc"
+  doc: "TOT upper threshold for the TDC data readout"
   address:
     - 16
     - 17
@@ -46,40 +396,1274 @@ upperTOT:
     - 0x3
   pixel:    1
   stat:     0
-  default:  0x0
+  default:  0x100
 
-disScrambler:
-  doc:      "Disable scrambler.
-  0: enable scrambler
-  1: disable scrambler"
+lowerTOT:
+  doc: "TOT lower threshold for the TDC data readout"
   address:
-    - 19
+    - 15
+    - 16
   mask:
+    - 0xFF
     - 0x1
-  pixel:    0
+  pixel:    1
+  stat:     0
+  default:  0x10
+
+upperCal:
+  doc: "Cal upper threshold for the TDC data readout"
+  address:
+    - 11
+    - 12
+  mask:
+    - 0xFC
+    - 0xF
+  pixel:    1
+  stat:     0
+  default:  0x200
+
+lowerCal:
+  doc: "Cal lower threshold for the TDC data readout"  # Potential mismatch between register table default (p.62) and address register table default (p. 63) in Users Manual.
+  address:
+    - 10
+    - 11
+  mask:
+    - 0xFF
+    - 0x3
+  pixel:    1
+  stat:     0
+  default:  0x10
+
+addrOffset:
+  doc: |-
+    Enabling of the circular buffer (CB) write address offset
+    by the pixel ID, active high.
+    1: enabling of the CB write address offset.
+    0: disabling of the CB write address offset.
+  address:
+    - 7
+  mask:
+    - 0x1
+  pixel:    1
   stat:     0
   default:  0x1
 
-singlePort:
-  doc:      "enable single port or both ports.
-  0: use both left and right serial ports.
-  1: use right serial port only"
+selfTestOccupancy:
+  doc: |-
+    Self-test data occupancy is selfTestOccupancy[6:0]/128.
+    For example:
+    1: 1/1.28%
+    2: 2/1.28%
+    5: 5/1.28%
+    10: 10/1.28%
   address:
-    - 19
+    - 8
   mask:
-    - 0x40
-  pixel:    0
+    - 0x7F
+  pixel:    1
   stat:     0
   default:  0x1
 
-mergeTriggerData:
-  doc:      "merge trigger and data in a port
-  0: trigger and data in separate port, only valid when single port is false.
-  1: trigger and data are merged in serial port"
+############################################
+######### In-Pixel Status Registers ########
+############################################
+
+ACC:
+  doc: "Accumulator of the threshold calibration."
   address:
-    - 20
+    - 5
+    - 6
+  mask:
+    - 0xFF
+    - 0xFF
+  pixel:    1
+  stat:     1
+
+ScanDone:
+  doc: "Scan done signal of the threshold calibration."
+  address:
+    - 1
   mask:
     - 0x1
+  pixel:    1
+  stat:     1
+
+BL:
+  doc: "Baseline obtained from threshold calibration."
+  address:
+    - 2
+    - 3
+  mask:
+    - 0xFF
+    - 0x3
+  pixel:    1
+  stat:     1
+
+NW:
+  doc: "Noise width from threshold calibration. Expect less than 10."
+  address:
+    - 1
+  mask:
+    - 0x1E
+  pixel:    1
+  stat:     1
+
+TH:
+  doc: "10-bit threshold applied to the DAC input."
+  address:
+    - 3
+    - 4
+  mask:
+    - 0xC0
+    - 0xFF
+  pixel:    1
+  stat:     1
+
+THState:
+  doc: "Threshold calibration state machine output."
+  address:
+    - 1
+  mask:
+    - 0xE0
+  pixel:    1
+  stat:     1
+
+PixelID:
+  doc: "Col[3:0], Row[3:0]"
+  address:
+    - 0
+  mask:
+    - 0xFF
+  pixel:    1
+  stat:     1
+
+############################################
+#### Peripheral Configuration Registers ####
+############################################
+
+readoutClockDelayPixel:
+  doc: "Phase delay of pixel readout clock, 780 ps a step."
+  address:
+    - 13
+  mask:
+    - 0x1F
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+readoutClockWidthPixel:
+  doc: "Positive pulse width of pixel clock, 780 ps a step."
+  address:
+    - 14
+  mask:
+    - 0x1F
+  pixel:    0
+  stat:     0
+  default:  0x20
+
+readoutClockDelayGlobal:
+  doc: "Phase delay of global readout clock, 780 ps a step."
+  address:
+    - 15
+  mask:
+    - 0x1F
   pixel:    0
   stat:     0
   default:  0x0
+
+readoutClockWidthGlobal:
+  doc: "Positive pulse width of global readout clock, 780 ps a step."
+  address:
+    - 16
+  mask:
+    - 0x1F
+  pixel:    0
+  stat:     0
+  default:  0x20
+
+serRateRight:
+  doc: |-
+    Data rate selection of the right data port.
+    2'b00: 320 Mbps;
+    2'b01: 640 Mbps;
+    2'b10: 1280 Mbps.
+  address:
+    - 19
+  mask:
+    - 0x30
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+serRateLeft:
+  doc: |-
+    Data rate selection of the left data port.
+    2'b00: 320 Mbps;
+    2'b01: 640 Mbps;
+    2'b10: 1280 Mbps.
+  address:
+    - 19
+  mask:
+    - 0xC
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+linkResetTestPattern:
+  doc: |-
+    Link reset test pattern selection.
+    1'b0: PRBS;
+    1'b1: Fixed pattern.
+  address:
+    - 19
+  mask:
+    - 0x2
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+linkResetFixedPattern:
+  doc: "User-specified pattern to be sent during link reset, LSB first."
+  address:
+    - 26
+    - 27
+    - 28
+    - 29
+  mask:
+    - 0xFF
+    - 0xFF
+    - 0xFF
+    - 0xFF
+  pixel:    0
+  stat:     0
+  default:  0xACC78CC5
+
+emptySlotBCID:
+  doc: "Empty BCID slot for synchronization."
+  address:
+    - 11
+    - 12
+  mask:
+    - 0xF0
+    - 0xFF
+  pixel:    0
+  stat:     0
+  default:  0x7
+
+triggerGranularity:
+  doc: |-
+    The trigger data size varies from 0, 1, 2, 4, 8, 16.
+    0/6/7: trigger data size is 0.
+    1: trigger data size is 1.
+    2: trigger data size is 2.
+    3: trigger data size is 4.
+    4: trigger data size is 8.
+    5: trigger data size is 16.
+  address:
+    - 20
+  mask:
+    - 0xE
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+disScrambler:
+  doc: |-
+    Disable scrambler.
+    0: enable scrambler
+    1: disable scrambler
+  address:
+    - 19
+  mask:
+    - 0x1
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+mergeTriggerData:
+  doc: |-
+    Merge trigger and data in a port
+    0: trigger and data in separate port, only valid when single port is false.
+    1: trigger and data are merged in serial port
+  address:
+    - 20
+  mask:
+    - 0x1
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+singlePort:
+  doc: |-
+    Enable single port or both ports.
+    0: use both left and right serial ports.
+    1: use right serial port only
+  address:
+    - 19
+  mask:
+    - 0x40
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+onChipL1AConf:
+  doc: |-
+    On-chip L1A mode
+    2'b0x: on-chip L1A disable;
+    2'b10: periodic L1A;
+    2'b11: random L1A.
+  address:
+    - 18
+  mask:
+    - 0x60
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+BCIDoffset:
+  doc: "BCID when BCID is reset"
+  address:
+    - 10
+    - 11
+  mask:
+    - 0xFF
+    - 0xF
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+fcSelfAlignEn:
+  doc: |-
+    Fast command decoder self-alignment mode enable.
+    1: self-alignment mode enabled;
+    0: manual alignment mode enabled.
+  address:
+    - 18
+  mask:
+    - 0x4
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+fcClkDelayEn:
+  doc: "Enable clock delay in fast command manual alignment mode"
+  address:
+    - 18
+  mask:
+    - 0x8
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+fcDataDelayEn:
+  doc: "Enable data delay in fast command manual alignment mode, active high."
+  address:
+    - 18
+  mask:
+    - 0x10
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+chargeInjectionDelay:
+  doc: |-
+    The charge injection delay to the 40 MHz clock rising
+    edge. Start from the rising edge of 40 MHz clock,
+    each step 781 ps. The pulse width is fixed of 50 ns.
+  address:
+    - 17
+  mask:
+    - 0x1F
+  pixel:    0
+  stat:     0
+  default:  0x18
+
+RefStrSel:
+  doc: "TDC reference strobe selection."
+  address:
+    - 6
+  mask:
+    - 0xFF
+  pixel:    0
+  stat:     0
+  default:  0x3
+
+PLL_BIASGEN_CONFIG:
+  doc: "Charge pump bias current selection, [0:8:120] uA. Debugging use only."    # Potential name mismatch of registers between page 55 and page 60 of Users manual
+  address:
+    - 1
+  mask:
+    - 0xF
+  pixel:    0
+  stat:     0
+  default:  0x8
+
+PLL_CONFIG_I_PLL:
+  doc: "Bias current selection of the I-filter unit cell in PLL mode [0:1.1:8] uA. Debugging use only."
+  address:
+    - 1
+  mask:
+    - 0xF0
+  pixel:    0
+  stat:     0
+  default:  0x9
+
+PLL_CONFIG_P_PLL:
+  doc: "Bias current selection of the P-filter unit cell in PLL mode [0:5.46:82] uA. Debugging use only."
+  address:
+    - 2
+  mask:
+    - 0xF
+  pixel:    0
+  stat:     0
+  default:  0x9
+
+PLL_R_CONFIG:
+  doc: "Resistor selection of the P-path in PLL mode [R=1/2*79.8k/CONFIG] Ohm. Debugging use only." # Potential name mismatch of registers between page 55 and page 60 of Users manual
+  address:
+    - 2
+  mask:
+    - 0xF0
+  pixel:    0
+  stat:     0
+  default:  0x2
+
+PLL_vcoDAC:
+  doc: "Bias current selection of the VCO core [0:0.470:7.1] mA. Debugging use only."
+  address:
+    - 3
+  mask:
+    - 0xF
+  pixel:    0
+  stat:     0
+  default:  0x8
+
+PLL_vcoRailMode:
+  doc: |-
+    Output rail-to-rail mode selection of the VCO, active low.
+    1'b0: rail-to-rail output.
+    1'b1: CML output.
+    Debugging use only.
+  address:
+    - 3
+  mask:
+    - 0x10
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+PLL_ENABLEPLL:
+  doc: "Enable PLL mode, active high. Debugging use only."
+  address:
+    - 3
+  mask:
+    - 0x20
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+PLL_FBDiv_skip:
+  doc: |-
+    Adjusting the phase of the output clk1G28 of freqPrescaler
+    in the feedback divider (N=64) by one skip from low to high.
+    Debugging use only.
+  address:
+    - 0
+  mask:
+    - 0x80
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+PLL_FBDiv_clkTreeDisable:
+  doc: |-
+    Disable the feedback divider, active high.
+    1'b0: all output clocks with different frequencies (40MHz - 2.56GHz) are enabled.
+    1'b1: The input clk2G56 from the prescaler and all output clocks are disabled.
+    Debugging use only.
+  address:
+    - 0
+  mask:
+    - 0x40
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+PLLclkgen_disSER:
+  doc: |- # Potential name mismatch of registers between page 56 and page 60 of Users manual
+    Disable output clocks for serializer, active high.
+    When PLLclkgen_disSER is high, the following clocks are disabled:
+    clk2g56S, clk2g56SN, clk5g12S, clk5g12SN.
+    Debuggin use only.
+  address:
+    - 0
+  mask:
+    - 0x8
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+PLLclkgen_disVCO:
+  doc: |- # Potential name mismatch of registers between page 56 and page 60 of Users manual
+    Disable VCO output buffer (associated with clk5g12lshp, clk5g12lshn), active high.
+    clk5g12lsh is the output clock of the first input buffer in prescaler, and the source
+    clock for all output clocks. Once disabled, all output clocks are disabled.
+    Debugging use only.
+  address:
+    - 0
+  mask:
+    - 0x10
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+PLLclkgen_disEOM:
+  doc: |- # Potential name mismatch of registers between page 56 and page 60 of Users manual
+    Disable output clocks for EOM, active high. When PLLclkgen_disEOM is high, the following
+    clocks are disabled: clk5g12EOMp, clk5g12EOMn.
+    Debugging use only.
+  address:
+    - 0
+  mask:
+    - 0x4
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+PLLclkgen_disCLK:
+  doc: |- # Potential name mismatch of registers between page 56 and page 60 of Users manual
+    Disable the internal clock buffers and 1/2 clock divider in prescaler, active high. When
+    PLLclkgen_disCLK is high, all output clocks are disabled.
+    Debugging use only.
+  address:
+    - 0
+  mask:
+    - 0x1
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+PLLclkgen_disDES:
+  doc: |- # Potential name mismatch of registers between page 56 and page 60 of Users manual
+    Disable output clocks for deserializer, active high. When PLLclkgen_disDES is high, the
+    following clocks are disabled: clk2g56Qp, clk2g56Qn, clk2g56lp, clk2g56ln. clk2g56Q is
+    the 2.56 GHz clock for test in ETROC_PLL. clk2g56Q is used as WS clock in ETROC2.
+    Debugging use only.
+  address:
+    - 0
+  mask:
+    - 0x2
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+CLKSel:
+  doc: |-
+    Selecting PLL clock or off-chip clock for TDC and readout.
+    1'b0: using off-chip clocks for TDC and readout;
+    1'b1: using PLL clocks for TDC and readout.
+    Debugging use only.
+  address:
+    - 0
+  mask:
+    - 0x20
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+PS_CPCurrent:
+  doc: "Charge pump current control bits, range from 0 to 15uA for charge and discharge. Debugging use only."
+  address:
+    - 4
+  mask:
+    - 0xF
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+PS_CapRst:
+  doc: "Reset the control voltage of DLL to power supply, active high. Debugging use only."
+  address:
+    - 4
+  mask:
+    - 0x10
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+PS_Enable:
+  doc: "Enabling DLL, active high. Debugging use only."
+  address:
+    - 4
+  mask:
+    - 0x20
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+PS_ForceDown:
+  doc: "Force to pull down the output of the phase detector, active high. Debugging use only."
+  address:
+    - 4
+  mask:
+    - 0x40
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+PS_PhaseAdj:
+  doc: "Phase selecting control bits, PS_PhaseAdj[7:3] for coarse, PS_PhaseAdj[2:0] for fine."
+  address:
+    - 5
+  mask:
+    - 0xFF
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+CLK40_EnRx:
+  doc: "Enable the Rx for the 40 MHz reference clock, active high. Debugging use only."
+  address:
+    - 7
+  mask:
+    - 0x1
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+CLK40_EnTer:
+  doc: "Enable internal termination of the Rx for the 40 MHz reference clock, active high. Debugging use only."
+  address:
+    - 7
+  mask:
+    - 0x2
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+CLK40_Equ:
+  doc: |-
+    Equalization strength of the Rx for the 40 MHz reference clock.
+    2'b00: equalization is turned off;
+    2'b11: maximal equalization.
+    Debugging use only.
+  address:
+    - 7
+  mask:
+    - 0xC
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+CLK40_InvData:
+  doc: "Inverting data of the Rx for the 40 MHz reference clock, active high. Debugging use only."
+  address:
+    - 7
+  mask:
+    - 0x10
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+CLK40_SetCM:
+  doc: "Set common voltage of the Rx for the 40 MHz reference clock to 1/2 vdd, active high. Debugging use only."
+  address:
+    - 7
+  mask:
+    - 0x20
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+CLK1280_EnRx:
+  doc: "Enable the Rx for the 1.28 GHz clock, active high. Debugging use only."
+  address:
+    - 8
+  mask:
+    - 0x1
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+CLK1280_EnTer:
+  doc: "Enable the internal termination of the Rx for the 1.28 GHz clock, active high. Debugging use only."
+  address:
+    - 8
+  mask:
+    - 0x2
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+CLK1280_Equ:
+  doc: |-
+    Equalization strength of the Rx for the 1.28 GHz clock.
+    2'b00: equalization is turned off;
+    2'b11: maximal equalization.
+    Debugging use only.
+  address:
+    - 8
+  mask:
+    - 0xC
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+CLK1280_InvData:
+  doc: "Inverting data of the Rx for the 1.28 GHz clock, active high. Debugging use only."
+  address:
+    - 8
+  mask:
+    - 0x10
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+CLK1280_SetCM:
+  doc: "Set common voltage of the Rx for the 1.28 GHz clock to 1/2 vdd, active high. Debugging use only."
+  address:
+    - 8
+  mask:
+    - 0x20
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+FC_EnRx:
+  doc: "Enable the Rx for the fast command, active high. Debugging use only."
+  address:
+    - 9
+  mask:
+    - 0x1
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+FC_EnTer:
+  doc: "Enable internal termination of the Rx for the fast command, active high. Debugging use only."
+  address:
+    - 9
+  mask:
+    - 0x2
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+FC_Equ:
+  doc: |-
+    Equalization strength of the Rx for the fast command.
+    2'b00: equalization is turned off;
+    2'b11: maximal equalization.
+    Debugging use only.
+  address:
+    - 9
+  mask:
+    - 0xC
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+FC_InvData:
+  doc: "Inverting data of the Rx for the fast command, active high. Debugging use only."
+  address:
+    - 9
+  mask:
+    - 0x10
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+FC_SetCM:
+  doc: "Set common voltage of the Rx for the fast command to 1/2 vdd, active high. Debugging use only."
+  address:
+    - 9
+  mask:
+    - 0x20
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+disPowerSequence:
+  doc: "Disabling the power up sequence, active high."
+  address:
+    - 18
+  mask:
+    - 0x1
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+softBoot:
+  doc: "Reset power sequencer controller, active high."
+  address:
+    - 18
+  mask:
+    - 0x2
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+EFuse_TCKHP:
+  doc: |-
+    The register controlling the SCLK pulse width, ranging ranges from 3 us to 10 us with step of 0.5 us.
+    The default value is 4 corresponding to 5 us pulse width.
+    Debugging use only.
+  address:
+    - 20
+  mask:
+    - 0xF0
+  pixel:    0
+  stat:     0
+  default:  0x4
+
+EFuse_EnClk:
+  doc: |-
+    EFuse clock enable.
+    1'b1: enabling the clock of the EFuse controller;
+    1'b0: disabling the clock of the EFuse controller.
+  address:
+    - 21
+  mask:
+    - 0x1
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+EFuse_Mode:
+  doc: |-
+    Operation mode of EFuse.
+    2'b01: programming mode;
+    2'b10: reading mode.
+  address:
+    - 21
+  mask:
+    - 0x6
+  pixel:    0
+  stat:     0
+  default:  0x2
+
+EFuse_Rstn:
+  doc: "Reset signal of the EFuse controller, active low."
+  address:
+    - 21
+  mask:
+    - 0x8
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+EFuse_Start:
+  doc: "Start signal of the EFuse programming. A positive pulse will start the programming."
+  address:
+    - 21
+  mask:
+    - 0x10
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+EFuse_Prog:
+  doc: "Data to be written into EFuse."
+  address:
+    - 22
+    - 23
+    - 24
+    - 25
+  mask:
+    - 0xFF
+    - 0xFF
+    - 0xFF
+    - 0xFF
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+EFuse_Bypass:
+  doc: |-
+    Bypass EFuse.
+    1'b0: EFuse output Q[31:0] is output;
+    1'b1: EFuse raw data from I2C (EFuse_Prog[31:0]) is output.
+  address:
+    - 21
+  mask:
+    - 0x20
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+IfLockThrCounter:
+  doc: "If the number of instantLock is true for 2^IfLockThrCounter in a row, the PLL is locked in the initial status."
+  address:
+    - 30
+  mask:
+    - 0xF
+  pixel:    0
+  stat:     0
+  default:  0xB
+
+IfReLockThrCounter:
+  doc: "If the number of instantLock is true for 2^IfReLockThrCounter in a row, the PLL is relocked before the unlock status is confirmed."
+  address:
+    - 30
+  mask:
+    - 0xF0
+  pixel:    0
+  stat:     0
+  default:  0xB
+
+IfUnLockThrCounter:
+  doc: "If the number of instantLock is false for 2^IfUnLockThrCounter in a row, the PLL is unlocked."
+  address:
+    - 31
+  mask:
+    - 0xF
+  pixel:    0
+  stat:     0
+  default:  0xB
+
+asyAlignFastcommand:
+  doc: |-
+    The fast command bit clock alignment command is issued by I2C.
+    Used in self-alignment only.
+    Initializing the clock phase alignment process at its rising edge (synchronized by the 40 MHz PLL clock)
+  address:
+    - 13
+  mask:
+    - 0x20
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+asyLinkReset:
+  doc: "Link reset signal from I2C, active high. If it is high, ETROC2 sends test pattern via link."
+  address:
+    - 13
+  mask:
+    - 0x40
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+asyPLLReset:
+  doc: "Reset PLL AFC from I2C, active low."
+  address:
+    - 13
+  mask:
+    - 0x80
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+asyResetChargeInj:
+  doc: "Reset charge injection module, active low."
+  address:
+    - 14
+  mask:
+    - 0x20
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+asyResetFastcommand:
+  doc: "Reset fastcommand from I2C, active low."
+  address:
+    - 14
+  mask:
+    - 0x40
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+asyResetGlobalReadout:
+  doc: "Reset globalReadout module, active low."
+  address:
+    - 14
+  mask:
+    - 0x80
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+asyResetLockDetect:
+  doc: "Reset lock detect, active low (original lockDetect reset is active high, polarity changed)"
+  address:
+    - 15
+  mask:
+    - 0x20
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+asyStartCalibration:
+  doc: "Start PLL calibration process, active high."
+  address:
+    - 15
+  mask:
+    - 0x40
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+VRefGen_PD:
+  doc: |-
+    Power down voltage reference generator, active high.
+    1'b1: the voltage reference generator is down.
+    1'b0: the voltage reference generator is up.
+  address:
+    - 3
+  mask:
+    - 0x80
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+TS_PD:
+  doc: |-
+    Power down the temperature sensor, active high.
+    1'b1: the temperature sensor is down;
+    1'b0: the temperature sensor is up.
+  address:
+    - 4
+  mask:
+    - 0x80
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+TDCClockTest:
+  doc: |-
+    The TDC clock testing enable.
+    1'b1: sending TDC clock at the left serial port;
+    1'b0: sending left serializer data at the left port.
+  address:
+    - 31
+  mask:
+    - 0x10
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+TDCStrobeTest:
+  doc: |-
+    The TDC reference strobe testing enable.
+    1'b1: sending TDC reference strobe at the right serial port;
+    1'b0: sending right serializer data at the right port.
+  address:
+    - 31
+  mask:
+    - 0x20
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+LTx_AmplSel:
+  doc: |-
+    Left Tx amplitude selection.
+    3'b000: min amplitude (50 mV)
+    3'b111: max amplitude (320 mV)
+    Step size is about 40 mV.
+  address:
+    - 16
+  mask:
+    - 0xE0
+  pixel:    0
+  stat:     0
+  default:  0x4
+
+RTx_AmplSel:
+  doc: |-
+    Right Tx amplitude selection.
+    3'b000: min amplitude (50 mV)
+    3'b111: max amplitude (320 mV)
+    Step size is about 40 mV.
+  address:
+    - 17
+  mask:
+    - 0xE0
+  pixel:    0
+  stat:     0
+  default:  0x4
+
+disLTx:
+  doc: "Left Tx disable, active high."
+  address:
+    - 18
+  mask:
+    - 0x80
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+disRTx:
+  doc: "Right Tx disable, active high."
+  address:
+    - 19
+  mask:
+    - 0x80
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+GRO_TOARST_N:
+  doc: "GRO TOA reset, active low."
+  address:
+    - 7
+  mask:
+    - 0x80
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+GRO_Start:
+  doc: "GRO Start, active high."
+  address:
+    - 7
+  mask:
+    - 0x40
+  pixel:    0
+  stat:     0
+  default:  0x0
+
+GRO_TOA_Latch:
+  doc: "GRO TOA latch clock."
+  address:
+    - 8
+  mask:
+    - 0x80
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+GRO_TOA_CK:
+  doc: "GRO TOA clock."
+  address:
+    - 8
+  mask:
+    - 0x40
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+GRO_TOT_CK:
+  doc: "GRO TOT clock."  # Potential name mismatch of registers between page 58 and page 60 of Users manual
+  address:
+    - 9
+  mask:
+    - 0x80
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+GRO_TOTRST_N:
+  doc: "GRO TOT reset, active low."
+  address:
+    - 9
+  mask:
+    - 0x40
+  pixel:    0
+  stat:     0
+  default:  0x1
+
+############################################
+######## Peripheral Status Registers #######
+############################################
+
+fcBitAlignError:
+  doc: "Bit alignment error"
+  address:
+    - 2
+  mask:
+    - 0x1
+  pixel:    0
+  stat:     1
+
+PS_Late:
+  doc: "Phase shifter late"
+  address:
+    - 0
+  mask:
+    - 0x80
+  pixel:    0
+  stat:     1
+
+AFCcalCap:
+  doc: "AFC capacitance"
+  address:
+    - 0
+  mask:
+    - 0x7E
+  pixel:    0
+  stat:     1
+
+AFCBusy:
+  doc: "AFC busy, 1: AFC is ongoing, 0: AFC is done"
+  address:
+    - 0
+  mask:
+    - 0x1
+  pixel:    0
+  stat:     1
+
+fcAlignFinalState:
+  doc: "Fast command alignment FSM state"
+  address:
+    - 1
+  mask:
+    - 0xF0
+  pixel:    0
+  stat:     1
+
+controllerState:
+  doc: "Global control FSM state"
+  address:
+    - 1
+  mask:
+    - 0xF
+  pixel:    0
+  stat:     1
+
+fcAlignStatus:
+  doc: "Fast command self-alignment error indicator, ed[3:0] in figure 53"
+  address:
+    - 2
+  mask:
+    - 0xF0
+  pixel:    0
+  stat:     1
+
+invalidFCCount:
+  doc: "Count of invalid fast command received"
+  address:
+    - 3
+    - 4
+  mask:
+    - 0xFF
+    - 0xF
+  pixel:    0
+  stat:     1
+
+pllUnlockCount:
+  doc: "Count of PLL unlock detected"
+  address:
+    - 4
+    - 5
+  mask:
+    - 0xF0
+    - 0xFF
+  pixel:    0
+  stat:     1
+
+EFuseQ:
+  doc: "32-bit EFuse output"
+  address:
+    - 6
+    - 7
+    - 8
+    - 9
+  mask:
+    - 0xFF
+    - 0xFF
+    - 0xFF
+    - 0xFF
+  pixel:    0
+  stat:     1
diff --git a/tamalero/ETROC.py b/tamalero/ETROC.py
index 7495c88da44284d3ad0d80fa2dd92dee97cfa2a3..784e888517a52be86d847d98603821671b7ebe51 100644
--- a/tamalero/ETROC.py
+++ b/tamalero/ETROC.py
@@ -218,7 +218,9 @@ class ETROC():
             self.wr_reg('mergeTriggerData', 0)
             self.wr_reg('disScrambler', 1)
 
+    # ***********************
     # *** IN-PIXEL CONFIG ***
+    # ***********************
 
     # (FOR ALL PIXELS) set/get load capacitance of preamp first stage
     # 0, 80, 80, or 160 fC FIXME typo? 80 appears twice in doc
@@ -280,59 +282,68 @@ class ETROC():
         self.wr_reg('PD_DACDiscri', 1, row=row, col=col)
 
     # (FOR ALL PIXELS) set/get injected charge
-    # 1 ~ 36 fC, typical charge is 7fC
-    def set_Qinj(self, C):
+    # 1 ~ 32 fC, typical charge is 7fC
+    def set_Qinj(self, C, row=0, col=0, broadcast=True):
         if C > 32:
             raise Exception('Injected charge should be < 32 fC.')
-        self.wr_reg('QSel', 0, C-1)
+        self.wr_reg('QSel', C-1, row=row, col=col, broadcast=broadcast)
 
-    def get_Qinj(self):
-        return self.rd_reg('QSel', 0)+1
+    def get_Qinj(self, row=0, col=0):
+        return self.rd_reg('QSel', row=row, col=col)
 
-    # enable/disable charge injection
-    def enable_Qinj(self, pix):
-        self.wr_reg('QInjEn', pix, 1)
+    # (FOR ALL PIXELS) enable/disable charge injection
+    def enable_Qinj(self, row=0, col=0, broadcast=True):
+        self.wr_reg('QInjEn', 1, row=row, col=col, broadcast=broadcast)
 
-    def disable_Qinj(self, pix):
-        self.wr_reg('QInjEn', pix, 0)
+    def disable_Qinj(self, row=0, col=0, broadcast=True):
+        self.wr_reg('QInjEn', 0, row=row, col=col, broadcast=broadcast)
 
-    # TDC control
-    def autoReset_TDC(self, pix):
-        self.wr_reg('autoReset_TDC', pix, 1)
+    # (FOR ALL PIXELS) TDC control
+    # TDC automatically reset controller for every clock period
+    def autoReset_TDC(self, row=0, col=0, broadcast=True):
+        self.wr_reg('autoReset_TDC', 1, row=row, col=col, broadcast=broadcast)
 
-    def enable_TDC(self, pix):
-        self.wr_reg('enable_TDC', pix, 1)
+    # enable/disable TDC conversion
+    def enable_TDC(self, row=0, col=0, broadcast=True):
+        self.wr_reg('enable_TDC', 1, row=row, col=col, broadcast=broadcast)
 
-    def disable_TDC(self, pix):
-        self.wr_reg('enable_TDC', pix, 0)
+    def disable_TDC(self, row=0, col=0, broadcast=True):
+        self.wr_reg('enable_TDC', 0, row=row, col=col, broadcast=broadcast)
 
-    def set_level_TDC(self, pix, w):
+    # Bit width of bubble tolerant in TDC encode
+    def set_level_TDC(self, w, row=0, col=0, broadcast=True):
         if w > 0b011:
             raise Exception('bit width can be up to 0b011.')
-        self.wr_reg('level_TDC', pix, w)
+        self.wr_reg('level_TDC', w, row=row, col=col, broadcast=broadcast)
 
-    def get_level_TDC(self, pix):
-        return self.rd_reg('level_TDC', pix)
+    def get_level_TDC(self, row=0, col=0):
+        return self.rd_reg('level_TDC', row=row, col=col)
 
-    def reset_TDC(self, pix):
-        self.wr_reg('resetn_TDC', pix, 1) #FIXME reg name has typo in doc?
+    # Reset TDC encoder, active low
+    def reset_TDC(self, row=0, col=0, broadcast=True):
+        self.wr_reg('resetn_TDC', 0, row=row, col=col, broadcast=broadcast) #FIXME reg name has typo in doc?
 
-    def enable_TDC_testMode(self, pix):
-        self.wr_reg('testMode_TDC', pix, 1)
+    # enable/disable test mode where TDC generates a fixed test pulse as input signal for test for every 25 ns
+    def enable_TDC_testMode(self, row=0, col=0, broadcast=True):
+        self.wr_reg('testMode_TDC', 1, row=row, col=col, broadcast=broadcast)
 
-    def disable_TDC_testMode(self, pix):
-        self.wr_reg('testMode_TDC', pix, 0)
+    def disable_TDC_testMode(self, row=0, col=0, broadcast=True):
+        self.wr_reg('testMode_TDC', 0, row=row, col=col, broadcast=broadcast)
 
-    # threshold callibration
-    def bypass_THCal(self, pix):
-        self.wr_reg('Bypass_THCal', pix, 1)
+    # (FOR ALL PIXELS) THCal control
+    # Bypass/apply in-pixel threshold calibration block
+    def bypass_THCal(self, row=0, col=0, broadcast=True):
+        self.wr_reg('Bypass_THCal', 1, row=row, col=col, broadcast=broadcast)
 
-    def apply_THCal(self, pix):
-        self.wr_reg('Bypass_THCal', pix, 0)
-
-    def set_Vth_pix(self, pix, vth):
-        self.wr_reg('DAC', vth, pix)
+    def apply_THCal(self, row=0, col=0, broadcast=True):
+        self.wr_reg('Bypass_THCal', 0, row=row, col=col, broadcast=broadcast)
 
+    # When Bypass_THCal = 1, TH = DAC
+#    def set_Vth_pix(self, vth, row=0, col=0, broadcast=True):
+#        self.wr_reg('DAC', vth, row=row, col=col, broadcast=broadcast)
+#
+#    def get_Vth_pix(self, row=0, col=0):
+#        return self.rd_reg('DAC', row=row, col=col)
     def set_Vth_mV(self, vth, row=0, col=0, broadcast=True):
         # FIXME this needs to be understood
         # Pretend that we set the threshold and then the "DAC" register
@@ -358,122 +369,897 @@ class ETROC():
         th = self.rd_reg('DAC', row=row, col=col)
         return offset*offset_step + th*th_step
 
-    def set_THoffset(self, pix, V):
-        self.wr_reg('TH_offset', pix, V)
+    # Threshold offset for calibrated baseline. TH = BL + TH_offset
+#    def set_THoffset(self, V, row=0, col=0, broadcast=True):
+#        self.wr_reg('TH_offset', V, row=row, col=col, broadcast=broadcast)
+#
+#    def get_THoffset(self, row=0, col=0):
+#        return self.rd_reg('TH_offset', row=row, col=col)
 
-    def reset_THCal(self, pix):
-        self.wr_reg('RSTn_THCal', pix, 1)
+    # Reset of threshold calibration block, active low
+    def reset_THCal(self, row=0, col=0, broadcast=True):
+        self.wr_reg('RSTn_THCal', 0, row=row, col=col, broadcast=broadcast)
 
-    def init_THCal(self, pix): #FIXME better name?
-        self.wr_reg('ScanStart_THCal', pix, 1)
+    # Initialize threshold calibration
+    def init_THCal(self, row=0, col=0, broadcast=True): #FIXME better name?
+        self.wr_reg('ScanStart_THCal', 1, row=row, col=col, broadcast=broadcast)
 
-    def enable_THCal_buffer(self, pix):
-        self.wr_reg('BufEn_THCal', pix, 1)
+    # Enable/disable threshold calibration buffer
+    def enable_THCal_buffer(self, row=0, col=0, broadcast=True):
+        self.wr_reg('BufEn_THCal', 1, row=row, col=col, broadcast=broadcast)
 
-    def disable_THCal_buffer(self, pix):
-        self.wr_reg('BufEn_THCal', pix, 0)
+    def disable_THCal_buffer(self, row=0, col=0, broadcast=True):
+        self.wr_reg('BufEn_THCal', 0, row=row, col=col, broadcast=broadcast)
 
-    def enable_THCal_clock(self, pix):
-        self.wr_reg('CLKEn_THCal', pix, 1)
+    # Enable/disable threshold calibration clock. Only used when threshold calibration clock is bypassed.
+    def enable_THCal_clock(self, row=0, col=0, broadcast=True):
+        self.wr_reg('CLKEn_THCal', 1, row=row, col=col, broadcast=broadcast)
 
-    def disable_THCal_clock(self, pix):
-        self.wr_reg('CLKEn_THCal', pix, 0)
+    def disable_THCal_clock(self, row=0, col=0, broadcast=True):
+        self.wr_reg('CLKEn_THCal', 0, row=row, col=col, broadcast=broadcast)
 
-    def set_workMode(self, pix, mode):
+    # (FOR ALL PIXELS) Readout control
+    # Readout work mode selection
+    def set_workMode(self, mode, row=0, col=0, broadcast=True):
         val = {'normal': 0b00, 'self test fixed': 0b01, 'self test random': 0b10}
         try:
-            self.wr_reg('workMode', pix, val(mode))
+            self.wr_reg('workMode', val(mode), row=row, col=col, broadcast=broadcast)
         except KeyError:
             print('Choose between \'normal\', \'self test fixed\', \'self test random\'.')
 
-    def get_workMode(self, pix):
+    def get_workMode(self, row=0, col=0):
         val = {0b00:'normal', 0b01:'self test fixed', 0b10:'self test random'}
-        return val[self.wr_reg('workMod', pix)]
+        return val[self.wr_reg('workMode', row=row, col=col)]
 
-    def set_L1Adelay(self, pix, delay):
-        self.wr_reg('L1Adelay', pix, delay)
+    # L1A latency
+    def set_L1Adelay(self, delay, row=0, col=0, broadcast=True):
+        self.wr_reg('L1Adelay', delay, row=row, col=col, broadcast=broadcast)
 
-    def get_L1Adelay(self, pix):
-        return self.rd_reg('L1Adelay', pix)
+    def get_L1Adelay(self, row=0, col=0):
+        return self.rd_reg('L1Adelay', row=row, col=col)
 
-    def enable_data_readout(self, pix):
-        self.wr_reg('disDataReadout', pix, 0)
+    # Enable/disable TDC data readout of current pixel
+    def enable_data_readout(self, row=0, col=0, broadcast=True):
+        self.wr_reg('disDataReadout', 0, row=row, col=col, broadcast=broadcast)
 
-    def disable_data_readout(self, pix):
-        self.wr_reg('disDataReadout', pix, 1)
+    def disable_data_readout(self, row=0, col=0, broadcast=True):
+        self.wr_reg('disDataReadout', 1, row=row, col=col, broadcast=broadcast)
 
-    def enable_trigger_readout(self, pix):
-        self.wr_reg('disTrigPath', pix, 0)
+    # Enable/disable trigger readout of current pixel
+    def enable_trigger_readout(self, row=0, col=0, broadcast=True):
+        self.wr_reg('disTrigPath', 0, row=row, col=col, broadcast=broadcast)
 
-    def disable_trigger_readout(self, pix):
-        self.wr_reg('disTrigPath', pix, 1)
+    def disable_trigger_readout(self, row=0, col=0, broadcast=True):
+        self.wr_reg('disTrigPath', 1, row=row, col=col, broadcast=broadcast)
 
-    def set_trigger_TH(self, pix, datatype, upper=None, lower=None):
+    # Set upper/lower thresholds for trigger readout of TOA, TOT, Cal
+    def set_trigger_TH(self, datatype, upper=None, lower=None, row=0, col=0, broadcast=True):
         if datatype not in ['TOA', 'TOT', 'Cal']:
             raise Exception('type of data should be TOA, TOT or CAL.')
         if upper is not None:
-            self.wr_reg('upper'+data+'Trig', pix, upper)
+            self.wr_reg('upper'+data+'Trig', upper, row=row, col=col, broadcast=broadcast)
         if lower is not None:
-            self.wr_reg('lower'+data+'Trig', pix, lower)
+            self.wr_reg('lower'+data+'Trig', lower, row=row, col=col, broadcast=broadcast)
 
-    def get_trigger_TH(self, pix, datatype):
+    def get_trigger_TH(self, datatype, row=0, col=0):
         if datatype not in ['TOA', 'TOT', 'Cal']:
             raise Exception('type of data should be TOA, TOT or CAL.')
         upper = 'upper'+data+'Trig'
         lower = 'lower'+data+'Trig'
-        return self.rd_reg(upper, pix), self.rd_reg(lower, pix)
+        return self.rd_reg(upper, row=row, col=col), self.rd_reg(lower, row=row, col=col)
 
-    def set_data_TH(self, pix, datatype, upper=None, lower=None):
+    # Set upper/lower thresholds for TDC data readout of TOA, TOT, Cal
+    def set_data_TH(self, datatype, upper=None, lower=None, row=0, col=0, broadcast=True):
         if datatype not in ['TOA', 'TOT', 'Cal']:
             raise Exception('type of data should be TOA, TOT or CAL.')
         if upper is not None:
-            self.wr_reg('upper'+data, pix, upper)
+            self.wr_reg('upper'+data, upper, row=row, col=col, broadcast=broadcast)
         if lower is not None:
-            self.wr_reg('lower'+data, pix, lower)
+            self.wr_reg('lower'+data, lower, row=row, col=col, broadcast=broadcast)
 
-    def get_data_TH(self, pix, datatype):
+    def get_data_TH(self, datatype, row=0, col=0):
         if datatype not in ['TOA', 'TOT', 'Cal']:
             raise Exception('type of data should be TOA, TOT or CAL.')
         upper = 'upper'+data
         lower = 'lower'+data
-        return self.rd_reg(upper, pix), self.rd_reg(lower, pix)
+        return self.rd_reg(upper, row=row, col=col), self.rd_reg(lower, row=row, col=col)
 
-    def enable_adr_offset(self, pix):
-        self.wr_reg('addrOffset', pix, 1)
+    # Enable/disable circular buffer write address offset
+    def enable_adr_offset(self, row=0, col=0, broadcast=True):
+        self.wr_reg('addrOffset', 1, row=row, col=col, broadcast=broadcast)
 
-    def disable_adr_offset(self, pix):
-        self.wr_reg('addrOffset', pix, 0)
+    def disable_adr_offset(self, row=0, col=0, broadcast=True):
+        self.wr_reg('addrOffset', 0, row=row, col=col, broadcast=broadcast)
 
-    def set_selftest_occupancy(self, pix, occ):
-        self.wr_reg('selfTestOccupancy', pix, occ)
+    # Self-test data occupancy is selfTestOccupancy[6:0]/128
+    def set_selftest_occupancy(self, occ, row=0, col=0, broadcast=True):
+        self.wr_reg('selfTestOccupancy', occ, row=row, col=col, broadcast=broadcast)
 
-    def get_selftest_occupancy(self, pix):
-        return self.rd_reg('selfTestOccupancy', pix)
+    def get_selftest_occupancy(self, row=0, col=0):
+        return self.rd_reg('selfTestOccupancy', row=row, col=col)
 
 
+    # ***********************
     # *** IN-PIXEL STATUS ***
+    # ***********************
 
-    def get_ACC(self, pix):
-        return self.rd_reg('ACC', pix)
+    # (FOR ALL PIXELS) Accumulator of the threshold calibration
+    def get_ACC(self, row=0, col=0):
+        return self.rd_reg('ACC', row=row, col=col)
 
-    def is_scanDone(self, pix):
-        result = self.rd_reg('ScanDone', pix)
+    # (FOR ALL PIXELS) Scan done signal of the threshold calibration
+    def is_scanDone(self, row=0, col=0):
+        result = self.rd_reg('ScanDone', row=row, col=col)
         if result == 1:
             return True
         else:
             return False
 
-    def get_baseline(self, pix):
-        return self.rd_reg('BL', pix)
+    # (FOR ALL PIXELS) Baseline obtained from threshold calibration
+    def get_baseline(self, row=0, col=0):
+        return self.rd_reg('BL', row=row, col=col)
+
+    # (FOR ALL PIXELS) Noise width from threshold calibration. Expect less than 10.
+    def get_noisewidth(self, row=0, col=0):
+        return self.rd_reg('NW', row=row, col=col)
+
+    # (FOR ALL PIXELS) 10-bit threshold applied to the DAC input
+    def get_threshold(self, row=0, col=0):
+        return self.rd_reg('TH', row=row, col=col)
+
+    # (FOR ALL PIXELS) Threshold calibration state machine output
+    def get_THstate(self, row=0, col=0):
+        return self.rd_reg('THstate', row=row, col=col)
+
+    # (FOR ALL PIXELS) Col[3:0], Row[3:0]
+    def get_pixelID(self, row=0, col=0):
+        return self.rd_reg('PixelID', row=row, col=col)
+
+    # ***********************
+    # **** PERIPH CONFIG ****
+    # ***********************
+
+    # Phase delay of readout clock, 780 ps a step (Pixel or Global)
+    def set_readoutClkDelay(self, clk, delay):
+        if clk not in ['Pixel', 'Global']:
+            raise Exception('Clock should be either Pixel or Global')
+        self.wr_reg('readoutClockDelay'+clk, delay)
+
+    def get_readoutClkDelay(self, clk):
+        if clk not in ['Pixel', 'Global']:
+            raise Exception('Clock should be either Pixel or Global')
+        return self.rd_reg('readoutClockDelay'+clk)
+
+    # Positive pulse width of readout clock, 780 ps a step (Pixel or Global)
+    def set_readoutClkWidth(self, clk, width):
+        if clk not in ['Pixel', 'Global']:
+            raise Exception('Clock should be either Pixel or Global')
+        self.wr_reg('readoutClockWidth'+clk, width)
+
+    def get_readoutClkWidth(self, clk):
+        if clk not in ['Pixel', 'Global']:
+            raise Exception('Clock should be either Pixel or Global')
+        return self.rd_reg('readoutClockWidth'+clk)
+
+    # Data rate selection of Right or Left serial port
+    def set_dataRate(self, port, rate):
+        if port not in ['Left', 'Right']:
+            raise Exception('Choose between Left or Right serial port')
+        val = {320:0b00, 640:0b01, 1280:0b10}
+        try:
+            self.wr_reg('serRate'+port, val[rate])
+        except KeyError:
+            print('Choose between rates of 320 Mbps, 640 Mbps and 1280 Mbps')
+
+    def get_dataRate(self, port):
+        if port not in ['Left', 'Right']:
+            raise Exception('Choose between Left or Right serial port')
+        val = {0b00:320, 0b01:640, 0b10:1280}
+        return val[self.rd_reg('serRate'+port)]
+
+    # Link reset test pattern selection
+    def set_linkResetTestPattern(self, mode):
+        val = {'PRBS':0b0, 'Fixed pattern':0b1}
+        try:
+            self.wr_reg('linkResetTestPattern', val[mode])
+        except KeyError:
+            print('Choose between \'PRBS\' and \'Fixed pattern\' selections')
+
+    def get_linkResetTestPattern(self):
+        val = {0b0:'PRBS', 0b1:'Fixed pattern'}
+        return val[self.rd_reg('linkResetTestPattern')]
+
+    # User-specified pattern to be sent during link reset, LSB first
+    def set_linkResetFixedPattern(self, pattern):
+        self.wr_reg('linkResetFixedPattern', pattern)
+
+    def get_linkResetFixedPattern(self):
+        return self.rd_reg('linkResetFixedPattern')
+
+    # Empty BCID slot for synchronization
+    def set_BCID(self, bcid):
+        self.wr_reg('emptySlotBCID', bcid)
+
+    def get_BCID(self):
+        return self.rd_reg('emptySlotBCID')
+
+    # Trigger data size, can be 0, 1, 2, 4, 8, 16
+    def set_triggerGranularity(self, size):
+        val = {0:0, 1:1, 2:2, 4:3, 8:4, 16:5}
+        try:
+            self.wr_reg('triggerGranularity', val[size])
+        except KeyError:
+            print('Trigger data size can only be 0, 1, 2, 4, 8 or 16')
+
+    def get_triggerGranularity(self):
+        val = {0:0, 1:1, 2:2, 3:4, 4:8, 5:16, 6:0, 7:0}
+        return val[self.rd_reg('triggerGranularity')]
+
+    # Enable/disable scrambler
+    def enable_Scrambler(self):
+        self.wr_reg('disScrambler', 0)
+
+    def disable_Scrambler(self):
+        self.wr_reg('disScrambler', 1)
+
+    # Merge trigger and data in a port
+    def set_mergeTriggerData(self, mode):
+        val = {'separate':0, 'merge':1}
+        if (self.get_singlePort == 'right') and (mode == 'separate'):
+            raise Exception('Trigger and data in separate ports is only allowed when singlePort is set to \'both\'')
+        try:
+            self.wr_reg('mergeTriggerData', val[mode])
+        except KeyError:
+            print('Choose between \'merge\' and \'separate\' options')
+
+    def get_mergeTriggerData(self):
+        val = {0: 'separate', 1:'merge'}
+        return val[self.rd_reg('mergeTriggerData')]
+
+    # Enable single port (right) or both ports
+    def set_singlePort(self, mode):
+        val = {'both':0, 'right':1}
+        try:
+            self.wr_reg('singlePort', val[mode])
+        except KeyError:
+            print('Choose between \'both\' and \'right\' options')
+
+    def get_singlePort(self):
+        val = {0:'both', 1:'right'}
+        return val[self.rd_reg('singlePort')]
+
+    # On-chip L1A mode
+    def set_l1aMode(self, mode):
+        val = {'disable':0b00, 'periodic':0b10, 'random':0b11}
+        try:
+            self.wr_reg('onChipL1AConf', val[mode])
+        except KeyError:
+            print('Choose between \'disable\', \'periodic\' and \'random\' options')
+
+    def get_l1aMode(self):
+        val = {0b00:'disable', 0b10:'periodic', 0b11:'random', 0b01:'disable'}
+        return val[self.rd_reg('onChipL1AConf')]
+
+    # BCID when BCID is reset
+    def set_BCIDoffset(self, offset):
+        self.wr_reg('BCIDoffset', offset)
+
+    def get_BCIDoffset(self, offset):
+        self.rd_reg('BCIDoffset')
+
+    # Fast command decoder self-alignment or manual alignment
+    def set_fcAlign(self, mode):
+        val = {'manual':0, 'self':1}
+        try:
+            self.wr_reg('fcSelfAlignEn', val[mode])
+        except KeyError:
+            print('Choose between \'manual\' and \'self\' options')
+
+    def get_fcAlign(self):
+        val = {0:'manual', 1:'self'}
+        return val[self.rd_reg('fcSelfAlignEn')]
+
+    # Enable/disable clock delay in fast command manual alignment mode
+    def enable_fcClkDelay(self):
+        assert self.get_fcAlign() == 'manual'
+        self.wr_reg('fcClkDelayEn', 1)
+
+    def disable_fcClkDelay(self):
+        assert self.get_fcAlign() == 'manual'
+        self.wr_reg('fcClkDelayEn', 0)
+
+    # Enable/disable data delay in fast command manual alignment mode, active high
+    def enable_fcDataDelay(self):
+        assert self.get_fcAlign() == 'manual'
+        self.wr_reg('fcDataDelayEn', 1)
+
+    def disable_fcDataDelay(self):
+        assert self.get_fcAlign() == 'manual'
+        self.wr_reg('fcDataDelayEn', 0)
+
+    # The charge injection delay to the 40 MHz clock rising edge. Start from rising edge
+    # of 40 MHz clock, each step 781 ps. The pulse width is fixed of 50 ns.
+    def set_chargeInjDelay(self, delay):
+        self.wr_reg('chargeInjectionDelay', delay)
+
+    def get_chargeInjDelay(self):
+        return self.rd_reg('chargeInjectionDelay')
+
+    # TDC Reference strobe selection
+    def set_refStr(self, refStr):
+        self.wr_reg('RefStrSel', refStr)
+
+    def get_refStr(self):
+        return self.rd_reg('RefStrSel')
+
+    # Charge pump bias current selection, [0:8:120] uA. Debugging use only.
+    def set_PLLBiasGen(self, bias):
+        self.wr_reg('PLL_BIASGEN_CONFIG', bias)
+
+    def get_PLLBiasGen(self):
+        return self.rd_reg('PLL_BIASGEN_CONFIG')
+
+    # Bias current selection of the I-filter (0:1.1:8 uA) or P-filter (0:5.46:82 uA) unit cell in PLL mod. Debugging use only.
+    def set_PLLConfig(self, filt, bias):
+        if filt not in ['I', 'P']:
+            raise Exception('Choose between \'I\' or \'P\' filter')
+        self.wr_reg('PLL_CONFIG_'+filt+'_PLL', bias)
+
+    def get_PLLConfig(self, filt):
+        if filt not in ['I', 'P']:
+            raise Exception('Choose between \'I\' or \'P\' filter')
+        return self.rd_reg('PLL_CONFIG_'+filt+'_PLL')
+
+    # Resistor selection of the P-path in PLL mode [R=1/2*79.8k/CONFIG] Ohm. Debugging use only.
+    def set_PLLRes(self, R):
+        config = 1 / (2 * 79.8e3) / R
+        self.wr_reg('PLL_R_CONFIG', config)
+
+    def get_PLLRes(self):
+        config = self.rd_reg('PLL_R_CONFIG')
+        R = 1 / (2 * 79.8e3) / config
+        return R
+
+    # Bias current selection of the VCO core [0:0.470:7.1] mA. Debugging use only.
+    def set_PLLvco(self, bias):
+        self.wr_reg('PLL_vcoDAC', bias)
+
+    def get_PLLvco(self):
+        return self.rd_reg('PLL_vcoDAC')
+
+    # Output rail-to-rail mode selection of the VCO, active low. Debugging use only.
+    def set_PLLvcoRail(self, mode):
+        if mode not in ['rail', 'CML']:
+            raise Exception('Chose between \'rail\' and \'CML\' options')
+        val = {'rail':0, 'CML':1}
+        self.wr_reg('PLL_vcoRailMode', val[mode])
+
+    def get_PLLvcoRail(self):
+        val = {0:'rail', 'CML':1}
+        return val[self.rd_reg('PLL_vcoRailMode')]
+
+    # Enable/disable PLL mode, active high. Debugging use only.
+    def enable_PLL(self):
+        self.wr_reg('PLL_ENABLEPLL', 1)
+
+    def disable_PLL(self):
+        self.wr_reg('PLL_ENABLEPLL', 0)
+
+    # Adjusting the phase of the output clk1G28 of freqPrescaler in the feedback
+    # divider (N=64) by one skip from low to high. Debugging use only.
+    def set_PLLFBDiv(self, skip):
+        self.wr_reg('PLL_FBDiv_skip', skip)
+
+    def get_PLLFBDiv(self):
+        return self.rd_reg('PLL_FBDiv_skip')
+
+    # Enable/disable feedback divider
+    def enable_PLLFB(self):
+        self.wr_reg('PLL_FBDiv_clkTreeDisable', 0)
+
+    def disable_PLLFB(self):
+        self.wr_reg('PLL_FBDiv_clkTreeDisable', 1)
+
+    # Enable/disable output clocks for serializer
+    def enable_PLLclkSer(self):
+        self.wr_reg('PLLclkgen_disSER', 0)
+
+    def disable_PLLclkSer(self):
+        self.wr_reg('PLLclkgen_disSER', 1)
+
+    # Enable/disable VCO output buffer (associated with clk5g12lshp, clk5g12lshn), active high.
+    # clk5g12lsh is the output clock of the first input buffer in prescaler, and the source
+    # clock for all output clocks. Once disabled, all output clocks are disabled. Debugging use only.
+    def enable_PLLvcoBuff(self):
+        self.wr_reg('PLLclkgen_disVCO', 0)
+
+    def disable_PLLvcoBuff(self):
+        self.wr_reg('PLLclkgen_disVCO', 1)
+
+    # Enable/disable output clocks for EOM, active high. When PLLclkgen_disEOM is high, the following
+    # clocks are disabled: clk5g12EOMp, clk5g12EOMn. Debugging use only.
+    def enable_PLLEOM(self):
+        self.wr_reg('PLLclkgen_disEOM', 0)
+
+    def disable_PLLEOM(self):
+        self.wr_reg('PLLclkgen_disEOM', 1)
+
+    # Enable/disable the internal clock buffers and 1/2 clock divider in prescaler, active high. When
+    # PLLclkgen_disCLK is high, all output clocks are disabled. Debugging use only.
+    def enable_PLLclk(self):
+        self.wr_reg('PLLclkgen_disCLK', 0)
+
+    def disable_PLLclk(self):
+        self.wr_reg('PLLclkgen_disCLK', 1)
+
+    # Enable/disable output clocks for deserializer, active high. When PLLclkgen_disDES is high, the
+    # following clocks are disabled: clk2g56Qp, clk2g56Qn, clk2g56lp, clk2g56ln. clk2g56Q is
+    # the 2.56 GHz clock for test in ETROC_PLL. clk2g56Q is used as WS clock in ETROC2. Debugging use only.
+    def enable_PLLDes(self):
+        self.wr_reg('PLLclkgen_disDES', 0)
+
+    def disable_PLLDes(self):
+        self.wr_reg('PLLclkgen_disDES', 1)
+
+    # Selecting PLL clock or off-chip clock for TDC and readout. Debugging use only.
+    def set_CLKSel(self, clk):
+        if clk not in ['off-chip', 'PLL']:
+            raise Exception('Choose between \'off-chip\' and \'PLL\' options')
+        val = {'off-chip':0, 'PLL':1}
+        self.wr_reg('CLKSel', val[clk])
+
+    def get_CLKSel(self):
+        val = {0:'off-chip', 1:'PLL'}
+        return val[self.rd_reg('CLKSel')]
+
+    # Charge pump current control bits, range from 0 to 15uA for charge and discharge. Debugging use only.
+    def set_CPCurrent(self, current):
+        self.wr_reg('PS_CPCurrent', current)
+
+    def get_CPCurrent(self):
+        return self.rd_reg('PS_CPCurrent')
+
+    # Reset the control voltage of DLL to power supply, active high. Debugging use only.
+    def toggle_CapRst(self):
+        val = ~self.get_CapRst()
+        self.wr_reg('PS_CapRst', val)
+
+    def get_CapRst(self):
+        return self.rd_reg('PS_CapRst')
+
+    # Enable/disable DLL, active high. Debugging use only.
+    def enable_DLL(self):
+        self.wr_reg('PS_Enable', 1)
+
+    def disable_DLL(self):
+        self.wr_reg('PS_Enable', 0)
+
+    # Force to pull down the output of the phase detector, active high. Debugging use only.
+    def set_PSForceDown(self, boolean):
+        if not isinstance(boolean, bool):
+            raise TypeError('Argument must be a boolean')
+        val = 1 if boolean else 0
+        self.wr_reg('PS_ForceDown', val)
+
+    def get_PSForceDown(self):
+        val = self.rd_reg('PS_ForceDown')
+        return True if val == 1 else False
+
+    # Phase selecting control bits, PS_PhaseAdj[7:3] for coarse, PS_PhaseAdj[2:0] for fine.
+    def set_PhaseAdj(self, phase):
+        self.wr_reg('PS_PhaseAdj', phase)
+
+    def get_PhaseAdj(self):
+        return self.rd_reg('PS_PhaseAdj')
+
+    # Enable/disable the Rx for the 40 MHz, 1.28 GHz reference clock or the fast command, active high. Debugging use only
+    def set_Rx(self, mode, boolean):
+        if not isinstance(boolean, bool):
+            raise TypeError('Argument must be True (enable) or False (disable)')
+        val  = 1 if boolean else 0
+        regs = {40:'CLK40_EnRx', 1280:'CLK1280_EnRx', 'FC':'FC_EnRx'}
+        try:
+            self.wr_reg(regs[mode], val)
+        except KeyError:
+            print('Choose between 40 (40 MHz ref. clock), 1280 (1.28 GHz ref. clock) and \'FC\' (fast command) options')
+
+    def get_Rx(self, mode):
+        regs = {40:'CLK40_EnRx', 1280:'CLK1280_EnRx', 'FC':'FC_EnRx'}
+        try:
+            return self.rd_reg(regs[mode])
+        except KeyError:
+            print('Choose between 40 (40 MHz ref. clock), 1280 (1.28 GHz ref. clock) and \'FC\' (fast command) options')
+
+    # Enable/disable internal termination of the Rx for the 40 MHz, 1.28 GHz reference clock or the fast command, active high. Debugging use only.
+    def set_Ter(self, mode, boolean):
+        if not isinstance(boolean, bool):
+            raise TypeError('Argument must be True (enable) or False (disable)')
+        val  = 1 if boolean else 0
+        regs = {40:'CLK40_EnTer', 1280:'CLK1280_EnTer', 'FC':'FC_EnTer'}
+        try:
+            self.wr_reg(regs[mode], val)
+        except KeyError:
+            print('Choose between 40 (40 MHz ref. clock), 1280 (1.28 GHz ref. clock) and \'FC\' (fast command) options')
+
+    def get_Ter(self, mode):
+        regs = {40:'CLK40_EnTer', 1280:'CLK1280_EnTer', 'FC':'FC_EnTer'}
+        try:
+            return self.rd_reg(regs[mode])
+        except KeyError:
+            print('Choose between 40 (40 MHz ref. clock), 1280 (1.28 GHz ref. clock) and \'FC\' (fast command) options')
+
+    # Equalization strength of the Rx for the 40 MHz, 1.28 GHz reference clock or the fast command. Debugging use only.
+    # 2'b00: equalization is turned off; 2'b11: maximal equalization.
+    def set_Equ(self, mode, equalization):
+        regs = {40:'CLK40_Equ', 1280:'CLK1280_Equ', 'FC':'FC_Equ'}
+        try:
+            self.wr_reg(regs[mode], equalization)
+        except KeyError:
+            print('Choose between 40 (40 MHz ref. clock), 1280 (1.28 GHz ref. clock) and \'FC\' (fast command) options for \'mode\' arg.')
+
+    def get_Equ(self, mode):
+        regs = {40:'CLK40_Equ', 1280:'CLK1280_Equ', 'FC':'FC_Equ'}
+        try:
+            return self.rd_reg(regs[mode])
+        except KeyError:
+            print('Choose between 40 (40 MHz ref. clock), 1280 (1.28 GHz ref. clock) and \'FC\' (fast command) options')
+
+    # Inverting data of the Rx for the 40 MHz, 1.28 GHz reference clock or the fast command, active high. Debugging use only.
+    def set_Inv(self, mode, boolean):
+        if not isinstance(boolean, bool):
+            raise TypeError('Argument must be True (invert) or False (don\'t invert)')
+        val  = 1 if boolean else 0
+        regs = {40:'CLK40_InvData', 1280:'CLK1280_InvData', 'FC':'FC_InvData'}
+        try:
+            self.wr_reg(regs[mode], val)
+        except KeyError:
+            print('Choose between 40 (40 MHz ref. clock), 1280 (1.28 GHz ref. clock) and \'FC\' (fast command) options')
+
+    def get_Inv(self, mode):
+        regs = {40:'CLK40_InvData', 1280:'CLK1280_InvData', 'FC':'FC_InvData'}
+        try:
+            return self.rd_reg(regs[mode])
+        except KeyError:
+            print('Choose between 40 (40 MHz ref. clock), 1280 (1.28 GHz ref. clock) and \'FC\' (fast command) options')
+
+    # Set common voltage of the Rx for the 40 MHz, 1.28 GHz reference clock or the fast command to 1/2 vdd, active high. Debugging use only.
+    def set_commonV(self, mode, boolean):
+        if not isinstance(boolean, bool):
+            raise TypeError('Argument must be True (set) or False (don\'t set)')
+        val  = 1 if boolean else 0
+        regs = {40:'CLK40_SetCM', 1280:'CLK1280_SetCM', 'FC':'FC_SetCM'}
+        try:
+            self.wr_reg(regs[mode], val)
+        except KeyError:
+            print('Choose between 40 (40 MHz ref. clock), 1280 (1.28 GHz ref. clock) and \'FC\' (fast command) options')
+
+    def get_commonV(self, mode):
+        regs = {40:'CLK40_SetCM', 1280:'CLK1280_SetCM', 'FC':'FC_SetCM'}
+        try:
+            return self.rd_reg(regs[mode])
+        except KeyError:
+            print('Choose between 40 (40 MHz ref. clock), 1280 (1.28 GHz ref. clock) and \'FC\' (fast command) options')
+
+    # Enable/disable the power up sequence, active high
+    def enable_PowerUp(self):
+        self.wr_reg('disPowerSequence', 0)
+
+    def disable_PowerUp(self):
+        self.wr_reg('disPowerSequence', 1)
+
+    # Reset power sequencer controller, active high
+    def reset_Power(self):
+        self.wr_reg('softBoot', 1)
+
+    # The register controlling the SCLK pulse width, ranging ranges from 3 us to 10 us with step of 0.5 us.
+    # The default value is 4 corresponding to 5 us pulse width. Debugging use only.
+    def set_SCLKWidth(self, width):
+        self.wr_reg('EFuse_TCKHP', width)
+
+    def get_SCLKWidth(self):
+        return self.rd_reg('EFuse_TCKHP')
+
+    # Enable/disable EFuse clock
+    def enable_EFuseClk(self):
+        self.wr_reg('EFuse_EnClk', 1)
+
+    def disable_EFuseClk(self):
+        self.wr_reg('EFuse_EnClk', 0)
+
+    # Operation mode of EFuse.
+    # 2'b01: programming mode;
+    # 2'b10: reading mode.
+    def set_EFuseMode(self, mode):
+        val = {'programming':0b01, 'reading':0b10}
+        try:
+            self.wr_reg('EFuse_Mode', val[mode])
+        except KeyError:
+            print('Choose between \'programming\' and \'reading\' options')
+
+    def get_EFuseMode(self):
+        val = {0b01:'programming', 0b10:'reading'}
+        return val[self.rd_reg('EFuse_Mode')]
+
+    # Reset signal of the EFuse controller, active low
+    def reset_EFuse(self):
+        self.wr_reg('EFuse_Rstn', 0)
+
+    # Start signal of the EFuse programming. A positive pulse will start the programming
+    def start_EFuse(self):
+        self.wr_reg('EFuse_Start', 1)
+
+    # Data to be written into EFuse
+    def set_EFuseDat(self, data):
+        self.wr_reg('EFuse_Prog', data)
+
+    def get_EFuseDat(self):
+        return self.rd_reg('EFuse_Prog')
+
+    # Bypass EFuse.
+    # 1'b0: EFuse output Q[31:0] is output;
+    # 1'b1: EFuse raw data from I2C (EFuse_Prog[31:0]) is output
+    def bypass_EFuse(self, bypass):
+        if not isinstance(bypass, bool):
+            raise TypeError('Argument must be True (bypass) or False (don\'t bypass)')
+        val = 1 if bypass else 0
+        self.wr_reg('EFuse_Bypass', val)
+
+    # If the number of instantLock is true for 2^IfLockThrCounter in a row, the PLL is locked in the initial status
+    def set_IfLockThrCounter(self, counter):
+        self.wr_reg('IfLockThrCounter', counter)
+
+    def get_IfLockThrCounter(self):
+        return self.rd_reg('IfLockThrCounter')
+
+    # If the number of instantLock is true for 2^IfReLockThrCounter in a row, the PLL is relocked before the unlock status is confirmed
+    def set_IfReLockThrCounter(self, counter):
+        self.wr_reg('IfReLockThrCounter', counter)
+
+    def get_IfReLockThrCounter(self):
+        return self.rd_reg('IfReLockThrCounter')
+
+    # If the number of instantLock is false for 2^IfUnLockThrCounter in a row, the PLL is unlocked
+    def set_IfUnLockThrCounter(self, counter):
+        self.wr_reg('IfUnLockThrCounter', counter)
+
+    def get_IfUnLockThrCounter(self):
+        return self.rd_reg('IfUnLockThrCounter')
+
+    # The fast command bit clock alignment command is issued by I2C.
+    # Used in self-alignment only.
+    # Initializing the clock phase alignment process at its rising edge (synchronized by the 40 MHz PLL clock)
+    def enable_FCClkPhaseAlign(self):
+        assert self.get_fcAlign() == 'self'
+        self.wr_reg('asyAlignFastcommand', 1)
+
+    def disable_FCClkPhaseAlign(self):
+        assert self.get_fcAlign() == 'self'
+        self.wr_reg('asyAlignFastcommand', 0)
+
+    # Link reset signal from I2C, active high. If it is high, ETROC2 sends test pattern via link
+    def set_LinkReset(self, reset):
+        if not isinstance(reset, bool):
+            raise TypeError('Argument must be True (reset) or False (don\'t reset)')
+        val = 1 if reset else 0
+        self.wr_reg('asyLinkReset', val)
+
+    def get_LinkReset(self):
+        return self.rd_reg('asyLinkReset')
+
+    # Reset PLL AFC from I2C, active low
+    def set_PLLReset(self, reset):
+        if not isinstance(reset, bool):
+            raise TypeError('Argument must be True (reset) or False (don\'t reset)')
+        val = 0 if reset else 1
+        self.wr_reg('asyPLLReset', val)
+
+    def get_PLLReset(self):
+        return self.rd_reg('asyPLLReset')
+
+    # Reset charge injection module, active low
+    def set_ChargeInjReset(self, reset):
+        if not isinstance(reset, bool):
+            raise TypeError('Argument must be True (reset) or False (don\'t reset)')
+        val = 0 if reset else 1
+        self.wr_reg('asyResetChargeInj', val)
+
+    def get_ChargeInjReset(self):
+        return self.rd_reg('asyResetChargeInj')
+
+    # Reset fastcommand from I2C, active low
+    def set_FCReset(self, reset):
+        if not isinstance(reset, bool):
+            raise TypeError('Argument must be True (reset) or False (don\'t reset)')
+        val = 0 if reset else 1
+        self.wr_reg('asyResetFastcommand', val)
+
+    def get_FCReset(self):
+        return self.rd_reg('asyResetFastcommand')
+
+    # Reset globalReadout module, active low
+    def set_GlobalReadoutReset(self, reset):
+        if not isinstance(reset, bool):
+            raise TypeError('Argument must be True (reset) or False (don\'t reset)')
+        val = 0 if reset else 1
+        self.wr_reg('asyResetGlobalReadout', val)
+
+    def get_GlobalReadoutReset(self):
+        return self.rd_reg('asyResetGlobalReadout')
+
+    # Reset lock detect, active low (original lockDetect reset is active high, polarity changed)
+    def set_LockDetectReset(self, reset):
+        if not isinstance(reset, bool):
+            raise TypeError('Argument must be True (reset) or False (don\'t reset)')
+        val = 0 if reset else 1
+        self.wr_reg('asyResetLockDetect', val)
+
+    def get_LockDetectReset(self):
+        return self.rd_reg('asyResetLockDetect')
+
+    # Start PLL calibration process, active high
+    def start_PLLCal(self):
+        self.wr_reg('asyStartCalibration', 1)
+
+    def stop_PLLCal(self):
+        self.wr_reg('asyStartCalibration', 0)
+
+    # Power down voltage reference generator, active high.
+    # 1'b1: the voltage reference generator is down.
+    # 1'b0: the voltage reference generator is up.
+    def power_up_VRef(self):
+        self.wr_reg('VRefGen_PD', 0)
+
+    def power_down_VRef(self):
+        self.wr_reg('VRefGen_PD', 1)
+
+    # Power down the temperature sensor, active high.
+    # 1'b1: the temperature sensor is down;
+    # 1'b0: the temperature sensor is up.
+    def power_up_TempSen(self):
+        self.wr_reg('TS_PD', 0)
+
+    def power_down_TempSen(self):
+        self.wr_reg('TS_PD', 1)
+
+    # The TDC clock testing enable.
+    # 1'b1: sending TDC clock at the left serial port;
+    # 1'b0: sending left serializer data at the left port.
+    def enable_TDCClkTest(self):
+        self.wr_reg('TDCClockTest', 1)
+
+    def disable_TDCClkTest(self):
+        self.wr_reg('TDCClockTest', 0)
+
+    # The TDC reference strobe testing enable.
+    # 1'b1: sending TDC reference strobe at the right serial port;
+    # 1'b0: sending right serializer data at the right port.
+    def enable_TDCRefStrTest(self):
+        self.wr_reg('TDCStrobeTest', 1)
+
+    def disable_TDCRefStrTest(self):
+        self.wr_reg('TDCStrobeTest', 0)
+
+    # Left/Right Tx amplitude selection.
+    # 3'b000: min amplitude (50 mV)
+    # 3'b111: max amplitude (320 mV)
+    # Step size is about 40 mV.
+    def set_TxAmplSel(self, side, amp):
+        regs = {'left':'LTx_AmplSel', 'right':'RTx_AmplSel'}
+        try:
+            self.wr_reg(regs[side], amp)
+        except KeyError:
+            print('Choose between \'left\' or \'right\' side options')
+
+    def get_TxAmplSel(self, side):
+        regs = {'left':'LTx_AmplSel', 'right':'RTx_AmplSel'}
+        try:
+            return self.rd_reg(regs[side])
+        except KeyError:
+            print('Choose between \'left\' or \'right\' side options')
+
+    # Left/Right Tx disable, active high.
+    def enable_Tx(self, side):
+        regs = {'left':'disLTx', 'right':'disRTx'}
+        try:
+            self.wr_reg(regs[side], 0)
+        except KeyError:
+            print('Choose between \'left\' or \'right\' side options')
+
+    def disable_Tx(self, side):
+        regs = {'left':'disLTx', 'right':'disRTx'}
+        try:
+            self.wr_reg(regs[side], 1)
+        except KeyError:
+            print('Choose between \'left\' or \'right\' side options')
+
+    # GRO TOA reset, active low
+    def set_GROTOAReset(self, reset):
+        if not isinstance(reset, bool):
+            raise TypeError('Argument must be True (reset) or False (don\'t reset)')
+        val = 0 if reset else 1
+        self.wr_reg('GRO_TOARST_N', val)
+
+    def get_GROTOAReset(self):
+        return self.rd_reg('GRO_TOARST_N')
+
+    # GRO Start, active high.
+    def start_GRO(self):
+        self.wr_reg('GRO_Start', 1)
+
+    def stop_GRO(self):
+        self.wr_reg('GRO_Start', 0)
+
+    # GRO TOA latch clock. (Guessing this means enable/disable)
+    def enable_GROTOALatch(self):
+        self.wr_reg('GRO_TOA_Latch', 1)
+
+    def disable_GROTOALatch(self):
+        self.wr_reg('GRO_TOA_Latch', 0)
+
+    # GRO TOA clock.
+    def enable_GROTOAClk(self):
+        self.wr_reg('GRO_TOA_CK', 1)
+
+    def disable_GROTOAClk(self):
+        self.wr_reg('GRO_TOA_CK', 0)
+
+    # GRO TOT clock.
+    def enable_GROTOTClk(self):
+        self.wr_reg('GRO_TOT_CK', 1)
+
+    def disable_GROTOTClk(self):
+        self.wr_reg('GRO_TOT_CK', 0)
+
+    # GRO TOT reset, active low.
+    def set_GROTOTReset(self, reset):
+        if not isinstance(reset, bool):
+            raise TypeError('Argument must be True (reset) or False (don\'t reset)')
+        val = 0 if reset else 1
+        self.wr_reg('GRO_TOTRST_N', val)
+
+    def get_GROTOTReset(self):
+        return self.rd_reg('GRO_TOTRST_N')
+
+    # ***********************
+    # **** PERIPH STATUS ****
+    # ***********************
+
+    # Bit alignment error
+    def get_BitAlignErr(self):
+        return self.rd_reg('fcBitAlignError')
+
+    # Phase shifter late
+    def get_PhaseShiftLate(self):
+        return self.rd_reg('PS_Late')
+
+    # AFC capacitance
+    def get_AFCCap(self):
+        return self.rd_reg('AFCcalCap')
+
+    # AFC busy, 1: AFC is ongoing, 0: AFC is done
+    def get_AFCBusy(self):
+        return self.rd_reg('AFCBusy')
+
+    # Fast command alignment FSM state
+    def get_FSM_FCAlign(self):
+        return self.rd_reg('fcAlignFinalState')
+
+    # Global control FSM state
+    def get_FSM_GlobCtrl(self):
+        return self.rd_reg('controllerState')
 
-    def get_noisewidth(self, pix):
-        return self.rd_reg('NW', pix)
+    # Fast command self-alignment error indicator, ed[3:0] in figure 53
+    def get_SelfAlignErr(self):
+        return self.rd_reg('fcAlignStatus')
 
-    def get_threshold(self, pix):
-        return self.rd_reg('TH', pix)
+    # Count of invalid fast command received
+    def get_invalidFCCount(self):
+        return self.rd_reg('invalidFCCount')
 
-    def get_THstate(self, pix):
-        return self.rd_reg('THstate', pix)
+    # Count of PLL unlock detected
+    def get_PLLUnlockCount(self):
+        return self.rd_reg('pllUnlockCount')
 
-    def get_pixelID(self, pix):
-        return self.rd_reg('PixelID', pix)
+    # 32-bit EFuse output
+    def get_EFuseOut(self):
+        return self.rd_reg('EFuseQ')