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.

[参考译文] TMS320F2.8388万D:DMA ISR不适用于高速触发源

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1090240/tms320f28388d-dma-isr-is-not-working-for-high-speed-trigger-source

部件号:TMS320F2.8388万D

您好,

 目前我计划通过DMA将ADC结果数据传输到SDRAM。

ePWM是我的ADC触发源。

ADC中断是DMA传输的触发源。

当我对ADC使用低采样率配置时,DMA工作正常,DMA中断即将出现。

但我通过提高ePWM频率提高了采样率(~1MSPS ),DMA中断不工作,但数据从ADC结果寄存器复制到SDRAM。

我无法找到任何解决此问题的方法,也无法找到为什么高速触发源出现此问题。

请告诉我,当我处理DMA的高速触发源时,如果我在这里遗漏了一些东西。

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

    请参阅以下主题:
    https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1089078/tms320f28388d-adc-samples-acquired-by-mcbsp-at-high-speed-are-lost---high-priority-dma-channel-is-blocked-by-multiple-sdram-refresh-cycles</s>2000 2000108.9078万2.8388万

    也许这也是同样的问题。

    此外:是否确定未收到DMA溢出错误? SDRAM刷新过程有时可能需要很长时间(取决于SDRAM速度和刷新时钟),并且DMA (或更确切地说是SDRAM)可能无法跟上如此高的数据速率。


    此致,
    Andy

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

    库拉库拉

    您正在使用多少个DMA通道? 您在DMA ISR例程中做了什么? 正如AndyP所指出的,您是否遇到DMA超时错误?

    此外,请分享您的DMA配置详细信息。

    此致,

    Manoj

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

    您好,Manoj,

    我只使用一个DMA通道。  

    在我的DMA ISR中,我正在更新我的DMA目标寄存器和目标卷影寄存器内容。 但DMA中断仅不会发生。但数据正通过DMA从源复制到目标。

    到目前为止,我已经禁用了溢出中断。

    这是我的DMA配置。

    //
    //远端内存中的缓冲区。
    //
    __attribute___(far) volatile uint16_t extSDRAMBuf[104.8576万];

    void configDMAChannel1()

    //
    //配置DMA通道1 (16位数据大小)。
    //
    destDMA = extSDRAMBuf;
    //srcDMA =(volatile uint16_t *) localSrcRAMBuf;
    srcDMA =(volatile uint16_t *)(ADCBRESULT_base+2);
    dma_configAddresses(DMA_CH1_base,(const void*)destdma,(const void*)srcdma);
    DMA_configBurst (DMA_CH1_BASE,1U,1U);//机架式
    //!@注释,要降低const src,请将trsnfer srcstep保持为零
    dma_configTransfer (dma_ch1_base,1024,0U,1);
    DMA_configWrap (DMA_CH1_BASE,0x1万U,0,0x1万U,0);

    //
    //将DMA触发源配置为软件,启用OneShot,禁用
    //连续模式,DMA传输的数据大小为16位。
    //
    DMA_configMode (DMA_CH1_BASE,DMA_TRIGG_ADCB1,(DMA_CFG_OneShot_DISABLE
    | DMA_CFG_CONTINUIENT_DISABLE | DMA_CFG_Size_16BIT);

    //
    //启用选定的外设触发器以在DMA上启动DMA传输
    //通道1。
    //
    dma_enableTrigger (dma_ch1_base);

    //dma_enableOverrunInterrupt (dma_ch1_base);
    dma_disableOverrunInterrupt (dma_ch1_base);
    DMA_setInterruptMode (DMA_CH1_BASE,DMA_INT_AT_END);
    dma_enableInterrupt (dma_ch1_base);
    //
    //清除所有虚假外设中断标志。
    //
    dma_clearTriggerFlag (dma_ch1_base);

    //
    //清除所有虚假同步错误标志。
    //
    DMA_clearErrorFlag (DMA_CH1_BASE);
    }

    //DMA_ISR
    __interrupt void dmach1ISR(void)

    DMA_configDestAddress(DMA_CH1_BASE,(const void*)(extSDRAMBuf+(1024*USN_DMA_ISR_Counter));
    dma_disableTrigger (dma_ch1_base);
    dma_enableTrigger (dma_ch1_base);

    dma_startChannel(DMA_CH1_base);
    USN_DMA_ISR_Counter++;
    在传输104.8576万(1M)样本后,//停止DMA
    IF (USN_DMA_ISR_Counter >1024)
    dma_stopChannel(DMA_CH1_base);
    //
    //通过删除SOC0的触发器来停止ADC
    //
    //ADC_setInterruptSOCTrigger (myADC0_BASE,ADC_SOC_NUMBER0,
    // ADC_INT_SOC_TRIGG_NONE);
    // ADC_setInterruptSOCTrigger (myADC1_BASE,ADC_SOC_NUMBER0,
    // ADC_INT_SOC_TRIGG_NONE);

    //
    //确认中断
    //
    interrupT_clearACKGroup(interrupT_ACK_group7);

    }

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

    我已启用 溢出中断 ,但我不确定如何检查溢出是否发生 。请告诉我如何检查溢出是否发生  

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

    请检查CONTOL.OVRFLG标志位以了解是否发生过载情况。 另外,希望您认识到DMA中断不会发生在每个突发中,而是发生在每个传输中。

    因此,在您的情况下,只有在每1024个字传输后才会得到DMA中断。

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

    您好,Manoj,

    我检查 了CONTROL.OVRFLG标志位,但它没有设置,并且始终为零。

    我也有check control.ERRCLR标志,但它也始终为零。

    但我观察到一种奇怪的行为,DMA中断正在发生,但不是在预期的时间间隔。

    正如我 在前面的回答中所提到的,ADC中断是DMA通道的触发源,我在ADC_ISR例程中使用了UINT32_t计数器并递增,这样我就可以知道 发生了多少ADC转换以及 发生了多少次DMA触发。

    然后我发现,对于ADC中断计数,DMA中断将出现12.2042万 (未修复,如果重置MCU并再次运行,则会有所变化),但由于我的DMA传输配置为1024,因此我预期在1024个ADC中断计数中会出现DMA中断。

    第1个DMA中断发生在ADC中断的12.2042万个计数处(即遇到12.2042万 ADC中断)

    第2个DMA中断发生 在  ADC中断的22.5192万个计数处

    第3 个DMA中断发生 在  ADC中断的50.6195万次计数处。

     

    这种模式 没有任何意义。  如果您重置MCU并重新开始测试,您将获得一些其他随机 数(ADC中断计数后的DMA中断)。

    如果我降低ADC的采样率(100KSPS),则相同的配置工作正常, 在1024 个事务(1024个ADC中断计数)后DMA中断正常。

    请告诉我,在处理 DMA (1MSPS ADC)的高速触发源时,如果我在这里漏掉了一些东西。

     注:到目前为止,MCU上没有太多负载,仅 配置了1个ADC,1个ePWM,SDRAM和1个DMA通道。

    也只配置和启用ADC中断和DMA中断。

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

    如何与SDRAM (SPI (或) EMIF)连接? 是否有其它高优先级中断源会导致计数延迟? 您是否可以尝试写入F2.8388万D RAM位置,而不是写入SDRAM,并查看此问题是否消失? 我想知道此问题是否由SDRAM接口引起

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

    我只与SDRAM和EMIF连接。

    我的整个代码中只有两个中断,一个是ADC中断,另一个是DMA中断。 ADC中断(PIE组1矢量) 的优先级高于DMA中断(PIE组7矢量),并且也是必需的。

    按照建议,我尝试 了F2.8388万D RAM作为DMA的目标,并对所有EMIF配置部分进行了注释,但行为 仍然相同。

    我还将ADC采样速度降低到100ksps, DMA的工作方式与  F2.8388万D RAM相同 。

    我觉得在DMA中,当它处理高速触发源时,只有一些问题。

    但我没有找到哪个配置会导致  问题的确切原因。

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

    库拉库拉

    在您之前的帖子中,您曾报告您没有获得DMA中断。 我希望我们已经解决了这个问题。对吗?

    现在,您的主要问题是我的DMA中断不应该是定期的(具有相同的周期计数)? 正确吗? 您可以私下向我发送电子邮件地址吗? 我希望通过WebEx通话来更好地了解问题?

    此致,

    Manoj

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

    更改ADC配置后,DMA中断按预期工作。

    在ADC配置中,我启用 了ADC中断的连续模式。

    因此,无论是否设置了中断标志位,都将生成ADC中断。 因此,DMA可以完美地获得其事件触发器,DMA ISR也可以正常工作。

    经过TRM后,我找到了这种模式。

    特别感谢  的快速支持。  

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

    继续我之前的回答,我将在此处添加我的ADC配置代码详细信息。

     

    //ADC初始化
    void AdcA_init()

    //myADC0初始化

    // ADC初始化:写入ADC配置并为ADC通电
    //配置模块到数字转换器模块预校准器。
    ADC_setPrescaler (ADCA_BASE,ADC_CLK_DIV_1_0/*ADC_CLK_DIV_4_0*/);
    //配置模数转换器分辨率和信号模式。
    ADC_setMode (ADCA_BASE,ADC_Resolution _16BIT /*ADC_Resolution _12位*/,ADC_MODE_DIFFERC/*ADC_MODE_SINGLE_END_END_*/);
    //设置转换脉冲结束的时间
    ADC_setInterruptPulseMode (ADCA_BASE,ADC_PULSE_END_of_CONV);
    //启动模数转换器内核。
    ADC_enableConverter (ADCA_BASE);
    //延迟1毫秒,以允许ADC有时间开机
    DEVICE_DELAY _US (500);

    // SOC配置:设置ADC ePWM通道和触发器设置
    //禁用SOC突发模式。
    //ADC_disableBurstMode (ADCA_BASE);2022年7月4日

    //设置SOC的优先级模式。
    ADC_setSOCPriPriority (ADCA_BASE,ADC_PRI_ALL ROL_ROUND);
    //开始转换2配置
    //在ADC中配置转换起点(SOC)及其中断SOC触发器。
    // SOC编号:1.
    //触发器:ADC_TRIGG_EPWM1_SOCA
    //通道:ADC_CH_ADCIN0_ADCIN1.
    //样例窗口:15个SYSCLK周期
    //中断触发器:ADC_INT_SOC_TRIGG_NONE
    ADC_setupSOC (ADCA_BASE,ADC_SOC_NUMBER0,ADC_TRIGATE_EPWM7_SOCA,ADC_CH_ADCIN0_ADCIN1,15U);

    //由SOM-07-04-2022添加
    ADC_ENableContinuousMode (ADCA_BASE,ADC_INT_NUMBER1);
    ADC_setInterruptSOCTrigger (ADCA_BASE,ADC_SOC_NUMBER0,ADC_INT_SOC_TRIGTER_NONE);
    // ADC中断1配置
    // SOC/EOC号码:1.
    //中断源:已启用
    ADC_setInterruptSource (ADCA_BASE,ADC_INT_NUMBER1,ADC_SOC_NUMBER0);

    ADC_enableInterrupt (ADCA_BASE,ADC_INT_NUMBER1);
    ADC_clearInterruptStatus (ADCA_BASE,ADC_INT_NUMBER1);


    中断注册(INT_ADCA1,&adcA1ISR);
    INTERRUL_ENABLE (INT_ADCA1);

    //ADCA_BASE
    }
    __interrupt void adcA1ISR(void)

    }

    注:DMA配置已添加到相同线程的先前响应中。

    此致,

    Someshwar K

    L&T技术服务。