add rom_reset_usb_boot_extra which supports >32 pins and ACTIVE_LOW; change existing uses to use this (#2084)

This commit is contained in:
Graham Sanderson 2024-11-21 16:48:05 -06:00 committed by GitHub
parent 6bb3ccf822
commit 5a98889434
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 67 additions and 12 deletions

View file

@ -63,6 +63,26 @@ void __attribute__((noreturn)) rom_reset_usb_boot(uint32_t usb_activity_gpio_pin
#endif #endif
} }
void __attribute__((noreturn)) rom_reset_usb_boot_extra(int usb_activity_gpio_pin, uint32_t disable_interface_mask, bool usb_activity_gpio_pin_active_low) {
#ifdef ROM_FUNC_RESET_USB_BOOT
(void)usb_activity_gpio_pin_active_low;
rom_reset_usb_boot_fn func = (rom_reset_usb_boot_fn) rom_func_lookup(ROM_FUNC_RESET_USB_BOOT);
func(usb_activity_gpio_pin < 0 ? 0 : (1u << usb_activity_gpio_pin), disable_interface_mask);
#elif defined(ROM_FUNC_REBOOT)
uint32_t flags = disable_interface_mask;
if (usb_activity_gpio_pin >= 0) {
flags |= BOOTSEL_FLAG_GPIO_PIN_SPECIFIED;
if (usb_activity_gpio_pin_active_low) {
flags |= BOOTSEL_FLAG_GPIO_PIN_ACTIVE_LOW;
}
}
rom_reboot(REBOOT2_FLAG_REBOOT_TYPE_BOOTSEL | REBOOT2_FLAG_NO_RETURN_ON_SUCCESS, 10, flags, usb_activity_gpio_pin);
__builtin_unreachable();
#else
panic_unsupported();
#endif
}
#if !PICO_RP2040 #if !PICO_RP2040
bool rom_get_boot_random(uint32_t out[4]) { bool rom_get_boot_random(uint32_t out[4]) {
uint32_t result[5]; uint32_t result[5];

View file

@ -237,6 +237,25 @@ static inline void __attribute__((noreturn)) reset_usb_boot(uint32_t usb_activit
rom_reset_usb_boot(usb_activity_gpio_pin_mask, disable_interface_mask); rom_reset_usb_boot(usb_activity_gpio_pin_mask, disable_interface_mask);
} }
/*!
* \brief Reboot the device into BOOTSEL mode
* \ingroup pico_bootrom
*
* This function reboots the device into the BOOTSEL mode ('usb boot").
*
* Facilities are provided to enable an "activity light" via GPIO attached LED for the USB Mass Storage Device,
* and to limit the USB interfaces exposed.
*
* \param usb_activity_gpio_pin GPIO pin to be used as an activitiy pin, or -1 for none
* from the host.
* \param disable_interface_mask value to control exposed interfaces
* - 0 To enable both interfaces (as per a cold boot)
* - 1 To disable the USB Mass Storage Interface
* - 2 To disable the USB PICOBOOT Interface
* \param usb_activity_gpio_pin_active_low Activity GPIO is active low (ignored on RP2040)
*/
void __attribute__((noreturn)) rom_reset_usb_boot_extra(int usb_activity_gpio_pin, uint32_t disable_interface_mask, bool usb_activity_gpio_pin_active_low);
/*! /*!
* \brief Connect the SSI/QMI to the QSPI pads * \brief Connect the SSI/QMI to the QSPI pads
* \ingroup pico_bootrom * \ingroup pico_bootrom

View file

@ -24,6 +24,11 @@
// 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=47 on RP2350B, 29 otherwise, group=pico_bootsel_via_double_reset // 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=47 on RP2350B, 29 otherwise, group=pico_bootsel_via_double_reset
// PICO_CONFIG: PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED_ACTIVE_LOW, Whether pin used as bootloader activity LED when BOOTSEL mode is entered via reset double tap is active low. Not supported on RP2040, type=bool, default=0, group=pico_bootsel_via_double_reset
#ifndef PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED_ACTIVE_LOW
#define PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED_ACTIVE_LOW 0
#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, min=0, max=3, 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 #ifndef PICO_BOOTSEL_VIA_DOUBLE_RESET_INTERFACE_DISABLE_MASK
#define PICO_BOOTSEL_VIA_DOUBLE_RESET_INTERFACE_DISABLE_MASK 0u #define PICO_BOOTSEL_VIA_DOUBLE_RESET_INTERFACE_DISABLE_MASK 0u
@ -127,13 +132,14 @@ static void __attribute__((constructor)) boot_double_tap_check(void) {
// Detected a double reset, so enter USB bootloader // Detected a double reset, so enter USB bootloader
clear_double_tap_flag(); clear_double_tap_flag();
#ifdef PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED #ifdef PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED
const uint32_t led_mask = 1u << PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED; const int led = PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED;
#else #else
const uint32_t led_mask = 0u; const int led = -1;
#endif #endif
reset_usb_boot( rom_reset_usb_boot_extra(
led_mask, led,
PICO_BOOTSEL_VIA_DOUBLE_RESET_INTERFACE_DISABLE_MASK PICO_BOOTSEL_VIA_DOUBLE_RESET_INTERFACE_DISABLE_MASK,
PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED_ACTIVE_LOW
); );
} }

View file

@ -73,6 +73,11 @@
// 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=47 on RP2350B, 29 otherwise, group=pico_stdio_usb // 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=47 on RP2350B, 29 otherwise, group=pico_stdio_usb
// PICO_CONFIG: PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED_ACTIVE_LOW, Whether pin to use as bootloader activity LED when BOOTSEL mode is entered via USB (either VIA_BAUD_RATE or VIA_VENDOR_INTERFACE) is active low, type=bool, default=0, group=pico_stdio_usb
#ifndef PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED_ACTIVE_LOW
#define PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED_ACTIVE_LOW 0
#endif
// 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 // 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 #ifndef PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED
#define PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED 0 #define PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED 0

View file

@ -119,16 +119,19 @@ static bool resetd_control_xfer_cb(uint8_t __unused rhport, uint8_t stage, tusb_
#if PICO_STDIO_USB_RESET_INTERFACE_SUPPORT_RESET_TO_BOOTSEL #if PICO_STDIO_USB_RESET_INTERFACE_SUPPORT_RESET_TO_BOOTSEL
if (request->bRequest == RESET_REQUEST_BOOTSEL) { if (request->bRequest == RESET_REQUEST_BOOTSEL) {
#ifdef PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED #ifdef PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED
uint gpio_mask = 1u << PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED; int gpio = PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED;
bool active_low = PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED_ACTIVE_LOW;
#else #else
uint gpio_mask = 0u; int gpio = -1;
bool active_low = false;
#endif #endif
#if !PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED #if !PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED
if (request->wValue & 0x100) { if (request->wValue & 0x100) {
gpio_mask = 1u << (request->wValue >> 9u); gpio = request->wValue >> 9u;
} }
active_low = request->wValue & 0x200;
#endif #endif
reset_usb_boot(gpio_mask, (request->wValue & 0x7f) | PICO_STDIO_USB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK); rom_reset_usb_boot_extra(gpio, (request->wValue & 0x7f) | PICO_STDIO_USB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK, active_low);
// does not return, otherwise we'd return true // does not return, otherwise we'd return true
} }
#endif #endif
@ -173,11 +176,13 @@ usbd_class_driver_t const *usbd_app_driver_get_cb(uint8_t *driver_count) {
void tud_cdc_line_coding_cb(__unused uint8_t itf, cdc_line_coding_t const* p_line_coding) { void tud_cdc_line_coding_cb(__unused uint8_t itf, cdc_line_coding_t const* p_line_coding) {
if (p_line_coding->bit_rate == PICO_STDIO_USB_RESET_MAGIC_BAUD_RATE) { if (p_line_coding->bit_rate == PICO_STDIO_USB_RESET_MAGIC_BAUD_RATE) {
#ifdef PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED #ifdef PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED
const uint gpio_mask = 1u << PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED; int gpio = PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED;
bool active_low = PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED_ACTIVE_LOW;
#else #else
const uint gpio_mask = 0u; int gpio = -1;
bool active_low = false;
#endif #endif
reset_usb_boot(gpio_mask, PICO_STDIO_USB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK); rom_reset_usb_boot_extra(gpio, PICO_STDIO_USB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK, active_low);
} }
} }
#endif #endif