From d0e51346cdc691624bc10da89a775a82ef86d92a Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 18 Jun 2026 17:44:16 +0700 Subject: fix(stm32_fsdev): don't enable the unused USB wakeup EXTI IRQ (F1/F3/G4/L1) The classic-USB STM32 fsdev driver enabled the EXTI-line USB wakeup interrupt (USBWakeUp_IRQn, and USBWakeUp_RMP_IRQn on the F3 remap path) in the NVIC, but never uses it: resume is serviced in-band via ISTR.WKUP in the USB_LP/HP ISR, and the driver never arms or clears that EXTI line. The wakeup EXTI interrupt is only needed to wake the core from STOP mode, which TinyUSB does not implement. Leaving its NVIC vector enabled lets it fire spuriously into an unhandled or looping vector -- the freeze reported in #3696 on STM32G473. USBWakeUp_IRQn is a valid, dedicated USB-wakeup-via-EXTI interrupt (e.g. stm32g473xx.h: =42 "USB Wakeup through EXTI line"), not an "unrelated interrupt"; it is simply unused here. - Comment out USBWakeUp_IRQn for F1/F3/G4/L1 and USBWakeUp_RMP_IRQn on the F3 remap path, kept in place so STOP-mode wakeup is a one-line re-enable. - Keep the STM32L1 USBWakeUp_IRQn -> USB_FS_WKUP_IRQn alias for that re-enable. - Document the rationale in fsdev_stm32.h with a TODO. - Comment out the matching USBWakeUp(_RMP)_IRQHandler in the F1/F3/G4 BSPs, and the FreeRTOS NVIC_SetPriority(USBWakeUp_IRQn) on F1/G4. Fixes #3696 Co-Authored-By: Claude Opus 4.8 (1M context) --- hw/bsp/stm32f1/family.c | 10 ++++++---- hw/bsp/stm32f3/family.c | 7 ++++--- hw/bsp/stm32g4/family.c | 10 ++++++---- src/portable/st/stm32_fsdev/fsdev_stm32.h | 22 +++++++++++++--------- 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/hw/bsp/stm32f1/family.c b/hw/bsp/stm32f1/family.c index abde44d21..67427da1f 100644 --- a/hw/bsp/stm32f1/family.c +++ b/hw/bsp/stm32f1/family.c @@ -63,9 +63,11 @@ void USB_LP_IRQHandler(void) { tud_int_handler(0); } -void USBWakeUp_IRQHandler(void) { - tud_int_handler(0); -} +// USB wakeup EXTI IRQ is not enabled by the fsdev driver (see fsdev_stm32.h); +// restore when STOP-mode wakeup is implemented. +//void USBWakeUp_IRQHandler(void) { +// tud_int_handler(0); +//} //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM @@ -128,7 +130,7 @@ void board_init(void) { // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_HP_CAN1_TX_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USBWakeUp_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + //NVIC_SetPriority(USBWakeUp_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif // LED diff --git a/hw/bsp/stm32f3/family.c b/hw/bsp/stm32f3/family.c index 35e1852e8..bddf224d2 100644 --- a/hw/bsp/stm32f3/family.c +++ b/hw/bsp/stm32f3/family.c @@ -76,9 +76,10 @@ void USB_LP_IRQHandler(void) { // USB wakeup interrupt (Channel 76): Triggered by the wakeup event from the USB // Suspend mode. -void USBWakeUp_RMP_IRQHandler(void) { - tud_int_handler(0); -} +// Not enabled by the fsdev driver (see fsdev_stm32.h); restore for STOP-mode wakeup. +//void USBWakeUp_RMP_IRQHandler(void) { +// tud_int_handler(0); +//} //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM diff --git a/hw/bsp/stm32g4/family.c b/hw/bsp/stm32g4/family.c index 433f74e2a..cf7d4329b 100644 --- a/hw/bsp/stm32g4/family.c +++ b/hw/bsp/stm32g4/family.c @@ -61,9 +61,11 @@ void USB_LP_IRQHandler(void) { tud_int_handler(0); } -void USBWakeUp_IRQHandler(void) { - tud_int_handler(0); -} +// USB wakeup EXTI IRQ is not enabled by the fsdev driver (see fsdev_stm32.h); +// restore when STOP-mode wakeup is implemented. +//void USBWakeUp_IRQHandler(void) { +// tud_int_handler(0); +//} // USB PD void UCPD1_IRQHandler(void) { @@ -99,7 +101,7 @@ void board_init(void) { // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_HP_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_SetPriority(USB_LP_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USBWakeUp_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + //NVIC_SetPriority(USBWakeUp_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif GPIO_InitTypeDef GPIO_InitStruct; diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index b15c95302..93cdac808 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -168,14 +168,18 @@ #define FSDEV_USE_SBUF_ISO 0 #endif -//--------------------------------------------------------------------+ -// -//--------------------------------------------------------------------+ - +// STM32L1 calls it USB_FS_WKUP_IRQn; alias so the commented USBWakeUp_IRQn below +// can be uncommented as-is. #if TU_CHECK_MCU(OPT_MCU_STM32L1) && !defined(USBWakeUp_IRQn) #define USBWakeUp_IRQn USB_FS_WKUP_IRQn #endif +// USB interrupt vectors to enable in NVIC. The EXTI-line USB wakeup interrupt +// (USBWakeUp_IRQn, and USBWakeUp_RMP_IRQn on F3) is left commented out: resume is +// handled in-band via ISTR.WKUP in the USB_LP/HP ISR; the EXTI line is only needed to +// wake the core from STOP mode, which this driver does not implement (it never arms or +// clears that EXTI line, so enabling its NVIC vector can only spuriously fire/freeze). +// TODO: uncomment USBWakeUp_IRQn (+ arm/clear its EXTI line) when adding STOP-mode wakeup. static const IRQn_Type fsdev_irq[] = { #if TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32L0, OPT_MCU_STM32L4, OPT_MCU_STM32U5) USB_IRQn, @@ -192,15 +196,15 @@ static const IRQn_Type fsdev_irq[] = { #elif CFG_TUSB_MCU == OPT_MCU_STM32F1 USB_HP_CAN1_TX_IRQn, USB_LP_CAN1_RX0_IRQn, - USBWakeUp_IRQn, + //USBWakeUp_IRQn, #elif CFG_TUSB_MCU == OPT_MCU_STM32F3 USB_HP_CAN_TX_IRQn, USB_LP_CAN_RX0_IRQn, - USBWakeUp_IRQn, + //USBWakeUp_IRQn, #elif TU_CHECK_MCU(OPT_MCU_STM32G4, OPT_MCU_STM32L1) USB_HP_IRQn, USB_LP_IRQn, - USBWakeUp_IRQn, + //USBWakeUp_IRQn, #elif CFG_TUSB_MCU == OPT_MCU_STM32WB USB_HP_IRQn, USB_LP_IRQn, @@ -223,7 +227,7 @@ TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_enable(uint8_t rhport) { if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) { NVIC_EnableIRQ(USB_HP_IRQn); NVIC_EnableIRQ(USB_LP_IRQn); - NVIC_EnableIRQ(USBWakeUp_RMP_IRQn); + //NVIC_EnableIRQ(USBWakeUp_RMP_IRQn); } else #endif { @@ -243,7 +247,7 @@ TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_disable(uint8_t rhport) { if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) { NVIC_DisableIRQ(USB_HP_IRQn); NVIC_DisableIRQ(USB_LP_IRQn); - NVIC_DisableIRQ(USBWakeUp_RMP_IRQn); + //NVIC_DisableIRQ(USBWakeUp_RMP_IRQn); } else #endif { -- cgit v1.3.1