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.

  • RTC or TIMER could be used for regular sampling. The point is to not trigger the sample task using PPI, but trigger it manually in the interrupt handler/driver callback for the RTC/TIMER peripheral.

    Are you seeing the issue at 20 Hz? I would not expect this to be a problem with double buffering and buffers large enough to hold some samples for each active channel.

  • Thanks for your speedy response Jørgen.  Your help is much appreciated.

    Yes, we are seeing this issue when sampling at 20Hz.  

    I have attempted a solution using a nrf_drv_timer_t but I am confused on one important point:  The SAADC is by default, a priority of 6.  I create a hardware timer on channel 2, but, It seems I cannot run a timer with a priority lower (numerically higher) than 6!  See this:

    nrf_drv_common_irq_enable.c

    #ifdef SOFTDEVICE_PRESENT

        ASSERT((priority == APP_IRQ_PRIORITY_LOW) || (priority == APP_IRQ_PRIORITY_HIGH));

    #endif

    This blocks my timer config from setting the priority lower than the ADC:

    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;

    timer_cfg.interrupt_priority = APP_IRQ_PRIORITY_LOWEST;

    So... I am at a loss on how this solution could work if I can't set the priority of the timer task to APP_IRQ_PRIORITY_LOWEST

  • Are you seeing the issue at 20 Hz? I would not expect this to be a problem with double buffering and buffers large enough to hold some samples for each active channel.


    We are using double buffering but each buffer is only 3 in size (because we're sampling from 3 channels... vdd, bat, and a motor).  

    It's unclear to me - with my current understanding of how this issue manifests - how increasing the buffer size solves the problem?  I thought this was a timing issue essentially? 

  • Which SDK version are you using? For nRF52 series, priority level 2, 3, 5, 6, and 7 should be available to the application.

    Yes, you are correct. The larger buffer size should not eliminate the issue, only delay it. I was thinking that the SAADC would be started when the first buffer is filled, but this would require implementing solution 1.

  • hey jorgen & others, 

    i am trying to sample 3 channels at 10khz with BLE. I have tried to do what users velitsu and Mathew have implemented (suggestion 1).

    I am still seeing data swap between channels. I am sure how to increase size of buffers either. 

    any futher suggestions ?

Related