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.

[参考译文] AM2634:EDMA3 ParRAM 配置问题

Guru**** 2412050 points
Other Parts Discussed in Thread: AM2634

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1111167/am2634-edma3-parram-configuration-question

器件型号:AM2634

您好!

我需要使用 AM2634中的 EDMA 和 FSI、通过快速串行链路通道将四个 ADC 的几(4)个采样值传输到配套芯片。 配置后、这些采样值的数据传输必须无限运行、无需任何进一步的 CPU 干预。 在这种情况下、CPU 代码仅用于配置目的、用于故障情况下的异常处理。

设置/配置通过以下方式完成:

- ADC 确实对一个差分输入(名为 Ai、Bi、Ci 和 Di)上的电压进行采样。 采样值存储在每个 ADC 的结果寄存器中。 采样间隔应为~ 2usec。

- ADC_A (来自输入 Ai)应通过其转换事件结束(EOC)触发 EDMA 通道(CH0)。 该通道应将采样值 SAMPLE_A 传输到 FSI 通道的数据 RAM 部分。 单个字传输完成后,它将“触发”(使用“链接”?) 下一个 EDMA 通道(CH1)执行相同的操作、但这次是来自 ADC_B 的样本"SCALE_B"、表示 Bi。 此单字传输的目标地址最多为两个字节、以便将 Bi 的采样值对齐到 Ai 的 SAMPLE_A 之上。 此机制使用 EDMA 通道 CH2和 CH3为 CI 和 Di 重复此机制。

- EDMA 通道 CH3 "触发"CH4、它基本上会将代码/命令字写入相应的 FSI 通道、以开始将四个采样值传输到外部配套芯片。

- FSI 传输完成后、应使用第五个 DMA 通道(CH5)复位所用 Tx FSI 通道内的内部 RAM 地址指针、以确保正确地选择接下来的四个样本。 FSI 通道中的数据 RAM 不是 FIFO。 因此、在当前传输完成后、每次都需要重寻址多达16个字的地址指针。 否则、Tx FSI 数据 RAM 中的位置会有所不同。

(随附的方框图显示了我尝试实现的目标)

到目前为止都很好。 现在、问题是:

Q1:如何设置 EDMA 的 ParRAM 来实现这一目标? 特别是如何在 ParRAM 中配置选项寄存器?

Q2:我是否需要通道链接、因为它必须在设置后运行无限次?

问题3:为了完成此设置、是否应使用一个示例?

Q4:AM2634的 TRM 在 EMDA 描述方面不完整。 我找到了 TI 的另一个文档。 "KeyStone 架构
增强型直接存储器存取(EDMA3)控制器用户指南"(sprugs5b.pdf)这是否可用于 AM2634上的 EDMA3?

BR

Markus

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

    我尝试使用两个 DMA 通道来简化上述架构。 这两个通道应进行链路、并应链接其中的每一个通道以在 EDMA3上创建连续模式。 我不确定是否理解正确。 在下面显示的设置代码中、我使用 dmaCh0和 dmaCh1。dmaCh0应从 ADC 的 EOC 标志触发。dmaCh0应从 ADC 读取结果寄存器、并将其写入 FSI Tx 通道2的环形缓冲器的开头。 完成此操作后、它应"触发"链式 DMA 通道 dmaCh1。dmaCh1用于启动 FSI Tx 传输。 这是通过将启动代码字写入 FSI Tx 2发送器单元的控制寄存器来实现的。

    上述情形应重复多次、然后 dmaCh0和 dmaCh1的通道链接应重新加载其 param 集以使其保持连续。

    当我运行下面显示的代码时、有时我会运行。 但是、启用 DMA 触发器似乎是一个问题。 可能也是整个 EDMA 的配置问题。 如果有任何帮助或提示、我们将不胜感激。

    BR

    Markus

    uint16_t App_dmaConfigure
           uint32_t dac_base、uint16_t table_size、EDMA_handle dma_handle、
           uint32_t dma_ch、uint32_t adc_base)


       uint32_t           baseAddr、RegionID;

       EMDMACCPaRAMEntry   edmaParam0、edmaParam32;//为'dmaCh0'设置参数
       EMDMACCPaRAMEntry   edmaParam1、edmaParam33;//为'dmaCh1'设置参数

       uint32_t           dmaCh0、tcc0、param0、param32;// ch0的资源引用
       uint32_t           dmaCh1、tcc1、param1、param33;// ch1的资源引用

       int32_t            testStatus = SystemP_Success;

       baseAddr = EDMA_getBaseAddr (gEdmaHandle[0]);
       DebugP_assert (baseAddr!= 0);

       RegionID = EDMA_getRegionId (gEdmaHandle[0]);
       DebugP_assert (RegionID < SOC_EDMA_NUM_REGIONS);

       /* DMA 通道0和参数集'param32'用于'通道链接'至。
        *使其成为连续模式通道。
        *

       dmaCh0 = dma_ch;
       testStatus = EDMA_LOADDMAChannel (gEdmaHandle[0]、&dmaCh0);
       DebugP_assert (testStatus = SystemP_Success);

       tcc0 = EDMA_resource_alloc_any;
       testStatus = EDMA_LOADTcc (gEdmaHandle[0]、_tcc0);
       DebugP_assert (testStatus = SystemP_Success);

       参数0 = EDMA_resource_alLOC_ANy;
       testStatus = EDMA_allocParam (gEdmaHandle[0]、&param0);
       DebugP_assert (testStatus = SystemP_Success);

       param32 = edma_resource_alloc_any;//针对 dmaCh0的通道链接 param 参考
       testStatus = EDMA_allocParam (gEdmaHandle[0]、&param32);
       DebugP_assert (testStatus = SystemP_Success);

       /*请求通道0 */
       EDMA_configureChannelRegion (baseAddr、RegionID、EDMA_channel_type_DMA、
            dmaCh0、tcc0、param0、EDMA_TEST_EVT_queue_no);

       /*在轮询模式下禁用要传输的通道中断*/
       EDMA_disableEvtIntraRegion (baseAddr、RegionID、dmaCh0);

       /* DMA 通道1。 这是要从通道0链接到的通道。
        *
        *
       dmaCh1 = EDMA_resource_alloc_any;
       testStatus = EDMA_LOADDMAChannel (gEdmaHandle[0]、&dmaCh1);
       DebugP_assert (testStatus = SystemP_Success);

       tcc1 = EDMA_resource_alloc_any;
       testStatus = EDMA_LOADTcc (gEdmaHandle[0]、_tcc1);
       DebugP_assert (testStatus = SystemP_Success);

       param1 = EDMA_resource_alloc_any;
       testStatus = EDMA_allocParam (gEdmaHandle[0]、&param1);
       DebugP_assert (testStatus = SystemP_Success);

       param33 = EDMA_resource_alloc_any;
       testStatus = EDMA_allocParam (gEdmaHandle[0]、&param33);
       DebugP_assert (testStatus = SystemP_Success);

       /*请求通道1 */
       EDMA_configureChannelRegion (baseAddr、RegionID、EDMA_channel_type_DMA、
            dmaCh1、tcc1、param33、EDMA_TEST_EVT_queue_no);

       /*在轮询模式下禁用要传输的通道中断*/
       EDMA_disableEvtIntraRegion (baseAddr、RegionID、dmaCh1);

       /*程序参数集 edmaParam0、edmaParam32 */
       EDMA_ccPaRAMEntry_init (&edmaParam0); //清除参数集
       EDMA_ccPaRAMEntry_init (&edmaParam32);//。

       edmaParam0.srcAddr      =(uint32_t) SOC_virtToPhy ((void *)(adc_base_cSL_adc_result_adcsesULT0));
       edmaParam0.destAddr     =(uint32_t) SOC_virtToPhy ((void *)(CONFIG_FSI_TX2_BASE_ADDR + FSI_TX_DBUF_BAS_ADDR);
       edmaParam0.aCnt         =(uint16_t) 2;
       edmaParam0.bcnt         =(uint16_t) table_size;
       edmaParam0.ccnt         =(uint16_t) 1;
       edmaParam0.bCntReload   = 0;
       edmaParam0.srcBIdx      =(int16_t) 0;
       edmaParam0.destBIdx     =(int16_t) 0;//始终写入到相同的位置
       edmaParam0.srcCIdx      =(int16_t) 0;
       edmaParam0.destCIdx     =(int16_t) 0;
       edmaParam0.linkAddr     = 0xFFFFFFU;
       edmaParam0.opt          =(EDMA_OPT_TCINTEN_MASK | EDMA_OPT_TCCHEN_MASK |
                                   (((((uint32_t) tcc0)<< EDMA_opt_TCC_SHIFT)& EDMA_opt_TCC_MASK);

       EDMA_setPaRAM (baseAddr、param0、edmaParam0);

       //用于 dmaCh0的“通道链接”
       edmaParam32.srcAddr      =(uint32_t) SOC_virtToPhy ((void *)(adc_base_cSL_adc_result_adcsesULT0));
       edmaParam32.destAddr     =(uint32_t) SOC_virtToPhy ((void *)(CONFIG_FSI_TX2_BASE_ADDR + FSI_TX_DBUF_BAS_ADDR);
       edmaParam32.aCnt         =(uint16_t) 2;
       edmaParam32.bCnt         =(uint16_t) table_size;
       edmaParam32.ccnt         =(uint16_t) 1;
       edmaParam32.bCntReload   = 0;
       edmaParam32.srcBIdx      =(int16_t) 0;
       edmaParam32.destBIdx     =(int16_t) 0;//始终写入到相同的位置
       edmaParam32.srcCIdx      =(int16_t) 0;
       edmaParam32.destCIdx     =(int16_t) 0;
       edmaParam32.linkAddr     = 0xFFFFFFU;
       edmaParam32.opt          =(EDMA_OPT_TCINTEN_MASK | EDMA_OPT_TCCHEN_MASK |
                                    (((((uint32_t) tcc0)<< EDMA_opt_TCC_SHIFT)& EDMA_opt_TCC_MASK);

       EDMA_setPaRAM (baseAddr、param32、edmaParam32);
       
       EDMA_linkChannel (baseAddr、param0、param32);
       EDMA_linkChannel (baseAddr、param32、param32);

       /*程序参数集 edmaParam1、edmaParam33 */
       EDMA_ccPaRAMEntry_init (&edmaParam1); //清除参数集
       EDMA_ccPaRAMEntry_init (&edmaParam33);//。

       edmaParam1.srcAddr      =(uint32_t) SOC_virtToPhy ((void *)(&gFSICh2TxStartWord4DMA);
       edmaParam1.destAddr     =(uint32_t) SOC_virtToPhy ((void *)(CONFIG_FSI_TX2_BASE_ADDR + CSL_FSI_TX_CFG_TX_FRAME_CTRL);
       edmaParam1.aCnt         =(uint16_t) 2;
       edmaParam1.bCnt         =(uint16_t) table_size;
       edmaParam1.ccnt         =(uint16_t) 1;
       edmaParam1.bCntReload   = 0;
       edmaParam1.srcBIdx      =(int16_t) 0;
       edmaParam1.destBIdx     =(int16_t) 0;//始终写入到相同的位置
       edmaParam1.srcCIdx      =(int16_t) 0;
       edmaParam1.destCIdx     =(int16_t) 0;
       edmaParam1.linkAddr     = 0xFFFFFFU;
       edmaParam1.op=          (EDMA_OPT_TCINTEN_MASK | EDMA_OPT_TCCHEN_MASK |
                                   (((((uint32_t) tcc1)<< EDMA_opt_TCC_SHIFT)& EDMA_opt_TCC_MASK);

       EDMA_setPaRAM (baseAddr、param1、edmaParam1);

       edmaParam33.srcAddr      =(uint32_t) SOC_virtToPhy ((void *)(&gFSICh2TxStartWord4DMA);
       edmaParam33.destAddr     =(uint32_t) SOC_virtToPhy ((void *)(CONFIG_FSI_TX2_BASE_ADDR + CSL_FSI_TX_CFG_TX_FRAME_CTRL);
       edmaParam33.aCnt         =(uint16_t) 2;
       edmaParam33.bcnt         =(uint16_t) table_size;
       edmaParam33.ccnt         =(uint16_t) 1;
       edmaParam33.bCntReload   = 0;
       edmaParam33.srcBIdx      =(int16_t) 0;
       edmaParam33.destBIdx     =(int16_t) 0;//始终写入到相同的位置
       edmaParam33.srcCIdx      =(int16_t) 0;
       edmaParam33.destCIdx     =(int16_t) 0;
       edmaParam33.linkAddr     = 0xFFFFFFU;
       edmaParam33.opt          =(EDMA_OPT_TCINTEN_MASK | EDMA_OPT_TCCHEN_MASK |
                                    (((((uint32_t) tcc1)<< EDMA_opt_TCC_SHIFT)& EDMA_opt_TCC_MASK);

       EDMA_setPaRAM (baseAddr、param33、edmaParam33);

       EDMA_linkChannel (baseAddr、param1、param33);
       EDMA_linkChannel (baseAddr、param33、param33);

       //为链传输设置参数。dmaCh0要链接到 dmaCh1
       EDMA_chainChannel (baseAddr、param0、dmaCh1、(EDMA_OPT_TCCHEN_MASK | EDMA_OPT_ITCCHEN_MASK));

       //为所有通道启用触发器。
       EDMA_enableTransferRegion (baseAddr、RegionID、dmaCh0、EDMA_TRIG_MODE_MANUAL);//需要???
       EDMA_enableTransferRegion (baseAddr、RegionID、dmaCh0、EDMA_TRIG_MODE_EVENT);
       返回 testStatus;

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

    Markus、您好!

    DMA 触发器 XBAR 是否配置为将 FSI 触发器路由到相应的 DMA 通道?  您可以使用"FSI_LOOP_DMA"示例的 SYSCFG 配置作为相同示例的参考。

    当使用多个 ADC 通道时、每个 ADC EOC 应触发相应的 DMA 通道。 DMA 通道不应链接在一起以传输 ADC 结果。 问题是无法保证 ADC 转换和 DMA 传输之间的同步。 您可以将对应于最后一个 ADC 的 EDMA 连接起来、以触发另一个 EDMA 通道来启动 FSI 传输。

    问题1:如何设置 EDMA 的参数来实现这一点? 特别是如何在 Param 中配置选项寄存器?

      A -您可以使用"ADC_SOC_Continuous_DMA"和"FSI_loopback_DMA" 示例作为参考、以配置 DMA 从 ADC 传输到 FSI、同时启动 DMA 传输。

    Q2:我是否需要通道链接、因为它必须在设置后运行无限次?

      答-是的、无限传输需要链接。

    问题3:为了完成此设置、是否应使用一个示例?

      A -不、我们没有这个设置的直接示例。

    Q4:AM2634的 TRM 在 EMDA 描述方面不完整。 我找到了 TI 的另一个文档。 "KeyStone 架构
    增强型直接存储器存取(EDMA3)控制器用户指南"(sprugs5b.pdf)这是否可用于 AM2634上的 EDMA3?

      A -是的、这可被用作一个基准。

    此致、

    Ashwin