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.

[参考译文] TMDXRM57LHDK:使用 DMA 在 SCI3上接收数据

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/579707/tmdxrm57lhdk-receiving-data-on-sci3-using-dma

器件型号:TMDXRM57LHDK
主题中讨论的其他器件:HALCOGEN

你(们)好。

我想将串行接口设置为使用 DMA 接收数据。  

我找到了 sci DMA 示例(Halcogen)、但无法使其正常工作。 它在环回模式下打印失败、或在环回为零时卡在 while 环路中。  

我创建了一个新项目、在 Halcogen 中启用了 sci3和 sci4、未更改配置(禁用了所有 sci 中断、两者中的帧参数相同)、并生成了代码。

我是否缺少一些配置步骤?  

另一件事是:根据一些其他论坛线程、如果要使用 DMA 接收数据、则需要执行虚拟 DMA 传输来更新 CTCOUNT、从而允许再次触发 DMA 接收请求。 因此、我想、我将需要它。  

如果我的虚拟发送和接收缓冲器在我的应用中被定义(uint8 dummy_array[2]、其中 idx 0将是 TX Addr、idx 1是 Rx Addr)、那么应该在'dmaReqAssign (dma_chx、dma_req_line)'中使用的 dummy_req_line 应该是什么?

此致、
Julio

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

    我正在研究您的问题、并将在明天再次与您讨论。 对拖延表示歉意。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你好、Chuck、

    感谢您在本主题上的帮助。
    您能找到什么吗?

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

    我对继续拖延表示歉意。 我希望明天能实现这一目标。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Julio、

    首先,我对迟迟不能与您联系表示歉意。

    [引用 user="Julio Cesar Aguilar Zerpa">我找到了 sci DMA 示例(Halcogen)、但无法使其正常工作。 它在环回模式下打印失败、或在环回为零时卡在 while 环路中。  

    我创建了一个新项目、在 Halcogen 中启用了 sci3和 sci4、未更改配置(禁用了所有 sci 中断、两者中的帧参数相同)、并生成了代码。

    我是否缺少一些配置步骤?  [/报价]

    我不能确定是否仅根据你的上述发言而列入了所有步骤。 我认为您很可能正确配置了 HalCoGen 工具、但是如果不看到代码、就不可能看到 DMA 是否按应有的方式配置。 主要关注的是要从中读取 SCI 的配置。

    [引用 user="Julio Cesar Aguilar Zerpa">另一件事是:根据其他一些论坛线程、如果要使用 DMA 接收数据、则需要执行虚拟 DMA 传输以更新 CTCOUNT、从而允许再次触发 DMA 接收请求。 因此、我想、我将需要它。  

    如果我的虚拟发送和接收缓冲区在我的应用中被定义(uint8 dummy_array[2]、其中 idx 0将是 TX Addr、idx 1是 Rx Addr)、应该在'dmaReqAssign (dma_chX、dum_req_line)'中使用的 dummy_req_line 应该是什么?[/quot]

    需要读取虚拟数据。 我认为、由于您只是在接收模式(半双工)下使用 SCI、因此您应该能够在初始化期间以回送模式启动传输。 当接收到虚拟数据时、可以将其抛出。 此时、DMA 应该能够接管。

    我还找到了介绍带有 DMA 的 SCI 的应用手册、这些可能对您有所帮助。 它位于 www.ti.com/.../spna213.pdf。

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

    由于存在缓存、在 RM57器件中使用 DMA 时、您应该注意到的另一个有趣的信息位。

    e2e.ti.com/.../666341

    同样、需要处理更多信息、但我希望这对您有所帮助。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、Chuck、

    再次感谢您的帮助。 它是高速缓存设置。

    该示例现在可以工作、但仅在回送模式下工作。 如果将环回模式设置为 false、程序将在 while 循环中挂起。 我将看到我可以找到的内容。

    我要附加 halcogen 文件。 它们可能会帮助您发现其他一些错误。

    e2e.ti.com/.../2766.SciDmaTransfer.zip

    编辑:

    我刚刚意识到、如果没有连接到 SCI4的外部源、回送模式为零、它将无法工作。

    谢谢。

    此致、
    Julio

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

    我正在尝试理解该示例、以便在我的应用中应用它。

    我需要通过硬件触发的 DMA 接收串行数据、但如前所述、我需要不断(或在每个 SCI DMA RX 之后)触发虚拟 DMA 请求、以便未来的 SCI DMA RX 请求可以被触发。

    我尝试不断地从示例中触发环回模式 DMA 传输(TX 和 RX)、但它不起作用。 我只得到第一个传输。 之后、程序将保持在'while (dmaGetInterruptStatus (DMA_CH2、BTC)!= true)'中。

    我不知道哪个函数执行实际触发。 我甚至在循环中使用了整个代码、什么也不使用。 我只得到第一个传输。

    我必须设置什么?

    顺便说一下、我不理解您说过在环回模式下进行传输作为初始化、这将触发我的 dma_sci_Rx 请求。

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

    [引用 user="Julio Cesar Aguilar Zerpa">我需要通过硬件触发的 DMA 接收串行数据、但如前所述、我需要不断(或在每个 SCI DMA RX 之后)触发虚拟 DMA 请求、以便将来可以触发 SCI DMA RX 请求。
    [/报价]

    只需在第一个 DMA 传输上进行虚拟传输即可启动该过程。 后续 DMA 传输不需要它。 此外、我还会考虑切换到一个基于 SW 的触发器、该触发器可以在您内部针对数据包中的第一个字节触发 RX 中断。 如果处理固定的数据包长度、则尤其如此。 您仍然会在每个数据包中获得一个 RX 中断、但 DMA 会负责移动数据。 您需要在 DMA 块传输完成的完成中断中重新启用接收中断。

    [引用 user="Julio Cesar Aguilar Zerpa">我不知道哪个函数执行实际触发。 我甚至在循环中使用了整个代码、什么也不使用。 我只得到了第一次转账。

    如果您使用硬件触发、它应该由 SCI 模块触发、因为它会在每次接收到一个字节时实例化 DMA 请求。

    [引用 user="Julio Cesar Aguilar Zerpa"]顺便 说一句、我不理解您对在环回模式下进行传输进行初始化所说的内容、这将触发我的 dma_sci_Rx 请求。
    [/报价]

    我的目的是说您在初始化期间启动了一个虚拟传输、以注意 DMA 的启动。 如果您将其基于 RX 接收中断和 SW 触发器、则可以避免这种情况。

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

    你好、Chuck、

    我能够使用 DMA 定期发送和接收、并且处于数字回路模式(就像在示例中一样)。 我只需要通过调用以下命令再次启用通道:

    dmaSetChEnable (DMA_CH1、DMA_HW);
    
    dmaSetChEnable (DMA_CH2、DMA_HW); 

    然后、我尝试从传感器接收数据、但在第一次迭代中 DMA 中断甚至没有被触发、所以我返回到示例并尝试在模拟回路模式下对其进行测试。 我还连接了 SCI4 RX 和 TX 引脚(NHET117和 NHET119、它们对吗?)。 再说一次、不会接收到任何内容。 我获得了 DMA TX 中断、那么我缺少了什么? 数字回路正常工作、但模拟回路无法正常工作。

    在这个线程中、这个人成功地尝试了同样的事情。 我甚至尝试了他的控制数据包配置。 但它不起作用。 他还通过'sciSend'发送第一个字节、这是我不理解的原因、但我还是尝试了。 它不起作用。

    我还尝试了您的软件触发想法、但同样没有成功(DMA RX 中断未被调用)。

    /* SCI 8位 TX/RX 数据的地址*/
    #define SCI3_TX_ADDR ((uint32_t)(&(sciREG3->TD)
    )#define SCI3_RX_ADDR ((uint32_t))(&(sciREG3->DRD)
    )#define SCI3_Rdma_RX_Rdma_Rdma*
    #define SCR3_Rdma_Rdma_Rdma*#define SC_R3_Rdma_Rdma_Rdma_Rdma*
    
    #define (#define SC_Rdma_Rdma_R3_Rdma_Rdma_Rdma_Rdma_Rdma_Rdma_Rdma_Rdma_Rdma_Rdma_Rdma*#def_Rdma_Rdma_Rdma*#def_Rdma_Rdma*#define 3
    
    
    
    
    
    (#define 3)#define SC_
    (1<<16)
    #define SCI_SET_RX_DMA (1<<17)
    #define SCI_SET_RX_DMA_ALL (1<<18)
    
    void dmaConfigCtrlPacket (g_dmaCTRL_pkt, uint32 src_addr,uint32 dest_addr,uint32 data_size,
    uint32 port_assign、uint32 mode_read、uint32 mode_write、uint32 frame_dest_offset)
    {
    ctrl_pkt->Sadd = src_addr;/*源地址 */
    Ctrl_pkt->DADD = dest_addr;/*目的地址 */
    CTRL_pkt->CHCTRL = 0;/*通道控制 */
    Ctrl_pkt->FRCNT= DATA_SIZE;/*帧计数 */
    Ctrl_pkt->ELCNT = 1;/*元素计数 */
    CTRL_pkt->ELDOFFSET = 0;/*元素目标偏移*/
    Ctrl_pkt->ELSOFFSET = 0;/*元素源偏移量 */
    CTRL_pkt->FRDOFFSET = FRAME_DEST_OFFSET;/*帧目标偏移*/
    CTRL_pkt->FRSOFFSET = 0;/*帧源偏移 //
    Ctrl_pkt->PORTASGN = port_assign;//端口 b */
    CTRL_pkt->RDSIZE = ACCESS_8_BIT;/*读取大小 */
    CTRL_pkt->WRSIZE = ACCESS_8_BIT;/*写入大小 //
    Ctrl_pkt->tType = block_transfer;//传输类型 */
    Ctrl_pkt->tType = FRAME_TRANSFRAME;/*传输类型 */
    CTRL_pkt->ADDMODERD = MODE_READ;读取/*地址模式 */
    CTRL_pkt->ADDMODEWR = MODE_WRITE;/*地址模式写入 //
    Ctrl_pkt->AUTOINIT = AUTOINIT_OFF;//自动初始化 //
    }
    
    void prepareDummyDMARequest (g_dmaCTRL* ctrl_pkt_1、g_dmaCTR* ctrl_pkt_2)
    {
    //启用 SCI 4作为环回*
    if (ctrl_pkt_2!= NULL)
    {
    sciEnableLoopback (sciREG4、Analog LBK);
    //EnsciableLbK、}
    
    
    //while (((sciREG4->FLR & SCI_TX_INT)=0U)||((sciREG4->FLR & 0x4)=0x4)
    //{
    //}/* Wait */
    
    * Assign DMA Request SCI4 transmit to Channel 1*/
    dmaReqAssign (sc_ch1、SCI2、dma_dma_dma_dma_4
    
    )
    
    
    
    ;/将 dma_dma_dma_dma_dma_q4 transmit (SCI2、dma_dma_dma_dma_dma_2) dma_dma_dma_2、dma_dma_dma_dma_q4
    
    /*配置 DMA 控制数据包*/
    dmaConfigCtrlPacket (Ctrl_pkt_1、(uint32)(&dma_dum_tx)、SCI4_TX_ADDR、dummy_size、Porta_Read_PORTB_write、 ADDR_INC1、ADDR_FIXED、0);
    IF (CTRL_pkt_2!= NULL)
    {
    dmaCtrlPacket (CTRL_pkt_2、SCI4_RX_ADDR、(UINT32)(&dma_dum_RX)、dummy_size、PORTB_Read_Porta_write、 Addr_fixed、ADDR_INC1、0);
    }
    
    ////*设置通道1和2的控制包*/
    dmaSetCtrlPacket (DMA_CH1、* Ctrl_pkt_1);
    if (Ctrl_pkt_2!= NULL)
    {
    dmaSetCtrlPacket (DMA_CH2、* Ctrl_pkt_2);if (ctrl_init_dmaCt_in2)
    
    
    }(
    如果已完成)、
    
    
    
    
    
    则启用 dmaCta_intran1、dma1、dmaTa_interrupt 1、dmaTma (dta_inta_inta_in2)
    
    }
    
    void startDummyDMARequest (g_dmaCTRL* ctrl_pkt_1、g_dmaCTRL* ctrl_pkt_2)
    {
    /*将标志重置为“未完成”*/
    dma_Comp_Flag = dma_dummy_flag;
    memset (dma_dum_RX、0、dma_size * sizeof (uint8));
    
    /*设置 DMA 通道0和1以在硬件请求时触发*/
    dmaSetChEnable (dma_ch1、dma_chHW);
    
    if (ctrl_pkt_2!= NULL)
    {
    dma_ch_dma_transmit dma_tma_tma_ch4
    }
    
    ;dma_tma_tma_chall_dma_tma_chEnable (dma_tma_tma_tma_ch4
    
    
    
    
    
    /*将标志设置为完成*/
    //dma_Comp_Flag = 0x55AAD09E;
    dma_Comp_Flag =~dma_Comp_Flag;
    
    //禁用 RX DMA 中断*/
    sciREG3->CLEARINT = SCI_SET_RX_DMA | SCI_SET_RX_DMA_ALL;
    
    //禁用 TX 和 RX 中断* sci_RX_Rdma_SET
    
    | SCI_RX_Rdma_Rdma_SET = SC_Rdma_Rdma_SET_Rdma_Rdma_Rdma_Rdma_Rdma_ALL;// SC_Rdma_SET
    
    #pragma weak (dmaGroupANotification)
    void dmaGroupANotification (dmaInterrupt_t inttype、uint32 channel)
    {
    //在用户代码开始和用户代码结束之间输入用户代码。 //
    //*用户代码开始(8)*/
    if (channel == 0)
    {
    channel0_interrupted = true;
    sci_printf ("DMA channel 0 interrupted \r\n);
    }
    否则(channel == 1)
    {
    channel1_interrupted = true;
    sci_printf ("DMA channel 1 interrupted \r\n);
    }
    channel2
    
    = true (channel1 interrupted);否则= true);channelchannel = true (channel2 = true)
    SCI_printf ("DMA 通道2中断\r\n);
    }
    
    Update_dma_Comp_Flag ();
    //用户代码结束*/
    } 

    就像信息一样:-)

    此致、

    Julio

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

    如果这在数字回送中工作、但不是模拟回送、则意味着您的引脚多路复用器未配置为将这些功能引入物理缓冲器/引脚。 您能否检查多路复用器选择?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你好、Chuck、

    当我创建一个新项目来测试这个时、我忘记激活串行接口的 pinmux。 这也可能是我激活 SCI RX 中断的原因。 我现在正在获取传感器数据:-)

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

    问题是否已解决?