Fifty-two libavr commits and twenty-seven of pureboot behind, which is far
enough that "it still builds" is not the interesting part. It builds, both
modes, byte-identical across them, five checks green - and the image is
**byte-for-byte the 8004 B the board is running**, so the catch-up costs this
deployment nothing and a redeploy was ruled out by comparison rather than
skipped by assumption.
The loader is the gap that mattered. pureboot rode as a submodule for its
geometry alone, so the commit that pinned this firmware did not build the one
image this board cannot be recovered without - the same hole tempmon had.
`pureboot_add_loader(pureboot)` closes it on nothing but pureboot's own
defaults for the chip, and the 386 B it produces is byte-for-byte what the
board's slot reads back.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
pureboot moved to its own repo, so the loader this board hands over to stopped
being reachable through a sibling checkout of the bootloader repo. It is a
submodule here now: this board has no reset line and no programming header, so
the resident loader is the only way in, and the commit naming the firmware
should name the loader it has to reach.
The reachability check stops carrying its own copy of where that loader is.
0x7e00 was a literal beside pureboot's own geometry, which the submodule
exports as PUREBOOT_BASE_HEX - one source for the fact now, and the check reads
whichever slot the pinned loader actually has. The boot-section bound stays a
literal, being a fuse fact rather than a loader one.
Built and tested at both pins on the bench: 5/5, cross-mode identity included,
and the image deployed to the board verifies byte-for-byte through its loader.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
libavr's guidance binds this repo too, and until now nothing here checked it -
`ctest` runs `libavr_format_test()` over this tree's own sources now (rules 11
and 33), skipping rather than passing where clang-format is absent. It caught
drift on its first run: a file written this week and edited after formatting.
Where the README states a measured size, `libavr_size_claim_test()` holds it to
the image and holds the image to the prose: advancing the library pin moved
three of these across the fleet with nothing saying so, and re-recording one
now requires the sentence that quotes it to move too.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The renames land (interrupt_guard, consume_reset_cause, set_duty), the
sampler binds its input in the new converter shape (the input pack plus
in<>::start() as free-running's one kick), and the console states
.allow_baud_error = true for the 115200-at-16-MHz this board has always
spoken - the receiver-tolerance table libavr now enforces is stricter
than the rate's own +2.1 %. The loader probe reads through
avr::flash_load instead of raw pgmspace, the terminal's line buffer is
std::array with backspace and delete named, the tree is reformatted
under InsertBraces, and the sources are ASCII.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Six things the port had dropped or got wrong, and the one that matters is
the last.
The help is a table again — name, dots, description, one command per line
— instead of a single line of bare words that said nothing about what any
of them did. The layout is the original's, colons at column 12, which
`bootloader` at ten characters is what sets.
Abbreviations are back, and they were a feature: any prefix resolves to
the first command it matches, so `up` is uptime and `st` is statistics.
Order does the disambiguating, which is why the table is in the
original's dispatch order and new entries go on the end — appending
cannot take an abbreviation that already meant something. `reset` keeps
the original's exception and must be typed in full: `r` should not be
able to clear the histogram.
The histogram gets its resolution back. The bar was capped at 40 columns
where the original scaled to 100, and on a distribution this narrow that
threw away most of the difference between neighbouring buckets. Same
normalisation as before: divide by whatever makes the tallest bucket fit.
The sample count moves to a fixed ten-column field before the bar, so the
numbers read as a table instead of trailing off the ragged right end.
`version` exists again, and this is 2.1 — 2.0 being the port as it stood.
Added while here: `save`, to force the writeback that otherwise waits up to
thirty minutes; the resistance in `show`, which is the one number that
says *why* a temperature is wrong and which the original printed; a
report when a line overflows the buffer rather than silently acting on
its head; "no data yet" where there is none; and a blank line after each
command's output.
And the way out. `bootloader` now jumps rather than resetting, because
pureboot hands straight back on WDRF by design — so the legacy
watchdog-reset hand-over reaches it and opens no window, which on a board
with no reset line is a board that cannot be reflashed. Two more bugs in
the same three lines: the target was 0x7800, a 2 KB boot section's base,
which on this board's 512-byte section reads erased and made the check
false and the command a no-op; and UCSR0B was left set, which mutes a
loader that bit-bangs the pin the USART still owns. All three are now
read back out of the emitted image by ctest, the address and the watchdog
red-proven against exactly the legacy behaviour they exist to catch.
libavr advances to 71cfb2f. Verified on the board: FanTemp v2.1, min 0 C
/ max 74 C matching what 1.8b reported off the same EEPROM, the fan curve
within one percentage point of the legacy double-precision one at every
5 C from 15 to 60, and `bootloader` -> pureboot 7 -> back to a running
application.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The submodule replaces FetchContent and the unpinned forge fallback;
LIBAVR_ROOT stays as the tandem-development override, the presets take the
toolchain file from the submodule, and the Studio project's include path
anchors there — correct by construction.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Same controller: thermistor on ADC0 averaged over 1000 free-running
conversions, 50 kHz fan PWM on OC0B, 115200 Bd console with the full
command set, EEPROM temperature histogram, watchdog-reset path into the
boot section. The Steinhart-Hart math and the libm log are gone — the
Beta equation and the cubic fan curve are consteval-evaluated into
flash tables; the firmware never does floating point. Byte-identical
.text in both libavr modes. Legacy stays on master.
Co-Authored-By: Claude <noreply@anthropic.com>