From d068be32208a992ca6be9f49eb837d825ea42472 Mon Sep 17 00:00:00 2001 From: Andrew Scheller Date: Thu, 4 Mar 2021 16:55:28 +0000 Subject: [PATCH 1/2] Add some extra defines to customise behaviour of STDIO_USB_RESET modes --- .../pico_bootsel_via_double_reset.c | 4 ++-- .../pico_stdio_usb/include/pico/stdio_usb.h | 12 ++++++++++++ .../pico_stdio_usb/reset_interface.c | 18 +++++++++++++----- 3 files changed, 27 insertions(+), 7 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 c535ba5a6..c396059c7 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,12 @@ #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 +// 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, max=29, 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_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 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 b85b83bd7..d57eab53e 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,18 @@ #define PICO_STDIO_USB_RESET_MAGIC_BAUD_RATE 1200 #endif +// Setting this to something other than -1 will prevent picotool specifying an activity LED via VENDOR_INTERFACE. Set to -2 to specify none whilst also preventing picotool from specifying an activity LED. +// PICO_CONFIG: PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED, GPIO to use as bootloader activity LED (or -1 for none) when BOOTSEL mode is entered via USB (either VIA_BAUD_RATE or VIA_VENDOR_INTERFACE), type=int, default=-1, max=29, group=pico_stdio_usb +#ifndef PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED +#define PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED -1 +#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 e042e71ca..85a3223ff 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" @@ -37,11 +42,12 @@ static bool resetd_control_request_cb(uint8_t __unused rhport, tusb_control_requ 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; - if (request->wValue & 0x100) { + uint gpio_mask = PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED >= 0 ? + 1u << PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED : 0u; + if ((PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED == -1) && (request->wValue & 0x100)) { gpio_mask = 1u << (request->wValue >> 9u); } - reset_usb_boot(gpio_mask, request->wValue & 0x7f); + 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 @@ -88,7 +94,9 @@ 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); + uint gpio_mask = PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED >= 0 ? + 1u << PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED : 0u; + reset_usb_boot(gpio_mask, PICO_STDIO_USB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK); } } #endif From 4444d79c424de821a8d0c5066b03ca312acd5124 Mon Sep 17 00:00:00 2001 From: Andrew Scheller Date: Thu, 4 Mar 2021 19:45:30 +0000 Subject: [PATCH 2/2] Tweaks to STDIO_USB_RESET defines --- .../pico_bootsel_via_double_reset.c | 12 +++++------ .../pico_stdio_usb/include/pico/stdio_usb.h | 9 ++++---- .../pico_stdio_usb/reset_interface.c | 21 ++++++++++++++----- 3 files changed, 27 insertions(+), 15 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 c396059c7..595a2d51e 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,10 +14,7 @@ #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, max=29, 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, min=0, max=3, default=0, group=pico_bootsel_via_double_reset #ifndef PICO_BOOTSEL_VIA_DOUBLE_RESET_INTERFACE_DISABLE_MASK @@ -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 d57eab53e..6a1effa5b 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,10 +54,11 @@ #define PICO_STDIO_USB_RESET_MAGIC_BAUD_RATE 1200 #endif -// Setting this to something other than -1 will prevent picotool specifying an activity LED via VENDOR_INTERFACE. Set to -2 to specify none whilst also preventing picotool from specifying an activity LED. -// PICO_CONFIG: PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED, GPIO to use as bootloader activity LED (or -1 for none) when BOOTSEL mode is entered via USB (either VIA_BAUD_RATE or VIA_VENDOR_INTERFACE), type=int, default=-1, max=29, group=pico_stdio_usb -#ifndef PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED -#define PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED -1 +// 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. diff --git a/src/rp2_common/pico_stdio_usb/reset_interface.c b/src/rp2_common/pico_stdio_usb/reset_interface.c index 85a3223ff..252548692 100644 --- a/src/rp2_common/pico_stdio_usb/reset_interface.c +++ b/src/rp2_common/pico_stdio_usb/reset_interface.c @@ -40,23 +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 = PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED >= 0 ? - 1u << PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED : 0u; - if ((PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED == -1) && (request->wValue & 0x100)) { +#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); } +#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; } @@ -94,8 +102,11 @@ 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) { - uint gpio_mask = PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED >= 0 ? - 1u << PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED : 0u; +#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); } }