From 4c768d2bb8af38b5407efea2c0f793cb332cee1e Mon Sep 17 00:00:00 2001 From: Andrew Scheller Date: Fri, 5 Mar 2021 01:01:30 +0000 Subject: [PATCH] Add some extra defines to customise behaviour of STDIO_USB_RESET modes (#226) * Add some extra defines to customise behaviour of STDIO_USB_RESET modes * Tweaks to STDIO_USB_RESET defines --- .../pico_bootsel_via_double_reset.c | 14 +++++----- .../pico_stdio_usb/include/pico/stdio_usb.h | 13 +++++++++ .../pico_stdio_usb/reset_interface.c | 27 ++++++++++++++++--- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/rp2_common/pico_bootsel_via_double_reset/pico_bootsel_via_double_reset.c b/src/rp2_common/pico_bootsel_via_double_reset/pico_bootsel_via_double_reset.c index c535ba5..595a2d5 100644 --- a/src/rp2_common/pico_bootsel_via_double_reset/pico_bootsel_via_double_reset.c +++ b/src/rp2_common/pico_bootsel_via_double_reset/pico_bootsel_via_double_reset.c @@ -14,12 +14,9 @@ #define PICO_BOOTSEL_VIA_DOUBLE_RESET_TIMEOUT_MS 200 #endif -// PICO_CONFIG: PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED, GPIO to use as bootloader activity LED when BOOTSEL mode is entered via reset double tap (or -1 for none), type=int, default=-1, group=pico_bootsel_via_double_reset -#ifndef PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED -#define PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED -1 -#endif +// PICO_CONFIG: PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED, Optionally define a pin to use as bootloader activity LED when BOOTSEL mode is entered via reset double tap, type=int, min=0, max=29, group=pico_bootsel_via_double_reset -// PICO_CONFIG: PICO_BOOTSEL_VIA_DOUBLE_RESET_INTERFACE_DISABLE_MASK, Optionally disable either the mass storage interface (bit 0) or the PICOBOOT interface (bit 1) when entering BOOTSEL mode via double reset, type=int, default=0, group=pico_bootsel_via_double_reset +// PICO_CONFIG: PICO_BOOTSEL_VIA_DOUBLE_RESET_INTERFACE_DISABLE_MASK, Optionally disable either the mass storage interface (bit 0) or the PICOBOOT interface (bit 1) when entering BOOTSEL mode via double reset, type=int, min=0, max=3, default=0, group=pico_bootsel_via_double_reset #ifndef PICO_BOOTSEL_VIA_DOUBLE_RESET_INTERFACE_DISABLE_MASK #define PICO_BOOTSEL_VIA_DOUBLE_RESET_INTERFACE_DISABLE_MASK 0u #endif @@ -75,8 +72,11 @@ static void __attribute__((constructor)) boot_double_tap_check(void) { } // Detected a double reset, so enter USB bootloader magic_location[0] = 0; - uint32_t led_mask = PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED >= 0 ? - 1u << PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED : 0u; +#ifdef PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED + const uint32_t led_mask = 1u << PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED; +#else + const uint32_t led_mask = 0u; +#endif reset_usb_boot( led_mask, PICO_BOOTSEL_VIA_DOUBLE_RESET_INTERFACE_DISABLE_MASK diff --git a/src/rp2_common/pico_stdio_usb/include/pico/stdio_usb.h b/src/rp2_common/pico_stdio_usb/include/pico/stdio_usb.h index b85b83b..6a1effa 100644 --- a/src/rp2_common/pico_stdio_usb/include/pico/stdio_usb.h +++ b/src/rp2_common/pico_stdio_usb/include/pico/stdio_usb.h @@ -54,6 +54,19 @@ #define PICO_STDIO_USB_RESET_MAGIC_BAUD_RATE 1200 #endif +// PICO_CONFIG: PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED, Optionally define a pin to use as bootloader activity LED when BOOTSEL mode is entered via USB (either VIA_BAUD_RATE or VIA_VENDOR_INTERFACE), type=int, min=0, max=29, group=pico_stdio_usb + +// PICO_CONFIG: PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED, Whether the pin specified by PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED is fixed or can be modified by picotool over the VENDOR USB interface, type=bool, default=0, group=pico_stdio_usb +#ifndef PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED +#define PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED 0 +#endif + +// Any modes disabled here can't be re-enabled by picotool via VENDOR_INTERFACE. +// PICO_CONFIG: PICO_STDIO_USB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK, Optionally disable either the mass storage interface (bit 0) or the PICOBOOT interface (bit 1) when entering BOOTSEL mode via USB (either VIA_BAUD_RATE or VIA_VENDOR_INTERFACE), type=int, min=0, max=3, default=0, group=pico_stdio_usb +#ifndef PICO_STDIO_USB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK +#define PICO_STDIO_USB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK 0u +#endif + // PICO_CONFIG: PICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE, Enable/disable resetting into BOOTSEL mode via an additional VENDOR USB interface - enables picotool based reset, type=bool, default=1, group=pico_stdio_usb #ifndef PICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE #define PICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE 1 diff --git a/src/rp2_common/pico_stdio_usb/reset_interface.c b/src/rp2_common/pico_stdio_usb/reset_interface.c index e042e71..2525486 100644 --- a/src/rp2_common/pico_stdio_usb/reset_interface.c +++ b/src/rp2_common/pico_stdio_usb/reset_interface.c @@ -5,8 +5,13 @@ */ #include "tusb.h" -#if PICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE #include "pico/bootrom.h" + +#if PICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE && !(PICO_STDIO_USB_RESET_INTERFACE_SUPPORT_RESET_TO_BOOTSEL || PICO_STDIO_USB_RESET_INTERFACE_SUPPORT_RESET_TO_FLASH_BOOT) +#warning PICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE has been selected but neither PICO_STDIO_USB_RESET_INTERFACE_SUPPORT_RESET_TO_BOOTSEL nor PICO_STDIO_USB_RESET_INTERFACE_SUPPORT_RESET_TO_FLASH_BOOT have been selected. +#endif + +#if PICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE #include "pico/stdio_usb/reset_interface.h" #include "hardware/watchdog.h" #include "device/usbd_pvt.h" @@ -35,22 +40,31 @@ static uint16_t resetd_open(uint8_t __unused rhport, tusb_desc_interface_t const // Support for parameterized reset via vendor interface control request static bool resetd_control_request_cb(uint8_t __unused rhport, tusb_control_request_t const *request) { if (request->wIndex == itf_num) { + #if PICO_STDIO_USB_RESET_INTERFACE_SUPPORT_RESET_TO_BOOTSEL if (request->bRequest == RESET_REQUEST_BOOTSEL) { - uint gpio_mask = 0; +#ifdef PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED + uint gpio_mask = 1u << PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED; +#else + uint gpio_mask = 0u; +#endif +#if !PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED if (request->wValue & 0x100) { gpio_mask = 1u << (request->wValue >> 9u); } - reset_usb_boot(gpio_mask, request->wValue & 0x7f); +#endif + reset_usb_boot(gpio_mask, (request->wValue & 0x7f) | PICO_STDIO_USB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK); // does not return, otherwise we'd return true } #endif + #if PICO_STDIO_USB_RESET_INTERFACE_SUPPORT_RESET_TO_FLASH_BOOT if (request->bRequest == RESET_REQUEST_FLASH) { watchdog_reboot(0, SRAM_END, PICO_STDIO_USB_RESET_RESET_TO_FLASH_DELAY_MS); return true; } #endif + } return false; } @@ -88,7 +102,12 @@ usbd_class_driver_t const *usbd_app_driver_get_cb(uint8_t *driver_count) { // Support for default BOOTSEL reset by changing baud rate void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding) { if (p_line_coding->bit_rate == PICO_STDIO_USB_RESET_MAGIC_BAUD_RATE) { - reset_usb_boot(0, 0); +#ifdef PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED + const uint gpio_mask = 1u << PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED; +#else + const uint gpio_mask = 0u; +#endif + reset_usb_boot(gpio_mask, PICO_STDIO_USB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK); } } #endif