CH32V307-USB虚拟串口的批量传输始末
以CH32V307为例,EVT中的SimulateCDC为USB模拟一个CDC串口的例程;
从端点描述符可以得知,USB设备是通过端点2与主机进行数据的收发,传输方式为批量传输;
其中,wMaxPackeSize字段描述端点支持的最大包长度,批量传输下,高速模式固定为512字节,全速模式可选8、16、32、64字节;
批量读数据 Bulk Read
批量读数据是设备向主机上传数据;由一个或多个IN事务组成,每个IN事务可分为令牌阶段、数据阶段和握手阶段;
当主机准备好接收数据时,会向设备发送IN令牌,若设备没有数据要上传,会响应NAK或STALL;
当设备有数据需要上传时,会将端点状态置为期望ACK;即端点控制寄存器MASK_UEP_T_RES段为0,表示设备DATA0/DATA1数据就绪并期望ACK;
这样当下一次主机的IN令牌来到时,数据的上传就开始了;
那么,主机如何判断设备此次上传什么时候结束呢,即如何判断是此次传输的最后一个IN事务?
最后一个IN事务分两种情况:
- 最后一个IN事务的数据长度小于端点支持的最大包长度,即主机收到的数据长度小于端点支持的最大包长度,那么主机认为数据已经上传完成;
- 最后一个IN事务的数据长度等于端点支持的最大包长度,这时设备需要额外发送一个0长度的数据包,告诉主机数据已经上传完成;
因此,设备在上传数据时需要增加数据长度的判断,
1、当此次IN事务上传的数据长度等于端点最大包长度时,将USB_Up_Pack0_Flag标志置位,表示可能需要发送额外的0长度数据包;
2、增加超时判断,确认此次IN事务是最后一个IN事务,然后额外上传一个0长度的数据包;
批量写数据 Bulk Write
批量写数据是主机向设备下发数据,由一个或多个OUT事务组成,每个OUT事务也分为令牌阶段、数据阶段和握手阶段;
当主机准备好数据要下发时,向设备发送OUT令牌,若设备成功接收数据并保存会在握手阶段响应ACK;若数据接收正确但是没有足够空间保存,则响应NAK;若数据接收正确但端点处于挂起状态,则响应STALL;若数据接收错误则不响应,让主机等待超时;