test: gate autobaud's logic floor, and say what an RC oscillator costs
The ATtiny13A run left autobaud's low-clock lock looking unreliable: 1/5 at 19200 on a 1.2 MHz RC part. The simulator does not reproduce it. At an exact clock the calibration is solid down to ~36 cycles a bit and fails outright by ~31 — a sharp edge, not a fraying one — where the real part was already 1 in 5 by ~59. So the effect is the oscillator's own jitter and not backend logic, and the two floors are different quantities about a factor of two apart. Both are worth having. pureboot.autobaud gates a tight-bit point, since its two existing clock points both sat near 100 cycles a bit and would not notice the floor moving. The README carries the other half: both floors side by side, the per-clock envelope measured on silicon, and the reason budgeting the logic's ~36 on an RC part is wrong. It also carries the trap that produced the confusion. On a patched-vector chip an erased application region walks back up into the loader, so every expired window opens another and the host's retries eventually catch the pulse — 5/5 where the same part with an application resident gives 1/5. Measure with an application in place, or the fixture flatters the backend. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -98,6 +98,27 @@ needs its divisor programmed) and that activation counts poll iterations rather
|
||||
than seconds, since there is no clock to convert them against
|
||||
(`PUREBOOT_AUTOBAUD_POLLS`, default 4,000,000).
|
||||
|
||||
**Pick the rate by cycles a bit, and leave the oscillator room.** What the
|
||||
calibration can measure is bounded by how many clock cycles one bit lasts, so a
|
||||
rate is only ever sensible relative to the clock. Two different floors matter:
|
||||
|
||||
| | cycles a bit |
|
||||
|---|---|
|
||||
| the logic's floor — exact clock, simulated | solid to ~36, fails outright by ~31 (`pureboot.autobaud` gates a point here) |
|
||||
| a factory-trimmed internal RC, measured on an ATtiny13A | reliable at ~118; already locking 1 attempt in 5 by ~59 |
|
||||
|
||||
The gap is the oscillator's own jitter, and no exact-clock simulation shows it.
|
||||
So on an RC part, **budget about 100 cycles a bit** — the same order as the
|
||||
fixed-baud software receiver's floor — rather than the logic's ~36. Measured
|
||||
envelope on that ATtiny13A, with an application resident: 9.6 and 4.8 MHz reach
|
||||
115200, 1.2 MHz reaches 9600, 600 kHz reaches 4800, 128 kHz reaches 2400.
|
||||
|
||||
One trap in testing this: on a patched-vector chip an **erased** application
|
||||
region walks straight back up into the loader, so every expired window opens
|
||||
another one and the host's retries eventually catch the pulse. That reads as far
|
||||
more reliable than the same part with an application resident, which gets one
|
||||
window per reset. Measure with an application in place.
|
||||
|
||||
A downstream project brings its usual libavr setup (the `libavr` target, the
|
||||
chip via the `LIBAVR_MCU` toolchain preset), consumes this directory, and
|
||||
states its deployment — an ATmega328P on its shipped 1 MHz fuses with the
|
||||
|
||||
Reference in New Issue
Block a user