<?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>UARTE internals (bare metal programming): Continuous reception, BREAK condition detection and how to use UARTE like a FIFO</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/97171/uarte-internals-bare-metal-programming-continuous-reception-break-condition-detection-and-how-to-use-uarte-like-a-fifo</link><description>Hi, 
 I&amp;#39;m making progress with using the UARTE in bare metal programming. My goal is to have maximum control over my system and provide a reliably and robust realtime implementation. So this time, I have some more sophisticated questions that are not</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Thu, 02 Mar 2023 11:42:24 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/97171/uarte-internals-bare-metal-programming-continuous-reception-break-condition-detection-and-how-to-use-uarte-like-a-fifo" /><item><title>RE: UARTE internals (bare metal programming): Continuous reception, BREAK condition detection and how to use UARTE like a FIFO</title><link>https://devzone.nordicsemi.com/thread/412987?ContentTypeID=1</link><pubDate>Thu, 02 Mar 2023 11:42:24 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:5496eadb-1f19-40a0-8d4c-08fa08afa640</guid><dc:creator>ovrebekk</dc:creator><description>&lt;p&gt;Hi Michael&lt;/p&gt;
&lt;p&gt;In general I would not recommend implementing low level peripheral drivers from scratch, unless you have very specific and challenging requirements. Our low level team have intimate knowledge of the Nordic hardware, and have developed the nrfx drivers over several years based on internal and external input. Even more importantly, these drivers are implicitly tested by thousands of customers (and our own internal tests), meaning any issues in the driver will be reported and fixed much quicker. Even if you are a better developer the most likely outcome is that you will spend a lot of time developing a similar driver that might&amp;nbsp;be better designed but that will have gone through significantly less testing.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;With that out of the way, I will try to respond to your specific questions below:&lt;/p&gt;
[quote user=""]&lt;strong&gt;Question 0:&lt;/strong&gt; How big is the internal FIFO of the UARTE modules?[/quote]
&lt;p&gt;The RX FIFO is 4 bytes in size.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;For TX there is no FIFO.&amp;nbsp;&lt;/p&gt;
[quote user=""]&lt;strong&gt;Question 1&lt;/strong&gt;: What happens to the remaining bytes in the internal FIFO when a new STARTRX task is triggered? Will the FIFO content be written to the EasyDMA buffer without date being lost? Or will the bytes in the internal FIFO be discarded when a STARTRX task is triggered? For reliable data reception (that does not miss any bytes on the UART while the receive buffer is switched), it would only make sense to continue writing the internal FIFO content when STARTRX is triggered, especially in combination with the ENDRX-STARTRX short which immediately restarts reception if the buffer is full.[/quote]
&lt;p&gt;Yes, if there are any remaining bytes in the FIFO when you issue STARTRX these will be written first, before any new incoming data.&amp;nbsp;&lt;/p&gt;
[quote user=""]&lt;strong&gt;Question 1a:&lt;/strong&gt; When using the ENDRX-STARTRX short, will there no data be lost if the old EasyDMA buffer is full, and the STARTRX task continues reception into the next buffer?[/quote]
&lt;p&gt;That is correct. The double buffer mechanism of the EasyDMA PTR register ensures that handover between the buffers happens immediately, and as&amp;nbsp;long as you ensure to always provide the next buffer before the current buffer is filled up there is no risk of data loss.&amp;nbsp;&lt;/p&gt;
[quote user=""]&lt;strong&gt;Question 1b:&lt;/strong&gt; When using the ENDRX-STARTRX short, if STOPRX is triggered before the current buffer is full, because of the short, reception should automatically be continued into the next buffer, just like question 1a mentioned. Will there also be no data loss in this case? Is this the way to manually trigger a safe/robust buffer switch and handle available data?[/quote]
&lt;p&gt;Yes. This is&amp;nbsp;the safe way to be able to read out RX data before the buffers fill up, in case you want a timeout type behavior on the RX side where you can process data after a period of inactivity (our higher level drivers in the SDK provides a similar functionality).&amp;nbsp;&lt;/p&gt;
[quote user=""]&lt;strong&gt;Question 2:&lt;/strong&gt; I documented my approach in the following flow chart. Will this work without data loss? My goal is to take advantage of the UARTE capabilities and use large buffers that allow for using low priority UARTE interrupts that do not interfere with other time critical code in the system.[/quote]
&lt;p&gt;Yes, this should work fine.&amp;nbsp;The way we handle timeout in our drivers is that&amp;nbsp;the timeout gets reset every time a new byte is received over the UART, meaning you will get an interrupt if there is no activity on RX for a predetermined amount of time, set by the timeout value.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This means that if you are receiving asynchronous messages of unknown length any new message will be processed after a delay set by the timeout period.&amp;nbsp;&lt;/p&gt;
[quote user=""]I consider using a BREAK condition for synchronizing communication shortly before the &lt;span style="text-decoration:underline;"&gt;beginning&lt;/span&gt; of a data packet. Unfortinately, there is very little information available about the BREAK bit in the ERRORSRC status word.[/quote]
&lt;p&gt;My recommendation would be to&amp;nbsp;add some packetization protocol to the data instead, rather than use breaks intentionally. I haven&amp;#39;t heard about anyone doing that with our UARTE peripheral, and I am not sure how well it would work in practice.&amp;nbsp;&lt;/p&gt;
[quote user=""]&lt;strong&gt;Question 3:&lt;/strong&gt; Is the BREAK bit just set by the SoC (when RxD stays low for too long) and must be reset by software? Or is it automatically reset of a rising edge is detected on the RxD line, so that it does automatically reflect the current RxD state?[/quote]
&lt;p&gt;The ERRORSRC register is set by HW and must be cleared by SW, more info &lt;a href="https://infocenter.nordicsemi.com/topic/ps_nrf5340/uarte.html?cp=4_0_0_6_37_8_36#register.ERRORSRC"&gt;here&lt;/a&gt;.&lt;/p&gt;
[quote user=""]&lt;strong&gt;estion 4:&lt;/strong&gt; Is the BREAK bit only set while reception is active (STARTRX triggered, ENDRX not triggered yet)? Or can I completely stop reception, wait for the BREAK bit to become active (e.g. by polling the bit), and then manually start reception?[/quote]
&lt;p&gt;You will not get framing or break errors if you haven&amp;#39;t started RX, no. RX has to be running for these errors to occur.&amp;nbsp;&lt;/p&gt;
[quote user=""]&lt;strong&gt;Question 5:&lt;/strong&gt; If I detect a BREAK condition and trigger STARTRX while RxD is still low. Will I get an error event (interrupt) again? Or will the UARTE module just wait for the next falling edge on RxD (which is the trigger for the Start bit of a transmission) and start receiving?[/quote]
&lt;p&gt;You won&amp;#39;t get a BREAK condition in this case as explained in 4, but if you start RX while RXD is low you will get a framing and break error shortly after RX is started.&amp;nbsp;&lt;/p&gt;
[quote user=""]By the way, it would be nice to have a BREAK event in a future version of the UARTE device for such purposes (and to prevent double events because of the frame error). Just a little suggestion for the engineers ;)[/quote]
&lt;p&gt;This you would have to discuss with one of our sales directors, they are the channels for suggesting new software or hardware features. I can tell you that the hardware guys, like many engineers, are risk averse and won&amp;#39;t make changes lightly ;)&lt;/p&gt;
[quote user=""]&lt;strong&gt;Question 7:&lt;/strong&gt; What happens if the STARTRX task is triggered while reception is already active? (Will reception be restarted at the next RXD.BUFFER? Will ENDRX be triggered? Or will nothing happen at all?)[/quote]
&lt;p&gt;I am 90% sure it will just be ignored if you trigger STARTRX while you are already in RX, but I will have to get this confirmed with the designers.&amp;nbsp;&lt;/p&gt;
[quote user=""]&lt;strong&gt;Question 8:&lt;/strong&gt; Is there any way to access the current state of the RXD EasyDMA unit which reflects the current buffer state in RAM? (If not, can you consider making it available in the next generation of devices? Naming it something like RXD.CURRENTAMOUNT or RXD.PROGRESSED or so? The information is already available in the system anyway...)[/quote]
&lt;p&gt;There is not unfortunately. The easiest way we have found to do this is to count the number of RXDRDY events (either in hardware using a TIMER and PPI channel, or through an interrupt), as mentioned earlier, but this event&amp;nbsp;could happen before the data is actually available in RAM. In order to be 100% sure how many bytes you have received you need to stop RX and read the AMOUNT register.&amp;nbsp;&lt;/p&gt;
[quote user=""]&lt;strong&gt;Question 9:&lt;/strong&gt; Considering what I have read in the documentation, it is not reliable to use the RXDRDY event in combination with a counter to manually count the received bytes and use it as the FIFO head, as the reflected data might not have been written to the EasyDMA buffer yet. (Also, I would be a bit worried about glitches when the counter module and the EasyDMA module go out of sync.) Do you agreee that this is not a reliable way to implement a simple and efficient FIFO with UARTE? Do you have any other suggestions?[/quote]
&lt;p&gt;Like indicated in Q8 you can use RXDRDY as an indication that data has been received, but there still might be some delay between this event occurring and the data being available. The safe way is to stop RX and read the AMOUNT register, and use this as a final count that you can then use to update the FIFO.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I guess the problem of having a larger application FIFO that you fill with UART data directly is what to do when you stop the RX in the middle of a transaction. At this point the next buffer will already be configured, and you will get a gap in the FIFO depending on how many bytes were remaining in the buffer when the UART was stopped.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Either you need to keep the FIFO separate from the EasyDMA buffer, which will introduce another memcpy, or you need to accept some gaps in your FIFO, and include a length parameter for each block where you store the exact number of bytes in that block.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Best regards&lt;br /&gt;Torbjørn&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>