SAADC PPI trigger channels separately

Hello, I'm working on an application with precise timing requirements. Basically I need to generate a short pulse and sample two channels during the pulse. In addition, I would like to use a third channel for a slower/low-priority battery monitor task.

I already have implemented the GPIO control for the pulse via Timers and PPI, and I was planning to use it as well to trigger ADC acquisitions during the pulse. However, I have two doubts:

  • Since the pulses happen with high frequency, I would like the ADC to store samples in a buffer autonomously. While the ADC supports buffering, it's unclear to me if I can still trigger manually each acquisition (via PPI) when using this feature (nrf_drv_saadc_buffer_convert or similar), or if the ADC just samples on its own time. For me, it's critical that the trigger is controlled for each sample by the PPI. To clarify with an example, I would like to setup a buffer (eg: 10 samples), then trigger via PPI 10 single acquisitions and only after the 10th get the callback/read the ADC buffered data. Is this possible?
  • Secondly, I would like to add a third channel that I can trigger occasionally for battery monitoring, independent of the time-sensitive application.

If not, what approach do you suggest?

Thank you!

  • Ah interesting! I'm not 100% sure, I think I'm using the nrfx 3.3.0 as in https://github.com/NordicSemiconductor/nrfx/tree/v3.3.0

    My project is based on nrf-conenct v2.6.1, which pulls this nrfx version (accordingly to the README and CHANGELOG files in the main folder)
    Hope this helps!

  • Hi there,

    Torbjørn was using nRF5SDK SAADC example that use the SAADC v1 driver not V2 as used in nRF Connect SDK. END event is generated each time the SAADC has filled up the buffer, the NRFX_SAADC_EVT_FINISHED is generated once all the provided buffers has been filled. In your case, they are equal since you're only using 1 buffer. 

    Yaxit said:

    For example, while the double-buffered solution works, with a single buffer it does not, and I just have an idea why that might be the case.

    With the doubled buffered solution, I add the new buffer in the callback as shown in the example, and I can always trigger the ADC by 1) triggering TASK_START and then 2) triggering TASK_SAMPLE via PPI.

    However, if I only use one buffer TASK_START is not sufficient, and I need to call nrfx_saadc_mode_trigger() again before I can start sampling with PPI.

    I believe this is the case because in the first case the acquisition is never "finished" (intended as EVT_FINISHED is asserted, aka all buffers are filled), while in the second case since there is a single buffer EVT_DONE and EVT_FINISHED both trigger. And it seems that after a EVT_FINISH I cannot simply use a TASK_START to re-trigger the ADC (not even if I add a buffer first).

    Could you share your code?

    regards

    Jared 

Related