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)

  • Hi,

    You also said " it seems the ENDRX interrupt is being fired about 4 bytes after the stop rx, which doesn't seem to agree with the manual"

    Quote from the spec

    The UARTE is able to receive up to four bytes after the STOPRX task has been triggered as long as these are sent in succession immediately after the RTS signal is deactivated. This is possible because after the RTS is deactivated the UARTE is able to receive bytes for an extended period equal to the time it takes to send 4 bytes on the configured baud rate.

    The above mentioned behavior makes sense because when you do a STOPRX which in turns deactivates the RTS signal, the peer device might take some time to see that it should stop sending more bytes if the flow control is simulated. So UARTE on nRF52 allow 4 more bytes to be transmitted. Also note that when This is also similar with UART with no EasyDMA

    When flow control is enabled, the UART will deactivate the RTS signal when there is only space for four more bytes in the receiver FIFO. The counterpart transmitter is therefore able to send up to four bytes after the RTS signal is deactivated before data is being overwritten. To prevent overwriting data in the FIFO, the counterpart UART transmitter must therefore make sure to stop transmitting data within four bytes after the RTS line is deactivated.

    I think if you want the other side to stop transmitting immediately after STOPRX is triggered, then use flow control and make sure that the peer uart also has hardware flow control (not CPU simulated flow control)

  • I unfortunately do not have the ability to use hardware flow control on the peer device. Is it possible to set up some fake RTS CTS on the nrf chip that will force ENDRX to fire early?

    Also, you're saying the ENDRX is being delayed because the peer transmitter is still sending data, yet on the last STOPRX task no data is being transmitted and it is taking just as long for ENDRX.

  • No it's not possible to fake something to force ENDRX to fire early, even with flow control, if the other end was slow stopping sending, the UARTE will continue to receive up to 4 characters in order to ensure it doesn't lose data, well unless the other end kept on sending yet more data.

    I do agree there is some ambiguity here which the docs don't cover. The UART is going to continue to receive bytes, but it's quite reasonable to assume it would ENDTX, buffer anything coming in in the TX buffer and write it out when the next EasyDMA starts. However it seems it doesn't do that. But it would be good to have clarification.

    I still don't see why this is a problem however. You call STOP, you wait for END, you look at see how many characters you have in your buffer, you wanted 4, you have 7. You copy 3 into the new buffer and set the EasyDMA pointer to point to the next byte and restart.

  • .. in that way you get your individual buffers, you just manipulate a couple of bytes and the count between stopping one transfer and starting the next.

    However quickly the UART stopped, I think you were always going to have at least an occasional extra byte in the buffer just owing to not quite stopping the task before the next character had started coming in. So this was always a case you were likely to have to deal with in code. But coding using the actual number of characters you actually received is pretty simple and saves you from all the vagaries of how fast something stops and whether you got to the stop event in time.

  • I do not know how many bytes will be in a message beforehand, that is decided by that small finite idle time of 1.5ms. So I end up with 11 bytes read in my buffer but I have no idea where in those 11 bytes the STOPRX was actually triggered.

    Again, you mention (along with the manual) that it will continue to receive up to 4 bytes after a STOPRX as long as they are sent immediately after and in succession. Yet you can see from the oscilloscope capture the last STOPRX task is triggered after the last byte, but it's still taking a 4 bytes delay.

Related