NRF_SAADC_EVENT_DONE appears delayed causing inconsistent ADC read timing

I have configured the ADC on my nRF52832 to trigger a read based on a PPI timer. I am using EasyDMA to capture 75 samples via double buffering. My PPI timer is configured to fire an ADC sample task every 1ms.

   nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL6,(uint32_t)nrf_timer_event_address_get(NRF_TIMER3,  NRF_TIMER_EVENT_COMPARE0), nrf_drv_saadc_sample_task_get());

I have scoped the signals and see that the NRF_SAADC_EVT_STARTED event is occurring every 1ms as expected. However, my NRF_SAADC_EVENT_DONE event is delayed by 3-4ms at times. This delay in getting the DONE event seems to occur every 500ms or so. When this occurs, it means I am taking ~78ms to read 75 samples which causes synchronization problems in our application.

I am looking for some guidance on where this delay may be coming from or configurations to check as I am out of ideas for next steps. I understand that you don't have access to all of my firmware code; but, I have commented out just about everything and this delay is still occurring. I am running SoftDevice S132 v7.3.0 with SDK 16.0.0. I have an active BLE connection while acquisition is occurring but I have removed all notifications just in case that was causing the hang. Other than BLE and ADC acquisition, I have debug logging enabled and call NRF_LOG_PROCESS() before calling nrf_pwr_mgmt_run() in my idle_state_handler() method. Very simple stuff at this point.

The attached image shows what I am seeing. The RED wave is the SAMPLE task, the GREEN wave is the DONE event and the BLUE wave toggles upon each call to my ADC callback upon DMA buffer full (NRF_DRV_SAADC_EVT_DONE). You can see that there is a gap in the GREEN wave form which has a width of ~4ms in this image (3ms longer than expected). You can see the widths of the good samples and the corrupted samples in the Timing Markers section on the right of the screen shot. Again, what might cause the ADC done event to be delayed  like this?

Any thoughts or suggestions would be much appreciated.

Thanks!

-Mike

  • Hi Edvin,

    I discovered the issue in my code base. I have setup an APP_TIMER that fires every 500msec. Inside the handler of that timer, I do some I2C communications. Any delays in that communication can cause the ADC event firing to be delayed. I don't understand how the APP_TIMERs are setup in hardware; but they apparently are managed via an interrupt that causes other interrupts (ADC events) to be delayed. I have removed the I2C communication from the timer callback and just set a flag, in essence, and call the I2C code in the main loop.

    Best,

    -Mike

Related