USB论坛
直播中

挽你何用

10年用户 981经验值
擅长:电源/新能源 MEMS/传感技术
私信 关注
[问答]

如何清除CYUSB3014的缓冲区数据?USB接口数据什么时候发送到电脑?

该芯片是CYUSB3014。工作模式下:GPIF II接口作为生产者,USB接口作为消费者。数据从外部FPGA进入GPIF II接口,然后通过USB 3.0接口发送到计算机软件。
请问:
1、如何清除GPIF II接口处对应的DMA BUFFER数据?当标志设置为满/非满状态时,一旦 DMA 缓冲区已满,标志信号就会指示它已满。清除DMA缓冲区数据后,相应的标志信号会改变吗?会不会变成非满状态?
2、如何清除USB 3.0接口对应的DMA BUFFER数据?
3、什么情况下USB 3.0接口会把缓冲的数据发送到电脑,需要接收电脑什么命令?

回帖(1)

王璐

2025-7-24 18:27:41

针对你关于 CYUSB3014(FX3)芯片在 GPIF II 作为生产者、USB 作为消费者模式下缓冲区清除和数据发送的问题,以下是详细解答:


核心概念回顾 (Producer-Consumer Model):



  • GPIF II (Producer): 负责从外部 FPGA 高速接收数据,填充到 FX3 的 Producer DMA Buffer

  • DMA Buffer: 这是 FX3 内部 SRAM 划分出来的一块内存区域,用于生产者(GPIF)和消费者(USB)之间的数据缓冲。

  • USB Core (Consumer): 负责将 Consumer DMA Buffer 中的数据通过 USB 3.0 接口传输到 PC 主机。


问题解答:




  1. 如何清除 GPIF II 接口处对应的 DMA BUFFER 数据 (Producer DMA Buffer)? FLAG信号如何变化?



    • 清除方法:不需要(通常也不能)直接手动"清除"或"擦除" Producer DMA Buffer 中的数据。数据的“清除”本质上是消费过程。

      • GPIF II (生产者) 将数据写入 Producer DMA Buffer。

      • USB Core (消费者) 通过 DMA 从 同一个 Producer DMA Buffer (在生产者-消费者模型中,这通常是共享的Sockets或DMA通道管理的缓冲区) 读取数据并通过USB发送出去。

      • 关键操作: 当 USB Core 成功将 Producer DMA Buffer 中的数据发送出去(或移动到后续缓冲区队列后),FX3 固件通过 DMA 通道回调函数 (DMA callback function) 获知该 Producer Buffer 已可用。

      • 在回调函数中,固件必须调用 CyU3PDmaChannelCommitBuffer() 或类似函数(依赖于你的 DMA 配置方式),将这个空的缓冲区重新提交 (Commit) 回给 GPIF II 的 DMA 通道。这一步是最关键的“清除”操作,它使得该缓冲区可以再次被 FPGA 写入。


    • FLAG信号变化:

      • 触发点: FLAG 信号反映的是 Producer DMA Buffer 队列的状态

      • 缓冲区满 -> 暂停: 当 FPGA 写入数据导致当前的 Producer DMA Buffer 已满,FX3 硬件会自动将相应的 FLAG 信号置为满状态 (通常是高电平或低电平,具体取决于你的 GPIF II 设计描述文件配置),通知 FPGA 暂停发送

      • 缓冲区释放 -> 恢复: 当固件调用 CyU3PDmaChannelCommitBuffer() 提交一个空的 Producer DMA Buffer 给 GPIF II DMA 通道后:

        • FX3 硬件检测到可用的空缓冲区出现(Producer DMA Buffer 队列不再满)。

        • FX3 硬件自动将对应的 FLAG 信号切换为非满状态 (通常是 FLAG 信号反转)。

        • 当 FPGA 检测到 FLAG 变为 非满状态,它就知道可以恢复向该通道发送数据。


      • 结论: 正确提交空缓冲区 (CyU3PDmaChannelCommitBuffer) 后,Producer DMA Buffer 状态变为“非满”,相应的 FLAG 信号会自动改变到非满状态





  2. 如何清除 USB 3.0 接口对应的 DMA BUFFER 数据 (Consumer DMA Buffer)?



    • 对于典型的流传输 (Bulk OUT 传输方向,数据 发送 到主机),USB 作为消费者侧也存在 DMA Buffer:

      • Producer -> Consumer Buffer: 当数据从 GPIF II 的 Producer DMA Buffer 传输过来,它会被 DMA 引擎移动到或复制到专门用于 USB OUT 端点Consumer DMA Buffer


    • 清除方法:

      • 数据“清除”的核心是数据被 USB 成功发送到主机并被主机确认

      • 主机主导发送: USB Core 只有在收到 PC 主机(USB Host)发出的 IN Token Packets (IN令牌包) 时,才会响应并将 Consumer DMA Buffer 中的数据发送出去。

      • 数据传输确认: 主机接收到数据包后,会回复一个 ACK (Acknowledgement) 包。

      • DMA 释放缓冲区:

        • 一旦 USB Core 接收到主机对发送出的数据包的 ACK

        • FX3 固件通过配置的 USB OUT 端点的回调函数 (USB Event Callback) 获知该 Consumer Buffer 中的数据已被成功发送并被主机确认。

        • 在这个回调函数中,固件必须调用 CyU3PDmaBufferDiscard() 或类似函数(可能需要 CyU3PDmaChannelGetBuffer() 配合使用)来回收 / 释放 (Discard/Release) 这个已经使用完毕的 Consumer DMA Buffer。

        • 固件在回收该缓冲区后,通常会立即调用 CyU3PDmaChannelCommitBuffer() 将这个空的 Consumer DMA Buffer 重新提交 (Commit) 给 USB OUT 端点。这一步是“清除”和复用缓冲区的关键,确保当主机下一次请求 IN 令牌时,FX3 有空的 Consumer Buffer 准备接收来自 Producer (GPIF II) 的新数据。


      • 总结: 清除/管理 Consumer DMA Buffer 的核心操作在固件的 USB OUT 端点完成回调函数中进行:CyU3PDmaBufferDiscard() (或等效操作) 回收已发送缓冲区 -> CyU3PDmaChannelCommitBuffer() 提交空缓冲区给端点等待下次传输。





  3. USB 3.0 接口把缓冲的数据发送到电脑的条件? 需要接收电脑什么命令?



    • 主要触发条件: USB Core 接收到 PC 主机 (USB Host) 发出的 IN Token Packet (IN令牌包)

      • IN Token含义: 主机发出 IN Token 表示它请求设备(FX3)发送数据。

      • Bulk OUT 端点行为: 对于配置为 Bulk OUT 端点(数据从设备 发送 到主机),在接收到主机发送给该端点的 IN Token 时:

        • 如果 USB Core 有已经准备好(或部分准备好)的有效数据 存在于已提交给该 OUT 端点的 Consumer DMA Buffer 中,

        • 它会立即响应这个 IN Token,将该缓冲区中的(部分)数据作为 DATA Packet 发送给主机。



    • 主机的作用:

      • 主机驱动发出请求: PC 端的 USB 设备驱动程序(如 Cypress 的 cyusb.sys 或 libusb 驱动)通过提交 URB (USB Request Block) 给 USB 核心驱动。对于读取设备数据的操作,驱动提交的是 Bulk OUT Transfer URB (读请求)

      • 主机控制器发送 IN Token: USB 主机控制器(硬件)根据核心驱动的调度,在合适的时机(基于 USB 总线的带宽分配和流控规则)向设备的特定 OUT 端点地址发送 IN Token


    • 缓冲区状态影响 (可选行为):

      • Flush on Commit: 在端点配置 (CyU3PSetEpCfg) 时,可以设置 CY_U3P_USB_EP_CFG_FLAG_FLUSH_ON_FULL(或其他相关标志,具体名称看 API Doc)。这意味着:

        • 如果你提交 (CyU3PDmaChannelCommitBuffer) 一个 非空但未完全填满 的 Consumer DMA Buffer 给 OUT 端点,

        • 并且之后没有新数据到来填充它使达到"满"状态,

        • FX3 USB Core 不会自动立即发送这个部分填满的缓冲区。

        • 必须等到主机下次发来 IN Token 时才会发送。


      • 禁用 Flush on Commit (推荐用于高性能): 不设置 FLUSH_ON_FULL 标志。这是最常见的配置。此时:

        • FX3 USB Core 会尝试积累数据以填满一个完整的最大包长度(例如 1024 bytes,取决于 wMaxPacketSize)再响应 IN Token,以达到最佳带宽利用率。

        • 仍然只在收到 IN Token 时发送数据包



    • 结论:

      • 必要条件: USB Core 必须接收到主机发出的、面向该OUT端点的 IN Token Packet 才会发送数据。

      • 充分条件: 有已提交给该 OUT 端点的 Consumer DMA Buffer 包含有效数据(无论是满的还是部分的)。在标准设置下,即使缓冲区是部分填满的,收到 IN Token 也会立即发送(除非配置了 FLUSH_ON_FULL 且缓冲区没满也没被显式刷新)。

      • 主机命令: 主机通过 USB 协议层发送的 IN Token 就是“发送数据”的命令。驱动层面表现为提交读取数据的 URB。





关键总结与建议:



  • 缓冲区管理在固件: GPIF Producer Buffer 和 USB Consumer Buffer 的管理主要都在 FX3 固件的 DMA 通道回调函数 中进行。Commit Buffer (提交空缓冲区给生产者/消费者) 是让数据流持续的关键。

  • FLAG 是硬件控制的: GPIF 的 FLAG 信号变化由 FX3 硬件根据 Producer Buffer 队列的空满状态自动管理。固件正确提交空 Buffer (CommitBuffer) 后,FLAG 会自动变为非满。

  • USB 数据发送是响应式的: IN Token 是主机请求设备的信号。FX3 只在收到 IN Token 时才会把准备好(在已提交的 Consumer Buffer 中)的数据发送出去。

  • 务必实现回调函数: 确保你的固件正确实现了:

    • GPIF 生产者端 DMA 通道的 PROD_CB 回调:收到数据(Buffer Full)后,你需要做的是把缓冲区 传递 给 USB 消费者端(使用 CyU3PDmaChannelSetSrcBuffer 或其他队列管理函数),而不是在此 Commit Producer Buffer。通常你会在 USB 消费完该数据后(在 USB 回调中)才去 Commit 相应的 Producer Buffer。

    • USB 消费者 (OUT Endpoint) 端 DMA 通道的完成回调:在此回调中 (USB_CB), 调用 CyU3PDmaBufferDiscard() (或其他等效操作) 释放刚发送完数据的 Consumer Buffer,然后立即调用 CyU3PDmaChannelCommitBuffer() 提交一个新的空 Consumer Buffer 给该端点,这样 USB Core 才能接收后续数据用于响应下一次 IN Token。


  • 参考 SDK 示例: Cypress FX3 SDK (如 cyfxbulklpautocyfxsyncslavefifo) 中的示例代码清晰展示了生产者和消费者 DMA 通道如何设置回调以及如何在回调中 CommitBuffer/Discard Buffer。仔细研究与你模式最接近的示例至关重要。


遵循上述原理和固件编程实践,就能确保数据从 FPGA 通过 GPIF II 进入 FX3,并在主机请求时顺畅地通过 USB 3.0 发送到 PC。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分