Skip to content

Zephyr port: open the serial port at 1200 baud to enter the bootloader - #11570

Open
mikeysklar wants to merge 5 commits into
adafruit:mainfrom
mikeysklar:zephyr-cp-bootloader-touch
Open

mikeysklar wants to merge 5 commits into
adafruit:mainfrom
mikeysklar:zephyr-cp-bootloader-touch

Conversation

@mikeysklar

@mikeysklar mikeysklar commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

What

Opening the USB serial port at 1200 baud now resets the board into its bootloader.

Why

The README said this worked, but the Zephyr port never handled it.

Raspberry Pi boards no longer need BOOTSEL to reflash.

The RP2 settings live in adaboot (adafruit/adaboot#9), so Zephyr Arduino can share them.

Board Test Before move After move
nRF54LM20 DK 1200 baud touch 36/36 20/20
Feather nRF52840 1200 baud touch, then UF2 copy 23/23 build only
Pico W 1200 baud touch, then UF2 copy 25/25 10/10
on_next_reset(UF2 / BOOTLOADER), then UF2 copy 3/3, 5/5 3/3, 3/3
Power off, cold boot stays in CircuitPython 30/30 10/10
Open at 115200 or held at 1200, no reset 18/18 5/5
Pico 2 W the four Pico W tests not tested 10/10, 3/3 + 3/3, 10/10, 5/5

Not tested: nRF54L15 DK (UART console). Pico, Pico 2 and Feather RP2040 are build-tested only.

Written with Claude. The "after move" tests were run on the farm by Claude; I reviewed them.

🤖 Generated with Claude Code

mikeysklar and others added 2 commits October 12, 2026 06:15
The README said the touch worked, but nothing handled it: the TinyUSB
handler is not built for this port.

Watch line coding and DTR on the first CDC. At 1200 baud with DTR low,
recheck 100 ms later, detach USB and call reset_to_bootloader(), which
now asks for UF2 mode so the Adafruit nRF52 bootloader shows its drive.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
On the RP2 boards the touch and on_next_reset(UF2) only rebooted into
CircuitPython, so every reflash needed BOOTSEL.

Add Zephyr's boot-mode retention region to the five RP2 overlays and
enable the retained-memory chain. Zephyr's rom_bootloader.c then enters
the ROM bootloader. A "CP" prefix and CRC8 keep cold-boot SRAM from
being read as a request.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
dhalbert
dhalbert previously approved these changes Oct 13, 2026

@dhalbert dhalbert left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks OK to me. @tannewt checking with you as well in case you have an adaboot consideration.

@mikeysklar

Copy link
Copy Markdown
Collaborator Author

Checked on a Feather nRF52840: adafruit-nrfutil --touch 1200 serial DFU still works 3/3 with this PR, and the bootloader now also shows the UF2 drive. Adaboot itself ignores the UF2 flag, so it needs no change.

@tannewt tannewt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing this. I think some of it should be moved to adaboot.

Comment thread ports/zephyr-cp/supervisor/usb.c
Comment thread ports/zephyr-cp/README.md Outdated
Comment thread ports/zephyr-cp/boards/rp2_boot_mode.dtsi Outdated
tannewt pushed a commit to adafruit/adaboot that referenced this pull request Oct 15, 2026
RP2 boards have no MCUboot, so adaboot_request_update_mode() had nothing
to signal on them. Wire Zephyr's boot-mode retention into the five RP2
layout dtsis (4-byte region with an "AB" prefix and CRC8, so cold-boot
SRAM is not read as a request) and add a module Kconfig that enables
RETAINED_MEM, RETENTION and RETENTION_BOOT_MODE on RP2 when the region is
chosen. Zephyr's RPI_PICO_ROM_BOOTLOADER then follows and enters the ROM
UF2 bootloader on the next boot.

This moves the settings out of CircuitPython (adafruit/circuitpython#11570)
so any application using adaboot gets the same behavior.

Signed-off-by: Mikey Sklar <mikeysklar@gmail.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The RP2 boot-mode retention region and its Kconfig defaults now live in
adaboot, next to the RP2 flash layouts, so Zephyr Arduino can share them.
Drop the CP copies and bump adaboot.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@tannewt tannewt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One Q about the delay.

Comment thread ports/zephyr-cp/supervisor/usb.c Outdated
msg->type == USBD_MSG_CDC_ACM_CONTROL_LINE_STATE) &&
msg->dev == touch_cdc) {
if (touch_requested()) {
k_work_schedule(&touch_work, K_MSEC(100));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need a delay? TinyUSB doesn't:

if (!dtr) {
cdc_line_coding_t coding;
// Use whichever CDC is itf 0.
tud_cdc_get_line_coding(&coding);
if (coding.bit_rate == 1200) {
reset_to_bootloader();
}
} else {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It isn't needed. I took it from ArduinoCore-samd, which waits 250 ms and cancels if DTR comes back. CircuitPython's TinyUSB path resets right away, so I removed it in 8cd3687.

Pico W, no delay Result
1200 touch, then UF2 copy 10/10, ROM drive 0.5-0.7 s after close
open at 115200, or held at 1200 5/5, no reset
power off 3/3, back in CircuitPython

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same on Pico 2 W:

Pico 2 W, no delay Result
1200 touch, then UF2 copy 10/10, ROM drive 0.5-0.9 s after close
open at 115200, or held at 1200 5/5, no reset
power off 3/3, back in CircuitPython

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same on Feather nRF52840:

Feather nRF52840, no delay Result
1200 touch, then UF2 copy 10/10, FTHR840BOOT drive 0.5-0.7 s after close
open at 115200, or held at 1200 5/5, no reset
power off 3/3, back in CircuitPython

Drop the 100 ms recheck. The TinyUSB ports reset as soon as DTR
drops at 1200 baud, and this now does the same.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@mikeysklar
mikeysklar requested a review from tannewt October 16, 2026 22:27
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.

3 participants