Detect runtime mode switches in segmenter, emit per-mode functions#149
Merged
Detect runtime mode switches in segmenter, emit per-mode functions#149
Conversation
Closes the fourth real gap from #145's plan-vs-shipped audit, with one caveat documented in the docs and tested empirically below. trace_segment.py: new find_mode_switches() walks the trace after init_end watching for `0x100=0 ... 0x100=1` cycles. Each cycle becomes a mode_switch_N phase. The runtime/post_init anchors move to the last 0x100=1, so traces without a mode switch are unchanged. trace_to_driver.py: emits one `<sensor>_set_mode_N` function per mode-switch phase, same shape as `_linear_init`. test_pipeline.sh: synthetic fixture extended with a mode switch (0x100=0 / VMAX-rewrite / 0x100=1). CI asserts `_set_mode_1` is emitted in the generated C and that it still passes gcc -Wall -Wextra and the self-diff. Empirical caveat: capture-side, mode switches require a streamer that supports runtime sensor reconfiguration. Majestic does not (config goes through .ini files + restart, each mode is a separate cold-init capture). Sofia does, via the DVR-IP protocol; python-dvr exposes the knobs. But whether a given knob causes a sensor-side reconfigure is sensor-specific - Sofia's BroadTrends path lands in software-side gain on most sensors. On SC2315E specifically, toggling AutoGain 0->1->0 while ipctool trace was watching produced *zero* additional 0x100 cycles - the sensor stays in linear mode. Sofia's supported-sensor list confirms `SC2315_WDR` is a separate entry from `SC2315E`, so no WDR firmware exists for that combo. The segmenter and generator are validated end-to-end on the synthetic fixture; live validation with a multi-mode sensor is deferred to whoever has hardware where Sofia drives a sensor with a `_WDR` variant. Docs: new "Capturing mode switches" section in sensor-driver-extraction.md walks through Majestic vs Sofia, the python-dvr API, the empirical SC2315E finding, and the heuristic's known blind spot (group-hold based hot swaps that don't toggle 0x100). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the fourth real gap from #145's plan-vs-shipped audit, with an empirical caveat documented in the docs.
Summary
trace_segment.pynow detects runtime mode switches (0x100=0 ... 0x100=1cycles after init) and emits them asmode_switch_Nphasestrace_to_driver.pyemits one<sensor>_set_mode_Nfunction per detected mode switch, same shape as_linear_inittools/test_pipeline.shextended with a synthetic mode-switch fixture; CI asserts the function is emitteddocs/sensor-driver-extraction.mdWhy
#145's plan called for capturing init plus mode/resolution switches plus runtime AE. #145 shipped init + AE; mode switches were never wired up. This finishes that.
Empirical caveat (worth reading before merging)
Capture-side, mode switches need a streamer that supports runtime sensor reconfiguration:
/etc/sensors/*.inifiles and requires a streamer restart. Each mode is a separate cold-init capture, no in-trace mode switches possible.Whether a given knob actually triggers a sensor-side reconfigure (vs just software-side AE) is sensor-specific. I tested
BroadTrends.AutoGainon the SC2315E test camera at10.216.128.106:Toggled 0→1→0 while
ipctool tracewas running. Result: zero additional 0x100 cycles in the trace after init. Sensor stays in linear mode regardless. Sofia's supported-sensor list (decompile atSofia.c:41394) confirms it:SC2315_WDRis a separate entry fromSC2315E— there's no WDR firmware for our SoC + sensor combo.So the segmenter and generator are validated end-to-end on the synthetic fixture (
tools/test_pipeline.sh). Live validation with a multi-mode sensor is deferred to whoever has hardware where Sofia drives a sensor with a_WDRvariant (SC2315 plain, IMX307, etc.).Heuristic and known blind spot
If a sensor hot-swaps modes via group-hold (e.g.
0x3812=0x00 ... reconfigure ... 0x3812=0x30) without toggling 0x100, this heuristic misses it. Extend the segmenter when you hit such a sensor.Regression check
Pipeline re-run on the SC2315E + Majestic capture from #145:
_linear_init: 172 writes, 169 unique regs, 100% / 100% / 100% vswidgetii/smart_sc2315e/sc2315e_sensor_ctl.c::sc2315e_linear_1080P30_init(unchanged)_linear_init,_post_init_exposure_prime,_ae_stepThe new code path doesn't fire on traces without mode switches, so existing behaviour is preserved.
Test plan
tools/test_pipeline.shsynthetic fixture has one mode switch; passesgcc -Wall -Wextra -fsyntax-onlyandgcc -ctest-extraction-pipelinejob catches regressions🤖 Generated with Claude Code