Unexpected behavior from SAADC at the beginning of sampling in advanced configuration mode.

The setup : nrf 52840 , NCS 1.9.1 , The SAADC is configured in advanced mode with 1 single end channel and double buffered with size of 16 (32bytes). RTC is configured to tick at 128 Hz. (pre scaler = 255). This tick event is connected to SAMPLE task via a PPI channel. 
When RTC is enabled, it starts ticking and PPI triggers sample task, SAADC samples and stores in the buffer, calls event handler when buffer is filled.
This continues till RTC is disabled. which is what the intended operation.

Everything is good so far, until I added another channel for sampling.
And ran into the problem something like the one discussed in this ticket . Followed the first solution mentioned there and ran into another one. 
This time it is with redundant data on the third buffer.

The third buffer is giving the same data as the first buffer. The driver is given two buffers before enabling the RTC and after each NRFX_SAADC_EVT_DONE event, another buffer is requested by calling event handler. (notice that the SAADC END event is connected to SAADC START task via PPI so i gave start_on_end as false in the saadc configuration.)

The first buffer given from event handler happens to be the third one for driver, this buffer is not over written with new samples. I have changed the static buffers to dynamic buffers, altered between 3 different buffer but no change in this behavior. 

After some investigation into the driver and SDK's example of the similar implementation,

noticed that a new buffer is set right when NRFX_SAADC_EVT_DONE is received. In order to do the same with NCS i made these two changes in the NCS saadc driver.

and set the buffer right when NRFX_SAADC_EVT_DONE is received in my code just like in SDK example.
This solved the all my problems with the code for now. And the only remaining question is  .. Does this change affect any part of the driver or performance of the SAADC or not.?? Can I rely on this ??
Or is there any other way to do this.??
The saadc driver seems to be updated in the later versions but the only change at this point in code i see is that saadc_trigger called first by checking start_on_end flag before calling the event handler with NRFX_SAADC_EVT_DONE event...


 

Parents
  • Hi,

    I'm not sure I follow the flow in your application and how this issue can occur, but is there a specific reason that you are not using the NRFX_SAADC_EVT_BUF_REQ event to provide the next buffer? The SAADC peripheral have double-buffering feature, allowing you to set the next buffer as soon as the STARTED event is generated. If you provide the next buffer in NRFX_SAADC_EVT_BUF_REQ event, it should set the buffer at the correct time.

    Modifying the driver is generally not recommended, but can be done if you need a different behavior than what is supported by the driver. You use-case sounds very general and should be supported by the driver already.

    Best regards,
    Jørgen

  • Hi Jørgen, 
    Very sorry for keeping you waiting this long. I was occupied with other works and could not attend this problem again. 
    To make it quick, I have prepared example codes that you can run nrf52840dk_nrf52840 board to reproduce what I am facing here. 

    - THE CHANNELS CONFIGURED HERE ARE P0.05 AND P0.31

    - TO DISTINGUISH BETWEEN THE SAMPLES OF THE TWO CHANNELS CONNECT THE P0.31 TO GROUND AND P0.5 TO VDD OR VICE-VERSA.

    - ALSO, I HAVE ADDED A TIME DIFFERENCE INDICATION FOR EVERY SAADC HANDLER CALL (WHICH PRINTS THE TIME ELAPSED BETWEEN PREVIOUS CALL TO THE CURRENT CALL - 32KHZ KERNEL CYCLE VALUE) TO GIVE AN IDEA OF THE TIMING OF THE EVENTS IN SAADC DRIVER).

    - ALSO, I AM DEVELOPING THIS APPLICATION ON NCS V1.9.1.

    1. blinky_dual_channel_error.zipblinky_dual_channel_error.zip

    this is the initial error. for simplicity i used the blinky example.
    steps to recreate: 

    - build the application and run it on eval board. 

    - you will see all the samples gets printed on UART as the buffers arrive from SAADC. 

    - observe the first two buffers on the log, at the end of first buffer and start of the second buffer you will find the values of the same channel repeated twice. (This might also happen at end of second buffer and start of third buffer)

    -to rectify, I followed the first workaround mentioned here. which resulted in the second error below.

    2. blinky_dual_channel_erro_after_end_to_start_ppi_channel.zipblinky_dual_channel_error_after_end_to_start_ppi_channel (2).zip

    - again, run this code, keeping the wires connected.

    - observe the time delays between saadc handler calls. after giving the first event done the buffer should be immediately request a buffer as the started event is generated when it starts writing samples to the second buffer.

      - and the third buffer values also get corrupted.

    -After this, I checked the saadc example in sdk and decided to make the changes in the driver which cleared all the issues and saadc worked properly.

    3blinky_after_driver_changes.zip. blinky_after_driver_changes.zip

    - Make the changes in the driver as described previously and run this code. 
    - this one has the end to start ppi channel enabled. and start_on_end flag in the saadc intialization given as false.

Reply
  • Hi Jørgen, 
    Very sorry for keeping you waiting this long. I was occupied with other works and could not attend this problem again. 
    To make it quick, I have prepared example codes that you can run nrf52840dk_nrf52840 board to reproduce what I am facing here. 

    - THE CHANNELS CONFIGURED HERE ARE P0.05 AND P0.31

    - TO DISTINGUISH BETWEEN THE SAMPLES OF THE TWO CHANNELS CONNECT THE P0.31 TO GROUND AND P0.5 TO VDD OR VICE-VERSA.

    - ALSO, I HAVE ADDED A TIME DIFFERENCE INDICATION FOR EVERY SAADC HANDLER CALL (WHICH PRINTS THE TIME ELAPSED BETWEEN PREVIOUS CALL TO THE CURRENT CALL - 32KHZ KERNEL CYCLE VALUE) TO GIVE AN IDEA OF THE TIMING OF THE EVENTS IN SAADC DRIVER).

    - ALSO, I AM DEVELOPING THIS APPLICATION ON NCS V1.9.1.

    1. blinky_dual_channel_error.zipblinky_dual_channel_error.zip

    this is the initial error. for simplicity i used the blinky example.
    steps to recreate: 

    - build the application and run it on eval board. 

    - you will see all the samples gets printed on UART as the buffers arrive from SAADC. 

    - observe the first two buffers on the log, at the end of first buffer and start of the second buffer you will find the values of the same channel repeated twice. (This might also happen at end of second buffer and start of third buffer)

    -to rectify, I followed the first workaround mentioned here. which resulted in the second error below.

    2. blinky_dual_channel_erro_after_end_to_start_ppi_channel.zipblinky_dual_channel_error_after_end_to_start_ppi_channel (2).zip

    - again, run this code, keeping the wires connected.

    - observe the time delays between saadc handler calls. after giving the first event done the buffer should be immediately request a buffer as the started event is generated when it starts writing samples to the second buffer.

      - and the third buffer values also get corrupted.

    -After this, I checked the saadc example in sdk and decided to make the changes in the driver which cleared all the issues and saadc worked properly.

    3blinky_after_driver_changes.zip. blinky_after_driver_changes.zip

    - Make the changes in the driver as described previously and run this code. 
    - this one has the end to start ppi channel enabled. and start_on_end flag in the saadc intialization given as false.

Children
  • shiva74638 said:
    -After this, I checked the saadc example in sdk and decided to make the changes in the driver which cleared all the issues and saadc worked properly.

    Does this mean that you resolved your issue? Or did you not manage to resolve it in your own application?

    shiva74638 said:
    - Make the changes in the driver as described previously and run this code. 

    Exactly which driver are you referring to here, and which changes? Your driver, the nrfx_saadc driver, the Zephyr ADC driver?

    shiva74638 said:
    - this one has the end to start ppi channel enabled. and start_on_end flag in the saadc intialization given as false.

    Yes, this is needed to prevent channel swapping in the buffer when sampling with PPI and having many other interrupts in the application blocking the SAADC interrupt.

    We have created NRFX examples in last release that works under Zephyr: https://github.com/zephyrproject-rtos/hal_nordic/blob/master/nrfx/samples/src/nrfx_saadc/maximum_performance/main.c

    Unfortunately there is no sample for the your exact use-case, however it could be built upon this example by adding extra channel.

    Two immediate issues comes to my mind regarding the timing issues you are experiencing:

    • You do not utilize NRFX_SAADC_EVT_READY or NRFX_SAADC_EVT_FINISHED in your application

    • Driver is susceptible to timing when it comes to dual buffering handling, so printk shouldn't be used in NRFX driver context

Related