There is a race condition in the SAADC driver when using buffer convert.
I am trying to drive ADC at maximum rate to sample 3 ADC channels, and so I call the following in the interrupt routine when it returns from completing an ADC and filling the first buffer. I am using
#define BUFFER_SAMPLES 3
in my application
/* set up next buffer */
err_code = nrfx_saadc_buffer_convert(p_buffer, BUFFER_SAMPLES);
APP_ERROR_CHECK(err_code);
/* start next sample */
err_code = nrfx_saadc_sample();
APP_ERROR_CHECK(err_code);
When I use the following
channel_config.acq_time = NRF_SAADC_ACQTIME_40US;
the sampling process freezes and does not do any ADC
However if I use
channel_config.acq_time = NRF_SAADC_ACQTIME_3US;
everything works.
Also if I set
#define BUFFER_SAMPLES 1
everything works.
I did some debugging and noticed if I set breakpoints everything worked, and I iterated to find a critical place. Eventually I determined if I placed a for...loop at ***** in the following the driver would work for 40US.
There appears to be a race condition in setting the NRF_SAADC_TASK_SAMPLE when a long acquisition is set, ie before the first sample is taken and written to RAM (not sure why one sample is taken after issuing a START but looking at memory shows this is the case).
nrfx_err_t nrfx_saadc_sample()
{
NRFX_ASSERT(saadc_m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
nrfx_err_t err_code = NRFX_SUCCESS;
if (saadc_m_cb.adc_state != NRF_SAADC_STATE_BUSY)
{
err_code = NRFX_ERROR_INVALID_STATE;
}
else if (saadc_m_cb.low_power_mode)
{
nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
}
else
{
******
nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);
}
NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
return err_code;
}
I have a workaround by using 3US but it would be good for this issue to be fixed.