Skip to content

HW Verify Issue 55 TES Bias Waveform Generator

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

HW Verify — Issue #55 / PR #79: Software TES bias waveform generator

Item: Issue #55 (Feature request: add TES bias waveform generator in software), delivered by PR #79 (Add software TES bias waveform generator). Board status: Needs HW Test · Track: Software · Priority: P0. PR #79 is ready pending hardware testing.

← back to Hardware Verification

What we are verifying

PR #79 adds TesBiasWaveformProcess (a pr.Process on Group) plus one tesBiasWaveformGenerator sub-device per TES bias line. It plays software-clocked sine / square / constant waveforms on the TES bias lines for testing and characterization, and restores the original TES biases when stopped.

It was validated in emulate (registration, sizing, waveform math). The hardware gates are:

  1. Waveforms actually play on real TES bias lines with the expected shape, frequency, and amplitude.
  2. Achievable update rate. Because this is software-clocked, the real SoftwareClock it can sustain is bounded by the host→board round-trip. Issue #55 explicitly asks to measure the latency on the bench and warn if the user requests a rate that can't be met. Confirm the over-rate warning fires.

You will need

  • A column module with TES bias outputs measurable on a scope (load board, off-cryostat is fine) — you need to see the waveform shape and timing.
  • The waveform generator lives on Group.TesBiasWaveformProcess; per-line generators are Group.TesBiasWaveformProcess.tesBiasWaveformGenerator[i] (one per TES bias entry, sized from config at construction).

Procedure

Setup

  1. Start the server (branch that includes PR #79 — it lands on pre-release, and reaches wtj-refactor via merge), connect a client, choose an enabled set (see Common bench setup).
  2. Put a scope on the TES bias line for the generator index you will drive.

Part 1 — square wave

  1. Configure one generator for a slow square wave you can eyeball on the scope:

    proc = sess.group.TesBiasWaveformProcess
    gen  = proc.tesBiasWaveformGenerator[0]     # first TES bias line
    gen.Mode.set('Square')                       # {'None','Square','Sine'}
    gen.Frequency.set(1.0)                       # Hz
    gen.TESBiasLow.set(0.0)                      # µA  (low level)
    gen.TESBiasHigh.set(50.0)                    # µA  (high level)
    proc.SoftwareClock.set(1000.0)               # Hz software update rate
    proc.Start()
  2. On the scope confirm: a 1 Hz square wave, levels corresponding to 0 and 50 µA, clean transitions. Record the trace.

  3. Stop and confirm restore:

    proc.Stop()
    # the process restores the pre-run Group.TesBias values on stop — confirm the
    # line returns to its prior level.

Part 2 — sine wave

  1. Same generator, sine mode:

    gen.Mode.set('Sine')
    gen.Frequency.set(2.0)                        # Hz
    gen.TESBiasLow.set(0.0)
    gen.TESBiasHigh.set(40.0)                     # peak level
    proc.SoftwareClock.set(2000.0)
    proc.Start()
  2. Confirm a clean 2 Hz sine on the scope with the expected amplitude. Check that SoftwareClock/Frequency gives enough samples per period that it looks like a sine, not a staircase. Stop.

Part 3 — achievable update rate (the #55 latency check)

  1. Push SoftwareClock up until the process can no longer keep up, and confirm the over-rate warning fires (PR #79 warns once, via the process logger, when requested timing lags):

    proc.SoftwareClock.set(20000.0)               # deliberately aggressive
    gen.Mode.set('Sine'); gen.Frequency.set(5.0)
    proc.Start()
    # watch the server log for the "can't sustain SoftwareClock / timing lags" warning
  2. Determine the maximum reliable update rate: step SoftwareClock down until the scope waveform is clean and no warning fires; record that as the achievable host→board rate for this bench. This number answers Issue #55's core question.

Part 4 — multiple lines and no-op guard

  1. Drive two or more generators at once (set Mode on several tesBiasWaveformGenerator[i]) and confirm each line plays independently.
  2. Confirm the no-op guard: with every generator set to Mode='None', Start() should no-op with a warning rather than driving anything.

Pass criteria

  • Square and sine waveforms appear on the scope with correct shape, frequency, and Low/High amplitudes.
  • Original TES bias level is restored on Stop().
  • Multiple lines play independently.
  • Over-rate warning fires when SoftwareClock is set too high.
  • Maximum sustainable SoftwareClock (update rate) measured and recorded.
  • All-None case no-ops with a warning.

Record

  • Firmware build stamp + git hash, software branch/commit, conda env:
  • Column module / scope setup:
  • Scope traces (square, sine):
  • Max sustainable update rate (Hz): ← the deliverable for Issue #55
  • Warning behavior confirmed (over-rate, all-None):

References

  • Issue #55 (feature request, incl. the "verify latency, warn if exceeded" ask)
  • PR #79 (implementation + emulate validation notes)
  • software/python/warm_tdm_api/_TesBiasWaveform.pyTesBiasWaveformProcess, tesBiasWaveformGenerator (Mode, Frequency, TESBiasLow, TESBiasHigh), SoftwareClock
  • Related: Issue #54 (firmware waveform generator — the eventual hardware-rate version)