feat(core/usbd_core): add ep0 setup handler into thread feature

This commit is contained in:
sakumisu
2025-02-01 14:42:29 +08:00
parent afc9213cd1
commit e592a548e9
3 changed files with 128 additions and 7 deletions

View File

@@ -48,6 +48,17 @@
/* Enable test mode */ /* Enable test mode */
// #define CONFIG_USBDEV_TEST_MODE // #define CONFIG_USBDEV_TEST_MODE
/* move ep0 setup handler from isr to thread */
// #define CONFIG_USBDEV_EP0_THREAD
#ifndef CONFIG_USBDEV_EP0_PRIO
#define CONFIG_USBDEV_EP0_PRIO 4
#endif
#ifndef CONFIG_USBDEV_EP0_STACKSIZE
#define CONFIG_USBDEV_EP0_STACKSIZE 2048
#endif
#ifndef CONFIG_USBDEV_MSC_MAX_LUN #ifndef CONFIG_USBDEV_MSC_MAX_LUN
#define CONFIG_USBDEV_MSC_MAX_LUN 1 #define CONFIG_USBDEV_MSC_MAX_LUN 1
#endif #endif

View File

@@ -4,6 +4,17 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "usbd_core.h" #include "usbd_core.h"
#ifdef CONFIG_USBDEV_EP0_THREAD
#include "usb_osal.h"
#define USB_EP0_STATE_SETUP 0
#define USB_EP0_STATE_IN 1
#define USB_EP0_STATE_OUT 2
#endif
#undef USB_DBG_TAG
#define USB_DBG_TAG "usbd_core"
#include "usb_log.h"
/* general descriptor field offsets */ /* general descriptor field offsets */
#define DESC_bLength 0 /** Length offset */ #define DESC_bLength 0 /** Length offset */
@@ -62,6 +73,10 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv {
#endif #endif
#ifdef CONFIG_USBDEV_TEST_MODE #ifdef CONFIG_USBDEV_TEST_MODE
bool test_req; bool test_req;
#endif
#ifdef CONFIG_USBDEV_EP0_THREAD
usb_osal_mq_t usbd_ep0_mq;
usb_osal_thread_t usbd_ep0_thread;
#endif #endif
struct usbd_interface *intf[16]; struct usbd_interface *intf[16];
uint8_t intf_altsetting[16]; uint8_t intf_altsetting[16];
@@ -1125,12 +1140,10 @@ void usbd_event_reset_handler(uint8_t busid)
g_usbd_core[busid].event_handler(busid, USBD_EVENT_RESET); g_usbd_core[busid].event_handler(busid, USBD_EVENT_RESET);
} }
void usbd_event_ep0_setup_complete_handler(uint8_t busid, uint8_t *psetup) static void __usbd_event_ep0_setup_complete_handler(uint8_t busid, struct usb_setup_packet *setup)
{ {
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
uint8_t *buf; uint8_t *buf;
memcpy(setup, psetup, 8);
#ifdef CONFIG_USBDEV_SETUP_LOG_PRINT #ifdef CONFIG_USBDEV_SETUP_LOG_PRINT
usbd_print_setup(setup); usbd_print_setup(setup);
#endif #endif
@@ -1195,7 +1208,20 @@ void usbd_event_ep0_setup_complete_handler(uint8_t busid, uint8_t *psetup)
} }
} }
void usbd_event_ep0_in_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbytes) void usbd_event_ep0_setup_complete_handler(uint8_t busid, uint8_t *psetup)
{
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
memcpy(setup, psetup, 8);
#ifdef CONFIG_USBDEV_EP0_THREAD
usb_osal_mq_send(g_usbd_core[busid].usbd_ep0_mq, USB_EP0_STATE_SETUP);
#else
__usbd_event_ep0_setup_complete_handler(busid, setup);
#endif
}
static void usbd_event_ep0_in_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbytes)
{ {
struct usb_setup_packet *setup = &g_usbd_core[busid].setup; struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
@@ -1236,11 +1262,12 @@ void usbd_event_ep0_in_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbyt
} }
} }
void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbytes) static void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbytes)
{ {
struct usb_setup_packet *setup = &g_usbd_core[busid].setup; struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
(void)ep; (void)ep;
(void)setup;
if (nbytes > 0) { if (nbytes > 0) {
g_usbd_core[busid].ep0_data_buf += nbytes; g_usbd_core[busid].ep0_data_buf += nbytes;
@@ -1249,6 +1276,9 @@ void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nby
USB_LOG_DBG("EP0 recv %d bytes, %d remained\r\n", nbytes, g_usbd_core[busid].ep0_data_buf_residue); USB_LOG_DBG("EP0 recv %d bytes, %d remained\r\n", nbytes, g_usbd_core[busid].ep0_data_buf_residue);
if (g_usbd_core[busid].ep0_data_buf_residue == 0) { if (g_usbd_core[busid].ep0_data_buf_residue == 0) {
#ifdef CONFIG_USBDEV_EP0_THREAD
usb_osal_mq_send(g_usbd_core[busid].usbd_ep0_mq, USB_EP0_STATE_OUT);
#else
/* Received all, send data to handler */ /* Received all, send data to handler */
g_usbd_core[busid].ep0_data_buf = g_usbd_core[busid].req_data; g_usbd_core[busid].ep0_data_buf = g_usbd_core[busid].req_data;
if (!usbd_setup_request_handler(busid, setup, &g_usbd_core[busid].ep0_data_buf, &g_usbd_core[busid].ep0_data_buf_len)) { if (!usbd_setup_request_handler(busid, setup, &g_usbd_core[busid].ep0_data_buf, &g_usbd_core[busid].ep0_data_buf_len)) {
@@ -1258,6 +1288,7 @@ void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nby
/*Send status to host*/ /*Send status to host*/
usbd_ep_start_write(busid, USB_CONTROL_IN_EP0, NULL, 0); usbd_ep_start_write(busid, USB_CONTROL_IN_EP0, NULL, 0);
#endif
} else { } else {
/* Start reading the remain data */ /* Start reading the remain data */
usbd_ep_start_read(busid, USB_CONTROL_OUT_EP0, g_usbd_core[busid].ep0_data_buf, g_usbd_core[busid].ep0_data_buf_residue); usbd_ep_start_read(busid, USB_CONTROL_OUT_EP0, g_usbd_core[busid].ep0_data_buf, g_usbd_core[busid].ep0_data_buf_residue);
@@ -1396,6 +1427,47 @@ int usbd_send_remote_wakeup(uint8_t busid)
} }
} }
#ifdef CONFIG_USBDEV_EP0_THREAD
static void usbdev_ep0_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
{
uintptr_t event;
int ret;
uint8_t busid = (uint8_t)CONFIG_USB_OSAL_THREAD_GET_ARGV;
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
while (1) {
ret = usb_osal_mq_recv(g_usbd_core[busid].usbd_ep0_mq, (uintptr_t *)&event, USB_OSAL_WAITING_FOREVER);
if (ret < 0) {
continue;
}
USB_LOG_DBG("event:%d\r\n", event);
switch (event) {
case USB_EP0_STATE_SETUP:
__usbd_event_ep0_setup_complete_handler(busid, setup);
break;
case USB_EP0_STATE_IN:
// do nothing
break;
case USB_EP0_STATE_OUT:
/* Received all, send data to handler */
g_usbd_core[busid].ep0_data_buf = g_usbd_core[busid].req_data;
if (!usbd_setup_request_handler(busid, setup, &g_usbd_core[busid].ep0_data_buf, &g_usbd_core[busid].ep0_data_buf_len)) {
usbd_ep_set_stall(busid, USB_CONTROL_IN_EP0);
return;
}
/*Send status to host*/
usbd_ep_start_write(busid, USB_CONTROL_IN_EP0, NULL, 0);
break;
default:
break;
}
}
}
#endif
int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event)) int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event))
{ {
int ret; int ret;
@@ -1410,6 +1482,21 @@ int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uin
bus = &g_usbdev_bus[busid]; bus = &g_usbdev_bus[busid];
bus->reg_base = reg_base; bus->reg_base = reg_base;
#ifdef CONFIG_USBDEV_EP0_THREAD
g_usbd_core[busid].usbd_ep0_mq = usb_osal_mq_create(1);
if (g_usbd_core[busid].usbd_ep0_mq == NULL) {
USB_LOG_ERR("No memory to alloc for g_usbd_core[busid].usbd_ep0_mq\r\n");
while (1) {
}
}
g_usbd_core[busid].usbd_ep0_thread = usb_osal_thread_create("usbd_ep0", CONFIG_USBDEV_EP0_STACKSIZE, CONFIG_USBDEV_EP0_PRIO, usbdev_ep0_thread, (void *)(uint32_t)busid);
if (g_usbd_core[busid].usbd_ep0_thread == NULL) {
USB_LOG_ERR("No memory to alloc for g_usbd_core[busid].usbd_ep0_thread\r\n");
while (1) {
}
}
#endif
g_usbd_core[busid].event_handler = event_handler; g_usbd_core[busid].event_handler = event_handler;
ret = usb_dc_init(busid); ret = usb_dc_init(busid);
usbd_class_event_notify_handler(busid, USBD_EVENT_INIT, NULL); usbd_class_event_notify_handler(busid, USBD_EVENT_INIT, NULL);
@@ -1429,5 +1516,14 @@ int usbd_deinitialize(uint8_t busid)
usbd_class_event_notify_handler(busid, USBD_EVENT_DEINIT, NULL); usbd_class_event_notify_handler(busid, USBD_EVENT_DEINIT, NULL);
usb_dc_deinit(busid); usb_dc_deinit(busid);
g_usbd_core[busid].intf_offset = 0; g_usbd_core[busid].intf_offset = 0;
#ifdef CONFIG_USBDEV_EP0_THREAD
if (g_usbd_core[busid].usbd_ep0_mq) {
usb_osal_mq_delete(g_usbd_core[busid].usbd_ep0_mq);
}
if (g_usbd_core[busid].usbd_ep0_thread) {
usb_osal_thread_delete(g_usbd_core[busid].usbd_ep0_thread);
}
#endif
return 0; return 0;
} }

View File

@@ -20,7 +20,7 @@
/* Enable print with color */ /* Enable print with color */
#define CONFIG_USB_PRINTF_COLOR_ENABLE #define CONFIG_USB_PRINTF_COLOR_ENABLE
/* data align size when use dma */ /* data align size when use dma or use dcache */
#ifndef CONFIG_USB_ALIGN_SIZE #ifndef CONFIG_USB_ALIGN_SIZE
#define CONFIG_USB_ALIGN_SIZE 4 #define CONFIG_USB_ALIGN_SIZE 4
#endif #endif
@@ -29,7 +29,6 @@
#define USB_NOCACHE_RAM_SECTION #define USB_NOCACHE_RAM_SECTION
/* ================= USB Device Stack Configuration ================ */ /* ================= USB Device Stack Configuration ================ */
// NOTE: Below configurations are removed to Kconfig, `idf.py menuconfig` to config them
/* Ep0 in and out transfer buffer */ /* Ep0 in and out transfer buffer */
#ifndef CONFIG_USBDEV_REQUEST_BUFFER_LEN #ifndef CONFIG_USBDEV_REQUEST_BUFFER_LEN
@@ -50,6 +49,17 @@
/* Enable test mode */ /* Enable test mode */
// #define CONFIG_USBDEV_TEST_MODE // #define CONFIG_USBDEV_TEST_MODE
/* move ep0 setup handler from isr to thread */
// #define CONFIG_USBDEV_EP0_THREAD
#ifndef CONFIG_USBDEV_EP0_PRIO
#define CONFIG_USBDEV_EP0_PRIO 4
#endif
#ifndef CONFIG_USBDEV_EP0_STACKSIZE
#define CONFIG_USBDEV_EP0_STACKSIZE 2048
#endif
#ifndef CONFIG_USBDEV_MSC_MAX_LUN #ifndef CONFIG_USBDEV_MSC_MAX_LUN
#define CONFIG_USBDEV_MSC_MAX_LUN 1 #define CONFIG_USBDEV_MSC_MAX_LUN 1
#endif #endif
@@ -70,6 +80,10 @@
#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01" #define CONFIG_USBDEV_MSC_VERSION_STRING "0.01"
#endif #endif
/* move msc read & write from isr to while(1), you should call usbd_msc_polling in while(1) */
// #define CONFIG_USBDEV_MSC_POLLING
/* move msc read & write from isr to thread */
// #define CONFIG_USBDEV_MSC_THREAD // #define CONFIG_USBDEV_MSC_THREAD
#ifndef CONFIG_USBDEV_MSC_PRIO #ifndef CONFIG_USBDEV_MSC_PRIO