mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-17 05:32:55 +08:00
usbd better support suspend/resume
This commit is contained in:
parent
e9851f5042
commit
491b5936d5
@ -262,18 +262,10 @@ void tud_task (void)
|
||||
|
||||
if ( !osal_queue_receive(_usbd_q, &event) ) return;
|
||||
|
||||
// Skip event if device is not connected except BUS_RESET & UNPLUGGED & FUNC_CALL
|
||||
if ( !(_usbd_dev.connected || event.event_id == DCD_EVENT_UNPLUGGED ||
|
||||
event.event_id == DCD_EVENT_BUS_RESET || event.event_id == USBD_EVENT_FUNC_CALL) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( event.event_id )
|
||||
{
|
||||
case DCD_EVENT_BUS_RESET:
|
||||
usbd_reset(event.rhport);
|
||||
_usbd_dev.connected = 1; // connected after bus reset
|
||||
break;
|
||||
|
||||
case DCD_EVENT_UNPLUGGED:
|
||||
@ -284,6 +276,10 @@ void tud_task (void)
|
||||
break;
|
||||
|
||||
case DCD_EVENT_SETUP_RECEIVED:
|
||||
// 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
|
||||
_usbd_dev.connected = 1;
|
||||
|
||||
// Process control request
|
||||
if ( !process_control_request(event.rhport, &event.setup_received) )
|
||||
{
|
||||
@ -294,6 +290,8 @@ void tud_task (void)
|
||||
break;
|
||||
|
||||
case DCD_EVENT_XFER_COMPLETE:
|
||||
// Only handle xfer callback in ready state
|
||||
// if (_usbd_dev.connected && !_usbd_dev.suspended)
|
||||
{
|
||||
// Invoke the class callback associated with the endpoint address
|
||||
uint8_t const ep_addr = event.xfer_complete.ep_addr;
|
||||
@ -641,16 +639,22 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr)
|
||||
break;
|
||||
|
||||
case DCD_EVENT_SUSPEND:
|
||||
// NOTE: When unplugging device, the D+/D- state are unstable and can accidentally meet the
|
||||
// SUSPEND condition ( Idle for 3ms ). Most likely when this happen both suspend and resume
|
||||
// are submitted by DCD before the actual UNPLUGGED
|
||||
// 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 don't distinguish suspend vs disconnect as well.
|
||||
// We will skip handling SUSPEND/RESUME event if not currently connected
|
||||
if ( _usbd_dev.connected )
|
||||
{
|
||||
_usbd_dev.suspended = 1;
|
||||
osal_queue_send(_usbd_q, event, in_isr);
|
||||
}
|
||||
break;
|
||||
|
||||
case DCD_EVENT_RESUME:
|
||||
if ( _usbd_dev.connected )
|
||||
{
|
||||
_usbd_dev.suspended = 0;
|
||||
osal_queue_send(_usbd_q, event, in_isr);
|
||||
}
|
||||
break;
|
||||
|
||||
case DCD_EVENT_SETUP_RECEIVED:
|
||||
|
@ -114,6 +114,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result
|
||||
|
||||
if ( _control_state.request.bmRequestType_bit.direction == TUSB_DIR_OUT )
|
||||
{
|
||||
TU_VERIFY(_control_state.buffer);
|
||||
memcpy(_control_state.buffer, _usbd_ctrl_buf, xferred_bytes);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user