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.

[参考译文] TMS570LC4357:使用 DMA 进行 SCI 接收

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1325644/tms570lc4357-sci-reception-with-dma

器件型号:TMS570LC4357

你好。  

我尝试从 SCI 器件接收数据、并使用 DMA 将数据复制到 RAM。 我从其他设备接收到突发数据(长度未知)、并 使用周期性线程轮询复制的数据。  

我建立一个 DMA 传输、将1字节作为元素大小、每帧1个元素、将帧数量作为接收缓冲区的大小(以字节为单位)、并激活 自动启动。

我从"20.2.4 DMA 通道控制数据包"的文档中了解到、 除非发生仲裁、否则工作控制数据包不会是最新的。 为此、我并行运行2个从 RAM 到 RAM 的8字节"虚拟"DMA 传输、 以强制对两个 FIFO 进行仲裁。  我不使用 FIFO A 或 B 中的信息、因为无法对所有 FIFO 的寄存器进行原子读取。  

我观察到强制仲裁 一直有效, 但在一个特定的情况下:当传输完全填满接收缓冲,没有更多的传输发生。  

我们举一个例子、我使用32字节的 接收缓冲区( 从0x80700100开始 、到 0x8070011f 结束)、启动时用0xFF 填充缓冲区。  

  1.  接收缓冲区为: >ff ff ff ff ff ff ff ff ff FF ff ff ff ff ff ff ff ff ff ff ff FF ff ff ff ff ff ff ff ff ff ff ff FF ff ff ff ff ff ff ff ff ff ff ff FF ff ff ff ff ff ff ff ff ff ff ff FF ff ff ff ff ff ff ff ff ff ff ff FF <

  2. 18字节开始传输 (值从0x00到0x11)

  3. 在传输期间、发生了一个读取操作:
      接收  缓冲区 大于00 01 02 03 04 05 06 07 ff ff ff ff ff ff ff FF ff ff ff ff ff ff ff ff ff ff ff FF ff ff ff ff ff ff ff ff ff ff ff FF ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff <
      工作控制数据包的 CDADDR 为0x80700108、正常。

  4. 传输结束后发生另一个读取操作:
      接收  缓冲区  大于00 01 02 03 04 05 06 07 08 09 0A 0b 0c 0d 0e 0f 10 11 off ff ff ff ff ff ff ff FF ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff <
       工作控制数据包的 CDADDR 为0x80700112、 正常且最新。

  5. 另一个14字节传输开始(值从0x11到0x1E)

  6. 在第2个传输期间、发生了一个读取操作:
      接收 缓冲器大于00 01 02 03 04 05 06 07 08 09 0A 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1A 1b ff <
       工作控制数据包的 CDADDR 为0x8070011d、 正常。

  7. 传输结束后发生另一个读取操作:  
      接收  缓冲器为>00 01 02 03 04 05 06 07 08 09 0A 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1A 1b c 1d <. 完全充满电。
       工作控制数据包的 CDADDR 为0x8070011e、即  不是最新的。  (即使两个 FIFO 进行了多次仲裁)
      已收到块转移完成中断。  
     工作控制数据包中的寄存器不会更改、直到发生另一个传输。

这种行为是否正常且预期会从 DMA 中发生、因为我在文档中没有看到有关此特定案例的任何信息?

这意味着、在任何情况下、块传输完成后工作控制数据包都不会更新。  

此致

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

    尊敬的 Jeff:

    首先、我建议您参考我对 CDADDR 寄存器行为的说明:

    (13) TMS570LC4357:在 SCI 链路上接收未知大小突发的数据流时、正确使用的机制是什么? -基于 Arm 的微控制器-内部论坛-基于 Arm 的微控制器-内部- TI E2E 支持论坛

    现在来到你的问题,我不明白你如何能够创建仲裁,只要你需要.

    请发送您用于调试的完整项目。 另外、请提供您正在验证的 CDADDR 寄存器的屏幕截图。

    ——
    谢谢、此致、
    Jagadish。

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

    你好。 您访问的页面不存在或已被删除提示信息  

    我不能与你分享我的整个项目很容易,但在这里仲裁强制部分:  

    #define TRANSFERT_SIZE 8
    char buffer_src[TRANSFERT_SIZE];
    char buffer_dst[TRANSFERT_SIZE];
    char buffer_src2[TRANSFERT_SIZE];
    char buffer_dst2[TRANSFERT_SIZE];
    dma_ctrl_t ctrl_packet_dummy;
    dma_ctrl_t ctrl_packet_dummy2;
    
    void dummyTransfertInit()
    {
    
      /* - Pre configure the constant part of the transfert control packet  */
      ctrl_packet_dummy.CHCTRL    = 0;                              
      ctrl_packet_dummy.ELCNT     = 1;                              
      ctrl_packet_dummy.FRCNT  = TRANSFERT_SIZE;                    
      ctrl_packet_dummy.ELDOFFSET = 0;                              
      ctrl_packet_dummy.ELSOFFSET = 0;                              
      ctrl_packet_dummy.FRDOFFSET = 0;                              
      ctrl_packet_dummy.FRSOFFSET = 0;                              
      ctrl_packet_dummy.RDSIZE    = ACCESS_8_BIT;                   
      ctrl_packet_dummy.WRSIZE    = ACCESS_8_BIT;                   
      ctrl_packet_dummy.TTYPE     = BLOCK_TRANSFER ;                
      ctrl_packet_dummy.ADDMODERD = ADDR_INC1;                      
      ctrl_packet_dummy.ADDMODEWR = ADDR_INC1;                      
      ctrl_packet_dummy.AUTOINIT  = AUTOINIT_OFF;                   
      ctrl_packet_dummy.PORTASGN  = 0x2;
      ctrl_packet_dummy.SADD   = (uint32_t)buffer_src; 
      ctrl_packet_dummy.DADD   = (uint32_t)buffer_dst; 
    
      /* - Pre configure the constant part of the transfert control packet  */
      ctrl_packet_dummy2.CHCTRL    = 0;                 
      ctrl_packet_dummy2.ELCNT     = 1;                 
      ctrl_packet_dummy2.FRCNT  = sizeof(buffer_src2);  
      ctrl_packet_dummy2.ELDOFFSET = 0;                 
      ctrl_packet_dummy2.ELSOFFSET = 0;                 
      ctrl_packet_dummy2.FRDOFFSET = 0;                 
      ctrl_packet_dummy2.FRSOFFSET = 0;                 
      ctrl_packet_dummy2.RDSIZE    = ACCESS_8_BIT;      
      ctrl_packet_dummy2.WRSIZE    = ACCESS_8_BIT;      
      ctrl_packet_dummy2.TTYPE     = BLOCK_TRANSFER ;   
      ctrl_packet_dummy2.ADDMODERD = ADDR_INC1;         
      ctrl_packet_dummy2.ADDMODEWR = ADDR_INC1;         
      ctrl_packet_dummy2.AUTOINIT  = AUTOINIT_OFF;      
      ctrl_packet_dummy2.PORTASGN  = 0x2;
      ctrl_packet_dummy2.SADD   = (uint32_t)buffer_src2;
      ctrl_packet_dummy2.DADD   = (uint32_t)buffer_dst2;
    }
    
    void dummyTransfert()
    {
      dmaSetCtrlPacket(DMA_CH0,  &ctrl_packet_dummy);
      dmaSetCtrlPacket(DMA_CH1,  &ctrl_packet_dummy2);
    
      // Enable 2 DMA transfer with the higher priority  ...
      dmaSetChEnable(DMA_CH0, DMA_SW);
      dmaSetChEnable(DMA_CH1, DMA_SW);
    
      uint32_t swChanEnable;
      uint32_t bit_chan_0_1 = ( 1 << DMA_CH0) | ( 1 << DMA_CH1);
    
      // ... and wait for the transfer to be done.
      do
      {
         swChanEnable = dmaREG->SWCHENAS;
      } while ((swChanEnable & bit_chan_0_1) != 0x0);
    }
    

    函数 dummyTransfertInit 在初始化时调用一次、然后 在我想强制仲裁时调用 dummyTransfert。 此函数通过通道0和1 (2个优先级最高)将 RAM 的2 DMA 传输到 RAM。 其他 DMA 传输使用具有较高数字的通道(即:较低优先级)。

    我 使用 TI 的示例提供的结构从工作控制数据包中检索 CDADDR 值:

    dmaRAMREG->WCP[MY_CHANNEL].CDADDR

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [报价 userid="539600" url="~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1325644/tms570lc4357-sci-reception-with-dma/5049673 #5049673"]您好。 您访问的页面不存在或已被删除提示信息  [报价]

    我已将链接中的页面转换为 pdf 格式。 请 参阅一次。

    e2e.ti.com/.../E2E_5F00_Thread.pdf

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

    你好。  
    是否有更新?

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

    尊敬的 Jeff:

    很抱歉我的答复出现延误。

    今天、我有机会对其进行测试。  

    我的观察是:
    一旦整个 DMA 传输完成、我的意思是所有的帧传输都已完成、这意味着相应通道上不再有待处理的传输、在这种情况下、如果该通道被高优先级通道中断、工作目录中就不会有任何数据副本。 这也是我们应该期望的正确,我的意思是工作目录只有在有一些待处理的转移时才需要,如果没有更多待处理的转移则不需要。

    下面是我的测试:

    我使用 SCI DMA 创建了一个具有4个帧和1个元素的工程。 每个字节传输中将有一个帧传输到 SCI 的 RX 寄存器中。

    我将按照您给定的方式使用存储器到存储器传输来创建仲裁、每当我按下 Launchpad 上的用户开关时、就会触发该仲裁。

    场景1:

    在我的第一次测试中、我将在触发仲裁之前向 SCI 传输3个帧(3个字节)。

    您可以看到、移动了3个字节、工作控制数据包仅具有其先前测试的值。 现在、我将创建仲裁、以便查看更新后的值进入工作控制数据包。

    正如您所看到的、CDADDDR 寄存器指向0x080015F3、因为我们从0x080015F0的起始地址移动了3个字节。

    现在、我还发送了最后一个帧、然后再次触发了仲裁、结果如下:

    如您所见、CDADDR 寄存器的最后值并没有更新。

    场景2:

     我正在将 2个帧(2字节)传输到 SCI 、然后触发 仲裁、结果如下:

    正如您所看到的、CDADDDR 寄存器指向0x080015F2是因为我们从0x080015F0的起始地址移动了3个字节。

    现在我刚刚发送了最后两个帧、然后我再次触发了仲裁、结果如下:

    如您所见、CDADDR 寄存器的最后值并没有更新。

    因此 、这样一来、CDADDR 寄存器 在相应待处理通道上的所有传输完成后即不会更新。

    以下是我测试的代码、供您参考:
    e2e.ti.com/.../5228.SCI_5F00_DMA_5F00_LC4357.zip

    ——
    谢谢、此致、
    Jagadish。

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

    你好。
    我很高兴你观察到相同的行为比我! :)

    但最后,我的问题是: "这种行为是正常的,预期从 DMA ,因为我看不到任何关于这个具体情况的资料在文件?"

    此致

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

    尊敬的 Jeff:

    我同意您的看法、即文档中未明确涵盖此特定案例

    但这只是预期行为。 工作控制数据包只有在块传输完成前才有用、一旦块传输完成、即使有仲裁、工作控制数据包中也不会有任何地址副本。

    ——
    谢谢、此致、
    Jagadish。

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

    你好。
    我明白您的观点、但在我的案例中 、我使用的是自动启动模式、因此在块传输完成后、运行控制数据包将很有帮助、因为预计会有更多的块。  

    要 使用 DMA 实现正确的软件、我需要知道其行为。 正如您所说的、文档中未明确涵盖该特定情况、因此我需要知道 DMA 中实现了什么。 (即: 当一个数据块完成时 DMA 不会有工作控制数据包,而不会影响配置 ?)

    此致

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

    尊敬的 Jeff:

    我明白了您的观点、但在我的案例中 、我使用的是自动启动模式、所以在块传输完成后、运行控制数据包将会有所帮助、因为需要更多的块。  [报价]

    即使自动启动模式已开启、DMA 通道也不会直接进入待处理状态、对吧? 只有在再次从 SCI 接收到新的字符请求之后、通道才会进入挂起状态、直到通道将执行自动启动并等待来自 SCI 的新请求才对?

    我还希望您了解、如果通道不处于待处理状态、根本就不会有任何仲裁。 我的意思是、直到通道处于挂起状态时、才会通过其他传输进行仲裁。 因此、这意味着不存在仲裁并且没有更多数据直接传输到工作控制数据包中。

    ——
    谢谢、此致、
    Jagadish。

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

    尊敬的 Jeff:

    Carlo 问我以下问题:

    我的问题可以总结为:当一个块完成时、DMA 是否永远不会更新工作控制数据包、配置无关紧要?

    答案)

    是的、当块传输完成时、DMA 永远不会更新工作控制数据包。

    如 TRM 中所述、仅当仲裁发生正确时、才会更新工作控制映像。 如果一个 DMA 通道完成了配置的传输次数、则另一个通道不会有任何机会进行通道仲裁、那么就没有更新有效图像的意义。

    甚至我在实践中测试了这种行为、他的行为与 TRM 中提到的行为相同。 我更新了 e2e 主题中的屏幕截图相同。

    ——
    谢谢、此致、
    Jagadish。