USB论坛
直播中

王桂兰

8年用户 1273经验值
私信 关注
[问答]

什么情况会导致BUFFER_RYD一直为低电平?

我们使用CYUSB4014 FX10芯片完成了BULK数据传输,我们想要将CYUSB4014 FX10的代码移植到CYUSB4024 FX20上,因此我们在官方网站下载最新的“mtb-example-fx20-uvc-uac-master”demo文件,将demo中的uva传输改为BULK传输,结果未能完成BULK数据传输。具体问题描述如下:
一、工程环境和版本信息
1、系统环境:win10专业版
2、版本号:22H2
3、APP VERSION
4014:
APP_VERSION: 01.00.00.0085
USBD_VERSION: 01.00.00.0090
HBDMA_VERS0.0028
4024:(来源:官网最新代码)
APP_VERSION: 01.00.02.0085
USBD_VERSION: 01.02.01.0093
HBDMA_VERSION: 01.02
4、传输协议:USB BULK
(4014和4024的工程源码见附件1和附件2)
二、问题具体表现
1、4024 USB_BILK传输失败
通过Bus Hound向USB发送命令,启动USB_BULK传输,在c++ streamer中检测是否成接收到USB_BULK数据,结果显示4014可以接收到USB_BULK数据,4024不能接收到USB_BULK数据。结果如下图:

2、BUFFER_RDY信号一直为低电平
按照“Detailed LVDS transaction diagram”中的流程,在完成“PHY and LINK training”后,BUFFER_RDY信号应该从低电平拉升到高电平,在4014工程中表现如此,但在4024工程中,BUFFE_RDY一直未被拉升到高电平。



在4014和4024工程中,通过串口输出如下信息:
Info:APP:Port 0 PHY Train Done******
Info:APP:Port 1 PHY Train Done******
Info:LVDS:LINK_TRAINING_STS0:0
Info:LVDS:LINK_TRAINING_STS1:0
这种信息是表示“PHY and LINK training”训练完成了吗?
还有什么情况会导致BUFFER_RYD一直为低电平?

回帖(1)

小黑羊

2025-8-18 16:41:50

BUFFER_RYD (通常代表 Buffer Ready) 信号持续为低电平表明 DMA 通道的消费者(USB 控制器)没有准备好接收来自生产者(你的固件)的数据。这意味着固件无法向 DMA 通道提交缓冲区,导致 BULK 数据传输阻塞。以下是导致 BUFFER_RYD 一直为低电平的常见原因及其排查方向,特别是针对你从 FX10 移植到 FX20 的场景:


核心原因分析 (Fx20 移植特有及通用原因)




  1. DMA 通道配置错误 (FX20 vs FX10 关键差异):



    • 错误的通道类型/模式: FX20 的 DMA 引擎比 FX10 更复杂、强大。确认你配置的 DMA 通道类型 (CyU3PDmaChannelConfig_t) 是否适合 BULK OUT 传输。

      • 对于从主机接收数据 (OUT Endpoint -> FX20 RAM):

        • MANUALMANUAL_OUT 模式通常是安全的起点。固件需要手动提交和回收缓冲区。

        • AUTO 模式理论上可以用,但需要固件作为 Producer 持续提供空的缓冲区给 DMA 引擎填充。如果配置为 AUTO 但固件没有提交足够的缓冲区,USB 控制器 (Consumer) 会因无缓冲区可用而拉低 BUFFER_RYD。


      • 仔细检查 cyu3pdma.h 中的 CyU3PDmaType_tCyU3PDmaMode_t 枚举,选择适合你场景的模式。 FX10 的配置可能不完全适用于 FX20。


    • 缓冲区大小/数量不足: CyU3PDmaChannelConfig_t 中的 size (每个缓冲区大小) 和 count (缓冲区数量) 设置不当。

      • 缓冲区大小必须至少等于 USB 端点描述符中定义的 wMaxPacketSize (通常 512 或 1024 用于 HS BULK)。确保 FX20 配置的 size >= 对应端点的 wMaxPacketSize

      • 缓冲区数量太少。USB 控制器处理数据需要时间,如果所有缓冲区都在处理中(还未被固件回收并重新提交),BUFFER_RYD 就会变低。尝试增加 count (例如 16, 32)。


    • 回调函数缺失或错误: CyU3PDmaChannelConfig_t 中的 cb 字段(CyU3PDmaCallback_t)必须正确设置。这个回调函数至关重要,它通知固件:

      • 对于 OUT 传输 (主机 -> FX20):当 DMA 通道填满一个缓冲区时触发 (CY_U3P_DMA_CB_RECV_CPLT),固件应在此处理数据并回收该缓冲区 (CyU3PDmaChannelDiscardBufferCyU3PDmaChannelCommitBuffer 用于重新提交空缓冲区)。

      • 对于 IN 传输 (FX20 -> 主机):当 DMA 通道发送完一个缓冲区时触发 (CY_U3P_DMA_CB_SEND_CPLT),固件应回收该缓冲区(CyU3PDmaChannelDiscardBuffer),如果需要继续发送,可以填充新数据并提交一个新缓冲区 (CyU3PDmaChannelCommitBuffer)。

      • 确认你的回调函数正确处理了相关事件。特别注意 FX20 SDK API 与 FX10 的可能差异。


    • DMA 通道未启动: 配置好 DMA 通道后,必须调用 CyU3PDmaChannelEnable(&glChHandleUtoP, CYU3P_NO_RSVD_BUF); 来启动它。检查代码是否执行了这一步?。




  2. USB 端点配置错误:



    • 端点类型不匹配: 确认你配置的 USB 端点描述符 (CyFxUSBSSConfig_t 或类似结构) 中,对应端点的 enType 字段设置为 CY_U3P_USB_EP_BULK,而不是 CY_U3P_USB_EP_INTRCY_U3P_USB_EP_ISO。移植时很容易忽略这一点。

    • (仅OUT) MaxPacketSize 错误: 端点描述符中的 wMaxPacketSize 必须与固件中 DMA 通道配置的缓冲区大小 (size) 匹配或小于它。通常设置为 512 (HS) 或 64 (FS)。

    • 端点未启用: 检查 USB 配置 (CyU3PUsbStart / CyU3PUsbSetDesc) 后,目标 BULK 端点是否确实被启用。使用 Cypress Control Center 或 Wireshark 检查 USB 描述符枚举是否正确。




  3. 缓冲区管理逻辑错误 (固件逻辑):



    • 初始空缓冲区未提交 (OUT 传输关键): 这是 最常见的原因之一!对于 OUT 传输 (主机发送数据到FX20),在启动 DMA 通道之后、之前,固件作为 Producer 必须向 DMA 通道 提交 (Commit) 一个或多个空的 RAM 缓冲区 (CyU3PDmaChannelCommitBuffer)。USB 控制器 (Consumer) 需要这些空缓冲区来存入主机发来的数据。如果没有任何空缓冲区被提交,BUFFER_RYD 会立刻变低且一直保持。仔细检查移植后的代码,确保在 USB 启动、DMA 通道 Enable 之后,立即提交了初始的空缓冲区。

    • 缓冲区回收后未重新提交: 在 DMA 回调函数 (CY_U3P_DMA_CB_RECV_CPLT for OUT) 中,固件处理完收到的数据后,必须回收那个已满的缓冲区 (CyU3PDmaChannelDiscardBuffer),然后立即 (或尽快) 再次提交一个空的缓冲区 (CyU3PDmaChannelCommitBuffer) 回 DMA 通道。如果处理完后没有及时提交新空缓冲区,USB 控制器很快又会用完缓冲区导致 BUFFER_RYD 变低。

    • 缓冲区地址/对齐错误: 提交的缓冲区地址必须是物理地址? (使用 CyU3PDmaBufferGetPhysicalAddr 获取 SDK 分配缓冲区的物理地址)。缓冲区地址通常需要满足特定对齐要求 (例如 32 字节),使用 SDK 提供的 CyU3PDmaBufferAlloc 分配缓冲区可以保证对齐。

    • 缓冲区过早回收或重复提交: 确保只在 RECV_CPLT 回调后回收 OUT 缓冲区,在 SEND_CPLT 回调后回收 IN 缓冲区。避免在 DMA 引擎还在使用缓冲区时就操作它。




  4. USB 事件处理阻塞:



    • FX20 SDK 要求固件在一个主循环中调用 CyU3PUsbGetEvent 并处理事件 (CY_U3P_USB_EVENT_SETCONF 等)。如果这个循环被阻塞 (例如,在 CY_U3P_DMA_CB_RECV_CPLT 回调中做了非常耗时的操作而未返回),USB 协议栈可能无法及时处理内部事件,包括通知 DMA 引擎释放缓冲区,从而导致 BUFFER_RYD 无法恢复。确保 USB 事件处理循环未被长时间阻塞,回调函数中只做必要操作 (如设置标志、入队),复杂处理放到主循环中。




  5. 硬件/连接问题 (相对少见,但仍需排除):



    • USB 线缆或连接不良。

    • VBUS 供电不稳定。

    • 硬件设计问题 (时钟、电源、阻抗匹配等)。确保 FX20 开发板/硬件正常工作。 最简单的方法是先让官方的 UVC/UAC 示例在你的硬件上跑通。




? 针对你移植场景的排查步骤




  1. 聚焦 DMA 配置:



    • 将你的 DMA 通道配置代码与官方 SDK 中专门用于 BULK 传输的示例 (如 cyfxbulklpautocyfxbulkasync) 进行逐行对比。特别注意 dmaCfg.size, dmaCfg.count, dmaCfg.prodSckId, dmaCfg.consSckId, dmaCfg.dmaMode, dmaCfg.notification (回调阈值), cb 这些关键字段。

    • 明确 Producer 和 Consumer Socket ID (prodSckId, consSckId):

      • FX20 的 Socket ID 定义可能与 FX10 不同。查找 cyu3sdk.h 或类似文件中的 CY_FX_EP_CONSUMER/CY_FX_EP_PRODUCER 宏定义。对于 USB BULK OUT 端点,consSckId 应该是 USB 消费者 Socket (通常是 (uint8_t)epAddr),prodSckId 应该是 FX20 RAM 的生产者 Socket (如 CY_U3P_UIB_SOCKET_PROD / CY_U3P_LPP_SOCKET_...)。

      • 错误的 Socket ID 绑定会导致 DMA 路径根本不通。





  2. 确认初始缓冲区提交 (OUT传输):



    • CyU3PDmaChannelEnable 调用之后,紧接着是否有 CyU3PDmaChannelCommitBuffer 调用来提交第一个空缓冲区?提交的数量是否足够?(通常至少提交 1-2 个初始空缓冲区给 USB OUT)。




  3. 审查回调函数:



    • 你的 DMA 回调函数是否正确定义并注册 (cfg.cb = MyDmaCallback)?

    • CY_U3P_DMA_CB_RECV_CPLT 事件中:

      • 是否调用了 CyU3PDmaChannelDiscardBuffer 来释放已处理的满缓冲区?

      • 是否紧接着调用了 CyU3PDmaChannelCommitBuffer 来提交一个新的空缓冲区回去?可以在此处设置一个 GPIO 翻转或打印日志来确认回调执行和提交动作。





  4. 检查 USB 配置:



    • 确认你的端点描述符数组 (如 glEpConfig[]) 中,用于 BULK 传输的那个端点,其 enType 确实是 CY_U3P_USB_EP_BULK

    • 确认 wMaxPacketSize 设置正确 (512 for HS)。




  5. 启用调试输出:



    • CyU3PDebugInit 中设置更高的 trace level (如 CY_U3P_TRACE_LEVEL_INFOCY_U3P_TRACE_LEVEL_WARNING)。

    • 在关键点 (如 DMA 配置前/后、Enable 调用、CommitBuffer 调用、回调函数入口) 添加 CyU3PDebugPrint 语句,打印状态信息、返回值 (检查所有 API 调用的返回值 CyU3PRetry_t!) 和缓冲区计数等信息到 UART。

    • 这个信息对于诊断 BUFFER_RYD 问题非常重要!




  6. 使用工具辅助诊断:



    • Cypress Control Center: 连接设备后,检查枚举是否成功,是否能识别到你的 BULK 端点。尝试使用 Control Center 的 BULK 端点测试功能发送数据,观察固件反应和 BUFFER_RYD 信号。

    • 逻辑分析仪/示波器: 直接测量 BUFFER_RYD 信号的物理电平,确认确实是低电平。同时监测 USB 数据线 (D+, D-) 和固件控制信号 GPIO (如果有调试输出)。

    • Wireshark: 捕获 USB 通信数据包,观察主机是否成功发送了 BULK OUT 数据包,以及 FX20 是否回应了 ACK/NAK/STALL。持续的 NAK 通常是端点未就绪的标志。




? 关键检查点总结 (优先级)



  1. FX20 SDK BULK 示例对比: 找到最新的 cyfxbulklpautocyfxbulkasync 示例,仔细对照其 DMA 配置 (prodSckId, consSckId, size, count, mode, cb)、初始缓冲区提交和回调函数处理逻辑。

  2. (OUT传输) 初始空缓冲区提交: 确保在 DMA Enable 之后立即提交了至少一个空缓冲区。

  3. DMA 回调函数: 确保正确处理 RECV_CPLT (回收满缓冲区 + 提交新空缓冲区)。

  4. 端点描述符: 确认端点类型是 BULKwMaxPacketSize 匹配。

  5. API 返回值检查: 检查所有 CyU3P* API 调用的返回值 (CY_U3P_SUCCESS?)。

  6. 启用 UART Debug Print: 这是了解代码执行流程和状态的最直接手段。


通过系统地检查以上方面,特别是 FX20 特有的 DMA 配置细节和初始缓冲区提交逻辑,你应该能够定位到导致 BUFFER_RYD 持续为低电平的原因并解决问题。移植时最大的挑战往往是底层 DMA 和 USB 端点配置的细微差异。耐心对比官方示例和你的代码,尤其注意 CyU3PDmaChannelCommitBuffer 的调用时机和缓冲区生命周期管理。 祝你顺利解决!?

举报

更多回帖

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