summaryrefslogtreecommitdiff
path: root/src/device
diff options
context:
space:
mode:
authorHiFiPhile <[email protected]>2025-09-12 15:49:40 +0200
committerHiFiPhile <[email protected]>2025-09-12 15:49:40 +0200
commitfad3dc492630a6a31a38b3340f506849ef3679ff (patch)
tree5ab1fef9daf657c1b3f1b7e238e02eb78e1b14cf /src/device
parent4ae433fa6ef451cccb2b09aa3748978b46aade5f (diff)
parent2027ac246791caa9f1dc03e9727b60d90bee0f2d (diff)
Merge branch 'master' into sb-ep
Diffstat (limited to 'src/device')
-rw-r--r--src/device/usbd.c74
-rw-r--r--src/device/usbd.h2
-rw-r--r--src/device/usbd_pvt.h1
3 files changed, 66 insertions, 11 deletions
diff --git a/src/device/usbd.c b/src/device/usbd.c
index 6e5fcf3b6..b09d02fbd 100644
--- a/src/device/usbd.c
+++ b/src/device/usbd.c
@@ -163,6 +163,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = {
.open = cdcd_open,
.control_xfer_cb = cdcd_control_xfer_cb,
.xfer_cb = cdcd_xfer_cb,
+ .xfer_isr = NULL,
.sof = NULL
},
#endif
@@ -176,6 +177,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = {
.open = mscd_open,
.control_xfer_cb = mscd_control_xfer_cb,
.xfer_cb = mscd_xfer_cb,
+ .xfer_isr = NULL,
.sof = NULL
},
#endif
@@ -189,6 +191,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = {
.open = hidd_open,
.control_xfer_cb = hidd_control_xfer_cb,
.xfer_cb = hidd_xfer_cb,
+ .xfer_isr = NULL,
.sof = NULL
},
#endif
@@ -202,6 +205,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = {
.open = audiod_open,
.control_xfer_cb = audiod_control_xfer_cb,
.xfer_cb = audiod_xfer_cb,
+ .xfer_isr = audiod_xfer_isr,
.sof = audiod_sof_isr
},
#endif
@@ -215,6 +219,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = {
.open = videod_open,
.control_xfer_cb = videod_control_xfer_cb,
.xfer_cb = videod_xfer_cb,
+ .xfer_isr = NULL,
.sof = NULL
},
#endif
@@ -228,6 +233,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = {
.reset = midid_reset,
.control_xfer_cb = midid_control_xfer_cb,
.xfer_cb = midid_xfer_cb,
+ .xfer_isr = NULL,
.sof = NULL
},
#endif
@@ -241,6 +247,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = {
.open = vendord_open,
.control_xfer_cb = tud_vendor_control_xfer_cb,
.xfer_cb = vendord_xfer_cb,
+ .xfer_isr = NULL,
.sof = NULL
},
#endif
@@ -254,6 +261,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = {
.open = usbtmcd_open_cb,
.control_xfer_cb = usbtmcd_control_xfer_cb,
.xfer_cb = usbtmcd_xfer_cb,
+ .xfer_isr = NULL,
.sof = NULL
},
#endif
@@ -267,6 +275,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = {
.open = dfu_rtd_open,
.control_xfer_cb = dfu_rtd_control_xfer_cb,
.xfer_cb = NULL,
+ .xfer_isr = NULL,
.sof = NULL
},
#endif
@@ -280,6 +289,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = {
.open = dfu_moded_open,
.control_xfer_cb = dfu_moded_control_xfer_cb,
.xfer_cb = NULL,
+ .xfer_isr = NULL,
.sof = NULL
},
#endif
@@ -293,7 +303,8 @@ tu_static usbd_class_driver_t const _usbd_driver[] = {
.open = netd_open,
.control_xfer_cb = netd_control_xfer_cb,
.xfer_cb = netd_xfer_cb,
- .sof = NULL,
+ .xfer_isr = NULL,
+ .sof = NULL,
},
#endif
@@ -306,6 +317,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = {
.open = btd_open,
.control_xfer_cb = btd_control_xfer_cb,
.xfer_cb = btd_xfer_cb,
+ .xfer_isr = NULL,
.sof = NULL
},
#endif
@@ -317,26 +329,24 @@ 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)
+#define TOTAL_DRIVER_COUNT ((uint8_t) (_app_driver_count + BUILTIN_DRIVER_COUNT))
// virtually joins built-in and application drivers together.
// Application is positioned first to allow overwriting built-in ones.
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 ) {
+ 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 ){
+ } else if (drvid < TOTAL_DRIVER_COUNT && BUILTIN_DRIVER_COUNT > 0) {
driver = &_usbd_driver[drvid - _app_driver_count];
}
return driver;
}
-
//--------------------------------------------------------------------+
// DCD Event
//--------------------------------------------------------------------+
-
enum { RHPORT_INVALID = 0xFFu };
tu_static uint8_t _usbd_rhport = RHPORT_INVALID;
@@ -465,13 +475,30 @@ bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
return true; // skip if already initialized
}
TU_ASSERT(rh_init);
-
- TU_LOG_USBD("USBD init on controller %u, speed = %s\r\n", rhport,
- rh_init->speed == TUSB_SPEED_HIGH ? "High" : "Full");
+#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
+ char const* speed_str = 0;
+ switch (rh_init->speed) {
+ case TUSB_SPEED_HIGH:
+ speed_str = "High";
+ break;
+ case TUSB_SPEED_FULL:
+ speed_str = "Full";
+ break;
+ case TUSB_SPEED_LOW:
+ speed_str = "Low";
+ break;
+ case TUSB_SPEED_AUTO:
+ speed_str = "Auto";
+ break;
+ default:
+ break;
+ }
+ TU_LOG_USBD("USBD init on controller %u, speed = %s\r\n", rhport, speed_str);
TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(usbd_device_t));
TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(dcd_event_t));
TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_fifo_t));
TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_edpt_stream_t));
+#endif
tu_varclr(&_usbd_dev);
_usbd_queued_setup = 0;
@@ -491,6 +518,7 @@ bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
// Get application driver if available
if (usbd_app_driver_get_cb) {
_app_driver = usbd_app_driver_get_cb(&_app_driver_count);
+ TU_ASSERT(_app_driver_count + BUILTIN_DRIVER_COUNT <= UINT8_MAX);
}
// Init class drivers
@@ -1231,6 +1259,32 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const* event, bool in_isr)
send = true;
break;
+ case DCD_EVENT_XFER_COMPLETE: {
+ // Invoke the class callback associated with the endpoint address
+ uint8_t const ep_addr = event->xfer_complete.ep_addr;
+ uint8_t const epnum = tu_edpt_number(ep_addr);
+ uint8_t const ep_dir = tu_edpt_dir(ep_addr);
+
+ send = true;
+ if(epnum > 0) {
+ usbd_class_driver_t const* driver = get_driver(_usbd_dev.ep2drv[epnum][ep_dir]);
+
+ if (driver && driver->xfer_isr) {
+ _usbd_dev.ep_status[epnum][ep_dir].busy = 0;
+ _usbd_dev.ep_status[epnum][ep_dir].claimed = 0;
+
+ send = !driver->xfer_isr(event->rhport, ep_addr, (xfer_result_t) event->xfer_complete.result, event->xfer_complete.len);
+
+ // xfer_isr() is deferred to xfer_cb(), revert busy/claimed status
+ if (send) {
+ _usbd_dev.ep_status[epnum][ep_dir].busy = 1;
+ _usbd_dev.ep_status[epnum][ep_dir].claimed = 1;
+ }
+ }
+ }
+ break;
+ }
+
default:
send = true;
break;
diff --git a/src/device/usbd.h b/src/device/usbd.h
index de6007fb3..e5a848809 100644
--- a/src/device/usbd.h
+++ b/src/device/usbd.h
@@ -244,7 +244,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
/* CDC Union */\
5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (uint8_t)((_itfnum) + 1),\
/* Endpoint Notification */\
- 7, TUSB_DESC_ENDPOINT, _ep_notif, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_notif_size), 16,\
+ 7, TUSB_DESC_ENDPOINT, _ep_notif, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_notif_size), 1,\
/* CDC Data Interface */\
9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 0, 2, TUSB_CLASS_CDC_DATA, 0, 0, 0,\
/* Endpoint Out */\
diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h
index 5c6f9dbee..f1797bf0d 100644
--- a/src/device/usbd_pvt.h
+++ b/src/device/usbd_pvt.h
@@ -57,6 +57,7 @@ typedef struct {
uint16_t (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t max_len);
bool (* control_xfer_cb ) (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
bool (* xfer_cb ) (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
+ bool (* xfer_isr ) (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); // optional, return false to defer to xfer_cb()
void (* sof ) (uint8_t rhport, uint32_t frame_count); // optional
} usbd_class_driver_t;