TinyUSB 各种描述符写法

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驱动文件拉进来,增加描述符,然后就好了,复合设备是不是简单又快捷.

发表评论

您的电子邮箱地址不会被公开。