diff options
| author | Scott Shawcroft <[email protected]> | 2018-11-08 13:45:30 -0800 |
|---|---|---|
| committer | Scott Shawcroft <[email protected]> | 2018-11-08 13:45:30 -0800 |
| commit | 30e3c64134789416e10ed867fa12c210b808e98f (patch) | |
| tree | 6cb85cea204a1398e49eeff7b0e96dd5104aad4b /src/device | |
| parent | 7a40ec2647f06c37c6b8f0b8af2c17ba747f0aeb (diff) | |
Polish up control split and treat it more like a normal endpoint.
Diffstat (limited to 'src/device')
| -rw-r--r-- | src/device/control.c | 14 | ||||
| -rw-r--r-- | src/device/control.h | 3 | ||||
| -rw-r--r-- | src/device/usbd.c | 16 |
3 files changed, 31 insertions, 2 deletions
diff --git a/src/device/control.c b/src/device/control.c index 4944a999e..5856f0628 100644 --- a/src/device/control.c +++ b/src/device/control.c @@ -59,8 +59,13 @@ void controld_init(void) { // Note dir is value of direction bit in setup packet (i.e DATA stage direction)
static inline bool dcd_control_status(uint8_t rhport, uint8_t dir)
{
+ uint8_t ep_addr = 0;
+ // Invert the direction.
+ if (dir == TUSB_DIR_OUT) {
+ ep_addr |= TUSB_DIR_IN_MASK;
+ }
// status direction is reversed to one in the setup packet
- return dcd_edpt_xfer(rhport, 1-dir, NULL, 0);
+ return dcd_edpt_xfer(rhport, ep_addr, NULL, 0);
}
static inline void dcd_control_stall(uint8_t rhport)
@@ -140,6 +145,12 @@ tusb_error_t controld_xfer_cb(uint8_t rhport, uint8_t edpt_addr, tusb_event_t ev if (p_request->wLength == control_state.total_transferred || xferred_bytes < 64) {
control_state.current_stage = CONTROL_STAGE_STATUS;
dcd_control_status(rhport, p_request->bmRequestType_bit.direction);
+
+ // Do the user callback after queueing the STATUS packet because the callback could be slow.
+ if ( TUSB_REQ_RCPT_INTERFACE == p_request->bmRequestType_bit.recipient )
+ {
+ tud_control_interface_control_complete_cb(rhport, tu_u16_low(p_request->wIndex), p_request);
+ }
} else {
if (TUSB_REQ_RCPT_INTERFACE == p_request->bmRequestType_bit.recipient) {
error = tud_control_interface_control_cb(rhport, tu_u16_low(p_request->wIndex), p_request, control_state.total_transferred);
@@ -161,7 +172,6 @@ tusb_error_t controld_process_setup_request(uint8_t rhport, tusb_control_request control_state.total_transferred = 0;
}
-
if ( TUSB_REQ_RCPT_INTERFACE == p_request->bmRequestType_bit.recipient )
{
error = tud_control_interface_control_cb(rhport, tu_u16_low(p_request->wIndex), p_request, 0);
diff --git a/src/device/control.h b/src/device/control.h index 24f0d0a14..881c99ead 100644 --- a/src/device/control.h +++ b/src/device/control.h @@ -68,6 +68,9 @@ tusb_error_t controld_process_setup_request(uint8_t rhport, tusb_control_request // Callback when the configuration of the device is changed.
tusb_error_t tud_control_set_config_cb(uint8_t rhport, uint8_t config_number);
+// Called when the DATA stage of a control transaction is complete.
+void tud_control_interface_control_complete_cb(uint8_t rhport, uint8_t interface, tusb_control_request_t const * const p_request);
+
tusb_error_t tud_control_interface_control_cb(uint8_t rhport, uint8_t interface, tusb_control_request_t const * const p_request, uint16_t bytes_already_sent);
//--------------------------------------------------------------------+
diff --git a/src/device/usbd.c b/src/device/usbd.c index 3c77fefba..c9d5e5642 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -96,6 +96,7 @@ typedef struct { tusb_error_t (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t* p_length);
// Control request is called one or more times for a request and can queue multiple data packets.
tusb_error_t (* control_request ) (uint8_t rhport, tusb_control_request_t const *, uint16_t bytes_already_sent);
+ void (* control_request_complete ) (uint8_t rhport, tusb_control_request_t const *);
tusb_error_t (* xfer_cb ) (uint8_t rhport, uint8_t ep_addr, tusb_event_t, uint32_t);
void (* sof ) (uint8_t rhport);
void (* reset ) (uint8_t);
@@ -108,6 +109,7 @@ static usbd_class_driver_t const usbd_class_drivers[] = .init = controld_init,
.open = NULL,
.control_request = NULL,
+ .control_request_complete = NULL,
.xfer_cb = controld_xfer_cb,
.sof = NULL,
.reset = controld_reset
@@ -118,6 +120,7 @@ static usbd_class_driver_t const usbd_class_drivers[] = .init = cdcd_init,
.open = cdcd_open,
.control_request = cdcd_control_request,
+ .control_request_complete = cdcd_control_request_complete,
.xfer_cb = cdcd_xfer_cb,
.sof = NULL,
.reset = cdcd_reset
@@ -130,6 +133,7 @@ static usbd_class_driver_t const usbd_class_drivers[] = .init = mscd_init,
.open = mscd_open,
.control_request = mscd_control_request,
+ .control_request_complete = mscd_control_request_complete,
.xfer_cb = mscd_xfer_cb,
.sof = NULL,
.reset = mscd_reset
@@ -143,6 +147,7 @@ static usbd_class_driver_t const usbd_class_drivers[] = .init = hidd_init,
.open = hidd_open,
.control_request = hidd_control_request,
+ .control_request_complete = hidd_control_request_complete,
.xfer_cb = hidd_xfer_cb,
.sof = NULL,
.reset = hidd_reset
@@ -155,6 +160,7 @@ static usbd_class_driver_t const usbd_class_drivers[] = .init = cusd_init,
.open = cusd_open,
.control_request = cusd_control_request,
+ .control_request_complete = cusd_control_request_complete,
.xfer_cb = cusd_xfer_cb,
.sof = NULL,
.reset = cusd_reset
@@ -309,6 +315,16 @@ static tusb_error_t usbd_main_st(void) return err;
}
+void tud_control_interface_control_complete_cb(uint8_t rhport, uint8_t interface, tusb_control_request_t const * const p_request) {
+ if (_usbd_dev.itf2drv[ interface ] < USBD_CLASS_DRIVER_COUNT)
+ {
+ const usbd_class_driver_t *driver = &usbd_class_drivers[_usbd_dev.itf2drv[interface]];
+ if (driver->control_request_complete != NULL) {
+ driver->control_request_complete(rhport, p_request);
+ }
+ }
+}
+
tusb_error_t tud_control_interface_control_cb(uint8_t rhport, uint8_t interface, tusb_control_request_t const * const p_request, uint16_t bytes_already_sent) {
if (_usbd_dev.itf2drv[ interface ] < USBD_CLASS_DRIVER_COUNT)
{
|
