Post Go back to editing

ADC Sampling/Conversion taking longer than expected

Hi, I sent a ticket to support and their answer was: "Support for our Low Power Processors is on Engineer Zone", so I hope someone here may help me.

I've been seeing a not expected behavior from ADC.

If my uC wakes-up from flexi mode the dummy conversion takes around 11.42us, and the others two conversions take ~23us (what I think is fine). But if my uC wakes-up from hibernate mode the dummy conversion takes ~168us and the others two conversions ~335us. I can't understand why it's taking so long after wake-up from hibernate.

My code is:

it wakes-up from external interruption, runs all the wake-up functions and them start the sampling from 2 analog channels. To measure the time I turned on one gpio before send the command to start sampling and then turned off right after the conversion done flag.

uC: ADUC3029

IDE: crosscore

Code snippet:

void acq_init(void)
{
	uint16_t rdy_done = 0;
	uint16_t timeout = 0;

    /* triggers power up and set the wait time */
    regbitor(*pREG_ADC0_CFG, BITM_ADC_CFG_PWRUP);
    regwrite(*pREG_ADC0_PWRUP, (ADC_POWERUP_WAIT_VALUE));

    /* configure the votlage reference to the low power mode */
    regwrite(*pREG_ADC0_CFG1, BITM_ADC_CFG1_RBUFLP);

    /* enable the ADC module */
    regbitor(*pREG_ADC0_CFG, BITM_ADC_CFG_EN);

    /* Loop com timeout esperando o ADC inicializar */
    while (!rdy_done && (timeout < DONE_TIMEOUT))
	{
    	rdy_done = regread(*pREG_ADC0_STAT)&(BITM_ADC_STAT_RDY);
    	timeout++;
	}

    /* clear the flag ADC_STAT.RDY */
    regwrite(*pREG_ADC0_STAT, BITM_ADC_STAT_RDY);

    /* calibrates the ADC */
    adc_calibrate();

}

void acq_wakeup(void)
{
	uint16_t rdy_done = 0;
	uint16_t timeout = 0;

    /* triggers power up and set the wait time */
    regbitor(*pREG_ADC0_CFG, BITM_ADC_CFG_PWRUP);
    regwrite(*pREG_ADC0_PWRUP, (ADC_POWERUP_WAIT_VALUE));

    /* configure the votlage reference to the low power mode */
    regwrite(*pREG_ADC0_CFG1, BITM_ADC_CFG1_RBUFLP);

    /* enable the ADC module */
    regbitor(*pREG_ADC0_CFG, BITM_ADC_CFG_EN);

    /* Timeout waiting ADC initialize */
    while (!rdy_done && (timeout < DONE_TIMEOUT))
	{
    	rdy_done = regread(*pREG_ADC0_STAT)&(BITM_ADC_STAT_RDY);
    	timeout++;
	}

    /* clear the flag ADC_STAT.RDY */
    regwrite(*pREG_ADC0_STAT, BITM_ADC_STAT_RDY);

    /* calibrates the ADC */
    adc_calibrate();
}

void acq_analog_chs (analog_chs *chs_data_ptr, uint8_t target_chs)
{
    /* set sampling time */
    regwrite(*pREG_ADC0_CNV_TIME, ADC_SAMPLING_TIME);
    
    /* Measure dummy time from here */

    /* dummy conversion at channel 0, wait for completion and clear the conversion done flag */
    regwrite(*pREG_ADC0_CNV_CFG, 0x0001);
    regbitor(*pREG_ADC0_CNV_CFG, BITM_ADC_CNV_CFG_SINGLE);

    while(!(*pREG_ADC0_STAT & 0x01))
    {

    }

    regwrite(*pREG_ADC0_STAT, (ADC_STAT_ALL_DONE_FLAGS_MASK));
    
    /* Measure dummy time to here */

    /* enable the channels requested at function call */
    acq_select(target_chs);
    
    /* Measure sample and conversion time from here */

    /* trigger ADC conversion */
    regbitor(*pREG_ADC0_CNV_CFG, BITM_ADC_CNV_CFG_SINGLE);

    /* wait until all expected conversion done flags are set and clear they right after */
    while((*pREG_ADC0_STAT & (ADC_STAT_ALL_DONE_FLAGS_MASK)) != target_chs)
    {

    }

    regwrite(*pREG_ADC0_STAT, (ADC_STAT_ALL_DONE_FLAGS_MASK));
    
    /* Measure sample and conversion time to here */

    /* check each channel enable switch bit and read from ADC's result register only the necessary data and stores it at the analog channels data buffer */

    if(target_chs & 0x02)
    {
        chs_data_ptr->v_sense = *pREG_ADC0_CH1_OUT;
    }
    if(target_chs & 0x08)
    {
        chs_data_ptr->a_sense = *pREG_ADC0_CH3_OUT;
    }
}

Thank you in advance.

Matheus Nogueira