From 1b18f10f4eabc3044369dd7bd5cd4a15bd683f8c Mon Sep 17 00:00:00 2001 From: BlackMark Date: Tue, 28 Jul 2026 01:03:15 +0200 Subject: [PATCH] docs: the OSCCAL axis, --scan, and the RC-oscillator deployment risk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- pureboot/README.md | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/pureboot/README.md b/pureboot/README.md index d86f28a..21c3266 100644 --- a/pureboot/README.md +++ b/pureboot/README.md @@ -72,6 +72,7 @@ repo's build and by a downstream project alike: | `USART ` | the USART instance (x4 megas carry two) | 0 | | `RX `, `TX ` | software-UART pins | `pb0`, `pb1` | | `TIMEOUT ` | the activation window | 8 | +| `OSCCAL ` | 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 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). **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 -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 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 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 ` +builds the correction in — one build–measure iteration converges. A loader +already deployed and silent is diagnosed with `--scan` (Host tool). + ## Updating the 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 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 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 @@ -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 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 ` 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) — SRAM, and through the same address space the register file and every I/O