From 89ddb292a2eb335585347f3713411f7775066c7b Mon Sep 17 00:00:00 2001 From: cepetr Date: Thu, 20 Mar 2025 15:29:14 +0100 Subject: [PATCH] feat(core): add event polling to usb vcp driver [no changelog] --- core/embed/io/usb/stm32/usb_class_vcp.c | 58 +++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/core/embed/io/usb/stm32/usb_class_vcp.c b/core/embed/io/usb/stm32/usb_class_vcp.c index 7e2be20ecd..1b732f2836 100644 --- a/core/embed/io/usb/stm32/usb_class_vcp.c +++ b/core/embed/io/usb/stm32/usb_class_vcp.c @@ -22,6 +22,7 @@ #include #include +#include #include "usb_internal.h" @@ -162,6 +163,8 @@ _Static_assert(sizeof(usb_vcp_state_t) <= USBD_CLASS_STATE_MAX_SIZE); static const USBD_ClassTypeDef usb_vcp_class; static const USBD_ClassTypeDef usb_vcp_data_class; +static const syshandle_vmt_t usb_vcp_handle_vmt; + #define usb_get_vcp_state(iface_num) \ ((usb_vcp_state_t *)usb_get_iface_state(iface_num, &usb_vcp_class)) @@ -449,12 +452,21 @@ static uint8_t usb_vcp_class_init(USBD_HandleTypeDef *dev, uint8_t cfg_idx) { USBD_LL_PrepareReceive(dev, state->ep_out, state->rx_packet, state->max_packet_len); + uint8_t iface_num = state->desc_block->iface_data.bInterfaceNumber; + syshandle_t handle = SYSHANDLE_USB_IFACE_0 + iface_num; + syshandle_register(handle, &usb_vcp_handle_vmt, state); + // !@# TODO check result + return USBD_OK; } static uint8_t usb_vcp_class_deinit(USBD_HandleTypeDef *dev, uint8_t cfg_idx) { usb_vcp_state_t *state = (usb_vcp_state_t *)dev->pUserData; + uint8_t iface_num = state->desc_block->iface_data.bInterfaceNumber; + syshandle_t handle = SYSHANDLE_USB_IFACE_0 + iface_num; + syshandle_unregister(handle); + // Flush endpoints USBD_LL_FlushEP(dev, state->ep_in); USBD_LL_FlushEP(dev, state->ep_out); @@ -590,4 +602,50 @@ static const USBD_ClassTypeDef usb_vcp_class = { static const USBD_ClassTypeDef usb_vcp_data_class = {}; +static void on_event_poll(void *context, bool read_awaited, + bool write_awaited) { + usb_vcp_state_t *state = (usb_vcp_state_t *)context; + + uint8_t iface_num = state->desc_block->iface_data.bInterfaceNumber; + syshandle_t handle = SYSHANDLE_USB_IFACE_0 + iface_num; + + if (read_awaited && usb_vcp_can_read(iface_num)) { + syshandle_signal_read_ready(handle, NULL); + } + + if (write_awaited && usb_vcp_can_write(iface_num)) { + syshandle_signal_write_ready(handle, NULL); + } +} + +static bool on_check_read_ready(void *context, systask_id_t task_id, + void *param) { + usb_vcp_state_t *state = (usb_vcp_state_t *)context; + uint8_t iface_num = state->desc_block->iface_data.bInterfaceNumber; + + UNUSED(task_id); + UNUSED(param); + + return usb_vcp_can_read(iface_num); +} + +static bool on_check_write_ready(void *context, systask_id_t task_id, + void *param) { + usb_vcp_state_t *state = (usb_vcp_state_t *)context; + uint8_t iface_num = state->desc_block->iface_data.bInterfaceNumber; + + UNUSED(task_id); + UNUSED(param); + + return usb_vcp_can_write(iface_num); +} + +static const syshandle_vmt_t usb_vcp_handle_vmt = { + .task_created = NULL, + .task_killed = NULL, + .check_read_ready = on_check_read_ready, + .check_write_ready = on_check_write_ready, + .poll = on_event_poll, +}; + #endif // KERNEL_MODE