<?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>Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/71336/read-continuous-stream-of-data-over-spi</link><description>Hello, 
 I want to read a status register in my SPI peripheral. Once I send my read request, the peripheral will send the status byte over and over, and I want to watch for a change. When it changes, I want to terminate the SPI transfer. 
 What is the</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Fri, 20 Feb 2026 11:56:33 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/71336/read-continuous-stream-of-data-over-spi" /><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/561701?ContentTypeID=1</link><pubDate>Fri, 20 Feb 2026 11:56:33 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:fba43d34-fd27-40f4-88cc-3d191b28fb63</guid><dc:creator>Arsalan Chauhdary</dc:creator><description>&lt;p data-start="143" data-end="146"&gt;Hi,&lt;/p&gt;
&lt;p data-start="148" data-end="503"&gt;From the stack trace and behavior you&amp;rsquo;re describing, this looks like a classic race condition between two SPI transactions occurring at different interrupt contexts. Even though both are configured at priority 6, an interrupt can still preempt execution depending on timing and how the driver state flag (&lt;code data-start="453" data-end="475"&gt;transfer_in_progress&lt;/code&gt;) is being read and updated.&lt;/p&gt;
&lt;p data-start="505" data-end="842"&gt;The issue likely isn&amp;rsquo;t that &lt;code data-start="533" data-end="549"&gt;NRF_ERROR_BUSY&lt;/code&gt; isn&amp;rsquo;t implemented &amp;mdash; it&amp;rsquo;s that the second call may be entering before the first call has safely set the flag in a thread-safe manner. Since the driver isn&amp;rsquo;t fully protected against simultaneous access across contexts, this can corrupt the state machine and cause the READY event loop to stall.&lt;/p&gt;
&lt;p data-start="844" data-end="870"&gt;A safer approach would be:&lt;/p&gt;
&lt;ol data-start="872" data-end="1185"&gt;
&lt;li data-start="872" data-end="950"&gt;
&lt;p data-start="875" data-end="950"&gt;Implement an external mutex or atomic lock around &lt;code data-start="925" data-end="949"&gt;nrf_drv_spi_transfer()&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-start="951" data-end="1061"&gt;
&lt;p data-start="954" data-end="1061"&gt;Use &lt;code data-start="958" data-end="983"&gt;CRITICAL_REGION_ENTER()&lt;/code&gt; / &lt;code data-start="986" data-end="1010"&gt;CRITICAL_REGION_EXIT()&lt;/code&gt; when checking and updating your own SPI-busy flag.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-start="1062" data-end="1185"&gt;
&lt;p data-start="1065" data-end="1185"&gt;Ensure both SPI calls execute from the same execution context (either both main loop or both ISR-driven but serialized).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-start="1187" data-end="1334"&gt;Disabling RTC interrupts during active chip select is possible, but architecturally it&amp;rsquo;s cleaner to serialize access instead of masking interrupts.&lt;/p&gt;
&lt;p data-start="1336" data-end="1542"&gt;In complex embedded systems &amp;mdash; much like scalable backend systems we design at halo digital, a leading &lt;a href="https://halodigital.co/web-development/"&gt;web development company USA &lt;/a&gt;&amp;mdash; shared resources must always be guarded externally if the driver itself isn&amp;rsquo;t fully thread-safe.&lt;/p&gt;
&lt;p data-start="1544" data-end="1595"&gt;The key here is controlled access, not retry loops.&lt;/p&gt;
&lt;p data-start="1597" data-end="1636" data-is-last-node="" data-is-only-node=""&gt;Hope this helps clarify the root cause.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/295443?ContentTypeID=1</link><pubDate>Sat, 20 Feb 2021 16:55:14 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ef45498d-d3ac-4de2-9f83-734eec1562ee</guid><dc:creator>nordev</dc:creator><description>&lt;p&gt;As an update, this is clearly here for a reason, as it creates a bunch of garbage data when I remove the &amp;quot;handler&amp;quot; condition. None of my SPI transfers actually result in correct data if this condition is gone (see the commented out part), though I can&amp;#39;t figure out why.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-components-multipleuploadfilemanager/bb92634c_2D00_2bc3_2D00_46c7_2D00_8a9a_2D00_880882539052-85290-complete/pastedimage1613686974480v1.png" alt=" " /&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I was able to use the app scheduler successfully though. Thank you for your help!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/295032?ContentTypeID=1</link><pubDate>Thu, 18 Feb 2021 09:45:36 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4342922c-131f-426e-a7db-5722b418ebb4</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;Sorry, I always think in terms of non-blocking calls so I forgot again that you were using blocking. As long as you use blocking API calls that is correct, it will not be a problem. In most real products where you do not want to waste CPU time and power you will use non-blocking calls, but you are right that it should be OK to ignore this issue in your specific use case.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/295019?ContentTypeID=1</link><pubDate>Thu, 18 Feb 2021 09:14:47 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:69a50561-c614-4ee4-8718-402ab9220fde</guid><dc:creator>nordev</dc:creator><description>&lt;p&gt;Thanks so much for your help.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Just to sanity check, but I was thinking about it again, and if the transfer_in_progress flag were set properly, it seems like I wouldn&amp;#39;t actually run into the problem you describe here?&amp;nbsp;&lt;/p&gt;
[quote userid="7377" url="~/f/nordic-q-a/71336/read-continuous-stream-of-data-over-spi/294958#294958"]the main loop may start a SPI transaction and the&amp;nbsp;&lt;span&gt;transfer_in_progress&amp;nbsp;flag may be read, but before it is written to a RTC interrupt occurs.&lt;/span&gt;[/quote]
&lt;p&gt;because if the main loop starts an SPI transaction, but doesn&amp;#39;t get to setting the transfer_in_progress flag before it gets interrupted, won&amp;#39;t the interrupt return and let the main loop keep going only &lt;em&gt;after&lt;/em&gt; it is done with its SPI transfer? And if the SPI transfer that was initiated by the main loop didn&amp;#39;t even get to sending the transfer_in_progress flag, that means it hasn&amp;#39;t actually started sending anything yet, so there wouldn&amp;#39;t be two conflicting uses of the same resources? So the flow would be, main loop calls the SPI driver --&amp;gt; gets interrupted before setting flag --&amp;gt; second transfer gets started --&amp;gt; second transfer completes and returns to main loop SPI driver call --&amp;gt; first transfer starts and completes. Unless I am misunderstanding how the interrupts work, please let me know.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I was getting the issue only because the flag wasn&amp;#39;t being set, so the first SPI transfer was actually in the middle of sending data when the interrupt happened.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/294999?ContentTypeID=1</link><pubDate>Thu, 18 Feb 2021 08:23:43 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:5b44d75d-a9cf-4f83-b6d0-0d0f9ebfb8bc</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
[quote user="nordev"]&lt;strong&gt;1) I&lt;/strong&gt;&lt;strong&gt;s there any way to define some sort of generic function prototype that I can make a queue for?&amp;nbsp;&lt;/strong&gt;[/quote]
&lt;p&gt;I would suggest the &lt;a href="https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/lib_scheduler.html"&gt;app_scheduler&lt;/a&gt; here. That is designed for exactly this use case. It is essentially just a queue that you put stuff into when handling interrupts, and process in the main loop. You will queue a function pointer and a context data (so it can be anything, you decide - and as large as you want as long as you adjust the element size for it). There are no good examples in the SDK, but the usage is quite simple so you can refer to&amp;nbsp;examples\nfc\writable_ndef_msg\main.c. Essentially you first initialize the queue so that it holds the largest elements you need. Then you queue stuff using&amp;nbsp;app_sched_event_put() when handlign the interrupt, and process it in your main loop by calling&amp;nbsp;app_sched_execute().&lt;/p&gt;
[quote user="nordev"]2) Do you know a way I can do this?&amp;nbsp;[/quote]
&lt;p&gt;You can disable the interrupt any time and then re-enable it. If an interrupt is pending it will be processed. I do not know if you use the RTC driver, but if you do interrupts are enabled when you init it. You can do this directly using&amp;nbsp;NVIC_EnableIRQ(RTC1_IRQn) and&amp;nbsp;NVIC_DisableIRQ(RTC1_IRQn) - adjust if using other RTC instance.&lt;/p&gt;
&lt;p&gt;If you ask me option 1 is by far the best. That is a straightforward and sensible way of handling this and similar issues, and is how you would typically solve this in a complex application.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/294988?ContentTypeID=1</link><pubDate>Thu, 18 Feb 2021 07:58:08 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6b117e15-b7e5-423f-acd5-848aad26f85f</guid><dc:creator>nordev</dc:creator><description>&lt;p&gt;&lt;strong&gt;EDIT:&lt;/strong&gt; I realized it is rather unwieldy to add all of the things that might call SPI to the main loop, especially since there is stuff I haven&amp;#39;t implemented yet that I will have to add in the future, and maybe there will be even more beyond that. I decided that the best solution would be to add SPI callback functions to a queue that then gets processed in the main loop, if this is possible. My problem is that all my callback functions will have different parameters . &lt;strong&gt;1) I&lt;/strong&gt;&lt;strong&gt;s there any way to define some sort of generic function prototype that I can make a queue for?&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Alternatively, I discovered this note:&lt;/p&gt;
&lt;p&gt;&lt;img alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-discussions-components-files/4/pastedimage1613634754015v1.png" /&gt;&lt;/p&gt;
&lt;p&gt;which suggests that &amp;quot;interrupt pending&amp;quot; flags are set independently of interrupts being enabled or disabled. Which suggests that I can disable interrupts, then incoming interrupts will set &amp;quot;interrupt pending&amp;quot; flags but not execute, and then whatever has an interrupt pending flag will simply execute once I re-enable interrupts. This is what I was getting at here:&lt;/p&gt;
[quote userid="85290" url="~/f/nordic-q-a/71336/read-continuous-stream-of-data-over-spi/293883#293883"]what I would like is for RTC interrupts to be disabled while a transfer is in progress (i.e. while chip select is low) and re-enabled when the transfer completes (chip select goes high),&lt;strong&gt; such that any interrupt that tries to happen in the middle of a transfer instead happens immediately after the transfer completes.&lt;/strong&gt;[/quote]
&lt;p&gt;&lt;strong&gt;2) Do you know a way I can do this?&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As a final alternative.... if I remove p_cb-&amp;gt;handler and use the NRF_BUSY return code to try again if a transfer was in progress, it would be probably very rare for something to interrupt after the transfer starts but before the &amp;quot;transfer in progress&amp;quot; flag gets set, right? So I could accept this risk, and maybe would have to reboot the device once in a rare while, if it is sufficiently rare (like 1 in 100,000 attempted SPI transfers).&amp;nbsp;&lt;strong&gt;3) Or maybe do you have some suggestion for making this flag-setting atomic?&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Thank you for your help!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/294961?ContentTypeID=1</link><pubDate>Wed, 17 Feb 2021 20:50:33 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:7fbd5baa-1eb9-4a24-881f-86499e2c4906</guid><dc:creator>nordev</dc:creator><description>&lt;p&gt;Thank you.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Will you consider asking the development team to remove the p_cb-&amp;gt;handler condition from the driver in a future SDK version?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/294958?ContentTypeID=1</link><pubDate>Wed, 17 Feb 2021 19:05:23 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b18badcc-0f20-411f-8491-a9c0a35cb688</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
[quote user="nordev"]right now, the only conflicting things that might simultaneously call the SPI driver are my main loop (not interrupt based) and the RTC interrupt. Given that I don’t expect anything else to be able to interrupt my RTC interrupt, I should be safe, right?&amp;nbsp;[/quote]
&lt;p&gt;I am not sure about that. If you make calls to the driver from both your main loop and an RTC interrupt, that means you may have this problem (think of the main context as the lowest possible priority). Specifically, the main loop may start a SPI transaction and the&amp;nbsp;&lt;span&gt;transfer_in_progress&amp;nbsp;flag may be read, but before it is written to a RTC interrupt occurs. Then the a new transaction might be started from the RTC interrupt.&lt;/span&gt;&lt;/p&gt;
[quote user="nordev"]I think this interrupt comes from the softdevice, which means there’s nothing I can do about matching&amp;nbsp;interrupt priority, correct? So I have to make sure they don’t conflict in some other way.&amp;nbsp;[/quote]
&lt;p&gt;Yes, that will have SoftDevice priority. You could move execution down to the main loop for all SPI transactions, perhaps. Either using some synchronization flags or using the app_scheduler or another mechanism. That is one way to avoid having to think about this. Alternatively, you can use a mutex as mentioned before, and handle this yourself outside the driver. Which is more appropriate depends on the specific application, but both are common approaches.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/294909?ContentTypeID=1</link><pubDate>Wed, 17 Feb 2021 15:10:38 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:5ae4c5e6-b956-4823-92bd-e89f9ee0b4b7</guid><dc:creator>nordev</dc:creator><description>[quote userid="7377" url="~/f/nordic-q-a/71336/read-continuous-stream-of-data-over-spi/294826#294826"]There is nothing preventing&amp;nbsp;transfer_in_progress from being checked first, then an interrup toccuring checking it again, and then writing it. [/quote][quote userid="7377" url="~/f/nordic-q-a/71336/read-continuous-stream-of-data-over-spi/294128#294128"]then it is theoretically possible that the second call with higher priority would interrupt the first after the transfer_in_progress was read but before it is written to. And then you would have problems[/quote]
&lt;p&gt;so this could&amp;nbsp;still be a&amp;nbsp;potential problem.&lt;/p&gt;
&lt;p&gt;right now, the only conflicting things that might simultaneously call the SPI driver are my main loop (not interrupt based) and the RTC interrupt. Given that I don&amp;rsquo;t expect anything else to be able to interrupt my RTC interrupt, I should be safe, right?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;eventually though, I will add another SPI transfer&amp;nbsp;that will be triggered from&amp;nbsp;a Current Time Service interrupt. I think this interrupt comes from the softdevice, which means there&amp;rsquo;s nothing I can do about matching&amp;nbsp;interrupt priority, correct? So I have to make sure they don&amp;rsquo;t conflict in some other way.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/294826?ContentTypeID=1</link><pubDate>Wed, 17 Feb 2021 11:58:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a3d760b4-d9d7-41d0-803c-768917e24feb</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;That is good spotted&lt;/p&gt;
[quote user="nordev"]1) Did nordic intend this behavior? (basically, did I do something wrong, or is this a bug?)[/quote]
&lt;p&gt;I am not sure if this is intended or not. You could argue that when using blocking mode it is easy for you to ensure that there is no conflict. And you would only be able to get a problem here if calls are made from different interrupt priorities. If that happens and they can overlap in time, then this will not be enough. On the other hand, there is no atomic operations or critical sections for updating the&amp;nbsp;transfer_in_progress flag in any case, so you would still risk issues if calling from different interrupt priorities and not ensuring that one transaction finish before you initiate the next.&lt;/p&gt;
[quote user="nordev"]2) Do you see any issue with me removing &lt;em&gt;&lt;strong&gt;p_cb-&amp;gt;handler&lt;/strong&gt;&lt;/em&gt; from the conditional above in (2.)?&amp;nbsp;[/quote]
&lt;p&gt;No, I do not immediately see any issues. But note my point above. There is nothing preventing&amp;nbsp;transfer_in_progress from being checked first, then an interrup toccuring checking it again, and then writing it. So the driver is&amp;nbsp;not thread safe and if you call the API from different interrupt priorities you &lt;em&gt;must&lt;/em&gt; ensure that there are no collisions outside of the driver. Alternatively, ensure that you always call the driver API from the same interrupt priority, then this is no issue.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/294730?ContentTypeID=1</link><pubDate>Tue, 16 Feb 2021 23:23:48 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:0a24324e-625c-43e6-ab18-b494b4f6cf45</guid><dc:creator>nordev</dc:creator><description>&lt;p&gt;Hi Einar,&lt;/p&gt;
&lt;p&gt;As an update, I found out what the issue is:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-discussions-components-files/4/pastedimage1613516954964v1.png" alt=" " /&gt;&lt;/p&gt;
&lt;p&gt;I hope this image is big enough for you to see, but basically:&lt;/p&gt;
&lt;p&gt;1. there is only one place in the driver where transfer_in_progress() is ever set to true&lt;/p&gt;
&lt;p&gt;2. it is guarded by&amp;nbsp;the following conditional:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;if (p_cb-&amp;gt;handler &amp;amp;&amp;amp; !(flags &amp;amp; (NRF_DRV_SPI_FLAG_REPEATED_XFER |
                                        NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER)))
        {
			p_cb-&amp;gt;transfer_in_progress = true;
        }&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;3. flags are 0, which is not a problem, but handler is ALSO 0, which is a problem. So the condition is never satisfied, and even though there is a transfer in progress, the transfer_in_progress boolean is always false.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Handler = 0 because I&amp;nbsp;initialize the SPI driver with:&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;err_code = nrf_drv_spi_init(&amp;amp;m_spi_at, &amp;amp;config, NULL, NULL);&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Because I thought I don&amp;#39;t need a handler if I am not using interrupts, since I am in blocking mode.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;My questions:&amp;nbsp;&lt;/p&gt;
&lt;p&gt;1) Did nordic intend this behavior? (basically, did I do something wrong, or is this a bug?)&lt;/p&gt;
&lt;p&gt;2) Do you see any issue with me removing &lt;em&gt;&lt;strong&gt;p_cb-&amp;gt;handler&lt;/strong&gt;&lt;/em&gt; from the conditional above in (2.)?&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/294727?ContentTypeID=1</link><pubDate>Tue, 16 Feb 2021 22:35:39 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:825aac99-55ab-4fd1-b380-82f1a43c1df2</guid><dc:creator>nordev</dc:creator><description>[quote userid="7377" url="~/f/nordic-q-a/71336/read-continuous-stream-of-data-over-spi/294128#294128"]So a new transaction would not be able to cause problems for an old, but should just result in the second call failing with&amp;nbsp;NRF_ERROR_BUSY.[/quote]
&lt;p&gt;I don&amp;#39;t know if this is actually the case, and I think the following concern still stands:&lt;/p&gt;
[quote userid="7377" url="~/f/nordic-q-a/71336/read-continuous-stream-of-data-over-spi/294128#294128"]So sure I might get an error code, but the damage will already have been done: the second transfer will have already disrupted the first transfer, which is what gets me stuck in the infinite while loop.&amp;nbsp;[/quote]
&lt;p&gt;Because I changed my code in this function (code in a previous response):&lt;/p&gt;
[quote userid="85290" url="~/f/nordic-q-a/71336/read-continuous-stream-of-data-over-spi/293630#293630"]at_read_status_once()[/quote]
&lt;p&gt;to do this:&amp;nbsp;&lt;/p&gt;
&lt;pre&gt;while(nrf_drv_spi_transfer(&amp;amp;m_spi_at, spi_tx_cmd, sizeof(spi_tx_cmd), spi_rx_buf, sizeof(spi_rx_buf)) == NRF_ERROR_BUSY);&lt;/pre&gt;
&lt;p&gt;so that if I got a NRF_ERROR_BUSY event it would just try again until it isn&amp;#39;t busy. But I still get stuck in this while loop forever inside&amp;nbsp;spi_xfer():&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-discussions-components-files/4/pastedimage1613514311470v2.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Here is the full stack. I have highlighted the two calls to nrf_drv_spi_transfer().&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-discussions-components-files/4/pastedimage1613514857990v3.png" /&gt;&lt;/p&gt;
&lt;p&gt;The first one is called from my main loop, and the second one is called from an RTC interrupt. My RTC is also a low interrupt priority, 6.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Note that NRF_ERROR_BUSY should be returned from nrf_drv_spi_xfer (second in the call stack above). But this does not happen -- &amp;quot;p_cb-&amp;gt;transfer_in_progress&amp;quot; seems to be false, even though there IS a transfer in progress (first highlight on above stack):&lt;/p&gt;
&lt;p&gt;&lt;img alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-discussions-components-files/4/pastedimage1613515122009v1.png" /&gt;&lt;/p&gt;
&lt;p&gt;What do you think is happening? Is this a bug with SDK 14.2? Is it fixed in later versions?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;-----&lt;/p&gt;
&lt;p&gt;As a separate matter, I had to refresh this webpage 5 times to get the &amp;quot;reply&amp;quot; button to show up at the bottom of your latest message (it showed up at the top underneath my original message but not elsewhere).&amp;nbsp;Generally, every time I use the forum, I have to refresh multiple times in order for the reply button to show up.&amp;nbsp;&lt;span&gt;Perhaps you can relay this to your web development team.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/294128?ContentTypeID=1</link><pubDate>Fri, 12 Feb 2021 10:52:45 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:84f7e647-c119-46a5-b3c4-3e52c8a64778</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
[quote user="nordev"]is the right way to do this APP_ERROR_CHECK()?[/quote]
&lt;p&gt;No. APP_ERROR_CHECK() is used to catch unexpected errors. The default error handler in the SDK will log and break if an error is detected with this and in debug mode. If in release mode it will perform a soft reset - in order to recover from an unexpected and unhandled error. The correct is to handle any expected errors specifically, and then call&amp;nbsp;APP_ERROR_CHECK() if the return value was not an expected/handled error, like you suggest with &amp;quot;if(nrf_drv_spi_transfer() != NRF_ERROR_BUSY)&amp;quot;.&lt;/p&gt;
[quote user="nordev"]So sure I might get an error code, but the damage will already have been done: the second transfer will have already disrupted the first transfer, which is what gets me stuck in the infinite while loop.&amp;nbsp;[/quote]
&lt;p&gt;This stems from my incorrect previous answer, I guess. The driver checks if a transaction is ongoing before doing any changes. So a new transaction would not be able to cause problems for an old, but should just result in the second call failing with&amp;nbsp;NRF_ERROR_BUSY. There is a slight possibility for an issue here though, as this is not implemented in thread safe way. So if the two calls are made at the same time with different priorities then it is theoretically possible that the second call with higher priority would interrupt the first after the transfer_in_progress was read but before it is written to. And then you would have problems. This would be solved by always calling from the same priority, or by using a proper check externally (using a mutex of similar).&lt;/p&gt;
[quote user="nordev"]is there some way to check without actually calling the SPI transfer function to see if it generates an error?[/quote]
&lt;p&gt;There is no API for that in the driver.&lt;/p&gt;
&lt;p&gt;To sum up, if you call from the same priority, you can just rely on handling the&amp;nbsp;NRF_ERROR_BUSY. If not, you should implement your one mutex on the outside. So that one &amp;quot;user&amp;quot; will lock the driver before starting and operation and unlock it when finished. And the same with the second. You could use&amp;nbsp;nrf_atomic_u32_t for that, or just a volatile variable that you read and update in a critical region (CRITICAL_REGION_ENTER() / CRITICAL_REGION_EXIT()).&lt;/p&gt;
[quote user="nordev"]are there other benefits of bundling the BLE event handling like this besides being able to queue interrupts &amp;amp; not lose them?[/quote]
&lt;p&gt;There are no extraordinary benefits in the context of BLE events or even nRF5 SDK specifically. It boils down to general concepts of handling interrupts / priorities. If you have a need to move processing of events/interrupts (BLE or other) down from interrupt context to main context, then using the scheduler makes sense. If not, then there is no need. Typically the more complex an application is and the more different interrupts etc or the longer the interrupt routines, the more important it becomes to move priorities down. That way stuff that can wait may wait, and there is time to process other interrupts in in a timely manner. But there is no right or wrong way here, it is application dependent. This is related to the general importance of keeping ISRs short. If you want to do a lot of work because of an interrupt, but only a small portion of it is time critical you can do the small portion in the ISR, and then queue the rest in the scheduler to be processed in the main context.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/294083?ContentTypeID=1</link><pubDate>Fri, 12 Feb 2021 05:01:18 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:19abe368-f63b-47b5-9325-ee385193454a</guid><dc:creator>nordev</dc:creator><description>&lt;p&gt;Thank you Einar.&amp;nbsp;&lt;/p&gt;
[quote userid="7377" url="~/f/nordic-q-a/71336/read-continuous-stream-of-data-over-spi/293904#293904"]You should get NRF_ERROR_BUSY if attempting to start a second transaction before the first has finished.[/quote]
&lt;p&gt;is the right way to do this APP_ERROR_CHECK()?&lt;/p&gt;
&lt;p&gt;The strange thing about checking this way, however, is that I have to actually call nrf_drv_spi_transfer() in order to get the error code. Either with APP_ERROR_CHECK() or something like &amp;ldquo;if(&lt;span&gt;nrf_drv_spi_transfer() != NRF_ERROR_BUSY)&amp;rdquo;.&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;So sure I might get an error code, but the damage will already have been done: the second transfer will have already disrupted the first transfer, which is what gets me stuck in the infinite while loop.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;is there some way to check without actually calling the SPI transfer function to see if it generates an error?&lt;/p&gt;
[quote userid="7377" url="~/f/nordic-q-a/71336/read-continuous-stream-of-data-over-spi/293904#293904"]Do you call&amp;nbsp;app_sched_execute() from your code? [/quote]
&lt;p&gt;no, I do not. are there other benefits of bundling the BLE event handling like this besides being able to queue interrupts &amp;amp; not lose them?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/293904?ContentTypeID=1</link><pubDate>Thu, 11 Feb 2021 08:36:34 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:2d542880-803c-47e2-82c8-8faafba953c0</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;First of all, I was a bit surprised when I checked the driver implementation yesterday and did not find a check for not starting a second transaction before the first finished. I turns out I glanced over it too quickly, though. You should get NRF_ERROR_BUSY if attempting to start a second transaction before the first has finished. So that means you can use this. Sorry for the confusion.&lt;/p&gt;
&lt;p&gt;Regarding chip select / slave select it is correct that the SPI peripheral does not handle that. However, the driver implements support for chip select by controlling a GPIO. So when you use the driver you get it handled for you.&lt;/p&gt;
[quote user="nordev"]How do I know if I am using the scheduler?[/quote]
&lt;p&gt;Do you call&amp;nbsp;app_sched_execute() from your code? If yes, you are using the scheduler, if not you are not using it. If you also set&amp;nbsp;NRF_SDH_DISPATCH_MODEL to 1 in your sdk_config.h BLE events are using the scheduler (meaning put in the queue and processed when you call&amp;nbsp;app_sched_execute()). As you are not aware of it I suspect you are not using it.&lt;/p&gt;
&lt;p&gt;Regarding the rest of the section about interrupts it is actually quite simple. To be specific:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Any interrupt will be processed immediately as long as it is enabled and no same or higher priority interrupt is currently being serviced.
&lt;ul&gt;
&lt;li&gt;If an interrupt of same or higher priority is being services, the new interrupt will be serviced immediately after the previous is finished (assuming no other higher priority interrupt occurs in the meantime).&lt;/li&gt;
&lt;li&gt;A interrupt routine that is interrupted by a higher priority interrupt will continue once the higher priority interrupt routine has finished.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, there are SW concepts that can be used to make some things easier. The app_scheduler&amp;nbsp;can be used to queue events from any interrupt priority. Then you process the queue in your main loop, so it is&amp;nbsp;not in an interrupt (so basically lowest possible priority). That is useful sometimes, particularly in more complex applications.&lt;/p&gt;
&lt;p&gt;Regarding SoftDevice that uses some peripherals that generate interrupts, but you will from the application only see SoftDevice interrupts that you are supposed to handle (in form of SoftDevice events). Interrupts from other peripherals (like for UART and RTC instances you are using) are forwarded to the application directly (it is actually done by the SoftDevice with slightly increases the interrupt latency, but other then that you can think of it as if the SoftDevice plays no role in it).&lt;/p&gt;
[quote user="nordev"]And interrupting another interrupt is ok, so long as the second interrupt is from a different source?[/quote]
&lt;p&gt;If you get a lot of the same interrupts before you can process them with the same IRQ number (same source), that will cause you to lose interrupts. This is one of the reasons you&amp;nbsp;should keep interrupts routines short. Other then that, interrupt from the same source cannot preempt another from the same source, as they will always have the same priority.&amp;nbsp;But an interrupt with higher priority then one currently being serviced will interrupt that one.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/293883?ContentTypeID=1</link><pubDate>Thu, 11 Feb 2021 05:49:59 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:5fe89e60-330c-4ddf-b30a-51cfbffc83bd</guid><dc:creator>nordev</dc:creator><description>[quote userid="7377" url="~/f/nordic-q-a/71336/read-continuous-stream-of-data-over-spi/293744#293744"] it is your responsibility to wait for the first transaction to finish before starting the next[/quote]
&lt;p&gt;Option 1:The RTC interrupt ultimately triggers the second transfer. &lt;strong&gt;Is there a way to temporarily disable the RTC interrupt&lt;/strong&gt;, such that the event that &lt;em&gt;should&lt;/em&gt; trigger the interrupt is &lt;em&gt;registered&lt;/em&gt; (an interrupt flag is set, perhaps), but &lt;em&gt;doesn&amp;#39;t&lt;/em&gt; actually trigger the interrupt until after interrupts are enabled again? In case a RTC interrupt should happen in the middle of an existing SPI transfer, what I would like is for RTC interrupts to be disabled while a transfer is in progress (i.e. while chip select is low) and re-enabled when the transfer completes (chip select goes high),&lt;strong&gt; such that any interrupt that tries to happen in the middle of a transfer instead happens immediately after the transfer completes.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Option 2: &lt;strong&gt;Is there a way to check if the SPI resource in question is in use?&lt;/strong&gt; I could place a condition on the SPI transfer called by the RTC interrupt callback so that it only executes if the SPI resource is free and waits otherwise. This would have the same effect as #1 and probably be more elegant.&lt;/p&gt;
&lt;p&gt;Also, just to clarify,&lt;strong&gt; is this sentence from your link from an outdated specification?&lt;/strong&gt; &amp;quot;The SPI master does not implement support for chip select directly.&amp;quot; I ask because I see that spi_config() includes a way to designate the chip select pin, and the spi driver itself seems to perform operations with this designated pin -- in fact, I rely on the drivers and don&amp;#39;t set/clear chip select directly. I am using SDK 14.2.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
[quote userid="7377" url="~/f/nordic-q-a/71336/read-continuous-stream-of-data-over-spi/293744#293744"]If you use the app scheduler and schedule SoftDevice events, then those would be processed in the main loop, so any code executing in an interrupt would block it[/quote]
&lt;p&gt;How do I know if I am using the scheduler? Above I mention two SPI transfers, one initiated by the RTC (&amp;quot;type 1&amp;quot;), and the other initiated by a request by the central to a BLE characteristic (&amp;quot;type 2&amp;quot;). Are you saying that the disconnection event doesn&amp;#39;t get processed when it occurs in the middle of the type 2 SPI transfer because BLE disconnect constitutes a SoftDevice interrupt, and the type 2 SPI transfer is already operating in a SoftDevice interrupt? So it seems that you can&amp;#39;t interrupt an interrupt with another interrupt of the same kind. But other events, like UART interrupts and the aforementioned RTC interrupt (even though it has a low interrupt priority of 6) are able to execute simply because they are NOT operating in a SoftDevice interrupt? So the SoftDevice doesn&amp;#39;t handle things like UART or RTC? And interrupting another interrupt is ok, so long as the second interrupt is from a different source?&lt;/p&gt;
&lt;p&gt;Thank you&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/293744?ContentTypeID=1</link><pubDate>Wed, 10 Feb 2021 11:53:29 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:875b731c-7207-44df-b8af-cac029ce9b78</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
[quote user="nordev"]&lt;strong&gt;1) &lt;/strong&gt;&lt;strong&gt;Do you have suggestions for how to mitigate this problem?&lt;/strong&gt;[/quote]
&lt;p&gt;SPI is &lt;em&gt;always&lt;/em&gt; full duplex. So whenever you transmit &lt;em&gt;x&lt;/em&gt; bytes, you also receive &lt;em&gt;x&lt;/em&gt; bytes. This is why you always need to provide both an Rx and Tx data buffer in the driver. But you cannot start two transfers at the same time, that will cause problems. Unfortunately the driver does not have a sanity check for this, so it is your responsibility to wait for the first transaction to finish before starting the next. Failing to do so will lead to problems so this should be fixed before anything else.&lt;/p&gt;
[quote user="nordev"] &lt;strong&gt;2) W&lt;/strong&gt;&lt;strong&gt;hy do you think some interrupts&amp;nbsp; are being generated, but others not?&lt;/strong&gt;[/quote]
&lt;p&gt;The typical reason for not getting some events is if the CPU is doing some work in the same or higher interrupt priority. I assume that is the case here? Regarding BLE the SoftDevice use two interrupt priorities (0 for mostly for internal usage and 4 for events to the application etc.) If you use the app scheduler and schedule SoftDevice events, then those would be processed in the main loop, so any code executing in an interrupt would block it (that is the case if using scheduler and having configured&amp;nbsp;NRF_SDH_DISPATCH_MODEL to 1 in sdk_config.h).&lt;/p&gt;
[quote user="nordev"]3) Can you tell me the chain of events that causes the &amp;quot;READY&amp;quot; event to get generated?[/quote]
&lt;p&gt;The short description is that the READY event every time a new byte is moved to the RXD register. For more details I suggest you refer to the&amp;nbsp;&lt;em&gt;SPI master transaction sequence&lt;/em&gt; section in the &lt;a href="https://infocenter.nordicsemi.com/topic/ps_nrf52840/spi.html?cp=4_0_0_5_23"&gt;SPI chapter in the product specification&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/293644?ContentTypeID=1</link><pubDate>Tue, 09 Feb 2021 21:45:27 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8afba341-214a-40f1-8b03-dd6a7bfa62c3</guid><dc:creator>nordev</dc:creator><description>&lt;p&gt;As an update, I found out when specifically this &amp;quot;stuck in loop&amp;quot; problem seems to occur:&lt;/p&gt;
&lt;p&gt;I have an RTC that generates a COMPARE event every X seconds, upon which it calls my at_read_status_once() fn from above, which TX data to the peripheral. The &amp;quot;stuck in loop&amp;quot; problem happens if the SPI TX command happens while SPI RX is in progress from the same peripheral. The SPI TX and SPI RX were initiated with two separate nrf_drv_spi_transfer(). In theory, SPI is supposed to allow duplex communication, so the simultaneous RX and TX should not be a problem; the issue is probably that at_read_status_once() expects a RX response, but there is already a separate RX in progress. &lt;strong&gt;1) &lt;/strong&gt;&lt;strong&gt;Do you have suggestions for how to mitigate this problem?&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Somehow, UART interrupts are able to get through, as you can see from the screenshot above, but other interrupts don&amp;#39;t. For example, because the bluetooth device is caught in this while loop, it isn&amp;#39;t sending connection packets to the central, and the connection fails -- but no interrupt is generated to process the tasks inside ble_event_handler() case BLE_GAP_EVT_DISCONNECTED. &lt;strong&gt;2) W&lt;/strong&gt;&lt;strong&gt;hy do you think some interrupts&amp;nbsp; are being generated, but others not?&lt;/strong&gt; &lt;strong&gt;&lt;/strong&gt;(note, RTC interrupt priority = 6. connection related events come from the softdevice, which i thought has the highest interrupt priority)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3) Can you tell me the chain of events that causes the &amp;quot;READY&amp;quot; event to get generated?&lt;/strong&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/293630?ContentTypeID=1</link><pubDate>Tue, 09 Feb 2021 18:48:10 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d9cc270f-d919-4458-b502-7515e2688045</guid><dc:creator>nordev</dc:creator><description>[quote userid="7377" url="~/f/nordic-q-a/71336/read-continuous-stream-of-data-over-spi/293374#293374"]Where&amp;nbsp;transfer_byte() is called from depends on if using the driver in blocking mode or interrupt driven. If blocking, it is called from&amp;nbsp;spi_xfer()[/quote]
&lt;p&gt;I am using blocking mode, and my call stack does include spi_xfer()&lt;/p&gt;
&lt;p&gt;I decided to handle this by just polling for the status byte over and over and receiving 1B back each time, instead of modifying the SDK to read a continuous stream.&lt;/p&gt;
&lt;p&gt;But I seem to be hitting an infinite loop because this READY event you mention doesn&amp;#39;t get generated sometimes:&lt;/p&gt;
[quote userid="7377" url="~/f/nordic-q-a/71336/read-continuous-stream-of-data-over-spi/293374#293374"] In either case it is called when a READY event has occurred, which according to the product specification happens in this situation: &amp;quot;The SPI master will generate a READY event every time a new byte is moved to the RXD register.&amp;quot;.[/quote]
&lt;p&gt;Here is my call stack. The highlighted line is where it is stuck. It just so happens here that a separate interrupt happened, so other code executed for a moment. &lt;/p&gt;
&lt;p&gt;&lt;img src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-discussions-components-files/4/pastedimage1612894826594v1.png" alt=" " /&gt;&lt;/p&gt;
&lt;p&gt;My code is like this:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;uint8_t at_read_status_once(void)
{
    uint8_t spi_tx_cmd[1] = {CMD_READ_STATUS_1};
    uint8_t spi_rx_buf[2];	// 1 B tx, 1 B rx

    nrf_drv_spi_transfer(&amp;amp;m_spi_at, spi_tx_cmd, sizeof(spi_tx_cmd), spi_rx_buf, sizeof(spi_rx_buf));
    return spi_rx_buf[1];	// 2nd byte is the rx response
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;And I call it like this: &lt;/p&gt;
&lt;p&gt;while(at_read_status_once() != 0x0);&lt;/p&gt;
&lt;p&gt;My purpose is to stay in the while loop and not move onto the next instruction until the status byte turns to 0x0. This works sometimes, but sometimes, this gets stuck in the while loop in the SDK here:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-discussions-components-files/4/pastedimage1612896414823v2.png" alt=" " /&gt;&lt;/p&gt;
&lt;p&gt;Why is the READY event never getting generated?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/293374?ContentTypeID=1</link><pubDate>Mon, 08 Feb 2021 14:53:07 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:83f3ad78-1d26-42a0-b12e-c5c97365426f</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
[quote user="nordev"]1. this still requires me to specify an RX buffer length, which I don&amp;#39;t necessarily know in advance.[/quote]
&lt;p&gt;Yes, that is the case. For the SPI peripheral that is not enforced by the HW (which just has double buffered Rx and Tx buffers), so you could write your own driver or modify the driver if that is a problem. Or&amp;nbsp;perhaps simpler, just call&amp;nbsp;nrfx_spi_abort() in the middle of a transfer if you find that you do not need to continue.&lt;/p&gt;
[quote user="nordev"]2. the below function also is dependent on transfer_byte(), but I am not really sure under what circumstances it is called.[/quote]
&lt;p&gt;Where&amp;nbsp;transfer_byte() is called from depends on if using the driver in blocking mode or interrupt driven. If blocking, it is called from&amp;nbsp;spi_xfer(). If non-blocking (which is probably what you will use in most cases), it is called from&amp;nbsp;irq_handler(). In either case it is called when a READY event has occurred, which according to the product specification happens in this situation: &amp;quot;The SPI master will generate a READY event every time a new byte is moved to the RXD register.&amp;quot;.&lt;/p&gt;
[quote user="nordev"]Why does the end of spi_xfer() only set the chip select back high and not do the rest of the things in finish_transfer()?[/quote]
&lt;p&gt;That is because it is a blocking function. So there is no callbck function to call etc.&lt;/p&gt;
[quote user="nordev"] If I choose to modify the functions, is there any downside to calling finish_transfer() after&amp;nbsp;&lt;strong&gt;while (transfer_byte(p_spi, p_cb));&lt;/strong&gt;&amp;nbsp;inside spi_xfer()?&amp;nbsp;[/quote]
&lt;p&gt;I am not sure why you want to do that? I think you first need to decide to use blocking or non blocking and also understand the driver if you want to make changes to it (other than hooking into&amp;nbsp;transfer_byte() just to read as I suggested, as that does not change the driver behaviour in any way).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/293179?ContentTypeID=1</link><pubDate>Fri, 05 Feb 2021 18:32:52 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d7a529e2-a00c-4943-aeb6-8e53a7753c0b</guid><dc:creator>nordev</dc:creator><description>&lt;p&gt;Thank you Einar. One complication with using this method is that most of the time, I want to read a SPI buffer of known length, and only sometimes, I want to process each byte as it comes in in the manner described above.&lt;/p&gt;
&lt;p&gt;I suppose I could create a duplicate transfer_byte() function, as well as a duplicate of all the functions that depend on transfer_byte(), such as spi_xfer(), nrf_drv_spi_xfer(), and nrf_drv_spi_transfer(), and simply call the modified functions (e.g., &amp;quot;my_nrf_drv_spi_transfer&amp;quot;) when I need to. But two issues:&lt;/p&gt;
&lt;p&gt;1. this still requires me to specify an RX buffer length, which I don&amp;#39;t necessarily know in advance.&lt;/p&gt;
&lt;p&gt;2. the below function also is dependent on transfer_byte(), but I am not really sure under what circumstances it is called. It seems somewhat redundant with the end of spi_xfer(), except that finish_transfer() is more thorough. Why does the end of spi_xfer() only set the chip select back high and not do the rest of the things in finish_transfer()? If I choose to modify the functions, is there any downside to calling finish_transfer() after&amp;nbsp;&lt;strong&gt;while (transfer_byte(p_spi, p_cb));&lt;/strong&gt;&amp;nbsp;inside spi_xfer()?&amp;nbsp;&lt;pre class="ui-code" data-mode="text"&gt;static void irq_handler_spi(NRF_SPI_Type * p_spi, spi_control_block_t * p_cb)
{
    ASSERT(p_cb-&amp;gt;handler);

    nrf_spi_event_clear(p_spi, NRF_SPI_EVENT_READY);
    NRF_LOG_DEBUG(&amp;quot;SPI: Event: NRF_SPI_EVENT_READY.&amp;quot;);

    if (!transfer_byte(p_spi, p_cb))
    {
        finish_transfer(p_cb);
    }
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Do you have recommendations for a way to approach the continuous stream read that do not encounter the issues above? Thank you!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Read continuous stream of data over SPI</title><link>https://devzone.nordicsemi.com/thread/293110?ContentTypeID=1</link><pubDate>Fri, 05 Feb 2021 13:42:11 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a392883f-f598-4d5d-888e-a290b7285e33</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;There are several ways to do this and I am not sure which is better. Using the SPI (and not SPIM) peripheral you will use the CPU for every byte, and you can inspect it. The driver is designed to handle this for you though, but you could for instance do a small hack and add your own callback function that is called from within the&amp;nbsp;transfer_byte() function in nrfx_spi.c so that you can process each byte as it comes in, but still let the driver do it&amp;#39;s work as normal.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>