基于DWC2的USB驱动开发-DOEP接收相关的DMA寄存器详解

描述

本文转自公众号,欢迎关注
基于DWC2的USB驱动开发-DOEP接收相关的DMA寄存器详解 (qq.com)

前言

前面我们详细介绍了发送即DIEP相关的一些寄存器,这一篇我们来看看接收即DOEP相关的一些寄存器。形式上DOEP和DIEP寄存器是类似的。不过我们看寄存器列表会发现DOEP会少一个寄存器DTXFSTSi ,

什么会少这个寄存器呢?

因为接收是所有端点共享一个接收缓冲区的,所以这里就没有DRXFSTSi 这个对应的寄存器来表示每个端点对应的接收缓冲区剩余可用空间了。发送是可以配置为每个端点独占一个缓冲区的所以有对应的寄存器。

虽然POEP少了一个寄存器,但是寄存器偏移地址上,还是和PIEP保持对应关系的,缺的位置还是预留了空间的,这对软件来说比较方便,所以一般IP的设计也要考虑软件的实现是否方便。

驱动开发

这一篇先来介绍DMA相关的寄存器,后面再讲剩余的寄存器,为什么DMA寄存器要单独讲,因为其很重要,了解其是如何设置,如何更新,什么阶段谁拥有等很重要,可以协助调试分析问题,并且DOEP和DIEP的DMA寄存器的行为有些许差异这点调试时是很重要的,所以这里重点讲。

DOEPDMAi

该寄存器的偏移地址是

0xB14 + i*20,虽然端点0的寄存器手册有单独描述,但是其偏移地址还是符合该表达式的,实际描述内容也是重复的。

这样所有的寄存器我们可以使用同样的宏来寻址

#define DOEP_DMA(n) (OTG_BASE + (0xb14 + (n)*0x20))

这也是IP设计寄存器地址设置要考虑的,方便软件编程。

我们来看手册的描述
驱动开发

如果是 Scatter/Gather DMA模式则该寄存器设置为描述符链表的地址,否则则设置接收缓冲区的地址,DMA接收到数据自动从RxFIFO搬运到该处。

注意该寄存器必须8字节对齐。

该值在OUT DONE,接收到数据产生中断后,软件可以回读其值,回读的值为设置的值偏移已经处理的描述符或者已经接收的字节数。

注意该寄存器写完后并不能立即回读,此时回读值为之前的值或者默认值,只有OUT DONE中断接收到数据之后才能回读,此时EPena硬件清零,回读的值已经是按照上述描述更新的值。

在软件设置该值(注意此时哪怕EPEna没有置位也是一样的)到OUT DONE中断之前该寄存器由控制器所有,此时软件不能再次写,回读也不能回读出写入的值。只有OUT DONE中断之后EPEna硬件自动清零后才能读会硬件更新的值,注意不是写入值,时硬件根据处理了多少描述符或者接受了多少数据递增后的值。

以下是实例

如下使用OUT端点2 设置

0x81012a0到DOEPDMAi ** ,** 0x81012a0是8字节对齐的,时描述符地址

执行完REG_DOEP_DMA(epnum) = (uint32_t)(pep->dma_addr);后回读DOEPDMAi****的值并没有更新,此时软件不能再写,回读也不能读出设置值

驱动开发

CTL寄存器的EPEna置位,SNAK变为了0表示不再NACK了,准备接收数据了

驱动开发

进入OUT DONE中断再来看

CTL寄存器的EPEna位硬件清零0.表示接收到了数据
驱动开发

此时DOEPDMAi 0x81012a0变为了0x81012a8,因为只有以一个描述符,所以处理完后偏移了8字节。

DOEPDMABi

该寄存器的偏移地址是

0xB1C + i*20

从上面可以看到

0x0000000变为了

0x8100d58

之前是0x0000000是因为设置完后并不能回读,实际的描述中对应的缓冲区是

0x8100d38,0x8100d58-0x8100d38正好是接收到的数据的长度。

驱动开发

总结

DMA相关的两个寄存器非常重要,可以帮助调试,但是要注意写入之后并不能马上回读,也不能再写,需要OUT DONE之后才能回读和重新写,写入该寄存器到OUT DONE中断之前该寄存器都是控制器所有。

审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分