static void saadc_init(void) {
nrf_drv_saadc_config_t saadc_config = NRF_DRV_SAADC_DEFAULT_CONFIG;
saadc_config.resolution = NRF_SAADC_RESOLUTION_12BIT;
saadc_config.oversample = (nrf_saadc_oversample_t)NRF_SAADC_OVERSAMPLE_256X;
saadc_config.interrupt_priority = NRFX_SAADC_CONFIG_IRQ_PRIORITY;
saadc_config.low_power_mode = NRFX_SAADC_CONFIG_LP_MODE;
nrf_saadc_channel_config_t channel_0_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);
channel_0_config.gain = NRF_SAADC_GAIN1_6;
channel_0_config.reference = NRF_SAADC_REFERENCE_INTERNAL;
channel_0_config.burst = NRF_SAADC_BURST_ENABLED;
//nrf_saadc_burst_set(0, NRF_SAADC_BURST_ENABLED);
nrf_saadc_channel_config_t channel_1_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN1);
channel_1_config.gain = NRF_SAADC_GAIN1_6;
channel_1_config.reference = NRF_SAADC_REFERENCE_INTERNAL;
channel_1_config.burst = NRF_SAADC_BURST_ENABLED;
//nrf_saadc_burst_set(1, NRF_SAADC_BURST_ENABLED);
nrf_saadc_channel_config_t channel_2_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN5);
channel_2_config.gain = NRF_SAADC_GAIN1_6;
channel_2_config.reference = NRF_SAADC_REFERENCE_INTERNAL;
channel_2_config.burst = NRF_SAADC_BURST_ENABLED;
//nrf_saadc_burst_set(2, NRF_SAADC_BURST_ENABLED);
nrf_saadc_channel_config_t channel_3_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN4);
channel_3_config.gain = NRF_SAADC_GAIN1_6;
channel_3_config.reference = NRF_SAADC_REFERENCE_INTERNAL;
channel_3_config.burst = NRF_SAADC_BURST_ENABLED;
//nrf_saadc_burst_set(3, NRF_SAADC_BURST_ENABLED);
ERROR_CHECK(nrf_drv_saadc_init(&saadc_config, saadc_event_handler));
ERROR_CHECK(nrf_drv_saadc_channel_init(0, &channel_0_config));
ERROR_CHECK(nrf_drv_saadc_channel_init(1, &channel_1_config));
ERROR_CHECK(nrf_drv_saadc_channel_init(2, &channel_2_config));
ERROR_CHECK(nrf_drv_saadc_channel_init(3, &channel_3_config));
//https://devzone.nordicsemi.com/f/nordic-q-a/63074/buffer-order-swap-of-saadc-used-with-nrf-mesh
nrf_ppi_channel_t saadc_buffer_swap_ppi_channel;
nrf_drv_ppi_channel_alloc(&saadc_buffer_swap_ppi_channel);
nrf_drv_ppi_channel_assign(saadc_buffer_swap_ppi_channel,
(uint32_t)&NRF_SAADC->EVENTS_END,
(uint32_t)&NRF_SAADC->TASKS_START);
nrf_drv_ppi_channel_enable(saadc_buffer_swap_ppi_channel);
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Starting initial SAADC calibration\n");
while(nrf_drv_saadc_calibrate_offset() != NRF_SUCCESS); //trigger calibration task
saadc_calibrate = false;
}
static void saadc_event_handler(nrf_drv_saadc_evt_t const * p_event) {
static uint16_t saadc_event_counter = 1; //used for recalibrating adc, start at 1 otherwise will calibrate right away
if(p_event->type == NRF_DRV_SAADC_EVT_DONE) {
//Read buffer
for(int i=0; i<SAADC_SAMPLES_IN_BUFFER; i++) {
saadc_value_current[i] = p_event->data.done.p_buffer[i];
}
if((saadc_event_counter % SAADC_CALIBRATION_INTERVAL) == 0) {
nrf_drv_saadc_abort(); //abort all ongoing conversions because calibration cannot be run if SAADC is busy
saadc_calibrate = true; //set flag to trigger calibration in main context when SAADC is stopped
saadc_event_counter = 0; //reset
}
if(saadc_calibrate == false) {
//Set buffer, double-buffering
ERROR_CHECK(nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAADC_SAMPLES_IN_BUFFER));
//Print samples
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "\nsaadc_value_current[0]: %u\nsaadc_value_current[1]: %u\nsaadc_value_current[2] %u\nsaadc_value_current[3]: %u\n", saadc_value[0], saadc_value[1], saadc_value[2], saadc_value[3]);
}
saadc_event_counter++;
}
else if(p_event->type == NRF_DRV_SAADC_EVT_CALIBRATEDONE) {
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "SAADC calibration complete\n");
//Need to setup both buffers, as they were both removed with the call to nrf_drv_saadc_abort before calibration
ERROR_CHECK(nrf_drv_saadc_buffer_convert(saadc_buffer_pool[0], SAADC_SAMPLES_IN_BUFFER));
ERROR_CHECK(nrf_drv_saadc_buffer_convert(saadc_buffer_pool[1], SAADC_SAMPLES_IN_BUFFER));
}
}
//======================================================//
//SAADC
if(saadc_calibrate) {
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Starting interval SAADC calibration\n");
while(nrf_drv_saadc_calibrate_offset() != NRF_SUCCESS); //trigger calibration task
saadc_calibrate = false;
/*
//PAN-212 workaround: https://devzone.nordicsemi.com/f/nordic-q-a/45339/saadc-burst-problems-in-scan-vs-non-scan-acquisitions/
//Above three lines commented out
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Power-cycling and re-initalizing SAADC for calibration\n");
nrf_drv_saadc_uninit();
*(volatile uint32_t *)0x40007FFC = 0;
*(volatile uint32_t *)0x40007FFC = 1;
saadc_init();
saadc_timeout_counter = 0; //reset
*/
}
else if((saadc_timeout_counter % SAADC_SAMPLE_INTERVAL) == 0) {
ERROR_CHECK(nrf_drv_saadc_sample());
saadc_timeout_counter = 0; //reset
}
saadc_timeout_counter++;