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

SAADC Sampling Issue

Hello,

I am trying to sample and reconstruct an audio signal using the SAADC and I2S respectively. I have a double buffer setup for the SAADC, where we process the data in one buffer while sampling in the other, but I am getting discontinuities in the output signal every time saadc_handler() is called. The attached scope shot captures the analog input waveform (yellow) and reconstructed output from I2S codec (green). It has been verified that the discontinuity happens exactly when SAADC changes output buffer from one to the other. My understanding is that the I2S output stream is set up correctly (we have tested with this i2s_example, and it worked perfectly), so I am assuming there is something I need to change when sampling.

The sampling and reconstruction frequency are both at 31.25 kHz, and each input buffer size is 1024 (with an output buffer size of 2048).

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <nrf.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "nrf.h"
#include "nrf_gpio.h"
#include "nrf_delay.h"
#include "nrf_twi_mngr.h"
#include "nrf_drv_spi.h"
#include "app_util_platform.h"
#include "nordic_common.h"
#include "app_timer.h"
#include "mem_manager.h"
#include "nrf_drv_clock.h"
#include "nrf_drv_gpiote.h"
#include "nrf_drv_saadc.h"
#include "nrf_drv_ppi.h"
#include "nrf_drv_timer.h"
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 

Here is a screenshot of the scope image of the input and output signals:

 

  • Hi,

    How does the buffer look when it is filled with the failing samples? Have you tried moving the processing of the buffer outside of the interrupt handler/callback handler (possibly copy the content to a third buffer or using a third buffer to allow double buffering and processing of one buffer)? I would also recommend that you move the nrf_drv_saadc_buffer_convert() call after you have processed/copied the buffer. Calling this function will trigger the START task, allowing the SAADC peripheral to overwrite the buffer while you process it.

    There is a new SAADC driver coming in NRFX that will handle double buffering pointer updates better, and provide more advanced features, but unfortunately, we do not provide any examples of this yet as it is not integrated into the SDK.

    Best regards,
    Jørgen

  • Hi Jørgen,

    I tried both of those suggestions, and I couldn't get a working solution. Moving nrf_drv_saadc_buffer_convert() call didn't seem to have an effect, likely since the buffer processing time is still shorter than the time it takes for the secondary buffer to fill up.

    Moving the buffer processing outside of the interrupt handler to the timer handlers didn't seem to resolve the issue as well; there is still a small glitch in the output buffer that lines up with everytime the saadc_handler() gets past the if statement (I tested this by toggling a GPIO everytime the if statement in the interrupt handler was true). I am thinking 

    Let me know if you have any other suggestions about this issue, and thank you for your advice!

  • Do you have a sample application that you can share, which we can use to reproduce the behavior?

    If you could also post the buffer with all the SAADC samples when this glitch happens, it would help with finding the root cause.