I am in the process of integrating the latest SAADC driver into my project and have noticed an issue after adding the errata 122 workaround to my saadc event handler per the example here. Without the workaround I am seeing expected values from two channels (VDD and a thermistor) and as expected, current consumption never returns to normal. With the workaround added to my event handler I am getting value that are quite a bit lower than they should be. VDD seems to be slightly low but the value is also within a reasonable range of the actual voltage that makes it difficult to tell. The value I am getting back from my thermistor is significantly lower however. Has anyone noticed this behavior in the V2 driver?
I am using a Rev2 nrf52840 with the thread and zigbee SDK 4.1 and the drivers from SDK 17.0.2.
Relevant code:
void saadc_callback(nrfx_saadc_evt_t const *p_event) { ret_code_t err_code = NRF_SUCCESS; if (p_event->type == NRFX_SAADC_EVT_DONE) { nrf_gpio_pin_clear(SENSOR_1_EN); // err_code = nrfx_saadc_buffer_convert(p_event->data.done.p_buffer, samples_in_buffer); // APP_ERROR_CHECK(err_code); //update_temperature_attribute(MULTI_SENSOR_ENDPOINT, convertTemp(p_event->data.done.p_buffer[0])); zb_schedule_app_callback((zb_callback_t)(process_temperature), MULTI_SENSOR_ENDPOINT, ZB_TRUE, p_event->data.done.p_buffer[0], ZB_FALSE); // Param 1 = endpoint (10), CB_Param = SAADC buffer value // Need to eventually determine why either not allowing the SAADC to calibrate (commenting the below block out) or only calibrating at any conditional interval (m_adc_evt_counter % 10 == 0) causes power consumption to be stuck in the 1.2mA range. if(m_adc_evt_counter) { nrfx_saadc_abort(); zb_schedule_app_callback(calibrate_adc, 0, ZB_FALSE, 0, ZB_FALSE); } m_adc_evt_counter++; NRF_LOG_INFO("VDD: %d", p_event->data.done.p_buffer[1]); } else if(p_event->type == NRFX_SAADC_EVT_CALIBRATEDONE) { NRF_LOG_INFO("SAADC Calibration Complete"); } // Workaround from Errata 122 volatile uint32_t temp1; volatile uint32_t temp2; volatile uint32_t temp3; temp1 = *(volatile uint32_t *)0x40007640ul; temp2 = *(volatile uint32_t *)0x40007644ul; temp3 = *(volatile uint32_t *)0x40007648ul; *(volatile uint32_t *)0x40007FFCul = 0ul; *(volatile uint32_t *)0x40007FFCul; *(volatile uint32_t *)0x40007FFCul = 1ul; *(volatile uint32_t *)0x40007640ul = temp1; *(volatile uint32_t *)0x40007644ul = temp2; *(volatile uint32_t *)0x40007648ul = temp3; } static void init_saadc() { ret_code_t err_code = NRF_SUCCESS; std::array <nrfx_saadc_channel_t, 2> channels = { { { .channel_config = { .resistor_p = NRF_SAADC_RESISTOR_DISABLED, .resistor_n = NRF_SAADC_RESISTOR_DISABLED, .gain = NRF_SAADC_GAIN1_4, .reference = NRF_SAADC_REFERENCE_VDD4, .acq_time = NRF_SAADC_ACQTIME_10US, .mode = NRF_SAADC_MODE_SINGLE_ENDED, .burst = NRF_SAADC_BURST_ENABLED, .pin_p = NRF_SAADC_INPUT_AIN5, .pin_n = NRF_SAADC_INPUT_DISABLED }, .pin_p = NRF_SAADC_INPUT_AIN5, .pin_n = NRF_SAADC_INPUT_DISABLED, .channel_index = 0 }, { .channel_config = { .resistor_p = NRF_SAADC_RESISTOR_DISABLED, .resistor_n = NRF_SAADC_RESISTOR_DISABLED, .gain = NRF_SAADC_GAIN1_6, .reference = NRF_SAADC_REFERENCE_INTERNAL, .acq_time = NRF_SAADC_ACQTIME_10US, .mode = NRF_SAADC_MODE_SINGLE_ENDED, .burst = NRF_SAADC_BURST_ENABLED, .pin_p = NRF_SAADC_INPUT_VDD, .pin_n = NRF_SAADC_INPUT_DISABLED }, .pin_p = NRF_SAADC_INPUT_VDD, .pin_n = NRF_SAADC_INPUT_DISABLED, .channel_index = 1 } } }; err_code = nrfx_saadc_init(NRFX_SAADC_CONFIG_IRQ_PRIORITY); APP_ERROR_CHECK(err_code); err_code = nrfx_saadc_channels_config(channels.data(), channels.size()); APP_ERROR_CHECK(err_code); while (nrfx_saadc_offset_calibrate(saadc_callback) != NRF_SUCCESS) { __WFE(); __SEV(); __WFE(); } } void zb_app_timer_handler(zb_uint8_t param) { ret_code_t err_code = NRF_SUCCESS; nrf_gpio_pin_set(SENSOR_1_EN); err_code = nrfx_saadc_simple_mode_set((1 << 0 | 1 << 1), NRF_SAADC_RESOLUTION_14BIT, NRF_SAADC_OVERSAMPLE_32X, saadc_callback); APP_ERROR_CHECK(err_code); err_code = nrfx_saadc_buffer_set(m_buffer_pool.data(), m_buffer_pool.size()); APP_ERROR_CHECK(err_code); err_code = nrfx_saadc_mode_trigger(); APP_ERROR_CHECK(err_code); zb_ret_t zb_err_code = zb_schedule_app_alarm(zb_app_timer_handler, 0, 60 * ZB_TIME_ONE_SECOND); APP_ERROR_CHECK(zb_err_code); }