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

Why does my SAADC hang on calibration?

Hello,

I am having an issue with my SAADC, it seems to hang while calibrating. The flow of my app is as follows, on my main the SAADC is started with saadc_start() , where a calibration happens and I don't get a hanging. Afterwards on the handler of the SAADC I desinitialize the SAADC. Later, I have my battery service (battery_level_update()) that will restart the SAADC in order to take a sample and then while calibrating, the SAADC hangs waiting for calibration outcome.

Any advise why does this occur?

Thanks

PS: I am using SDK12.2 with s132v3

void saadc_handler_interrupt(nrf_drv_saadc_evt_t const * const p_event)
{
    uint32_t err_code;
    uint16_t voltage_mV;
    nrf_saadc_value_t adc_result;
    uint16_t tmp_voltage;
    float    adc_gain;

    NRF_LOG_INFO("SAADC interruption\n");

    if (p_event->type == NRF_DRV_SAADC_EVT_CALIBRATEDONE)
    {
        m_adc_cal_in_progress = false;
    }
    else if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
    {
        adc_result = (float) 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);

        err_code = adc_gain_enum_to_real_gain(ADC_GAIN, &adc_gain);
        APP_ERROR_CHECK(err_code);


        // calling the function that converts the adc reading adc_result into a voltage in mV
        err_code = adc_to_batt_voltage(adc_result, &voltage_mV);
        APP_ERROR_CHECK(err_code);
        
        NRF_LOG_INFO("Read value from saadc %d [mV]\n",voltage_mV);
        //calling the function that will send the battery voltage reading to the BLE stack
        batt_event_handler_adc(voltage_mV);
        
    }
    
    //TODO: disble saadc when not used
//    NRF_LOG_INFO("Disabling SAADC...\n");
//    nrf_drv_saadc_uninit();

}

static uint32_t saadc_calibrate( nrf_drv_saadc_config_t saadc_config)
{
    uint32_t err_code;

    m_adc_cal_in_progress = true;
    err_code = nrf_drv_saadc_calibrate_offset();
    APP_ERROR_CHECK(err_code);

    while(m_adc_cal_in_progress)
    {
        /* Wait for SAADC calibration to finish. */
    }

    return M_BATT_STATUS_CODE_SUCCESS;
}

static uint32_t saadc_start(batt_meas_param_t batt_meas_init)
{
    uint32_t err_code;

   
    nrf_drv_saadc_config_t saadc_config = NRF_DRV_SAADC_DEFAULT_CONFIG;

    err_code = nrf_drv_saadc_init(&saadc_config, saadc_handler_interrupt);
    APP_ERROR_CHECK(err_code);

    // we calibrate the SAADC before configuring it
    err_code = saadc_calibrate(saadc_config);
    APP_ERROR_CHECK(err_code);


    nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(batt_meas_init.adc_pin_no);

    channel_config.burst    = NRF_SAADC_BURST_ENABLED;
    channel_config.gain     = ADC_GAIN;
    //channel_config.acq_time = NRF_SAADC_ACQTIME_3US;

    err_code = nrf_drv_saadc_channel_init(0, &channel_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_buffer_convert(m_buffer, ADC_BUF_SIZE);
    APP_ERROR_CHECK(err_code);

     return M_BATT_STATUS_CODE_SUCCESS;
}


void battery_level_update(void)
{
    uint32_t err_code;
    uint8_t  battery_level;

    nrf_saadc_event_t  saadc_event;
    nrf_saadc_event_check(saadc_event);
    
    NRF_LOG_INFO("Battery Level update interruption\r\n");

    err_code = saadc_start(batt_meas_init);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_sample();
    APP_ERROR_CHECK(err_code);
    

}
Related