summaryrefslogtreecommitdiff
path: root/src/device
diff options
context:
space:
mode:
authorhathach <[email protected]>2026-03-19 10:40:50 +0700
committerhathach <[email protected]>2026-03-19 10:40:50 +0700
commit0fd8fd45b51a62f118203ec729574119eb03d526 (patch)
treef8262dca7347548a620b9e2212cbe207d93ce18e /src/device
parent0dd509ad3639a49f7f6a885da02670c09c05a058 (diff)
parent8a9f44bdd267d05640d1028c07269d044291243b (diff)
Merge branch 'refs/heads/master' into rp2040-hcd-epx
Diffstat (limited to 'src/device')
-rw-r--r--src/device/usbd.c49
-rw-r--r--src/device/usbd.h22
-rw-r--r--src/device/usbd_control.c10
-rw-r--r--src/device/usbd_pvt.h2
4 files changed, 74 insertions, 9 deletions
diff --git a/src/device/usbd.c b/src/device/usbd.c
index 1e21c667a..42903576c 100644
--- a/src/device/usbd.c
+++ b/src/device/usbd.c
@@ -334,6 +334,19 @@ static const usbd_class_driver_t _usbd_driver[] = {
.sof = NULL
},
#endif
+
+ #if CFG_TUD_PRINTER
+ {
+ .name = DRIVER_NAME("PRINTER"),
+ .init = printerd_init,
+ .deinit = printerd_deinit,
+ .reset = printerd_reset,
+ .open = printerd_open,
+ .control_xfer_cb = printerd_control_xfer_cb,
+ .xfer_cb = printerd_xfer_cb,
+ .sof = NULL
+ },
+ #endif
};
enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(_usbd_driver) };
@@ -585,7 +598,7 @@ bool tud_deinit(uint8_t rhport) {
// Deinit device controller driver
dcd_int_disable(rhport);
dcd_disconnect(rhport);
- TU_VERIFY(dcd_deinit(rhport));
+ TU_ASSERT(dcd_deinit(rhport));
// Deinit class drivers
for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) {
@@ -666,8 +679,14 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) {
return;
}
- // Loop until there is no more events in the queue
- while (1) {
+ // Loop until there are no more events in the queue or CFG_TUD_TASK_EVENTS_PER_RUN is reached
+ for (unsigned epr = 0;; epr++) {
+#if CFG_TUD_TASK_EVENTS_PER_RUN > 0
+ if (epr >= CFG_TUD_TASK_EVENTS_PER_RUN) {
+ TU_LOG_USBD("USBD event limit (" TU_XSTRING(CFG_TUD_TASK_EVENTS_PER_RUN) ") reached\r\n");
+ break;
+ }
+#endif
dcd_event_t event;
if (!osal_queue_receive(_usbd_q, &event, timeout_ms)) {
return;
@@ -817,7 +836,9 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
#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(" %s", tu_str_std_request[p_request->bRequest]);
- if (TUSB_REQ_GET_DESCRIPTOR != p_request->bRequest) TU_LOG_USBD("\r\n");
+ if (TUSB_REQ_GET_DESCRIPTOR != p_request->bRequest) {
+ TU_LOG_USBD("\r\n");
+ }
}
#endif
@@ -953,7 +974,25 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
//------------- Class/Interface Specific Request -------------//
case TUSB_REQ_RCPT_INTERFACE: {
- uint8_t const itf = tu_u16_low(p_request->wIndex);
+ uint8_t itf;
+ #if CFG_TUD_PRINTER
+ // Printer GET_DEVICE_ID has a weird wIndex = interface (high) | alt (low)
+ // attempt to interpret this as a printer request if matched
+ if (TUSB_REQ_TYPE_CLASS == p_request->bmRequestType_bit.type &&
+ TUSB_DIR_IN == p_request->bmRequestType_bit.direction &&
+ TUSB_PRINTER_REQUEST_GET_DEVICE_ID == p_request->bRequest) {
+ itf = tu_u16_high(p_request->wIndex);
+ if (itf < TU_ARRAY_SIZE(_usbd_dev.itf2drv)) {
+ const usbd_class_driver_t * driver = get_driver(_usbd_dev.itf2drv[itf]);
+ if (driver != NULL && driver->control_xfer_cb == printerd_control_xfer_cb) {
+ if (invoke_class_control(rhport, driver, p_request)) {
+ return true;
+ }
+ }
+ }
+ }
+ #endif
+ itf = tu_u16_low(p_request->wIndex);
TU_VERIFY(itf < TU_ARRAY_SIZE(_usbd_dev.itf2drv));
usbd_class_driver_t const * driver = get_driver(_usbd_dev.itf2drv[itf]);
diff --git a/src/device/usbd.h b/src/device/usbd.h
index bd5a3c395..d3a6dccbb 100644
--- a/src/device/usbd.h
+++ b/src/device/usbd.h
@@ -41,8 +41,13 @@ enum {
typedef struct {
uint16_t bm_double_buffered; // bitmap of IN endpoints to be double buffered, only effective for bulk endpoints
+ bool vbus_sensing; // Vbus pin is used for device connection detection, mandatory for tud_umount_cb()
} tud_configure_dwc2_t;
+ #ifndef CFG_TUD_CONFIGURE_DWC2_DEFAULT
+ #define CFG_TUD_CONFIGURE_DWC2_DEFAULT {.bm_double_buffered = 0, .vbus_sensing = CFG_TUD_VBUS_DETECT_HW}
+ #endif
+
typedef union {
tud_configure_dwc2_t dwc2;
} tud_configure_param_t;
@@ -292,6 +297,19 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
/* Endpoint In */\
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0
+//--------------------------------------------------------------------+
+// Printer Descriptor Templates
+//--------------------------------------------------------------------+
+
+#define TUD_PRINTER_DESC_LEN (9 + 7 + 7) // one interface, two endpoints
+
+#define TUD_PRINTER_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \
+ /* Interface */\
+ 9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_PRINTER, 1, 2, _stridx,\
+ /* Endpoint Out */\
+ 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
+ /* Endpoint In */\
+ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0
//--------------------------------------------------------------------+
// MTP Descriptor Templates
@@ -819,7 +837,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
/* Interface */ \
9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, TUD_DFU_APP_CLASS, TUD_DFU_APP_SUBCLASS, DFU_PROTOCOL_RT, _stridx, \
/* Function */ \
- 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101)
+ 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0110)
//--------------------------------------------------------------------+
// DFU Descriptor Templates
@@ -833,7 +851,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
#define TUD_DFU_DESCRIPTOR(_itfnum, _alt_count, _stridx, _attr, _timeout, _xfer_size) \
TU_XSTRCAT(TUD_DFU_ALT_,_alt_count)(_itfnum, 0, _stridx), \
/* Function */ \
- 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101)
+ 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0110)
#define TUD_DFU_ALT(_itfnum, _alt, _stridx) \
/* Interface */ \
diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c
index 47d58a1f9..87593d4a7 100644
--- a/src/device/usbd_control.c
+++ b/src/device/usbd_control.c
@@ -63,6 +63,10 @@ CFG_TUD_MEM_SECTION static struct {
TUD_EPBUF_DEF(buf, CFG_TUD_ENDPOINT0_BUFSIZE);
} _ctrl_epbuf;
+uint8_t* usbd_get_ctrl_buf(void) {
+ return _ctrl_epbuf.buf;
+}
+
//--------------------------------------------------------------------+
// Application API
//--------------------------------------------------------------------+
@@ -93,7 +97,7 @@ static bool data_stage_xact(uint8_t rhport) {
if (_ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_IN) {
ep_addr = EDPT_CTRL_IN;
- if (0u != xact_len) {
+ if (0u != xact_len && _ctrl_xfer.buffer != _ctrl_epbuf.buf) {
TU_VERIFY(0 == tu_memcpy_s(_ctrl_epbuf.buf, CFG_TUD_ENDPOINT0_BUFSIZE, _ctrl_xfer.buffer, xact_len));
}
}
@@ -169,7 +173,9 @@ bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result,
if (_ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_OUT) {
TU_VERIFY(_ctrl_xfer.buffer);
- memcpy(_ctrl_xfer.buffer, _ctrl_epbuf.buf, xferred_bytes);
+ if (_ctrl_xfer.buffer != _ctrl_epbuf.buf) {
+ memcpy(_ctrl_xfer.buffer, _ctrl_epbuf.buf, xferred_bytes);
+ }
TU_LOG_MEM(CFG_TUD_LOG_LEVEL, _ctrl_xfer.buffer, xferred_bytes, 2);
}
diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h
index 72323ac80..5f11ea481 100644
--- a/src/device/usbd_pvt.h
+++ b/src/device/usbd_pvt.h
@@ -72,6 +72,8 @@ void usbd_int_set(bool enabled);
void usbd_spin_lock(bool in_isr);
void usbd_spin_unlock(bool in_isr);
+uint8_t* usbd_get_ctrl_buf(void);
+
//--------------------------------------------------------------------+
// USBD Endpoint API
// Note: rhport should be 0 since device stack only support 1 rhport for now