summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAngus Gratton <angus@redyak.com.au>2023-10-25 11:04:54 +1100
committerDamien George <damien@micropython.org>2023-11-09 12:27:33 +1100
commit2d363a23cb9e825200e772f973eab921a69e0646 (patch)
tree349f4d1f8c91454a7fbae3f68489be9a139454f5
parentbbc5a18d092425bee802d88a5c9ed3516056bdd5 (diff)
shared/tinyusb: Schedule TinyUSB task function from dcd_event_handler.
dcd_event_handler() is called from the IRQ when a new DCD event is queued for processing by the TinyUSB thread mode task. This lets us queue the handler to run immediately when MicroPython resumes. Currently this relies on a linker --wrap hack to work, but a PR has been submitted to TinyUSB to allow the function to be called inline from dcd_event_handler() itself. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
-rw-r--r--shared/tinyusb/mp_usbd.c23
-rw-r--r--shared/tinyusb/mp_usbd.h3
2 files changed, 23 insertions, 3 deletions
diff --git a/shared/tinyusb/mp_usbd.c b/shared/tinyusb/mp_usbd.c
index ea1de674b..87c10310f 100644
--- a/shared/tinyusb/mp_usbd.c
+++ b/shared/tinyusb/mp_usbd.c
@@ -27,17 +27,40 @@
#include <stdlib.h>
#include "py/mpconfig.h"
+#include "py/runtime.h"
#if MICROPY_HW_ENABLE_USBDEV
#ifndef NO_QSTR
#include "tusb.h" // TinyUSB is not available when running the string preprocessor
+#include "device/dcd.h"
#include "device/usbd.h"
#include "device/usbd_pvt.h"
#endif
+// Legacy TinyUSB task function wrapper, called by some ports from the interpreter hook
void usbd_task(void) {
tud_task_ext(0, false);
}
+// TinyUSB task function wrapper, as scheduled from the USB IRQ
+static void mp_usbd_task(mp_sched_node_t *node);
+
+extern void __real_dcd_event_handler(dcd_event_t const *event, bool in_isr);
+
+// If -Wl,--wrap=dcd_event_handler is passed to the linker, then this wrapper
+// will be called and allows MicroPython to schedule the TinyUSB task when
+// dcd_event_handler() is called from an ISR.
+TU_ATTR_FAST_FUNC void __wrap_dcd_event_handler(dcd_event_t const *event, bool in_isr) {
+ static mp_sched_node_t usbd_task_node;
+
+ __real_dcd_event_handler(event, in_isr);
+ mp_sched_schedule_node(&usbd_task_node, mp_usbd_task);
+}
+
+static void mp_usbd_task(mp_sched_node_t *node) {
+ (void)node;
+ tud_task_ext(0, false);
+}
+
#endif
diff --git a/shared/tinyusb/mp_usbd.h b/shared/tinyusb/mp_usbd.h
index 3a93b929c..2e4feaca9 100644
--- a/shared/tinyusb/mp_usbd.h
+++ b/shared/tinyusb/mp_usbd.h
@@ -29,9 +29,6 @@
#include "py/obj.h"
-// Call instead of tud_task()
-void mp_usbd_task(void);
-
// Function to be implemented in port code.
// Can write a string up to MICROPY_HW_USB_DESC_STR_MAX characters long, plus terminating byte.
extern void mp_usbd_port_get_serial_number(char *buf);