Skip to content

Commit 5a98889

Browse files
authored
add rom_reset_usb_boot_extra which supports >32 pins and ACTIVE_LOW; change existing uses to use this (#2084)
1 parent 6bb3ccf commit 5a98889

File tree

5 files changed

+67
-12
lines changed

5 files changed

+67
-12
lines changed

src/rp2_common/pico_bootrom/bootrom.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,26 @@ void __attribute__((noreturn)) rom_reset_usb_boot(uint32_t usb_activity_gpio_pin
6363
#endif
6464
}
6565

66+
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) {
67+
#ifdef ROM_FUNC_RESET_USB_BOOT
68+
(void)usb_activity_gpio_pin_active_low;
69+
rom_reset_usb_boot_fn func = (rom_reset_usb_boot_fn) rom_func_lookup(ROM_FUNC_RESET_USB_BOOT);
70+
func(usb_activity_gpio_pin < 0 ? 0 : (1u << usb_activity_gpio_pin), disable_interface_mask);
71+
#elif defined(ROM_FUNC_REBOOT)
72+
uint32_t flags = disable_interface_mask;
73+
if (usb_activity_gpio_pin >= 0) {
74+
flags |= BOOTSEL_FLAG_GPIO_PIN_SPECIFIED;
75+
if (usb_activity_gpio_pin_active_low) {
76+
flags |= BOOTSEL_FLAG_GPIO_PIN_ACTIVE_LOW;
77+
}
78+
}
79+
rom_reboot(REBOOT2_FLAG_REBOOT_TYPE_BOOTSEL | REBOOT2_FLAG_NO_RETURN_ON_SUCCESS, 10, flags, usb_activity_gpio_pin);
80+
__builtin_unreachable();
81+
#else
82+
panic_unsupported();
83+
#endif
84+
}
85+
6686
#if !PICO_RP2040
6787
bool rom_get_boot_random(uint32_t out[4]) {
6888
uint32_t result[5];

src/rp2_common/pico_bootrom/include/pico/bootrom.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,25 @@ static inline void __attribute__((noreturn)) reset_usb_boot(uint32_t usb_activit
237237
rom_reset_usb_boot(usb_activity_gpio_pin_mask, disable_interface_mask);
238238
}
239239

240+
/*!
241+
* \brief Reboot the device into BOOTSEL mode
242+
* \ingroup pico_bootrom
243+
*
244+
* This function reboots the device into the BOOTSEL mode ('usb boot").
245+
*
246+
* Facilities are provided to enable an "activity light" via GPIO attached LED for the USB Mass Storage Device,
247+
* and to limit the USB interfaces exposed.
248+
*
249+
* \param usb_activity_gpio_pin GPIO pin to be used as an activitiy pin, or -1 for none
250+
* from the host.
251+
* \param disable_interface_mask value to control exposed interfaces
252+
* - 0 To enable both interfaces (as per a cold boot)
253+
* - 1 To disable the USB Mass Storage Interface
254+
* - 2 To disable the USB PICOBOOT Interface
255+
* \param usb_activity_gpio_pin_active_low Activity GPIO is active low (ignored on RP2040)
256+
*/
257+
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);
258+
240259
/*!
241260
* \brief Connect the SSI/QMI to the QSPI pads
242261
* \ingroup pico_bootrom

src/rp2_common/pico_bootsel_via_double_reset/pico_bootsel_via_double_reset.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424

2525
// 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
2626

27+
// 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
28+
#ifndef PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED_ACTIVE_LOW
29+
#define PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED_ACTIVE_LOW 0
30+
#endif
31+
2732
// 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
2833
#ifndef PICO_BOOTSEL_VIA_DOUBLE_RESET_INTERFACE_DISABLE_MASK
2934
#define PICO_BOOTSEL_VIA_DOUBLE_RESET_INTERFACE_DISABLE_MASK 0u
@@ -127,13 +132,14 @@ static void __attribute__((constructor)) boot_double_tap_check(void) {
127132
// Detected a double reset, so enter USB bootloader
128133
clear_double_tap_flag();
129134
#ifdef PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED
130-
const uint32_t led_mask = 1u << PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED;
135+
const int led = PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED;
131136
#else
132-
const uint32_t led_mask = 0u;
137+
const int led = -1;
133138
#endif
134-
reset_usb_boot(
135-
led_mask,
136-
PICO_BOOTSEL_VIA_DOUBLE_RESET_INTERFACE_DISABLE_MASK
139+
rom_reset_usb_boot_extra(
140+
led,
141+
PICO_BOOTSEL_VIA_DOUBLE_RESET_INTERFACE_DISABLE_MASK,
142+
PICO_BOOTSEL_VIA_DOUBLE_RESET_ACTIVITY_LED_ACTIVE_LOW
137143
);
138144
}
139145

src/rp2_common/pico_stdio_usb/include/pico/stdio_usb.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@
7373

7474
// 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
7575

76+
// 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
77+
#ifndef PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED_ACTIVE_LOW
78+
#define PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED_ACTIVE_LOW 0
79+
#endif
80+
7681
// 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
7782
#ifndef PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED
7883
#define PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED 0

src/rp2_common/pico_stdio_usb/reset_interface.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,16 +119,19 @@ static bool resetd_control_xfer_cb(uint8_t __unused rhport, uint8_t stage, tusb_
119119
#if PICO_STDIO_USB_RESET_INTERFACE_SUPPORT_RESET_TO_BOOTSEL
120120
if (request->bRequest == RESET_REQUEST_BOOTSEL) {
121121
#ifdef PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED
122-
uint gpio_mask = 1u << PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED;
122+
int gpio = PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED;
123+
bool active_low = PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED_ACTIVE_LOW;
123124
#else
124-
uint gpio_mask = 0u;
125+
int gpio = -1;
126+
bool active_low = false;
125127
#endif
126128
#if !PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED
127129
if (request->wValue & 0x100) {
128-
gpio_mask = 1u << (request->wValue >> 9u);
130+
gpio = request->wValue >> 9u;
129131
}
132+
active_low = request->wValue & 0x200;
130133
#endif
131-
reset_usb_boot(gpio_mask, (request->wValue & 0x7f) | PICO_STDIO_USB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK);
134+
rom_reset_usb_boot_extra(gpio, (request->wValue & 0x7f) | PICO_STDIO_USB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK, active_low);
132135
// does not return, otherwise we'd return true
133136
}
134137
#endif
@@ -173,11 +176,13 @@ usbd_class_driver_t const *usbd_app_driver_get_cb(uint8_t *driver_count) {
173176
void tud_cdc_line_coding_cb(__unused uint8_t itf, cdc_line_coding_t const* p_line_coding) {
174177
if (p_line_coding->bit_rate == PICO_STDIO_USB_RESET_MAGIC_BAUD_RATE) {
175178
#ifdef PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED
176-
const uint gpio_mask = 1u << PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED;
179+
int gpio = PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED;
180+
bool active_low = PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED_ACTIVE_LOW;
177181
#else
178-
const uint gpio_mask = 0u;
182+
int gpio = -1;
183+
bool active_low = false;
179184
#endif
180-
reset_usb_boot(gpio_mask, PICO_STDIO_USB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK);
185+
rom_reset_usb_boot_extra(gpio, PICO_STDIO_USB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK, active_low);
181186
}
182187
}
183188
#endif

0 commit comments

Comments
 (0)