After performing the first ADC operation (4 channel scan, sample rate controlled from TIMER1), the power consumption stays at almost 4 mA for the nRF52832.
Why?
Initialization code:
case DRIVER_ADC_IOCTL_START:
if( ioctl )
{
memset( dma_sample_buf, 0, sizeof( dma_sample_buf ));
memset( read_ring_buf, 0, sizeof( read_ring_buf ));
ovfl_mask = 0;
current_dma_buffer = 0;
read_since_event = 1;
SAADC_RESULT->PTR = ( uint32_t *)&dma_sample_buf[current_dma_buffer][0];
if( sample_callback != NULL )
{
// Call back function is called on each sample
SAADC_RESULT->MAXCNT = NOF_SCAN_CHANNELS;
}
else
{
SAADC_RESULT->MAXCNT = NOF_DMA_SAMPLES * NOF_SCAN_CHANNELS;
}
SAADC_INTENSET = INT_STARTED | INT_END | INT_STOPPED | INT_CALIBRATEDONE;
SAADC_SAMPLERATE = 0;// ( 1 << 12 ) | 1333; // Sample rate 16 MHz / ( 5 x 266) = 12030 Hz.
// Sample rate setup
TIMER1_PRESCALER = 0; // 16 MHx base frequency
TIMER1_MODE = 0; // Timer
TIMER1_BITMODE = 0; // 16 Bit timer
TIMER1_CC[0] = 16000000 / SAMPLE_RATE;
TIMER1_SHORTS = 1; // CC0 clears counter
TIMER1_TASKS_CLEAR = 1;
// Analog input mapping - setup to fit board
#if defined( CONFIG_TARGET_NRF_DK ) || defined( CONFIG_TARGET_NRF_DK_BREAK_OUT)
SAADC_CH[0].PSELP = AIN1;
SAADC_CH[1].PSELP = AIN2;
SAADC_CH[2].PSELP = AIN4;
SAADC_CH[3].PSELP = AIN5;
//SAADC_CH[4].PSELP = AIN0;
#else
SAADC_CH[0].PSELP = AIN0;
SAADC_CH[1].PSELP = AIN1;
SAADC_CH[2].PSELP = AIN2;
SAADC_CH[3].PSELP = AIN3; // VBAT_MON
#endif
// Analog input configuration - according to errata 74 this must be the last thing before enable
SAADC_CH[0].CONFIG = RESP_BYPASS | RESN_BYPASS | GAIN1_4 | REFSEL_INTERNAL | TACQ_10US | MODE_SE | BURST_DISABLED;
SAADC_CH[1].CONFIG = RESP_BYPASS | RESN_BYPASS | GAIN1_4 | REFSEL_INTERNAL | TACQ_10US | MODE_SE | BURST_DISABLED;
SAADC_CH[2].CONFIG = RESP_BYPASS | RESN_BYPASS | GAIN1_4 | REFSEL_INTERNAL | TACQ_10US | MODE_SE | BURST_DISABLED;
SAADC_CH[3].CONFIG = RESP_BYPASS | RESN_BYPASS | GAIN1_4 | REFSEL_INTERNAL | TACQ_10US | MODE_SE | BURST_DISABLED;
//SAADC_CH[4].CONFIG = RESP_BYPASS | RESN_BYPASS | GAIN1_4 | REFSEL_VDD1_4 | TACQ_10US | MODE_SE | BURST_DISABLED;
PPI_CH[0].EEP = &TIMER1_EVENTS_COMPARE[0];
PPI_CH[0].TEP = &SAADC_TASKS_SAMPLE;
PPI_CHENSET = 1;
NVIC_SetPriority( SAADC_IRQ_NO, SAADC_IRQ_LEVEL );
NVIC_ClearPendingIRQ( SAADC_IRQ_NO );
NVIC_EnableIRQ( SAADC_IRQ_NO );
SAADC_ENABLE = 1;
isr_cmd = ISR_CMD_CALIBRATE_OFFSET;
SAADC_TASKS_CALIBRATEOFFSE = 1;
adc_client = os_get_pid();
}
else
{
isr_cmd = ISR_CMD_STOP;
}
break;
Code to stop ADC in IRQ handler:
if( SAADC_EVENTS_STOPPED > 0 )
{
SAADC_EVENTS_STOPPED = 0;
if( isr_cmd == ISR_CMD_CALIBRATE_OFFSET )
{
isr_cmd = ISR_CMD_NONE;
TIMER1_TASKS_START = 1;
SAADC_TASKS_START = 1;
}
else // Stop ADC
{
NVIC_DisableIRQ( SAADC_IRQ_NO );
SAADC_ENABLE = 0;
uint8_t n;
for( n = 0; n < 8; n++ )
{
SAADC_CH[n].CONFIG = 0;
SAADC_CH[n].PSELP = 0;
SAADC_CH[n].PSELN = 0;
}
TIMER1_TASKS_CLEAR = 1;
TIMER1_TASKS_STOP = 1;
PPI_CHENCLR = 1;
os_isr_status_bits_set( DEVHDL_ADC, ISR_STATUS_SAMPLING_STOPPED );
}
}
Appart from the high current consumption the operation is fine.