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

SAADC low power SDKv13.0.0 and S132

Hello,

I'm currently developing an application on nrf52832 that'll use SAADC low power to fetch battery voltage level and report that value on BLE advertising data. I've adapt github example nFRF52-ADC-examples to the following:

#define REFERENCE_TO_MV		0.879120879 // 12BIT = 0xFFF - mV = ((x/0xFFF) * 3.6) * 1000 = 0.88
#include "nrf_drv_saadc.h"
#include "app_util_platform.h"
#include "batt_level.h"

nrf_saadc_value_t batteryReading;
nrf_drv_saadc_config_t adcConfig = {
	.resolution = NRF_SAADC_RESOLUTION_12BIT,
	.oversample = NRF_SAADC_OVERSAMPLE_8X,
	.interrupt_priority = APP_IRQ_PRIORITY_HIGH,
	.low_power_mode = true
};
nrf_saadc_channel_config_t batteryChannel = {
	.reference = NRF_SAADC_REFERENCE_INTERNAL,  // 0.6V internal reference
	.gain = NRF_SAADC_GAIN1_6,					// 1/6 Gain (VIN+ will be 0.6/(1/6) = 3.6V
	.acq_time = NRF_SAADC_ACQTIME_10US,
	.mode = NRF_SAADC_MODE_SINGLE_ENDED,		// VIN- shorted to GND
	.pin_p = NRF_SAADC_INPUT_VDD,				// Positive to battery voltage VDD
	.pin_n = NRF_SAADC_INPUT_DISABLED,			// Negative is GND
	.resistor_p = NRF_SAADC_RESISTOR_DISABLED,
	.resistor_n = NRF_SAADC_RESISTOR_DISABLED
};

battery_callback_t conversionResult;

void BatteryLevel_callback(nrf_drv_saadc_evt_t const *p_event){
    float mVInDecimal;
    uint16_t roundedVoltageValue;
    ret_code_t err_code;

    if(p_event->type == NRF_DRV_SAADC_EVT_CALIBRATEDONE){
        // done calibration initiate conversion
        err_code = nrf_drv_saadc_buffer_convert(&batteryReading, 1); // clear buffer
        APP_ERROR_CHECK(err_code);
    }else if(p_event->type == NRF_DRV_SAADC_EVT_DONE){
        err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, 1);
        APP_ERROR_CHECK(err_code);

        // disable the peripehral to save power!
        nrf_drv_saadc_uninit();
        NRF_SAADC->INTENCLR = (SAADC_INTENCLR_END_Clear << SAADC_INTENCLR_END_Pos);
        NVIC_ClearPendingIRQ(SAADC_IRQn);

        // convert read value to mV
        mVInDecimal = p_event->data.done.p_buffer[0] * REFERENCE_TO_MV;
        // convert to integer
        roundedVoltageValue = mVInDecimal;

        // call callback
        conversionResult(roundedVoltageValue);
    }
}

ret_code_t BatteryLevel_Init(battery_callback_t callback){
    ret_code_t err_code;
    conversionResult = callback;

    err_code = nrf_drv_saadc_init(&adcConfig, BatteryLevel_callback);
    APP_ERROR_CHECK(err_code);

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

    err_code = nrf_drv_saadc_buffer_convert(&batteryReading, 1);
    APP_ERROR_CHECK(err_code);

    NRF_SAADC->CH[0].CONFIG |= 0x01000000;	// enable burst mode, to be used with Oversample (Burst will sample the number of times defined on oversample)

    return nrf_drv_saadc_sample();
}

The voltage level sampled seems to be ok. But I getting spurious fault errors with id NRF_FAULT_ID_SD_ASSERT.

From looking in other threads in the forum I presume that I'm getting this assertion error because SAADC low power uses RTC0 as does softdevice (removing use of SAADC peripheral seems to solve the problem).

Is it possible to use SAADC low power alongside with softdevice, if so, what changes to I have to make to stop the assertion fails?

Related