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.

[参考译文] ADC-AM263X:多个 MCU-PLUS-SDK 到 DMA 缓冲器的持续采样

Guru**** 2763545 points

Other Parts Discussed in Thread: SYSCONFIG

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1319076/mcu-plus-sdk-am263x-continuous-sampling-of-multiple-adcs-to-dma-buffers

器件型号:MCU-PLUS-SDK AM263X
主题中讨论的其他器件:SysConfig

我需要配置多个 ADC 通道以连续 读取电压并将样本存储到 RAM

 所有通道的采样频率都需要约为200Hz。 因此、我想使用 DMA。

我正在 尝试对 TI-TMDSCNCD263-AM263x Sitara 控制卡进行概念验证。

SDK 示例似乎为 adc_soc_continuous_dma_am263x-cc_r5fss0-0_nortos_ti-arm-clang。

我有这个示例可以运行、但 SDK 示例填充 DMA 缓冲区、然后停止。 这不是我想要的。

我想要修改示例、以便应用层事件可以随时复制 DMA 缓冲区、从而获取最近样本的快照。  如果需要的话、暂时禁用中断来复制数据不是一个问题。

我 曾尝试 在 ISR 中删除函数调用(见此处)、我怀疑这可能会停止我想要的"从 ADC 到 DMA 的连续"。  

void App_adcISR(void *args)
{
    /* Remove ePWM trigger */
    EPWM_disableADCTrigger(CONFIG_EPWM0_BASE_ADDR, EPWM_SOC_A);

    /* Disable this interrupt from happening again */
    ADC_disableInterrupt(gAdc1baseAddr, ADC_INT_NUMBER1);
}

void App_dmach0ISR(Edma_IntrHandle intrHandle, void *args)
{
    SemaphoreP_Object *semObjPtr = (SemaphoreP_Object *)args;
    DebugP_assert(semObjPtr != NULL);

    /* Stop the ADCs by removing the trigger for SOC0 */
    ADC_setInterruptSOCTrigger(gAdc1baseAddr, ADC_SOC_NUMBER0,
                               ADC_INT_SOC_TRIGGER_NONE);
    ADC_setInterruptSOCTrigger(gAdc2baseAddr, ADC_SOC_NUMBER0,
                               ADC_INT_SOC_TRIGGER_NONE);

    /* Post the semaphore to signal end of DMA transfer */
    SemaphoreP_post(semObjPtr);
}

然而,当我在 App_dmach0ISR()中设置一个断点时,它只被命中一次。

请建议为实现 "到 DMA 的连续 ADC"、需要执行哪些操作。

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

    尊敬的 Tollman:

    该示例展示了我们如何使用 ADC INT 触发 DMA 传输、在本例中、ADC 结果传输到 RAM 中的缓冲区。 DMA 被配置为一定数量的传输、不超过该数量。 如果您想要进行无限传输、则必须在参数集到期之前修改 DMA 配置以实现非常大量的传输、而当参数集到期时、请使用中断来重新配置以进行又一次大量的传输。  

    您的请求是、根据应用的需要、DMA 应将最新的转换数据传输到 RAM、这不是连续的 ADC-DMA 传输。 如果我理解错了、请更正我。 但是,如果是这样,您不必将 DMA 配置为由 ADC 触发,而是可以由软件触发,就像任何其他 DMA 轮询传输一样,请参阅: https://software-dl.ti.com/mcu-plus-sdk/esd/AM263X/09_01_00_41/exports/docs/api_guide_am263x/EXAMPLES_DRIVERS_EDMA_POLLED_TRANSFER.html

    请阐明适合您的方法、以便我们可以尝试为您提供帮助。

    谢谢。此致、

    马德哈瓦

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

    感谢响应  Madhava。  

    查看您发布的内容、查看您引用的 SDK 示例并再次阅读参考手册后、似乎一种可行的 解决方案 是在该领域使用

     链接地址(LINK)

    ...在 EDMA Channel Param 设置中。  

    我认为、这应该可以 在不需要处理器干预的情况下实现 ADC 结果到交替(乒乓) RAM 缓冲器的持续传输。

    是这样吗?

    此致、

    托尔曼

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

    Tollman、

    可以。 这种方法是正确的。 EDMA 链接传输示例可用于引用此类配置。

    谢谢。此致、

    马德哈瓦

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

    Madhava,

     很抱歉耽误你的时间、其他任务抢占了这个项目。

     

    我尝试修改了 SDK 示例:

     adc_soc_continuous_dma_am263x-cc_r5fss0-0_nortos_ti-arm-clang

    使用该交替的两个参数集。

     我尝试通过以下方式实现这一目标:

    • 创建第二个参数集。
    • 修改 链接地址  ‘param 中、将"point to"设置为第2个、反之亦然。 我正在使用  EDMA_allocParam ()按获得这些值、但我不确定这是正确的。
    • 修改 bCntReload ‘"表大小"。 我不确定这是正确的。 我尝试对该值同时使用表大小和零。
    • 排除 ISR 中在缓冲区填满后禁用 ADC 采样的语句。 请参阅( #ifdef s Top_采样_时_缓冲区_满 )。
    • 使主‘成为"永久循环"、因此我可以设置断点并检查 gAdc1DataBuffer 和  gAdc2DataBuffer

     

    结果:

    • 应用程序_dmach0ISR ()不会按要求执行多次。 我希望 ISR 在每个 param set 开关之后执行。
    • 当在"‘循环"中停止秒间隔时、 gAdc1DataBuffer gAdc2DataBuffer 值不会按预期变化。

     

    我将附加修改后的 adc_soc_continuous_dma_am263x-cc_r5fss0-0_nortos_ti-arm-clang 项目。

    这是怎么了?

    此致、

    斯科特

    e2e.ti.com/.../adc_5F00_soc_5F00_continuous_5F00_dma_5F00_am263x_2D00_cc_5F00_r5fss0_2D00_0_5F00_nortos_5F00_ti_2D00_arm_2D00_clang_2800_20240220_5F00_0745_2D00_PingPongTest01_2900_.zip

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

    Scott、您好、

    修改 链接地址  ‘param 中、将"point to"设置为第2个、反之亦然。 我正在使用  EDMA_allocParam ()为这些值,但我不确定这是正确的。

    您是否可以按照如下方式使用 API 尝试链接?  这基本上使参数1点到 参数2。 用完1后、将复制2。 另外, param 2指向2,因此,当复制到 param 1,它仍然喜欢 param 2在用尽后被复制。

    • EDMA_linkChannel (baseAddr、param1、param2 );
    • EDMA_linkChannel (baseAddr、Param2、Param2 );
    修改 bCntReload ‘"表大小"。 我不确定这是正确的。 我尝试对该值同时使用表大小和零[/引号]

    我不确定这是否需要给指定的用例。  

    void App_adcISR(void *args)
    {
    #ifdef   STOP_SAMPLING_WHEN_BUFFER_FULL
        /* Remove ePWM trigger */
        EPWM_disableADCTrigger(CONFIG_EPWM0_BASE_ADDR, EPWM_SOC_A);
    
        /* Disable this interrupt from happening again */
        ADC_disableInterrupt(gAdc1baseAddr, ADC_INT_NUMBER1);
    #endif  // STOP_SAMPLING_WHEN_BUFFER_FULL
    }
    

    这用于在第一个 ADC 之后停止从 EPWM 触发 ADC、因为 ADC SOC 配置为从 ADCINT 和 EPWM_SOCx 获取触发。 现在只有一个 ADCINT 用于连续触发 ADC SOC。 因此您可以删除此处的#ifdef。

    该示例是针对勘误权变措施而设计的。 有一个 empty_param ParamSet、它复制1 soc、然后链接到 param1。 现在、param1将传输1个 soc。 一旦 param1耗尽、我们希望将 param2转移、但请注意、empty_param 不与任何链接、将在耗尽时保留、并会使任何进一步的触发失效、而不会再链接到 param1。  

    步骤将是...

    1. empty_param 和 param1都具有重复的内容。 实际参数集链接到重复项、重复项链接到自身。   
    2. 应该为原稿和重复项启用链接,以便在复印时保留链接配置。
    3. 如果您希望增加实际 ParamSet 中要传输的 SOC 的数量、我们可能必须将其更改为实际参数集的 AB 同步模式、并将 bCnt 。 但基本情况可以在稍后尝试。  

    谢谢。此致、

    马德哈瓦

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

    尊敬的 Madhava:

    感谢您的帮助。

    我按照您的建议进行了更改。 现在我看到 ADC 缓冲区不断更新,App_dmach0ISR()不断 被 调用。 这是一个很好的进展。

    我需要以大约1kHz 的频率对全部30个模拟输入进行采样、并在处理每个通道的256个样本后处理缓冲器。  我计划相应地更改 SysConfig 中的 ADC 时钟预分频器和 SOC 配置、

    在执行此操作之前 、我要处理 缓冲区组织。

    首先、我想让 ADC 结果缓冲器位于多维 阵列中、而不是 SDK 示例中的各个缓冲器。

    为此、我定义尺寸:

    /**
      *  Ping-pong buffers
      */
    #define ADC_BUFFER_NUM          (2U)
    
    /**
      *  AM263x ADC modules
      */
    #define ADC_MODULE_NUM          (5U)
    
    /**
      *  AM263x ADC channels per modules
      */
    #define ADC_CHANNEL_NUM          (6U)
    
    /**
      *  Depth of sample buffer per channel.
      */
    #define ADC_SAMPLE_NUM          (256U)
    
    /**
      *  Size of the entire buffer of a Module. (ping or pong)
      *  Note:  x 2 for uint16_t
      */
    #define ADC_MODULE_BUFFER_SIZE  (ADC_CHANNEL_NUM * ADC_SAMPLE_NUM * 2)

    然后定义用于保存结果的默认缓冲数组:  

    /**
      *  This buffer holds all analog input data. It is written by EDMA.
      *  All channels for all modules are sampled round robin, with one SOC per channel
      *  For ADC0 AdcInBuf[0][0] will fill completely, then AdcInBuf[0][1] before starting
      *  to fill AdcInBuf[0][0] again switching in a ping-pong pattern. An interrupt is triggered
      *  upon each switch to allow processing.
      */
    uint16_t AdcInBuf[ADC_MODULE_NUM][ADC_BUFFER_NUM][ADC_CHANNEL_NUM][ADC_SAMPLE_NUM];

    然后   调整 App_dmaConfigure()调用以便为每个 ADC 模块调用。 我对 这里的所有参数都不是很有信心:

    /* 
     * Configure DMA channels to transfer ADC results.
     * Note: This function assumes the dest buffer points to a 2D (ping pong) buffer of size (ADC_MODULE_BUFFER_SIZE * 2)
     */
    App_dmaConfigure(AdcInBuf[0], ADC_MODULE_BUFFER_SIZE, gEdmaHandle[0],
                ADC0_EDMA_CHANNEL, CONFIG_ADC0_RESULT_BASE_ADDR, &tccAlloc0, EDMA_TEST_EVT_QUEUE_NO_0);
    
    App_dmaConfigure(AdcInBuf[1], ADC_MODULE_BUFFER_SIZE, gEdmaHandle[0],
                ADC1_EDMA_CHANNEL, CONFIG_ADC1_RESULT_BASE_ADDR, &tccAlloc1, EDMA_TEST_EVT_QUEUE_NO_1);
    
    App_dmaConfigure(AdcInBuf[2], ADC_MODULE_BUFFER_SIZE, gEdmaHandle[0],
                ADC2_EDMA_CHANNEL, CONFIG_ADC2_RESULT_BASE_ADDR, &tccAlloc2, EDMA_TEST_EVT_QUEUE_NO_2);
    
    App_dmaConfigure(AdcInBuf[3], ADC_MODULE_BUFFER_SIZE, gEdmaHandle[0],
                ADC3_EDMA_CHANNEL, CONFIG_ADC3_RESULT_BASE_ADDR, &tccAlloc3, EDMA_TEST_EVT_QUEUE_NO_3);
    
    App_dmaConfigure(AdcInBuf[4], ADC_MODULE_BUFFER_SIZE, gEdmaHandle[0],
                ADC4_EDMA_CHANNEL, CONFIG_ADC4_RESULT_BASE_ADDR, &tccAlloc4, EDMA_TEST_EVT_QUEUE_NO_4);
    
    App_dmaConfigure(AdcInBuf[5], ADC_MODULE_BUFFER_SIZE, gEdmaHandle[0],
                ADC5_EDMA_CHANNEL, CONFIG_ADC5_RESULT_BASE_ADDR, &tccAlloc5, EDMA_TEST_EVT_QUEUE_NO_5);

    然后   修改 App_dmaConfigure()以考虑乒乓机制。

    uint16_t App_dmaConfigure(
            const uint16_t *table, uint16_t table_size,
            EDMA_Handle dma_handle, uint32_t dma_ch,
            uint32_t adc_base, uint32_t *tccAlloc, uint32_t event_queue_number)
    {
    //...

    ... App_dmaConfigure() ping 缓冲区参数

    //...
        //Each CSL_ADC_RESULT_ADCRESULTx address offset is 2-bytes apart.
        //Param set 1
        EDMA_configureChannelRegion(baseAddr, regionId, EDMA_CHANNEL_TYPE_DMA,
                dmaCh, tcc, param1, event_queue_number);
        /* Program Param Set 1 (ping buffer)*/
        EDMA_ccPaRAMEntry_init(&edmaParam);
        edmaParam.srcAddr       = (uint32_t) SOC_virtToPhy((void *)(adc_base+CSL_ADC_RESULT_ADCRESULT0));
        edmaParam.destAddr      = (uint32_t) SOC_virtToPhy((void *)table);
        

    ...  App_dmaConfigure() pong buffer params

        //Param set 2
        EDMA_configureChannelRegion(baseAddr, regionId, EDMA_CHANNEL_TYPE_DMA,
                dmaCh, tcc, param1, event_queue_number);
        /* Program Param Set 2 (pong buffer)
         * Note: destAddr = table + table_size
         */
       
        EDMA_ccPaRAMEntry_init(&edmaParam);
        edmaParam.srcAddr       = (uint32_t) SOC_virtToPhy((void *)(adc_base+CSL_ADC_RESULT_ADCRESULT0));
        edmaParam.destAddr      = (uint32_t) SOC_virtToPhy((void *)table + table_size); 

    我尚未解决  "AB 同步模式"问题、 稍后我将解决该问题。

    edmaParam.srcAddr 假定每个 CSL_ADC_RESULTx 地址偏移相隔2个字节、但我希望在设置同步模式后、传输会将 CSL_ADC_RESULTx 复制到 AdcInBuf[][][][x]。

    该架构合理吗?

    如果是、我将尝试配置"AB 同步模式"参数。

    此致、

    托尔曼

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

    更新:

    我一直在研究 同步 EDMA 转移。

    我发现这个论坛的讨论,似乎是相关的:

    2D AB-Syncronized EDMA 传输-处理器论坛-处理器- TI E2E 支持论坛

    即、它正在传输音频样本块。 我正在查看本材料、以期待您的回复。

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

    尊敬的 Tollman:

    然后   将 App_dmaConfigure()调用调整为每个 ADC 模块调用。 我对 这里的所有参数都没有信心:

    DMA 中只有两个队列。 该示例展示了每个对的 ADC 传输。

    请阐明是否必须在一个触发条件中传输更多的 ADC-SOC-Results。 信道 ADC 只有几个 INT、但每个信道有16 SOC/ 6个通道。 如果是、那么您可以对实际通道进行配置、一次性传输更多的 SOC 结果。  

    ……  APP_DMAConfigure() pong 缓冲器参数

    在代码中、   `edmaParam.destAddr   =(uint32_t) SOC_virtToPhy ((void *) table + table_size);`为什么会这样?  

    AM263x 中的 EDMA 能够通过其在 DMA/QDMA 通道上的链接/链式传输实现 A/AB/传输中的高级传输、并具有可以来自 SoC 上的许多外设/子系统的触发器。 我强烈建议参考 TRM 中的 EDMA 部分和 EDMA 的 SDK 示例、以便更好地集成到应用中、这可以帮助您节省采用不同方法的时间。   

    谢谢。  

    马德哈瓦

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

    我已经阅读过 TRM、论坛帖子(如上所述)和培训视频。 我还将查看 EDMA SDK 示例。  

    我将尝试使用此信息来修改代码、看看我是否能使它正常工作。  

    同时、关于您的问题:

    -------------------------------------------------------

    "在 DMA 中只有两个队列。 该示例展示了每个对的 ADC 传输。

    请阐明是否必须在一个触发条件中传输更多的 ADC-SOC-Results。 信道 ADC 只有几个 INT、但每个信道有16 SOC/ 6个通道。 如果是、那么您可以对实际通道进行配置、一次性传输更多的 SOC 结果。 "

    我想您的意思是、由于我要对所有通道进行循环 SOC、因此我只能在通道5 (即最后一个)转换 完成时触发事件。 该事件触发的传输可以传输全部六个 CONFIG_ADCx_RESULT_BASE_ADDR。

    假设如此、我在 TRM SPRUJ17E - 7.4.2.7 EOC 和中断运行模式中看到:

    我没有看到如何 通过 SysConfig 执行此操作。

    如何为 ADC 模块中的所有结果启用一个传输?

     -------------------------------------------------------

    在代码中、   `edmaParam.destAddr   =(uint32_t) SOC_virtToPhy ((void *) table + table_size);`为什么会这样?  

    这‘通过参数集2指向"乒乓缓冲器":

    &AdcInBuf[X][1]

    ...给出:

    uint16_t AdcInBuf[ADC_MODULE_NUM][ADC_BUFFER_NUM][ADC_CHANNEL_NUM][ADC_SAMPLE_NUM];

    明白了吗?

    ----------------

    最初,对于同步 EDMA TransferI 计划:

    acnt = 2 (2字节、uint16_t)。 一个元素。  [** ParamSet.aCnt**]
    BCNT = 6 (通道数组、CONTROLSS_ADCx_RESULTy)。 一帧。  [** ParamSet.bCnt**]
    CCNT = 256 (一个块的样本深度)[**ParamSet.ccn**  ]

    但是 、现在我正在调查:

    ACNT =(2 * 6)(2字节、uint16_t)、* 6个元素/通道。 一帧。  [** ParamSet.aCnt**  ]
    BCNT = 256 (一个块的样本深度) [**ParamSet.bCnt**  ]
    CCNT =  1[**ParamSet.ccn**  ]

    此致、

    托尔曼

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

    尊敬的 Tollman:

    我想您的意思是、由于我要对所有通道进行循环 SOC、因此我只能在通道5 (即最后一个)转换 完成时触发事件。 该事件触发的传输可以传输全部六个 CONFIG_ADCx_RESULT_BASE_ADDR。

    假设如此、我在 TRM SPRUJ17E - 7.4.2.7 EOC 和中断运行模式中看到:

    我没有看到如何 通过 SysConfig 执行此操作。

    如何为 ADC 模块中的所有结果启用一个传输?

    [/报价]

    可以。 假设 SOCx 需要处于连续 CONV 模式、将 INT 1设置为由 SOCy 触发、并将 SOC x 设置为 y 由 INT1触发。 还使用同一个 INT 1来触发 DMA 通道、在这里、如果是传输模式、它可以为 aCnt =(y-x+1)* 2、而不是 aCnt = 2。  

    对于其触发器组中的每个 SOC、有一个中断可以触发它的配置、[下图供参考]  

    这是否合理?

    "对不起,我不小心给弄丢了。"  

    但是 、现在我正在调查:

    ACNT =(2 * 6)(2字节、uint16_t)、* 6个元素/通道。 一帧。  [** ParamSet.aCnt**  ]
    BCNT = 256 (一个块的样本深度) [**ParamSet.bCnt**  ]
    CCNT =  1[**ParamSet.ccn**  ]
    [/报价]

    在 AB 同步传输中、这意味着有6个连续 SOC、但 BCNT 是256很可怕! 如果 ADC 结果对 SOC0-15、PPB RES 0-4有效、总共20个32位的寄存器、并且低位16是每个寄存器中的有效寄存器、为什么您要在单个触发器中传输这么多的数据。 请在此处查看。

    谢谢。此致、

    马德哈瓦

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

    尊敬的  Madhava:

    我 认为我尝试执行的操作可能会产生困惑。 也许是在术语上的混淆。

    我决定从一个更简单的 SDK 示例开始、然后构建最终的解决方案。

    这次我开始使用 SDK 示例:

     adc_soc_epwm_am263x-cc_r5fss0-0_nortos_ti-arm-clang

    采样时基:

    我发现我的第一个错误是使用术语"连续"。 我想、由于我要以大约1ms 的周期进行采样、因此我可以使用 PWM 来触发每个 ADC 通道的 SOC。 通过将优先级模式设置为"基于 SOC 的所有优先级"、我可以按确定的顺序以1ms 连续对每个通道采样。

    目前、我仅使用具有三个通道的 ADC1。

    ADC 接口:

    我现在使最后一个 SOC (通道2)成为 ADC1中断1的源。

    DMA 传输:

    接下来、我将 DMA 通道触发器设置为 ADC1_INT1 (Xbar)

    我还将结果缓冲区 RAM (DMA 目标)调整为(2字节* 256个样本、* 3个通道)。

    测试:

    通过切换 ADC ISR 和 DMA ISR 内的测试点、然后检查结果缓冲区、我可以看到采样正在工作。

    我将两个输入连接到固定电压、第三个输入连接到方波、结果缓冲器看起来不错、即通道交替、ADC1_0以预期的速率切换。

    这是一个缓冲区标记、用于演示:

    在256次传输之后、DMA ISR 将触发。

    现在、我只需要添加乒乓机制。

    添加乒乓模式:

    现在我需要增加乒乓机制、在256次传输后将交换缓冲区。 我还没有这项功能、我怀疑有一个问题可能是我使用 A、B、C 计数。

    您写道:

    在 AB 同步传输中、这意味着有6个连续 SOC、但 BCNT 是256很可怕! 如果 ADC 结果对 SOC0-15、PPB RES 0-4有效、总共20个32位的寄存器、并且低位16是每个寄存器中的有效寄存器、为什么您要在单个触发器中传输这么多的数据。 请在此处查看。

    这使我认为、对于我的三通道示例、'A count'*'B count'应该为6。 即每次传输6个字节。

    这意味着 C 计数应该为256。  即、我希望在 乒乓交换之前对一个256ms 的窗口进行采样。

    如果有必要、请告诉我。

     同时我也在做实验。

    此外、资源还包括:

    KeyStone 架构增强直接存储器存取(EDMA3)控制器(修订版 B)(TI.com)

    ...有效的 AM263x?

    此致、

    托尔曼

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

    尊敬的 Tollman:

    是的、您为 EDMA 共享的文档对于 AM263x 有效、但触发器/SOC 集成的集合可能不同。

    谢谢。

    马德哈瓦

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

    尊敬的  Madhava:

    我做了一些实验、C count =256。

    但是、根据我的测试点以及结果缓冲区中的值、似乎:

    1. 在256个帧且发生 DMA 中断后、Ping 缓冲器填充。
    2.   256帧后、下一个 Pong 缓冲器填充 、并且 DMA 中断发生。
    3. PONG 缓冲器的最后一帧在每个 ADC 中断时更新、并且每个 ADC 中断会触发一个 DMA 中断 。

    即 DMA 位于 PONG 缓冲器的末尾、"tuck"、而 PING 缓冲器绝不会在初始256帧后更新。

    我的参数集配置位于以下代码中:  


        //ConfigureChannelRegion for Param set 1
        EDMA_configureChannelRegion(baseAddr, regionId, EDMA_CHANNEL_TYPE_DMA,
                dmaCh, tcc, param1, event_queue_number);
    
        /* Program Param Set 1 */
        EDMA_ccPaRAMEntry_init(&edmaParam);
        edmaParam.srcAddr       = (uint32_t) SOC_virtToPhy((void *)(adc_base+CSL_ADC_RESULT_ADCRESULT0));
        edmaParam.destAddr      = (uint32_t) SOC_virtToPhy((void *)buf1);
        edmaParam.aCnt          = (uint16_t) 2 * 3;
        edmaParam.bCnt          = (uint16_t) 1;
        edmaParam.cCnt          = (uint16_t) buf_size;
        edmaParam.bCntReload    = 1;
        //edmaParam.bCntReload    = buf_size;
        edmaParam.srcBIdx       = (int16_t) EDMA_PARAM_BIDX(0);
        edmaParam.destBIdx      = (int16_t) EDMA_PARAM_BIDX(0);
        edmaParam.srcCIdx       = (int16_t) 0;
        edmaParam.destCIdx      = (int16_t) 2 * 3;
        edmaParam.linkAddr      = 0xFFFFU;
        edmaParam.srcBIdxExt    = (int8_t) EDMA_PARAM_BIDX_EXT(0);
        edmaParam.destBIdxExt   = (int8_t) EDMA_PARAM_BIDX_EXT(0);
        edmaParam.opt           = (EDMA_OPT_TCINTEN_MASK |
                                  ((((uint32_t)tcc) << EDMA_OPT_TCC_SHIFT) & EDMA_OPT_TCC_MASK));
        /* Enabling the Interrupt for Transfer complete of all the data */
        EDMA_setPaRAM(baseAddr, param1, &edmaParam);
    
    
        //ConfigureChannelRegion for Param set 2
        //EDMA_configureChannelRegion(baseAddr, regionId, EDMA_CHANNEL_TYPE_DMA,
        //            dmaCh, tcc, param2, event_queue_number);
    
        EDMA_ccPaRAMEntry_init(&edmaParam);
        edmaParam.srcAddr       = (uint32_t) SOC_virtToPhy((void *)(adc_base+CSL_ADC_RESULT_ADCRESULT0));
        edmaParam.destAddr      = (uint32_t) SOC_virtToPhy((void *)buf2);
        edmaParam.aCnt          = (uint16_t) 2 * 3;
        edmaParam.bCnt          = (uint16_t) 3;
        edmaParam.cCnt          = (uint16_t) buf_size;
        edmaParam.bCntReload    = 1;
        //edmaParam.bCntReload    = buf_size;
        edmaParam.srcBIdx       = (int16_t) EDMA_PARAM_BIDX(0);
        edmaParam.destBIdx      = (int16_t) EDMA_PARAM_BIDX(0);
        edmaParam.srcCIdx       = (int16_t) 0;
        edmaParam.destCIdx      = (int16_t) 2 * 3;
    
        edmaParam.linkAddr      = 0xFFFFU;
        edmaParam.srcBIdxExt    = (int8_t) EDMA_PARAM_BIDX_EXT(0);
        edmaParam.destBIdxExt   = (int8_t) EDMA_PARAM_BIDX_EXT(0);
        edmaParam.opt           = (EDMA_OPT_TCINTEN_MASK |
                                  ((((uint32_t)tcc) << EDMA_OPT_TCC_SHIFT) & EDMA_OPT_TCC_MASK));
    
        /* Enabling the Interrupt for Transfer complete of all the data */
        EDMA_setPaRAM(baseAddr, param2, &edmaParam);
    
        EDMA_linkChannel(baseAddr, param1, param2);
        EDMA_linkChannel(baseAddr, param2, param1);
    

     你看到问题了吗?

    此致、

    托尔曼

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

    尊敬的 TollMan:

     您看到问题了吗?

    可以。 您正在以以下方式链接:param1 -> param2、param2 -> param1。 但到 Param2耗尽时、正在检查与 param1的链接、该参数现在已耗尽。 您必须链接 param1->param2、param2-> 参数2。 然后、如果您需要不同的缓冲区、我建议使用 param1 (buf1)-> param2 (buf2)-> paramM3 (buf1)->param2 (buf2)。

    谢谢。此致、  

    马德哈瓦

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

    马德哈瓦

    通过使用第三个参数集(PARAM3)并将 PARAM3链接到 PARAM2、可以使用乒乓缓冲器方案。

    感谢您的帮助!

    托尔曼