3.USB库移植
GD的USB库在
GD32F4xx\_Firmware\_Library\_V3.0.2\GD32F4xx\_Firmware\_Library\Firmware\GD32F4xx\_usb\_library
中,然后他们提供了demo,demo在
GD32F4xx\_Firmware\_Library\_V3.0.2\GD32F4xx\_Firmware\_Library\Examples\USB
里面,这里可以选,作为host还是device,然后device模式的时候有多种模式。
这里笔者使用的是device模式,和上位机的USB通信模式可以用cdc-acm也可以用hid。作为 cdc-acm的时候,对于上位机,它类似于一个高速的串口,如果是上位机运行linux,会容易开发一点。
这里可以识别到GD32的CDC\_ACM设备为high-speed,说明USB3300已经正常工作了。
然后测试收发
可以看到发送的内容都接收到了,说明USB 收发正常。
4.双USB CDC-ACM功能开发
所谓的双USB CDC-ACM,就是使用USB复合设备,一个USB设备上面有几种功能。最典型的应用的就是4G模块。
GD原生并不支持双USB CDC-ACM,不过他们给了一个复合设备的demo,是hid+打印机的,可以在GD32F4xx\_Firmware\_Library\Examples\USB\USB\_Device\composite\_dev\_hid\_printer找到它。然后网上有人基于STM32F7设计过多个USB
CDC-ACM复合设备
那么可以基于这些工程来进行GD32F427上面双USB CDC-ACM的开发。
GD的USB库跟ST的USB库整体框架差不多,看下面这个图就能明白。
endpoint是usb的最小通信单元,GD32F427的USBFS有8个endpoint,四收四发,USBHS有12个endpoint,6收6发。一个CDC-ACM需要三个endpoint,命令端口收一个,数据端口收发各一个。端点0的收发都不能占用,是用于USB匹配的。因此要实现两个USB-ACM复合,只能使用USBHS。
USB各个class从endpoint里面拿到数据之后可以根据各自协议的不同来实现协议解析,定长度传输等。CDC-ACM是最简单的,endpoint里面拿到的就是原始数据,不用转换。而像CDC-ECM这种,里面的数据则是要经过IP TCP(UDP)等协议转换之后才能给到应用层处理。
下面针对开发步骤进行说明。
1、模板使用的是GD的工程里面单USB
CDC-ACM的。新建一个源文件,比如叫做dual\_cdc\_acm.c,将cdc\_acm\_core.c里面的内容复制进去。
2、注意到USB的初始化函数
关注它最后两个参数,前面那个是USB描述信息,也就是给端点0用于与HOST端进行匹配的。后面那个是一系列回调函数,用于中断里面事务处理。这里新建两个结构体
3、修改USB描述信息,结构体usb\_desc\_dev
这里bDeviceClass要改为0xEF,意思是USB复合设备,然后bDeviceSubClass是USB\_CLASS\_CDC,也就是0x02,最后一个实测没什么影响。
修改config信息。这个config信息其实用一个大的数组来存放会更加灵活
这个dual\_cdc\_acm\_config\_desc的信息按照那篇基于STM32F7的多个USB
CDC-ACM复合设备的文档改就行。这些都是标准的。
4、改回调函数,其实重点改后两个,也就是数据收发的就行。GD的是只有一个cdc设备,要改成支持两个,就要判断一下数据是哪个端点来的,要发往哪个端点。
5、分配endpoint,对应两组CDC设备。
6、包装收发函数各一个给应用层调用。如果是在rtos下面使用,发送函数建议加个锁,以免并行的时候多个线程同时写endpoint里面的数据
完成这些步骤之后,可以写一回环的demo验证一下
编译,下载到开发板之后,插电脑,可以看到两个USB设备
然后可以用串口工具测试下收发。
可以看到回环测试成功,PC端发出去的数据跟收到的一样。
原作者:chenjie