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