docs: the OSCCAL axis, --scan, and the RC-oscillator deployment risk

Configuration gains the OSCCAL row; Deployment says what the build cannot
see (±10 % factory trim against a frame's ~±4 %, and silence that reads as
wiring); the update section names an OSCCAL bake as a link change in effect,
declared with --staged-baud; the host-tool section documents --scan and the
measured clock --info adds on an autobaud session; the version map gains 6.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-28 01:03:15 +02:00
parent 52c4cdab32
commit 1b18f10f4e

View File

@@ -72,6 +72,7 @@ repo's build and by a downstream project alike:
| `USART <n>` | the USART instance (x4 megas carry two) | 0 | | `USART <n>` | the USART instance (x4 megas carry two) | 0 |
| `RX <pin>`, `TX <pin>` | software-UART pins | `pb0`, `pb1` | | `RX <pin>`, `TX <pin>` | software-UART pins | `pb0`, `pb1` |
| `TIMEOUT <s>` | the activation window | 8 | | `TIMEOUT <s>` | the activation window | 8 |
| `OSCCAL <byte>` | a measured oscillator trim, applied before anything runs | none — no value, no code |
The default baud is the fastest of 115200/57600/38400/19200/9600 the clock The default baud is the fastest of 115200/57600/38400/19200/9600 the clock
reaches within 2.5 % — the same U2X-included divisor search libavr's baud reaches within 2.5 % — the same U2X-included divisor search libavr's baud
@@ -285,7 +286,9 @@ Two generations exist. **1 through 4** speak one session — a 12-byte info bloc
from `b`, and a command per memory (`R`/`W` flash, `r`/`w` EEPROM, `F` fuses). from `b`, and a command per memory (`R`/`W` flash, `r`/`w` EEPROM, `F` fuses).
**5** replaced those with the single `G`/`g` pair over selector-named spaces **5** replaced those with the single `G`/`g` pair over selector-named spaces
above; the shipped tool speaks both, choosing on the version it reads, so a above; the shipped tool speaks both, choosing on the version it reads, so a
deployed pureboot 4 stays drivable and self-updatable to 5. deployed pureboot 4 stays drivable and self-updatable to 5. **6** changes
nothing on the wire: it marks the builds that may carry a baked `OSCCAL` trim
(Configuration), so a tool driving an update knows such images exist.
Every closed generation is tagged in this repo at its era's last commit — the Every closed generation is tagged in this repo at its era's last commit — the
commit just before the next version bump, so a tag holds everything its commit just before the next version bump, so a tag holds everything its
@@ -350,6 +353,18 @@ mega (SPM only executes from the boot section — reflash the .hex), but *runs*
on a patched-vector chip, and the ordinary `--update-loader` flow re-homes it on a patched-vector chip, and the ordinary `--update-loader` flow re-homes it
into the top slot from there (`pureboot.rehome`). into the top slot from there (`pureboot.rehome`).
**Fixed-baud on an internal RC oscillator is a deployment risk the build
cannot see.** The factory trim is ±10 % where an 8N1 frame survives about
±4: a part at the edge answers nothing at the built rate, and the symptom —
silence — reads as a wiring fault (a real ATtiny13A measured 5.5 %, outside
every standard rate at its own documented default). The **autobaud build is
the deployment-proof backend**: it has no rate to miss. Where fixed-baud on
RC is wanted anyway, measure first and bake the trim: an autobaud session's
`--info` prints the part's true clock from the loader's own measured bit
period, OSCCAL moves the oscillator about 1 % per step, and `OSCCAL <byte>`
builds the correction in — one buildmeasure iteration converges. A loader
already deployed and silent is diagnosed with `--scan` (Host tool).
## Updating the loader ## Updating the loader
`pureboot.py --update-loader new_pureboot.bin` replaces the resident loader `pureboot.py --update-loader new_pureboot.bin` replaces the resident loader
@@ -374,6 +389,11 @@ The host retunes on the open port, so no DTR pulse resets the copy it is talking
to. Omit them against a changed link and the update stops after installing the to. Omit them against a changed link and the update stops after installing the
staging copy, saying so and naming this as the cause. staging copy, saying so and naming this as the cause.
An `OSCCAL`-baked image is a link change in effect even at an unchanged rate
on paper: the staging copy shifts the physical clock the moment its `run()`
starts, and from then on speaks exactly what it was built for. Declare it
like any other link change — `--staged-baud` with the new build's rate.
The preflight refuses an image built for another chip: the stamp every pureboot The preflight refuses an image built for another chip: the stamp every pureboot
binary carries must resolve to the device's own geometry, and the error names binary carries must resolve to the device's own geometry, and the error names
both. Die revisions share their base signature and geometry, so their images both. Die revisions share their base signature and geometry, so their images
@@ -430,7 +450,19 @@ application data into a mega's reset walk region.
`--autobaud` opens with the calibration pulse instead of the plain knock, for a `--autobaud` opens with the calibration pulse instead of the plain knock, for a
loader built `SERIAL autobaud`; the rest of the session is identical, at loader built `SERIAL autobaud`; the rest of the session is identical, at
whatever `--baud` the host chose. whatever `--baud` the host chose. Its `--info` adds the **measured clock**
the loader's bit-period unit, decoded and multiplied by the session rate —
which is the number an `OSCCAL` bake or a fixed-baud build for the part is
held against; `--clock <hz>` states the drift against a nominal.
`--scan` is the diagnosis once a fixed-baud loader has gone silent: it walks
±10 % around `--baud` in 2 % steps, nearest first, one probe per activation
window — reset the target as each probe announces itself (a board with DTR
wired to reset is pulsed by the probe's own port-open). A loader
off-frequency answers at its oscillator's ratio, and the report gives the
found rate as the session workaround, the offset, the OSCCAL correction's
direction at ~1 % per step, and the autobaud way out. Standalone — no other
operation combines with it.
`--peek ADDR[:N]` and `--poke ADDR:HEX` reach the data space (pureboot 5) — `--peek ADDR[:N]` and `--poke ADDR:HEX` reach the data space (pureboot 5) —
SRAM, and through the same address space the register file and every I/O SRAM, and through the same address space the register file and every I/O