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

stop and restart SAADC to power saving

Hello, I'm using softdevice 6.0 and SDK 15.

In my application, I would like stop the SAADC at the disconnection and then restart SAADC at the connection to power saving.

To start SAADC I use this code:

void saadc_init(void)
{
    ret_code_t err_code;

    err_code = nrf_drv_saadc_init(NULL, saadc_callback);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_channel_init(0, &channel_config_PRESSURE);
    APP_ERROR_CHECK(err_code);

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

 }

To launch a sampling I use the call:

nrf_drv_saadc_sample();

To stop the SAADC I use the call:

nrf_drv_saadc_uninit()

The problem is that after the stop the interrupt handler of SAADC no longer works.

The code for interrupt handler is the following:

void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{
  nrf_saadc_value_t adc_result;
  uint16_t pressure_mV_local;
  uint16_t pressure_mV_acc;
  int i;
  char debug_str[10] = {0};

    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, SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);

        adc_result = p_event->data.done.p_buffer[0];

    }
}

What is the correct procedure to stop and then to restart the SAADC?

Thanks

 

Parents
  • Hi,

    It is fine to call nrf_drv_saadc_uninit() as you do, but then you also have to initialize everything again before the next use. iI is not clear to me whether you do that or not? If not, you should get an assert from the driver if you have built the application with the DEBUG_NRF preprocessor define set (used by default in the Debug target for SES projects in the SDK).

    If this is not the problem, can you explain in more detail what you do and how the "interrupt handler of SAADC no longer works"?

  • Hello,the sequence of the operation is:

    connection

    saadc_init

    nrf_drv_saadc_sample

    saadc interrupt handler is triggered

    disconnection

    nrf_drv_saadc_uninit

    connection

    saadc_init

    nrf_drv_saadc_sample

    but at this point the saadc interrupt handler is not triggerd; SDK returns no error

    Best regards

  • Hi,

    That's odd. It should be straight forward, as demonstrated by this example application (adapted and simplified from the SAADC example in SDK 15.0.0):

    #include <stdbool.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    #include "nrf.h"
    #include "nrf_drv_saadc.h"
    #include "boards.h"
    #include "app_error.h"
    #include "nrf_delay.h"
    #include "app_util_platform.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #define SAMPLES_IN_BUFFER 1
    
    static nrf_saadc_value_t    m_buffer;
    static uint32_t             m_adc_evt_counter;
    static volatile bool        m_sampling = false;
    
    
    static 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, SAMPLES_IN_BUFFER);
            APP_ERROR_CHECK(err_code);
    
            NRF_LOG_INFO("ADC event number: %d", (int)m_adc_evt_counter);
            NRF_LOG_INFO("%d", p_event->data.done.p_buffer[0]);
    
            m_adc_evt_counter++;
    
            m_sampling = false;
        }
    }
    
    
    static void saadc_init(void)
    {
        ret_code_t err_code;
        nrf_saadc_channel_config_t channel_config =
            NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);
    
        err_code = nrf_drv_saadc_init(NULL, saadc_callback);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_channel_init(0, &channel_config);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_buffer_convert(&m_buffer, SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);
    }
    
    
    static void saadc_uninit(void)
    {
        nrf_drv_saadc_uninit();
    }
    
    
    static void saadc_sample(void)
    {
        m_sampling = true;
    
        ret_code_t err_code = nrf_drv_saadc_sample();
        APP_ERROR_CHECK(err_code);
    }
    
    
    static void saadc_init_sample_uninit(void)
    {
        saadc_init();
        saadc_sample();
        while (m_sampling == true) {};
        saadc_uninit();
    }
    
    
    int main(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        NRF_LOG_INFO("SAADC HAL simple example started.");
    
        while (1)
        {
            saadc_init_sample_uninit();
            NRF_LOG_FLUSH();
            nrf_delay_ms(100);
        }
    }
    

    Can you compare with the example and see in what way it differs from your implementation?

Reply
  • Hi,

    That's odd. It should be straight forward, as demonstrated by this example application (adapted and simplified from the SAADC example in SDK 15.0.0):

    #include <stdbool.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    #include "nrf.h"
    #include "nrf_drv_saadc.h"
    #include "boards.h"
    #include "app_error.h"
    #include "nrf_delay.h"
    #include "app_util_platform.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #define SAMPLES_IN_BUFFER 1
    
    static nrf_saadc_value_t    m_buffer;
    static uint32_t             m_adc_evt_counter;
    static volatile bool        m_sampling = false;
    
    
    static 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, SAMPLES_IN_BUFFER);
            APP_ERROR_CHECK(err_code);
    
            NRF_LOG_INFO("ADC event number: %d", (int)m_adc_evt_counter);
            NRF_LOG_INFO("%d", p_event->data.done.p_buffer[0]);
    
            m_adc_evt_counter++;
    
            m_sampling = false;
        }
    }
    
    
    static void saadc_init(void)
    {
        ret_code_t err_code;
        nrf_saadc_channel_config_t channel_config =
            NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);
    
        err_code = nrf_drv_saadc_init(NULL, saadc_callback);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_channel_init(0, &channel_config);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_buffer_convert(&m_buffer, SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);
    }
    
    
    static void saadc_uninit(void)
    {
        nrf_drv_saadc_uninit();
    }
    
    
    static void saadc_sample(void)
    {
        m_sampling = true;
    
        ret_code_t err_code = nrf_drv_saadc_sample();
        APP_ERROR_CHECK(err_code);
    }
    
    
    static void saadc_init_sample_uninit(void)
    {
        saadc_init();
        saadc_sample();
        while (m_sampling == true) {};
        saadc_uninit();
    }
    
    
    int main(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        NRF_LOG_INFO("SAADC HAL simple example started.");
    
        while (1)
        {
            saadc_init_sample_uninit();
            NRF_LOG_FLUSH();
            nrf_delay_ms(100);
        }
    }
    

    Can you compare with the example and see in what way it differs from your implementation?

Children
Related