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.

[参考译文] AM2434:永远等待 ADC 转换时出现问题

Guru**** 2445810 points
Other Parts Discussed in Thread: AM2434, SYSCONFIG

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1199705/am2434-a-problem-waiting-for-adc-conversion-forever

器件型号:AM2434
"Thread: SysConfig"中讨论的其他器件

您好、专家:

我在 我们的系统中发现了一个始终等待 ADC 转换的问题。 我们使用 AM2434的内部 ADC 每隔1秒检查一次系统温度 该逻辑是通过参考 SDK 08.02.00.31中的 ADC 一次性示例实现的。 我们还使用轮询方法实现并测试了它。 但是、 轮询方法和中断方法都出现了此问题。 问题有时在2小时内发生、有时在3天内没有发生。

我可以问、是否报告了类似情况、该情况正在讨论中、还是在最新的 SDK 中修复了该情况?

如果您分享您在这个问题上的经验、检查点和任何历史、我将不胜感激。

谢谢。

Moonil

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

    尊敬的 Moonil:

    我没有意识到您刚才所说的 ADC 存在任何问题。

    您能否进一步说明这个问题?

    • ADC 的配置是什么?
    • 触发 ADC 的是什么?
    • ADC 在挂起发生时是否触发了中断?
    • 您是否有单元测试演示问题?
    • 如果您有单元测试、是否已尝试使用更高版本的 SDK 来查看问题是否得到解决?

    此致、
    弗兰克

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

    尊敬的 Moonil:

    另一个问题:您是看到不正确的 ADC 输出还是未发生 ADC 转换?  

    此致、
    弗兰克

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

    尊敬的 Frank:  

    您是否看到 ADC 输出不正确或 ADC 转换未发生?  [/报价]

    在我的测试中、由于 ISR 在有问题的情况中似乎不是由 ADC 触发、ADC 转换未完成。

    您能先回顾一下下面实施的代码吗?

    1. adc_drV_AM243X_fnCtor ()-在系统引导期间初始化 ADC。
    2. ADC_DRV_AM243X_fnStartConversion ()-由应用程序调用以启动 ADC 转换。
    3. ADC_DRV_AM243X_fnIsConversionDone ()-由应用程序调用以等待  ADC 转换完成。
      • 如果在1秒内没有响应、这也有重新启动 ADC 的代码 (正在测试)
    4. ADC_DRV_AM243X_fnRead ()-由应用程序调用以读取 ADC 数据。
    5. adc_drv_am243x_fnIsr () -由 ISR 从 ADC 调用。

    应用程序正在以2->3->4的顺序调用。

    tuiSTATUS ADC_DRV_AM243X_fnCtor( void )
    {
        HwiP_Params hwiPrms;
        tuiSTATUS   status = eSTATUS_ERR;
    
        if( SystemP_SUCCESS == SemaphoreP_constructBinary( &gAdcSyncSemObject, 0 ) )
        {
            // Register & enable interrupt.
            HwiP_Params_init( &hwiPrms );
            hwiPrms.intNum   = CONFIG_ADC0_INTR;
            hwiPrms.callback = &adc_drv_am243x_fnIsr;
            hwiPrms.priority = 1U;
            if( SystemP_SUCCESS == HwiP_construct( &gAdcHwiObject, &hwiPrms ) )
            {
                // Clear All interrupt status.
                ADCClearIntrStatus( CONFIG_ADC0_BASE_ADDR, ADC_INTR_STATUS_ALL );
    
                // Power up the ADC.
                ADCPowerUp( CONFIG_ADC0_BASE_ADDR, TRUE );
    
                // Wait for 4us at least
                ClockP_usleep( 5u );
    
                // Do the internal calibration.
                ADCInit( CONFIG_ADC0_BASE_ADDR, FALSE, 0u, 0u );
    
                status = eSTATUS_OK;
            }
        }
        return ( status );
    }
    
    tucBOOL ADC_DRV_AM243X_fnStartConversion( void )
    {
        adcSequencerStatus_t status;
        adcStepConfig_t      adcConfig;
        uint32               adcStep;
        uint32               channelCount;
        sint8                configStatus;
    
        // Enable interrupts.
        ADCEnableIntr( CONFIG_ADC0_BASE_ADDR, ( ADC_INTR_SRC_END_OF_SEQUENCE |
                                                ADC_INTR_SRC_FIFO0_THRESHOLD |
                                                ADC_INTR_SRC_FIFO0_OVERRUN |
                                                ADC_INTR_SRC_FIFO0_UNDERFLOW |
                                                ADC_INTR_SRC_FIFO1_THRESHOLD |
                                                ADC_INTR_SRC_FIFO1_OVERRUN |
                                                ADC_INTR_SRC_FIFO1_UNDERFLOW |
                                                ADC_INTR_SRC_OUT_OF_RANGE ) );
    
        // Initialize ADC configuration params.
        adcConfig.mode             = ADC_OPERATION_MODE_SINGLE_SHOT;
        adcConfig.openDelay        = 0x1u;
        adcConfig.sampleDelay      = 0u;
        adcConfig.rangeCheckEnable = 0u;
        adcConfig.averaging        = ADC_AVERAGING_16_SAMPLES;
        adcConfig.fifoNum          = ADC_FIFO_NUM_0;
    
        // Configure all required steps - Step 0 to 7 mapped to channel 0 to 7
        for( channelCount = 0U; channelCount < ADC_DRV_AM243X_NUM_CHANNELS; channelCount++ )
        {
            adcConfig.channel = ADC_CHANNEL_1 + channelCount;
            adcStep = ADC_STEP_1 + channelCount;
            configStatus = ADCSetStepParams( CONFIG_ADC0_BASE_ADDR, adcStep, &adcConfig );
            if( CSL_EFAIL == configStatus )
            {
                return ( eSTATUS_ERR );
            }
        }
    
        // Enable Step IDs, to identify which measurement came from which channels.
        ADCStepIdTagEnable( CONFIG_ADC0_BASE_ADDR, TRUE );
    
        configStatus = ADCSetCPUFIFOThresholdLevel( CONFIG_ADC0_BASE_ADDR, ADC_FIFO_NUM_0, 40u );
        if( CSL_EFAIL == configStatus )
        {
            return ( eSTATUS_ERR );
        }
    
        // Step enable.
        for( channelCount = 0U; channelCount < ADC_DRV_AM243X_NUM_CHANNELS; channelCount++ )
        {
            adcStep = ADC_STEP_1 + channelCount;   // Step -> Channel one to one mapped.
            ADCStepEnable( CONFIG_ADC0_BASE_ADDR, adcStep, TRUE );
        }
    
        // Start ADC conversion.
        ADCStart( CONFIG_ADC0_BASE_ADDR, TRUE);    // Start ADC conversion.
    
        return ( eSTATUS_OK );
    }
    
    tucBOOL ADC_DRV_AM243X_fnIsConversionDone( void )
    {
        sint32 status;
    
        // Wait for the interrupt to occur.
        status = SemaphoreP_pend( &gAdcSyncSemObject, pdMS_TO_TICKS( ADC_DRV_TIMEOUT_MS ) );
    
        // Restart ADC.
        if( SystemP_SUCCESS != status )
        {
            KDBG( DBG_ERR, "Internal ADC timeout and restart!\r\n" );
    
            // Power down the ADC.
            ADCPowerUp( CONFIG_ADC0_BASE_ADDR, FALSE );
    
            // Wait for 4us at least
            ClockP_usleep( 5u );
    
            // Clear All interrupt status.
            ADCClearIntrStatus( CONFIG_ADC0_BASE_ADDR, ADC_INTR_STATUS_ALL );
    
            // Power up the ADC.
            ADCPowerUp( CONFIG_ADC0_BASE_ADDR, TRUE );
    
            // Wait for 4us at least
            ClockP_usleep( 5u );
    
            // Do the internal calibration.
            ADCInit( CONFIG_ADC0_BASE_ADDR, FALSE, 0u, 0u );
    
            // Start conversion.
            ADC_DRV_AM243X_fnStartConversion();
    
            // Wait for the interrupt to occur.
            status = SemaphoreP_pend( &gAdcSyncSemObject, pdMS_TO_TICKS( ADC_DRV_TIMEOUT_MS ) );
            if( SystemP_SUCCESS != status )
            {
                KDBG( DBG_ERR, "Internal ADC timeout again!!!\r\n" );
                return( FALSE );
            }
        }
    
        return( TRUE );
    }
    
    tucBOOL ADC_DRV_AM243X_fnRead( ADC_DRV_AM243X_tzVALUES *pValues )
    {
        uint8  fifoWordCount;
        uint8  index;
        uint8  stepId;
        uint16 rawData;
        uint32 fifoData;
    
        fifoWordCount = ADCGetFIFOWordCount( CONFIG_ADC0_BASE_ADDR, ADC_FIFO_NUM_0 );
    
        for( index = 0U; index < fifoWordCount; index++ )
        {
            // Retrieve the next value from the FIFO.
            fifoData = ADCGetFIFOData( CONFIG_ADC0_BASE_ADDR, ADC_FIFO_NUM_0 );
            stepId   = ( ( fifoData & ADC_FIFODATA_ADCCHNLID_MASK ) >>
                         ADC_FIFODATA_ADCCHNLID_SHIFT);
            rawData  = ( ( fifoData & ADC_FIFODATA_ADCDATA_MASK ) >>
                         ADC_FIFODATA_ADCDATA_SHIFT);
    
            // Insert the value into the appropriate place in the structure
            *( ( uint16 * )pValues + stepId ) = rawData;
        }
    
        return( TRUE );
    }
    
    void adc_drv_am243x_fnIsr( void *handle )
    {
        uint32_t status;
    
        /* Get interrupt status and clear */
        status = ADCGetIntrStatus( CONFIG_ADC0_BASE_ADDR );
        ADCClearIntrStatus( CONFIG_ADC0_BASE_ADDR, status );
    
        /* Process ISR */
        SemaphoreP_post( &gAdcSyncSemObject );
    
        /* Set EOI to generate next interrupt if any */
        ADCWriteEOI( CONFIG_ADC0_BASE_ADDR );
    }

    这是通过参考 SDK 中的 TI 示例实现的。

    仅供参考、在 SDK 08.02.00.31和 SDK 08.05.00.24之间的"adc.c"中我无法找到任何不同的代码。

    此致、

    Moonil

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

    尊敬的 Moonil:

    我将看一下您的代码、看看我是否能发现任何问题。

    我仍然有问题:

    • ADC 的配置是什么?
    • 触发 ADC 的是什么?
    • ADC 在挂起发生时是否触发了中断?

    挂起发生时、ADC_STATUS 寄存器(地址0x28001028)的内容是什么?

    此致、
    弗兰克

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

    尊敬的 Frank:

    感谢您对此问题的迅速响应、

    什么是 ADC 配置?

    是否要了解 ADC syscfg 的配置? 您能告诉我我必须通知您什么样的配置吗?

    什么触发 ADC?

    正如我提到过的、应用任务会触发 ADC 来读取我们的系统温度。

    当挂起时 ADC 是否触发了中断?

    否、发生挂起时未调用 ISR。

    挂起发生时 ADC_STATUS 寄存器(地址0x28001028)的内容是什么?

    这个问题是随机发生的。 已 在轮询方法实现中检查 ADC 状态、但尚未在中断方法中检查。

    在轮询方法测试期间 ADC_STATUS 处于忙状态。 请查看下面的捕获、

    此致、

    Moonil

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

    尊敬的 Moonil:

    您想知道 ADC syscfg 的配置吗? 您能告诉我我必须通知您什么样的配置吗?

    是的、我要求提供 SysConfig 中的配置以及您通过 API 函数进行的任何配置。

    正如我所说,应用程序任务触发 adc

    好的,那么你在一个应用任务中调用 ADCStart()呢? 我在您共享的代码片段中看到了这一点。

    否,发生挂起时未调用 ISR。

    我的意思是、ADC 已经发出一个到 VIM/R5F 的中断信号、而不是 VIM/R5F 是否已经对中断做出响应。 ADC 是否已发出中断信号应显示在 ADC_STATUS 中。 通过打开"Memory"窗口并将地址设置为0x28001028、您可以在 CCS 中看到这一点。 您也可以通过调用 API 函数 ADCGetIntrStatus ()来检查代码中的状态。

    我会检查您的代码段并与您联系。

    此致、
    弗兰克

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

    尊敬的 Moonil:

    很抱歉响应延迟。 我查看了您的代码、并将其与 ADC Singleshot 示例进行了比较: https://software-dl.ti.com/mcu-plus-sdk/esd/AM243X/08_05_00_24/exports/docs/api_guide_am243x/EXAMPLES_DRIVERS_ADC_SINGLESHOT.html

    我看到您的代码严格遵循单次示例。 大多数情况下、我认为您的代码没有任何问题。 不过,我有以下意见:

    #1: ADC_DRV_AM243X_fnStartConversion ():
    ADCStart()在 ADCStepEnable()循环之后被立即调用。 在 singlehot 示例中,FSM 在调用 ADCStart()之前检查空闲。

    #2:ADC_DRV_AM243X_fnIsConversionDone ():
    Semaphore pend()有一个超时。 在 singlehot 示例中,semaphore pend()被设置为永远等待。

    #3:ADC_DRV_AM243X_fnIsConversionDone ():
    在信号量超时的情况下、执行代码以重新启动 ADC。

    • 该代码是否曾在您的系统中执行?
    • 我认为、您应该在调用 ADC 上电和初始化 API 之前"拆卸"API。

    是否可以修改 SDK 一次性示例以重现问题?

    此致、
    弗兰克

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

    尊敬的 Frank:

    感谢您查看我的代码。

    #1:adc_drv_am243X_fnStartConversion ():
    ADCStart()在 ADCStepEnable()循环之后被立即调用。 在 singlehot 示例中,FSM 在调用 ADCStart ()之前检查空闲状态。

    正如您所指出的、丢失了检查 FSM 是否空闲的代码、但在我的测试中、添加检查空闲的代码后会出现同样的问题。  当以下问题发生时、我捕获了 ADC_STATUS 寄存器(0x28001028)[#1]。 其值为0x00000010。

    根据 TRM[#2]、该值是的待定事件 "FIFO0欠流中断" "ADC 不会自动从下溢条件中恢复。 因此、发生这种情况后、软件将需要禁用并重新启用 ADC "

    q1)您能否说明在通过一个清晰的示例执行此操作后、如何禁用和重新启用 ADC? 由于我们生产计划的紧迫性、因此我需要尽快让 TI 确认恢复代码。 仅供参考、我共享的恢复代码在这种情况下不起作用。

    Q2)什么原因可以导致  电流  频率是多少? 如果您分享您对此的了解、我将不胜感激。 这种下溢似乎不是根本原因、而是在发生其他根本问题之后出现了以下情况。

    Q3)我在调用 ADCStart ()之前使用该代码来检查空闲,这与下面的 TI 示例中的代码相同,您认为这个 TI 示例代码是正确的吗? 我认为"&"应该是"||"。 但是,当我用"||"测试时,fsmBusy 在运行大约10小时后一直是1个,所以,这导致了一个"无限 while 循环",其中 FSM 永远不会进入空闲状态。  请分享您对此规范的看法。 我需要首先确认该示例代码以缩小调查范围。

        /* Check if FSM is idle */
        ADCGetSequencerStatus(baseAddr, &status);
        while ((ADC_ADCSTAT_FSM_BUSY_IDLE != status.fsmBusy) &&
               ADC_ADCSTAT_STEP_ID_IDLE != status.stepId)
        {
            ADCGetSequencerStatus(baseAddr, &status);
        }

    [#1]

    [#2]

    我期待您的答复。

    此致、

    Moonil

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

    尊敬的 Moonil:

    q1)您能告诉我如何在发生这种情况后通过一个明确的示例禁用并重新启用 ADC 吗? 由于我们生产计划的紧迫性、因此我需要尽快让 TI 确认恢复代码。 仅供参考、我共享的恢复代码在此情况下不起作用。

    我认为、弄清造成下溢的原因比弄清如何从下溢中恢复要重要。

    总之、我不知道 SDK 中有任何用于从下溢/溢出中恢复的代码。 我将向软件开发团队询问相关情况。 首先、我建议在示例中调用"tear-down"API、然后调用"bring-up" API。

    例如、我建议您尝试类似这样的操作:

    if (underflow)
        // de-init ADC
        App_adcStop(baseAddr);
        App_adcDeInit(baseAddr);
        
        // re-init ADC
        App_adcInit(baseAddr);
        App_adcConfig(baseAddr);
        App_adcStart(baseAddr);
    

    可能并不是所有从这些应用级函数中调用的 API 函数都需要被调用。 例如、我怀疑 AFE 是否需要断电并备份以恢复。

    Q2)原因何在  电流  频率是多少? 如果您分享您对此的了解、我将不胜感激。 这种下溢似乎不是根本原因,而是在发生其他根本问题之后出现以下情况。

    我看到了 TRM 第12.1.1.6.23节 ADC_FIFO0DATA 寄存器中提到的下溢原因的唯一地方:从该寄存器读取将自动递增 FIFO 读取指针。 如果您在 FIFO 为空时进行读取、则会触发下溢中断。

    Q3)我在调用 ADCStart ()之前使用该代码来检查空闲,这与下面的 TI 示例中的代码相同,您觉得这个 TI 示例代码正确吗? 我认为"&"应该是"||"。 但是,当我用"||"测试时,fsmBusy 在运行大约10小时后一直是1个,所以,这导致了一个"无限 while 循环",其中 FSM 永远不会进入空闲状态。  请分享您对此规范的看法。 我需要先确认此示例代码以缩小调查范围。

    我认为这是一个错误。 根据 TRM、12.1.1.6.11 ADC_SEQUENCER 寄存器:

    软件可以读取该寄存器、找出在 ADC 端口上转换的当前调度步骤 ID。 如果要关闭控制器然后再重新开启、则应在再次启用 ADC 模块之前检查 STEP_id 位并与空闲状态进行比较。 此外、在再次启用控制器之前、用户应等待 FSM 位5读取 IDL。

    这意味着在 ADC 被(重新)启用前、等待 STEP_IDLE=IDLE (0h)和 FSM_BUSY=IDLE (10h)、即等待 while (STEP_IDLE!=IDLE)或(FSM_BUSY!=IDLE)。 这是写入等待循环的方式、不能有一个处于空闲状态、代码将停止等待并继续。

    fsmBusy 始终为1

    我无法使用示例代码重现此行为。 在第一次调用 ADCGetSequencerStatus()后,我始终观察到 status.fsmBusy=0。

    您的系统中是否有多个线程可能会按照预期顺序调用某些应用级函数?

    此致、
    弗兰克

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

    尊敬的 Moonil:

    启用下溢中断、但 ISR 中没有处理下溢中断。 在此 ISR 中发布一个信标、用于向 EOC 发送信号、与下溢无关。 这需要进行适当更新以处理应用中的下溢。

    我不确定您的应用中下溢是如何发生的:

    • CPU 仅在收到 ADC 的 EOC 中断信号后读取 FIFO。
    • CPU 获取 FIFO 字计数并将其用作 FIFO 读取次数、因此 CPU 不应过多次地读取 FIFO。

    为了查找何时发生下溢、您可以向 ISR 添加代码以检查是否发生下溢。 然后单步执行 ISR 代码的剩余部分、并返回导致下溢的代码。

    此致、
    弗兰克

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

    尊敬的 Frank:

    感谢您的解释。

    我使用轮询方法再次测试了两个案例、如下所示:

    测试情况1:

    • 添加了在调用 ADCStart ()之前检查 FSM 是否处于空闲状态的代码 使用  用于检查 IDLE 的 TI 示例代码(&&)。
    • 这是可以的-它仍然运行没有任何问题超过20小时。 继续这个测试。

    测试情况2:

    • 添加了在调用  ADCStart ()之前检查 FSM 是否空闲的代码  使用修改后的代码(||)检查空闲状态。
    • 这是不正常的-问题发生在大约9小时内。
    • 在此测试中、检查 FSM 是否处于空闲状态的条件为"STEP_IDLE==IDLE (10h)和 FSM_BUSY==IDLE (0h)"。 正如我们在 TI 示例中指出的那样,这个修改被应用于这个测试中,但结果 FSM 总是很忙(1h),所以在调用 ADCStart()之前,代码是无限循环的。

    从这些测试结果来看、我想知道我们是否可以说 TI 示例代码正确、因为它并不是错误。

    q1)您能否向您的团队确认示例代码、以检查 FSM 是否空闲?

    Q2)您是否可以再次使用轮询方法查看下面的代码? 这段代码运行一整天都没有问题。

    tuiSTATUS ADC_DRV_AM243X_fnCtor( void )
    {
        sint8           configStatus;
        uint32          channelCount;
        uint32          adcStep;
        adcStepConfig_t adcConfig;
    
        // Clear All interrupt status.
        ADCClearIntrStatus( CSL_ADC0_BASE, ADC_INTR_STATUS_ALL );
    
        // Power up the ADC.
        ADCPowerUp( CSL_ADC0_BASE, TRUE );
    
        // Wait for ADC to power up.
        while( AdcIsPoweredUp( CSL_ADC0_BASE ) == FALSE );
    
        // Do the internal calibration.
        ADCInit( CSL_ADC0_BASE, FALSE, 0U, 0U );
    
        // ADC initializes as started - we stop it here, so it doesn't take measurements before
        // we want them.
        ADCStart( CSL_ADC0_BASE, FALSE );
    
        // Configure the ADC steps.
        // Initialize ADC configuration params.
        adcConfig.mode             = ADC_OPERATION_MODE_SINGLE_SHOT;
        adcConfig.openDelay        = 0x1U;
        adcConfig.sampleDelay      = 0U;
        adcConfig.rangeCheckEnable = 0U;
        adcConfig.averaging        = ADC_AVERAGING_16_SAMPLES;
        adcConfig.fifoNum          = ADC_FIFO_NUM_0;
    
        // Configure all required steps - Step 0 to 7 mapped to channel 0 to 7
        for( channelCount = 0U; channelCount < ADC_DRV_AM243X_NUM_CHANNELS; channelCount++ )
        {
            adcConfig.channel = ADC_CHANNEL_1 + channelCount;
            adcStep = ADC_STEP_1 + channelCount;
            configStatus = ADCSetStepParams( CSL_ADC0_BASE, adcStep, &adcConfig );
            if( CSL_EFAIL == configStatus )
            {
                return ( eSTATUS_ERR );
            }
        }
    
        // Enable Step IDs, to identify which measurement came from which channels.
        ADCStepIdTagEnable( CSL_ADC0_BASE, TRUE );
    
        return ( eSTATUS_OK );
    }
    
    tucBOOL ADC_DRV_AM243X_fnStartConversion( void )
    {
        adcSequencerStatus_t status;
        uint32               channelCount;
        uint32               adcStep;
    
        // Enable each step in the ADC for a one-shot measurement.
        for( channelCount = 0U; channelCount < ADC_DRV_AM243X_NUM_CHANNELS; channelCount++ )
        {
            adcStep = ADC_STEP_1 + channelCount;
            ADCStepEnable( CSL_ADC0_BASE, adcStep, TRUE );
        }
    
        // Check if finite state machine is idle.
        ADCGetSequencerStatus( CSL_ADC0_BASE, &status );
        while ( ( ADC_ADCSTAT_FSM_BUSY_IDLE != status.fsmBusy ) &&
                ( ADC_ADCSTAT_STEP_ID_IDLE != status.stepId ) )
        {
            ADCGetSequencerStatus( CSL_ADC0_BASE, &status );
        }
    
        // Start ADC conversion.
        ADCStart( CSL_ADC0_BASE, TRUE );
    
        return ( TRUE );
    }
    
    tucBOOL ADC_DRV_AM243X_fnIsConversionDone( void )
    {
        adcSequencerStatus_t status;
    
        ADCGetSequencerStatus( CSL_ADC0_BASE, &status );
    
        // Check if FSM is idle.
        if( ( ADC_ADCSTAT_FSM_BUSY_IDLE != status.fsmBusy ) &&
            ( ADC_ADCSTAT_STEP_ID_IDLE != status.stepId ) )
        {
            return( FALSE );
        }
    
        return( TRUE );
    }
    
    tucBOOL ADC_DRV_AM243X_fnRead( ADC_DRV_AM243X_tzVALUES *pValues )
    {
        uint8  fifoWordCount;
        uint8  index;
        uint8  stepId;
        uint16 rawData;
        uint32 fifoData;
    
        fifoWordCount = ADCGetFIFOWordCount( CSL_ADC0_BASE, ADC_FIFO_NUM_0 );
    
        for( index = 0U; index < fifoWordCount; index++ )
        {
            // Retrieve the next value from the FIFO.
            fifoData = ADCGetFIFOData( CSL_ADC0_BASE, ADC_FIFO_NUM_0 );
            stepId   = ( ( fifoData & ADC_FIFODATA_ADCCHNLID_MASK ) >>
                         ADC_FIFODATA_ADCCHNLID_SHIFT);
            rawData  = ( ( fifoData & ADC_FIFODATA_ADCDATA_MASK ) >>
                         ADC_FIFODATA_ADCDATA_SHIFT);
    
            // Insert the value into the appropriate place in the structure
            *( ( uint16 * )pValues + stepId ) = rawData;
        }
    
        return( TRUE );
    }

    此致、

    Moonil

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

    尊敬的 Moonil:

    从这些测试结果来看、我想知道我们是否可以说 TI 示例代码正确、因为它并不是错误。

    q1)您能否向您的团队确认示例代码、以检查 FSM 是否空闲?

    [/报价]

    我目前仅在 TRM 中提供了该信息。 示例中的代码与针对 FSM 的 ADC 行为的 TRM 描述不匹配。 但是、TRM 中可能存在错误。 我将对此进行跟进。

    Q2)您能否再次使用轮询方式查看下面的代码? 此代码目前运行无问题,运行时间已超过一天。

    我复查了代码、觉得没问题。 我没有看到您在检查代码中是否存在下溢。 这种情况不再发生吗?

    此致、
    弗兰克

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

    尊敬的 Frank:

    我目前只有 TRM 中的信息。 示例中的代码与针对 FSM 的 ADC 行为的 TRM 描述不匹配。 但是、TRM 中可能存在错误。 我将对此进行跟进。[/报价]

    是的、可能需要正确更新 TRM。

    我查看了该代码,看起来不错。 我没有看到您在检查代码中是否存在下溢。 这是否不再发生?

    您查看的我的代码已运行了1周以上、没有任何问题。 所以、我认为这个问题已经解决、不需要进行代码检查下溢。

    如果 发现任何问题、我会再次发布。

    谢谢!

    Moonil

    [/quote]