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

Offset in SAADC samples with Easy DMA and BLE

I have a nrf52 application that samples four saadc channels at 1kHZ. That is: Map four pins to ADC input and let Easy DMA take care of the sampling so that the data is processed ten times a second (100 * 4 samples). This works pretty well, except...

When I enable the BLE connection, the data is shifted in the buffer. Without BLE enabled, the data layout in the memory is as following {{1,2,3,4}, {1,2,3,4}, ...}. But, when BLE is activated, the memory layout is: {{4,1,2,3}, {4,1,2,3}, ...} I really don't know what causes the difference. I have no way to check if the data is shifted, or did the samples just swap places. I wonder if the softdevice blocks some of the samples that would cause the problem.

The saadc implementation is double buffered, like in "saadc_sample_from_two_pins - scan mode" here

The BLE implementation is based on ble_app_hrs_freertos in SDK 12.1.0. That is also the SDK version I'm using.

Any help would be appreciated.

  • Hi jorgen, if i look at figure 101 of PS v1.3, the next RESULT.PTR is set after the STARTED event. What I think happens for me sometimes, is that the RESULT.PTR is set only after the next START, and I guess that also leads to the same issue as reported in this forum post.

    What i'm now planning to use as solution is to stop the timer that triggers the SAMPLE task, if the RESULT.PTR is not set yet a few samples before the END. In that case, i will restart the ADC. (for this to work, i was wondering how much time it can take for the STARTED event to be sent after START has been called).

    If you have other suggestions, let me know :)

  • We do not have measurements on how long time it will take from START task until STARTED event. You can test this yourself by setting and clearing a GPIO using PPI and GPIOTE, and a logic analyzer to see the time the pin is set. 

  • I am using PPI to connect END to START but i still DO see channels swaps.

    I use 3 channels and i abort ADC sampling and shut down the ADC to save power/

    Later on, when i re enable the sampling using the exact same code, i see one or two channels skipped so i get constant channels mismatch in my ram buffer.

    The number of skipped channels depend on how much delay i add before stopping the ADC when aborting.

    When i use 15us delay (exactly equal to 3 samples = 3us acq + 2 us convert x 3), i do get good results.

    But this concerns me a lot since i do not understand why is that and how to make sure timing issues will not cause the problem to re appear

  • I ended up fixing it with a timeout timer. It's rather complicated, but i've never had any channel skips anymore.

    I described it all in this document, with text and uml diagrams. Code can be found on the repository too, but it's part of a large whole.

  • Have you tried to stop the SAADC (triggering STOP task) and setup the buffers again after you init it again? If you uninit the SAADC in the middle of a scan cycle, you might end up in the same situation, with incomplete DMA events. You should also call abort function and wait for the SAADC to complete ongoing tasks before uninit.

Related