本文转自公众号系列文章,欢迎关注
基于DWC2的USB驱动开发-USB包详解 (qq.com)
一.前言
前面我们对SETUP完成标志DOEPINTn.SetUp进行了详细的分析,该标志用于表明SETUP阶段的完成,数据阶段(无数据阶段则是状态阶段)的开始。我们知道控制传输有三个阶段SETUP阶段,数据阶段,状态阶段,现在我们知道了什么时候由SETUP阶段转数据阶段,那么什么时候数据阶段转状态阶段呢? 这个问题就引出了我们继续这篇文章的分析。
我们发现本系列文章很多都是自然而然地问题引出的,然后针对问题去查找答案,以此来进行USB的学习和开发,相信这种状态是一种很好的状态,甚至很多人会有意犹未竟,追剧的感觉,解决一个问题又冒出一个问题,又促使继续深挖,搞技术就是要如此。
二.DOEPINTn.StsPhseRcvd
之前我们就讲了手册中的如下表格,对应的不同的控制传输的状态,但是当时还是云里雾里不甚理解,上一篇我们抽丝剥茧了解了Setup的含义,这一篇继续来分析StsPhseRcvd,把每一个bit的精确含义理解了,再来理解这个表格就容易了。
还是老规矩我们先来看手册的描述
定义就是StsPhseRcvd表示控制传输切换到了状态阶段。
只有Scatter Gather DMA模式,控制OUT端点有,顺便提一下本系列文章没有单独说明则都是针对Scatter Gather DMA模式。
下面也说明了本标志产生的条件是:控制器接收了控制写传输的数据阶段,主机发过来的所有数据,并搬运到了缓冲区中(注意并不是用户空间中,搬运到用户空间还需要XferCompl来指明,即上述Case D和Case E的区别)。表明主机由数据阶段切换到了状态阶段。
该中断后设备程序可以进行状态阶段的响应了。
这里顺便提一下控制器处理时DOEPINTn.StsPhseRcvd优先级高于DOEPINTn.Setup。
以上的说明还是不够精确,还是协议层面的描述,比如数据阶段切换到状态阶段到底是对应的具体的哪个节点呢,对应的是谁发了什么包之后呢?
编程手册中如下有描述,实际是数据OUT阶段之后,设备收到了IN令牌之后置该位。
是不是很熟悉,原来和Setup的置位原理是差不多的,也是设备端延迟确认。
同样的是因为OUT数据阶段,设备回了ACK之后,主机收没收到ACK,设备并不知道,主机下一步是不是需要重新OUT还是进入状态阶段设备也不知道,所以只能等主机发了IN才知道主机切换到了状态阶段。
如下所示
这里我们还是同样的会有一个疑问,为什么只有控制写的OUT端点有这个标志,为什么控读IN端点没有?
前面我们知道判断Setup完成的标志是,设备在SETUP后收到了OUT或者IN,
如果收到了OUT则表示SETUP阶段完成,开始控制写数据阶段,
如果收到了IN则表示SETUP阶段完成,可能是开始读数据阶段或无数据,直接进入状态阶段。因为是硬件判断的对于IN存在两种情况,所以硬件实际不好判断 ,所以交给软件去判断。
所以对于这几种模式软件操作流程如下:
所以对于控制读操作,SETUP完成后,软件就需要同时准备好OUT描述符以接收状态包,同时准备IN描述符以发送数据。数据和状态同时处理。
SETUP阶段 -> 数据和状态
对于控制写操作,SETUP完成后,软件准备OUT描述符以接收数据,StsPhseRcvd中断后再准备IN描述符发送状态包。数据阶段和状态阶段分开处理。
SETUP阶段-> 数据阶段 -> 状态阶段
对于无数据控制传输
SETUP完成后,准备IN描述符准备发送状态包。
SETUP阶段- -> 状态阶段
三.DOEPINTn.XferCompl/DIEPINTn.XferCompl
分别表示IN和OUT描述符已经被DMA处理,即RxFIFO的内容搬运到了用户空间,或者用户空间数据搬运到了TxFIFO。
注意这里DMA处理完和实际总线上数据发送和接收是两码事。
比如对于IN端点,XferCompl完成,只是表示用户数据搬运到了TxFIFO中,
下一次IN令牌,硬件才从TxFIFO中取出数据发送到总线上去。
这里注意如果TxFIFO中还有残留的之前的数据,则本次搬运到TxFIFO的数据还不会发送,要等后续的IN才会发送。
所以一般这里需要先Flush掉TxFIFO,保证下一次IN发送的就是本次的数据。
四. **DIEPINTn.INTknTX****FEmp /DOEPINTn.OUTTknEPdis **
五.驱动编写注意事项
设备软件必须等到StsPhseRcvd中断即主机发了IN才能切换到状态阶段,准备IN描述符准备发0长包。因为如果主机不发IN则主机可能还在数据阶段,此时设备并不能确认下一包就是IN。
同样的因为设备确认有滞后,实际是在IN令牌后才能进该中断,确认主机进入了状态阶段,所以对于该IN硬件是自动NAK的,
所以中断服务函数中软件除了EPEna之外还要CNAK,以在后续IN中硬件根据新设置的IN描述符响应状态包(0长包)。
注意IN端点,及时Flush掉TxFIFO,保证下一次IN,传输的是本次设置的IN描述符对应的数据。
六.总结
以上对DOEPINTn.StsPhseRcvd进行了详细的解析,和Setup原理基本类似,同时也介绍了其他一些相关中断位。
审核编辑 黄宇
-
usb
+关注
关注
60文章
7907浏览量
264124 -
驱动开发
+关注
关注
0文章
130浏览量
12067 -
DWC2
+关注
关注
0文章
35浏览量
120
发布评论请先 登录
相关推荐
评论