summaryrefslogtreecommitdiff
path: root/src/device/usbd.c
diff options
context:
space:
mode:
authorhathach <[email protected]>2021-03-10 17:10:49 +0700
committerhathach <[email protected]>2021-03-10 17:10:49 +0700
commit794083b647d1e591fcdba441da56b6f7646ae573 (patch)
tree040c54a46afd2f347fc8a474b17d881de3280eb7 /src/device/usbd.c
parentde1f36f2b02b00d8012748be304186e1eb78c728 (diff)
parentf9817da397d9e24801bb1b7e2b8ed0ddcef36d62 (diff)
Merge branch 'master' into edpt_ISO_xfer
Diffstat (limited to 'src/device/usbd.c')
-rw-r--r--src/device/usbd.c41
1 files changed, 27 insertions, 14 deletions
diff --git a/src/device/usbd.c b/src/device/usbd.c
index 1879729e8..8b126a9f6 100644
--- a/src/device/usbd.c
+++ b/src/device/usbd.c
@@ -699,13 +699,21 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
// notable requests are: GET HID REPORT DESCRIPTOR, SET_INTERFACE, GET_INTERFACE
if ( !invoke_class_control(rhport, driver, p_request) )
{
- // For GET_INTERFACE, it is mandatory to respond even if the class
- // driver doesn't use alternate settings.
- TU_VERIFY( TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type &&
- TUSB_REQ_GET_INTERFACE == p_request->bRequest);
+ // For GET_INTERFACE and SET_INTERFACE, it is mandatory to respond even if the class
+ // driver doesn't use alternate settings or implement this
+ TU_VERIFY(TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type);
- uint8_t alternate = 0;
- tud_control_xfer(rhport, p_request, &alternate, 1);
+ if (TUSB_REQ_GET_INTERFACE == p_request->bRequest)
+ {
+ uint8_t alternate = 0;
+ tud_control_xfer(rhport, p_request, &alternate, 1);
+ }else if (TUSB_REQ_SET_INTERFACE == p_request->bRequest)
+ {
+ tud_control_status(rhport, p_request);
+ } else
+ {
+ return false;
+ }
}
}
break;
@@ -992,11 +1000,15 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr)
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);
+ // UNPLUGGED event can be bouncing, only processing if we are currently connected
+ if ( _usbd_dev.connected )
+ {
+ _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;
case DCD_EVENT_SOF:
@@ -1004,9 +1016,10 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr)
break;
case DCD_EVENT_SUSPEND:
- // NOTE: When plugging/unplugging device, the D+/D- state are unstable and can accidentally meet the
- // SUSPEND condition ( Idle for 3ms ). Some MCUs such as SAMD doesn't distinguish suspend vs disconnect as well.
- // We will skip handling SUSPEND/RESUME event if not currently connected
+ // 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 )
{
_usbd_dev.suspended = 1;