1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-03-28 14:05:43 +00:00

feat(core): add event polling to usb driver

[no changelog]
This commit is contained in:
cepetr 2025-03-20 15:29:14 +01:00
parent b6ac04fc28
commit dc05c6d5f7

View File

@ -24,6 +24,7 @@
#include <io/usb.h>
#include <sec/random_delays.h>
#include <sys/sysevent_source.h>
#include <sys/systick.h>
#include "usb_internal.h"
@ -56,6 +57,11 @@ typedef struct {
uint8_t state[USBD_CLASS_STATE_MAX_SIZE] __attribute__((aligned(8)));
} usb_iface_t;
// USB driver task local storage
typedef struct {
usb_state_t state;
} usb_driver_tls_t;
typedef struct {
// Set if the driver is initialized
secbool initialized;
@ -84,8 +90,8 @@ typedef struct {
// Set to `sectrue` if the USB stack was ready sinced the last start
secbool was_ready;
// Current state of USB configuration
secbool configured;
// Task local storage for USB driver
usb_driver_tls_t tls[SYSTASK_MAX_TASKS];
} usb_driver_t;
@ -97,6 +103,7 @@ static usb_driver_t g_usb_driver = {
// forward declarations of dispatch functions
static const USBD_ClassTypeDef usb_class;
static const USBD_DescriptorsTypeDef usb_descriptors;
static const syshandle_vmt_t g_usb_handle_vmt;
static secbool __wur check_desc_str(const char *s) {
if (NULL == s) return secfalse;
@ -174,9 +181,13 @@ secbool usb_init(const usb_dev_info_t *dev_info) {
drv->config_desc->bMaxPower = 0x32;
// starting with this flag set, to avoid false warnings
drv->configured = sectrue;
drv->initialized = sectrue;
if (!syshandle_register(SYSHANDLE_USB, &g_usb_handle_vmt, drv)) {
usb_deinit();
return secfalse;
}
return sectrue;
}
@ -187,6 +198,8 @@ void usb_deinit(void) {
return;
}
syshandle_unregister(SYSHANDLE_USB);
usb_stop();
drv->initialized = secfalse;
@ -306,31 +319,25 @@ usb_event_t usb_get_event(void) {
if (drv->initialized != sectrue) {
// The driver is not initialized
return false;
return USB_EVENT_NONE;
}
secbool configured = usb_configured();
if (configured != drv->configured) {
drv->configured = configured;
if (configured == sectrue) {
return USB_EVENT_CONFIGURED;
} else {
return USB_EVENT_DECONFIGURED;
}
usb_state_t new_state;
usb_get_state(&new_state);
usb_driver_tls_t *tls = &drv->tls[systask_id(systask_active())];
if (new_state.configured != tls->state.configured) {
tls->state.configured = new_state.configured;
return new_state.configured ? USB_EVENT_CONFIGURED : USB_EVENT_DECONFIGURED;
}
return USB_EVENT_NONE;
}
void usb_get_state(usb_state_t *state) {
usb_driver_t *drv = &g_usb_driver;
usb_state_t s = {0};
if (drv->initialized == sectrue) {
s.configured = drv->configured == sectrue;
}
s.configured = usb_configured();
*state = s;
}
@ -779,4 +786,39 @@ static const USBD_ClassTypeDef usb_class = {
.GetUsrStrDescriptor = usb_class_get_usrstr_desc,
};
static void on_task_created(void *context, systask_id_t task_id) {
usb_driver_t *drv = (usb_driver_t *)context;
usb_driver_tls_t *tls = &drv->tls[task_id];
memset(tls, 0, sizeof(usb_driver_tls_t));
}
static void on_event_poll(void *context, bool read_awaited,
bool write_awaited) {
UNUSED(context);
UNUSED(write_awaited);
if (read_awaited) {
usb_state_t new_state;
usb_get_state(&new_state);
syshandle_signal_read_ready(SYSHANDLE_USB, &new_state);
}
}
static bool on_check_read_ready(void *context, systask_id_t task_id,
void *param) {
usb_driver_t *drv = (usb_driver_t *)context;
usb_driver_tls_t *tls = &drv->tls[task_id];
usb_state_t *new_state = (usb_state_t *)param;
return (new_state->configured != tls->state.configured);
}
static const syshandle_vmt_t g_usb_handle_vmt = {
.task_created = on_task_created,
.task_killed = NULL,
.check_read_ready = on_check_read_ready,
.check_write_ready = NULL,
.poll = on_event_poll,
};
#endif // KERNEL_MODE