summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhathach <[email protected]>2020-04-17 13:38:22 +0700
committerhathach <[email protected]>2020-04-17 13:38:22 +0700
commit05476d9ad72321aa6e57ff5acbc4b25e1366fead (patch)
tree10a12e71a679243ad5775ed7e0088242b8e763c8 /src
parentf4df82939955d86f6c2e826e1bc9f4b5bb713df8 (diff)
parent85f0894fff89baaaa91a6dc3554a3149fc2fc062 (diff)
Merge branch 'master' into remove-dcd-set-config
Diffstat (limited to 'src')
-rw-r--r--src/class/cdc/cdc_device.c12
-rw-r--r--src/class/cdc/cdc_host.c2
-rw-r--r--src/class/dfu/dfu_rt_device.c4
-rw-r--r--src/class/dfu/dfu_rt_device.h2
-rw-r--r--src/class/hid/hid_device.c2
-rw-r--r--src/class/midi/midi_device.c46
-rw-r--r--src/class/msc/msc_device.c3
-rw-r--r--src/class/net/net_device.c361
-rw-r--r--src/class/usbtmc/usbtmc_device.c8
-rw-r--r--src/class/vendor/vendor_device.c2
-rw-r--r--src/common/tusb_types.h7
-rw-r--r--src/device/dcd.h12
-rw-r--r--src/device/usbd.c192
-rw-r--r--src/device/usbd.h50
-rw-r--r--src/device/usbd_pvt.h1
-rw-r--r--src/portable/espressif/esp32s2/dcd_esp32s2.c21
-rw-r--r--src/portable/microchip/samd/dcd_samd.c2
-rw-r--r--src/portable/microchip/samg/dcd_samg.c22
-rw-r--r--src/portable/nordic/nrf5x/dcd_nrf5x.c2
-rw-r--r--src/portable/nuvoton/nuc120/dcd_nuc120.c2
-rw-r--r--src/portable/nuvoton/nuc121/dcd_nuc121.c2
-rw-r--r--src/portable/nuvoton/nuc505/dcd_nuc505.c13
-rw-r--r--src/portable/nxp/lpc17_40/dcd_lpc17_40.c18
-rw-r--r--src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c16
-rw-r--r--src/portable/nxp/transdimension/dcd_transdimension.c17
-rw-r--r--src/portable/sony/cxd56/dcd_cxd56.c12
-rw-r--r--src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c164
-rw-r--r--src/portable/st/synopsys/dcd_synopsys.c23
-rw-r--r--src/portable/template/dcd_template.c12
-rw-r--r--src/portable/ti/msp430x5xx/dcd_msp430x5xx.c27
-rw-r--r--src/portable/valentyusb/eptri/dcd_eptri.c15
-rw-r--r--src/tusb_option.h9
32 files changed, 695 insertions, 386 deletions
diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c
index 14b9a3153..95b14ba54 100644
--- a/src/class/cdc/cdc_device.c
+++ b/src/class/cdc/cdc_device.c
@@ -223,11 +223,11 @@ void cdcd_reset(uint8_t rhport)
bool cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length)
{
// Only support ACM subclass
- TU_ASSERT ( CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass);
+ TU_VERIFY ( TUSB_CLASS_CDC == itf_desc->bInterfaceClass &&
+ CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass);
- // Only support AT commands, no protocol and vendor specific commands.
- TU_ASSERT(tu_within(CDC_COMM_PROTOCOL_NONE, itf_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA) ||
- itf_desc->bInterfaceProtocol == 0xff);
+ // Note: 0xFF can be used with RNDIS
+ TU_VERIFY(tu_within(CDC_COMM_PROTOCOL_NONE, itf_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA));
// Find available interface
cdcd_interface_t * p_cdc = NULL;
@@ -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
diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c
index 595e7fd62..5e45e8f6b 100644
--- a/src/class/cdc/cdc_host.c
+++ b/src/class/cdc/cdc_host.c
@@ -86,7 +86,7 @@ bool tuh_cdc_serial_is_mounted(uint8_t dev_addr)
{
// TODO consider all AT Command as serial candidate
return tuh_cdc_mounted(dev_addr) &&
- (CDC_COMM_PROTOCOL_ATCOMMAND <= cdch_data[dev_addr-1].itf_protocol) &&
+ (CDC_COMM_PROTOCOL_NONE <= cdch_data[dev_addr-1].itf_protocol) &&
(cdch_data[dev_addr-1].itf_protocol <= CDC_COMM_PROTOCOL_ATCOMMAND_CDMA);
}
diff --git a/src/class/dfu/dfu_rt_device.c b/src/class/dfu/dfu_rt_device.c
index ad1871dad..0ef5fe63f 100644
--- a/src/class/dfu/dfu_rt_device.c
+++ b/src/class/dfu/dfu_rt_device.c
@@ -61,8 +61,8 @@ bool dfu_rtd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16
(void) rhport;
// Ensure this is DFU Runtime
- TU_ASSERT(itf_desc->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS);
- TU_ASSERT(itf_desc->bInterfaceProtocol == DFU_PROTOCOL_RT);
+ TU_VERIFY(itf_desc->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS);
+ TU_VERIFY(itf_desc->bInterfaceProtocol == DFU_PROTOCOL_RT);
uint8_t const * p_desc = tu_desc_next( itf_desc );
(*p_length) = sizeof(tusb_desc_interface_t);
diff --git a/src/class/dfu/dfu_rt_device.h b/src/class/dfu/dfu_rt_device.h
index 4348a0f3a..294d993e3 100644
--- a/src/class/dfu/dfu_rt_device.h
+++ b/src/class/dfu/dfu_rt_device.h
@@ -58,7 +58,7 @@ typedef enum
//--------------------------------------------------------------------+
// Invoked when received new data
-TU_ATTR_WEAK void tud_dfu_rt_reboot_to_dfu(void);
+TU_ATTR_WEAK void tud_dfu_rt_reboot_to_dfu(void); // TODO rename to _cb convention
//--------------------------------------------------------------------+
// Internal Class Driver API
diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c
index 7cb35f1ce..cbdc5bece 100644
--- a/src/class/hid/hid_device.c
+++ b/src/class/hid/hid_device.c
@@ -160,6 +160,8 @@ void hidd_reset(uint8_t rhport)
bool hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t *p_len)
{
+ TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass);
+
uint8_t const *p_desc = (uint8_t const *) desc_itf;
// Find available interface
diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c
index ae6e3afe1..6eb522380 100644
--- a/src/class/midi/midi_device.c
+++ b/src/class/midi/midi_device.c
@@ -253,21 +253,31 @@ void midid_reset(uint8_t rhport)
}
}
-bool midid_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length)
+bool midid_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t *p_length)
{
- // For now handle the audio control interface as well.
- if ( AUDIO_SUBCLASS_CONTROL == p_interface_desc->bInterfaceSubClass) {
- uint8_t const * p_desc = tu_desc_next ( (uint8_t const *) p_interface_desc );
- (*p_length) = sizeof(tusb_desc_interface_t);
- // Skip over the class specific descriptor.
- (*p_length) += tu_desc_len(p_desc);
+ // 1st Interface is Audio Control v1
+ TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass &&
+ AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass &&
+ AUDIO_PROTOCOL_V1 == desc_itf->bInterfaceProtocol);
+
+ uint16_t drv_len = tu_desc_len(desc_itf);
+ uint8_t const * p_desc = tu_desc_next(desc_itf);
+
+ // Skip Class Specific descriptors
+ while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) )
+ {
+ drv_len += tu_desc_len(p_desc);
p_desc = tu_desc_next(p_desc);
- return true;
}
- TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == p_interface_desc->bInterfaceSubClass &&
- AUDIO_PROTOCOL_V1 == p_interface_desc->bInterfaceProtocol );
+ // 2nd Interface is MIDI Streaming
+ TU_VERIFY(TUSB_DESC_INTERFACE == tu_desc_type(p_desc));
+ tusb_desc_interface_t const * desc_midi = (tusb_desc_interface_t const *) p_desc;
+
+ TU_VERIFY(TUSB_CLASS_AUDIO == desc_midi->bInterfaceClass &&
+ AUDIO_SUBCLASS_MIDI_STREAMING == desc_midi->bInterfaceSubClass &&
+ AUDIO_PROTOCOL_V1 == desc_midi->bInterfaceProtocol );
// Find available interface
midid_interface_t * p_midi = NULL;
@@ -280,13 +290,15 @@ bool midid_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc,
}
}
- p_midi->itf_num = p_interface_desc->bInterfaceNumber;
+ p_midi->itf_num = desc_midi->bInterfaceNumber;
- uint8_t const * p_desc = tu_desc_next( (uint8_t const *) p_interface_desc );
- (*p_length) = sizeof(tusb_desc_interface_t);
+ // next descriptor
+ drv_len += tu_desc_len(p_desc);
+ p_desc = tu_desc_next(p_desc);
+ // Find and open endpoint descriptors
uint8_t found_endpoints = 0;
- while (found_endpoints < p_interface_desc->bNumEndpoints)
+ while (found_endpoints < desc_midi->bNumEndpoints)
{
if ( TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE])
{
@@ -298,14 +310,16 @@ bool midid_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc,
p_midi->ep_out = ep_addr;
}
- (*p_length) += p_desc[DESC_OFFSET_LEN];
+ drv_len += p_desc[DESC_OFFSET_LEN];
p_desc = tu_desc_next(p_desc);
found_endpoints += 1;
}
- (*p_length) += p_desc[DESC_OFFSET_LEN];
+ drv_len += p_desc[DESC_OFFSET_LEN];
p_desc = tu_desc_next(p_desc);
}
+ *p_length = drv_len;
+
// Prepare for incoming data
TU_ASSERT( usbd_edpt_xfer(rhport, p_midi->ep_out, p_midi->epout_buf, CFG_TUD_MIDI_EPSIZE), false);
diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c
index 06cc9dbb6..68f5587fd 100644
--- a/src/class/msc/msc_device.c
+++ b/src/class/msc/msc_device.c
@@ -157,7 +157,8 @@ void mscd_reset(uint8_t rhport)
bool mscd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_len)
{
// only support SCSI's BOT protocol
- TU_ASSERT(MSC_SUBCLASS_SCSI == itf_desc->bInterfaceSubClass &&
+ TU_VERIFY(TUSB_CLASS_MSC == itf_desc->bInterfaceClass &&
+ MSC_SUBCLASS_SCSI == itf_desc->bInterfaceSubClass &&
MSC_PROTOCOL_BOT == itf_desc->bInterfaceProtocol);
mscd_interface_t * p_msc = &_mscd_itf;
diff --git a/src/class/net/net_device.c b/src/class/net/net_device.c
index 68520625a..0f2ccbd44 100644
--- a/src/class/net/net_device.c
+++ b/src/class/net/net_device.c
@@ -27,7 +27,7 @@
#include "tusb_option.h"
-#if ( TUSB_OPT_DEVICE_ENABLED && (CFG_TUD_NET != OPT_NET_NONE) )
+#if ( TUSB_OPT_DEVICE_ENABLED && CFG_TUD_NET )
#include "net_device.h"
#include "device/usbd_pvt.h"
@@ -40,40 +40,60 @@ void rndis_class_set_handler(uint8_t *data, int size); /* found in ./misc/networ
//--------------------------------------------------------------------+
typedef struct
{
- uint8_t itf_num;
+ uint8_t itf_num; // Index number of Management Interface, +1 for Data Interface
+ uint8_t itf_data_alt; // Alternate setting of Data Interface. 0 : inactive, 1 : active
+
uint8_t ep_notif;
uint8_t ep_in;
uint8_t ep_out;
+
+ bool ecm_mode;
+
+ // Endpoint descriptor use to open/close when receving SetInterface
+ // TODO since configuration descriptor may not be long-lived memory, we should
+ // keep a copy of endpoint attribute instead
+ uint8_t const * ecm_desc_epdata;
+
} netd_interface_t;
-#if CFG_TUD_NET == OPT_NET_ECM
- #define CFG_TUD_NET_PACKET_PREFIX_LEN 0
- #define CFG_TUD_NET_PACKET_SUFFIX_LEN 0
- #define CFG_TUD_NET_INTERFACESUBCLASS CDC_COMM_SUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL
-#elif CFG_TUD_NET == OPT_NET_RNDIS
- #define CFG_TUD_NET_PACKET_PREFIX_LEN sizeof(rndis_data_packet_t)
- #define CFG_TUD_NET_PACKET_SUFFIX_LEN 0
- #define CFG_TUD_NET_INTERFACESUBCLASS TUD_RNDIS_ITF_SUBCLASS
-#elif CFG_TUD_NET == OPT_NET_EEM
- #define CFG_TUD_NET_PACKET_PREFIX_LEN 2
- #define CFG_TUD_NET_PACKET_SUFFIX_LEN 4
- #define CFG_TUD_NET_INTERFACESUBCLASS CDC_COMM_SUBCLASS_ETHERNET_EMULATION_MODEL
-#endif
+#define CFG_TUD_NET_PACKET_PREFIX_LEN sizeof(rndis_data_packet_t)
+#define CFG_TUD_NET_PACKET_SUFFIX_LEN 0
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t received[CFG_TUD_NET_PACKET_PREFIX_LEN + CFG_TUD_NET_MTU + CFG_TUD_NET_PACKET_PREFIX_LEN];
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t transmitted[CFG_TUD_NET_PACKET_PREFIX_LEN + CFG_TUD_NET_MTU + CFG_TUD_NET_PACKET_PREFIX_LEN];
-#if CFG_TUD_NET == OPT_NET_ECM
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static tusb_control_request_t notify =
- {
- .bmRequestType = 0x21,
- .bRequest = 0 /* NETWORK_CONNECTION */,
+struct ecm_notify_struct
+{
+ tusb_control_request_t header;
+ uint32_t downlink, uplink;
+};
+
+static const struct ecm_notify_struct ecm_notify_nc =
+{
+ .header = {
+ .bmRequestType = 0xA1,
+ .bRequest = 0 /* NETWORK_CONNECTION aka NetworkConnection */,
.wValue = 1 /* Connected */,
.wLength = 0,
- };
-#elif CFG_TUD_NET == OPT_NET_RNDIS
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t rndis_buf[120];
-#endif
+ },
+};
+
+static const struct ecm_notify_struct ecm_notify_csc =
+{
+ .header = {
+ .bmRequestType = 0xA1,
+ .bRequest = 0x2A /* CONNECTION_SPEED_CHANGE aka ConnectionSpeedChange */,
+ .wLength = 8,
+ },
+ .downlink = 9728000,
+ .uplink = 9728000,
+};
+
+CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static union
+{
+ uint8_t rndis_buf[120];
+ struct ecm_notify_struct ecm_buf;
+} notify;
//--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION
@@ -115,19 +135,28 @@ void netd_reset(uint8_t rhport)
bool netd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length)
{
- // sanity check the descriptor
- TU_ASSERT (CFG_TUD_NET_INTERFACESUBCLASS == itf_desc->bInterfaceSubClass);
+ bool const is_rndis = (TUD_RNDIS_ITF_CLASS == itf_desc->bInterfaceClass &&
+ TUD_RNDIS_ITF_SUBCLASS == itf_desc->bInterfaceSubClass &&
+ TUD_RNDIS_ITF_PROTOCOL == itf_desc->bInterfaceProtocol);
+
+ bool const is_ecm = (TUSB_CLASS_CDC == itf_desc->bInterfaceClass &&
+ CDC_COMM_SUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL == itf_desc->bInterfaceSubClass &&
+ 0x00 == itf_desc->bInterfaceProtocol);
+
+ TU_VERIFY ( is_rndis || is_ecm );
// confirm interface hasn't already been allocated
- TU_ASSERT(0 == _netd_itf.ep_in);
+ TU_ASSERT(0 == _netd_itf.ep_notif);
- //------------- first Interface -------------//
+ // sanity check the descriptor
+ _netd_itf.ecm_mode = is_ecm;
+
+ //------------- Management Interface -------------//
_netd_itf.itf_num = itf_desc->bInterfaceNumber;
- uint8_t const * p_desc = tu_desc_next( itf_desc );
(*p_length) = sizeof(tusb_desc_interface_t);
+ uint8_t const * p_desc = tu_desc_next( itf_desc );
-#if CFG_TUD_NET != OPT_NET_EEM
// Communication Functional Descriptors
while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) )
{
@@ -142,35 +171,49 @@ 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);
}
- //------------- second Interface -------------//
- if ( (TUSB_DESC_INTERFACE == p_desc[DESC_OFFSET_TYPE]) &&
- (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) )
+ //------------- Data Interface -------------//
+ // - RNDIS Data followed immediately by a pair of endpoints
+ // - CDC-ECM data interface has 2 alternate settings
+ // - 0 : zero endpoints for inactive (default)
+ // - 1 : IN & OUT endpoints for active networking
+ TU_ASSERT(TUSB_DESC_INTERFACE == tu_desc_type(p_desc));
+
+ do
{
- // next to endpoint descriptor
+ tusb_desc_interface_t const * data_itf_desc = (tusb_desc_interface_t const *) p_desc;
+ TU_ASSERT(TUSB_CLASS_CDC_DATA == data_itf_desc->bInterfaceClass);
+
+ (*p_length) += tu_desc_len(p_desc);
p_desc = tu_desc_next(p_desc);
- (*p_length) += sizeof(tusb_desc_interface_t);
- }
-#endif
+ }while( _netd_itf.ecm_mode && (TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) );
+
+ // Pair of endpoints
+ TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc));
- if (TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE])
+ if ( _netd_itf.ecm_mode )
+ {
+ // ECM by default is in-active, save the endpoint attribute
+ // to open later when received setInterface
+ _netd_itf.ecm_desc_epdata = p_desc;
+ }else
{
- // Open endpoint pair
+ // Open endpoint pair for RNDIS
TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &_netd_itf.ep_out, &_netd_itf.ep_in) );
- (*p_length) += 2*sizeof(tusb_desc_endpoint_t);
- }
+ tud_network_init_cb();
- tud_network_init_cb();
+ // we are ready to transmit a packet
+ can_xmit = true;
- // we are ready to transmit a packet
- can_xmit = true;
+ // prepare for incoming packets
+ tud_network_recv_renew();
+ }
- // prepare for incoming packets
- tud_network_recv_renew();
+ (*p_length) += 2*sizeof(tusb_desc_endpoint_t);
return true;
}
@@ -181,116 +224,167 @@ bool netd_control_complete(uint8_t rhport, tusb_control_request_t const * reques
{
(void) rhport;
- // Handle class request only
- TU_VERIFY (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS);
-
- TU_VERIFY (_netd_itf.itf_num == request->wIndex);
-
-#if CFG_TUD_NET == OPT_NET_RNDIS
- if (request->bmRequestType_bit.direction == TUSB_DIR_OUT)
+ // Handle RNDIS class control OUT only
+ if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS &&
+ request->bmRequestType_bit.direction == TUSB_DIR_OUT &&
+ _netd_itf.itf_num == request->wIndex)
{
- rndis_class_set_handler(rndis_buf, request->wLength);
+ if ( !_netd_itf.ecm_mode )
+ {
+ rndis_class_set_handler(notify.rndis_buf, request->wLength);
+ }
}
-#endif
return true;
}
+static void ecm_report(bool nc)
+{
+ notify.ecm_buf = (nc) ? ecm_notify_nc : ecm_notify_csc;
+ notify.ecm_buf.header.wIndex = _netd_itf.itf_num;
+ netd_report((uint8_t *)&notify.ecm_buf, (nc) ? sizeof(notify.ecm_buf.header) : sizeof(notify.ecm_buf));
+}
+
// Handle class control request
// return false to stall control endpoint (e.g unsupported request)
bool netd_control_request(uint8_t rhport, tusb_control_request_t const * request)
{
- // Handle class request only
- TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS);
+ switch ( request->bmRequestType_bit.type )
+ {
+ case TUSB_REQ_TYPE_STANDARD:
+ switch ( request->bRequest )
+ {
+ case TUSB_REQ_GET_INTERFACE:
+ {
+ uint8_t const req_itfnum = (uint8_t) request->wIndex;
+ TU_VERIFY(_netd_itf.itf_num+1 == req_itfnum);
- TU_VERIFY (_netd_itf.itf_num == request->wIndex);
+ tud_control_xfer(rhport, request, &_netd_itf.itf_data_alt, 1);
+ }
+ break;
-#if CFG_TUD_NET == OPT_NET_ECM
- /* the only required CDC-ECM Management Element Request is SetEthernetPacketFilter */
- if (0x43 /* SET_ETHERNET_PACKET_FILTER */ == request->bRequest)
- {
- tud_control_xfer(rhport, request, NULL, 0);
- notify.wIndex = request->wIndex;
- usbd_edpt_xfer(TUD_OPT_RHPORT, _netd_itf.ep_notif, (uint8_t *)&notify, sizeof(notify));
- }
-#elif CFG_TUD_NET == OPT_NET_RNDIS
- if (request->bmRequestType_bit.direction == TUSB_DIR_IN)
- {
- rndis_generic_msg_t *rndis_msg = (rndis_generic_msg_t *)rndis_buf;
- uint32_t msglen = tu_le32toh(rndis_msg->MessageLength);
- TU_ASSERT(msglen <= sizeof(rndis_buf));
- tud_control_xfer(rhport, request, rndis_buf, msglen);
- }
- else
- {
- tud_control_xfer(rhport, request, rndis_buf, sizeof(rndis_buf));
+ case TUSB_REQ_SET_INTERFACE:
+ {
+ uint8_t const req_itfnum = (uint8_t) request->wIndex;
+ uint8_t const req_alt = (uint8_t) request->wValue;
+
+ // Only valid for Data Interface with Alternate is either 0 or 1
+ TU_VERIFY(_netd_itf.itf_num+1 == req_itfnum && req_alt < 2);
+
+ // ACM-ECM only: qequest to enable/disable network activities
+ TU_VERIFY(_netd_itf.ecm_mode);
+
+ _netd_itf.itf_data_alt = req_alt;
+
+ if ( _netd_itf.itf_data_alt )
+ {
+ // TODO since we don't actually close endpoint
+ // hack here to not re-open it
+ if ( _netd_itf.ep_in == 0 && _netd_itf.ep_out == 0 )
+ {
+ TU_ASSERT(_netd_itf.ecm_desc_epdata);
+ TU_ASSERT( usbd_open_edpt_pair(rhport, _netd_itf.ecm_desc_epdata, 2, TUSB_XFER_BULK, &_netd_itf.ep_out, &_netd_itf.ep_in) );
+
+ // TODO should be merge with RNDIS's after endpoint opened
+ // Also should have opposite callback for application to disable network !!
+ tud_network_init_cb();
+ can_xmit = true; // we are ready to transmit a packet
+ tud_network_recv_renew(); // prepare for incoming packets
+ }
+ }else
+ {
+ // TODO close the endpoint pair
+ // For now pretend that we did, this should have no harm since host won't try to
+ // communicate with the endpoints again
+ // _netd_itf.ep_in = _netd_itf.ep_out = 0
+ }
+
+ tud_control_status(rhport, request);
+ }
+ break;
+
+ // unsupported request
+ default: return false;
+ }
+ break;
+
+ case TUSB_REQ_TYPE_CLASS:
+ TU_VERIFY (_netd_itf.itf_num == request->wIndex);
+
+ if (_netd_itf.ecm_mode)
+ {
+ /* the only required CDC-ECM Management Element Request is SetEthernetPacketFilter */
+ if (0x43 /* SET_ETHERNET_PACKET_FILTER */ == request->bRequest)
+ {
+ tud_control_xfer(rhport, request, NULL, 0);
+ ecm_report(true);
+ }
+ }
+ else
+ {
+ if (request->bmRequestType_bit.direction == TUSB_DIR_IN)
+ {
+ rndis_generic_msg_t *rndis_msg = (rndis_generic_msg_t *)notify.rndis_buf;
+ uint32_t msglen = tu_le32toh(rndis_msg->MessageLength);
+ TU_ASSERT(msglen <= sizeof(notify.rndis_buf));
+ tud_control_xfer(rhport, request, notify.rndis_buf, msglen);
+ }
+ else
+ {
+ tud_control_xfer(rhport, request, notify.rndis_buf, sizeof(notify.rndis_buf));
+ }
+ }
+ break;
+
+ // unsupported request
+ default: return false;
}
-#else
- (void)rhport;
-#endif
return true;
}
-struct cdc_eem_packet_header
-{
- uint16_t length:14;
- uint16_t bmCRC:1;
- uint16_t bmType:1;
-};
-
static void handle_incoming_packet(uint32_t len)
{
uint8_t *pnt = received;
uint32_t size = 0;
-#if CFG_TUD_NET == OPT_NET_ECM
- size = len;
-#elif CFG_TUD_NET == OPT_NET_RNDIS
- rndis_data_packet_t *r = (rndis_data_packet_t *)pnt;
- if (len >= sizeof(rndis_data_packet_t))
- if ( (r->MessageType == REMOTE_NDIS_PACKET_MSG) && (r->MessageLength <= len))
- if ( (r->DataOffset + offsetof(rndis_data_packet_t, DataOffset) + r->DataLength) <= len)
- {
- pnt = &received[r->DataOffset + offsetof(rndis_data_packet_t, DataOffset)];
- size = r->DataLength;
- }
-#elif CFG_TUD_NET == OPT_NET_EEM
- struct cdc_eem_packet_header *hdr = (struct cdc_eem_packet_header *)pnt;
-
- (void)len;
-
- if (hdr->bmType)
+ if (_netd_itf.ecm_mode)
{
- /* EEM Control Packet: discard it */
- tud_network_recv_renew();
+ size = len;
}
else
{
- /* EEM Data Packet */
- pnt += CFG_TUD_NET_PACKET_PREFIX_LEN;
- size = hdr->length - 4; /* discard the unused CRC-32 */
+ rndis_data_packet_t *r = (rndis_data_packet_t *)pnt;
+ if (len >= sizeof(rndis_data_packet_t))
+ if ( (r->MessageType == REMOTE_NDIS_PACKET_MSG) && (r->MessageLength <= len))
+ if ( (r->DataOffset + offsetof(rndis_data_packet_t, DataOffset) + r->DataLength) <= len)
+ {
+ pnt = &received[r->DataOffset + offsetof(rndis_data_packet_t, DataOffset)];
+ size = r->DataLength;
+ }
}
-#endif
+
+ bool accepted = false;
if (size)
{
struct pbuf *p = pbuf_alloc(PBUF_RAW, size, PBUF_POOL);
- bool accepted = true;
if (p)
{
memcpy(p->payload, pnt, size);
p->len = size;
accepted = tud_network_recv_cb(p);
- }
- if (!p || !accepted)
- {
- /* if a buffer couldn't be allocated or accepted by the callback, we must discard this packet */
- tud_network_recv_renew();
+ if (!accepted) pbuf_free(p);
}
}
+
+ if (!accepted)
+ {
+ /* if a buffer was never handled by user code, we must renew on the user's behalf */
+ tud_network_recv_renew();
+ }
}
bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
@@ -320,6 +414,11 @@ bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
}
}
+ if ( _netd_itf.ecm_mode && (ep_addr == _netd_itf.ep_notif) )
+ {
+ if (sizeof(notify.ecm_buf.header) == xferred_bytes) ecm_report(false);
+ }
+
return true;
}
@@ -337,7 +436,7 @@ void tud_network_xmit(struct pbuf *p)
if (!can_xmit)
return;
- len = CFG_TUD_NET_PACKET_PREFIX_LEN;
+ len = (_netd_itf.ecm_mode) ? 0 : CFG_TUD_NET_PACKET_PREFIX_LEN;
data = transmitted + len;
for(q = p; q != NULL; q = q->next)
@@ -347,23 +446,15 @@ void tud_network_xmit(struct pbuf *p)
len += q->len;
}
-#if CFG_TUD_NET == OPT_NET_RNDIS
- rndis_data_packet_t *hdr = (rndis_data_packet_t *)transmitted;
- memset(hdr, 0, sizeof(rndis_data_packet_t));
- hdr->MessageType = REMOTE_NDIS_PACKET_MSG;
- hdr->MessageLength = len;
- hdr->DataOffset = sizeof(rndis_data_packet_t) - offsetof(rndis_data_packet_t, DataOffset);
- hdr->DataLength = len - sizeof(rndis_data_packet_t);
-#elif CFG_TUD_NET == OPT_NET_EEM
- struct cdc_eem_packet_header *hdr = (struct cdc_eem_packet_header *)transmitted;
- /* append a fake CRC-32; the standard allows 0xDEADBEEF, which takes less CPU time */
- data[0] = 0xDE; data[1] = 0xAD; data[2] = 0xBE; data[3] = 0xEF;
- /* adjust length to reflect added fake CRC-32 */
- len += 4;
- hdr->bmType = 0; /* EEM Data Packet */
- hdr->length = len - sizeof(struct cdc_eem_packet_header);
- hdr->bmCRC = 0; /* Ethernet Frame CRC-32 set to 0xDEADBEEF */
-#endif
+ if (!_netd_itf.ecm_mode)
+ {
+ rndis_data_packet_t *hdr = (rndis_data_packet_t *)transmitted;
+ memset(hdr, 0, sizeof(rndis_data_packet_t));
+ hdr->MessageType = REMOTE_NDIS_PACKET_MSG;
+ hdr->MessageLength = len;
+ hdr->DataOffset = sizeof(rndis_data_packet_t) - offsetof(rndis_data_packet_t, DataOffset);
+ hdr->DataLength = len - sizeof(rndis_data_packet_t);
+ }
do_in_xfer(transmitted, len);
}
diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c
index 92d8d34ef..abe26ced3 100644
--- a/src/class/usbtmc/usbtmc_device.c
+++ b/src/class/usbtmc/usbtmc_device.c
@@ -263,17 +263,19 @@ void usbtmcd_init_cb(void)
bool usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length)
{
(void)rhport;
- TU_ASSERT(usbtmc_state.state == STATE_CLOSED);
uint8_t const * p_desc;
uint8_t found_endpoints = 0;
+ TU_VERIFY(itf_desc->bInterfaceClass == TUD_USBTMC_APP_CLASS);
+ TU_VERIFY(itf_desc->bInterfaceSubClass == TUD_USBTMC_APP_SUBCLASS);
+
#ifndef NDEBUG
- TU_ASSERT(itf_desc->bInterfaceClass == TUD_USBTMC_APP_CLASS);
- TU_ASSERT(itf_desc->bInterfaceSubClass == TUD_USBTMC_APP_SUBCLASS);
// Only 2 or 3 endpoints are allowed for USBTMC.
TU_ASSERT((itf_desc->bNumEndpoints == 2) || (itf_desc->bNumEndpoints ==3));
#endif
+ TU_ASSERT(usbtmc_state.state == STATE_CLOSED);
+
// Interface
(*p_length) = 0u;
p_desc = (uint8_t const *) itf_desc;
diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c
index 8db5005f4..7f2fe9793 100644
--- a/src/class/vendor/vendor_device.c
+++ b/src/class/vendor/vendor_device.c
@@ -168,6 +168,8 @@ void vendord_reset(uint8_t rhport)
bool vendord_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_len)
{
+ TU_VERIFY(TUSB_CLASS_VENDOR_SPECIFIC == itf_desc->bInterfaceClass);
+
// Find available interface
vendord_interface_t* p_vendor = NULL;
for(uint8_t i=0; i<CFG_TUD_VENDOR; i++)
diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h
index c37c19bad..70d0db942 100644
--- a/src/common/tusb_types.h
+++ b/src/common/tusb_types.h
@@ -139,6 +139,7 @@ typedef enum
TUSB_REQ_RCPT_OTHER
} tusb_request_recipient_t;
+// https://www.usb.org/defined-class-codes
typedef enum
{
TUSB_CLASS_UNSPECIFIED = 0 ,
@@ -178,6 +179,12 @@ typedef enum
typedef enum
{
+ APP_SUBCLASS_USBTMC = 0x03,
+ APP_SUBCLASS_DFU_RUNTIME = 0x01
+} app_subclass_type_t;
+
+typedef enum
+{
DEVICE_CAPABILITY_WIRELESS_USB = 0x01,
DEVICE_CAPABILITY_USB20_EXTENSION = 0x02,
DEVICE_CAPABILITY_SUPERSPEED_USB = 0x03,
diff --git a/src/device/dcd.h b/src/device/dcd.h
index f4e6edb95..99a0e01ca 100644
--- a/src/device/dcd.h
+++ b/src/device/dcd.h
@@ -89,7 +89,7 @@ typedef struct TU_ATTR_ALIGNED(4)
void dcd_init (uint8_t rhport);
// Interrupt Handler
-void dcd_irq_handler(uint8_t rhport) TU_ATTR_USED;
+void dcd_int_handler(uint8_t rhport);
// Enable device interrupt
void dcd_int_enable (uint8_t rhport);
@@ -106,10 +106,10 @@ void dcd_set_config (uint8_t rhport, uint8_t config_num);
// Wake up host
void dcd_remote_wakeup(uint8_t rhport);
-// Connect or disconnect D+/D- line pull-up resistor.
-// Defined in dcd source if MCU has internal pull-up.
-// Otherwise, may be defined in BSP.
+// Connect by enabling internal pull-up resistor on D+/D-
void dcd_connect(uint8_t rhport) TU_ATTR_WEAK;
+
+// Disconnect by disabling internal pull-up resistor on D+/D-
void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK;
//--------------------------------------------------------------------+
@@ -123,6 +123,10 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * re
// Configure endpoint's registers according to descriptor
bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc);
+// Close an endpoint.
+// Since it is weak, caller must TU_ASSERT this function's existence before calling it.
+void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) TU_ATTR_WEAK;
+
// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack
bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes);
diff --git a/src/device/usbd.c b/src/device/usbd.c
index 55d6aa7eb..26183c960 100644
--- a/src/device/usbd.c
+++ b/src/device/usbd.c
@@ -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) );
+ 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* desc_itf = (tusb_desc_interface_t*) 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];
- // Check if class is supported
- uint8_t drv_id;
- for (drv_id = 0; drv_id < USBD_CLASS_DRIVER_COUNT; drv_id++)
+ drv_len = 0;
+ if ( driver->open(rhport, desc_itf, &drv_len) )
{
- 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
+ TU_ASSERT( DRVID_INVALID == _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] );
- // 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;
+ TU_LOG2(" %s open\r\n", _usbd_driver[drv_id].name);
+ _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) );
+ // 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);
- mark_interface_endpoint(_usbd_dev.ep2drv, p_desc, itf_len, drv_id);
+ for(uint8_t i=1; i<desc_itf_assoc->bInterfaceCount; i++)
+ {
+ _usbd_dev.itf2drv[desc_itf->bInterfaceNumber+i] = drv_id;
+ }
+ }
- p_desc += itf_len; // next interface
+ 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
diff --git a/src/device/usbd.h b/src/device/usbd.h
index 6b31d8113..fcb4e5c5f 100644
--- a/src/device/usbd.h
+++ b/src/device/usbd.h
@@ -48,7 +48,7 @@ bool tud_init (void);
void tud_task (void);
// Interrupt handler, name alias to DCD
-#define tud_irq_handler dcd_irq_handler
+#define tud_int_handler dcd_int_handler
// Check if device is connected and configured
bool tud_mounted(void);
@@ -183,9 +183,9 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
#define TUD_CDC_DESCRIPTOR(_itfnum, _stridx, _ep_notif, _ep_notif_size, _epout, _epin, _epsize) \
/* Interface Associate */\
- 8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, CDC_COMM_PROTOCOL_ATCOMMAND, 0,\
+ 8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, CDC_COMM_PROTOCOL_NONE, 0,\
/* CDC Control Interface */\
- 9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, CDC_COMM_PROTOCOL_ATCOMMAND, _stridx,\
+ 9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, CDC_COMM_PROTOCOL_NONE, _stridx,\
/* CDC Header */\
5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0120),\
/* CDC Call */\
@@ -291,23 +291,23 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re
// Interface number, number of endpoints, EP string index, USB_TMC_PROTOCOL*, bulk-out endpoint ID,
// bulk-in endpoint ID
#define TUD_USBTMC_IF_DESCRIPTOR(_itfnum, _bNumEndpoints, _stridx, _itfProtocol) \
-/* Interface */ \
+ /* Interface */ \
0x09, TUSB_DESC_INTERFACE, _itfnum, 0x00, _bNumEndpoints, TUD_USBTMC_APP_CLASS, TUD_USBTMC_APP_SUBCLASS, _itfProtocol, _stridx
#define TUD_USBTMC_IF_DESCRIPTOR_LEN 9u
#define TUD_USBTMC_BULK_DESCRIPTORS(_epout, _epin, _bulk_epsize) \
-/* Endpoint Out */ \
-7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_bulk_epsize), 0u, \
-/* Endpoint In */ \
-7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_bulk_epsize), 0u
+ /* Endpoint Out */ \
+ 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_bulk_epsize), 0u, \
+ /* Endpoint In */ \
+ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_bulk_epsize), 0u
#define TUD_USBTMC_BULK_DESCRIPTORS_LEN (7u+7u)
/* optional interrupt endpoint */ \
// _int_pollingInterval : for LS/FS, expressed in frames (1ms each). 16 may be a good number?
#define TUD_USBTMC_INT_DESCRIPTOR(_ep_interrupt, _ep_interrupt_size, _int_pollingInterval ) \
-7, TUSB_DESC_ENDPOINT, _ep_interrupt, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_interrupt_size), 0x16
+ 7, TUSB_DESC_ENDPOINT, _ep_interrupt, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_interrupt_size), 0x16
#define TUD_USBTMC_INT_DESCRIPTOR_LEN (7u)
@@ -342,12 +342,14 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re
//------------- CDC-ECM -------------//
-// Length of template descriptor: 62 bytes
-#define TUD_CDC_ECM_DESC_LEN (9+5+5+13+7+9+7+7)
+// Length of template descriptor: 71 bytes
+#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 */\
@@ -358,8 +360,10 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re
13, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ETHERNET_NETWORKING, _mac_stridx, 0, 0, 0, 0, U16_TO_U8S_LE(_maxsegmentsize), U16_TO_U8S_LE(0), 0,\
/* Endpoint Notification */\
7, TUSB_DESC_ENDPOINT, _ep_notif, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_notif_size), 1,\
- /* CDC Data Interface */\
- 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 0, 2, TUSB_CLASS_CDC_DATA, 0, 0, 0,\
+ /* CDC Data Interface (default inactive) */\
+ 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 0, 0, TUSB_CLASS_CDC_DATA, 0, 0, 0,\
+ /* CDC Data Interface (alternative active) */\
+ 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum)+1), 1, 2, TUSB_CLASS_CDC_DATA, 0, 0, 0,\
/* Endpoint In */\
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
/* Endpoint Out */\
@@ -372,10 +376,10 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re
/* Windows XP */
#define TUD_RNDIS_ITF_CLASS TUSB_CLASS_CDC
#define TUD_RNDIS_ITF_SUBCLASS CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL
- #define TUD_RNDIS_ITF_PROTOCOL CDC_COMM_PROTOCOL_MICROSOFT_RNDIS
+ #define TUD_RNDIS_ITF_PROTOCOL 0xFF /* CDC_COMM_PROTOCOL_MICROSOFT_RNDIS */
#else
/* Windows 7+ */
- #define TUD_RNDIS_ITF_CLASS 0xE0
+ #define TUD_RNDIS_ITF_CLASS TUSB_CLASS_WIRELESS_CONTROLLER
#define TUD_RNDIS_ITF_SUBCLASS 0x01
#define TUD_RNDIS_ITF_PROTOCOL 0x03
#endif
@@ -408,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
diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h
index b9947044b..26b9700e8 100644
--- a/src/device/usbd_pvt.h
+++ b/src/device/usbd_pvt.h
@@ -38,6 +38,7 @@
//--------------------------------------------------------------------+
//bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc);
+void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr);
// Submit a usb transfer
bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes);
diff --git a/src/portable/espressif/esp32s2/dcd_esp32s2.c b/src/portable/espressif/esp32s2/dcd_esp32s2.c
index 126f3ea20..986df3b3b 100644
--- a/src/portable/espressif/esp32s2/dcd_esp32s2.c
+++ b/src/portable/espressif/esp32s2/dcd_esp32s2.c
@@ -190,9 +190,6 @@ void dcd_init(uint8_t rhport)
USB_ENUMDONEMSK_M |
USB_RESETDETMSK_M |
USB_DISCONNINTMSK_M;
-
- ESP_LOGV(TAG, "DCD init - Soft CONNECT");
- USB0.dctl &= ~USB_SFTDISCON_M; // Connect
}
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
@@ -216,18 +213,20 @@ void dcd_remote_wakeup(uint8_t rhport)
(void)rhport;
}
-// disconnect by disabling internal pull-up resistor on D+/D-
-void dcd_disconnect(uint8_t rhport)
-{
- USB0.dctl |= USB_SFTDISCON_M;
-}
-
// connect by enabling internal pull-up resistor on D+/D-
void dcd_connect(uint8_t rhport)
{
+ (void) rhport;
USB0.dctl &= ~USB_SFTDISCON_M;
}
+// disconnect by disabling internal pull-up resistor on D+/D-
+void dcd_disconnect(uint8_t rhport)
+{
+ (void) rhport;
+ USB0.dctl |= USB_SFTDISCON_M;
+}
+
/*------------------------------------------------------------------*/
/* DCD Endpoint port
*------------------------------------------------------------------*/
@@ -639,7 +638,7 @@ static void handle_epin_ints(void)
}
-static void dcd_int_handler(void* arg)
+static void _dcd_int_handler(void* arg)
{
(void) arg;
@@ -727,7 +726,7 @@ static void dcd_int_handler(void* arg)
void dcd_int_enable (uint8_t rhport)
{
(void) rhport;
- esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, (intr_handler_t) dcd_int_handler, NULL, &usb_ih);
+ esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, (intr_handler_t) _dcd_int_handler, NULL, &usb_ih);
}
void dcd_int_disable (uint8_t rhport)
diff --git a/src/portable/microchip/samd/dcd_samd.c b/src/portable/microchip/samd/dcd_samd.c
index 2c01f8017..bd61df86a 100644
--- a/src/portable/microchip/samd/dcd_samd.c
+++ b/src/portable/microchip/samd/dcd_samd.c
@@ -331,7 +331,7 @@ void maybe_transfer_complete(void) {
}
-void dcd_irq_handler (uint8_t rhport)
+void dcd_int_handler (uint8_t rhport)
{
(void) rhport;
diff --git a/src/portable/microchip/samg/dcd_samg.c b/src/portable/microchip/samg/dcd_samg.c
index 93d9029d6..7703ee0dc 100644
--- a/src/portable/microchip/samg/dcd_samg.c
+++ b/src/portable/microchip/samg/dcd_samg.c
@@ -138,9 +138,6 @@ void dcd_init (uint8_t rhport)
(void) rhport;
tu_memclr(_dcd_xfer, sizeof(_dcd_xfer));
-
- // Enable pull-up, disable transceiver
- UDP->UDP_TXVC = UDP_TXVC_PUON | UDP_TXVC_TXVDIS_Msk;
}
// Enable device interrupt
@@ -186,6 +183,23 @@ void dcd_remote_wakeup (uint8_t rhport)
(void) rhport;
}
+void dcd_connect(uint8_t rhport)
+{
+ (void) rhport;
+
+ // Enable pull-up, disable transceiver
+ UDP->UDP_TXVC = UDP_TXVC_PUON | UDP_TXVC_TXVDIS_Msk;
+}
+
+void dcd_disconnect(uint8_t rhport)
+{
+ (void) rhport;
+
+ // disable both pullup and transceiver
+ UDP->UDP_TXVC = UDP_TXVC_TXVDIS_Msk;
+}
+
+
//--------------------------------------------------------------------+
// Endpoint API
//--------------------------------------------------------------------+
@@ -333,7 +347,7 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
//--------------------------------------------------------------------+
// ISR
//--------------------------------------------------------------------+
-void dcd_irq_handler(uint8_t rhport)
+void dcd_int_handler(uint8_t rhport)
{
uint32_t const intr_mask = UDP->UDP_IMR;
uint32_t const intr_status = UDP->UDP_ISR & intr_mask;
diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c
index 389266217..95240f9f0 100644
--- a/src/portable/nordic/nrf5x/dcd_nrf5x.c
+++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c
@@ -373,7 +373,7 @@ void bus_reset(void)
_dcd.xfer[0][TUSB_DIR_OUT].mps = MAX_PACKET_SIZE;
}
-void dcd_irq_handler(uint8_t rhport)
+void dcd_int_handler(uint8_t rhport)
{
(void) rhport;
diff --git a/src/portable/nuvoton/nuc120/dcd_nuc120.c b/src/portable/nuvoton/nuc120/dcd_nuc120.c
index 050aea255..9195b8dbe 100644
--- a/src/portable/nuvoton/nuc120/dcd_nuc120.c
+++ b/src/portable/nuvoton/nuc120/dcd_nuc120.c
@@ -306,7 +306,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
ep->CFG |= USBD_CFG_CSTALL_Msk;
}
-void dcd_irq_handler(uint8_t rhport)
+void dcd_int_handler(uint8_t rhport)
{
(void) rhport;
diff --git a/src/portable/nuvoton/nuc121/dcd_nuc121.c b/src/portable/nuvoton/nuc121/dcd_nuc121.c
index df72cbb2d..edd1e14a7 100644
--- a/src/portable/nuvoton/nuc121/dcd_nuc121.c
+++ b/src/portable/nuvoton/nuc121/dcd_nuc121.c
@@ -312,7 +312,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
ep->CFG |= USBD_CFG_CSTALL_Msk;
}
-void dcd_irq_handler(uint8_t rhport)
+void dcd_int_handler(uint8_t rhport)
{
(void) rhport;
diff --git a/src/portable/nuvoton/nuc505/dcd_nuc505.c b/src/portable/nuvoton/nuc505/dcd_nuc505.c
index 3baed87c5..aceb6df09 100644
--- a/src/portable/nuvoton/nuc505/dcd_nuc505.c
+++ b/src/portable/nuvoton/nuc505/dcd_nuc505.c
@@ -112,8 +112,6 @@ static struct
uint16_t total_bytes;
} ctrl_in_xfer;
-static volatile bool configuration_changed;
-
static volatile struct xfer_ctl_t *current_dma_xfer;
@@ -219,7 +217,6 @@ static void bus_reset(void)
/* Reset USB device address */
USBD->FADDR = 0;
- configuration_changed = false;
current_dma_xfer = NULL;
}
@@ -305,7 +302,6 @@ void dcd_set_config(uint8_t rhport, uint8_t config_num)
{
(void) rhport;
(void) config_num;
- configuration_changed = true;
}
void dcd_remote_wakeup(uint8_t rhport)
@@ -435,7 +431,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
}
}
-void dcd_irq_handler(uint8_t rhport)
+void dcd_int_handler(uint8_t rhport)
{
(void) rhport;
@@ -579,15 +575,14 @@ void dcd_irq_handler(uint8_t rhport)
else if (cep_state & USBD_CEPINTSTS_STSDONEIF_Msk)
{
/* given ACK from host has happened, we can now set the address (if not already done) */
- if((USBD->FADDR != assigned_address) && (USBD->FADDR == 0)) USBD->FADDR = assigned_address;
-
- if (configuration_changed)
+ if((USBD->FADDR != assigned_address) && (USBD->FADDR == 0))
{
+ USBD->FADDR = assigned_address;
+
for (enum ep_enum ep_index = PERIPH_EPA; ep_index < PERIPH_MAX_EP; ep_index++)
{
if (USBD->EP[ep_index].EPCFG & USBD_EPCFG_EPEN_Msk) USBD->EP[ep_index].EPRSPCTL = USBD_EPRSPCTL_TOGGLE_Msk;
}
- configuration_changed = false;
}
USBD->CEPINTEN = USBD_CEPINTEN_SETUPPKIEN_Msk;
diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c
index 1d755ce63..21a678c66 100644
--- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c
+++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c
@@ -181,9 +181,7 @@ void dcd_init(uint8_t rhport)
LPC_USB->UDCAH = (uint32_t) _dcd.udca;
LPC_USB->DMAIntEn = (DMA_INT_END_OF_XFER_MASK /*| DMA_INT_NEW_DD_REQUEST_MASK*/ | DMA_INT_ERROR_MASK);
- sie_write(SIE_CMDCODE_DEVICE_STATUS, 1, 1); // connect
-
- // USB IRQ priority should be set by application previously
+ // Clear pending IRQ
NVIC_ClearPendingIRQ(USB_IRQn);
}
@@ -221,6 +219,18 @@ void dcd_remote_wakeup(uint8_t rhport)
(void) rhport;
}
+void dcd_connect(uint8_t rhport)
+{
+ (void) rhport;
+ sie_write(SIE_CMDCODE_DEVICE_STATUS, 1, SIE_DEV_STATUS_CONNECT_STATUS_MASK);
+}
+
+void dcd_disconnect(uint8_t rhport)
+{
+ (void) rhport;
+ sie_write(SIE_CMDCODE_DEVICE_STATUS, 1, 0);
+}
+
//--------------------------------------------------------------------+
// CONTROL HELPER
//--------------------------------------------------------------------+
@@ -498,7 +508,7 @@ static void dd_complete_isr(uint8_t rhport, uint8_t ep_id)
}
// main USB IRQ handler
-void dcd_irq_handler(uint8_t rhport)
+void dcd_int_handler(uint8_t rhport)
{
uint32_t const dev_int_status = LPC_USB->DevIntSt & LPC_USB->DevIntEn;
LPC_USB->DevIntClr = dev_int_status;// Acknowledge handled interrupt
diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c
index 9af8e6019..c1f80185b 100644
--- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c
+++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c
@@ -95,7 +95,7 @@ enum {
CMDSTAT_DEVICE_ADDR_MASK = TU_BIT(7 )-1,
CMDSTAT_DEVICE_ENABLE_MASK = TU_BIT(7 ),
CMDSTAT_SETUP_RECEIVED_MASK = TU_BIT(8 ),
- CMDSTAT_DEVICE_CONNECT_MASK = TU_BIT(16), ///< reflect the softconnect only, does not reflect the actual attached state
+ CMDSTAT_DEVICE_CONNECT_MASK = TU_BIT(16), ///< reflect the soft-connect only, does not reflect the actual attached state
CMDSTAT_DEVICE_SUSPEND_MASK = TU_BIT(17),
CMDSTAT_CONNECT_CHANGE_MASK = TU_BIT(24),
CMDSTAT_SUSPEND_CHANGE_MASK = TU_BIT(25),
@@ -209,6 +209,18 @@ void dcd_remote_wakeup(uint8_t rhport)
(void) rhport;
}
+void dcd_connect(uint8_t rhport)
+{
+ (void) rhport;
+ DCD_REGS->DEVCMDSTAT |= CMDSTAT_DEVICE_CONNECT_MASK;
+}
+
+void dcd_disconnect(uint8_t rhport)
+{
+ (void) rhport;
+ DCD_REGS->DEVCMDSTAT &= ~CMDSTAT_DEVICE_CONNECT_MASK;
+}
+
//--------------------------------------------------------------------+
// DCD Endpoint Port
//--------------------------------------------------------------------+
@@ -333,7 +345,7 @@ static void process_xfer_isr(uint32_t int_status)
}
}
-void dcd_irq_handler(uint8_t rhport)
+void dcd_int_handler(uint8_t rhport)
{
(void) rhport; // TODO support multiple USB on supported mcu such as LPC55s69
diff --git a/src/portable/nxp/transdimension/dcd_transdimension.c b/src/portable/nxp/transdimension/dcd_transdimension.c
index 2872f1435..539629c3d 100644
--- a/src/portable/nxp/transdimension/dcd_transdimension.c
+++ b/src/portable/nxp/transdimension/dcd_transdimension.c
@@ -322,7 +322,7 @@ void dcd_init(uint8_t rhport)
{
tu_memclr(&_dcd_data, sizeof(dcd_data_t));
- dcd_registers_t* const dcd_reg = _dcd_controller[rhport].regs;
+ dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
// Reset controller
dcd_reg->USBCMD |= USBCMD_RESET;
@@ -342,7 +342,6 @@ void dcd_init(uint8_t rhport)
dcd_reg->USBINTR = INTR_USB | INTR_ERROR | INTR_PORT_CHANGE | INTR_RESET | INTR_SUSPEND /*| INTR_SOF*/;
dcd_reg->USBCMD &= ~0x00FF0000; // Interrupt Threshold Interval = 0
- dcd_reg->USBCMD |= TU_BIT(0); // connect
}
void dcd_int_enable(uint8_t rhport)
@@ -376,6 +375,18 @@ void dcd_remote_wakeup(uint8_t rhport)
(void) rhport;
}
+void dcd_connect(uint8_t rhport)
+{
+ dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
+ dcd_reg->USBCMD |= USBCMD_RUN_STOP;
+}
+
+void dcd_disconnect(uint8_t rhport)
+{
+ dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
+ dcd_reg->USBCMD &= ~USBCMD_RUN_STOP;
+}
+
//--------------------------------------------------------------------+
// HELPER
//--------------------------------------------------------------------+
@@ -492,7 +503,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t
//--------------------------------------------------------------------+
// ISR
//--------------------------------------------------------------------+
-void dcd_irq_handler(uint8_t rhport)
+void dcd_int_handler(uint8_t rhport)
{
dcd_registers_t* const dcd_reg = _dcd_controller[rhport].regs;
diff --git a/src/portable/sony/cxd56/dcd_cxd56.c b/src/portable/sony/cxd56/dcd_cxd56.c
index 320b7237e..7fd630384 100644
--- a/src/portable/sony/cxd56/dcd_cxd56.c
+++ b/src/portable/sony/cxd56/dcd_cxd56.c
@@ -201,6 +201,18 @@ void dcd_remote_wakeup(uint8_t rhport)
DEV_WAKEUP(usbdev);
}
+void dcd_connect(uint8_t rhport)
+{
+ (void) rhport;
+ DEV_CONNECT(usbdev);
+}
+
+void dcd_disconnect(uint8_t rhport)
+{
+ (void) rhport;
+ DEV_DISCONNECT(usbdev);
+}
+
//--------------------------------------------------------------------+
// Endpoint API
//--------------------------------------------------------------------+
diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
index 2939e5ae2..dbc1e6952 100644
--- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
@@ -63,19 +63,16 @@
* Current driver limitations (i.e., a list of features for you to add):
* - STALL handled, but not tested.
* - Does it work? No clue.
- * - All EP BTABLE buffers are created as max 64 bytes.
- * - Smaller can be requested, but it has to be an even number.
+ * - All EP BTABLE buffers are created based on max packet size of first EP opened with that address.
* - No isochronous endpoints
* - Endpoint index is the ID of the endpoint
* - This means that priority is given to endpoints with lower ID numbers
* - Code is mixing up EP IX with EP ID. Everywhere.
- * - No way to close endpoints; Can a device be reconfigured without a reset?
* - Packet buffer memory is copied in the interrupt.
* - This is better for performance, but means interrupts are disabled for longer
* - DMA may be the best choice, but it could also be pushed to the USBD task.
* - No double-buffering
* - No DMA
- * - No provision to control the D+ pull-up using GPIO on devices without an internal pull-up.
* - Minimal error handling
* - Perhaps error interrupts should be reported to the stack, or cause a device reset?
* - Assumes a single USB peripheral; I think that no hardware has multiple so this is fine.
@@ -131,15 +128,16 @@
* Configuration
*****************************************************/
-// HW supports max of 8 endpoints, but this can be reduced to save RAM
+// HW supports max of 8 bidirectional endpoints, but this can be reduced to save RAM
+// (8u here would mean 8 IN and 8 OUT)
#ifndef MAX_EP_COUNT
-# define MAX_EP_COUNT 8u
+# define MAX_EP_COUNT 8U
#endif
// If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it
// Both of these MUST be a multiple of 2, and are in byte units.
#ifndef DCD_STM32_BTABLE_BASE
-# define DCD_STM32_BTABLE_BASE 0u
+# define DCD_STM32_BTABLE_BASE 0U
#endif
#ifndef DCD_STM32_BTABLE_LENGTH
@@ -163,7 +161,9 @@ typedef struct
uint8_t * buffer;
uint16_t total_len;
uint16_t queued_len;
- uint16_t max_packet_size;
+ uint16_t pma_ptr;
+ uint8_t max_packet_size;
+ uint8_t pma_alloc_size;
} xfer_ctl_t;
static xfer_ctl_t xfer_status[MAX_EP_COUNT][2];
@@ -177,15 +177,19 @@ static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[6];
static uint8_t remoteWakeCountdown; // When wake is requested
-// EP Buffers assigned from end of memory location, to minimize their chance of crashing
// into the stack.
-static uint16_t ep_buf_ptr;
static void dcd_handle_bus_reset(void);
-static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, size_t wNBytes);
-static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, size_t wNBytes);
static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix);
static void dcd_ep_ctr_handler(void);
+// PMA allocation/access
+static uint8_t open_ep_count;
+static uint16_t ep_buf_ptr; ///< Points to first free memory location
+static void dcd_pma_alloc_reset(void);
+static uint16_t dcd_pma_alloc(uint8_t ep_addr, size_t length);
+static void dcd_pma_free(uint8_t ep_addr);
+static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, size_t wNBytes);
+static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, size_t wNBytes);
// Using a function due to better type checks
// This seems better than having to do type casts everywhere else
@@ -219,7 +223,7 @@ void dcd_init (uint8_t rhport)
asm("NOP");
}
USB->CNTR = 0; // Enable USB
-
+
USB->BTABLE = DCD_STM32_BTABLE_BASE;
reg16_clear_bits(&USB->ISTR, USB_ISTR_ALL_EVENTS); // Clear pending interrupts
@@ -231,12 +235,6 @@ void dcd_init (uint8_t rhport)
pcd_set_endpoint(USB,i,0u);
}
- // Initialize the BTABLE for EP0 at this point (though setting up the EP0R is unneeded)
- // This is actually not necessary, but helps debugging to start with a blank RAM area
- for(uint32_t i=0;i<(DCD_STM32_BTABLE_LENGTH>>1); i++)
- {
- pma[PMA_STRIDE*(DCD_STM32_BTABLE_BASE + i)] = 0u;
- }
USB->CNTR |= USB_CNTR_RESETM | USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM;
dcd_handle_bus_reset();
@@ -368,7 +366,7 @@ static void dcd_handle_bus_reset(void)
pcd_set_endpoint(USB,i,0u);
}
- ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8*MAX_EP_COUNT; // 8 bytes per endpoint (two TX and two RX words, each)
+ dcd_pma_alloc_reset();
dcd_edpt_open (0, &ep0OUT_desc);
dcd_edpt_open (0, &ep0IN_desc);
@@ -501,7 +499,7 @@ static void dcd_ep_ctr_handler(void)
}
}
-void dcd_irq_handler(uint8_t rhport) {
+void dcd_int_handler(uint8_t rhport) {
(void) rhport;
@@ -592,6 +590,85 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * re
}
}
+static void dcd_pma_alloc_reset(void)
+{
+ ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8*MAX_EP_COUNT; // 8 bytes per endpoint (two TX and two RX words, each)
+ //TU_LOG2("dcd_pma_alloc_reset()\r\n");
+ for(uint32_t i=0; i<MAX_EP_COUNT; i++)
+ {
+ xfer_ctl_ptr(i,TUSB_DIR_OUT)->pma_alloc_size = 0U;
+ xfer_ctl_ptr(i,TUSB_DIR_IN)->pma_alloc_size = 0U;
+ xfer_ctl_ptr(i,TUSB_DIR_OUT)->pma_ptr = 0U;
+ xfer_ctl_ptr(i,TUSB_DIR_IN)->pma_ptr = 0U;
+ }
+}
+
+/***
+ * Allocate a section of PMA
+ *
+ * If the EP number has already been allocated, and the new allocation
+ * is larger than the old allocation, then this will fail with a TU_ASSERT.
+ * (This is done to simplify the code. More complicated algorithms could be used)
+ *
+ * During failure, TU_ASSERT is used. If this happens, rework/reallocate memory manually.
+ */
+static uint16_t dcd_pma_alloc(uint8_t ep_addr, size_t length)
+{
+ uint8_t const epnum = tu_edpt_number(ep_addr);
+ uint8_t const dir = tu_edpt_dir(ep_addr);
+ xfer_ctl_t* epXferCtl = xfer_ctl_ptr(epnum,dir);
+
+ if(epXferCtl->pma_alloc_size != 0U)
+ {
+ //TU_LOG2("dcd_pma_alloc(%x,%x)=%x (cached)\r\n",ep_addr,length,epXferCtl->pma_ptr);
+ // Previously allocated
+ TU_ASSERT(length <= epXferCtl->pma_alloc_size, 0xFFFF); // Verify no larger than previous alloc
+ return epXferCtl->pma_ptr;
+ }
+
+ uint16_t addr = ep_buf_ptr;
+ ep_buf_ptr = (uint16_t)(ep_buf_ptr + length); // increment buffer pointer
+
+ // Verify no overflow
+ TU_ASSERT(ep_buf_ptr <= PMA_LENGTH, 0xFFFF);
+
+ epXferCtl->pma_ptr = addr;
+ epXferCtl->pma_alloc_size = length;
+ //TU_LOG2("dcd_pma_alloc(%x,%x)=%x\r\n",ep_addr,length,addr);
+
+ return addr;
+}
+
+/***
+ * Free a block of PMA space
+ */
+static void dcd_pma_free(uint8_t ep_addr)
+{
+ uint8_t const epnum = tu_edpt_number(ep_addr);
+ uint8_t const dir = tu_edpt_dir(ep_addr);
+
+ // Presently, this should never be called for EP0 IN/OUT
+ TU_ASSERT(open_ep_count > 2, /**/);
+ TU_ASSERT(xfer_ctl_ptr(epnum,dir)->max_packet_size != 0, /**/);
+ open_ep_count--;
+
+ // If count is 2, only EP0 should be open, so allocations can be mostly reset.
+
+ if(open_ep_count == 2)
+ {
+ ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8*MAX_EP_COUNT + 2*CFG_TUD_ENDPOINT0_SIZE; // 8 bytes per endpoint (two TX and two RX words, each), and EP0
+
+ // Skip EP0
+ for(uint32_t i=1; i<MAX_EP_COUNT; i++)
+ {
+ xfer_ctl_ptr(i,TUSB_DIR_OUT)->pma_alloc_size = 0U;
+ xfer_ctl_ptr(i,TUSB_DIR_IN)->pma_alloc_size = 0U;
+ xfer_ctl_ptr(i,TUSB_DIR_OUT)->pma_ptr = 0U;
+ xfer_ctl_ptr(i,TUSB_DIR_IN)->pma_ptr = 0U;
+ }
+ }
+}
+
// The STM32F0 doesn't seem to like |= or &= to manipulate the EP#R registers,
// so I'm using the #define from HAL here, instead.
@@ -601,28 +678,30 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc
uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress);
uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress);
const uint16_t epMaxPktSize = p_endpoint_desc->wMaxPacketSize.size;
+ uint16_t pma_addr;
+ uint32_t wType;
+
// Isochronous not supported (yet), and some other driver assumptions.
-
TU_ASSERT(p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS);
TU_ASSERT(epnum < MAX_EP_COUNT);
// Set type
switch(p_endpoint_desc->bmAttributes.xfer) {
case TUSB_XFER_CONTROL:
- pcd_set_eptype(USB, epnum, USB_EP_CONTROL);
+ wType = USB_EP_CONTROL;
break;
#if (0)
case TUSB_XFER_ISOCHRONOUS: // FIXME: Not yet supported
- pcd_set_eptype(USB, epnum, USB_EP_ISOCHRONOUS); break;
+ wType = USB_EP_ISOCHRONOUS;
break;
#endif
case TUSB_XFER_BULK:
- pcd_set_eptype(USB, epnum, USB_EP_BULK);
+ wType = USB_EP_CONTROL;
break;
case TUSB_XFER_INTERRUPT:
- pcd_set_eptype(USB, epnum, USB_EP_INTERRUPT);
+ wType = USB_EP_INTERRUPT;
break;
default:
@@ -630,32 +709,59 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc
return false;
}
+ pcd_set_eptype(USB, epnum, wType);
pcd_set_ep_address(USB, epnum, epnum);
// Be normal, for now, instead of only accepting zero-byte packets (on control endpoint)
// or being double-buffered (bulk endpoints)
pcd_clear_ep_kind(USB,0);
+ pma_addr = dcd_pma_alloc(p_endpoint_desc->bEndpointAddress, p_endpoint_desc->wMaxPacketSize.size);
+
if(dir == TUSB_DIR_IN)
{
- *pcd_ep_tx_address_ptr(USB, epnum) = ep_buf_ptr;
+ *pcd_ep_tx_address_ptr(USB, epnum) = pma_addr;
pcd_set_ep_tx_cnt(USB, epnum, p_endpoint_desc->wMaxPacketSize.size);
pcd_clear_tx_dtog(USB, epnum);
pcd_set_ep_tx_status(USB,epnum,USB_EP_TX_NAK);
}
else
{
- *pcd_ep_rx_address_ptr(USB, epnum) = ep_buf_ptr;
+ *pcd_ep_rx_address_ptr(USB, epnum) = pma_addr;
pcd_set_ep_rx_cnt(USB, epnum, p_endpoint_desc->wMaxPacketSize.size);
pcd_clear_rx_dtog(USB, epnum);
pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_NAK);
}
xfer_ctl_ptr(epnum, dir)->max_packet_size = epMaxPktSize;
- ep_buf_ptr = (uint16_t)(ep_buf_ptr + p_endpoint_desc->wMaxPacketSize.size); // increment buffer pointer
return true;
}
+/**
+ * Close an endpoint.
+ *
+ * This function may be called with interrupts enabled or disabled.
+ *
+ * This also clears transfers in progress, should there be any.
+ */
+void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr)
+{
+ (void)rhport;
+ uint32_t const epnum = tu_edpt_number(ep_addr);
+ uint32_t const dir = tu_edpt_dir(ep_addr);
+
+ if(dir == TUSB_DIR_IN)
+ {
+ pcd_set_ep_tx_status(USB,epnum,USB_EP_TX_DIS);
+ }
+ else
+ {
+ pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_DIS);
+ }
+
+ dcd_pma_free(ep_addr);
+}
+
// Currently, single-buffered, and only 64 bytes at a time (max)
static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix)
diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c
index dc752b37a..0c9c2650d 100644
--- a/src/portable/st/synopsys/dcd_synopsys.c
+++ b/src/portable/st/synopsys/dcd_synopsys.c
@@ -209,10 +209,6 @@ void dcd_init (uint8_t rhport)
// Enable USB transceiver.
USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_PWRDWN;
-
- // Soft Connect -> Enable pullup on D+/D-.
- // This step does not appear to be specified in the programmer's model.
- dev->DCTL &= ~USB_OTG_DCTL_SDIS;
}
void dcd_int_enable (uint8_t rhport)
@@ -250,6 +246,23 @@ void dcd_remote_wakeup(uint8_t rhport)
(void) rhport;
}
+void dcd_connect(uint8_t rhport)
+{
+ (void) rhport;
+ USB_OTG_DeviceTypeDef * dev = DEVICE_BASE;
+
+ dev->DCTL &= ~USB_OTG_DCTL_SDIS;
+}
+
+void dcd_disconnect(uint8_t rhport)
+{
+ (void) rhport;
+ USB_OTG_DeviceTypeDef * dev = DEVICE_BASE;
+
+ dev->DCTL |= USB_OTG_DCTL_SDIS;
+}
+
+
/*------------------------------------------------------------------*/
/* DCD Endpoint port
*------------------------------------------------------------------*/
@@ -656,7 +669,7 @@ static void handle_epin_ints(USB_OTG_DeviceTypeDef * dev, USB_OTG_INEndpointType
}
}
-void dcd_irq_handler(uint8_t rhport) {
+void dcd_int_handler(uint8_t rhport) {
(void) rhport;
diff --git a/src/portable/template/dcd_template.c b/src/portable/template/dcd_template.c
index d29c98e55..ba1383f31 100644
--- a/src/portable/template/dcd_template.c
+++ b/src/portable/template/dcd_template.c
@@ -91,6 +91,18 @@ void dcd_remote_wakeup (uint8_t rhport)
(void) rhport;
}
+// Connect by enabling internal pull-up resistor on D+/D-
+void dcd_connect(uint8_t rhport)
+{
+ (void) rhport;
+}
+
+// Disconnect by disabling internal pull-up resistor on D+/D-
+void dcd_disconnect(uint8_t rhport)
+{
+ (void) rhport;
+}
+
//--------------------------------------------------------------------+
// Endpoint API
//--------------------------------------------------------------------+
diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c
index edccec33f..da75a7f3f 100644
--- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c
+++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c
@@ -134,9 +134,6 @@ void dcd_init (uint8_t rhport)
// Enable reset and wait for it before continuing.
USBIE |= RSTRIE;
- // Enable pullup.
- USBCNF |= PUR_EN;
-
USBKEYPID = 0;
}
@@ -207,6 +204,28 @@ void dcd_remote_wakeup(uint8_t rhport)
(void) rhport;
}
+void dcd_connect(uint8_t rhport)
+{
+ dcd_int_disable(rhport);
+
+ USBKEYPID = USBKEY;
+ USBCNF |= PUR_EN; // Enable pullup.
+ USBKEYPID = 0;
+
+ dcd_int_enable(rhport);
+}
+
+void dcd_disconnect(uint8_t rhport)
+{
+ dcd_int_disable(rhport);
+
+ USBKEYPID = USBKEY;
+ USBCNF &= ~PUR_EN; // Disable pullup.
+ USBKEYPID = 0;
+
+ dcd_int_enable(rhport);
+}
+
/*------------------------------------------------------------------*/
/* DCD Endpoint port
*------------------------------------------------------------------*/
@@ -539,7 +558,7 @@ static void handle_setup_packet(void)
dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true);
}
-void dcd_irq_handler(uint8_t rhport)
+void dcd_int_handler(uint8_t rhport)
{
(void) rhport;
diff --git a/src/portable/valentyusb/eptri/dcd_eptri.c b/src/portable/valentyusb/eptri/dcd_eptri.c
index 1054e71d6..8dde874fc 100644
--- a/src/portable/valentyusb/eptri/dcd_eptri.c
+++ b/src/portable/valentyusb/eptri/dcd_eptri.c
@@ -397,6 +397,19 @@ void dcd_remote_wakeup(uint8_t rhport)
(void) rhport;
}
+void dcd_connect(uint8_t rhport)
+{
+ (void) rhport;
+ usb_pullup_out_write(1);
+}
+
+void dcd_disconnect(uint8_t rhport)
+{
+ (void) rhport;
+ usb_pullup_out_write(0);
+}
+
+
//--------------------------------------------------------------------+
// DCD Endpoint Port
//--------------------------------------------------------------------+
@@ -613,7 +626,7 @@ static void handle_setup(void)
usb_setup_ev_pending_write(1);
}
-void dcd_irq_handler(uint8_t rhport)
+void dcd_int_handler(uint8_t rhport)
{
(void)rhport;
uint8_t next_ev;
diff --git a/src/tusb_option.h b/src/tusb_option.h
index 6e2a2f125..0826a5aab 100644
--- a/src/tusb_option.h
+++ b/src/tusb_option.h
@@ -124,15 +124,6 @@
#define OPT_MODE_HIGH_SPEED 0x10 ///< High speed
/** @} */
-/** \defgroup group_supported_netif Supported Network Interface
- * \ref CFG_TUD_NET must be defined to one of these
- * @{ */
-#define OPT_NET_NONE 0 ///< No network interface
-#define OPT_NET_ECM 1 ///< CDC-ECM
-#define OPT_NET_RNDIS 2 ///< RNDIS
-#define OPT_NET_EEM 3 ///< CDC-EEM
-/** @} */
-
#ifndef CFG_TUSB_RHPORT0_MODE
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE
#endif