mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-17 05:32:55 +08:00
Merge pull request #344 from hathach/enhance-itf-assoc
Enhance Interface Associate descriptor handling
This commit is contained in:
commit
eb2aaa5de8
@ -262,12 +262,12 @@ bool cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t
|
||||
|
||||
p_cdc->ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress;
|
||||
|
||||
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
||||
(*p_length) += tu_desc_len(p_desc);
|
||||
p_desc = tu_desc_next(p_desc);
|
||||
}
|
||||
|
||||
//------------- Data Interface (if any) -------------//
|
||||
if ( (TUSB_DESC_INTERFACE == p_desc[DESC_OFFSET_TYPE]) &&
|
||||
if ( (TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) &&
|
||||
(TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) )
|
||||
{
|
||||
// next to endpoint descriptor
|
||||
|
@ -117,10 +117,6 @@ void netd_init(void)
|
||||
tu_memclr(&_netd_itf, sizeof(_netd_itf));
|
||||
}
|
||||
|
||||
void netd_init_data(void)
|
||||
{
|
||||
}
|
||||
|
||||
void netd_reset(uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
@ -166,32 +162,21 @@ bool netd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t
|
||||
|
||||
_netd_itf.ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress;
|
||||
|
||||
(*p_length) += p_desc[DESC_OFFSET_LEN];
|
||||
(*p_length) += tu_desc_len(p_desc);
|
||||
p_desc = tu_desc_next(p_desc);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool netd_open_data(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length)
|
||||
{
|
||||
TU_VERIFY(TUSB_CLASS_CDC_DATA == itf_desc->bInterfaceClass);
|
||||
|
||||
// confirm interface hasn't already been allocated
|
||||
TU_ASSERT(0 == _netd_itf.ep_in);
|
||||
|
||||
uint8_t const * p_desc = tu_desc_next( itf_desc );
|
||||
(*p_length) = sizeof(tusb_desc_interface_t);
|
||||
|
||||
//------------- Data Interface -------------//
|
||||
while ( (TUSB_DESC_INTERFACE == p_desc[DESC_OFFSET_TYPE]) &&
|
||||
(TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) )
|
||||
// TODO extract Alt Interface 0 & 1
|
||||
while ((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) &&
|
||||
(TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) )
|
||||
{
|
||||
// next to endpoint descriptor
|
||||
(*p_length) += tu_desc_len(p_desc);
|
||||
p_desc = tu_desc_next(p_desc);
|
||||
(*p_length) += sizeof(tusb_desc_interface_t);
|
||||
}
|
||||
|
||||
if (TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE])
|
||||
if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc))
|
||||
{
|
||||
// Open endpoint pair
|
||||
TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &_netd_itf.ep_out, &_netd_itf.ep_in) );
|
||||
@ -207,6 +192,7 @@ bool netd_open_data(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint
|
||||
// prepare for incoming packets
|
||||
tud_network_recv_renew();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -73,10 +73,8 @@ void tud_network_xmit(struct pbuf *p);
|
||||
// INTERNAL USBD-CLASS DRIVER API
|
||||
//--------------------------------------------------------------------+
|
||||
void netd_init (void);
|
||||
void netd_init_data (void);
|
||||
void netd_reset (uint8_t rhport);
|
||||
bool netd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length);
|
||||
bool netd_open_data (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length);
|
||||
bool netd_control_request (uint8_t rhport, tusb_control_request_t const * request);
|
||||
bool netd_control_complete (uint8_t rhport, tusb_control_request_t const * request);
|
||||
bool netd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
|
||||
|
@ -188,9 +188,8 @@ static usbd_class_driver_t const _usbd_driver[] =
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_NET
|
||||
/* RNDIS management interface */
|
||||
{
|
||||
DRIVER_NAME("RNDIS")
|
||||
DRIVER_NAME("NET")
|
||||
.init = netd_init,
|
||||
.reset = netd_reset,
|
||||
.open = netd_open,
|
||||
@ -199,30 +198,6 @@ static usbd_class_driver_t const _usbd_driver[] =
|
||||
.xfer_cb = netd_xfer_cb,
|
||||
.sof = NULL,
|
||||
},
|
||||
|
||||
/* CDC-ECM management interface */
|
||||
{
|
||||
DRIVER_NAME("CDC-ECM")
|
||||
.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,
|
||||
},
|
||||
|
||||
/* RNDIS/CDC-ECM data interface */
|
||||
{
|
||||
DRIVER_NAME("CDC-DATA")
|
||||
.init = netd_init_data,
|
||||
.reset = NULL,
|
||||
.open = netd_open_data,
|
||||
.control_request = NULL,
|
||||
.control_complete = NULL,
|
||||
.xfer_cb = netd_xfer_cb,
|
||||
.sof = NULL,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -611,9 +586,10 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
|
||||
case TUSB_REQ_SET_INTERFACE:
|
||||
{
|
||||
uint8_t const alternate = (uint8_t) p_request->wValue;
|
||||
(void) alternate;
|
||||
|
||||
// TODO not support alternate interface yet
|
||||
TU_ASSERT(alternate == 0);
|
||||
// TU_ASSERT(alternate == 0);
|
||||
tud_control_status(rhport, p_request);
|
||||
}
|
||||
break;
|
||||
@ -727,41 +703,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 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 TODO alternate interface
|
||||
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;
|
||||
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
|
||||
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
|
||||
|
@ -343,11 +343,13 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re
|
||||
//------------- CDC-ECM -------------//
|
||||
|
||||
// Length of template descriptor: 71 bytes
|
||||
#define TUD_CDC_ECM_DESC_LEN (9+5+5+13+7+9+9+7+7)
|
||||
#define TUD_CDC_ECM_DESC_LEN (8+9+5+5+13+7+9+9+7+7)
|
||||
|
||||
// CDC-ECM Descriptor Template
|
||||
// Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size.
|
||||
#define TUD_CDC_ECM_DESCRIPTOR(_itfnum, _desc_stridx, _mac_stridx, _ep_notif, _ep_notif_size, _epout, _epin, _epsize, _maxsegmentsize) \
|
||||
/* Interface Association */\
|
||||
8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, 0, 0,\
|
||||
/* CDC Control Interface */\
|
||||
9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, 0, _desc_stridx,\
|
||||
/* CDC-ECM Header */\
|
||||
@ -410,22 +412,6 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re
|
||||
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0
|
||||
|
||||
|
||||
//------------- CDC-EEM -------------//
|
||||
|
||||
// Length of template descriptor: 23 bytes
|
||||
#define TUD_CDC_EEM_DESC_LEN (9+7+7)
|
||||
|
||||
// CDC-EEM Descriptor Template
|
||||
// Interface number, description string index, EP data address (out, in) and size.
|
||||
#define TUD_CDC_EEM_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \
|
||||
/* EEM Interface */\
|
||||
9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ETHERNET_EMULATION_MODEL, CDC_COMM_PROTOCOL_ETHERNET_EMULATION_MODEL, _stridx,\
|
||||
/* Endpoint In */\
|
||||
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
|
||||
/* Endpoint Out */\
|
||||
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user