第一范文网 - 专业文章范例文档资料分享平台

USB3.0设计资源 cypress芯片程序解读

来源:用户分享 时间:2025/6/9 17:22:04 本文由loading 分享 下载这篇文档手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:xxxxxxx或QQ:xxxxxx 处理(尽可能给您提供完整文档),感谢您的支持与谅解。

再下去就是设置DMA的传输尺寸,这里都设为0表示无限大。

最后将一个全局变量,即标志置为1。表示现在这个传输已经激活,其实这个标志只在打印中用一下,表示可以开始打印了。还有就是在激活应用时,如果已激活,则直接停止而不是去再激活它。见程序 断开及复位时做了如下处理:

如果上文中的全局变量已设为标志,则停止应用,如果没设,则什么事也不做。停止应用中做的事情是删除DMA通道,重新配置EP1和EP80

注册了配置事件后,下面要将描述符设置一下。因为等一会USB连接好了后就会与PC交互,如果事先不设置好,则没办法做,所以要做在先。此时配置描述符并不表示已经和PC进行交互了,而是等到以后由芯片自动与之交谈。程序就不干预了。

设置超速设备描述符。 VID和PID在此,还有EP0的长度设为2^9=512与下文中有点矛盾啊? 设置高速设备描述符。 同上,EP0的长度设为64字节。 设置全速设备描述符吗?不设了,估计不支持全速设备吧。

设置BOS描述符。这叫二进制设备存储描述符,这个是超速设备才有的(好象1.1中没看到它)。 设置设备量化描述符,例如EP0支持64字节在这里定义的。设备类与子类也在这里有。指明了USB2.0。 设置超速设备配置描述符,这个描述符有点长,因为它要配置端口的情况。它含配置,接口,端点,而端点有两个。一个发送端点,一个接收端点。在接口描述符中就会指出有2个端点。而在端点描述符中会指出它是BULK型的传输,另外还有端点的地址,最大包长即0124超速。这个超速端点的公司描述符没有什么用。而2。0就没有这个公司描述符部分。 设置高速设备配置描述符(略—与超速差不多的) 设置全速设备配置描述符(略)

设置字符串0的描述符----这里主要是语言描述符。

设置字符串1的描述符---这里主要指制造厂名称,例如可以改为renywell

设置字符串2的描述符----这里指的是产品号,例如F3X。我们可以改为camara或任意 最后连接USB物理设备。此时枚举将正式开始进行。PC机将与设备进行交互了。

小结一下,主程序启动一个线程后,在这个线程的开始的第2个初始化非常之重要,在这个初始化中 做一些非常重要的事情,它先是将GPIF初始化了一下,并启动了状态机。然后将USB的回调函数设置了一下,SETUP注册了,但是没有什么用,配置设置注册了,起了一个很大的作用就是调用了

CyFxSlFifoApplnStart。在这个函数中配置了端点,创建了DMA通道(回调也就注册了)。设置通道为无究大尺寸。并将一个全局变量的标志置为1。配置注册后,它开始对USB进行配置。具体将各个描述符设置好。其中第一个设置好的就是设备描述符,在这里PID和VID都在这个描述符中,正因为它PC才能找到驱动程序。在将所有的描述符都设置好了后,就连接USB等着PC机与其交互了。

交互好了后,PC机就会发数据下来,UtoP这个DMA通道就会被启动。当一个缓冲区满了后就会有一个回调函数被调用。而这个回调函数就是在创建DMA通道时被注册的。于是回调函数中就要处理来的数据。它要将来的数据送到P端口去。就是UtoP

在这个回调函数中做的主要事情就是:

Status=CyU3PDmaChannelCommitBuffer(chHandle,input->buffer_p.count,0);

这个函数有点困难。它要把count个字节送到目的地去?按照注释,这是一个生产者事件通知回调函数,这个通知将在每一个缓冲区收到数据后被发出。这个缓冲区将不会被送到目的地除非这个缓冲区被明显地被committed. 这个调用将失败如果总线复位,USB断开或者有一个应用错误时。

我们再看定义时的注释:这个函数通常用于手动DMA通道中。这个函数发送当前DMA描述符中的缓冲区至消费者。它在CY_U3P_DMA_TYPE_MANUAL_IN通道中是无效的。这个数据的数量必须是严格的需

9

要发送给消费者socket的数量。另外这个API也用于AUTO通道为某一特殊的目的。它仅仅当消费者socket处于挂起状态时被调用。在其它所有的情况下,它将返回一个错误标志。这个API也用于承诺当前的消费者缓冲区在部分BUF挂起状态下-----SUSP_CONS_PARTIAL_BUF..

注意到的是这个回调函数传过来一个 *input变量。而这个结构中含有buffer的地址,实际数据个数,buffer的大小,例如可以很大,我们这里是1024。和状态。这4个参量。我们当前仅用了一个参量。下次调试时也许可以看一下这个buff中到底是些什么,是纯数据呢还是有什么长度之类的参量。好象记得buffer中含一个长度似的。

于是整个代码基本上看清了。

下面我们再看一个代码试试看,想找一个代码,让PC从一个端口发数据过来,然后由下位机将发下来的包全部求反后再发回去。在PC上,将编一个小程序,向某一端口发送1024个字节,然后从另一个端口读回来。看下位机是否有这个例程呢?

还真有这些例程。我们先看一个手动的。即回到PC的数据后,由手动将这些数据再送回去。再看一个自动的,即完全不用程序干预,将收到的自动送到PC上去。

如果我想将数据都求一下反该怎么办呢?好象DMA中也有这方面的不过看完这两个例程再说。好象讲到可以修改里面的数据再送回去的。这个可能是DMA的什么的。故在看例子之前,我们再看详细一下DMA方面的章节。

DMA定义了下列概念:socket,buffers and descriptors. 缓冲,描述符,和socket.

一个抽象的软件提供使得编程者无需太多关注下面的细节。抽象来看,DMA能在两个块中提供一个数据通道。

一个数据通道首先要定义。

一半是生产者块,另一半是消费者块。

生产者和消费者可以是:USB端点,GPIF II,SPI,UART等串口,MEMERY。 需要的缓冲数量必须指定。

DMA的类型必须定义以便于寻址公共数据传输的情形。 自动通道。

自动通道是数据流在生产者和消费者之间可以不间断地传输当这个通道建立起来并开始后。

在运行时,没有软件需要干预。软件仅仅负责为通道建立需要的资源,建立连接。当做好这些后,数据可以继续在这个通道上流动直到它停止或释放。 两种自动通道方式是支持

一种是自动通道一种是自动通道带提示的。

先看自动通道。DMA_TYPE_AUTO 这是完全自动的通道,它由一个生产者socket,一个消费者socket和一个预先定义的缓冲区数量来定义,每一个都是用户可编程的。

缓冲区是等尺寸的。缓冲区的数量由通道产生时指定好了。在内部缓冲区是循环链接由一个描述符链。 带提示的有一点点区别,仅仅的改变是在一个buffer被传送好后,一个事件被传给应用程序。缓冲区指针和数据大小传给了应用程序。当数据需要检查时这是有用的。例如想知道有多少数据被收集这类统计信息。 但要注意的是:

A真正的数据流是不会被阻碍的。DMA继续传输而不会中断。 B这个通知并不能用于去修改DMA缓冲区的内容。

一对多自动通道 多对一自动通道

手动通道

10

DMA_TYPE_MANUAL 这是需要CPU干预的。内部,这个通道有两个分开的描述列表。一个为生产者socket.另一个为消费者socket。在通道产生时,用户程序必须指明缓冲区的数量并注册一个回调函数。

当通道进行操作时,注册的回调函数被激活在一个数据缓冲被填充被生产者。在这个回调函数中,用户程序可以:

修改数据包的内容(数据包的大小不能变) 承担这个数据包,触发一个发送传输。 插入一个新的客制化的数据包进入数据流中。 丢弃当前的包而不发给消费者。

加一个固定大小的头或尾给接收包。这个头或尾的大小在创建时就指定好的。 从接收的包中移动一个固定大小的头或尾。

手动在通道 Manual IN Channel DMA_TYPE_MANUAL_IN这个选择是一个特殊的通道,此时CPU的固件是一个消费者。一个回调函数必须注册在通道创建时。当一个指定的缓冲区数量被传输出就会调用这个回调函数。 Manual Out Channel

DMA_TYPE_MANUAL_OUTP 这个通道是一个特殊的通道,此时CPU固件是数据的生产者。用户应用需要得到激活的数据缓冲,填充的缓冲然后承担它。 此外还有手动的一对多,和手动的多对一通道。

DMA需要的缓冲由通道函数处理。缓冲的数量(缓冲的个数及每个缓冲的大小)必须在通道建立时指定。如果通道产生成功,请求的缓冲将被成功地在内存中分配。它是从block pool中分配的。用户程序并不需要分配任何缓冲区。 有以下DMA的API函数: 创建和清除DMA通道 在DMA通道上建立数据传输。 挂起或恢复DMA通道。 放弃和复位DMA通道

接收数据指指定的缓冲(重载模式) 传送数据从指定的缓冲区(重载模式) 等当前的传输完成

取得数据缓冲区从DMA通道 承担数据缓冲区去传输 丢弃缓冲区从DMA通道。

有了以上基础上,我们再来看程序就方便多了: 这是一个手动传输的例子

Main()函数 唯一有关的是在初始化IO口时,用到串口。 应用定义的函数:生成一个进程。没有多少要讲的。 线程函数中:

首先,初始化串口,这里是UART。没有新的不同。 再就是CyFxBulkLpApplnInit(); 可能会在这里有很多事要做。 看来来是起动USB功能。

先是建立USB的DMA通道,这个是API函数过程不知道的。

然后是注册两个回调函数,一个是USB建立过程中的回调,一个是配置设置的回调 在配置回调中做了一些事主要是启动传输过程CyFxBulkLpApplnStart() 在这个过程中先得到USB的速率,然后将生产者端点使能(配置好)

11

再将消费者配置好。再创建一个DMA通道,在创建这个通道时,有下列参数要设置的 DMA的尺寸。

DMA的缓冲区个数,用了8个缓冲区 DMA生产者ID DMA的消费者ID

DMA传输模式 以字节为计算

DMA通知的事件:这是DMA的缓冲生产出来时发通知 通知的回调函数。 其它都为0

然后再将一个全局变量glIsApplnActive置为1。---注意到兰色部分都是在设置配置时回调中做的事。

然后,这个由线程函数的再继续做下去。应该配置USB描述符了吧。确实如此, 最后做的就是连接USB了。结束。

然后我们要看的恐怕只有回调函数要关注一下子了。很简单如下 Status=CyU3PDmaChannelCommitBuffer(chHandle,input->buffer_p.count,0); glDMARxCount++;

有一个问题是生产者是从PC机向USB的端口发一批数据过来。而DMA通道却只涉及到 CY_FX_EP_PRODUCER_SOCKET

哪么,这个DMA通道怎样将USB的OUT端口1与这个生产者联系起来的呢? 看下面的注释看是否明白一些:

Socket ID有两个部分组成,一个是IP号,一个是 socket号。每一个周边器件(peripheral)有一个固定的ID。例如LPP的ID号是0而PIB是1。USB输出是3,而USB输入是4。所以,输出应该是301而输入应该是401。但是看了后发现生产者是401 而消费者是301。比较奇怪。按手册上的说法,生产者是ingress.而消费者是engress.所以USB的OUT端点是生产者,而IN端点是消费者。Ingress它是以4开头的,因此,这个USB的输出端点就是401。而输入IN端点则是301。我们的回调函数是在生产者生产出一个buffer时,就启用了这个回调函数。

再看自动方式是如何运行的?

数据从PC机经OUT端点到生产者中。OUT端点实际上是设备端的接收端点。它是生产者。 然后自动的返回到IN端点,它是消费者。Ingress代表生产者。而Egress代表消费者。 OUT Ingress 生产者 端点01 Socket 401

看它开启的一个线程中做的工作就是将USB配置好。然后连接USB。当然在这个函数中早些时候,它将USB的事件设置回调函数加进去。

事件回调函数中将创建DMA通道之类的事情。主要区别在这里。估计回调函数也没有了因为是自动的。 这个回调函数中调用的函数是CyFxBulkLpAppInStart(). 首先仍是通过USB的速度取得缓冲区的长度。即1024。

然后要配置生产者的端点,它就是一个OUT端点1。再配置消费者端点,它的端点就是IN端点0X81

IN Egress 消费者 端点81 Socket 301 12

搜索更多关于: USB3.0设计资源 cypress芯片程序解读 的文档
USB3.0设计资源 cypress芯片程序解读.doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.diyifanwen.net/c5wmtk8dazv3uh255bmnx_3.html(转载请注明文章来源)
热门推荐
Copyright © 2012-2023 第一范文网 版权所有 免责声明 | 联系我们
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:xxxxxx 邮箱:xxxxxx@qq.com
渝ICP备2023013149号
Top