Repository navigation
test(firmware): add SoakRig node sketches for the #291 soak rig - #339
Draft
mottihoresh wants to merge 16 commits into
Draft
mottihoresh wants to merge 16 commits into
mottihoresh wants to merge 16 commits into
Conversation
Two PanelGroup node sketches behind the #291 soak test panel. Between them they carry one instance of every v1 control class on every PinRef backend. BoardA (NODE_ID 1, STM32F103C8) takes the J11 GPIO stations, the MCP23017 on J_I2C1, the ADS1115 on J_I2C2 and the J_BL1 dimmer zone. BoardB (NODE_ID 2, STM32F103CB) takes the three X27 needles, the ShiftBus section and the three drum displays; it needs the 128 KB part because U8g2 plus three StepperMotors links at 94% of a C8. Alternate builds are #if 0 blocks in the sketches rather than duplicated hardware: SwitchWithCover2Pos (#293) and Switch2Pos on board A, StepPattern::FULL_4STATE on board B. That last one needs the config field overwritten after makeX27Config() returns, since the helper hardcodes StepPattern::SWITEC_6STATE and takes no pattern argument. AngleSensorInput (#294) is compiled out: #291 moved it onto its own magnet-knob fixture, and a live instance would read a floating ADS channel for the length of the soak. Board B's bare 0x3C panel sits on J_I2C2, the non-default trunk, so that the DrumDisplay TwoWire& overload from #318 is exercised against hardware before #295 freezes the API. Pin and bit assignments, DCS bindings and the stepper calibration numbers are provisional and move when the panel is wired. The class-to-backend pairing is the coverage contract #291's gate checks and must not drift. Refs #291
The weekly full build already discovers Firmware/Examples/SoakRig, because select-platformio-projects.py rglobs Firmware/**/platformio.ini. PR builds use library_dependents instead, and that listed no Examples/ project at all, so a library change on a PR never selected the soak rig. Add both SoakRig nodes under the five libraries they depend on, and add a DrumDisplay key — without one, a DrumDisplay change selects nothing. Its two other real dependents are listed with it so the key is not misleading. Drop ten Firmware/Prototype/* entries: that directory does not exist and has no history in this repo. Verified with the selector itself: a PanelGroup change now selects both boards, a DrumDisplay change selects BoardB, and full mode still enumerates all 35 projects.
mottihoresh
marked this pull request as draft
October 15, 2026 17:09
mottihoresh
added a commit
that referenced
this pull request
Oct 15, 2026
The generator reads the committed map to carry full_build_paths over, which is hand-maintained and cannot be derived. On an unresolved merge conflict that read hit json.loads and failed with a raw traceback. Two branches touching the map at once is the expected case, not a rare one -- #339 conflicts with this branch right now -- so turn that traceback into the resolution: take either side, then regenerate over the top of it.
…a-5bbda6 # Conflicts: # .github/firmware-platformio-impact.json
Two station changes from the #291 rig owner. Second 74HC595 and second 74HC165. Everything on the rig sat on chip 0, so nothing under the soak crossed a cascade hop. Both chains are now two chips deep and both chips in each chain carry live bits, so a dead QH'->DS or QH->SER hop cannot pass as a merely quiet rig. The caution ladder is split 2/2 across the '595 chips on purpose: all four lamps come from one broadcast word, so a single MASTER_TEST press must fan out across the hop inside one transfer, which a tidy chip-per-function split would not test. The X27 coils stay together on chip 0 so a step is still one atomic four-bit flip. On the '165 side the ON-OFF-ON moves to chip 1 rather than the home microswitch, because it is polled every loop and a fault shows at once, whereas the home switch is read only during the boot seek. No setup code: configureAsInput/Output call noteInput/noteOutput, which grow the chain to cover the highest chip declared, so a chip-1 PinRef is the whole opt-in. This is not the first exercise of the cascade — Firmware/Tests/ShiftBus already has bench_probe595, bench_probe165 and frame_map spanning chips 0 and 1. What is new is the cascade carrying live control classes under a multi-hour soak rather than a standalone probe sketch. R16-503 illuminated pushbutton. Board A's J11 momentary and its LED are now one part (SW-PUSH-R16503-*): one 16 mm hole instead of two. No firmware change -- the lamp is driven from the sim, not from the contacts, so they remain two independent stations on their own pins. Recorded in the wiring comments because the pin map would otherwise read as two unrelated stations. Refs #291
2 of 18 tasks
The assembled PanelGroup base 0.2.0 (BO-0014) has an STM32F103C8, not a CB. Board B links at 96.6 % of a C8 (FULL_4STATE alternate 96.7 %), enough for the soak. README records the fallback order if a change overflows: move a non-display station to board A, else rework to a CB.
8 tasks done
#359 landed the v1.0 API freeze on main. Two changes reach these sketches. AnalogInput now takes (controlId, PinRef, const AnalogConfig&) and nothing positional, so instrPot and floodPot lose their six-argument form. Both drop their tuning entirely rather than restate it: hysteresis defaults to HYSTERESIS_AUTO, which resolves to AnalogConfig::DCS_HYSTERESIS (1024) for a DCSIN_* id -- exactly what they were passing. floodPot now declares identically to instrPot, which is the point of the station pair: only the PinRef differs. StepperConfig fields default to the X27 family, so the FULL_4STATE alternate build is a plain designated initializer and the makeCanopy4StateConfig() helper goes away. The comment keeps why it is spelled out rather than built from makeX27Config(): that helper fixes the pattern, so the older form had to overwrite the field after the call. AngleSensorInput and the makeX27Config calls compile unchanged -- the new AngleConfig is an optional trailing argument these sketches never passed. Builds: board A 73.6 % flash of a C8, board B 48.4 % of a CB. Board B's revision follows in the merge of fd31eeb. Refs #291
…nto mh/upbeat-visvesvaraya-5bbda6
…erge Board A 73.6 % of a C8, board B 96.9 % (63,488 of 65,536). The FULL_4STATE alternate now measures the same as the main build rather than 0.1 pt above it: its StepperConfig is a static const that nothing references until you swap it in, so the compiler drops it. Refs #291
Merging main brought in its generated map, which does not know SoakRig exists -- those projects live only on this branch -- so the HIDControls key came back without them and the up-to-date check failed. Regenerated with gen-platformio-impact-map.py --write; both boards are now listed under every library they depend on, and --check passes. Refs #291
This was referenced Oct 26, 2026
…a-5bbda6 # Conflicts: # .github/firmware-platformio-impact.json
97.3 % of flash (63,756 of 65,536), up from 96.9 % before this merge and 96.6 % when board B moved to the C8 -- about 230 bytes of library growth per merge from main, with 1,780 bytes left. None of it is this sketch's own growth, so the README now says to re-measure after every merge and to take the documented fallback order rather than trim the sketch if one overflows. Refs #291
The bootloader chain (#362-#367) gives every production STM32 image a 4 KB bootloader at 0x08000000 and starts apps at 0x08001000, so a C8 app region is 61,440 B rather than 65,536. Both SoakRig projects now pull Firmware/shared/stm32.ini for the identity-block linker script, the post-build stamp, the app offset and the bootstrap target -- one level deeper than Templates/Panels, so ../../../ rather than ../../. Board B did not fit: 63,756 B against 61,440, over by 2,316. -flto links it at 55,020 B, 89.6 % of the region with 6,420 B spare, and drops RAM 5,752 -> 5,548. LTO buys margin rather than clearing 2.3 KB once. Board B grew ~230 B per merge from main (96.6 -> 96.9 -> 97.3 % of a C8 over two merges) and none of that is this sketch's code, so the alternatives were measured and rejected: an F103CB means reworking an assembled board, and trimming the unused DrumDisplay font leaves 39 bytes, which one merge erases -- stackable, never standalone. Verified .isr_vector lands at 0x08001000 on both boards, since PlatformIO keeps reporting a percentage of 65,536 and its bar no longer means anything here. Both alternate #if 0 builds still link: board A 51,104 B, board B 55,020 B. README gains the flashing section (bootstrap once on a blank board, clearing flash protection for Tests/ sketches, the 0x740-0x7FF bootloader CAN range) and a soak-traffic section noting the extra 8-byte READY_n per node per SYNC_REQ from #383, plus a standing note to bench LTO deliberately against the ShiftBus ISR and the U8g2 statics. Refs #291
7 tasks
…eat-visvesvaraya-5bbda6 # Conflicts: # .github/firmware-platformio-impact.json
Board A 48,884 B (79.6 % of the 61,440 B app region), board B 55,292 B (90.0 %, 6,148 spare). Both up ~280 B from library growth in this merge, which is the drift the LTO margin exists to absorb. isr_vector re-confirmed at 0x08001000 on both. Refs #291
This branch has not been deployed
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.
Two PanelGroup node sketches for the #291 soak test rig, plus the CI bookkeeping that keeps them building.
The sketches
Firmware/Examples/SoakRig/— BoardA (NODE_ID1,genericSTM32F103C8) and BoardB (NODE_ID2,genericSTM32F103C8). Between them they carry one instance of every v1 control class on everyPinRefbackend, which is the coverage contract #291's gate checks.J_I2C1, ADS1115 onJ_I2C2,J_BL1dimmerJ_BL1dimmerBoth boards are C8s — that is what the assembled bases carry. Board B is tight (U8g2 plus three
StepperMotorinstances; theFULL_4STATEalternate is 96.7 %), and the README lists the fallback if a change overflows: move a non-display station to board A, else rework board B to a CB.Board A uses only
J11pins that exist on both base revisions, so it runs on the already-assembled 0.1.0 board today. Board B needs 0.2.0 forJ_SR.Alternate builds are
#if 0blocks, not extra hardwareThree of them, per #291's alternate-build table:
SwitchWithCover2Pos(#293) andSwitch2Poson board A,StepPattern::FULL_4STATEon board B. Each compiles — verified by building with every block flipped on, not just by eye.Two things worth calling out in review:
FULL_4STATEneeds the config field overwritten aftermakeX27Config()returns. That helper hardcodesStepPattern::SWITEC_6STATE(StepperMotor.cpp:263) and takes no pattern argument, so a block that only passes its other parameters compiles, looks right, and runs the 6-state table — reporting an enum member proven while docs(firmware): v1.0 API + wire-format freeze review and compatibility policy #295 freezes it unexercised.J_I2C2, the non-default trunk, deliberately. That selects the(U8G2&, const DrumReadout&, TwoWire&, …)overload added in feat(firmware): DrumDisplay takes a bus or a mux #318; onWirethe sketch would take the no-bus constructor and leave the overload untested against hardware. Both arrangements satisfy thehardware-standardsshadowing rule, so coverage is the tie-breaker.AngleSensorInput(#294) is compiled out: #291 moved it onto its own magnet-knob fixture, and a live instance would read a floating ADS channel for the length of the soak.What is provisional
Pin and bit assignments, DCS bindings, and the stepper and angle-sensor calibration numbers all move once the panel is physically wired. The class-to-backend pairing is the part that must not drift. The README states which is which.
CI
Firmware/Examples/SoakRigwas already picked up by the weekly full build, which rglobsFirmware/**/platformio.ini. PR builds uselibrary_dependents, which listed noExamples/project at all, so a library change on a PR would never have selected the rig. Both boards are now registered under the five libraries they depend on, and aDrumDisplaykey was added — without one, aDrumDisplaychange selected nothing.Also drops ten
Firmware/Prototype/*entries: that directory does not exist and has no history in this repo.Verified by running the selector rather than reading the JSON: a
PanelGroupchange selects both boards, aDrumDisplaychange selects BoardB plus its two real siblings, and full mode still enumerates all 35 projects.Refs #291