Skip to content

fw-v0.6

Choose a tag to compare

@github-actions github-actions released this 06 Oct 14:37
· 467 commits to main since this release

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() indexed SMPR2 with (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.py cannot drive BitTag, PresTag or UIUCTag, aborting with Monitor 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 reached ABORTED.
  • tag-test is intermittent on UIUCTag, as above.
  • BitTag-legacy does not build, at fw-v0.5 as well as here: main.c:289 passes too few arguments to StateMachine().
  • CompassTagAT25 has 200 bytes of headroom before its calibration page, as above.