Skip to content

Apps: Inline CMSIS-DAP code, fix and test serial issues#110

Merged
microbit-matt-hillsdon merged 11 commits into
appsfrom
own-dap
Mar 6, 2026
Merged

Apps: Inline CMSIS-DAP code, fix and test serial issues#110
microbit-matt-hillsdon merged 11 commits into
appsfrom
own-dap

Conversation

@microbit-matt-hillsdon

Copy link
Copy Markdown
Contributor
  • Inline what we need from the CMSIS-DAP protocol handling, removing the dapjs dependency
    • Removes a bunch of duplicate code for partial flashing with very confused layering
    • Removes vendored copy for ESM packaging reasons
    • Enables more structured error handling / no string matching and errors from timeouts
    • Allows us to push logging into this code
  • Fix partial flash retry by reinitialising SWD (potentially fine before, maybe refactor broke it)
  • Saturate DAPLink CDC buffers before flash to prevent serial data loss
    • We'll see how this goes on the apps branch before shipping it for real.
  • Improve serial data handling around flash
  • Simplify device wrapper and clarify naming across USB and Bluetooth
  • Simplify error handler; review error landing and logging
  • Deduplicate ABORT_ALL constant between cmsis-dap and arm-debug
  • Add test coverage for extracting interfaces
  • Add a human-in-the-loop hardware test runner (USB flash, fallback paths, serial integrity, replug)
  • Minor demo improvement: the ability to easily reflash the same hex without faff

This targets the apps branch because of the scale of the change and the fact it's targeting 1.0 release rather than because of the apps as such.

The partial flashing code already duplicated significant portions of the
dapjs protocol stack. Consolidate everything into a single cmsis-dap.ts
module covering the subset we use: SWD transport, Cortex-M debug, and
DAPLink serial/flash vendor commands.

Also renames DAPWrapper to USBDeviceWrapper and disambiguates device
field names (bleDevice/usbDevice).
Fix stale serial data appearing after flash by addressing a race in the
serial stop/start cycle. When stopSerial() is called, an in-flight
serialRead() can still deliver data after the stop, refilling any
consumer line buffer that was cleared on reset. Fix by suppressing data
delivery once polling is set to false, and by firing the serialreset
event after the polling loop actually exits rather than when stop is
requested.

Drain DAPLink's serial buffer before flash to discard output that
accumulated between the last serial read and the halt. After flash,
start serial listening before resetting (partial flash only) so early
program output is captured in DAPLink's 512-byte ring buffer.

Simplify flashAsync: remove the disconnect/reconnect cycle (invalidate
DAP state instead, keeping USB open) and remove the timeout-based
fallback from partial to full flash which masked connection problems.

Minor:
- Strip \r in demo app serial listener (for CRLF)
- Fix vitest exclude pattern for build directory
Rename reconnectDaplink for clarity.

Add ability to inject faults into flashing via the demo app to test this flow.
Move board info caching and logging up to connection.ts, reducing
device-wrapper.ts to a thin composition root. Rename fields for
clarity: device→usbDevice/bleDevice for raw devices, connection→device
for wrapper state.
We now control all sources of errors other than the browser cases matched by
regexp. Review the browser ones and link to the Chromium source, which
fortunately proves they're not localized.
DAPLink's CDC serial path races with WebUSB vendor serial reads for the
same UART ring buffer, causing truncated serial output after flash.
Work around this by pushing NUL bytes through the target's UART to fill
DAPLink's internal buffers before flashing. Once full, CDC stops
consuming and post-flash output is preserved for vendor reads.

V1 (nRF51) runs a Thumb blob for the legacy byte-at-a-time UART.
V2 (nRF52833) uses SWD register writes to trigger a UARTE DMA transfer.
Both paths fully configure the UART from scratch (pins, baud rate) since
the previous program may not have set it up.

Only applied on the first flash after physical USB connection and only
when serial listeners are attached.

See: ARMmbed/DAPLink#903
Tests basic flashing flows including checking serial output.

Move the hex files as they're useful more widely than the capacitor project.

Remove fault injection from the demo now hardware-test has it.
@microbit-matt-hillsdon
microbit-matt-hillsdon merged commit 55c1844 into apps Mar 6, 2026
3 of 4 checks passed
@microbit-matt-hillsdon
microbit-matt-hillsdon deleted the own-dap branch March 6, 2026 16:06
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