Not enough USB endpoints? Not true! MCU with full USB endpoints can help you!
1. USB2.0 endpoint issues that are easily misleading
In the USB2.0 specification document, for device mode, the description of the USB endpoint address is as follows. It can be seen that the lower four bits are the USB2.0 endpoint number, which can be up to 16 endpoints. The highest bit (the eighth bit) is the endpoint direction, which can be either input or output.
There are two meanings here:
1. Each endpoint can be a unidirectional data transmission, that is, the endpoint is either input or output.
2. In USB2.0, each endpoint can support simultaneous bidirectional data transmission, that is, a maximum of 16 endpoints are supported, and data transmission can be input or output simultaneously.
But it also brings some misleading information:
1. However, when introducing MCU documents of some manufacturers, there will be descriptions of how many USB endpoints it has and whether it supports bidirectional data transmission. For example, "it has 8 USB endpoints and supports bidirectional data transmission". This may mean that endpoint 0 supports bidirectional data transmission, but other endpoints may be unidirectional. It may also mean that it supports bidirectional data transmission but not simultaneous bidirectional data transmission.
2. When developers use USB, especially when it is in device mode and requires a composite device, a series of problems may occur due to insufficient endpoints due to the above misleading information.
The endpoint in this article refers to: the endpoint can support both input and output bidirectional data transmission.
2. Introduction to USB peripherals
All of Xianji's current MCU series have USB peripherals that are 480Mbps high-speed USB2.0, and each endpoint in device mode supports simultaneous bidirectional communication, with a maximum of 16 full-blooded endpoints.
For example, the USB peripherals of the HPM5300 series are introduced as follows:
However, it should be noted that not all MCU series support the full maximum of 16 simultaneous bidirectional endpoints. For example, the earliest HPM6700 series, HPM6300 series, and HPM6200 series only support 8 simultaneous bidirectional endpoints.
The subsequent products such as HPM5300 series, HPM6800 series, and HPM6E00 series all have a maximum of 16 simultaneous bidirectional endpoints. You can see the IP feature macro definition in the HPM SDK as follows:
3. Verify the maximum endpoint implementation of the first
To verify whether 16 endpoints are reached, a CDC-type device can be used, with the HPM5300EVK as the platform. Of course, the HPM5301EVKlite can also be used.
Again, source code link:
https://github.com/RCSN/hpm_sdk_extra.git
The path is in demos/multi_cdc_acm_vcom.
To implement a USB CDC class device, two interfaces are required, one interface needs to have an INT endpoint, and the other interface needs an IN endpoint and an OUT endpoint. This can be summarized as requiring two input IN endpoints and one output OUT endpoint.
If each CDC needs to carry an INT endpoint, a maximum of 7 USB CDC class devices can be implemented (2 * 7 = 14 endpoints), leaving one endpoint unused.
The effect is as follows, 7 USB CDC class devices are implemented.
Seven CDC devices are turned on for sending and receiving at the same time
4. Implementation Principles and Steps
Here, the composite device of multiple CDCs is implemented using the cherryusb protocol stack, which has been mentioned many times in this public account. You can refer to the following articles:
《 Using cherryusb's vendor class driver to implement USB secondary screen 》
《 Using cherryusb to implement USB converter 》
《 Using cherryusb to implement DAP debugger 》
《 Using cherryusb to implement USB 4G network card 》
《 Cherryusb's USB host explanation 》
For this protocol stack, HPM SDK also provides a wealth of examples, covering three categories: host, device, and multi-device
The multi-channel CDC in this article also refers to the cherryusb example of hpm_sdk
Mainly cdc_acm and composite parts:
samples/cherryusb/cdc_acm/cdc_acm_vcom
This example provides the implementation of the cdc device
samples/cherryusb/composite/cdc_acm_hid_msc
This example provides the implementation of a composite device
This article does not elaborate on the USB principles and the internal implementation of the cherryusb protocol stack, but rather explains them with examples.
To implement a USB device, you must first perform an enumeration process with the host. The so-called enumeration process is actually the host continuously sending commands to request responses from the slave, such as USB descriptors (device descriptors, configuration descriptors, interface descriptors, endpoint descriptors, string descriptors, etc.)
In the cherryusb protocol stack, you don't need to care too much about the field description of the relevant descriptor, but define a related macro definition to open the fields that users only need to care about. For example, the following device descriptor defines USB_DEVICE_DESCRIPTOR_INIT
Cherryusb's USB descriptor setting is implemented using callbacks. When the USB request is a USB descriptor, the corresponding descriptor request callback will come in. The following introduces the USB descriptor settings in turn.
1. USB device descriptor
Refer to the composite device example:
The descriptor encapsulation uses USB_DEVICE_DESCRIPTOR_INIT, which needs to assign the USB version number, USB class and subclass, protocol code number (for composite devices, this field is 0xEF 0x02 0x01), manufacturer's VID PID number, etc.
Callback registration, other descriptor callbacks are implemented similarly.
From the USB packet capture, we can see that the host requests the device descriptor and the slave responds.
2. In CherryUSB, the above configuration descriptors, interface descriptors, and endpoint descriptors can all be concentrated in a descriptor array, and the corresponding descriptors are also implemented by macro definitions.
Configuration descriptor USB_CONFIG_DESCRIPTOR_INIT
Interface descriptor, endpoint descriptor CDC_ACM_DESCRIPTOR_INIT
The device descriptor needs to tell the total number of interfaces and the length of the endpoint descriptor.
Here the descriptor length is (9 + (CDC_ACM_DESCRIPTOR_LEN * MAX_CDC_COUNT))
9 represents the fixed length occupied by the configuration descriptor. The interface and endpoint descriptors required by the cdc require 66 bytes, and the total length required for the 7 cdcs implemented is 471
From the USB packet capture, there is no error in the descriptor implementation obtained
In terms of endpoint allocation, the in and out of cdc use bidirectional endpoints 1 to 7, while the INT endpoint uses endpoints 8 to 14.
In the descriptors of the cdc class (including IAD, interface descriptor, endpoint descriptor, etc.), the CDC_ACM_DESCRIPTOR_INIT macro is used. The user only needs to assign the starting interface offset address, three endpoint numbers, and the endpoint BULK length. Here, the first parameter represents the starting offset interface number. Because one cdc occupies two interfaces, each CDC needs to be offset by two.
The allocation of endpoints can also be seen in USB packet capture.
Next is the USB Device initialization related
1. The USB descriptor callback needs to be registered, the API is usbd_desc_register
2. Add two interfaces, as well as IN and OUT endpoint address registration and operation callback
3. USB device initialization usbd_initialize
IN and OUT data sending and receiving callback functions
It should be noted that for the registered USB event, the first receive transmission needs to be started when USBD_EVENT_CONFIGURED occurs
The above is the general implementation idea. For details, please refer to the provided source code.
V. Conclusion
1. All of Xianji's USB peripherals are 480Mbps high-speed USB2.0, and each endpoint in device mode supports simultaneous bidirectional communication, with a maximum of 16 endpoints. It also has built-in DMA, which can meet and realize most USB2.0 application scenarios with maximum efficiency.
2. Thanks to the open source of the cherryUSB protocol stack, USB has unlimited possibilities in MCU.