diff --git a/CMakeLists.txt b/CMakeLists.txt index cb300f5..8a1155d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,7 @@ set(VERSION_MINOR 73) ## Release Type Selection option(DH_DEBUG "Build a debug version" OFF) +option(DH_DEBUG_CDC_FLASH "Enable CDC command to trigger bootloader mode" OFF) ## Hardware Configuration set(DP_PIN_DEFAULT 14 CACHE STRING "Default USB D+ Pin Number") @@ -120,6 +121,10 @@ target_compile_definitions(${binary} if (DH_DEBUG) add_definitions(-DDH_DEBUG) endif() + +if (DH_DEBUG_CDC_FLASH) + add_definitions(-DDH_DEBUG_CDC_FLASH) +endif() target_include_directories(${binary} PUBLIC ${COMMON_INCLUDES}) target_link_libraries(${binary} PUBLIC ${COMMON_LINK_LIBRARIES}) diff --git a/README.md b/README.md index 2d14a06..d928150 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,12 @@ _Note_ - This is not an actual generic USB drive, you can't use it to copy files **Option 2** - Using the ROM bootloader - hold the on-board button while connecting each Pico and copy the uf2 to the flash drive that appears. Images later than 0.6 support holding the button without having to fiddle around the power supply, but the "hold button while plugging" should always work, regardless of device state. +**Option 3** - CDC Flash Command (Debug builds only) - If the firmware was built with `DH_DEBUG_CDC_FLASH=ON`, you can trigger bootloader mode via CDC serial command: +```shell +echo -n 'flash' > /dev/tty.usbmodem11104 +``` +This immediately resets the device into bootloader mode where it appears as "RPI-RP2" drive. This feature is intended for development workflows. + ## Misc features ### Mouse slowdown diff --git a/src/usb.c b/src/usb.c index 4bafbaf..ee2938f 100644 --- a/src/usb.c +++ b/src/usb.c @@ -93,6 +93,25 @@ void tud_umount_cb(void) { global_state.tud_connected = false; } +#ifdef DH_DEBUG_CDC_FLASH +void tud_cdc_rx_cb(uint8_t itf) { + char buf[64]; + uint32_t count = tud_cdc_n_available(itf); + + if (count == 0) + return; + + if (count > sizeof(buf)) + count = sizeof(buf); + + tud_cdc_n_read(itf, buf, count); + + if (count >= 5 && memcmp(buf, "flash", 5) == 0) { + reset_usb_boot(0, 0); + } +} +#endif + /* ================================================== * * =============== USB HOST Section =============== * * ================================================== */