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, as mentioned before in this thread, 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.

  • Since this just cost me a day of work:

    This also relates to Anomaly 74 of the nRF52832!

    From the Errata:

    3.15 [74]

    SAADC: Started events fires prematurely

    This anomaly applies to IC Rev. Rev 1, build codes QFAA-B00, QFAB-B00, CIAA-B00. It was inherited from the previous IC revision Engineering C.

    Symptoms False EVENTS_STARTED

    Conditions TACQ <= 5 µs

    Consequences The EVENTS_STARTED can come when not expected

    Workaround The module must be fully configured before it is enabled, and the TACQ configuration must be the last configuration set before ENABLE.

    There is a flag in the SDK to apply the workaround, NRF52_PAN_74, but from what I can see the problem still arises when the last channel to be added has TACQ >5µs and therefore the workaround is not applied!

  • So you fixed it by calling nrf_saadc_enable() after the last nrf_saadc_channel_init() ?

    Would that mean you have to disable the SAADC when you want to reconfigure channels?

  • I've just hit a similar issue.
    I'm using the nRF52810. I'm using the driver to sample 4 channels (AIN0 through AIN3) at 120 Hz to a 32-sample long double buffer using TIMER1 as a hardware timer. It's very important to sample at precise intervals, so I can't trigger the SAMPLE task via software.

    My PPI setup used to be:
    TIMER1->EVENTS_COMPARE[0] ==== (short) ====> TIMER1->TASKS_CLEAR
    TIMER1->EVENTS_COMPARE[0] ==============> SAADC->TASKS_SAMPLE

    (TIMER1 is started on boot via software after the SAADC is initialized)

    It worked fine apparently. however, when hitting a breakpoint or on some BLE events, the channel order gets swapped from 1, 2, 3, 4 to 2, 3, 4, 1.

    Then I stumbled upon this thread and changed the PPI setup as follows:
    TIMER1->EVENTS_COMPARE[0] ==== (short) ====> TIMER1->TASKS_CLEAR
    TIMER1->EVENTS_COMPARE[0] ==============> SAADC->TASKS_SAMPLE

    SAADC->EVENTS_END ===============> TIMER1->TASKS_STOP

    SAADC->EVENTS_STARTED ===========> TIMER1->TASKS_START

    (TIMER1 is not started via software on boot)

    This way I prevent the SAMPLE task to be triggered before the driver swaps the buffers.

    My questions:
    1.- Can you foresee any further issues with this fix?.
    2.- I don't care about occasional glitches in the sampling interval due to the CPU being too busy to swap the buffers and trigger the SAADC START task on time when the current buffer runs out as long as they are few and sparse. Is there potential for severe or frequent glitches with this approach, or can you suggest an alternative workaround to avoid the glitches at all?

    Thanks for your assistance and take care!!

  • 1. This should prevent you from triggering the SAMPLE task while the SAADC is not started, so I believe this solution should work.

    2. The frequency and length of the glitches will depend on the BLE activity and other higher priority events. But this solution will shift the sampling point around in time when you start/stop the timer, is this not a problem as long as the time between the samples is constant?

Related