Merge remote-tracking branch 'origin/master' into ZLP_Request2

This commit is contained in:
Nathan Conrad
2019-10-31 12:23:54 -04:00
88 changed files with 3421 additions and 1309 deletions

View File

@@ -39,17 +39,20 @@
typedef enum
{
DCD_EVENT_BUS_RESET = 1,
DCD_EVENT_INVALID = 0,
DCD_EVENT_BUS_RESET,
DCD_EVENT_UNPLUGGED,
DCD_EVENT_SOF,
DCD_EVENT_SUSPEND,
DCD_EVENT_SUSPEND, // TODO LPM Sleep L1 support
DCD_EVENT_RESUME,
DCD_EVENT_SETUP_RECEIVED,
DCD_EVENT_XFER_COMPLETE,
// Not an DCD event, just a convenient way to defer ISR function
USBD_EVENT_FUNC_CALL
USBD_EVENT_FUNC_CALL,
DCD_EVENT_COUNT
} dcd_eventid_t;
typedef struct TU_ATTR_ALIGNED(4)
@@ -76,7 +79,7 @@ typedef struct TU_ATTR_ALIGNED(4)
};
} dcd_event_t;
TU_VERIFY_STATIC(sizeof(dcd_event_t) <= 12, "size is not correct");
//TU_VERIFY_STATIC(sizeof(dcd_event_t) <= 12, "size is not correct");
/*------------------------------------------------------------------*/
/* Device API
@@ -116,20 +119,51 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr);
// clear stall, data toggle is also reset to DATA0
void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr);
/*------------------------------------------------------------------*/
/* Event Function
* Called by DCD to notify device stack
*------------------------------------------------------------------*/
void dcd_event_handler(dcd_event_t const * event, bool in_isr);
//--------------------------------------------------------------------+
// Event API
//--------------------------------------------------------------------+
// Called by DCD to notify device stack
extern void dcd_event_handler(dcd_event_t const * event, bool in_isr);
// helper to send bus signal event
void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr);
static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr);
// helper to send setup received
void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr);
static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr);
// helper to send transfer complete event
void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr);
static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr);
//--------------------------------------------------------------------+
// Inline helper
//--------------------------------------------------------------------+
static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr)
{
dcd_event_t event = { .rhport = rhport, .event_id = eid, };
dcd_event_handler(&event, in_isr);
}
static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr)
{
dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED };
memcpy(&event.setup_received, setup, 8);
dcd_event_handler(&event, in_isr);
}
static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr)
{
dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE };
event.xfer_complete.ep_addr = ep_addr;
event.xfer_complete.len = xferred_bytes;
event.xfer_complete.result = result;
dcd_event_handler(&event, in_isr);
}
#ifdef __cplusplus
}

View File

@@ -167,6 +167,20 @@ static usbd_class_driver_t const usbd_class_drivers[] =
.sof = NULL
},
#endif
#if CFG_TUD_DFU_RT
{
.class_code = TUD_DFU_APP_CLASS,
//.subclass_code = TUD_DFU_APP_SUBCLASS
.init = dfu_rtd_init,
.reset = dfu_rtd_reset,
.open = dfu_rtd_open,
.control_request = dfu_rtd_control_request,
.control_complete = dfu_rtd_control_complete,
.xfer_cb = dfu_rtd_xfer_cb,
.sof = NULL
},
#endif
};
enum { USBD_CLASS_DRIVER_COUNT = TU_ARRAY_SIZE(usbd_class_drivers) };
@@ -192,6 +206,66 @@ void usbd_control_reset (uint8_t rhport);
bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
void usbd_control_set_complete_callback( bool (*fp) (uint8_t, tusb_control_request_t const * ) );
//--------------------------------------------------------------------+
// Debugging
//--------------------------------------------------------------------+
#if CFG_TUSB_DEBUG > 1
static char const* const _usbd_event_str[DCD_EVENT_COUNT] =
{
"INVALID" ,
"BUS_RESET" ,
"UNPLUGGED" ,
"SOF" ,
"SUSPEND" ,
"RESUME" ,
"SETUP_RECEIVED" ,
"XFER_COMPLETE" ,
"FUNC_CALL"
};
// must be same driver order as usbd_class_drivers[]
static char const* const _usbd_driver_str[USBD_CLASS_DRIVER_COUNT] =
{
#if CFG_TUD_CDC
"CDC",
#endif
#if CFG_TUD_MSC
"MSC",
#endif
#if CFG_TUD_HID
"HID",
#endif
#if CFG_TUD_MIDI
"MIDI",
#endif
#if CFG_TUD_VENDOR
"Vendor",
#endif
#if CFG_TUD_USBTMC
"USBTMC"
#endif
};
static char const* const _tusb_std_request_str[] =
{
"Get Status" ,
"Clear Feature" ,
"Reserved" ,
"Set Feature" ,
"Reserved" ,
"Set Address" ,
"Get Descriptor" ,
"Set Descriptor" ,
"Get Configuration" ,
"Set Configuration" ,
"Get Interface" ,
"Set Interface" ,
"Synch Frame"
};
#endif
//--------------------------------------------------------------------+
// Application API
//--------------------------------------------------------------------+
@@ -216,8 +290,10 @@ bool tud_remote_wakeup(void)
//--------------------------------------------------------------------+
// USBD Task
//--------------------------------------------------------------------+
bool usbd_init (void)
bool tud_init (void)
{
TU_LOG2("USBD init\r\n");
tu_varclr(&_usbd_dev);
// Init device queue & task
@@ -225,7 +301,11 @@ bool usbd_init (void)
TU_ASSERT(_usbd_q != NULL);
// Init class drivers
for (uint8_t i = 0; i < USBD_CLASS_DRIVER_COUNT; i++) usbd_class_drivers[i].init();
for (uint8_t i = 0; i < USBD_CLASS_DRIVER_COUNT; i++)
{
TU_LOG2("%s init\r\n", _usbd_driver_str[i]);
usbd_class_drivers[i].init();
}
// Init device controller driver
dcd_init(TUD_OPT_RHPORT);
@@ -279,6 +359,8 @@ void tud_task (void)
if ( !osal_queue_receive(_usbd_q, &event) ) return;
TU_LOG2("USBD: event %s\r\n", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED");
switch ( event.event_id )
{
case DCD_EVENT_BUS_RESET:
@@ -293,6 +375,9 @@ void tud_task (void)
break;
case DCD_EVENT_SETUP_RECEIVED:
TU_LOG2(" ");
TU_LOG2_MEM(&event.setup_received, 1, 8);
// 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;
@@ -307,29 +392,30 @@ 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;
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const ep_dir = tu_edpt_dir(ep_addr);
TU_LOG2(" Endpoint: 0x%02X, Bytes: %ld\r\n", ep_addr, event.xfer_complete.len);
_usbd_dev.ep_status[epnum][ep_dir].busy = false;
if ( 0 == epnum )
{
// Invoke the class callback associated with the endpoint address
uint8_t const ep_addr = event.xfer_complete.ep_addr;
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const ep_dir = tu_edpt_dir(ep_addr);
_usbd_dev.ep_status[epnum][ep_dir].busy = false;
if ( 0 == epnum )
{
// control transfer DATA stage callback
usbd_control_xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len);
}
else
{
uint8_t const drv_id = _usbd_dev.ep2drv[epnum][ep_dir];
TU_ASSERT(drv_id < USBD_CLASS_DRIVER_COUNT,);
usbd_class_drivers[drv_id].xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len);
}
// control transfer DATA stage callback
usbd_control_xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len);
}
else
{
uint8_t const drv_id = _usbd_dev.ep2drv[epnum][ep_dir];
TU_ASSERT(drv_id < USBD_CLASS_DRIVER_COUNT,);
TU_LOG2(" %s xfer callback\r\n", _usbd_driver_str[drv_id]);
usbd_class_drivers[drv_id].xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len);
}
}
break;
case DCD_EVENT_SUSPEND:
@@ -382,6 +468,13 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
return tud_vendor_control_request_cb(rhport, p_request);
}
#if CFG_TUSB_DEBUG > 1
if (TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type && p_request->bRequest <= TUSB_REQ_SYNCH_FRAME)
{
TU_LOG2(" %s\r\n", _tusb_std_request_str[p_request->bRequest]);
}
#endif
switch ( p_request->bmRequestType_bit.recipient )
{
//------------- Device Requests e.g in enumeration -------------//
@@ -494,6 +587,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
// GET HID REPORT DESCRIPTOR falls into this case
// stall control endpoint if driver return false
usbd_control_set_complete_callback(usbd_class_drivers[drvid].control_complete);
TU_LOG2(" %s control request\r\n", _usbd_driver_str[drvid]);
TU_ASSERT(usbd_class_drivers[drvid].control_request != NULL &&
usbd_class_drivers[drvid].control_request(rhport, p_request));
break;
@@ -503,6 +597,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
// forward to class driver: "non-STD request to Interface"
// stall control endpoint if driver return false
usbd_control_set_complete_callback(usbd_class_drivers[drvid].control_complete);
TU_LOG2(" %s control request\r\n", _usbd_driver_str[drvid]);
TU_ASSERT(usbd_class_drivers[drvid].control_request != NULL &&
usbd_class_drivers[drvid].control_request(rhport, p_request));
}
@@ -570,7 +665,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
// For std-type requests: non-std request codes are already discarded.
// must not call tud_control_status(), and return value will have no effect
// class driver is invoked last, so that EP already has EP stall cleared (in event of clear feature EP halt)
TU_LOG2(" %s control request\r\n", _usbd_driver_str[drv_id]);
if ( usbd_class_drivers[drv_id].control_request &&
usbd_class_drivers[drv_id].control_request(rhport, p_request))
{
@@ -627,6 +722,7 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num)
_usbd_dev.itf2drv[desc_itf->bInterfaceNumber] = drv_id;
uint16_t itf_len=0;
TU_LOG2(" %s open\r\n", _usbd_driver_str[drv_id]);
TU_ASSERT( usbd_class_drivers[drv_id].open(rhport, desc_itf, &itf_len) );
TU_ASSERT( itf_len >= sizeof(tusb_desc_interface_t) );
@@ -788,34 +884,6 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr)
}
}
// helper to send bus signal event
void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr)
{
dcd_event_t event = { .rhport = rhport, .event_id = eid, };
dcd_event_handler(&event, in_isr);
}
// helper to send setup received
void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr)
{
dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED };
memcpy(&event.setup_received, setup, 8);
dcd_event_handler(&event, in_isr);
}
// helper to send transfer complete event
void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr)
{
dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE };
event.xfer_complete.ep_addr = ep_addr;
event.xfer_complete.len = xferred_bytes;
event.xfer_complete.result = result;
dcd_event_handler(&event, in_isr);
}
//--------------------------------------------------------------------+
// Helper
//--------------------------------------------------------------------+

View File

@@ -41,6 +41,9 @@
// Application API
//--------------------------------------------------------------------+
// Init device stack
bool tud_init (void);
// Task function should be called in main/rtos loop
void tud_task (void);
@@ -304,6 +307,21 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re
/* Endpoint In */\
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0
//------------- DFU Runtime -------------//
#define TUD_DFU_APP_CLASS (TUSB_CLASS_APPLICATION_SPECIFIC)
#define TUD_DFU_APP_SUBCLASS 0x01u
// Length of template descriptr: 18 bytes
#define TUD_DFU_RT_DESC_LEN (9 + 9)
// DFU runtime descriptor
// Interface number, string index, attributes, detach timeout, transfer size
#define TUD_DFU_RT_DESCRIPTOR(_itfnum, _stridx, _attr, _timeout, _xfer_size) \
/* 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)
#ifdef __cplusplus
}

View File

@@ -33,8 +33,6 @@
extern "C" {
#endif
bool usbd_init (void);
//--------------------------------------------------------------------+
// USBD Endpoint API
//--------------------------------------------------------------------+