This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TM4C1294KCPDT:使用 UDMA 接收 EPI 数据

Guru**** 2516170 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1357528/tm4c1294kcpdt-receive-epi-data-using-udma

器件型号:TM4C1294KCPDT

我们的应用每50ms 接收一次从 FPGA 流式传输的6964字节数据块。 我们的初始实施方案使用了32位 EPI 数据总线以及由 FPGA 提供的请求发送信号。 发送请求信号在端口 P:5触发中断时、将读取 EPI 总线数据并将其写入缓冲区。 一旦接收到完整的数据块、就会通过 SPI0上的 uDMA 发送数据块。 我们遇到的问题是、处理 EPI 数据中断会导致主线程导致 USB 接收/发送停止运行。 因此、我们一直在尝试迁移代码、使用 uDMA 从 EPI 总线传输数据。

我们的初始尝试做出了以下假设:
1.不能在 EPI0和 SPI0之间进行直接 uDMA 传输。 因此、我们的设计使用 uDMA 将数据块从 EPI 总线接收到缓冲区中。 当 EPI 总线上接收到完整的数据块时、使用接收到的 EPI 缓冲区、通过 UDMA 将数据发送到 SPI0。
2.需要使用 EPI 时钟信号将 EPI 读操作与 FPGA 同步。 由于 EPI 时钟频率为 EPI31、因此需要将 EPI 总线宽度降至24、16或8。 uDMA 事务仅限于32、16或8的数据大小。 因此、EPI 数据总线需要减少到16位。
3、将 FPGA 信号源请求发送的信号重命名为帧信号。 FRAME 信号上升沿触发 PortP:5中断以启动 uDMA 事务、接收来自 FPGA 的数据。 帧信号下降沿触发端口 P:5、该端口触发 UDMA 在 SPI 0上流式传输接收到的数据。

请评论是否有任何这些假设不正确或被误解。

我们的以下实现无法运行、问题可能是我们对 Tivaware 文档和示例的解释/理解导致的。 您是否会查看随附的代码块、并就如何使用 uDMA 从 EPI 数据总线传输数据提供指导。

e2e.ti.com/.../EPIuDMACode.c

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Unknown 说:
    1. 无法在 EPI0和 SPI0之间直接进行 uDMA 传输。 因此、我们的设计使用 uDMA 将数据块从 EPI 总线接收到缓冲区中。 当 EPI 总线上接收到完整的数据块时、使用接收到的 EPI 缓冲区、通过 UDMA 将数据发送到 SPI0。
    [/报价]

    正确。  

    Unknown 说:
    2. 需要使用 EPI 时钟信号使 EPI 读操作与 FPGA 同步。 由于 EPI 时钟频率为 EPI31、因此需要将 EPI 总线宽度降至24、16或8。 uDMA 事务仅限于32、16或8的数据大小。 因此、EPI 数据总线需要减少到16位。
    [/报价]

    您是否有可以确认 EPI 在接口上具有正确信号(例如时钟、帧、rd / wr addr/data)的逻辑分析仪?

    Unknown 说:

    FRAME 信号是 EPI 的输出信号、而非输入信号。 。 请查看以下说明和帧信号的示例时序图。 另请参阅数据表以了解详细信息。 请注意、对于每帧的描述、帧的波形取决于 WR/RD 信号。 如示例时序图中所示、帧信号将跟随 RD 信号。  您可能指的是来自 FPGA 的自定义帧(充当触发器或使能端)信号。 在这种情况下、应由谁来处理 EPI 帧信号? 您的 FPGA 会忽略它吗? 您的 FPGA 如何知道 uDMA 的读取是否已完成? 还是仅保持高电平50毫秒? 如果 uDMA 未在50mS 内完成从 FPGA 的读取、该怎么办? 在这种情况下、您将只接收部分数据、因为下降沿帧信号已触发向 SPI 的传输。 在使 Frame 信号的下一个上升沿生效之前、您的 FPGA 如何知道到 SPI 的传输已完成?  您需要将这一点考虑在内。

    FRAME 信号时序
    FRAME 信号的时序由 FRMCNT 和 FRM50位控制。 当 FRM50为
    清零时、FRAME 信号为高电平、WR 或 RD 选通信号为高电平。 当 FRMCNT 清零时、
    FRAME 信号就是 WR 和 RD 选通信号的逻辑或、即 FRAME 信号在
    每一次读或写访问、见852页的图11-22。

    我会建议你使用除法和征服者的方法。 首先仅从 EPI 实现 uDMA 传输。 确保缓冲区中已接收所有数据。 接下来、使用 uDMA 仅将数据从缓冲区传输到 SPI。 当两个通道同时工作时、将两个通道合并到同一个应用程序中并确保在两个通道之间实现正确同步、因此读取(来自 EPI)将在写入(到 SPI)之前首先发生。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    抱歉、对于我们所称的帧的信号造成了混乱。 这并不是 EPIOS30线路上的 EPI FRAME 信号。 我们称为帧的信号由 FPGA 提供、并在配置为中断的 GPIO 端口 P:Pin5上接收。 在 FRAME 信号的上升沿、通过16位 EPI 总线和配置为 EPI 时钟的 EPIOS31触发 UDMA 接收。 FPGA 使用 EPI 时钟将数据移入 EPI 总线、FPGA 在时钟下降沿加载数据、而微控制器在时钟上升沿读取 EPI 总线。 FRAME 信号的下降沿用于指示所有数据何时从 FPGA 发送。 用于通过 SPI0触发接收到的 EPI 数据缓冲器的 uDMA 传输。 至于建议的分配及完成方法、我们确实让 SPI0 uDMA 正常工作。 我们仅担心没有正确配置 Tivaware 函数来启动 EPI uDMA 传输。

    我们已将示波器探针连接到 EPIOS31 EPI 时钟信号上、但没有看到其在切换、探针始终为高电平。

    我们不需要使用附加的 EPI 握手信号、如 RD、WR、EPI 帧、因为 FPGA 仅使用 EPI 时钟信号传输。

    能否确认我们是否了解如何配置 EPI 和 UDMA。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我们已将示波器探针连接到 EPIOS31 EPI 时钟信号上、但没有看到其在切换、探针始终为高电平。

    [/报价]

    这将是诊断原因的第一件事、因为没有时钟、您的 FPGA 将不会响应。 您能否看一下下面的帖子、其中 Noah 将其工作代码发布为通用模式、尽管使用 CPU 而不是 UDMA 将数据从 EPI 中移动。 我还建议您也执行相同的操作、使一个使用 CPU 的工作 EPI 先添加 uDMA 功能、然后再添加 uDMA 功能。  

    https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1311611/tm4c129encpdt-using-epi-with-ti-rtos---configuring-epi-and-its-associated-gpio-for-general-purpose-mode?tisearch=e2e-sitesearch&keymatch=EPIConfigGPModeSet#

    我还发现以下代码片段看上去像是从 EPI 到 SSI 的传输、只需为 EPI 设置一个 uDMA 通道就可以实现。  

    MAP_uDMAChannelControlSet( UDMA_SEC_CHANNEL_EPI0RX | UDMA_PRI_SELECT,
                                                            UDMA_SIZE_32 | UDMA_SRC_INC_32 |
                                                           UDMA_DST_INC_32 | UDMA_ARB_8 );

    MAP_uDMAChannelTransferSet( UDMA_SEC_CHANNEL_EPI0RX | UDMA_PRI_SELECT,
                                                           UDMA_MODE_AUTO, (void*)buf, (void*)(SSI0_BASE + SSI_O_DR),
                                                           size / 4);

    MAP_uDMAChannelSelectSecondary( UDMA_DEF_TMR1A_SEC_EPI0RX );

    MAP_uDMAChannelEnable( UDMA_SEC_CHANNEL_EPI0RX );