<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>NRFX SAADC in Zephyr fast and slow interleaved sampling</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/75988/nrfx-saadc-in-zephyr-fast-and-slow-interleaved-sampling</link><description>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</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Fri, 25 Jun 2021 15:04:15 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/75988/nrfx-saadc-in-zephyr-fast-and-slow-interleaved-sampling" /><item><title>RE: NRFX SAADC in Zephyr fast and slow interleaved sampling</title><link>https://devzone.nordicsemi.com/thread/317282?ContentTypeID=1</link><pubDate>Fri, 25 Jun 2021 15:04:15 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:bb120310-2fd7-44e4-a852-56c773c603e8</guid><dc:creator>Simon</dc:creator><description>&lt;p&gt;Check out this answer&amp;nbsp;&lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/20291/offset-in-saadc-samples-with-easy-dma-and-ble/79053#79053"&gt;https://devzone.nordicsemi.com/f/nordic-q-a/20291/offset-in-saadc-samples-with-easy-dma-and-ble/79053#79053&lt;/a&gt;, which explain this issue and why it happens. Also see the two possible solutions.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NRFX SAADC in Zephyr fast and slow interleaved sampling</title><link>https://devzone.nordicsemi.com/thread/317266?ContentTypeID=1</link><pubDate>Fri, 25 Jun 2021 14:03:12 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a75d7ba8-9043-44db-ba30-908d859f9347</guid><dc:creator>Simon</dc:creator><description>[deleted]&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NRFX SAADC in Zephyr fast and slow interleaved sampling</title><link>https://devzone.nordicsemi.com/thread/316570?ContentTypeID=1</link><pubDate>Tue, 22 Jun 2021 23:53:36 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:075e4043-5cf0-44a0-ad16-e65791048050</guid><dc:creator>Farhang</dc:creator><description>&lt;p&gt;&lt;a href="https://devzone.nordicsemi.com/members/simoniversen"&gt;Simon&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Thanks for looking into this,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;It seems like I have managed to solve the problem.. Though I am not entirely sure, so it would be really nice to get your team&amp;#39;s feedback.&lt;/p&gt;
&lt;p&gt;So it seems like since I am triggering the SAADC via PPI via a Timer at 44us, when we hit the EVT_DONE/EVT_BUF_REQ, the IRQ response is not fast enough through Zephyr,&lt;/p&gt;
&lt;p&gt;If&amp;nbsp;that is indeed the case, the next SAMPLE TASK could be triggered BEFORE the IRQ has dealt with either of the two events above, the Saadc could be in &amp;quot;end&amp;quot; mode (i.e. not Started), in which case I&amp;#39;d like to know what is the expected behavior of the saadc/ nrfx_saadc driver.&lt;/p&gt;
&lt;p&gt;If that is the case, I thought there would be 2 solutions:&lt;/p&gt;
&lt;p&gt;1- Increase the IRQ priority of the saadc IRQ and perhaps use IRQ_DIRECT_CONNECT(), I could not find enough info about this, and how to increase the IRQ priority via .dts or .overlay file. I thought I increased it by passing in a lower priority to&amp;nbsp;nrfx_saadc_init() but in Zephyr/nrfx lib this actually doesn&amp;#39;t do anything.&lt;/p&gt;
&lt;p&gt;Can you please share any info on changing IRQ priorities of peripherals via Zephyr?&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;2- This solution worked:&lt;/p&gt;
&lt;p&gt;Added another Timer (timer 2) and set it to Counter mode. Using this counter I count the number of times SAADC Sample Task has been hit via the PPI/Timer 1, then when it hits a compare value CC0 that I&amp;#39;m interested in, e.g. 1024 in this case, it stops the Timer 1 via another PPI by triggering the STOP task of timer 1. This way I ensure the sample task has been hit exactly N times not more in a timely manner, independent of the IRQ response time of zephyr. I can share this code in PM if needed.&lt;/p&gt;
&lt;p&gt;In fact I did confirm the timer 1 was hitting its CC0 too many times, I did confirm this by setting CC1 of timer 2 to 1025 just to see if it ever hits the SAMPLE task too many times, and sure it did! Then when I implemented the STOP via the additional PPI channel explained above, it never did.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Again, I&amp;#39;d really like to know what goes wrong inside the processor when we get the data misalignment (the older code I shared with you), this way I can be more confident I have actually fixed the problem!&lt;br /&gt;In our product application if data gets misaligned it is impossible to detect and product will product bad data without any signs of it... so this is a big deal!&lt;/p&gt;
&lt;p&gt;Thanks for looking into this.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NRFX SAADC in Zephyr fast and slow interleaved sampling</title><link>https://devzone.nordicsemi.com/thread/316566?ContentTypeID=1</link><pubDate>Tue, 22 Jun 2021 22:36:53 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:bb72bbe8-3426-4d29-b332-1f8304ff97bf</guid><dc:creator>Simon</dc:creator><description>&lt;p&gt;Apologies&amp;nbsp;for the late reply, a huge part of the support team are on vacation and you may experience delayed answers.&lt;/p&gt;
&lt;p&gt;I was able to reproduce your issue. By setting the differential input of the first channel to positive and vice versa with the second channel. After running it for a while I saw that the check&amp;nbsp;&lt;span&gt;&lt;code&gt;check_ch1_pos_ch2_neg()&lt;/code&gt; generated an error.&amp;nbsp;&lt;/span&gt;I&amp;#39;m not entirely sure what causing this. I&amp;#39;ll try to get a better grasp about it tomorrow, and ask some of my colleagues for possible causes.&lt;/p&gt;
&lt;p&gt;It seems like you potentially found a solution:&lt;/p&gt;
[quote user="farhangj"]I increased the IRQ priority of nrfx_saadc from 7 to 0. The problem seems to have gone away, but I&amp;#39;m doing long term testing to see if it ever happens rarely.[/quote]
&lt;p&gt;&amp;nbsp;However, I guess it would be nice to understand the root cause.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NRFX SAADC in Zephyr fast and slow interleaved sampling</title><link>https://devzone.nordicsemi.com/thread/315812?ContentTypeID=1</link><pubDate>Thu, 17 Jun 2021 09:59:57 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:70793da9-f895-4523-a398-ac26aef9ed50</guid><dc:creator>Simon</dc:creator><description>&lt;p&gt;Hello Farhang, sorry for the delay on this. I got the code from you in PM, but I forgot about it. Since this ticket is in not in my queue of cases (because&amp;nbsp;it&amp;#39;s in a waiting state, since I answered last and waited for a reply). My apologies for that. I will test your project&amp;nbsp;the next days.&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Simon&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NRFX SAADC in Zephyr fast and slow interleaved sampling</title><link>https://devzone.nordicsemi.com/thread/315197?ContentTypeID=1</link><pubDate>Mon, 14 Jun 2021 15:06:53 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:24e40806-0cce-4b7d-8f83-4b5559e35d85</guid><dc:creator>Simon</dc:creator><description>[quote user="farhangj"]I can share my code if needed in a PM.[/quote]
&lt;p&gt;Yes, this would be nice.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NRFX SAADC in Zephyr fast and slow interleaved sampling</title><link>https://devzone.nordicsemi.com/thread/315022?ContentTypeID=1</link><pubDate>Mon, 14 Jun 2021 05:21:21 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b36e9ee8-9d3a-4a67-965b-cbdfecc8e575</guid><dc:creator>Farhang</dc:creator><description>&lt;p&gt;&lt;a href="https://devzone.nordicsemi.com/members/simoniversen"&gt;Simon&lt;/a&gt; Thanks for this info.&lt;/p&gt;
&lt;p&gt;I have been facing a new challenge lately with nrfx/ncs where at high sampling rate, very randomly/rarely, the data buffer in RAM would be misaligned.&lt;/p&gt;
&lt;p&gt;e.g. if i have 2 channels configured, and doing sampling via Timer/PPI/nrfx_saadc, sometimes instead of the order of channels being, ch1, ch2, ch1, ch2 etc in &amp;quot;RESULT BUFFER&amp;quot; I get ch2,ch1, ch2, ch1.. I can tell when this happens usinga a breakpoint, because I intentionally have ch1 connected to positive potential (differential measurement, V_ch1+ &amp;gt; V_ch1- ) and ch2 is negative.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Could this be related to interrupt handling delays in zephyr?&lt;/p&gt;
&lt;p&gt;I&amp;#39;m sampling at 22KHz which is ~ 44us timer tick that send the SAMPLE TASK to saadc&amp;nbsp;(3us sampling).&lt;/p&gt;
&lt;p&gt;My guess is there is a race condition at nrfx_saadc interrupt handling around when EVT_BUF_REQ happens.&lt;/p&gt;
&lt;p&gt;e.g. If an extra timer tick happens when the new buffer is being handed over to nrfx/saadc, when the previous buffer has ENDed what is the expected behavior? This isn&amp;#39;t explained very clearly in the datasheet of nrf52840.&lt;/p&gt;
&lt;p&gt;I increased the IRQ priority of nrfx_saadc from 7 to 0. The problem seems to have gone away, but I&amp;#39;m doing long term testing to see if it ever happens rarely.&lt;/p&gt;
&lt;p&gt;another question: Do I need to use IRQ_DIRECT_CONNECT? I&amp;#39;m currently using IRQ_CONNECT. I&amp;#39;ve read that DIRECT makes the IRQ handling faster potentially.&lt;/p&gt;
&lt;p&gt;I have also disabled start_on_end int the nrfx_saadc config, so I can take control of START TASK, I stop the timer after EVT_DONE, to ensure no extra SAMPLE TASKS are triggered to saadc one it is done. Then I send the start task and wait for BUF_EVT and then the timer starts.&lt;/p&gt;
&lt;p&gt;If there are any relevant posts that you are aware of please share.&lt;/p&gt;
&lt;p&gt;I can share my code if needed in a PM.&lt;/p&gt;
&lt;p&gt;Thanks&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NRFX SAADC in Zephyr fast and slow interleaved sampling</title><link>https://devzone.nordicsemi.com/thread/314898?ContentTypeID=1</link><pubDate>Fri, 11 Jun 2021 11:53:06 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a056c616-4b37-4dcf-9c38-5657cb41da40</guid><dc:creator>Simon</dc:creator><description>[quote user=""]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.[/quote]
&lt;p&gt;It may be fine re-initializing the ADC from the interrupt since it such a small operation. However, I can&amp;#39;t say this for certain.&lt;/p&gt;
&lt;p&gt;The section&amp;nbsp;&lt;a href="https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.5.1/zephyr/reference/kernel/other/interrupts.html#offloading-isr-work"&gt;Offloading ISR work&lt;/a&gt; recommends ISRs to execute quickly, to ensure predictable system operation.&amp;nbsp;So the optimal approach would be to offload the ADC re-initialization to a Workqueue Thread, or another thread.&amp;nbsp;&lt;a href="https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.5.1/zephyr/reference/kernel/other/interrupts.html#offloading-isr-work"&gt;Offloading ISR work&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;says the following&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;em&gt;&amp;quot;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.&amp;nbsp;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.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;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 &lt;a href="https://github.com/too1/ncs-peripheral-uart-adc/blob/d575cdb9a2e0d7e5f0984a6a228bcb0d3a6f1a7c/src/main.c#L564"&gt;Torbjørn&amp;#39;s NCS ADC code snippet&lt;/a&gt;&amp;nbsp;to see how to offload work to a Work Queue.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NRFX SAADC in Zephyr fast and slow interleaved sampling</title><link>https://devzone.nordicsemi.com/thread/313747?ContentTypeID=1</link><pubDate>Fri, 04 Jun 2021 17:45:49 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c1f2daa0-1c93-435e-a143-88430fc342de</guid><dc:creator>Simon</dc:creator><description>[quote user=""]Since using advanced mode and PPI,&amp;nbsp; 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.[/quote]
&lt;p&gt;&amp;nbsp;As mentioned in&amp;nbsp;&lt;a href="https://infocenter.nordicsemi.com/index.jsp?topic=%2Fps_nrf52840%2Fkeyfeatures_html5.html&amp;amp;cp=4_0_0"&gt;nRF52840 Product Specification - SAADC - Oversampling&lt;/a&gt;, it is not possible to use more than one channel when using oversampling:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;em&gt;&amp;quot;&lt;span&gt;Note:&lt;/span&gt;&amp;nbsp;Oversampling should only be used when a single input channel is enabled, as averaging is performed over all enabled channels.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;/em&gt;One way of going about this, is to only have one channel enabled at the time, and when you&amp;#39;re done oversampling on that channel you reconfigure the SAADC to use the next channel. As Kenneth suggests in this ticket:&amp;nbsp;&lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/71704/right-way-to-oversample-burst-multiple-saadc-input-pins"&gt;https://devzone.nordicsemi.com/f/nordic-q-a/71704/right-way-to-oversample-burst-multiple-saadc-input-pins&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You could probably also disable oversampling and sample over several channels and do the averaging in software.&lt;/p&gt;
[quote user=""]&lt;p&gt;1- How do I add other channels that I don&amp;#39;t need to be sampled very fast? e.g. a few times ( &amp;lt; 20sps) per second.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;does this mean I&amp;nbsp; have to stop PPI and uninit and reinit&amp;nbsp; 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.&lt;/p&gt;[/quote]
&lt;p&gt;&amp;nbsp;&amp;quot;does this mean I have to stop PPI and unitit and reinit saadc...&amp;quot;. Yes, this would be the way to go about this, since there is no way of&amp;nbsp;&lt;span&gt;configuring separate sampling&amp;nbsp;rates for separate channels. I will get back to you next week about the specifics of the implementation.&lt;/span&gt;&lt;/p&gt;
[quote user=""]&lt;p&gt;2- Hardware question: What are the noise/performance figures for the GAIN amplifier inside the nRF52840 SAADC for different gain/attenuate settings?&amp;nbsp;&lt;br /&gt;Basically we do have an AGC amplifier circuit that feeds those high frequency channels into nRF ADC pins, therefore we&amp;#39;re curious to see what gain or attenuate setting inside SAADC results in best performance, and hence adjust our external AGC accordingly.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;[/quote]
&lt;p&gt;&amp;nbsp;I will look into this next week as well.&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Simon&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>