stm32 usb

stm32 CDC设备,虚拟串口:

         实现将usb口收到的数据通过串口发送出去,串口收到的数据通过usb口发送出去。

stm32 usb_第1张图片

 stm32 usb_第2张图片

 

stm32 usb_第3张图片

端点数据接收发送分析:

 在端点的发送和接收前,首先需要配置端点的DFIFO,对于stm32 usb device总共支持6个IN/OUT端点(其中包括端点0),RXFIFO是一个共用的RAM段,TXFIFO对于每个端点有单独的RAM配置段。

FIFO结构如下图(实际RXFIFO和TXFIFO用了一段连续的RAM区)

stm32 usb_第4张图片

对于RXFIFO,固定地址为“0”, 然后上面是端点0的TXFIFO,依次是其他IN端点的FIFO,这个可以由用户去配置。

对应stm32官方例程代码如下:

(1)

(2)

(3)

 stm32 usb_第5张图片

In过程分析:

     对于device而言,in的过程就是一个数据发送的过程,需要将应用层数据发送到DFIFO(IN)上面即可,剩下的由usb硬件完成。

  (1)在上层usbd_cdc_interface.c文件中设置接收/发送 应用buff。

    stm32 usb_第6张图片

   (2) 在usbd_cdc.c中是实际的指向

stm32 usb_第7张图片

   (3) 周期性的判断有没有数据需要发送,如果有

     stm32 usb_第8张图片

   因为用户buff做成了一个环形队列,所有调用USBD_CDC_SetTxBuffer指定发送队列的起始地址和长度,

   调用USBD_CDC_TransmitPacket函数将数据发送出去。将USBD_CDC_TransmitPacket函数展开如下:

  stm32 usb_第9张图片

 然后调用到HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)函数

stm32 usb_第10张图片 

 再到USB_EPStartXfer函数,该函数是最底层的端点操作函数,此处只是完成的端点使能,

stm32 usb_第11张图片

 端点一使能,即会出发TXFIFO Empty中断,便会在Empty中断中执行将应用层数据放到IN DFIFO中,数据会自动的从usb总线发送出去。这一个In的过程就结束了。

Out过程分析:

 1) 设置端点fifo大小,其中第二个参数为

  

  2) 配置,并且使能Out端点

  在USBD_LL_OpenEP函数中用于配置端点的控制寄存器DOEPCTL,包含端点的大小,传输类型等,

  在USBD_LL_PrepareReceive函数中用于指定端点上层的接口属性,包括接收的用户buff地址,和其他(packet cnt 和size有些还没完全看懂),然后使能端点。

 stm32 usb_第12张图片

  3) 如果端点收到包数据,会先出发RxQLevel的中断,在该中断中将对应(out)端点中的数据读取的用户buff中,因为RXFIFO是共用的,所以读取fifo前需要先读取寄存器OTG_HS_GRXSTSR/OTG_HS_GRXSTSP,从而知道这个包数据是属于哪个端点的。

     这里面主要就是USB_ReadPacket函数将对应的fifo数据读取到应用层。

    stm32 usb_第13张图片

  4) 包数据接收完成后就会触发传输发成标志,然后在该中断中去处理用户buff中的数据。

      stm32 usb_第14张图片

 

 

 

 

stm32 usb_第15张图片

stm32 usb_第16张图片

stm32 usb_第17张图片

上面的pdev->pUserData)->Receive函数就是通过DMA将收到的应用层数据发送到串口上去。

 

差不多就这样的,很多地方还没有理解到,大致的流程应该就是这样的!

你可能感兴趣的:(协议)