Merge branch 'master' into remove-dcd-set-config
This commit is contained in:
@@ -73,8 +73,17 @@ enum { DRVID_INVALID = 0xFFu };
|
||||
//--------------------------------------------------------------------+
|
||||
// Class Driver
|
||||
//--------------------------------------------------------------------+
|
||||
typedef struct {
|
||||
uint8_t class_code;
|
||||
#if CFG_TUSB_DEBUG >= 2
|
||||
#define DRIVER_NAME(_name) .name = _name,
|
||||
#else
|
||||
#define DRIVER_NAME(_name)
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#if CFG_TUSB_DEBUG >= 2
|
||||
char const* name;
|
||||
#endif
|
||||
|
||||
void (* init ) (void);
|
||||
void (* reset ) (uint8_t rhport);
|
||||
@@ -89,7 +98,7 @@ static usbd_class_driver_t const _usbd_driver[] =
|
||||
{
|
||||
#if CFG_TUD_CDC
|
||||
{
|
||||
.class_code = TUSB_CLASS_CDC,
|
||||
DRIVER_NAME("CDC")
|
||||
.init = cdcd_init,
|
||||
.reset = cdcd_reset,
|
||||
.open = cdcd_open,
|
||||
@@ -102,7 +111,7 @@ static usbd_class_driver_t const _usbd_driver[] =
|
||||
|
||||
#if CFG_TUD_MSC
|
||||
{
|
||||
.class_code = TUSB_CLASS_MSC,
|
||||
DRIVER_NAME("MSC")
|
||||
.init = mscd_init,
|
||||
.reset = mscd_reset,
|
||||
.open = mscd_open,
|
||||
@@ -115,7 +124,7 @@ static usbd_class_driver_t const _usbd_driver[] =
|
||||
|
||||
#if CFG_TUD_HID
|
||||
{
|
||||
.class_code = TUSB_CLASS_HID,
|
||||
DRIVER_NAME("HID")
|
||||
.init = hidd_init,
|
||||
.reset = hidd_reset,
|
||||
.open = hidd_open,
|
||||
@@ -128,7 +137,7 @@ static usbd_class_driver_t const _usbd_driver[] =
|
||||
|
||||
#if CFG_TUD_MIDI
|
||||
{
|
||||
.class_code = TUSB_CLASS_AUDIO,
|
||||
DRIVER_NAME("MIDI")
|
||||
.init = midid_init,
|
||||
.open = midid_open,
|
||||
.reset = midid_reset,
|
||||
@@ -141,7 +150,7 @@ static usbd_class_driver_t const _usbd_driver[] =
|
||||
|
||||
#if CFG_TUD_VENDOR
|
||||
{
|
||||
.class_code = TUSB_CLASS_VENDOR_SPECIFIC,
|
||||
DRIVER_NAME("VENDOR")
|
||||
.init = vendord_init,
|
||||
.reset = vendord_reset,
|
||||
.open = vendord_open,
|
||||
@@ -153,12 +162,8 @@ static usbd_class_driver_t const _usbd_driver[] =
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_USBTMC
|
||||
// Presently USBTMC is the only defined class with the APP_SPECIFIC class code.
|
||||
// We maybe need to add subclass codes here, or a callback to ask if a driver can
|
||||
// handle a particular interface.
|
||||
{
|
||||
.class_code = TUD_USBTMC_APP_CLASS,
|
||||
//.subclass_code = TUD_USBTMC_APP_SUBCLASS
|
||||
DRIVER_NAME("TMC")
|
||||
.init = usbtmcd_init_cb,
|
||||
.reset = usbtmcd_reset_cb,
|
||||
.open = usbtmcd_open_cb,
|
||||
@@ -171,8 +176,7 @@ static usbd_class_driver_t const _usbd_driver[] =
|
||||
|
||||
#if CFG_TUD_DFU_RT
|
||||
{
|
||||
.class_code = TUD_DFU_APP_CLASS,
|
||||
//.subclass_code = TUD_DFU_APP_SUBCLASS
|
||||
DRIVER_NAME("DFU-RT")
|
||||
.init = dfu_rtd_init,
|
||||
.reset = dfu_rtd_reset,
|
||||
.open = dfu_rtd_open,
|
||||
@@ -185,19 +189,14 @@ static usbd_class_driver_t const _usbd_driver[] =
|
||||
|
||||
#if CFG_TUD_NET
|
||||
{
|
||||
.class_code =
|
||||
#if CFG_TUD_NET == OPT_NET_RNDIS
|
||||
TUD_RNDIS_ITF_CLASS,
|
||||
#else
|
||||
TUSB_CLASS_CDC,
|
||||
#endif
|
||||
DRIVER_NAME("NET")
|
||||
.init = netd_init,
|
||||
.reset = netd_reset,
|
||||
.open = netd_open,
|
||||
.control_request = netd_control_request,
|
||||
.control_complete = netd_control_complete,
|
||||
.xfer_cb = netd_xfer_cb,
|
||||
.sof = NULL
|
||||
.sof = NULL,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
@@ -244,32 +243,6 @@ static char const* const _usbd_event_str[DCD_EVENT_COUNT] =
|
||||
"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
|
||||
#if CFG_TUD_NET
|
||||
"NET"
|
||||
#endif
|
||||
};
|
||||
|
||||
static char const* const _tusb_std_request_str[] =
|
||||
{
|
||||
"Get Status" ,
|
||||
@@ -326,7 +299,7 @@ bool tud_init (void)
|
||||
// Init class drivers
|
||||
for (uint8_t i = 0; i < USBD_CLASS_DRIVER_COUNT; i++)
|
||||
{
|
||||
TU_LOG2("%s init\r\n", _usbd_driver_str[i]);
|
||||
TU_LOG2("%s init\r\n", _usbd_driver[i].name);
|
||||
_usbd_driver[i].init();
|
||||
}
|
||||
|
||||
@@ -435,7 +408,7 @@ void tud_task (void)
|
||||
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]);
|
||||
TU_LOG2(" %s xfer callback\r\n", _usbd_driver[drv_id].name);
|
||||
_usbd_driver[drv_id].xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len);
|
||||
}
|
||||
}
|
||||
@@ -480,7 +453,7 @@ static bool invoke_class_control(uint8_t rhport, uint8_t drvid, tusb_control_req
|
||||
TU_ASSERT(_usbd_driver[drvid].control_request);
|
||||
|
||||
usbd_control_set_complete_callback(_usbd_driver[drvid].control_complete);
|
||||
TU_LOG2(" %s control request\r\n", _usbd_driver_str[drvid]);
|
||||
TU_LOG2(" %s control request\r\n", _usbd_driver[drvid].name);
|
||||
return _usbd_driver[drvid].control_request(rhport, request);
|
||||
}
|
||||
|
||||
@@ -596,38 +569,17 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
|
||||
uint8_t const drvid = _usbd_dev.itf2drv[itf];
|
||||
TU_VERIFY(drvid < USBD_CLASS_DRIVER_COUNT);
|
||||
|
||||
if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD)
|
||||
// all requests to Interface (STD or Class) is forwarded to class driver.
|
||||
// notable requests are: GET HID REPORT DESCRIPTOR, SET_INTERFACE, GET_INTERFACE
|
||||
if ( !invoke_class_control(rhport, drvid, p_request) )
|
||||
{
|
||||
switch ( p_request->bRequest )
|
||||
{
|
||||
case TUSB_REQ_GET_INTERFACE:
|
||||
{
|
||||
// TODO not support alternate interface yet
|
||||
uint8_t alternate = 0;
|
||||
tud_control_xfer(rhport, p_request, &alternate, 1);
|
||||
}
|
||||
break;
|
||||
// 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);
|
||||
|
||||
case TUSB_REQ_SET_INTERFACE:
|
||||
{
|
||||
uint8_t const alternate = (uint8_t) p_request->wValue;
|
||||
|
||||
// TODO not support alternate interface yet
|
||||
TU_ASSERT(alternate == 0);
|
||||
tud_control_status(rhport, p_request);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// forward to class driver: "STD request to Interface"
|
||||
// GET HID REPORT DESCRIPTOR falls into this case
|
||||
TU_VERIFY(invoke_class_control(rhport, drvid, p_request));
|
||||
break;
|
||||
}
|
||||
}else
|
||||
{
|
||||
// forward to class driver: "non-STD request to Interface"
|
||||
TU_VERIFY(invoke_class_control(rhport, drvid, p_request));
|
||||
uint8_t alternate = 0;
|
||||
tud_control_xfer(rhport, p_request, &alternate, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -727,37 +679,59 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num)
|
||||
|
||||
while( p_desc < desc_end )
|
||||
{
|
||||
// Each interface always starts with Interface or Association descriptor
|
||||
tusb_desc_interface_assoc_t const * desc_itf_assoc = NULL;
|
||||
|
||||
// Class will always starts with Interface Association (if any) and then Interface descriptor
|
||||
if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc) )
|
||||
{
|
||||
p_desc = tu_desc_next(p_desc); // ignore Interface Association
|
||||
}else
|
||||
{
|
||||
TU_ASSERT( TUSB_DESC_INTERFACE == tu_desc_type(p_desc) );
|
||||
|
||||
tusb_desc_interface_t* desc_itf = (tusb_desc_interface_t*) p_desc;
|
||||
|
||||
// Check if class is supported
|
||||
uint8_t drv_id;
|
||||
for (drv_id = 0; drv_id < USBD_CLASS_DRIVER_COUNT; drv_id++)
|
||||
{
|
||||
if ( _usbd_driver[drv_id].class_code == desc_itf->bInterfaceClass ) break;
|
||||
}
|
||||
TU_ASSERT( drv_id < USBD_CLASS_DRIVER_COUNT );
|
||||
|
||||
// Interface number must not be used already TODO alternate interface
|
||||
TU_ASSERT( DRVID_INVALID == _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] );
|
||||
_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_driver[drv_id].open(rhport, desc_itf, &itf_len) );
|
||||
TU_ASSERT( itf_len >= sizeof(tusb_desc_interface_t) );
|
||||
|
||||
mark_interface_endpoint(_usbd_dev.ep2drv, p_desc, itf_len, drv_id);
|
||||
|
||||
p_desc += itf_len; // next interface
|
||||
desc_itf_assoc = (tusb_desc_interface_assoc_t const *) p_desc;
|
||||
p_desc = tu_desc_next(p_desc); // next to Interface
|
||||
}
|
||||
|
||||
TU_ASSERT( TUSB_DESC_INTERFACE == tu_desc_type(p_desc) );
|
||||
|
||||
tusb_desc_interface_t const * desc_itf = (tusb_desc_interface_t const*) p_desc;
|
||||
uint8_t drv_id;
|
||||
uint16_t drv_len;
|
||||
|
||||
for (drv_id = 0; drv_id < USBD_CLASS_DRIVER_COUNT; drv_id++)
|
||||
{
|
||||
usbd_class_driver_t const *driver = &_usbd_driver[drv_id];
|
||||
|
||||
drv_len = 0;
|
||||
if ( driver->open(rhport, desc_itf, &drv_len) )
|
||||
{
|
||||
// Interface number must not be used already
|
||||
TU_ASSERT( DRVID_INVALID == _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] );
|
||||
|
||||
TU_LOG2(" %s open\r\n", _usbd_driver[drv_id].name);
|
||||
_usbd_dev.itf2drv[desc_itf->bInterfaceNumber] = drv_id;
|
||||
|
||||
// If IAD exist, assign all interfaces to the same driver
|
||||
if (desc_itf_assoc)
|
||||
{
|
||||
// IAD's first interface number and class/subclass/protocol should match with opened interface
|
||||
TU_ASSERT(desc_itf_assoc->bFirstInterface == desc_itf->bInterfaceNumber &&
|
||||
desc_itf_assoc->bFunctionClass == desc_itf->bInterfaceClass &&
|
||||
desc_itf_assoc->bFunctionSubClass == desc_itf->bInterfaceSubClass &&
|
||||
desc_itf_assoc->bFunctionProtocol == desc_itf->bInterfaceProtocol);
|
||||
|
||||
for(uint8_t i=1; i<desc_itf_assoc->bInterfaceCount; i++)
|
||||
{
|
||||
_usbd_dev.itf2drv[desc_itf->bInterfaceNumber+i] = drv_id;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Assert if cannot find supported driver
|
||||
TU_ASSERT( drv_id < USBD_CLASS_DRIVER_COUNT && drv_len >= sizeof(tusb_desc_interface_t) );
|
||||
|
||||
mark_interface_endpoint(_usbd_dev.ep2drv, p_desc, drv_len, drv_id); // TODO refactor
|
||||
|
||||
p_desc += drv_len; // next interface
|
||||
}
|
||||
|
||||
// invoke callback
|
||||
@@ -1035,4 +1009,20 @@ bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr)
|
||||
return _usbd_dev.ep_status[epnum][dir].stalled;
|
||||
}
|
||||
|
||||
/**
|
||||
* usbd_edpt_close will disable an endpoint.
|
||||
*
|
||||
* In progress transfers on this EP may be delivered after this call.
|
||||
*
|
||||
*/
|
||||
void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr)
|
||||
{
|
||||
TU_ASSERT(dcd_edpt_close, /**/);
|
||||
TU_LOG2(" CLOSING Endpoint: 0x%02X\r\n", ep_addr);
|
||||
|
||||
dcd_edpt_close(rhport, ep_addr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user