From 5ed4e4d0abfc49d3cde89cebc166ebbe0ef512d8 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Thu, 21 May 2020 21:34:44 +0800 Subject: [PATCH 1/5] lib: tinyusb: update to get tud_task_is_queue_empty This update gives us access to a function we can run with interrupts disabled to determine if the queue is empty. Signed-off-by: Sean Cross --- lib/tinyusb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tinyusb b/lib/tinyusb index 76bf96bcb0c12..dc5445e2f45cb 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 76bf96bcb0c12ba241ee4ecc175afb257e550d19 +Subproject commit dc5445e2f45cb348a44fe24fc1be4bc8b5ba5bab From d1a7fdd9d4720c43d0ab9f16267fd124a414ce9d Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Fri, 8 May 2020 12:37:32 +0800 Subject: [PATCH 2/5] supervisor: support debugging tinyusb Allow for passing `-DCFG_TUSB_DEBUG=1` or `-DCFG_TUSB_DEBUG=2` on the command line to enable debugging tinyusb within circuitpython. Signed-off-by: Sean Cross --- supervisor/shared/usb/tusb_config.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/supervisor/shared/usb/tusb_config.h b/supervisor/shared/usb/tusb_config.h index 627de743e26a3..5b7230983ecd4 100644 --- a/supervisor/shared/usb/tusb_config.h +++ b/supervisor/shared/usb/tusb_config.h @@ -49,7 +49,9 @@ //--------------------------------------------------------------------+ #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE +#ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 +#endif /*------------- RTOS -------------*/ #ifndef CFG_TUSB_OS From 77cf4dce8f1ae03edbe275cb82e250daeba8990f Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Fri, 8 May 2020 12:38:23 +0800 Subject: [PATCH 3/5] nrf: disable interrupts before running wfi In order to ensure we don't have any outstanding requests, disable interrupts prior to issuing `WFI`. As part of this process, check to see if there are any pending USB requests, and only execute the `WFI` if there is no pending data. This fixes #2855 on NRF. Signed-off-by: Sean Cross --- ports/nrf/supervisor/port.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index ea09115f7663d..aa138e4814e55 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -51,8 +51,11 @@ #include "common-hal/rtc/RTC.h" #include "common-hal/neopixel_write/__init__.h" +#include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/rtc/__init__.h" +#include "lib/tinyusb/src/device/usbd.h" + #ifdef CIRCUITPY_AUDIOBUSIO #include "common-hal/audiobusio/I2SOut.h" #endif @@ -264,7 +267,15 @@ void port_sleep_until_interrupt(void) { sd_app_evt_wait(); } else { // Call wait for interrupt ourselves if the SD isn't enabled. - __WFI(); + // Note that `wfi` should be called with interrupts disabled, + // to ensure that the queue is properly drained. The `wfi` + // instruction will returned as long as an interrupt is + // available, even though the actual handler won't fire until + // we re-enable interrupts. + common_hal_mcu_disable_interrupts(); + if (!tud_task_event_ready()) + __WFI(); + common_hal_mcu_enable_interrupts(); } } From fd4ef233c6d9b312c3582466c68390a16ddf15fa Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Thu, 21 May 2020 21:46:37 +0800 Subject: [PATCH 4/5] nrf: port: add memory barrier before wfi ARM recommends issuing a DSB instruction propr to issuing WFI, as it is required on many parts suchas Cortex-M7. This is effectively a no-op on the Cortex-M4 used in most NRF parts, however it ensures that we won't be surprised when new parts come out. See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0321a/BIHICBGB.html for more information. Signed-off-by: Sean Cross --- ports/nrf/supervisor/port.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index aa138e4814e55..36725293c813d 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -273,8 +273,10 @@ void port_sleep_until_interrupt(void) { // available, even though the actual handler won't fire until // we re-enable interrupts. common_hal_mcu_disable_interrupts(); - if (!tud_task_event_ready()) + if (!tud_task_event_ready()) { + __DSB(); __WFI(); + } common_hal_mcu_enable_interrupts(); } } From 67cf005ee545df6b1d6f2a4947c58d6c2afb0f51 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Fri, 8 May 2020 16:59:39 +0800 Subject: [PATCH 5/5] nrf: nvm: assume sd is not enabled if interrupts are off If interrupts are disabled, then calling sd_* functions will hardfault. Instead, assume that it's safe to write if interrupts are disabled. Signed-off-by: Sean Cross --- ports/nrf/peripherals/nrf/nvm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ports/nrf/peripherals/nrf/nvm.c b/ports/nrf/peripherals/nrf/nvm.c index 63b168f14e6f1..dc50e2eefa243 100644 --- a/ports/nrf/peripherals/nrf/nvm.c +++ b/ports/nrf/peripherals/nrf/nvm.c @@ -40,6 +40,8 @@ STATIC bool sd_is_enabled(void) { uint8_t sd_en = 0; + if (__get_PRIMASK()) + return false; (void) sd_softdevice_is_enabled(&sd_en); return sd_en; }