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

SAADC oversample with burst configuration

Dear DevZone,

I am trying to configure the SAADC on my custom nRF52840 board.

I would like to use it in blocking mode together with oversample 16x and burst enabled.

I started from the example provided in the SDK, and I firstly removed all the parts related to non-blocking mode.

Then I modified the parameters to set oversample and burst mode. Here the steps I performed:

  • I modified the configuration struct to enable burst in this way:

#define NRFX_SAADC_DEFAULT_CHANNEL_CONFIG_SE(PIN_P) \
{ \
.resistor_p = NRF_SAADC_RESISTOR_DISABLED, \
.resistor_n = NRF_SAADC_RESISTOR_DISABLED, \
.gain = NRF_SAADC_GAIN1_6, \
.reference = NRF_SAADC_REFERENCE_INTERNAL, \
.acq_time = NRF_SAADC_ACQTIME_3US, \
.mode = NRF_SAADC_MODE_SINGLE_ENDED, \
.burst = NRF_SAADC_BURST_ENABLED, \ //enabled burst mode to automatically acquire 2^oversample samples with one request
.pin_p = (nrf_saadc_input_t)(PIN_P), \
.pin_n = NRF_SAADC_INPUT_DISABLED \
}

  • I modified the following value in the sdk_config file:

// <0=> Disabled
// <1=> 2x
// <2=> 4x
// <3=> 8x
// <4=> 16x
// <5=> 32x
// <6=> 64x
// <7=> 128x
// <8=> 256x

#ifndef NRFX_SAADC_CONFIG_OVERSAMPLE
#define NRFX_SAADC_CONFIG_OVERSAMPLE 4
#endif

Is the procedure correct? Am I missing something? Do you think there could be any issues related to the buffer size if I use the blocking mode (nrfx_saadc_sample_convert function)?

Thank you very much in advance,

best regard,

Gianluca Milani

Parents Reply Children
  • Thank you very much Jared,

    do you know if there is a suggested way to verify the actual realization of the 16 events related to the readings with an oscilloscope? Or via code? Thanks,

    best regards,

    Gianluca

  • Gianlucamilani said:

    do you know if there is a suggested way to verify the actual realization of the 16 events related to the readings with an oscilloscope? Or via code? Thanks,

     "DONE event is generated for every input sample taken" from product spec, which means that you can use the callback handler to see that the samples are taken during the oversampling.

  • Thanks Jared,

    I saw in this post https://devzone.nordicsemi.com/f/nordic-q-a/67552/what-is-the-eventdone-of-saadc-oversampling the differences between the EVENTS_DONE event of the oversample and the one for the buffer which is filled (SAADC_EVT_DONE).

    I cannot understand how to handle the generation of the event EVENTS_DONE in the callback function . can I do as the case with SAADC_EVT_DONE putting the address of the register? something like this?

    void saadc_callback_handler(nrf_drv_saadc_evt_t const * p_event)
    {
    //Empty
    static int a;
    if (p_event->type == 0x108)
    {
    
    
    a++;
    }
    }

    Thanks,

    Gianluca

  •  Hi,

    You're actually 100% correct, and I managed to mix up the SW and HW events myself. I'm so sorry for this. The driver doesn't really support monitoring the DONE event. You can use a PPI + a Timer in counter mode that increments every time the EVENTS_DONE event is produced. It's a bit more complex than just waiting for the DONE event to be produced by the driver. What's your intention of implementing this?

    regards

    Jared 

  • Dear Jared, 

    don't worry at all, thanks for the answer.

    My only intention was to check if I was actually performing the oversample correctly, but if you can confirm me that with the code I showed you before the oversampling is implemented, I can also avoid to perform this verification.

    P.S.: As you suggested here:

    I don't see any reason to use blocking in the first place as I don't see any benefit from it. It will just cause a higher power consumption.

    I tried to use the non-blocking one-shot mode. I did it following following the basic instruction from Infocenter:

    Here my code instructions for periodically triggering the reading:
        for(int n=1; n=1000; n++){
          
        err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool, SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);
        err_code = nrfx_saadc_sample();
        APP_ERROR_CHECK(err_code);
        float bat_vol = m_buffer_pool[0]*2.8/2*6*0.6/4095;
    
        nrf_delay_ms(1000);
    
        }
    Do you thing I am doing it correctly?
    Thanks,
    Gianluca
Related