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.

[参考译文] TMS570LS0914:ADC G2_Thr 降至0以下

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1119099/tms570ls0914-adc-g2_thr-falls-below-0

器件型号:TMS570LS0914

尊敬的 TI 支持:

 

我们在与 DMA 模块相关的 ADC 模块中发现了一个潜在的错误/未记录的行为。

我们已经找到了一种适合我们的解决方法、但希望您可以查看它或为我们提供替代方法。

 

首先、让我解释一下我们的设置:

我们使用来自 TMS 的21个 ADC 通道。

17通道在组1中、将由 SW 触发。 通道由任务(SafeRTOS)使用函数 ADC_TMS570LS_getADCValue (请参阅下文)触发

 

4通道在组2中、由 RTI_COMP_0作为组转换触发。

每次组转换都应触发 DMA 请求、然后将组缓冲器复制到 RAM 中。

DMA 的配置如下:

  • 每帧8个元素(= ADC 组2 FIFO 大小)
  • 元素大小为32位
  • 帧传输

 

RTI_COMP_0计时器也用作操作系统的 SysTick 中断。 (1000Hz 频率)

 

我们注意 到、在一段未定义但特定的时间后、G2_Thr 将从8 (=FifoSize = ElementCount)缓慢下降到0。

当 G2_Thr 达到0时、DMA 请求被更频繁地触发、并且 DMA 读取的值无效。  

我们已经了解到、如果我们启动转换、G2_Thr 会降低、如果它未被读取、则会再次增加。

 

我们期望以下行为:

  • 每1ms 触发一次 ADC 转换
  • 4个有效的 ADC 值被写入组2缓冲器
  • 成功地将4个 ADC 值写入组缓冲器后、DMA 被触发
  • DMA 将整个组缓冲器(8个元件)复制到已配置的 RAM 部分。
  • 因此、每1ms、我们就会在 RAM 中看到4个新的 ADC 值

 

在我们的系统中、我们还使用 CAN 节点。 如果我们增加 CAN 上的总线负载、我们会注意到 G2_Thr 的值下降得更快。

同时 、由 SW 触发的 ADC 通道更频繁地超时(检查 ADC_TMS570LS_getADCValue)。

 

对我们来说、似乎有两个问题:

  1. 软件触发的手动 ADC 转换与直接通过 RTI 触发的自动转换之间可能会发生冲突
  • 是否有任何有关可能发生冲突的文档? 如果是,如何防止碰撞?

 

  1. 冲突发生后、DMA 请求速度过快
  • 我们预计只有在写入4个有效 ADC 值时才会发生 DMA 请求

 

在确定问题时、我们开发了一种解决方法、该方法对我们有效、但我们需要您进行验证。

  1. 我们将硬件触发源设置为 NHET-14
    1. 从而使触发时序发生偏移、并且与 RTI 无关
  2. 我们在软件中检查 G2_Thr、如果它低于5、则:
    1. 复位 FIFO:                                                               ADC[0]->GxFIFORESETCR[2]= 1;
    2. 清除转换结束标志和阈值 IRQ 标志、 ADC[0]->GxINTFLG[2]= 9;
    3. 将阈值计数器设置为8;                                       ADC[0]->GxINTCR[2]= 8;
    4. 将 G2_Blocks 设置为8:                                                   ADC[0]->G2DMACR= 0x0008000D;
  3. 启用组1转换结束中断使能
    1. 因此、软件触发的 ADC 转换不会超时。

 

以下是我们的代码函数:

adc_status_t adc_tms570LS_getADCValue (const adc_SignalConfig*信号、uint16_t* adcValue)

  adc_status_t adcStatus = adc_FAILRUE;

  ADC_DATA_t convData[22]={0};

   uint8_t adcPortIndex =(信号->端口=ADC_Porta)? 0:1;

 

  ADC_TMS570LS_startConversion (SIGNAL);/* Aquire Conversion Data */

 

  if ((adcReg[adcPortIndex]->GxSEL[信号->组]!= 0U)

  {

         uint16_t 超时= 0xFFFF;

         //等待完成

      while (!ADC_TMS570LS_isConversionComplete (SIGNAL)&& TIMEOUT)

      {

        超时--;

      }

      if (超时!= 0U)

      {

         ADC_TMS570LS_getData (信号、转换数据);

        *adcValue = convData[0]。value;

        adcStatus = adc_Success;

      }

      其他

      {

        adcStatus = adc_timeout;

      }

  }

  返回 adcStatus

ADC_TMS570LS_getData:

静态 uint32_t ADC_TMS570LS_getData (const ADC_SignalConfig*信号、ADC_DATA_t*数据)

  uint32_t count = uint32_MAX;

   uint8_t adcPortIndex =(信号->端口=ADC_Porta)? 0:1;

 

    uint32_t buf;

    uint32_t intcr_reg = adcReg[adcPortIndex]->GxINTCR[信号->组]; //多空间 RTE:NIV [对齐]

    adc_data_t* ptr  =数据;

 

    uint32_t 计数=(intcr_reg >= 256U)? FioSize[adcPortIndex]:(FioSize[adcPortIndex]–(intcr_reg & 0xFFU);

 

    if ((adcReg [(uint8_t) signal->port - 1U]->OPMODECR & 0x80000000U)>0) // if ADC 配置为12位分辨率

    {                                   

      /**- 获取转换数据和通道/引脚 ID */

      for (uint32_t i = 0U;i < count;i++)

      {

        buf    = adcReg[adcPortIndex]->GxBUF[信号->组].BUF0; //多空间 RTE:NIV [对齐]

        ptr ->值=(uint16)(buf & 0xFFFU);

        ptr -> id  =(uint32)((buf >> 16U)& 0x1FU);

        PTR++;

         }

    }

  adcReg[adcPortIndex]->GxINTFLG[信号->组]= 9U;

 

  返回计数;

此致、

Thorben

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

    Thorben、您好!

    我已开始处理您的问题、我将很快回复您。

    --

    谢谢、

    Jagadish。

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

    Thorben、您好!

    我以前从未见过这种问题。 对于 DMA 传输、最好启用 BLK_Xfer 并设置 EV_BLOCK_8。

    不建议在组阈值中断的同时为组启用块 DMA 传输。

    您能否发布您的代码以供我查看?