From 82547372d1a83f03d137a20f71b2d60a5702a75a Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Mon, 6 May 2024 08:42:08 +0200 Subject: [PATCH 1/2] edpt_dma_start() is called during interrupt time as well, dcd_edpt_xfer() needs DI/EI at one point --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 2fe721d6b..805eb1dda 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -77,6 +77,18 @@ #endif #endif +/** disable interrupts */ +#define DISABLE_IRQ() \ + uint32_t prim = __get_PRIMASK(); \ + __disable_irq(); + +/** (re)enable interrupts */ +#define ENABLE_IRQ() \ + if (!prim) \ + { \ + __enable_irq(); \ + } + /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ @@ -147,7 +159,7 @@ static void start_dma(volatile uint32_t* reg_startep) { static void edpt_dma_start(volatile uint32_t* reg_startep) { if (atomic_flag_test_and_set(&_dcd.dma_running)) { - usbd_defer_func((osal_task_func_t)(uintptr_t ) edpt_dma_start, (void*) (uintptr_t) reg_startep, true); + usbd_defer_func((osal_task_func_t)(uintptr_t ) edpt_dma_start, (void*) (uintptr_t) reg_startep, is_in_isr()); } else { start_dma(reg_startep); } @@ -434,11 +446,15 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE)); if (control_status) { + DISABLE_IRQ(); + // Status Phase also requires EasyDMA has to be available as well !!!! edpt_dma_start(&NRF_USBD->TASKS_EP0STATUS); // The nRF doesn't interrupt on status transmit so we queue up a success response. dcd_event_xfer_complete(0, ep_addr, 0, XFER_RESULT_SUCCESS, is_in_isr()); + + ENABLE_IRQ(); } else if (dir == TUSB_DIR_OUT) { xfer->started = true; if (epnum == 0) { From 9d561410e58ba9efb6ef2bff7b03a2f47dee8d64 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Mon, 13 May 2024 18:57:03 +0200 Subject: [PATCH 2/2] revert (unverified) second race condition --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 805eb1dda..bb07063d2 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -77,18 +77,6 @@ #endif #endif -/** disable interrupts */ -#define DISABLE_IRQ() \ - uint32_t prim = __get_PRIMASK(); \ - __disable_irq(); - -/** (re)enable interrupts */ -#define ENABLE_IRQ() \ - if (!prim) \ - { \ - __enable_irq(); \ - } - /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ @@ -446,15 +434,11 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE)); if (control_status) { - DISABLE_IRQ(); - // Status Phase also requires EasyDMA has to be available as well !!!! edpt_dma_start(&NRF_USBD->TASKS_EP0STATUS); // The nRF doesn't interrupt on status transmit so we queue up a success response. dcd_event_xfer_complete(0, ep_addr, 0, XFER_RESULT_SUCCESS, is_in_isr()); - - ENABLE_IRQ(); } else if (dir == TUSB_DIR_OUT) { xfer->started = true; if (epnum == 0) {