[AT32F405] 【AT-START-F405测评】第二篇 使用USB-HS实现虚拟串口(CDC)

[复制链接]
 楼主| duanks 发表于 2024-5-24 20:30 | 显示全部楼层 |阅读模式
USB简介
雅特力已写好了非常好用的USB库,使我们无需考虑实现细节,但一些基础的内容任然需要了解
详细可以参考附件中的
AN57294 USB 101 An Introduction to Universal Serial Bus 2.0 (Chinese).pdf
usb_20.pdf
另外,在调试USB应用时,有两个很重要的软件可以帮助调试
Bus Hound监控电脑与设备的数据传输,直接对端口进行操作
USBlyzer查看设备描述符

在USB传输中,包含IN和OUT两个方向,从Host(电脑)到Device(开发板)为OUT,反之为IN,所有数据传输均只可由主机发起
所有的传输都通过端点进行,端点有一个一字节的标号,低4位标识序号,最高位表示方向(1=IN,0=OUT),例如0x81表示端点1为IN端点
端点有4种类型,control(控制),iso(同步),bulk(批量),interrupt(中断),具体描述可以看AN57294
CDC中使用了control端点(好像不用也行)和bulk端点

要知道USB设备具体是做什么的,我们需要使用描述符(Descriptor)来描述设备,其结构为一个长度+类型+内容的字符串
* Device Descriptor
  * USB版本号
  * 设备类
  * PID,VID等
* Configuration Descriptor
  * 该配置的接口数量
  * 配置编号
  * 供电等
* Interface Association Descriptor
  * 将同一功能的接口组合在一起,比如一个IAD将CDC类接口组合在一起,一个IAD将WINUSB接口组合在一起
* Interface Descriptor
  * 接口编号
  * 接口的具体类别(作用)
* Endpoint Descriptor
  * 端点类型
  * 端点大小等
* 字符串描述符
  * 在standard request->GET_DESCRIPTOR根据编号返回即可
* 类相关描述符
  * 比如CDC interface descriptor,具体看类相关的手册,如
    * CDC120-20101103-track.pdf
    * PSTN120.pdf

设置描述符
在写好描述符后,将其填入**usbd_desc_handler**结构体中,在连接电脑后,电脑首先会通过端点0发送setup包来请求描述符,这时USB库会自动返回对应的描述符

设置类的具体处理
首先是init_handler,在这里需要打开处端点0外的所有端点,做好OUT端点的接收,并初始化一些在连接时需要初始化的变量
在clear_handler中处理断开连接的的操作,比如关闭端点
在setup_handler中处理setup包,比如设置波特率,返回字符串等
在ept0_rx_handler中接收line coding数据
在in_handler和out_handler处理除端点0外其它端点数据
所有的类处理函数都放在usbd_class_handler结构体中

主要函数
在设置好描述符和处理函数后,调用usbd_init即可,所有数据处理均在回调函数中进行
* usbd_ept_recv接收OUT端点发来的数据,接收完成后由中断进入out_handler
* usbd_ept_send发送至IN端点,发送完成后进入in_handler,由于接收只能由主机发起,要处理好由于长期处于发送状态的超时问题

CDC类简介
CDC类使用一个中断IN端点处理串口命令(好像没有),一个BULK IN端点将串口接收的数据发送到电脑,一个BULK OUT端点将电脑发送的数据发输出串口
具体的CDC描述符如下
  1. USB_DEVICE_IF_DESC_LEN,       /* bLength: interface descriptor size */
  2. USB_DESCIPTOR_TYPE_INTERFACE, /* bDescriptorType: interface descriptor
  3.                                     type */
  4. 0x00,               /* bInterfaceNumber: number of interface */
  5. 0x00,               /* bAlternateSetting: alternate set */
  6. 0x01,               /* bNumEndpoints: number of endpoints */
  7. USB_CLASS_CODE_CDC, /* bInterfaceClass: CDC class code */
  8. 0x02, /* bInterfaceSubClass: subclass code, Abstract Control Model*/
  9. 0x01, /* bInterfaceProtocol: protocol code, AT Command */
  10. CDC_INT_INTERFACE_STR_IDX, /* iInterface: index of string descriptor */

  11. 0x05, /* bFunctionLength: size of this descriptor in bytes */
  12. USBD_CDC_CS_INTERFACE, /* bDescriptorType: CDC interface descriptor type
  13.                         */
  14. USBD_CDC_SUBTYPE_HEADER, /* bDescriptorSubtype: Header function
  15.                             Descriptor 0x00*/
  16. LBYTE(CDC_BCD_NUM),
  17. HBYTE(CDC_BCD_NUM), /* bcdCDC: USB class definitions for communications */

  18. 0x05, /* bFunctionLength: size of this descriptor in bytes */
  19. USBD_CDC_CS_INTERFACE, /* bDescriptorType: CDC interface descriptor type
  20.                         */
  21. USBD_CDC_SUBTYPE_CMF,  /* bDescriptorSubtype: Call Management function
  22.                             descriptor subtype 0x01 */
  23. 0x00,                  /* bmCapabilities: 0x00*/
  24. 0x01, /* bDataInterface: interface number of data class interface
  25.             optionally used for call management */

  26. 0x04, /* bFunctionLength: size of this descriptor in bytes */
  27. USBD_CDC_CS_INTERFACE, /* bDescriptorType: CDC interface descriptor type
  28.                         */
  29. USBD_CDC_SUBTYPE_ACM, /* bDescriptorSubtype: Abstract Control Management
  30.                             functional descriptor subtype 0x02 */
  31. 0x02, /* bmCapabilities: Support Set_Line_Coding and Get_Line_Coding
  32.             0x02 */

  33. 0x05, /* bFunctionLength: size of this descriptor in bytes */
  34. USBD_CDC_CS_INTERFACE, /* bDescriptorType: CDC interface descriptor type
  35.                         */
  36. USBD_CDC_SUBTYPE_UFD,  /* bDescriptorSubtype: Union Function Descriptor
  37.                             subtype 0x06 */
  38. 0x00, /* bControlInterface: The interface number of the communications
  39.             or data class interface 0x00 */
  40. 0x01, /* bSubordinateInterface0: interface number of first subordinate
  41.             interface in the union */

  42. USB_DEVICE_EPT_LEN, /* bLength: size of endpoint descriptor in bytes */
  43. USB_DESCIPTOR_TYPE_ENDPOINT, /* bDescriptorType: endpoint descriptor
  44.                                 type */
  45. CDC_INT_EPT, /* bEndpointAddress: the address of endpoint on usb
  46.                         device described by this descriptor */
  47. USB_EPT_DESC_INTERRUPT, /* bmAttributes: endpoint attributes */
  48. LBYTE(CDC_CMD_MAX),
  49. HBYTE(CDC_CMD_MAX), /* wMaxPacketSize: maximum packe
  50.                                         size this endpoint */
  51. CDC_HID_BINTERVAL_TIME, /* bInterval: interval for polling endpoint for
  52.                             data transfers */

  53. USB_DEVICE_IF_DESC_LEN,       /* bLength: interface descriptor size */
  54. USB_DESCIPTOR_TYPE_INTERFACE, /* bDescriptorType: interface descriptor
  55.                                     type */
  56. 0x01,                   /* bInterfaceNumber: number of interface */
  57. 0x00,                   /* bAlternateSetting: alternate set */
  58. 0x02,                   /* bNumEndpoints: number of endpoints */
  59. USB_CLASS_CODE_CDCDATA, /* bInterfaceClass: CDC-data class code */
  60. 0x00, /* bInterfaceSubClass: Data interface subclass code 0x00*/
  61. 0x00, /* bInterfaceProtocol: data class protocol code 0x00 */
  62. CDC_DATA_INTERFACE_STR_IDX, /* iInterface: index of string descriptor */

  63. USB_DEVICE_EPT_LEN, /* bLength: size of endpoint descriptor in bytes */
  64. USB_DESCIPTOR_TYPE_ENDPOINT, /* bDescriptorType: endpoint descriptor
  65.                                 type */
  66. CDC_BULK_IN_EPT, /* bEndpointAddress: the address of endpoint on
  67.                             usb device described by this descriptor */
  68. USB_EPT_DESC_BULK,    /* bmAttributes: endpoint attributes */
  69. LBYTE(CDC_IN_MAX),
  70. HBYTE(CDC_IN_MAX), /* wMaxPacketSize: maximum packe size
  71.                                         this endpoint */
  72. 0x00, /* bInterval: interval for polling endpoint for data transfers */

  73. USB_DEVICE_EPT_LEN, /* bLength: size of endpoint descriptor in bytes */
  74. USB_DESCIPTOR_TYPE_ENDPOINT, /* bDescriptorType: endpoint descriptor
  75.                                 type */
  76. CDC_BULK_OUT_EPT, /* bEndpointAddress: the address of endpoint on
  77.                             usb device described by this descriptor */
  78. USB_EPT_DESC_BULK,     /* bmAttributes: endpoint attributes */
  79. LBYTE(CDC_OUT_MAX),
  80. HBYTE(CDC_OUT_MAX), /* wMaxPacketSize: maximum packe
  81.                                         size this endpoint */
  82. 0x00, /* bInterval: interval for polling endpoint for data transfers */
串口收发流程
串口收发分别使用两个数组做双缓冲,串口/USB接收/发送完成后会自动接收/发送数据,此外,每隔20ms亦会进行数据处理
CDC.zip (9.53 MB, 下载次数: 44)

gangong 发表于 2024-10-28 19:59 | 显示全部楼层
点赞
黑心单片机 发表于 2024-11-16 19:31 | 显示全部楼层
我想要看你的串口双缓冲,这个我很需要
呐咯密密 发表于 2024-11-19 10:06 | 显示全部楼层
这个代码的格式错乱了,能更正一下吗?看着太累了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

33

主题

142

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部

33

主题

142

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部