Skip to content

Fix UICR not updated during WebUSB partial flashing#113

Merged
microbit-matt-hillsdon merged 6 commits into
appsfrom
uicr-fix
Mar 7, 2026
Merged

Fix UICR not updated during WebUSB partial flashing#113
microbit-matt-hillsdon merged 6 commits into
appsfrom
uicr-fix

Conversation

@microbit-matt-hillsdon

@microbit-matt-hillsdon microbit-matt-hillsdon commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

Problem

Partial flashing skips all addresses >= 0x10000000, which means UICR (User Information Configuration Registers) is never written. This is normally fine because UICR doesn't change between flashes — but after an interrupted full flash, the device is left with erased UICR and a "dead" micro:bit that won't boot.

The sequence that triggers this:

  1. Full flash begins → DAPLink's flash_manager_init does a chip erase (wiping all flash and UICR)
  2. Flash is interrupted (error, disconnect, etc.)
  3. Fallback partial flash completes main flash successfully but skips UICR
  4. Device has correct program flash but blank UICR → bootloader address is gone → device won't boot

Future flashes may also be partial if most pages were written successfully leading to the situation described in #112.

Solution

After every partial flash, ensureUicr() reads device UICR and compares it against the hex file:

  • No mismatch → nothing to do (the common case, zero overhead beyond a few SWD reads)
  • Mismatch, only 1→0 bit changes needed → write directly without erasing (works on both V1 and V2, since UICR bits can only be cleared)
  • Mismatch, 0→1 bit changes needed (V2) → erase UICR via NVMC.ERASEUICR, then write
  • Mismatch, 0→1 bit changes needed (V1) → no independent UICR erase exists, fall back to full flash

Also refactors hex data parsing: the old convertDataToPaddedBytes chain is replaced by toMemoryMap() + extractFlashAndUicr(), which parses the input once to produce both the flash byte array and UICR entries.

Hardware test

Adds UICR recovery after interrupted full flash test to the hardware test suite. We re-flash the same hex and verify the device boots and produces serial output.

Fixes #112

Partial flashing skips addresses >= 0x10000000, so UICR is never
written. After an interrupted full flash (which chip-erases UICR),
the fallback partial flash leaves UICR blank, bricking the device.

Now ensureUicr() runs after every partial flash to compare device UICR
against the hex file. Write-without-erase when only 1→0 bit changes
are needed (both V1/V2). On V2, use NVMC.ERASEUICR when 0→1 changes
are required. On V1 (no independent UICR erase), fall back to full
flash.

Also refactors hex parsing: toMemoryMap() + extractFlashAndUicr()
replace the old convertDataToPaddedBytes chain, parsing the input
once to produce both flash bytes and UICR entries.

Fixes: microbit-foundation/python-editor-v3#1131
Use the log lines to make sure we triggered the UIRC scenario
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Mar 7, 2026

Copy link
Copy Markdown

Deploying microbit-connection with  Cloudflare Pages  Cloudflare Pages

Latest commit: d3f58c9
Status:🚫  Build failed.

View logs

Use waitFor() with timeout for NVMC ready polling instead of bare
while loops. Add configurable delay parameter to waitFor() so NVMC
polls can use 5ms instead of the default 100ms. Also add UICR_LIMIT
to bound the UICR address range.
@microbit-matt-hillsdon
microbit-matt-hillsdon merged commit 64b165f into apps Mar 7, 2026
3 of 4 checks passed
@microbit-matt-hillsdon
microbit-matt-hillsdon deleted the uicr-fix branch March 7, 2026 22:32
microbit-matt-hillsdon added a commit to microbit-foundation/python-editor-v3 that referenced this pull request Apr 29, 2026
This contains the pre-1.0 breaking API changes and USB serial re-work.

We'll run this on Python beta for a bit to build confidence as the BLE code has
had far more real use than the USB changes.

This should improve serial issues after first physical connection + flash and
extra serial from previous programs leaking into subsequent ones.

Relevant fixes:
- Workaround for the bad response issue - microbit-foundation/microbit-connection#72
- Use DAPLink vendor command for serial number - microbit-foundation/microbit-connection#103
- Inline CMSIS-DAP code, fix and test serial issues - microbit-foundation/microbit-connection#110
- Fix UICR not updated during WebUSB partial flashing - microbit-foundation/microbit-connection#113
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant