Repository navigation
fw-v0.6
Tag firmware for the five distributed targets. Each image ships with its build manifest, recording the commit, the ChibiOS commit and branch, the toolchain and nanopb versions, and the SHA-256 of the image. CI does not bench-test power behaviour — qualification is a separate step before flight, and the table below is the record of it.
All five targets are qualified against this release, each measured from the published image rather than a local rebuild, and each with its session logs attached as an asset.
Qualification
Supply voltage is stated with every current because the targets do not share one: the L432 tags run unregulated from a 2.5 V cell and IMUTag from 3.7 V. A current figure means nothing without it.
| Target | Qualified | Supply | Idle | Running | Finished |
|---|---|---|---|---|---|
| IMUTagNandBmp581 | 2026-10-07 | 3.693 V | 6.43 uA | 665.41 uA @ 400 Hz | 6.43 uA |
| CompassTagAT25 | 2026-10-06 | 2.496 V | 0.21 uA | 1.95 / 1.9478 uA @ 30 s | 0.21 uA |
| UIUCTag | 2026-10-08 | 2.496 V | 0.1572 uA | 0.5620 uA @ 300 s | 0.1598 uA |
| BitTag | 2026-10-07 | 2.496 V | 0.1185 uA | 0.4941 uA @ default (1 bit/5 min); 0.5073 / 0.5068 @ 1 bit/s | 0.1178 uA |
| PresTag | 2026-10-07 | 2.496 V | 0.1118 uA | 0.3894 / 0.3908 uA @ 60 s | 0.1108 uA |
No power regression
Every distributed image changed in this release — shared ADC code, a verify added to every tag's configuration-write path, and four boards' LSE configuration — so nothing carried forward from fw-v0.5. Against the previous qualified figures on the same boards and supplies:
| Target | Running | Change |
|---|---|---|
| IMUTagNandBmp581 | 662 → 665.41 uA | +0.5% |
| CompassTagAT25 | 1.96 → 1.95 uA | −0.5% |
| BitTag | 0.508 → 0.5073 uA @ 1 bit/s | −0.14% |
IMUTag is the target that matters most here: at 665 uA it draws three orders of magnitude more than the others, so it alone decides whether a deployment makes its battery life, and it is the part where image layout has moved idle current by 150x in the past. Its firmware contribution is isolated — the outgoing image was measured on the same board in the same session before flashing, giving idle 6.2881 → 6.4137 uA (+2.3%) and running +0.5%.
IMUTagNandBmp581
Board 00303143433650090059002E at 3.6932 V. The full harness ran, including three attach-storm sets: six rounds, none aborted, data intact. Attach storms are meaningful for this target and only this one — IMUTag stays awake through a run and must restart collection after an attach, whereas the L432 tags collect on events and sit in standby between them.
Idle 6.4144 / 6.4382 / 6.428 / 6.4355 uA over four trials; life-cycle idle 6.43, running 665.41 @ 400 Hz, finished 6.43, idle after a full cycle 6.45 uA; download sane; tag-test ALL_PASSED.
CompassTagAT25
Board 203633324B4250060022005E, CompassTagAT25.elf sha256 ba99e8534395963d635c0c7f8ab123d4f40cb39768b22336634c7fbbb012078f, measured with --skip-build so the harness could not substitute a rebuild.
Four idle trials 0.2181 / 0.2144 / 0.2139 / 0.2137 uA; life cycle idle 0.21, running 1.95, finished 0.21, idle-after-cycle 0.21 uA; a second 900 s running window at 1.9478 uA, 0.1% from the first; three storm sets, 240 attach/detach cycles, none aborted; the 30 s sample interval exact in all six stored round databases; tag-test ALL_PASSED.
Calibration survived the flash byte-identically, verified either side. __calibration_start__ was confirmed still at 0x0800b000 — the address this board was calibrated under — before the flash was allowed. Headroom between the image end and that page is now 200 bytes, down from 936; when it closes, .calibration moves and a calibrated board silently reads an unwritten page.
UIUCTag
Board 2036354B3032500800520028. A 31-minute run from 16:22:35Z stored 7 pressure and 7 temperature samples at exactly 300 s and 30 activity buckets at exactly 60 s, the first on the first minute boundary after the start, with no slot missed. Idle 0.1572, running 0.5620, finished 0.1598, idle after a full cycle 0.1598 uA; tag-test ALL_PASSED.
Running current is 26% below the 0.76 uA measured on this board at bring-up. Lower is not a budget concern; the likeliest cause is accelerometer configuration, since that session was still resolving an activity-pegged ADXL367.
tag-test is intermittent on this target — roughly four attempts in six return a result, the failures being host-side link timeouts at the first transaction rather than device-test failures.
BitTag
Board 2035374D303150190059002F. Both logging configurations were measured. At 1 bit/s, two 30-minute windows agreed to 0.1% (0.5073 and 0.5068 uA), both within 0.25% of this tag's fw-v0.5 figure; the run stored 1860 activity records with every interval exactly 1 s. At the shipped default of 1 bit per 5 minutes the run draws 0.4941 uA.
The logging rate is nearly free: 300x less logging buys 2.6%. BitTag's run current is set by the accelerometer watching for activity, not by how often a bit is written, so battery life must not be estimated from the record rate.
Activity values are zero throughout because the tag was stationary. Activity sensitivity (Phase D of its test plan) has never been run, in this qualification or fw-v0.5's.
PresTag
Board 203330503641500400490058. The first PresTag release qualification — the 2026-09 campaign was explicitly not one, because the stored-configuration write was unchecked, which this release fixes.
Two independent 30-minute runs agreed to 0.36% (0.3894 and 0.3908 uA at the 60 s period) and each stored 31 consecutive samples exactly 60 s apart with no gap or drift. Idle 0.1118, finished 0.1108, idle after a full cycle 0.1108 uA; four idle trials 0.1227 / 0.1142 / 0.1139 / 0.1137 uA; tag-test ALL_PASSED.
What is in this release
- The internal ADC.
adcVDD()indexedSMPR2with(channel - 9)rather than(channel - 10), writing the sampling time to the wrong channel's field, and sampled the internal channels without the settling time VREFINT and the temperature sensor need. A UIUCTag reported 3.77–3.96 V and 92.5–111.4 C against a 2.4960 V rail. Both defects date to the initial commit; the margin was board-dependent, which is why the same code read correctly elsewhere for a long time. - The stored-configuration write is verified. It was programmed and its result ignored on seven of eight implementations. Flash programming only clears bits, so a write into a region that was not erased yields the bitwise AND of old and new — the tag runs a configuration nobody asked for while the host prints the one it sent. A failure now aborts the start with
EVENT_CONFIGERROR. This makes the failure loud; it does not make the write succeed. - LSE bypass on every distributed board. All clock LSE from an RV-3028, which drives a clock signal rather than a crystal, but only PresTagv3 was configured for it. The others carried a boot that hangs forever in
__early_init, with a monitor-attach timeout as the only symptom. All five boards have now been powered and qualified on this image, so the change is confirmed on every one. - BitTag no longer samples VDD and temperature on every wake — 35 conversions per stored value at the default format — and PresTag's default sample period moves from 90 s to 60 s.
Known limitations
tag_release_check.pycannot drive BitTag, PresTag or UIUCTag, aborting withMonitor attach failed: initial DEMCR read failed— the attach-from-sleep problem. Those three were qualified by running the phases by hand. The harness aborts; the tags do not, and no run in any session reachedABORTED.tag-testis intermittent on UIUCTag, as above.BitTag-legacydoes not build, atfw-v0.5as well as here:main.c:289passes too few arguments toStateMachine().- CompassTagAT25 has 200 bytes of headroom before its calibration page, as above.