Skip to content

Emit AE/AGC callback skeleton + document ipctool sensor monitor#147

Merged
widgetii merged 1 commit intomasterfrom
feat/ae-callback-skeleton
May 3, 2026
Merged

Emit AE/AGC callback skeleton + document ipctool sensor monitor#147
widgetii merged 1 commit intomasterfrom
feat/ae-callback-skeleton

Conversation

@widgetii
Copy link
Copy Markdown
Member

@widgetii widgetii commented May 3, 2026

Follow-up to #145 / #146. Two changes that share a theme: making the AE/AGC layer of an extracted sensor driver navigable.

Write-side: AE/AGC callback skeleton

trace_to_driver.py now emits a third function <sensor>_ae_step containing the per-frame AE/AGC writes captured during the runtime phase, tagged /* TODO: derive */. The original plan in #145 promised this; #145 shipped only a comment block.

For SC2315E + Majestic from #145:

void sc2315e_ae_step(VI_PIPE ViPipe)
{
    (void)ViPipe;
    sensor_write_register(0x5781, 0x60);  /* TODO: derive */
    sensor_write_register(0x5785, 0x30);  /* TODO: derive */
    sensor_write_register(0x3314, 0x14);  /* TODO: derive */
}

The reference's cmos_gains_update writes 0x5781=96 (0x60), 0x5785=48 (0x30) in its else-branch and cmos_inttime_update writes 0x3314=20 (0x14) in its low-inttime branch — the skeleton captures the right registers and the values that the running AE loop wrote during steady-state ambient light. A varying-light capture would surface the if-branches too.

Selection heuristic: top 8 by frequency, each ≥25% of the max count. Conservative on noisy traces; permissive on clean ones.

Read-side: document ipctool sensor monitor

ipctool sensor monitor is an existing feature: poll a fixed list of AE/exposure registers from the running sensor over I2C/SPI in a loop, decoded as labelled fields. SC2315E was already wired up but the feature itself was never documented.

$ ipctool sensor monitor
EXP   100  AGAIN  310  DGAIN  80  VMAX  546  R3301  f  R3314  14  R3632  8  HOLD  0  R5781  60  R5785  30
                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                                       same hot regs that trace_to_driver picks up

Same idea as _ae_step, but read-side. The two pair naturally:

  1. Extract _ae_step via trace → register set
  2. Run sensor monitor while varying lighting (cover lens, switch IR cut) → value time-series
  3. Derive the AE conditional / LUT from the value distribution

The new "Stage 4 — Live-reading the AE state" section in docs/sensor-driver-extraction.md walks through this pairing and includes the recipe for adding a new sensor's reg list to src/snstool.c.

Also renamed R3812HOLD in the sc2315e reg table — that register is the group-hold trigger from cmos_gains_update and self-documents the live output.

Test plan

  • tools/test_pipeline.sh extended to assert the new _ae_step function is emitted; passes
  • gcc -Wall -Wextra -fsyntax-only on real captured + generated scaffold passes
  • CI test-extraction-pipeline job catches regressions in segmenter / generator
  • Cross-check against widgetii/smart_sc2315e/sc2315e_cmos.c confirms register selection
  • ipctool-upx sensor monitor runs on the SC2315E camera; output shows the renamed HOLD field correctly
  • No regression in pre-commit clang-format check

🤖 Generated with Claude Code

Two changes that share a theme: making the AE/AGC layer of an
extracted sensor driver navigable. The first (write-side) finishes a
deferred item from #145; the second (read-side) documents an
existing-but-undocumented ipctool feature.

Write-side: trace_to_driver.py now emits a third function
`<sensor>_ae_step` that writes each runtime hot register (top 8,
above 25% of the max count) with its last-seen trace value, in
trace order, each tagged `/* TODO: derive */`. Header documents that
the values are placeholders and points at the vendor's
cmos_inttime_update / cmos_gains_update equivalents for the math.

Cross-checked against widgetii/smart_sc2315e on the SC2315E + Majestic
capture from #145: skeleton emits exactly 0x3314, 0x5781, 0x5785 with
values 0x14, 0x60, 0x30 - matching the else-branches of the reference's
two AE callbacks. The trace was captured under steady ambient light,
so only the low-gain / short-inttime branch values appear.

Read-side: `ipctool sensor monitor` already supported SC2315E (added
some time ago); the feature was never documented anywhere. It reads
the same hot register set in a loop while the sensor runs, giving you
value time-series under varying lighting - the natural complement to
the static trace-extraction. New "Stage 4 - Live-reading the AE state"
section in docs/sensor-driver-extraction.md walks through pairing the
two: extract `_ae_step` for the register set, then `monitor` while
varying lighting to capture the value distribution that derives the
threshold conditionals. Renamed sc2315e's R3812 to HOLD (it is the
group-hold trigger from cmos_gains_update) so the live-read output is
self-explanatory.

test_pipeline.sh asserts the new function is emitted and the file
still passes gcc -Wall -Wextra. Docs updated to describe the third
function and the inherent limitation (math not in trace).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@widgetii widgetii force-pushed the feat/ae-callback-skeleton branch from f6a5f52 to 0611528 Compare May 3, 2026 08:54
@widgetii widgetii changed the title Emit AE/AGC callback skeleton from runtime phase Emit AE/AGC callback skeleton + document ipctool sensor monitor May 3, 2026
@widgetii widgetii merged commit a4ead51 into master May 3, 2026
3 checks passed
@widgetii widgetii deleted the feat/ae-callback-skeleton branch May 3, 2026 09:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant