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.

[参考译文] RM48L952:了解 Mibspi DMA 数据大小

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/996614/rm48l952-understanding-mibspi-dma-data-size

你好!

我计划在 mibspi 上使用 DMA、目前正在测试模块、但我很难理解它的确切工作方式。

Mibspi 必须处理至少为2个字节到最多为823个字节的数据大小、并且可能会有所不同。 问题是使用 DMA 传递823字节数据包、我提出了2个选项。

使用 Mibspi 的所有128字缓冲器、将其作为128个元素、7个帧数据传递。 在这种情况下、(128*7)-823 = 73字节将是冗余的。 我不知道我是否正确、但如果 DMAxCOUNT 实际上是 DMA 传输的元素数量、那么我可以在 Mibspi 和 DMA 传输(接收) 823字节数据时停止它。

2.仅使用 mibspi 的1字缓冲区、将其作为1个元素、823帧数据传递、反之亦然。 写入 TX 的单个缓冲器并从 Rx 的单个缓冲器中读取。

我尝试了这两种方法来实现这一目标。 不幸的是、它运行得不是很好。 实际上、我甚至不确定这些是否可行。 我已经尝试更改了许多控制值、最常见的问题是  、mibspi Rx DMA 接收到的数据 变为相同的数据(例如 :接收"abcdefgh"变为"cccccccccccccccc")。 我想知道使用数字回送是否必须实现 这一点。

我会详细介绍一下、但 我想知道这些选项中是否有一个是可行的。

对于这种通信、最好使用兼容的 SPI、但 spi5 TX/Rx 和 sci TX/Rx 共享相同的 DMA 请求行、并且由于我必须同时使用这两者、我想使用 mibspi5并为 mibspi5使用其他 DMA 请求行。  

感谢您的帮助!

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

    您好!

    只有当 DMACNTLEN 寄存器中的大计数位置位时、才使用 DMAxCOUNT。 DMAxCOUNT 中的 ICOUNT 是 DMA 传输的数量、而不是元素数量。 如果在 DMA 配置中使用帧传输、则 ICOUNT 定义帧编号。 在您的示例中、ICOUNT=7-1=6。 传输的元素数量为128*7=896。  

    每个 DMA 传输可轻松传输1个元素。  

    附件是我的 MibSPI+DMA 工作示例:

       

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

    您好、Wang、

    我认为您的示例未附在后面? 我检查并参考了您的 另一个 RM48L952示例:使用 DMA 的 MibSpi Tx 和 Rx -其他微控制器论坛-其他微控制器- TI E2E 支持论坛、但仍然无法正确完成。

    我当前用于测试的设计如下:

    txBuffer 和 rxBuffer 均为128字节大小、但数据总共为66字节。

    Fullscreen
    1
    2
    static uint8_t txBuffer[128] = "abcdefghijklmnopqrstuvwxyz\r\n0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n";
    static uint8_t rxBuffer[128] = {0};
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    数据格式与默认格式相同、除非 charlen 为8位。 传输组缓冲器模式为7 (挂起读取/写入)、以便 DMA 可以同步、而组缓冲器大小为1、以便 Mibspi 和 DMA 可以用于传输任何大小的数据。

    在 DMA 控制数据包中、元素数量为1、帧数量为66、以发送并得到总计66字节。 此外、还可以通过更改帧计数来轻松更改数据长度。 元件的大小为8位、ttype 为 block_transfer、因此可通过单次激活来实现数据通信。

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void setDmaMibspiPacketCommon(g_dmaCTRL *packet)
    {
    packet->CHCTRL = 0;
    packet->ELCNT = 1;
    packet->FRCNT = 66;
    packet->PORTASGN = 4;
    packet->RDSIZE = ACCESS_8_BIT;
    packet->WRSIZE = ACCESS_8_BIT;
    packet->TTYPE = BLOCK_TRANSFER;
    packet->ADDMODERD = ADDR_OFFSET;
    packet->ADDMODEWR = ADDR_OFFSET;
    packet->AUTOINIT = AUTOINIT_OFF;
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    对于传输、源为 txBuffer、帧偏移为1、而目的为 TX[0]。data、两个偏移都为0。 对于接收、源为 Rx[0].data、两个偏移量都为0、而目的为 rxBuffer、帧偏移量为1。

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    mibspiRAM_t* ram = ((mibspiRAM_t *)0xFF0A0000U);
    void setDmaMibspiPacketTransmit(g_dmaCTRL *packet)
    {
    packet->ELSOFFSET = 0;
    packet->FRSOFFSET = 1;
    packet->SADD = (uint32_t)txBuffer;
    packet->ELDOFFSET = 0;
    packet->FRDOFFSET = 0;
    packet->DADD = (uint32_t)(&(ram->tx[0].data));
    }
    void setDmaMibspiPacketReceive(g_dmaCTRL *packet)
    {
    packet->ELSOFFSET = 0;
    packet->FRSOFFSET = 0;
    packet->SADD = (uint32_t)(&(ram->rx[0].data));
    packet->ELDOFFSET = 0;
    packet->FRDOFFSET = 1;
    packet->DADD = (uint32_t)rxBuffer;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    以下代码是主例程。 在进入循环之前、程序设置 DMA 控制数据包、启用 DMA、设置请求线路、为 DMA Rx 启用 BTC 中断。

    在主循环中的每次迭代中、程序清除缓冲区、设置 DMA 通道使能、设置 DMA 请求和开始传输、然后等待直到完成。

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    void mibspiMasterDmaTest(){
    g_dmaCTRL dmaRxPacket = {0};
    g_dmaCTRL dmaTxPacket = {0};
    uint32_t dmaReqlineMibspiRx = 28; /* mibspi5[14] */
    uint32_t dmaReqlineMibspiTx = 29; /* mibspi5[15] */
    uint32_t dmaChannelRx = DMA_CH0;
    uint32_t dmaChannelTx = DMA_CH1;
    int i;
    /* Digital loopback test mode */
    mibspiEnableLoopback(mibspiREG5, Digital_Lbk);
    setDmaMibspiPacketCommon(&dmaTxPacket);
    setDmaMibspiPacketCommon(&dmaRxPacket);
    setDmaMibspiPacketTransmit(&dmaTxPacket);
    setDmaMibspiPacketReceive(&dmaRxPacket);
    /* Dma request line channel for mibspi5 */
    mibspiREG5->DMACTRL[0] |= (14 << 20) | (15 << 16);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    在 DMA 通知中、程序通过 UART (sci)将 rxBuffer 输出到 PC。

    Fullscreen
    1
    2
    3
    4
    5
    void dmaGroupANotification(dmaInterrupt_t inttype, uint32 channel)
    {
    /* Send data to console */
    sciSend(sciREG, 128, rxBuffer);
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    预期行为为打印

    abcdefghijklmnopqrstuvwxyz
    0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ

    PC 端子。 但是、它会打印相同的随机字符66次、主要是 c、g 或 h。当我在传输结束后立即读取 mibspiRAM5存储器时、TX 有10 (\n)是正确的、但 Rx 有104 (h)、这是不正确的。

    我认为我做得正确、但看起来不正确。 问题可能出在哪呢?

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

    请对 tType 使用帧传输。   

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

    您好、Wang、

    将 tType 更改为 Frame transfer (帧传输)并禁用 OneShot for Transfer Group (传输组)使其工作正常。

    现在、我尝试使用 DMA OneShot 和 DMAxCOUNT 值来传输数据、因此在下面部分中没有注释。

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void mibspiMasterDmaTest(){
    ...
    mibspiREG5->DMACTRL[0] |= (1 << 31);
    mibspiREG5->DMACNTLEN = 1;
    mibspiREG5->DMACOUNT[0] |= (65 << 16);
    ...
    while(1){
    ...
    }
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    它会传输数据、但仅传输一次。 我查看了寄存器值、它显示 RxBuf 已满。 此外、TG0的已完成中断和已挂起中断都已置位。 在 针对 Rx 调用 DMA BTC 通知时、TG 启用且 TG 控制寄存器中触发的 TG 为1。

    我是否需要更改其他一些值才能使其正常工作?

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

    如果 DMACTRL 寄存器的第31位(OneShot)被置位、则 DMA 传输(ICOUNT + 1)帧将被置位。  

    如果 TGxCTRL 寄存器的 OneShot 被置位、MibSPI 只为每个触发事件传输1次(如果 TG 大小为1个缓冲区、则只传输1个缓冲区)。