按照WCH的文档描述,CH32V203的USBD和CAN公用了512字节的收发缓冲区,如果同时使用USBD和CAN,那么USBD使用的缓冲区不能超过384字节,也就是需要分128字节给CAN使用。按照地址来区分:
USBD使用[0x40006000,0x40006300),地址空间768B,实际384B可用
CAN1使用[0x40006300, 0x40006400),地址空间256B,实际128B可用
我的项目为使用CH32V203C8T6实现USBCAN卡,代码之前已经在其它厂家的ARM芯片上实现,运行一切正常。
USBCAN卡主要就是实现USB和CAN之间的数据转发,目前初步测试USB转发到CAN运行一切正常,反过来,从CAN转发到USB接口,转发几千帧以后,CAN接口就再也无法收到数据了。此时复位并重新初始化CAN接口可以重新收到数据。
CAN使用FIFO0接收,只要FIFO0有数据就触发中断,在中断中读取FIFO0中的全部数据。CAN接收与USBD公用一个ISR,CAN接收到的数据通过USB转发到PC,查看CAN的寄存器完全正常,和之前正常接收时并没有差异,USBD使用的缓冲区为336字节(0x150)小于384字节。CAN改为使用FIFO1接收,经过测试现象一样,也是几千帧以后CAN再也无法接收到数据。
尝试关闭USB接口的转发,即CAN接口收到数据以后,不再通过USB的IN端点转发出去,实测一切正常了,可以收到全部CAN接口上的数据。看起来还是USBD和CAN共享的缓冲区出了问题。
实际USB使用了3个端点,EP0,EP1,EP2,缓冲区描述表使用0x30个字节,EP0的发送接收分别使用0x40字节,EP1的发送接收分别使用0x10字节,EP2的发送接收分别使用0x40字节,总共使用的字节数为0x30+(0x40+0x10+0x40)*2=0x150字节,全部内容放在缓冲区的前面,后面地址留给CAN使用,地址0x40006000开始的缓冲区描述表内容如下,
memrd 40006000 0x40006000 30 00 00 00 18 00 00 00 70 00 00 00 00 84 00 00 0.......p....... 0x40006010 B0 00 00 00 D4 AD 00 00 C0 00 00 00 00 20 00 00 ............. .. 0x40006020 D0 00 00 00 E2 A9 00 00 10 01 00 00 FF 87 00 00 ................ 0x40006030 0A 89 00 00 40 D8 00 00 B1 8A 00 00 2E AE 00 00 ....@...........?
现在的感觉是USBD的IN端点数据发送破坏了CAN的数据接收,CH32V203的这个USBD外设从寄存器分布来看是和STM32F103兼容的,相比STM32F103增加和和CAN外设的兼容性,除了这一点还有没有其它不同?和CAN兼容是否还有需要注意的点?