I have been doing some measurements on the execution time of my code and noticed something strange.
Currently, I am using an application timer to trigger the ADC to sample at 256Hz.
The code to trigger the ADC in the application timer interrupt handler is shown below,
Timer Interrupt Handler and Snippet of the function to trigger ADC sampling
( ignore the third ADC channel which is sampled at a different freq and not enabled currently )
static void timer_timeout_handler(void * p_context)
{
adc_sample();
LED_drv_timer_update();
}
static void adc_sample()
{
int timer1 = app_timer_cnt_get();
temp_cnt_tck++;
int16_t temp[5] = {10};
if( !m_saadc_initialized )
{
*((volatile uint32_t *)0x40007FFC) = 1;
saadc_init2();
if( ( (temp_cnt_tck % (tempSR/TEMP_OVER) ) == 0) && (temp_on) && (temp_cnt_tck>0))
{
NRF_SAADC->CH[2].PSELP = ANALOG_TEMPERATURE_SENSOR_PIN << SAADC_CH_PSELP_PSELP_Pos;
NRF_SAADC->CH[2].PSELN = SAADC_CH_PSELN_PSELN_NC << SAADC_CH_PSELN_PSELN_Pos;
NRF_SAADC->RESULT.MAXCNT = 3;
}
m_saadc_initialized = true;
}
saadc_sample();
int timer2 = app_timer_cnt_get();
int timer_d;
app_timer_cnt_diff_compute(timer2,timer1,&timer_d);
NRF_LOG_INFO("Ticks %d %d %d\n",timer1, timer2,timer_d);
NRF_LOG_FLUSH();
.
.
.
.
}
SAADC Task Trigger ( taken from the forum )
ADC is reset to address the issue with high DMA current event after un-initialization when
bust + oversample + scan mode is enabled
static void saadc_sample()
{
NRF_SAADC->TASKS_START = 1;
while (NRF_SAADC->EVENTS_STARTED == 0);
NRF_SAADC->EVENTS_STARTED = 0;
// Do a SAADC sample, will put the result in the configured RAM buffer.
NRF_SAADC->TASKS_SAMPLE = 1;
while (NRF_SAADC->EVENTS_END == 0);
NRF_SAADC->EVENTS_END = 0;
NRF_SAADC->TASKS_STOP = 1;
saadc_uninit2();
*((volatile uint32_t *)0x40007FFC) = 0;
m_saadc_initialized = false;
}
SAADC Configuration ( taken from the forum )
static void saadc_init2(void)
{
// Configure SAADC singled-ended channel, Internal reference (0.6V) and 1/6 gain.
NRF_SAADC->CH[0].CONFIG = (SAADC_CH_CONFIG_GAIN_Gain4 << SAADC_CH_CONFIG_GAIN_Pos) |
(SAADC_CH_CONFIG_MODE_Diff << SAADC_CH_CONFIG_MODE_Pos) |
(SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) |
(SAADC_CH_CONFIG_RESN_Bypass << SAADC_CH_CONFIG_RESN_Pos) |
(SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESP_Pos) |
(SAADC_CH_CONFIG_TACQ_40us << SAADC_CH_CONFIG_TACQ_Pos) |
(SAADC_OVERSAMPLE_OVERSAMPLE_Over4x << SAADC_OVERSAMPLE_OVERSAMPLE_Pos)|
(SAADC_CH_CONFIG_BURST_Enabled << SAADC_CH_CONFIG_BURST_Pos);
// Configure the SAADC channel with VDD as positive input, no negative input(single ended).
NRF_SAADC->CH[0].PSELP = ANALOG_CH0_PIN << SAADC_CH_PSELP_PSELP_Pos;
NRF_SAADC->CH[0].PSELN = ANALOG_VREF_PIN << SAADC_CH_PSELN_PSELN_Pos;
NRF_SAADC->CH[1].CONFIG = (SAADC_CH_CONFIG_GAIN_Gain4 << SAADC_CH_CONFIG_GAIN_Pos) |
(SAADC_CH_CONFIG_MODE_Diff << SAADC_CH_CONFIG_MODE_Pos) |
(SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) |
(SAADC_CH_CONFIG_RESN_Bypass << SAADC_CH_CONFIG_RESN_Pos) |
(SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESP_Pos) |
(SAADC_CH_CONFIG_TACQ_40us << SAADC_CH_CONFIG_TACQ_Pos)|
(SAADC_OVERSAMPLE_OVERSAMPLE_Over4x << SAADC_OVERSAMPLE_OVERSAMPLE_Pos)|
(SAADC_CH_CONFIG_BURST_Enabled << SAADC_CH_CONFIG_BURST_Pos);
// Configure the SAADC channel with VDD as positive input, no negative input(single ended).
NRF_SAADC->CH[1].PSELP = ANALOG_CH1_PIN << SAADC_CH_PSELP_PSELP_Pos;
NRF_SAADC->CH[1].PSELN = ANALOG_VREF_PIN2 << SAADC_CH_PSELN_PSELN_Pos;
NRF_SAADC->CH[2].CONFIG = (SAADC_CH_CONFIG_GAIN_Gain1_6 << SAADC_CH_CONFIG_GAIN_Pos) |
(SAADC_CH_CONFIG_MODE_SE << SAADC_CH_CONFIG_MODE_Pos) |
(SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) |
(SAADC_CH_CONFIG_RESN_Bypass << SAADC_CH_CONFIG_RESN_Pos) |
(SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESP_Pos) |
(SAADC_CH_CONFIG_TACQ_40us << SAADC_CH_CONFIG_TACQ_Pos)|
(SAADC_OVERSAMPLE_OVERSAMPLE_Over4x << SAADC_OVERSAMPLE_OVERSAMPLE_Pos)|
(SAADC_CH_CONFIG_BURST_Enabled << SAADC_CH_CONFIG_BURST_Pos);
// // Configure the SAADC channel with VDD as positive input, no negative input(single ended).
NRF_SAADC->CH[2].PSELP = SAADC_CH_PSELP_PSELP_NC << SAADC_CH_PSELP_PSELP_Pos;
NRF_SAADC->CH[2].PSELN = SAADC_CH_PSELN_PSELN_NC << SAADC_CH_PSELN_PSELN_Pos;
// Configure the SAADC resolution.
NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_12bit << SAADC_RESOLUTION_VAL_Pos;
// Configure result to be put in RAM at the location of "result" variable.
NRF_SAADC->RESULT.MAXCNT = 2;
NRF_SAADC->RESULT.PTR = (uint32_t)&result[0];
// No automatic sampling, will trigger with TASKS_SAMPLE.
NRF_SAADC->SAMPLERATE = SAADC_SAMPLERATE_MODE_Task << SAADC_SAMPLERATE_MODE_Pos;
// Enable SAADC (would capture analog pins if they were used in CH[0].PSELP)
NRF_SAADC->ENABLE = SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos;
here I am trying to measure the time taken for the saadc_sample function to execute, which is
is a blocking function that waits for the 2 channels to finish sampling ( oversampling 4x, 40us acquisition time, burst enabled on all channels ).
I noticed that the time taken is the same ( 3 ticks = approx 90us ) regardless of the oversampling configuration, whereas intuitively the time taken should
be 2 ( channel count ) * 40us ( acquisition time ) * 4 ( oversample ) = 320us.
Is this normal or is there something that I am missing?
Output from RTT

Thanks!