USB设备主要四个描述符,分别是设备描述符(Device Descriptors),配置描述符(Configuration Descriptor),报告描述符(Configuration Descriptor),字符描述符(String Descriptors),相信做过USB开发都很熟悉,并且有各种工具生成描述符.
其中设备描述符没什么需要改的,基本上由硬件决定,因此老实上报硬件数据就是,除非想降低传输性能地去做?在TinyUSB内是这样的,唯一值得我们操作的大概只有VID/PID.
//--------------------------------------------------------------------+
// Device Descriptors
//--------------------------------------------------------------------+
tusb_desc_device_t const desc_device =
{
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = USB_BCD,
.bDeviceClass = 0x00,
.bDeviceSubClass = 0x00,
.bDeviceProtocol = 0x00,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = USB_VID,
.idProduct = USB_PID,
.bcdDevice = 0x0100,
.iManufacturer = 0x01,
.iProduct = 0x02,
.iSerialNumber = 0x03,
.bNumConfigurations = 0x01
};
生成结果是这样的.
配置描述符则由宏展开,事实上TinyUSB内置很多不同描述符模板,基于宏配置节约很多工作量.
uint8_t const desc_configuration[] =
{
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
// Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval
TUD_HID_DESCRIPTOR(ITF_NUM_HID, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 5)
};
他的内部包含接口描述符和端点描述符,这就是TinyUSB的魅力所在,比如添加一个其他,比如我增加两个串口,我需要改多少代码呢?看补丁.
diff --git a/Core/Inc/tusb_config.h b/Core/Inc/tusb_config.h
index 40b90ff..563b9fa 100644
--- a/Core/Inc/tusb_config.h
+++ b/Core/Inc/tusb_config.h
@@ -105,7 +105,7 @@
//------------- CLASS -------------//
#define CFG_TUD_HID 1
-#define CFG_TUD_CDC 0
+#define CFG_TUD_CDC 2
#define CFG_TUD_MSC 0
#define CFG_TUD_MIDI 0
#define CFG_TUD_VENDOR 0
@@ -113,6 +113,13 @@
// HID buffer size Should be sufficient to hold ID (if any) + Data
#define CFG_TUD_HID_EP_BUFSIZE 16
+// CDC FIFO size of TX and RX
+#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
+#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
+
+// CDC Endpoint transfer buffer size, more is faster
+#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
+
#ifdef __cplusplus
}
#endif
diff --git a/Core/Src/usb_descriptors.c b/Core/Src/usb_descriptors.c
index 791813f..8d0508a 100644
--- a/Core/Src/usb_descriptors.c
+++ b/Core/Src/usb_descriptors.c
@@ -47,9 +47,9 @@ tusb_desc_device_t const desc_device =
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = USB_BCD,
- .bDeviceClass = 0x00,
- .bDeviceSubClass = 0x00,
- .bDeviceProtocol = 0x00,
+ .bDeviceClass = TUSB_CLASS_MISC,
+ .bDeviceSubClass = MISC_SUBCLASS_COMMON,
+ .bDeviceProtocol = MISC_PROTOCOL_IAD,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = USB_VID,
@@ -98,12 +98,23 @@ uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance)
enum
{
ITF_NUM_HID,
+ ITF_NUM_CDC_0,
+ ITF_NUM_CDC_0_DATA,
+ ITF_NUM_CDC_1,
+ ITF_NUM_CDC_1_DATA,
ITF_NUM_TOTAL
};
-#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN)
+#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_HID * TUD_HID_DESC_LEN + CFG_TUD_CDC * TUD_CDC_DESC_LEN)
-#define EPNUM_HID 0x81
+#define EPNUM_HID 0x81
+#define EPNUM_CDC_0_NOTIF 0x82
+#define EPNUM_CDC_0_OUT 0x02
+#define EPNUM_CDC_0_IN 0x83
+
+#define EPNUM_CDC_1_NOTIF 0x84
+#define EPNUM_CDC_1_OUT 0x04
+#define EPNUM_CDC_1_IN 0x85
uint8_t const desc_configuration[] =
{
@@ -111,7 +122,13 @@ uint8_t const desc_configuration[] =
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
// Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval
- TUD_HID_DESCRIPTOR(ITF_NUM_HID, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 5)
+ TUD_HID_DESCRIPTOR(ITF_NUM_HID, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 5),
+
+ // 1st CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
+ TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_0, 0, EPNUM_CDC_0_NOTIF, 8, EPNUM_CDC_0_OUT, EPNUM_CDC_0_IN, 64),
+
+ // 2nd CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
+ TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1, 0, EPNUM_CDC_1_NOTIF, 8, EPNUM_CDC_1_OUT, EPNUM_CDC_1_IN, 64)
};
#if TUD_OPT_HIGH_SPEED
diff --git a/Makefile b/Makefile
index d9195bf..5712542 100644
--- a/Makefile
+++ b/Makefile
@@ -60,8 +60,9 @@ Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c \
Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c \
Middlewares/Third_Party/tinyusb/src/tusb.c \
Middlewares/Third_Party/tinyusb/src/class/hid/hid_device.c \
+Middlewares/Third_Party/tinyusb/src/class/cdc/cdc_device.c \
Middlewares/Third_Party/tinyusb/src/common/tusb_fifo.c \
Middlewares/Third_Party/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c \
Middlewares/Third_Party/tinyusb/src/device/usbd.c \
Middlewares/Third_Party/tinyusb/src/device/usbd_control.c
把CDC驱动文件拉进来,增加描述符,然后就好了,复合设备是不是简单又快捷.