Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SAADC reinit crash device

Hi

I am running saadc battery measurement using the refernce code.

When I run the  adc_configure() I have about 500uA consumption

then According to this thread   I run this code (below 3 lines)  after I read the battery level in the saadc_event_handler()

nrf_drv_saadc_uninit();
NRF_SAADC->INTENCLR = (SAADC_INTENCLR_END_Clear << SAADC_INTENCLR_END_Pos);
NVIC_ClearPendingIRQ(SAADC_IRQn);

The problem occuers when I try to re-start the measument again, the device crash if I run adc_configure() or even just run nrf_drv_saadc_init()

Any advice?  why does this occuer?

void adc_configure(void)
{
ret_code_t err_code = nrf_drv_saadc_init(NULL, saadc_event_handler);
APP_ERROR_CHECK(err_code);

nrf_saadc_channel_config_t config =
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_VDD);
err_code = nrf_drv_saadc_channel_init(0, &config);
APP_ERROR_CHECK(err_code);

err_code = nrf_drv_saadc_buffer_convert(&adc_buf[0], 1);
APP_ERROR_CHECK(err_code);

err_code = nrf_drv_saadc_buffer_convert(&adc_buf[1], 1);
APP_ERROR_CHECK(err_code);
//reduce 500uA from saadc currents
// nrf_drv_saadc_uninit();
// NRF_SAADC->INTENCLR = (SAADC_INTENCLR_END_Clear << SAADC_INTENCLR_END_Pos);
//NVIC_ClearPendingIRQ(SAADC_IRQn);
}

  • Hey Yaniv,

    You need to uninit the driver after the ADC is finished sampling, in the event handler and not in the adc_configure function. 

    Cheers,

    Håkon.

  • Hi,

    I am doing that, Sorry didn't copy that part

    still crashing after second init (not after uinint)

    Any advice?

    void saadc_event_handler(nrf_drv_saadc_evt_t const * p_event)
    {
    if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
    {
    nrf_saadc_value_t adc_result;
    uint16_t batt_lvl_in_milli_volts;
    uint8_t percentage_batt_lvl;
    uint32_t err_code;

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

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

    batt_lvl_in_milli_volts = ADC_RESULT_IN_MILLI_VOLTS(adc_result) +
    DIODE_FWD_VOLT_DROP_MILLIVOLTS;
    percentage_batt_lvl = battery_level_in_percent(batt_lvl_in_milli_volts);
    if (batt_lvl_in_milli_volts > 0x0C40) //> 2.9V
    batt_lvl_in_milli_volts2 = 0x30;
    if (batt_lvl_in_milli_volts < 0x0C40) //2.5V
    batt_lvl_in_milli_volts2 = 0x25;
    if (batt_lvl_in_milli_volts < 0x0834) //<2.1V
    batt_lvl_in_milli_volts2 = 0x20;

    nrf_drv_saadc_uninit();
    NRF_SAADC->INTENCLR = (SAADC_INTENCLR_END_Clear << SAADC_INTENCLR_END_Pos);
    NVIC_ClearPendingIRQ(SAADC_IRQn);
    }
    }

    void adc_configure(void)
    {
    ret_code_t err_code = nrf_drv_saadc_init(NULL, saadc_event_handler);
    APP_ERROR_CHECK(err_code);

    nrf_saadc_channel_config_t config =
    NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_VDD);
    err_code = nrf_drv_saadc_channel_init(0, &config);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_buffer_convert(&adc_buf[0], 1);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_buffer_convert(&adc_buf[1], 1);
    APP_ERROR_CHECK(err_code);

    }

  • I'll test your code when I get back to work on Wednesday.

Related