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

High power after starting SAADC and softdevice

Hi everyone,

after a few days of analysis, I was able to find out what is the problem making my board consume a lot when idle.

I use SDK 15.0.0, softdevice S132 and a custom board with a few hardware (TWI and SAADC). BLE is not advertising for the moment.

If I run my code without using the SAADC, I have an idle consumption of 2-3 uA, which is perfect. I have periodic readings from the TWI and

all works fine.

As soon as I enable the SAADC, after I receive the first callback with correct data, the idle consumption become of about 470uA, and it never goes down.

I declared, as said in some discussions, the following in sdk.config


#ifndef NRFX_SAADC_CONFIG_LP_MODE
#define NRFX_SAADC_CONFIG_LP_MODE 1
#endif

and in the saadc_callback, I call uninit and I clear all the interrupts. My code is the following

void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{


    if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
    {

        ret_code_t err_code;

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

        int i;
        for (i = 0; i < NUM_SAMPLES; i++)
        {
            NRF_LOG_INFO("SAADC Sample: %d", p_event->data.done.p_buffer[i]);
        } 

    }

    nrf_drv_saadc_abort();
    nrf_drv_saadc_uninit();
        NRF_SAADC->INTENCLR = (SAADC_INTENCLR_END_Clear << SAADC_INTENCLR_END_Pos);               //Disable the SAADC interrupt

		NVIC_DisableIRQ( SAADC_IRQn );
        NVIC_ClearPendingIRQ(SAADC_IRQn);    
        NRF_CLOCK->TASKS_HFCLKSTOP;



}

I tried all the possible combinations for disabling the SAADC, without success.

So, my question is: how can I get rid of these 470uA of extra consumption? I suspect that somehow they come from the HFCLK, which for some reason is activated when reading

from the saadc, but if I understood correctly, the softdevice should manage the HFCLK by itself, right?

I also post my saadc_init code

void saadc_init(void)
{
    ret_code_t err_code;    


    nrf_saadc_channel_config_t pressure_channel_config =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN1);     
        pressure_channel_config.gain = NRF_SAADC_GAIN1_6;
        pressure_channel_config.reference  = NRF_SAADC_REFERENCE_INTERNAL;
        pressure_channel_config.burst = NRF_SAADC_BURST_ENABLED;
        pressure_channel_config.acq_time = NRF_SAADC_ACQTIME_10US;
        pressure_channel_config.pin_n = NRF_SAADC_INPUT_DISABLED;
        pressure_channel_config.resistor_n = NRF_SAADC_RESISTOR_DISABLED;
        pressure_channel_config.resistor_p = NRF_SAADC_RESISTOR_DISABLED;
        err_code = nrf_drv_saadc_init(NULL, saadc_callback);

        err_code = nrf_drv_saadc_channel_init(0, &pressure_channel_config);
        err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0], PH_NUM_SAMPLES);
        err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1], PH_NUM_SAMPLES);

    APP_ERROR_CHECK(err_code);
      

}

Parents Reply Children
  • Hi Martin, thanks for your reply.

    I found a solution and it was not the logger module; it is not clear to me but maybe you can understand why this is working.

    In my original post I forgot to mention that I was using 2 channels and a double buffer: following indications here in the forum, I was using one buffer for one channel and the other one for the second channel. 

    It turned out that for some reason the double buffering was causing the extra consumption. I now use a single buffer and I initialize the saadc to measure a first time from one channel and inside the saadc_callback I re-initialize the saadc to measure from the second channel (I use a shared variable to select first a channel then the other).

    It is not important for my application to have both values at exactly the same time, so this solution is fine for me.

    In any case, even if it works, I am curious to understand why the double buffer causes an extra consumption....do you have any idea about this?

  • Hi,

    I'm glad you figured out a solution. 

    When you use two (or more) buffers the SAADC driver utilizes EasyDMA to be able to take multiple samples without bothering your CPU with interrupts for each sample. EasyDMA requires certain HW resources, like e.g. the HF clock, to work and these resources draw more current. 

Related