Skip to content

HW Verify Issue 24 Power On DAC Fullscale

Benjamin Reese edited this page Aug 14, 2026 · 2 revisions

HW Verify — Issue #24: RS/SQ1FB/SQ1B/SSAFB power on at full scale

Item: Issue #24 (RS, SQ1FB, SQ1B, and SSAFB signals power on outputting at full scale; RS opposite polarity wrt column module signals). Board status: Needs HW Test · Track: Firmware · Priority: P1.

← back to Hardware Verification

What we are verifying

On the bench, immediately after power-on and before any software runs, the column and row DAC outputs (TES bias, SSA_FB, SSA_SIG, SQ1B, SQ1FB, and the row-select RS lines) were measured sourcing current — several at or near full scale — instead of sitting at differential zero (~1.25 V above common ground, DAC mid-scale). Two distinct observations to characterize:

  1. Power-on level. Do the DAC outputs power on at full scale (or any nonzero drive) rather than a safe zero? This risks pushing current into the cryostat before configuration.
  2. RS polarity. The row-select (RS) signals measured opposite polarity to the column-board signals.

A secondary question raised in the issue: are the RS lines for rows that are not in the row order properly zeroed when the system runs with a subset of the max rows?

This is a measurement/characterization task — quantify current state on real hardware so we can decide whether a firmware power-on-reset default is needed. There is no committed fix to confirm yet; the deliverable is a clean, repeatable measurement.

You will need

  • A column module and a row module, each terminated in load boards (standard 100 Ω across every signal pair), exactly as in the original report — so this is an off-cryostat bench measurement.
  • A multimeter (voltage drop across the 100 Ω loads) and the load-board pinout.
  • A way to power-cycle the modules cleanly.

Procedure

Part 1 — power-on levels (no software)

  1. With the modules powered off, connect the load boards. Have the DMM ready.

  2. Power on the modules. Do not start the server or run any command yet.

  3. Measure the voltage drop across the 100 Ω load for each signal and record it in the table below. Reproduce at least the signals from the original report:

    Signal Load-board pins (from #24) V drop across 100 Ω Implied current Notes
    TES bias 0 29 & 78
    SSA_FB_0 5 & 55
    SSA_SIG_0 31 & 80
    SQ1B_0 6 & 56
    SQ1FB_0 32 & 81
    RS_00 49 & 98 polarity vs. column signals?
  4. Also note, for the signals that read ~0 mV, whether they sit at 0 V wrt common ground (true off) vs. ~1.25 V wrt ground (differential zero / mid-scale). The original report saw TES bias and SSA_SIG at 0 mV drop but still at 0 V wrt ground — i.e. not at the mid-scale "zero" the DACs settle to once explicitly set. Capture this distinction; it is the crux of the issue.

Part 2 — after InitDacAdc (does init change anything?)

  1. Start the server (see Common bench setup) and connect a client.

  2. Run the column-board init and re-measure the same signals:

    cb = sess.group.ColumnBoard[0]
    cb.InitDacAdc()          # power-cycles Ad9681, relocks, zeros SaBias + TesBias

    InitDacAdc (firmware/python/warm_tdm/_ColumnFpgaBoard.py) also calls SaBiasDac.ZeroVoltages() and zeroes TesBias.BiasCurrent[*]. Record whether the measured outputs change after init. (The original report saw no change after InitDacAdc — confirm or refute.)

Part 3 — explicit zero, then RS polarity

  1. Explicitly drive the column force/bias outputs to zero and confirm they settle to differential zero (~1.25 V wrt ground, 0 mV across the load):

    ncol = len(sess.group.ColTuneEnable.get())
    sess.group.Sq1FbForceCurrent.set([0.0] * ncol)
    sess.group.Sq1BiasForceCurrent.set([0.0] * ncol)
    sess.group.SaFbForceCurrent.set([0.0] * ncol)
  2. RS polarity + unused-row zeroing. Set a small row order and drive rows manually to compare RS polarity against the column signals, and check that rows outside the order are held at their off level:

    rb = sess.group.RowBoard[0]
    rb.RowDacDriver.Mode.set('MANUAL')      # manual row control
    rb.RowDacDriver.ActivateRowIndex.set(0) # drive one physical row on
    # measure RS_00 drop + polarity vs. a column signal
    rb.RowDacDriver.DeactivateRowIndex.set(0)

    The on/off levels the driver applies per row-select line are RowDacDriver.FasOn and RowDacDriver.FasOff (_RowDacDriver2.py). Rows not in the active order should sit at FasOff. Record whether unused rows are actually held there.

Pass criteria

This is characterization, so "pass" = a complete, unambiguous measurement, not necessarily zeroed outputs:

  • Power-on drop recorded for every signal in the Part 1 table, with the 0 V-vs-mid-scale distinction noted for any ~0 mV signal.
  • Confirmed whether InitDacAdc changes the outputs.
  • Confirmed the outputs do reach differential zero once explicitly set.
  • RS polarity relative to column signals documented (agrees / opposite).
  • Unused-row RS behavior documented (held at FasOff / not).

If outputs power on hot, that confirms the need for a firmware power-on default — note it on the issue so a firmware fix can be scoped.

Record

  • Firmware build stamps + git hashes (ops.print_hardware()):
  • Software commit / conda env:
  • Modules + load boards used:
  • Filled Part 1 table + Part 2/3 notes:
  • Outcome (pass / fail / needs FW change):

References

  • Issue #24 (original bench measurements and pin map)
  • firmware/python/warm_tdm/_ColumnFpgaBoard.pyInitDacAdc, force-current vars
  • firmware/python/warm_tdm/_RowDacDriver2.pyMode, ActivateRowIndex, DeactivateRowIndex, FasOn, FasOff
  • Related: Issue #86 (override writes can be dropped — relevant if a zero "doesn't take")