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.

[参考译文] TM4C129ENCPDT:无法接收数据、EK-TM4C129EXL 板中使用 SSI UDMA 基本模式发送的数据

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1199010/tm4c129encpdt-not-able-to-receive-data-data-sent-using-ssi-udma-basic-mode-in-ek-tm4c129exl-board

器件型号:TM4C129ENCPDT

您好、TI 社区、  

我是新手、我希望通过 DMA 基本模式从 tm4c129EXL 板向1.3英寸 OLED 显示屏连续传输1024位数据。 之前、我尝试以下代码。

   使用 uDMA_channel_SSI1TX 通道将数据从缓冲区 g_ui8TxBuf 传输到(void *)(SSI1_base)。 不传输数据

  • 我需要 使用 uDMAChannelRequest (uDMA_transfer_channel);来触发还是使用 uDMAChannelEnable (uDMA_transfer_channel);足够了
  • 我不确定要在目的地接收数据、我使用的 是 SSIDataGetNonBlocking、这是从 SSI1基地址接收数据的正确方法。

请查找以下代码:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/udma.h"
#include "driverlib/pin_map.h"
#include "driverlib/gpio.h"
#include "driverlib/ssi.h"
#define CLK_FREQ 80000000
#define CLK_RATE 1000000
#define DATA_WIDTH 8
#define SSI_RXBUF_SIZE 256
#define UDMA_TRANSFER_CHANNEL UDMA_CHANNEL_SSI1TX
#define SSIDATA_FRAME_SIZE UDMA_SIZE_8
#define TIMES_DMA_TRANSFER UDMA_ARB_8
#define UDMA_TRANSFER_MODE UDMA_MODE_BASIC
#define SSI_TXBUF_SIZE 256
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

提前感谢您

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

    您好 Ajaykumar:

    很抱歉、我今天无法分析您的代码以查看问题。 我将争取在明天这样做并提供反馈。 通常只 需要 uDMAChannelEnable、因为外设将会发出传输请求。  uDMAChannelRequest 通常用于 SW 传输、因为没有外设会触发传输请求。

    我会尝试在查看您的代码后发现它的问题。 UDMA 的启用可能比较棘手、因此可能只是需要一个小的调整。

    此致、

    拉尔夫·雅各比

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

    您好  Ajaykumar:

    在 我的代码审查开始时、我首先观察到的是、您的时钟配置达到了我们的 SYSCTL#23勘误表、因此程序可能无法正常工作。

    请将时钟 配置更改为以下值:  

    Fullscreen
    1
    2
    SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN |
    SYSCTL_USE_PLL | SYSCTL_CFG_VCO_240), 120000000);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    您可以在此处阅读勘误表详细信息: https://www.ti.com/lit/pdf/spmz850

    接下来、您会 执行一些 uDMA 配置、但在此之前未启用模块。 首先需要启用模块。 因此、放置  uDMAEnable(); API 调用  while (!SysCtlPeripheralReady (SYSCTL_Periph_UDMA) 请先检查和、然后再检查  uDMAControlBaseSet 调用。

    我在开始时没有看到任何其他需要调整的东西、但这两项是重大的变化、因此请进行这些更新、看看您是否能够使用它们操作转接。

    此致、

    拉尔夫·雅各比

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

    您好、Ralph Jacobi:

    首先我要感谢重播

    我按照你的指示做了如下:   

    已将时钟配置更改为 SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN |
    SYSCTL_USE_PLL | SYSCTL_CFG_VCO_240)、120000000);

    然后执行  

    while (!SysCtlPeripheralReady (SYSCTL_Periph_UDMA)  

    uDMAEnable();

    uDMAControlBaseSet (&pui8ControlTable[0]);

    其余的 UDMA 配置、如 ChannelAttributeEnable、 ChannelControlSet 和 SSIDMAEnable  

    在 我正在获取的 SSIDataGetNonBlocking (SSI1_base、&u32Rxdata[i])之后验证 u32Rxdata 写入的数据时、我可以将数据放入 SSI 端口  

    u32Rxdata[0]= 0至 u32Rxdata[255]= 0在控制台中预期结果, u32Rxdata[0]= 0至 u32Rxdata[255]= 255。

    此致;

    Ajaykumar V.

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

    您好 Ajaykumar:

    在此处进一步深入探究您的用例、我认为我需要更加明确地了解您希望通过 使用 DMA 进行的当前测试实现的具体目标:

    我是新手,开始关注如何使用 DMA 基本模式将1024位数据连续从 tm4c129EXL 板传输到1.3英寸 OLED 显示屏。
    [userid="55364" url="~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1199010/tm4c129encpdt-not-able-to-receive-data-data-sent-using-ssi-udma-basic-mode-in-ek-tm4c129exl-board ]我不确定是否要在目的地接收数据,我使用了 SSIData1来接收正确的基准数据[/引用]

    除非使用内部回送模式,否则使用  SSIDataGetNonBlocking 将不起作用。

    通过为 SSI TX 设置 DMA、您将不会在 SSI RX 缓冲区中接收到任何数据。 当配置为使用 DMA 数据时、SSI 外设会将数据从缓冲区流出到 SSI 引脚上、而不是 SSI RX 缓冲区。

    通过最初的声音、您正在尝试通过这些引脚将数据发送到显示屏-因此、如果这是您的主要测试案例、那么您应重点通过逻辑分析仪(或在必要时使用示波器)读取 SPI 引脚 观察任何数据输出、而您不会使用任何 SSIDataGet API。

    如果要测试回循环数据以简单地查看 DMA 的执行情况、则需要使用 SSILoopbackEnable、在该点您能够在内部回循环数据。 这将是一个不同于您最初描述的初始用例。

    此致、

    拉尔夫·雅各比

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

    您好、Ralph Jacobi:

    主要用例是使用 SSI DMA 基本传输模式在 OLED 显示屏上显示数据。  

    我想让您知道、我会在办公室外休息两天(IST)。

    当我回来的时候,我会尽快对您的建议作出最大的回应。

    感谢您的耐心和理解。

    此致。

    Ajaykumar V.

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

    您好 Ajakumar:

    不用担心外出、我们可以在您回来后恢复此操作-线程在30天内不会锁定、时间充足。

    一旦您返回、我认为最重要的测试将是监视实际的 SSI 引脚并查看它们上是否正在输出数据。

    为了在初始时使其尽可能简单、您可能需要使用  SSIDataPutNonBlocking 来验证您是否获得输出数据、而无需 DMA。 然后在配置了 DMA 并使用 DMA 传输触发的情况下进行测试。

    此致、

    拉尔夫·雅各比

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

    您好、Ralph Jacobi:

    要使其  在初始时尽可能简单,您可能需要在没有 DMA 的情况下使用 SSIDataPutNonBlocking 来验证您是否获得输出数据。 然后在配置 DMA 并使用 DMA 传输触发的情况下进行测试。

    我可以在没有 DMA 的情况下使用 SSIDataPut ()来传输数据,当尝试使用 DMA 配置和触发时,我无法传输数据。

    此致、

    Ajaykumar V.

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

    您好  Ajaykumar:

    我将尝试在我自己的硬件上运行您提供的代码来进行测试和调试、但今天我还没有机会这样做、所以我会在星期一尝试这样做、然后向大家报告。

    此致、

    拉尔夫·雅各比

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

    您好 Ajaykumar:

    我已经建立了你的例子,但我不知道它是打算如何工作.

    也就是说,我在你的主要内容中看到:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for(i = 0; i < SSI_TXBUF_SIZE; i++)
    {
    // Wait for data to be available in the receive buffer
    while(SSIDataGetNonBlocking(SSI1_BASE, &u32Rxdata[i])) {}
    }
    //print on console
    for(i = 0; i< SSI_TXBUF_SIZE; i++)
    {
    printf("u32Rxdata[%d] = %d\n", i, u32Rxdata[i]);
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    但我完全没有看到将 SSI 模块配置为 RX、也没有配置用于接收数据的引脚。

    SSIDataGetNonBlocking 在 RX FIFO 中查找数据、这时没有任何给定的配置。

    如果示例项目符合您的预期、您能否更好地解释它应该做什么?

    此致、

    拉尔夫·雅各比

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

    您好、Ralph Jacobi:

    很抱歉,上面代码中缺少的部分,以上代码是为了验证通过 SSI DMA 通道发送的数据,而不是项目的完整概念。

    我正在做的是:仅使用 SSI DMA (具有基本传输模式)从 TM4C129ENCPDT 发送数据、仅在1.3英寸 Adafruit OLED 显示屏上持续接收。

    我按照以下过程在 OLED 上显示数据:

    1. 启动的 OLED 显示、其中包含 SSI 模块配置以及显示器关闭、时钟设置、更新和打开命令。
    2.  udma_Configuration ();其中有
      1. UDMA 外设启用。
      2. uDMA 准备就绪、然后启用 uDMA 模块
      3. uDMAControlBaseSet();
      4. 通道属性首先禁用、然后 针对 udma_channel_SSI1TX、用户突发模式启用
      5. 设置的特性、按8位数据大小进行传输、源以字节为单位递增、并按字节进行缓冲区复制。 使用一个128的总线仲裁大小。 例如、  

        uDMAChannelControlSet (uDMA_CHANNEL_SSI1TX | UDMA_PRI_SELECT、UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_128);

      6.  SSIDMAEnable (SSI1_BASE、SSI、DMA_TX);//将控制传输到 UDMA 控制器
    3. dma_transfer();传输缓冲区和传输大小现已配置。 使用基本模式进行传输。
      1. uDMAChannelTransferSet (uDMA_CHANNEL_SSI1TX  | uDMA_PRI_SELECT、UDMA_MODE_BASIC、DUMPLE_DATA、(void *)(SSI1_BASE)、1024);
      2. uDMAChannelEnable (uDMA_CHANNEL_SSI1TX);开始传输数据。

      3. //等待 DMA 传输完成
        while (uDMAChannelIsEnabled (uDMA_CHANNEL_SSI1TX){}
    4. dma_rx ();从 SSI1_base 接收数据以接收 OLED 的缓冲区
    5. display();将接收缓冲区中的数据发送到 Display。

    请按照上述步骤找到以下代码:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    // uDMA_OLED_transfer.c
    // this transfer data from data buffer of uC to OLED display
    #include <stdint.h>
    #include <stdbool.h>
    #include <stdio.h>
    #include <string.h>
    #include "inc/hw_memmap.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/udma.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/gpio.h"
    #include "driverlib/ssi.h"
    #define UDMA_TRANSFER_CHANNEL UDMA_CHANNEL_SSI1TX
    #define UDMA_RX_CHANNEL UDMA_CHANNEL_SSI1RX
    #define SSIDATA_FRAME_SIZE UDMA_SIZE_8
    #define TIMES_DMA_TRANSFER UDMA_ARB_128
    #define UDMA_TRANSFER_MODE UDMA_MODE_BASIC
    #define SSI_TXBUF_SIZE 1024
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    以下提到的方法是否可用于在 OLED 外设接收数据并进行进一步处理? 如果不是正确的方式,请建议正确的方式,我很乐意学习新的技术。

    • 使用 SSI DMA Rx 通道(我使用了该通道)
    • 使用轮询:(使用对我没有用处的 UC 周期)
    • 更新固件
    • 使用轮询和中断

    此致、

    Ajaykumar V.

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

    您好 Ajaykumar:

    谢谢。 我发现您的 DMA TX 有问题。 使用 uDMAChannelTransferSet 时、您有一个轻微但关键的遗漏、会导致 DMA 无法正常运行。  

    当指向目标地址时、您不能只是指向 SSI1_BASE 外设地址、您需要专门针对其数据寄存器。

    您仅使用了函数 (void *)(SSI1_base)、但需要使用 (void *)(SSI1_base + SSI_O_DR )

    要执行此操作、  您必须添加  #include "inc/hw_ssi.h"  错误的标记、否则将无法找到 SSI_O_DR 寄存器地址。

    完成这项更改后、我能够通过 DMA 将 SSI 数据传输到 SSI 引脚上。

    Fullscreen
    1
    2
    3
    4
    uDMAChannelTransferSet(UDMA_TRANSFER_CHANNEL | UDMA_PRI_SELECT,
    UDMA_TRANSFER_MODE, g_ui8TxBuf ,
    (void *)(SSI1_BASE + SSI_O_DR),
    sizeof(g_ui8TxBuf));
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    由于我没有 Adafruit 显示屏、我注释掉了 RX 代码、并没有对其进行测试。 但是、我注意到你 也需要在你的 DMA_RX 函数中进行同样的更改。

    希望这是缺少的步骤、能让您继续前进。

    此致、

    拉尔夫·雅各比

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

    您好、Ralph Jacobi:

    我按照您的建议进行了更改、它很有效。

    使用 (void *)(SSI1_base + SSI_O_DR )

    这解决了上述解决方案的部分问题,我能够传输存在于 u32Rxdata 中的预先写入数据(垃圾值)。 我想我无法将数据从 SSI_O_DR 写入 u32Rxdata。 就像您说的

    SSI 外设在配置为使用 DMA 数据时,会将数据从缓冲区流出至 SSI 引脚,而不是 SSI RX 缓冲区

    如何从 SSI_O_DR 接收到 Rx 缓冲区的数据、以便能够在显示屏上显示数据。

    尝试使用以下代码时:

    Fullscreen
    1
    2
    3
    4
    5
    6
    uDMAChannelTransferSet(UDMA_CHANNEL_SSI1RX | UDMA_PRI_SELECT,
    UDMA_TRANSFER_MODE, (void *)(SSI1_BASE + SSI_O_DR),
    u32Rxdata,
    sizeof(u32Rxdata));
    uDMAChannelEnable(UDMA_TRANSFER_CHANNEL | UDMA_CHANNEL_SSI1RX);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    从 0x2000026c 读取包含一些无用值的数据。 我 使用上述代码将数据写入 u32Rxdata、但不会写入 u32Rxdata。

    1. 我需要同时发送和接收吗? 写入的影响。
    2.  

      下列方法是否可用于在 OLED 外设接收数据并进行进一步处理? 如果方式不正确、请建议正确的方式

    和/或建议从 SSI_O_DR 接收数据以接收缓冲区的方法、以便能够显示在 OLED 上。

    另外还观察到、 当我尝试查看在调试运行模式下使用断点时、我无法在"Memory Browser"(内存浏览器)中看到我将要从 g_ui8TxBuf 传输到 SSI_O_DR 的数据。 它正在写入出现在 SSI_O_DR 中的预写入数据。   

    此致、

    Ajaykumar V.

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

    您好 Ajaykumar:

    通道传输的配置看起来不错、因此开启时必须有其他因素会影响接收。

    您能否在 LCD 向 TM4C MCU 发送数据的 SSI 总线的示波器或逻辑状态分析仪上进行捕获? 由于没有屏幕、我无法复制您的确切情况、因此我需要先查看 SSI 线路、然后才能提供更多反馈。

    此致、

    拉尔夫·雅各比

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

    您好,Ralph Jacobi

    感谢您的耐心。

    因为我没有逻辑分析仪或示波器。 我正在程序中使用断点。

    我无法将数据写入/读取到 SSI_O_DR。 以前  g_ui8TxBuf 仅填充0x00。上次我没有尝试其他的时候尝试其他数据 。尝试使用其他数据时 、我无法看到我正在 SSI_O_DR 的 Memory 浏览器中从 g_ui8TxBuf 传输到 SSI_O_DR 的数据。当我尝试在调试运行中查看使用断点时 测试模式。 或者它没有在显示屏上打印、它正在写入位于 SSI_O_DR 中的预写入数据。

    此致、

    Ajaykumar V.

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

    您好  Ajaykumar:

    使用 DMA 时、您无法通过断点观察到任何有意义的内容。  您将需要获取能够让您查看 SSI 线路的工具的访问权限。

    或者、您可以在开始时通过删除 DMA 操作来简单地解决此问题、直到您可以获得经过验证的标准 SSI 双向通信、然后在实现后重新添加 DMA。 即使在这种情况下、查看 SSI 线路也能显著加快调试速度、但至少在不使用 DMA 的情况下、你可以尝试实现当前 所需的功能。

    此致、

    拉尔夫·雅各比

x 出现错误。请重试或与管理员联系。