This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SAADC callback

I have this working and producing good and accurate results, but I'm still puzzled by some of the examples in the SDK and the documentation.

I am using the processor to call for the saadc sample (i.e, not ppi) and I set the nrf_drv_saadc_buffer_converts immediately before hand:

err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0], SAMPLES_IN_BUFFER);
err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1], SAMPLES_IN_BUFFER);
err_code = nrf_drv_saadc_sample();

In the examples in the SDK (12) and elsewhere I also see another nrf_drv_saadc_buffer_convert call in the callback handler prior to reading the data in the buffer:

err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);

My question is what is the point of calling this again in the call back and why is the first argument p_event->data.done.p_buffer? I've read the documentation but it still doesn't make sense to me. Could anyone explain this as if they are speaking to a 5 year old?

Many thanks,

  • Hi,

    The SAADC of nRF52 support double buffering, meaning you can have two buffers setup for conversion where one is processed while the other is used for sampling.

    When you call

    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0], SAMPLES_IN_BUFFER);
    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1], SAMPLES_IN_BUFFER);
    

    you setup two buffers.

    When one of the buffers is full, you will get a callback. You now have to setup the buffer for sampling again, if not, your application will not have a buffer available for sampling.

    The reason the first argument is p_event->data.done.p_buffer is that this is a pointer to the buffer that is full and caused the callback. By using this as the argument, the same buffer will be setup for conversion.

    Best regards,

    Jørgen

  • Ok, thanks. So am I correct in thinking that the reason it is fine to set up that buffer again before reading the data in the buffer is that it won't be overridden until a sample is triggered once more? So setting up the buffer could be done either before or after reading the data in the buffer?

  • In this example if should not matter, as there is only one channel active, space for 5 samples in each buffer, and a sampling rate of once every 400ms. Due to the double buffering, the second buffer will be used for sampling when the first buffer is full. The data in the buffer will not be erased, as it only use a pointer to the memory location, and it will neither be overwritte until the second buffer is full, meaning 2 seconds after you get the callback, leaving you plenty time to read the buffer. In a more high-speed sample application, I would suggest reading the buffer before setting it up for conversion again to avoid loss of samples.

  • Hello all, I have question about buffer filling, if there is multiple channels initialized for conversion, that's means that p_event->data.done.p_buffer[0] contains the converted value for first channel enabled, p_event->data.done.p_buffer[1] for the second one, and p_event->data.done.p_buffer[2] for the third one?

Related