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

UARTE STOPRX on exact byte

Hi there,

I'm issuing a STOPRX at a specific time but I'm noticing that more bytes are being put into the buffer from after the STOPRX was issued.

Is there a way to stop the UARTE on the exact byte and process, and receive all bytes from that point on to a different buffer?

Please advise.

UPDATE

After triggering a STOPRX, the UARTE will hang around for a few more bytes, placing them in the same buffer and then calling ENDRX. This is problematic since these new bytes are part of a different message.

image description

Here you can see that STOPRX is triggered during some small idle times, yet the ENDRX doesn't happen till much later.

This results in ENDRX being called with 11, 6 and 1 bytes read (when it should be 6, 6 and 6 bytes read)

  • It is pretty confusing and the docs on this aren't the very best. Let's try another way of looking at it, I thought about it a bit just now.

    Once you start a receive the UART will continue to receive until the sender stops sending. The only exception is if the UART runs out of space, when it has no choice but to stop.

    Since UART is async, you never know the other side has stopped, so it infers it when there is no activity for a time dependent on the baudrate. If that time passes, it assumes the sender has stopped.

    The RX FIFO is 4 bytes long, so in the usual case where you have received MAXCNT bytes and your data buffer is full, it can only receive 4 more bytes at which point, even if the sender is still sending, it has to stop.

    This is where the STOPRX case, to me, seems inconsistent. It's still continues to receive while the other end send and it still uses the timeout to ...

  • ... work out when it's stopped sending, however it also seems still to have the 4 byte limit. That would make sense to me if, after sending STOPRX the UART stopped putting characters in the data buffer and started buffering them in the RX FIFO, immediately. That, to my mind, is what I'd expect it to do. Then the 4 bytes make sense as it only has 4 bytes of FIFO.

    What it seems to do however is KEEP moving received characters to the data buffer, even though you asked it to please stop. At that point it doesn't really have a 4 byte limit, it could keep going until the data buffer is full + 4 more bytes, but it still stops after 4. I can see why, it separates the RX part into the FIFO from the EasyDMA part out of it again. To my mind it would be more consistent if the STOPRX task immediately stopped the DMA and no more bytes went to the data buffer, and any new arrivals stayed ...

  • ... in the RX FIFO ready for the next transfer. That would make STOPRX really mean stop RX.

    But it seems that's not how it works in this implementation. STOPRX begins the 'waiting to stop' period, the UART will continue to receive until either 1) it detects a long period of inactivity (the timeout) and infers the sender has stopped or 2) it receives 4 more bytes. Of those bytes, as many as will fit in the buffer will go there, all 4 in many cases, the rest will then sit in the RX FIFO.

    This is my mental model for what it's doing. I'd prefer it did something slightly different, but I can see reasons why it might work that way, DMA transfers run sort of independently so they aren't necessarily easy to stop. Doesn't help the original poster's use case, I think using legacy mode would do what he actually needs to get done.

  • Hi RK,

    You made me read the PS again :)
    This is what I am certain is happening.

    1. STOPRX is triggered, at this point we separate two things. EasyDMA and RX FIFO.

    1.a) EasyDma sees the STOPRX immediately and it would try to finish any ongoing transfers from FIFO to RAM buffer. This might be delayed because of the traffic in the system bus. After finishing the ongoing transfer the ENDRX event will be given. The EasyDMA will not pick any new bytes from the RXFIFO. The delay between STOPRX and END event is directly related to the time needed for EasyDMA to finish its ongoing transfer.

    1.b) the RX FIFO will still be able to receive 4 bytes of data after STOPRX is generated and this is not dependent on when ENDRX is generated. It is only depending on how many bytes are coming within next 4 byte transfer time with the set baudrate and how much space is left in RX FIFO. The incoming bytes AFTER STOPRX is triggered should stay in FIFO. You need to trigger FLUSHRX explicitly for moving this to RAM ....

  • I think the confusion here is that the delay between STOPRX and ENDRX event is because of the 4 bytes reception ability !!?? which I think is not correct. The ability to receive 4 bytes after STOPRX has nothing to do with the delay for ENDRX. As you said, the incoming bytes after STOPRX should stay in FIFO and I think that is how it will be. Otherwise FLUSHRX task would not make any sense to me. Do you agree?

Related