Skip to content

TinyUSB: Schedule tud_task from the DCD interrupt, switch rp2 & samd ports #12846

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ports/rp2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ target_compile_options(${MICROPY_TARGET} PRIVATE

target_link_options(${MICROPY_TARGET} PRIVATE
-Wl,--defsym=__micropy_c_heap_size__=${MICROPY_C_HEAP_SIZE}
-Wl,--wrap=dcd_event_handler
)

set_source_files_properties(
Expand Down
15 changes: 0 additions & 15 deletions ports/rp2/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,23 +250,8 @@ extern void mp_thread_end_atomic_section(uint32_t);
#define MICROPY_PY_LWIP_REENTER lwip_lock_acquire();
#define MICROPY_PY_LWIP_EXIT lwip_lock_release();

#if MICROPY_HW_ENABLE_USBDEV
#define MICROPY_HW_USBDEV_TASK_HOOK extern void usbd_task(void); usbd_task();
#define MICROPY_VM_HOOK_COUNT (10)
#define MICROPY_VM_HOOK_INIT static uint vm_hook_divisor = MICROPY_VM_HOOK_COUNT;
#define MICROPY_VM_HOOK_POLL if (get_core_num() == 0 && --vm_hook_divisor == 0) { \
vm_hook_divisor = MICROPY_VM_HOOK_COUNT; \
MICROPY_HW_USBDEV_TASK_HOOK \
}
#define MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_POLL
#define MICROPY_VM_HOOK_RETURN MICROPY_VM_HOOK_POLL
#else
#define MICROPY_HW_USBDEV_TASK_HOOK
#endif

#define MICROPY_EVENT_POLL_HOOK_FAST \
do { \
if (get_core_num() == 0) { MICROPY_HW_USBDEV_TASK_HOOK } \
extern void mp_handle_pending(bool); \
mp_handle_pending(true); \
} while (0)
Expand Down
3 changes: 3 additions & 0 deletions ports/samd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ LIBSTDCPP_FILE_NAME = "$(shell $(CXX) $(CXXFLAGS) -print-file-name=libstdc++.a)"
LDFLAGS += -L"$(shell dirname $(LIBSTDCPP_FILE_NAME))"
endif

LDFLAGS += --wrap=dcd_event_handler

MPY_CROSS_FLAGS += -march=$(MPY_CROSS_MCU_ARCH)

SRC_C += \
Expand Down Expand Up @@ -131,6 +133,7 @@ SHARED_SRC_C += \
shared/runtime/sys_stdio_mphal.c \
shared/timeutils/timeutils.c \
shared/tinyusb/mp_cdc_common.c \
shared/tinyusb/mp_usbd.c

ASF4_SRC_C += $(addprefix lib/asf4/$(MCU_SERIES_LOWER)/,\
hal/src/hal_atomic.c \
Expand Down
8 changes: 4 additions & 4 deletions ports/samd/samd_isr.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,10 +310,10 @@ const ISR isr_vector[] __attribute__((section(".isr_vector"))) = {
&Sercom7_Handler, // 77 Serial Communication Interface 7 (SERCOM7): SERCOM7_3 - 6
0, // 78 Control Area Network 0 (CAN0)
0, // 79 Control Area Network 1 (CAN1)
&USB_0_Handler_wrapper, // 80 Universal Serial Bus (USB): USB_EORSM_DNRS, ...
&USB_1_Handler_wrapper, // 81 Universal Serial Bus (USB): USB_SOF_HSOF
&USB_2_Handler_wrapper, // 82 Universal Serial Bus (USB): USB_TRCPT0_0 - _7
&USB_3_Handler_wrapper, // 83 Universal Serial Bus (USB): USB_TRCPT1_0 - _7
&USB_Handler_wrapper, // 80 Universal Serial Bus (USB): USB_EORSM_DNRS, ...
&USB_Handler_wrapper, // 81 Universal Serial Bus (USB): USB_SOF_HSOF
&USB_Handler_wrapper, // 82 Universal Serial Bus (USB): USB_TRCPT0_0 - _7
&USB_Handler_wrapper, // 83 Universal Serial Bus (USB): USB_TRCPT1_0 - _7
0, // 84 Ethernet MAC (GMAC)
0, // 85 Timer Counter Control 0 (TCC0): TCC0_CNT_A ...
0, // 86 Timer Counter Control 0 (TCC0): TCC0_MC_0
Expand Down
4 changes: 0 additions & 4 deletions ports/samd/samd_soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ void samd_init(void);
void samd_main(void);

void USB_Handler_wrapper(void);
void USB_0_Handler_wrapper(void);
void USB_1_Handler_wrapper(void);
void USB_2_Handler_wrapper(void);
void USB_3_Handler_wrapper(void);

void sercom_enable(Sercom *spi, int state);
void sercom_register_irq(int sercom_id, void (*sercom_irq_handler));
Expand Down
27 changes: 0 additions & 27 deletions ports/samd/tusb_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,33 +117,6 @@ const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
return desc_str;
}

#if defined(MCU_SAMD21)

void USB_Handler_wrapper(void) {
tud_int_handler(0);
tud_task();
}

#elif defined(MCU_SAMD51)

void USB_0_Handler_wrapper(void) {
tud_int_handler(0);
tud_task();
}

void USB_1_Handler_wrapper(void) {
tud_int_handler(0);
tud_task();
}

void USB_2_Handler_wrapper(void) {
tud_int_handler(0);
tud_task();
}

void USB_3_Handler_wrapper(void) {
tud_int_handler(0);
tud_task();
}

#endif
23 changes: 23 additions & 0 deletions shared/tinyusb/mp_usbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 0 additions & 3 deletions shared/tinyusb/mp_usbd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down