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

NRFX SAADC in Zephyr fast and slow interleaved sampling

Hi Nordic team,

I have successfully developed an application using nrfx (Timer/PPI/SAADC) combo in NCS 1.5.x to be able to sample 2x differential channels very fast.

Similar to the method advised here

I have a few questions:

Since using advanced mode and PPI,  everything is set to work automatically, very fast (16K sample per sec) for 2x differential channels, and 4x oversample, adding more channels is impossible w/o lowering the overall sample rate.

1- How do I add other channels that I don't need to be sampled very fast? e.g. a few times ( < 20sps) per second. 

does this mean I  have to stop PPI and uninit and reinit  saadc to get the samples for low freq channels, then uninit reinit for the fast sampling? and switch between the two operations constantly? if this is the only way, can I do this in an interrupt context that is initiated by the timer? hence keeping it in sync with the timer/ppi/saadc combo.

Or is there a better way I cannot think of?

Unfortunately I cannot sample the high frequency channels less than 16ksps, so lowering that is not an option.

2- Hardware question: What are the noise/performance figures for the GAIN amplifier inside the nRF52840 SAADC for different gain/attenuate settings? 
Basically we do have an AGC amplifier circuit that feeds those high frequency channels into nRF ADC pins, therefore we're curious to see what gain or attenuate setting inside SAADC results in best performance, and hence adjust our external AGC accordingly.

Thanks,

Parents
  • Since using advanced mode and PPI,  everything is set to work automatically, very fast (16K sample per sec) for 2x differential channels, and 4x oversample, adding more channels is impossible w/o lowering the overall sample rate.

     As mentioned in nRF52840 Product Specification - SAADC - Oversampling, it is not possible to use more than one channel when using oversampling:

    "Note: Oversampling should only be used when a single input channel is enabled, as averaging is performed over all enabled channels."

    One way of going about this, is to only have one channel enabled at the time, and when you're done oversampling on that channel you reconfigure the SAADC to use the next channel. As Kenneth suggests in this ticket: https://devzone.nordicsemi.com/f/nordic-q-a/71704/right-way-to-oversample-burst-multiple-saadc-input-pins.

    You could probably also disable oversampling and sample over several channels and do the averaging in software.

    1- How do I add other channels that I don't need to be sampled very fast? e.g. a few times ( < 20sps) per second. 

    does this mean I  have to stop PPI and uninit and reinit  saadc to get the samples for low freq channels, then uninit reinit for the fast sampling? and switch between the two operations constantly? if this is the only way, can I do this in an interrupt context that is initiated by the timer? hence keeping it in sync with the timer/ppi/saadc combo.

     "does this mean I have to stop PPI and unitit and reinit saadc...". Yes, this would be the way to go about this, since there is no way of configuring separate sampling rates for separate channels. I will get back to you next week about the specifics of the implementation.

    2- Hardware question: What are the noise/performance figures for the GAIN amplifier inside the nRF52840 SAADC for different gain/attenuate settings? 
    Basically we do have an AGC amplifier circuit that feeds those high frequency channels into nRF ADC pins, therefore we're curious to see what gain or attenuate setting inside SAADC results in best performance, and hence adjust our external AGC accordingly.

     I will look into this next week as well.

    Best regards,

    Simon

  • if this is the only way, can I do this in an interrupt context that is initiated by the timer? hence keeping it in sync with the timer/ppi/saadc combo.

    It may be fine re-initializing the ADC from the interrupt since it such a small operation. However, I can't say this for certain.

    The section Offloading ISR work recommends ISRs to execute quickly, to ensure predictable system operation. So the optimal approach would be to offload the ADC re-initialization to a Workqueue Thread, or another thread. Offloading ISR work says the following 

    "When an ISR offloads work to a thread, there is typically a single context switch to that thread when the ISR completes, allowing interrupt-related processing to continue almost immediately. However, depending on the priority of the thread handling the offload, it is possible that the currently executing cooperative thread or other higher-priority threads may execute before the thread handling the offload is scheduled."

    If you make sure the thread handling the offload is of high priority, you may not encounter any issues with synchronization/not being able to reconfigure it fast enough. Check out Torbjørn's NCS ADC code snippet to see how to offload work to a Work Queue.

Reply
  • if this is the only way, can I do this in an interrupt context that is initiated by the timer? hence keeping it in sync with the timer/ppi/saadc combo.

    It may be fine re-initializing the ADC from the interrupt since it such a small operation. However, I can't say this for certain.

    The section Offloading ISR work recommends ISRs to execute quickly, to ensure predictable system operation. So the optimal approach would be to offload the ADC re-initialization to a Workqueue Thread, or another thread. Offloading ISR work says the following 

    "When an ISR offloads work to a thread, there is typically a single context switch to that thread when the ISR completes, allowing interrupt-related processing to continue almost immediately. However, depending on the priority of the thread handling the offload, it is possible that the currently executing cooperative thread or other higher-priority threads may execute before the thread handling the offload is scheduled."

    If you make sure the thread handling the offload is of high priority, you may not encounter any issues with synchronization/not being able to reconfigure it fast enough. Check out Torbjørn's NCS ADC code snippet to see how to offload work to a Work Queue.

Children
No Data
Related