summaryrefslogtreecommitdiff
path: root/src/device
diff options
context:
space:
mode:
authorhathach <[email protected]>2023-11-29 17:21:21 +0700
committerhathach <[email protected]>2023-11-29 17:21:21 +0700
commit1c1c2dc3b95b36136373f74380b90646d4847718 (patch)
tree2f5b26393cfbe648cb6eb15ea0a03b5003091496 /src/device
parent00484d18a5b89eb3a0e7cc138f34142f3464016d (diff)
parent9c9ebb342d2d3cb0396ff4ad8c7b09acd2aee75e (diff)
Merge branch 'master' into codeql
Diffstat (limited to 'src/device')
-rw-r--r--src/device/dcd.h30
-rw-r--r--src/device/usbd.c229
-rw-r--r--src/device/usbd.h19
-rw-r--r--src/device/usbd_control.c11
-rw-r--r--src/device/usbd_pvt.h26
5 files changed, 147 insertions, 168 deletions
diff --git a/src/device/dcd.h b/src/device/dcd.h
index 18a708347..8c6813cf7 100644
--- a/src/device/dcd.h
+++ b/src/device/dcd.h
@@ -47,8 +47,7 @@
// MACRO CONSTANT TYPEDEF PROTYPES
//--------------------------------------------------------------------+
-typedef enum
-{
+typedef enum {
DCD_EVENT_INVALID = 0,
DCD_EVENT_BUS_RESET,
DCD_EVENT_UNPLUGGED,
@@ -65,13 +64,11 @@ typedef enum
DCD_EVENT_COUNT
} dcd_eventid_t;
-typedef struct TU_ATTR_ALIGNED(4)
-{
+typedef struct TU_ATTR_ALIGNED(4) {
uint8_t rhport;
uint8_t event_id;
- union
- {
+ union {
// BUS RESET
struct {
tusb_speed_t speed;
@@ -123,7 +120,7 @@ void dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_W
//--------------------------------------------------------------------+
// Initialize controller to device mode
-void dcd_init (uint8_t rhport);
+void dcd_init(uint8_t rhport);
// Interrupt Handler
void dcd_int_handler(uint8_t rhport);
@@ -184,11 +181,11 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr);
void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr);
// Allocate packet buffer used by ISO endpoints
-// Some MCU need manual packet buffer allocation, we allocation largest size to avoid clustering
+// Some MCU need manual packet buffer allocation, we allocate the largest size to avoid clustering
TU_ATTR_WEAK bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size);
// Configure and enable an ISO endpoint according to descriptor
-TU_ATTR_WEAK bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc);
+TU_ATTR_WEAK bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc);
//--------------------------------------------------------------------+
// Event API (implemented by stack)
@@ -198,23 +195,20 @@ TU_ATTR_WEAK bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t co
extern void dcd_event_handler(dcd_event_t const * event, bool in_isr);
// helper to send bus signal event
-TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr)
-{
+TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr) {
dcd_event_t event = { .rhport = rhport, .event_id = eid };
dcd_event_handler(&event, in_isr);
}
// helper to send bus reset event
-TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr)
-{
+TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr) {
dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_BUS_RESET };
event.bus_reset.speed = speed;
dcd_event_handler(&event, in_isr);
}
// helper to send setup received
-TU_ATTR_ALWAYS_INLINE static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr)
-{
+TU_ATTR_ALWAYS_INLINE static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr) {
dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED };
memcpy(&event.setup_received, setup, sizeof(tusb_control_request_t));
@@ -222,8 +216,7 @@ TU_ATTR_ALWAYS_INLINE static inline void dcd_event_setup_received(uint8_t rhport
}
// helper to send transfer complete event
-TU_ATTR_ALWAYS_INLINE static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr)
-{
+TU_ATTR_ALWAYS_INLINE static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr) {
dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE };
event.xfer_complete.ep_addr = ep_addr;
@@ -233,8 +226,7 @@ TU_ATTR_ALWAYS_INLINE static inline void dcd_event_xfer_complete (uint8_t rhport
dcd_event_handler(&event, in_isr);
}
-static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_isr)
-{
+TU_ATTR_ALWAYS_INLINE static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_isr) {
dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SOF };
event.sof.frame_count = frame_count;
dcd_event_handler(&event, in_isr);
diff --git a/src/device/usbd.c b/src/device/usbd.c
index 44c2530ce..59466b42e 100644
--- a/src/device/usbd.c
+++ b/src/device/usbd.c
@@ -43,9 +43,6 @@
#define CFG_TUD_TASK_QUEUE_SZ 16
#endif
-// Debug level of USBD
-#define USBD_DBG 2
-
//--------------------------------------------------------------------+
// Device Data
//--------------------------------------------------------------------+
@@ -81,7 +78,7 @@ tu_static usbd_device_t _usbd_dev;
//--------------------------------------------------------------------+
// Class Driver
//--------------------------------------------------------------------+
-#if CFG_TUSB_DEBUG >= 2
+#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
#define DRIVER_NAME(_name) .name = _name,
#else
#define DRIVER_NAME(_name)
@@ -241,35 +238,21 @@ enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(_usbd_driver) };
tu_static usbd_class_driver_t const * _app_driver = NULL;
tu_static uint8_t _app_driver_count = 0;
+#define TOTAL_DRIVER_COUNT (_app_driver_count + BUILTIN_DRIVER_COUNT)
+
// virtually joins built-in and application drivers together.
// Application is positioned first to allow overwriting built-in ones.
-static inline usbd_class_driver_t const * get_driver(uint8_t drvid)
-{
- // Application drivers
- if ( usbd_app_driver_get_cb )
- {
- if ( drvid < _app_driver_count ) return &_app_driver[drvid];
- drvid -= _app_driver_count;
+TU_ATTR_ALWAYS_INLINE static inline usbd_class_driver_t const * get_driver(uint8_t drvid) {
+ usbd_class_driver_t const * driver = NULL;
+ if ( drvid < _app_driver_count ) {
+ // Application drivers
+ driver = &_app_driver[drvid];
+ } else if ( drvid < TOTAL_DRIVER_COUNT && BUILTIN_DRIVER_COUNT > 0 ){
+ driver = &_usbd_driver[drvid - _app_driver_count];
}
-
- // when there is no built-in drivers BUILTIN_DRIVER_COUNT = 0 will cause -Wtype-limits warning
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wtype-limits"
-#endif
-
- // Built-in drivers
- if (drvid < BUILTIN_DRIVER_COUNT) return &_usbd_driver[drvid];
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
-
- return NULL;
+ return driver;
}
-#define TOTAL_DRIVER_COUNT (_app_driver_count + BUILTIN_DRIVER_COUNT)
-
//--------------------------------------------------------------------+
// DCD Event
//--------------------------------------------------------------------+
@@ -290,6 +273,11 @@ tu_static osal_queue_t _usbd_q;
#define _usbd_mutex NULL
#endif
+TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event, bool in_isr) {
+ bool ret = osal_queue_send(_usbd_q, event, in_isr);
+ if (tud_event_hook_cb) tud_event_hook_cb(event->rhport, event->event_id, in_isr);
+ return ret;
+}
//--------------------------------------------------------------------+
// Prototypes
@@ -308,7 +296,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event,
//--------------------------------------------------------------------+
// Debug
//--------------------------------------------------------------------+
-#if CFG_TUSB_DEBUG >= 2
+#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
tu_static char const* const _usbd_event_str[DCD_EVENT_COUNT] =
{
"Invalid" ,
@@ -330,7 +318,7 @@ void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback)
usbd_class_driver_t const * driver = get_driver(i);
if ( driver && driver->control_xfer_cb == callback )
{
- TU_LOG(USBD_DBG, " %s control complete\r\n", driver->name);
+ TU_LOG_USBD(" %s control complete\r\n", driver->name);
return;
}
}
@@ -386,8 +374,7 @@ bool tud_connect(void)
//--------------------------------------------------------------------+
// USBD Task
//--------------------------------------------------------------------+
-bool tud_inited(void)
-{
+bool tud_inited(void) {
return _usbd_rhport != RHPORT_INVALID;
}
@@ -396,10 +383,10 @@ bool tud_init (uint8_t rhport)
// skip if already initialized
if ( tud_inited() ) return true;
- TU_LOG(USBD_DBG, "USBD init on controller %u\r\n", rhport);
- TU_LOG_INT(USBD_DBG, sizeof(usbd_device_t));
- TU_LOG_INT(USBD_DBG, sizeof(tu_fifo_t));
- TU_LOG_INT(USBD_DBG, sizeof(tu_edpt_stream_t));
+ TU_LOG_USBD("USBD init on controller %u\r\n", rhport);
+ TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(usbd_device_t));
+ TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_fifo_t));
+ TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_edpt_stream_t));
tu_varclr(&_usbd_dev);
@@ -424,7 +411,7 @@ bool tud_init (uint8_t rhport)
{
usbd_class_driver_t const * driver = get_driver(i);
TU_ASSERT(driver);
- TU_LOG(USBD_DBG, "%s init\r\n", driver->name);
+ TU_LOG_USBD("%s init\r\n", driver->name);
driver->init();
}
@@ -496,21 +483,21 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
dcd_event_t event;
if ( !osal_queue_receive(_usbd_q, &event, timeout_ms) ) return;
-#if CFG_TUSB_DEBUG >= 2
- if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG(USBD_DBG, "\r\n"); // extra line for setup
- TU_LOG(USBD_DBG, "USBD %s ", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED");
+#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
+ if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG_USBD("\r\n"); // extra line for setup
+ TU_LOG_USBD("USBD %s ", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED");
#endif
switch ( event.event_id )
{
case DCD_EVENT_BUS_RESET:
- TU_LOG(USBD_DBG, ": %s Speed\r\n", tu_str_speed[event.bus_reset.speed]);
+ TU_LOG_USBD(": %s Speed\r\n", tu_str_speed[event.bus_reset.speed]);
usbd_reset(event.rhport);
_usbd_dev.speed = event.bus_reset.speed;
break;
case DCD_EVENT_UNPLUGGED:
- TU_LOG(USBD_DBG, "\r\n");
+ TU_LOG_USBD("\r\n");
usbd_reset(event.rhport);
// invoke callback
@@ -518,8 +505,8 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
break;
case DCD_EVENT_SETUP_RECEIVED:
- TU_LOG_PTR(USBD_DBG, &event.setup_received);
- TU_LOG(USBD_DBG, "\r\n");
+ TU_LOG_BUF(CFG_TUD_LOG_LEVEL, &event.setup_received, 8);
+ TU_LOG_USBD("\r\n");
// Mark as connected after receiving 1st setup packet.
// But it is easier to set it every time instead of wasting time to check then set
@@ -534,7 +521,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
// Process control request
if ( !process_control_request(event.rhport, &event.setup_received) )
{
- TU_LOG(USBD_DBG, " Stall EP0\r\n");
+ TU_LOG_USBD(" Stall EP0\r\n");
// Failed -> stall both control endpoint IN and OUT
dcd_edpt_stall(event.rhport, 0);
dcd_edpt_stall(event.rhport, 0 | TUSB_DIR_IN_MASK);
@@ -548,7 +535,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const ep_dir = tu_edpt_dir(ep_addr);
- TU_LOG(USBD_DBG, "on EP %02X with %u bytes\r\n", ep_addr, (unsigned int) event.xfer_complete.len);
+ TU_LOG_USBD("on EP %02X with %u bytes\r\n", ep_addr, (unsigned int) event.xfer_complete.len);
_usbd_dev.ep_status[epnum][ep_dir].busy = 0;
_usbd_dev.ep_status[epnum][ep_dir].claimed = 0;
@@ -563,7 +550,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
usbd_class_driver_t const * driver = get_driver( _usbd_dev.ep2drv[epnum][ep_dir] );
TU_ASSERT(driver, );
- TU_LOG(USBD_DBG, " %s xfer callback\r\n", driver->name);
+ TU_LOG_USBD(" %s xfer callback\r\n", driver->name);
driver->xfer_cb(event.rhport, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len);
}
}
@@ -575,27 +562,27 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
// e.g suspend -> resume -> unplug/plug. Skip suspend/resume if not connected
if ( _usbd_dev.connected )
{
- TU_LOG(USBD_DBG, ": Remote Wakeup = %u\r\n", _usbd_dev.remote_wakeup_en);
+ TU_LOG_USBD(": Remote Wakeup = %u\r\n", _usbd_dev.remote_wakeup_en);
if (tud_suspend_cb) tud_suspend_cb(_usbd_dev.remote_wakeup_en);
}else
{
- TU_LOG(USBD_DBG, " Skipped\r\n");
+ TU_LOG_USBD(" Skipped\r\n");
}
break;
case DCD_EVENT_RESUME:
if ( _usbd_dev.connected )
{
- TU_LOG(USBD_DBG, "\r\n");
+ TU_LOG_USBD("\r\n");
if (tud_resume_cb) tud_resume_cb();
}else
{
- TU_LOG(USBD_DBG, " Skipped\r\n");
+ TU_LOG_USBD(" Skipped\r\n");
}
break;
case USBD_EVENT_FUNC_CALL:
- TU_LOG(USBD_DBG, "\r\n");
+ TU_LOG_USBD("\r\n");
if ( event.func_call.func ) event.func_call.func(event.func_call.param);
break;
@@ -620,7 +607,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
static bool invoke_class_control(uint8_t rhport, usbd_class_driver_t const * driver, tusb_control_request_t const * request)
{
usbd_control_set_complete_callback(driver->control_xfer_cb);
- TU_LOG(USBD_DBG, " %s control request\r\n", driver->name);
+ TU_LOG_USBD(" %s control request\r\n", driver->name);
return driver->control_xfer_cb(rhport, CONTROL_STAGE_SETUP, request);
}
@@ -641,11 +628,11 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
return tud_vendor_control_xfer_cb(rhport, CONTROL_STAGE_SETUP, p_request);
}
-#if CFG_TUSB_DEBUG >= 2
+#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
if (TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type && p_request->bRequest <= TUSB_REQ_SYNCH_FRAME)
{
- TU_LOG(USBD_DBG, " %s", tu_str_std_request[p_request->bRequest]);
- if (TUSB_REQ_GET_DESCRIPTOR != p_request->bRequest) TU_LOG(USBD_DBG, "\r\n");
+ TU_LOG_USBD(" %s", tu_str_std_request[p_request->bRequest]);
+ if (TUSB_REQ_GET_DESCRIPTOR != p_request->bRequest) TU_LOG_USBD("\r\n");
}
#endif
@@ -701,7 +688,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
if ( _usbd_dev.cfg_num )
{
// already configured: need to clear all endpoints and driver first
- TU_LOG(USBD_DBG, " Clear current Configuration (%u) before switching\r\n", _usbd_dev.cfg_num);
+ TU_LOG_USBD(" Clear current Configuration (%u) before switching\r\n", _usbd_dev.cfg_num);
// close all non-control endpoints, cancel all pending transfers if any
dcd_edpt_close_all(rhport);
@@ -713,8 +700,18 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
_usbd_dev.speed = speed; // restore speed
}
- // switch to new configuration if not zero
- if ( cfg_num ) TU_ASSERT( process_set_config(rhport, cfg_num) );
+ // Handle the new configuration and execute the corresponding callback
+ if ( cfg_num )
+ {
+ // switch to new configuration if not zero
+ TU_ASSERT( process_set_config(rhport, cfg_num) );
+
+ if ( tud_mount_cb ) tud_mount_cb();
+ }
+ else
+ {
+ if ( tud_umount_cb ) tud_umount_cb();
+ }
}
_usbd_dev.cfg_num = cfg_num;
@@ -730,7 +727,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
// Only support remote wakeup for device feature
TU_VERIFY(TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue);
- TU_LOG(USBD_DBG, " Enable Remote Wakeup\r\n");
+ TU_LOG_USBD(" Enable Remote Wakeup\r\n");
// Host may enable remote wake up before suspending especially HID device
_usbd_dev.remote_wakeup_en = true;
@@ -741,7 +738,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
// Only support remote wakeup for device feature
TU_VERIFY(TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue);
- TU_LOG(USBD_DBG, " Disable Remote Wakeup\r\n");
+ TU_LOG_USBD(" Disable Remote Wakeup\r\n");
// Host may disable remote wake up after resuming
_usbd_dev.remote_wakeup_en = false;
@@ -924,7 +921,7 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num)
if ( (sizeof(tusb_desc_interface_t) <= drv_len) && (drv_len <= remaining_len) )
{
// Open successfully
- TU_LOG(USBD_DBG, " %s opened\r\n", driver->name);
+ TU_LOG_USBD(" %s opened\r\n", driver->name);
// Some drivers use 2 or more interfaces but may not have IAD e.g MIDI (always) or
// BTH (even CDC) with class in device descriptor (single interface)
@@ -967,9 +964,6 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num)
TU_ASSERT(drv_id < TOTAL_DRIVER_COUNT);
}
- // invoke callback
- if (tud_mount_cb) tud_mount_cb();
-
return true;
}
@@ -983,7 +977,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
{
case TUSB_DESC_DEVICE:
{
- TU_LOG(USBD_DBG, " Device\r\n");
+ TU_LOG_USBD(" Device\r\n");
void* desc_device = (void*) (uintptr_t) tud_descriptor_device_cb();
@@ -1007,7 +1001,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
case TUSB_DESC_BOS:
{
- TU_LOG(USBD_DBG, " BOS\r\n");
+ TU_LOG_USBD(" BOS\r\n");
// requested by host if USB > 2.0 ( i.e 2.1 or 3.x )
if (!tud_descriptor_bos_cb) return false;
@@ -1029,12 +1023,12 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
if ( desc_type == TUSB_DESC_CONFIGURATION )
{
- TU_LOG(USBD_DBG, " Configuration[%u]\r\n", desc_index);
+ TU_LOG_USBD(" Configuration[%u]\r\n", desc_index);
desc_config = (uintptr_t) tud_descriptor_configuration_cb(desc_index);
}else
{
// Host only request this after getting Device Qualifier descriptor
- TU_LOG(USBD_DBG, " Other Speed Configuration\r\n");
+ TU_LOG_USBD(" Other Speed Configuration\r\n");
TU_VERIFY( tud_descriptor_other_speed_configuration_cb );
desc_config = (uintptr_t) tud_descriptor_other_speed_configuration_cb(desc_index);
}
@@ -1050,7 +1044,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
case TUSB_DESC_STRING:
{
- TU_LOG(USBD_DBG, " String[%u]\r\n", desc_index);
+ TU_LOG_USBD(" String[%u]\r\n", desc_index);
// String Descriptor always uses the desc set from user
uint8_t const* desc_str = (uint8_t const*) tud_descriptor_string_cb(desc_index, tu_le16toh(p_request->wIndex));
@@ -1063,7 +1057,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
case TUSB_DESC_DEVICE_QUALIFIER:
{
- TU_LOG(USBD_DBG, " Device Qualifier\r\n");
+ TU_LOG_USBD(" Device Qualifier\r\n");
TU_VERIFY( tud_descriptor_device_qualifier_cb );
@@ -1082,66 +1076,64 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
//--------------------------------------------------------------------+
// DCD Event Handler
//--------------------------------------------------------------------+
-TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr)
-{
- switch (event->event_id)
- {
+TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const* event, bool in_isr) {
+ bool send = false;
+ switch (event->event_id) {
case DCD_EVENT_UNPLUGGED:
- _usbd_dev.connected = 0;
- _usbd_dev.addressed = 0;
- _usbd_dev.cfg_num = 0;
- _usbd_dev.suspended = 0;
- osal_queue_send(_usbd_q, event, in_isr);
- break;
+ _usbd_dev.connected = 0;
+ _usbd_dev.addressed = 0;
+ _usbd_dev.cfg_num = 0;
+ _usbd_dev.suspended = 0;
+ send = true;
+ break;
case DCD_EVENT_SUSPEND:
// NOTE: When plugging/unplugging device, the D+/D- state are unstable and
// can accidentally meet the SUSPEND condition ( Bus Idle for 3ms ).
// In addition, some MCUs such as SAMD or boards that haven no VBUS detection cannot distinguish
// suspended vs disconnected. We will skip handling SUSPEND/RESUME event if not currently connected
- if ( _usbd_dev.connected )
- {
+ if (_usbd_dev.connected) {
_usbd_dev.suspended = 1;
- osal_queue_send(_usbd_q, event, in_isr);
+ send = true;
}
- break;
+ break;
case DCD_EVENT_RESUME:
// skip event if not connected (especially required for SAMD)
- if ( _usbd_dev.connected )
- {
+ if (_usbd_dev.connected) {
_usbd_dev.suspended = 0;
- osal_queue_send(_usbd_q, event, in_isr);
+ send = true;
}
- break;
+ break;
case DCD_EVENT_SOF:
- // SOF driver handler in ISR context
- for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++)
- {
- usbd_class_driver_t const * driver = get_driver(i);
- if (driver && driver->sof)
- {
- driver->sof(event->rhport, event->sof.frame_count);
- }
- }
-
// Some MCUs after running dcd_remote_wakeup() does not have way to detect the end of remote wakeup
// which last 1-15 ms. DCD can use SOF as a clear indicator that bus is back to operational
- if ( _usbd_dev.suspended )
- {
+ if (_usbd_dev.suspended) {
_usbd_dev.suspended = 0;
- dcd_event_t const event_resume = { .rhport = event->rhport, .event_id = DCD_EVENT_RESUME };
- osal_queue_send(_usbd_q, &event_resume, in_isr);
+ dcd_event_t const event_resume = {.rhport = event->rhport, .event_id = DCD_EVENT_RESUME};
+ queue_event(&event_resume, in_isr);
+ }
+
+ // SOF driver handler in ISR context
+ for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) {
+ usbd_class_driver_t const* driver = get_driver(i);
+ if (driver && driver->sof) {
+ driver->sof(event->rhport, event->sof.frame_count);
+ }
}
// skip osal queue for SOF in usbd task
- break;
+ break;
default:
- osal_queue_send(_usbd_q, event, in_isr);
- break;
+ send = true;
+ break;
+ }
+
+ if (send) {
+ queue_event(event, in_isr);
}
}
@@ -1185,18 +1177,15 @@ bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count
}
// Helper to defer an isr function
-void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr)
-{
- dcd_event_t event =
- {
+void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr) {
+ dcd_event_t event = {
.rhport = 0,
.event_id = USBD_EVENT_FUNC_CALL,
};
-
event.func_call.func = func;
event.func_call.param = param;
- dcd_event_handler(&event, in_isr);
+ queue_event(&event, in_isr);
}
//--------------------------------------------------------------------+
@@ -1248,7 +1237,7 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
// TODO skip ready() check for now since enumeration also use this API
// TU_VERIFY(tud_ready());
- TU_LOG(USBD_DBG, " Queue EP %02X with %u bytes ...\r\n", ep_addr, total_bytes);
+ TU_LOG_USBD(" Queue EP %02X with %u bytes ...\r\n", ep_addr, total_bytes);
// Attempt to transfer on a busy endpoint, sound like an race condition !
TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0);
@@ -1265,7 +1254,7 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
// DCD error, mark endpoint as ready to allow next transfer
_usbd_dev.ep_status[epnum][dir].busy = 0;
_usbd_dev.ep_status[epnum][dir].claimed = 0;
- TU_LOG(USBD_DBG, "FAILED\r\n");
+ TU_LOG_USBD("FAILED\r\n");
TU_BREAKPOINT();
return false;
}
@@ -1282,7 +1271,7 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
- TU_LOG(USBD_DBG, " Queue ISO EP %02X with %u bytes ... ", ep_addr, total_bytes);
+ TU_LOG_USBD(" Queue ISO EP %02X with %u bytes ... ", ep_addr, total_bytes);
// Attempt to transfer on a busy endpoint, sound like an race condition !
TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0);
@@ -1293,14 +1282,14 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16
if (dcd_edpt_xfer_fifo(rhport, ep_addr, ff, total_bytes))
{
- TU_LOG(USBD_DBG, "OK\r\n");
+ TU_LOG_USBD("OK\r\n");
return true;
}else
{
// DCD error, mark endpoint as ready to allow next transfer
_usbd_dev.ep_status[epnum][dir].busy = 0;
_usbd_dev.ep_status[epnum][dir].claimed = 0;
- TU_LOG(USBD_DBG, "failed\r\n");
+ TU_LOG_USBD("failed\r\n");
TU_BREAKPOINT();
return false;
}
@@ -1326,7 +1315,7 @@ void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
// only stalled if currently cleared
if ( !_usbd_dev.ep_status[epnum][dir].stalled )
{
- TU_LOG(USBD_DBG, " Stall EP %02X\r\n", ep_addr);
+ TU_LOG_USBD(" Stall EP %02X\r\n", ep_addr);
dcd_edpt_stall(rhport, ep_addr);
_usbd_dev.ep_status[epnum][dir].stalled = 1;
_usbd_dev.ep_status[epnum][dir].busy = 1;
@@ -1343,7 +1332,7 @@ void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
// only clear if currently stalled
if ( _usbd_dev.ep_status[epnum][dir].stalled )
{
- TU_LOG(USBD_DBG, " Clear Stall EP %02X\r\n", ep_addr);
+ TU_LOG_USBD(" Clear Stall EP %02X\r\n", ep_addr);
dcd_edpt_clear_stall(rhport, ep_addr);
_usbd_dev.ep_status[epnum][dir].stalled = 0;
_usbd_dev.ep_status[epnum][dir].busy = 0;
@@ -1371,7 +1360,7 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr)
rhport = _usbd_rhport;
TU_ASSERT(dcd_edpt_close, /**/);
- TU_LOG(USBD_DBG, " CLOSING Endpoint: 0x%02X\r\n", ep_addr);
+ TU_LOG_USBD(" CLOSING Endpoint: 0x%02X\r\n", ep_addr);
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
diff --git a/src/device/usbd.h b/src/device/usbd.h
index b11c1a09d..5456148bf 100644
--- a/src/device/usbd.h
+++ b/src/device/usbd.h
@@ -50,8 +50,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr);
// Task function should be called in main/rtos loop
TU_ATTR_ALWAYS_INLINE static inline
-void tud_task (void)
-{
+void tud_task (void) {
tud_task_ext(UINT32_MAX, false);
}
@@ -80,8 +79,7 @@ bool tud_suspended(void);
// Check if device is ready to transfer
TU_ATTR_ALWAYS_INLINE static inline
-bool tud_ready(void)
-{
+bool tud_ready(void) {
return tud_mounted() && !tud_suspended();
}
@@ -148,6 +146,9 @@ TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en);
// Invoked when usb bus is resumed
TU_ATTR_WEAK void tud_resume_cb(void);
+// Invoked when there is a new usb event, which need to be processed by tud_task()/tud_task_ext()
+TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr);
+
// Invoked when received control request with VENDOR TYPE
TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
@@ -467,7 +468,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
/* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\
TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\
/* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\
- TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\
+ TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\
/* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\
TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000)
@@ -516,7 +517,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
/* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\
TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\
/* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\
- TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\
+ TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\
/* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\
TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000)
@@ -564,7 +565,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
/* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\
TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\
/* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\
- TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\
+ TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\
/* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\
TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\
/* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\
@@ -773,10 +774,6 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
#define TUD_BT_PROTOCOL_PRIMARY_CONTROLLER 0x01
#define TUD_BT_PROTOCOL_AMP_CONTROLLER 0x02
-#ifndef CFG_TUD_BTH_ISO_ALT_COUNT
-#define CFG_TUD_BTH_ISO_ALT_COUNT 0
-#endif
-
// Length of template descriptor: 38 bytes + number of ISO alternatives * 23
#define TUD_BTH_DESC_LEN (8 + 9 + 7 + 7 + 7 + (CFG_TUD_BTH_ISO_ALT_COUNT) * (9 + 7 + 7))
diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c
index 2afe967b5..76d062e40 100644
--- a/src/device/usbd_control.c
+++ b/src/device/usbd_control.c
@@ -32,10 +32,7 @@
#include "tusb.h"
#include "device/usbd_pvt.h"
-// Debug level of USBD Control
-#define USBD_CONTROL_DEBUG 2
-
-#if CFG_TUSB_DEBUG >= USBD_CONTROL_DEBUG
+#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
extern void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback);
#endif
@@ -58,7 +55,7 @@ typedef struct
tu_static usbd_control_xfer_t _ctrl_xfer;
-CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN
+CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN
tu_static uint8_t _usbd_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE];
//--------------------------------------------------------------------+
@@ -191,7 +188,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result
{
TU_VERIFY(_ctrl_xfer.buffer);
memcpy(_ctrl_xfer.buffer, _usbd_ctrl_buf, xferred_bytes);
- TU_LOG_MEM(USBD_CONTROL_DEBUG, _usbd_ctrl_buf, xferred_bytes, 2);
+ TU_LOG_MEM(CFG_TUD_LOG_LEVEL, _usbd_ctrl_buf, xferred_bytes, 2);
}
_ctrl_xfer.total_xferred += (uint16_t) xferred_bytes;
@@ -208,7 +205,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result
// callback can still stall control in status phase e.g out data does not make sense
if ( _ctrl_xfer.complete_cb )
{
- #if CFG_TUSB_DEBUG >= USBD_CONTROL_DEBUG
+ #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
usbd_driver_print_control_complete_name(_ctrl_xfer.complete_cb);
#endif
diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h
index 8393d3469..153be7cee 100644
--- a/src/device/usbd_pvt.h
+++ b/src/device/usbd_pvt.h
@@ -23,8 +23,8 @@
*
* This file is part of the TinyUSB stack.
*/
-#ifndef USBD_PVT_H_
-#define USBD_PVT_H_
+#ifndef _TUSB_USBD_PVT_H_
+#define _TUSB_USBD_PVT_H_
#include "osal/osal.h"
#include "common/tusb_fifo.h"
@@ -33,13 +33,19 @@
extern "C" {
#endif
+// Level where CFG_TUSB_DEBUG must be at least for USBD is logged
+#ifndef CFG_TUD_LOG_LEVEL
+#define CFG_TUD_LOG_LEVEL 2
+#endif
+
+#define TU_LOG_USBD(...) TU_LOG(CFG_TUD_LOG_LEVEL, __VA_ARGS__)
+
//--------------------------------------------------------------------+
// Class Driver API
//--------------------------------------------------------------------+
-typedef struct
-{
- #if CFG_TUSB_DEBUG >= 2
+typedef struct {
+ #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
char const* name;
#endif
@@ -52,7 +58,7 @@ typedef struct
} usbd_class_driver_t;
// Invoked when initializing device stack to get additional class drivers.
-// Can optionally implemented by application to extend/overwrite class driver support.
+// Can be implemented by application to extend/overwrite class driver support.
// Note: The drivers array must be accessible at all time when stack is active
usbd_class_driver_t const* usbd_app_driver_get_cb(uint8_t* driver_count) TU_ATTR_WEAK;
@@ -104,8 +110,7 @@ bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endp
// Check if endpoint is ready (not busy and not stalled)
TU_ATTR_ALWAYS_INLINE static inline
-bool usbd_edpt_ready(uint8_t rhport, uint8_t ep_addr)
-{
+bool usbd_edpt_ready(uint8_t rhport, uint8_t ep_addr) {
return !usbd_edpt_busy(rhport, ep_addr) && !usbd_edpt_stalled(rhport, ep_addr);
}
@@ -117,11 +122,10 @@ void usbd_sof_enable(uint8_t rhport, bool en);
*------------------------------------------------------------------*/
bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in);
-void usbd_defer_func( osal_task_func_t func, void* param, bool in_isr );
-
+void usbd_defer_func(osal_task_func_t func, void *param, bool in_isr);
#ifdef __cplusplus
}
#endif
-#endif /* USBD_PVT_H_ */
+#endif