mirror of
https://github.com/hathach/tinyusb.git
synced 2025-04-01 19:20:35 +00:00
usbd add connected, suspended, remote_wakeup
- remove use of osal_queue_reset
This commit is contained in:
parent
28610198df
commit
93a853cd5b
@ -38,7 +38,7 @@
|
|||||||
/* Blink pattern
|
/* Blink pattern
|
||||||
* - 250 ms : device not mounted
|
* - 250 ms : device not mounted
|
||||||
* - 1000 ms : device mounted
|
* - 1000 ms : device mounted
|
||||||
* - 2000 ms : device is suspended
|
* - 2500 ms : device is suspended
|
||||||
*/
|
*/
|
||||||
static uint32_t blink_interval_ms = 250;
|
static uint32_t blink_interval_ms = 250;
|
||||||
|
|
||||||
@ -210,6 +210,18 @@ void tud_umount_cb(void)
|
|||||||
blink_interval_ms = 250;
|
blink_interval_ms = 250;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Invoked when device is suspended
|
||||||
|
void tud_suspend_cb(bool remote_wakeup_en)
|
||||||
|
{
|
||||||
|
(void) remote_wakeup_en;
|
||||||
|
blink_interval_ms = 2500;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tud_resume_cb(void)
|
||||||
|
{
|
||||||
|
blink_interval_ms = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// BLINKING TASK
|
// BLINKING TASK
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
@ -48,7 +48,7 @@ typedef enum
|
|||||||
DCD_EVENT_SETUP_RECEIVED,
|
DCD_EVENT_SETUP_RECEIVED,
|
||||||
DCD_EVENT_XFER_COMPLETE,
|
DCD_EVENT_XFER_COMPLETE,
|
||||||
|
|
||||||
USBD_EVT_FUNC_CALL
|
USBD_EVENT_FUNC_CALL
|
||||||
} dcd_eventid_t;
|
} dcd_eventid_t;
|
||||||
|
|
||||||
typedef struct ATTR_ALIGNED(4)
|
typedef struct ATTR_ALIGNED(4)
|
||||||
@ -67,7 +67,7 @@ typedef struct ATTR_ALIGNED(4)
|
|||||||
uint32_t len;
|
uint32_t len;
|
||||||
}xfer_complete;
|
}xfer_complete;
|
||||||
|
|
||||||
// USBD_EVT_FUNC_CALL
|
// USBD_EVENT_FUNC_CALL
|
||||||
struct {
|
struct {
|
||||||
void (*func) (void*);
|
void (*func) (void*);
|
||||||
void* param;
|
void* param;
|
||||||
|
@ -40,14 +40,20 @@
|
|||||||
// Device Data
|
// Device Data
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
typedef struct {
|
typedef struct {
|
||||||
volatile uint8_t config_num; // 0 is non-configured ~ disconnect
|
volatile uint8_t config_num;
|
||||||
bool remote_wakeup_en;
|
|
||||||
|
|
||||||
uint8_t itf2drv[16]; // map interface number to driver (0xff is invalid)
|
struct ATTR_PACKED
|
||||||
uint8_t ep2drv[8][2]; // map endpoint to driver ( 0xff is invalid )
|
{
|
||||||
|
volatile uint8_t connected : 1;
|
||||||
|
volatile uint8_t suspended : 1;
|
||||||
|
uint8_t remote_wakeup_en : 1;
|
||||||
|
};
|
||||||
|
|
||||||
// uint8_t ep_busy_mask[2]; // bit mask for busy endpoint
|
// uint8_t ep_busy_mask[2]; // bit mask for busy endpoint
|
||||||
uint8_t ep_stall_mask[2]; // bit mask for stalled endpoint
|
uint8_t ep_stall_mask[2]; // bit mask for stalled endpoint
|
||||||
|
|
||||||
|
uint8_t itf2drv[16]; // map interface number to driver (0xff is invalid)
|
||||||
|
uint8_t ep2drv[8][2]; // map endpoint to driver ( 0xff is invalid )
|
||||||
}usbd_device_t;
|
}usbd_device_t;
|
||||||
|
|
||||||
static usbd_device_t _usbd_dev = { 0 };
|
static usbd_device_t _usbd_dev = { 0 };
|
||||||
@ -246,8 +252,27 @@ void tud_task (void)
|
|||||||
|
|
||||||
if ( !osal_queue_receive(_usbd_q, &event) ) return;
|
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 )
|
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:
|
||||||
|
usbd_reset(event.rhport);
|
||||||
|
|
||||||
|
// invoke callback
|
||||||
|
if (tud_umount_cb) tud_umount_cb();
|
||||||
|
break;
|
||||||
|
|
||||||
case DCD_EVENT_SETUP_RECEIVED:
|
case DCD_EVENT_SETUP_RECEIVED:
|
||||||
// Process control request
|
// Process control request
|
||||||
if ( !process_control_request(event.rhport, &event.setup_received) )
|
if ( !process_control_request(event.rhport, &event.setup_received) )
|
||||||
@ -278,19 +303,15 @@ void tud_task (void)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DCD_EVENT_BUS_RESET:
|
// NOTE: When unplugging device, the D+/D- state are unstable and can accidentally meet the
|
||||||
usbd_reset(event.rhport);
|
// SUSPEND condition ( Idle for 3ms ). Most likely when this happen both suspend and resume
|
||||||
// TODO remove since if task is too slow, we could clear the event of the new attached
|
// are submitted by DCD before the actual UNPLUGGED
|
||||||
osal_queue_reset(_usbd_q);
|
case DCD_EVENT_SUSPEND:
|
||||||
|
if (tud_suspend_cb) tud_suspend_cb( _usbd_dev.remote_wakeup_en );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DCD_EVENT_UNPLUGGED:
|
case DCD_EVENT_RESUME:
|
||||||
usbd_reset(event.rhport);
|
if (tud_resume_cb) tud_resume_cb();
|
||||||
// TODO remove since if task is too slow, we could clear the event of the new attached
|
|
||||||
osal_queue_reset(_usbd_q);
|
|
||||||
|
|
||||||
// invoke callback
|
|
||||||
if (tud_umount_cb) tud_umount_cb();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DCD_EVENT_SOF:
|
case DCD_EVENT_SOF:
|
||||||
@ -303,7 +324,7 @@ void tud_task (void)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBD_EVT_FUNC_CALL:
|
case USBD_EVENT_FUNC_CALL:
|
||||||
if ( event.func_call.func ) event.func_call.func(event.func_call.param);
|
if ( event.func_call.func ) event.func_call.func(event.func_call.param);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -555,9 +576,8 @@ static void const* get_descriptor(tusb_control_request_t const * p_request, uint
|
|||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
// out of range
|
// out of range
|
||||||
/* The 0xEE index string is a Microsoft USB extension.
|
// The 0xEE index string is a Microsoft USB extension.
|
||||||
* It can be used to tell Windows what driver it should use for the device !!!
|
// It can be used to tell Windows what driver it should use for the device !!!
|
||||||
*/
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -587,7 +607,8 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DCD_EVENT_UNPLUGGED:
|
case DCD_EVENT_UNPLUGGED:
|
||||||
_usbd_dev.config_num = 0; // mark disconnected
|
_usbd_dev.connected = 0;
|
||||||
|
_usbd_dev.config_num = 0;
|
||||||
osal_queue_send(_usbd_q, event, in_isr);
|
osal_queue_send(_usbd_q, event, in_isr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -595,9 +616,23 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr)
|
|||||||
// nothing to do now
|
// nothing to do now
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// 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
|
||||||
case DCD_EVENT_SUSPEND:
|
case DCD_EVENT_SUSPEND:
|
||||||
|
if (_usbd_dev.connected ) // skip event if disconnected
|
||||||
|
{
|
||||||
|
_usbd_dev.suspended = 1;
|
||||||
|
osal_queue_send(_usbd_q, event, in_isr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case DCD_EVENT_RESUME:
|
case DCD_EVENT_RESUME:
|
||||||
osal_queue_send(_usbd_q, event, in_isr);
|
if (_usbd_dev.connected ) // skip event if disconnected
|
||||||
|
{
|
||||||
|
_usbd_dev.suspended = 0;
|
||||||
|
osal_queue_send(_usbd_q, event, in_isr);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DCD_EVENT_SETUP_RECEIVED:
|
case DCD_EVENT_SETUP_RECEIVED:
|
||||||
@ -606,14 +641,14 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr)
|
|||||||
|
|
||||||
case DCD_EVENT_XFER_COMPLETE:
|
case DCD_EVENT_XFER_COMPLETE:
|
||||||
// skip zero-length control status complete event, should dcd notifies us.
|
// skip zero-length control status complete event, should dcd notifies us.
|
||||||
if ( 0 == tu_edpt_number(event->xfer_complete.ep_addr) && event->xfer_complete.len == 0) break;
|
if ( (0 == tu_edpt_number(event->xfer_complete.ep_addr)) && (event->xfer_complete.len == 0) ) break;
|
||||||
|
|
||||||
osal_queue_send(_usbd_q, event, in_isr);
|
osal_queue_send(_usbd_q, event, in_isr);
|
||||||
TU_ASSERT(event->xfer_complete.result == XFER_RESULT_SUCCESS,);
|
TU_ASSERT(event->xfer_complete.result == XFER_RESULT_SUCCESS,);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Not an DCD event, just a convenient way to defer ISR function should we need
|
// Not an DCD event, just a convenient way to defer ISR function should we need to
|
||||||
case USBD_EVT_FUNC_CALL:
|
case USBD_EVENT_FUNC_CALL:
|
||||||
osal_queue_send(_usbd_q, event, in_isr);
|
osal_queue_send(_usbd_q, event, in_isr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -683,7 +718,7 @@ void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr)
|
|||||||
dcd_event_t event =
|
dcd_event_t event =
|
||||||
{
|
{
|
||||||
.rhport = 0,
|
.rhport = 0,
|
||||||
.event_id = USBD_EVT_FUNC_CALL,
|
.event_id = USBD_EVENT_FUNC_CALL,
|
||||||
};
|
};
|
||||||
|
|
||||||
event.func_call.func = func;
|
event.func_call.func = func;
|
||||||
|
@ -61,7 +61,6 @@ typedef void (*osal_task_func_t)( void * );
|
|||||||
* osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
|
* osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
|
||||||
* osal_queue_receive (osal_queue_t const queue_hdl, void *p_data, uint32_t msec, uint32_t *p_error)
|
* osal_queue_receive (osal_queue_t const queue_hdl, void *p_data, uint32_t msec, uint32_t *p_error)
|
||||||
* bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr)
|
* bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr)
|
||||||
* osal_queue_reset()
|
|
||||||
*
|
*
|
||||||
* Semaphore
|
* Semaphore
|
||||||
* osal_semaphore_def_t, osal_semaphore_t
|
* osal_semaphore_def_t, osal_semaphore_t
|
||||||
|
@ -125,11 +125,6 @@ static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * da
|
|||||||
return in_isr ? xQueueSendToBackFromISR(queue_hdl, data, NULL) : xQueueSendToBack(queue_hdl, data, OSAL_TIMEOUT_WAIT_FOREVER);
|
return in_isr ? xQueueSendToBackFromISR(queue_hdl, data, NULL) : xQueueSendToBack(queue_hdl, data, OSAL_TIMEOUT_WAIT_FOREVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void osal_queue_reset(osal_queue_t const queue_hdl)
|
|
||||||
{
|
|
||||||
xQueueReset(queue_hdl);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -161,11 +161,6 @@ static inline bool osal_queue_send(osal_queue_t const qhdl, void const * data, b
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void osal_queue_reset(osal_queue_t const queue_hdl)
|
|
||||||
{
|
|
||||||
// TODO implement later
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -190,13 +190,6 @@ static inline bool osal_queue_send(osal_queue_t const qhdl, void const * data, b
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void osal_queue_reset(osal_queue_t const qhdl)
|
|
||||||
{
|
|
||||||
// tusb_hal_int_disable_all();
|
|
||||||
tu_fifo_clear(&qhdl->ff);
|
|
||||||
// tusb_hal_int_enable_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -205,13 +205,14 @@ void dcd_set_config (uint8_t rhport, uint8_t config_num)
|
|||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
(void) config_num;
|
(void) config_num;
|
||||||
// Nothing to do
|
|
||||||
|
|
||||||
// Clear current pending
|
// Enable usbevent for suspend and resume detection
|
||||||
|
// Since the bus signal D+/D- are stable from now on.
|
||||||
|
|
||||||
|
// Clear current pending first
|
||||||
NRF_USBD->EVENTCAUSE |= NRF_USBD->EVENTCAUSE;
|
NRF_USBD->EVENTCAUSE |= NRF_USBD->EVENTCAUSE;
|
||||||
NRF_USBD->EVENTS_USBEVENT = 0;
|
NRF_USBD->EVENTS_USBEVENT = 0;
|
||||||
|
|
||||||
// Enable usb event for suspend and resume
|
|
||||||
NRF_USBD->INTENSET = USBD_INTEN_USBEVENT_Msk;
|
NRF_USBD->INTENSET = USBD_INTEN_USBEVENT_Msk;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,7 +378,8 @@ void USBD_IRQHandler(void)
|
|||||||
|
|
||||||
if ( int_status & USBD_INTEN_USBEVENT_Msk )
|
if ( int_status & USBD_INTEN_USBEVENT_Msk )
|
||||||
{
|
{
|
||||||
uint32_t const evt_cause = NRF_USBD->EVENTCAUSE;
|
uint32_t const evt_cause = NRF_USBD->EVENTCAUSE & (USBD_EVENTCAUSE_SUSPEND_Msk | USBD_EVENTCAUSE_RESUME_Msk);
|
||||||
|
NRF_USBD->EVENTCAUSE = evt_cause; // clear interrupt
|
||||||
|
|
||||||
if ( evt_cause & USBD_EVENTCAUSE_SUSPEND_Msk )
|
if ( evt_cause & USBD_EVENTCAUSE_SUSPEND_Msk )
|
||||||
{
|
{
|
||||||
@ -388,8 +390,6 @@ void USBD_IRQHandler(void)
|
|||||||
{
|
{
|
||||||
dcd_event_bus_signal(0, DCD_EVENT_RESUME , true);
|
dcd_event_bus_signal(0, DCD_EVENT_RESUME , true);
|
||||||
}
|
}
|
||||||
|
|
||||||
NRF_USBD->EVENTCAUSE = evt_cause; // clear interrupt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( int_status & EDPT_END_ALL_MASK )
|
if ( int_status & EDPT_END_ALL_MASK )
|
||||||
|
Loading…
x
Reference in New Issue
Block a user