I have searched Nordic and the web and have seen several instances of "can't uninit saadc successfully". Neither Nordic support nor I am aware of a single example of saadc uninit working. My private thread with Nordic (in which I share more proprietary code details) has reached a dead end so I am looking for a solution from the community based only on Nordic's saadc example.
I see about ten different library calls that may be relevant to adding an uninit sequence to the SAADC example in SDK 14.2.0. My goal is, using Nordic's example on their DK board, to:
- measure DK power consumption before SAADC comes up
- measure DK power consumption while SAADC is up
- measure DK power consumption after SAADC has been uninit'd
- verify that #1 and #3 current measurements are the same
All I am asking for is a recommended uninit sequence for the Nordic SDK 14.2.0 saadc example. Then I will expand on that solution and apply it to my dual ADC channel code below.
Except for the fact that current consumption is (usually) too high after the uninit completes the following code sequence is working as intended. This code is a two adc channel extension of the Nordic example. The #3 current measurement is always 5,10,15, or 20 mA higher than the #1 current measurement which leads me to think that the random timing of the uninit relative to the sampling and clock may be the problem.
// Nordic SDK 14.2.0 example saadc - modified for TWO ADC channels
nrf_drv_saadc_init(NULL, saadc_bemf_callback);
// Two adc channels
nrf_drv_saadc_channel_init(FR_ADC_ISEN_CHANNEL, &m_adc_channel_config0);
nrf_drv_saadc_channel_init(FR_ADC_BEMF_CHANNEL, &m_adc_channel_config1);
nrf_drv_saadc_buffer_convert(l_buffer_pool[0], FR_ADC_BUFFER_SIZE);
nrf_drv_saadc_buffer_convert(l_buffer_pool[1], FR_ADC_BUFFER_SIZE);
nrf_drv_ppi_init();
nrf_drv_timer_init(&l_timer, &timer_cfg, timer_handler);
nrf_drv_timer_extended_compare(
&l_timer,
NRF_TIMER_CC_CHANNEL0,
ticks,
NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
false
);
nrf_drv_timer_enable(&l_timer);
nrf_drv_timer_compare_event_address_get(
&l_timer,
NRF_TIMER_CC_CHANNEL0
);
nrf_drv_saadc_sample_task_get();
nrf_drv_ppi_channel_alloc(&l_ppi_channel();
nrf_drv_ppi_channel_enable(l_ppi_channel);
// The above, similar to Nordic's example but with TWO ADC channels works
// perfectly
// Init done, now try uninit
nrf_drv_ppi_channel_disable(l_ppi_channel);
nrf_drv_ppi_channel_free(l_ppi_channel);
nrf_drv_timer_disable(&l_timer);
nrf_drv_timer_uninit(&l_timer);
nrf_drv_ppi_uninit();
// Again, I'm using Two ADC channels
nrf_drv_saadc_channel_uninit(FR_ADC_BEMF_CHANNEL);
nrf_drv_saadc_channel_uninit(FR_ADC_ISEN_CHANNEL);
nrf_drv_saadc_uninit();
// Current draw is NOT back to initial levels, and the resulting draw varies
// by multiples of 5mA !!! What would cause the 5mA granularity (I'm using a
// microamp capable meter)