I'm using a timer to read the ADC repeatedly using PPI. On ADC read finish I call nrfx_saadc_buffer_convert ready for the next timer event. However, if I want to cancel conversion before the next timer event I stop the timer and call nrfx_saadc_abort. This fails because the ADC isn't converting, but nrfx_saadc_buffer_convert set the state to busy.
Essentially the problem is attempting to abort after calling nrfx_saadc_buffer_convert but before sampling fails.
Is this a bug? It seems abort should abort even if buffer_convert has been called without the sample task being started. Is there a way to just cancel the buffer_convert? Should I just call nrfx_saadc_sample followed by nrfx_saadc_abort? (this is inconvenient because I don't want to sample again, so I need to set a flag to indicate sampling is aborted and then ignore the result and don't call buffer_convert again)
When you call nrfx_saadc_buffer_convert , m_cb.adc_state = NRF_SAADC_STATE_BUSY;
If you call nrfx_saadc_abort before sampling
then it checks for the busy state as below
The nrfx_saadc_is_busy will return true since nrfx_saadc_buffer_convert marked it so. Hence it should go ahead with trigger the STOP task.
However, if I want to cancel conversion before the next timer event I stop the timer and call nrfx_saadc_abort. This fails because the ADC isn't converting, but nrfx_saadc_buffer_convert set the state to busy.
I think you misunderstood nrfx_saadc_abort->nrfx_saadc_is_busy condition.
Or maybe I misunderstood your question. If so, excuse me and please help me understand the problem.
I am running SAADC in low power mode, so all the nrfx_saadc_buffer_convert function does is init the buffer and enable interrupts. The sampling is started on the timer. So when abort is called before sample, there is no task to stop (the state in SAADC is busy, but the ADC isn't actually doing anything), so it waits for the state to be idle but the state is not changed by anything, so that fails and it hits the assert:
// Wait for ADC being stopped.
NRFX_WAIT_FOR((m_cb.adc_state == NRF_SAADC_STATE_IDLE), HW_TIMEOUT, 0, result);
That does not look correct, Seems like a bug in the nrfx. But before confirming that it is a bug and giving you a possible workaround, can you please give me your project (or stripped version of it) for me to replicate this and analyze it a bit closer?