When using the local timer of the SAADC it should be started with TASK_START according to https://infocenter.nordicsemi.com/topic/ps_nrf52840/saadc.html?cp=4_0_0_5_22_4#concept_continuous.
"The internal timer and the continuous sampling are started by triggering the START task and stopped using the STOP task."
However this doesn't work. TASK_SAMPLE is also required.
void SAADC_IRQHandler(void)
{
if (nrf_saadc_event_check(NRF_SAADC_EVENT_END)) {
nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
__LOG(LOG_SRC_APP, LOG_LEVEL_DBG1, "NRF_SAADC_EVENT_END\n");
}
if (nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED)) {
nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
__LOG(LOG_SRC_APP, LOG_LEVEL_DBG1, "NRF_SAADC_EVENT_STARTED\n");
}
}
void current_sensor_init(void) {
nrf_saadc_resolution_set(NRF_SAADC_RESOLUTION_14BIT);
nrf_saadc_oversample_set(NRF_SAADC_OVERSAMPLE_16X);
nrf_saadc_continuous_mode_enable(16 * 16 * (2 + 3));
nrf_saadc_int_disable(NRF_SAADC_INT_ALL);
nrf_saadc_int_enable(NRF_SAADC_INT_END);
nrf_saadc_int_enable(NRF_SAADC_INT_STARTED);
nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
NRFX_IRQ_PRIORITY_SET(SAADC_IRQn, NRFX_SAADC_CONFIG_IRQ_PRIORITY);
NRFX_IRQ_ENABLE(SAADC_IRQn);
nrf_saadc_enable();
nrf_saadc_channel_config_t config = {
.resistor_p = NRF_SAADC_RESISTOR_DISABLED,
.resistor_n = NRF_SAADC_RESISTOR_DISABLED,
.gain = NRF_SAADC_GAIN1_5,
.reference = NRF_SAADC_REFERENCE_INTERNAL,
.acq_time = NRF_SAADC_ACQTIME_3US,
.mode = NRF_SAADC_MODE_DIFFERENTIAL,
.burst = NRF_SAADC_BURST_ENABLED,
.pin_p = NRF_SAADC_INPUT_AIN3,
.pin_n = NRF_SAADC_INPUT_AIN4,
};
nrf_saadc_channel_init(0, &config);
nrf_saadc_buffer_init(s_buf, 250);
nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
//nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);
}
In the above only NRF_SAADC_EVENT_STARTED is shown in the log.
If TASK_SAMPLE is triggered the NRF_SAADC_EVENT_END is also emitted to the log.
nrf_ppi_channel_t ppi_saadc_end;
APP_ERROR_CHECK(nrfx_ppi_channel_alloc(&ppi_saadc_end));
APP_ERROR_CHECK(nrfx_ppi_channel_assign(
ppi_saadc_end, nrf_saadc_event_address_get(NRF_SAADC_EVENT_END),
nrf_saadc_task_address_get(NRF_SAADC_TASK_START)));
nrf_ppi_channel_enable(ppi_saadc_end);
Connecting EVENT_END to TASK_START using PPI seem to be enough to keep the local timer running. But if TASK_CALIBRATEOFFSET is triggered after EVENT_END instead of TASK_START, TASK_SAMPLE is required to get the local timer to start sampling again.
I can't find anything related to this in the PS nor the Errata.
This was tested on the nRF52840-DK with an AAC0 variant. The same behavior was also seen on a nRF52833 AAA0 variant.
Thanks.