基于DWC2的USB驱动开发-抽丝剥茧再论切换到状态阶段标志DOEPINTn.StsPhseRcvd

描述

本文转自公众号系列文章,欢迎关注
基于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原理基本类似,同时也介绍了其他一些相关中断位。

审核编辑 黄宇

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

全部0条评论

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

×
20
完善资料,
赚取积分