本文转自公众号,欢迎关注
基于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中断之前该寄存器都是控制器所有。
审核编辑:汤梓红
-
寄存器
+关注
关注
31文章
5308浏览量
119975 -
usb
+关注
关注
60文章
7888浏览量
263919 -
dma
+关注
关注
3文章
559浏览量
100411 -
驱动开发
+关注
关注
0文章
130浏览量
12061 -
DWC2
+关注
关注
0文章
35浏览量
119
发布评论请先 登录
相关推荐
评论