This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Stopping SAADC after buffer convert using PPI

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

        if (nrfx_saadc_is_busy())
        {
            xxx
        }

    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.
    bool result;
    NRFX_WAIT_FOR((m_cb.adc_state == NRF_SAADC_STATE_IDLE), HW_TIMEOUT, 0, result);
    NRFX_ASSERT(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?

  • I've changed my code now to work around the issue by calling sample and waiting for the next ADC result. But to reproduce, roughly:

    init saadc and a channel

    call buffer_convert on the channel

    call abort, will hit assert

  • Good that you have a workaround for this and the workaround looks sensible too. It seems like a bug trying to abort immediately after buffer_convert. 

Related