Production workflow for PAC52xx using time-multiplexed SWD and UART.
bootloader/- Bootloader source package (5s boot detect window, SWD-safe startup behavior)app/- Example application source package (main.cis the file you usually edit)tools/- Build scriptsbuild_and_flash.bat- Single command to build both images and flash bothmonitor_uart.bat/monitor_uart.ps1- Continuous UART monitor
- SWD flash system (
build_and_flash.bat)
- Purpose: compile + program bootloader and app.
- Transport: SWD only.
- Hardware used: STLink V2 probe + PAC52xx EVK target.
- OpenOCD board config:
board/pac52xx_evk.cfg. - COM port usage: none.
- Runtime UART monitor (
monitor_uart.bat)
- Purpose: view live app/bootloader text output.
- Transport: UART only.
- Hardware used: USB-UART bridge connected to PE1/PE2.
- Default serial port:
COM40at115200.
- Bootloader command channel (optional service/debug)
- Purpose: enter bootloader UART mode and exchange protocol bytes (detect
0xAA, response0x7E). - Transport: UART plus STLink reset orchestration (external helper script in
PACFLASH/tools). - COM port usage: same UART COM port.
tools/uart_flash_app.ps1default detect timeout is32000ms (-DetectTimeoutMs) so it spans the 20s SWD guard plus UART detect window.
On every reset, bootloader startup now follows this sequence:
- SWD is enabled immediately.
- If PBTN is detected, bootloader latches into SWD hold mode and does not jump to app.
- If PBTN is not detected, SWD-only guard window is held for
SWD_GUARD_TIMEOUT_MS(default 20000 ms). - Bootloader enters UART detect mode for
BOOTLOAD_REQUEST_TIMEOUT_MS(default 5000 ms). - If no bootload request arrives, control transfers to app.
- During bootloader detect/app runtime, pressing PBTN forces SWD hold mode until next reset.
UART single-byte control commands in detect/app modes:
0xAA: enter bootloader command mode (bootloader responds with0x7E).0x53: enter SWD hold mode (failsafe lock for recovery).
Bootloader protocol command:
BL_CMD_ENTER_SWD_MODE(command ID0x06): puts target into SWD hold mode from bootloader protocol.
SWD safety policy in this repo:
- Bootloader/app now default to never disabling SWD-at-POR in firmware paths (
BL_PREVENT_SWD_DISABLE=1,APP_PREVENT_SWD_DISABLE=1). SWD_GUARD_TIMEOUT_MSis set to 20000 ms.
Shared pin note (PD0/PD1):
- In shared mode, once app configures UART on PD0/PD1, continuous live SWD attach is not guaranteed.
- Entering SWD hold via PBTN or command now explicitly remaps PD0/PD1 back to SWD and then latches there until reset.
- UART receive polling now probes both PD0/PD1 TX/RX directions in shared mode, so command bytes can still be detected if wiring orientation is reversed.
From C:\Qorvo:
RADLoader\build_and_flash.batFrom Git Bash:
cmd.exe /c RADLoader\\build_and_flash.batWhat it does:
- Builds bootloader binary
- Builds app binary
- Mass-erases device
- Flashes bootloader at
0x00000000 - Flashes app at
0x00001000 - Verifies both images and starts execution
If flashing fails with unable to connect to the target, check EVK power and STLink wiring first, then retry.
PAC5285 note: this flow does not require an external SRST pin. build_and_flash.bat uses a no-SRST attach sequence by default.
From C:\Qorvo:
RADLoader\monitor_uart.batExpected example output:
app uart monitor ready
uptime = 0ms
uptime = 100ms
...
Boot startup also prints:
RADLoader V1.2
uart detect mode
Stop with Ctrl+C.
If normal flashing fails with unable to connect to the target, run:
RADLoader\recover_swd_hold_reset.batThis script performs two recovery attempts automatically:
- No-reset attach at very low SWD speed, then mass erase.
- Connect-under-reset path (only if SRST is actually wired), then mass erase.
PAC5285 reset behavior: use the board PB button (hold ~4s) to trigger hardware reset before the recovery attempts.
If this script still reports RECOVERY FAILED, the issue is below the build/script layer (typically reset wiring, SWD signal integrity, or probe/target electrical state).
Automated recovery helper:
RADLoader\tools\recover_swd_bruteforce.ps1repeats low-speed SWD attach + mass erase attempts to catch narrow reset windows.
- Edit app code in
RADLoader\app\main.c - Run
RADLoader\build_and_flash.bat - Run
RADLoader\monitor_uart.bat
Set these only if your paths/ports differ:
RADLOADER_TOOLROOT(default:C:\ncs\toolchains\c1a76fddb2\opt\zephyr-sdk\arm-zephyr-eabi\bin)RADLOADER_OPENOCD(default:C:\Qorvo\OpenOCD\0.10.0-8-20180512-1921\bin\openocd.exe)RADLOADER_OPENOCD_SCRIPTS(default:C:\Qorvo\OpenOCD\0.10.0-8-20180512-1921\scripts)RADLOADER_BOARD_CFG(default:board/pac52xx_evk.cfg)RADLOADER_COM(default:COM40)RADLOADER_BAUD(default:115200)
- Use STLink V2 for SWD operations in this flow.
- UART monitoring depends on OS COM enumeration. If
COM40is absent, replug the USB-UART adapter and rerun monitor.
Current default build (shared interface on PD0/PD1):
- SWD and UART share PD0/PD1 with boot-time safety gating.
Optional test override (separated interfaces):
- Set
BL_UART_PIN_MODEinbootloader/src/bootloader_config.htoBL_UART_PIN_MODE_SEPARATE. - Set
APP_UART_PIN_MODEinapp/main.ctoAPP_UART_PIN_MODE_SEPARATE. - This routes UART to PE1 (TXD) and PE2 (RXD) while keeping SWD on PD0/PD1.