EmbeddedRelated.com
Forums

UART behavior for CTS/RTS - Kinetis bugs?

Started by Dave Nadler October 27, 2016
Hi all - Perhaps some of you have encountered this?

The post linked below shows the Kinetis UART continues to transmit after the receiver has de-asserted CTS:
https://community.nxp.com/thread/432154
Freescale engineers claim their part is OK and its the other guys fault...

Here's my question: As this is an asynchronous link, the receiver can de-assert CTS at any time. What is the transmitter supposed to do? For example, suppose CTS is de-asserted in the middle of transmitting a character: Must the transmitter immediately stop, and restart transmitting the character from the start bit when CTS is again asserted (which in turn introduces a race condition around the end of character transmission)? Or finish the current character transmission and then pause (another race condition for "current character")? Is there any specification on how this should be handled? Or even any consensus?

Thanks in advance,
Best Regards, Dave

PS: I've always used a protocol layer that corrects dropped characters so never had this impact an application, but using some parts like SiLabs bluegiga for SPP don't give that option (at the layer of controlling the Bluetooth device, or supporting a non-protocol client expecting a simple ASCII data stream). Even worse, these things drop status messages into the (application data) stream with no consistent header/delimiter - good luck catching all possible Bluetooth events.
On 10/27/2016 1:21 PM, Dave Nadler wrote:
> Hi all - Perhaps some of you have encountered this? > > The post linked below shows the Kinetis UART continues to transmit after the > receiver has de-asserted CTS: https://community.nxp.com/thread/432154 > Freescale engineers claim their part is OK and its the other guys fault... > > Here's my question: As this is an asynchronous link, the receiver can > de-assert CTS at any time. What is the transmitter supposed to do? For > example, suppose CTS is de-asserted in the middle of transmitting a > character: Must the transmitter immediately stop, and restart transmitting > the character from the start bit when CTS is again asserted (which in turn
No.
> introduces a race condition around the end of character transmission)? Or > finish the current character transmission and then pause (another race > condition for "current character")? Is there any specification on how this > should be handled? Or even any consensus?
Of course, serial (EIA232) comms are highly application dependant. A TWX would handle this differently than a modern PC, etc. But... Clear-To-Send indicates *clear* (i.e., "OK") to (begin to) send. The transmitter should sample it at the start of transmission and defer the transmission until it is asserted (and "stable"). As most transmitters (serializers) are decoupled from the "holding register", this often means that AT LEAST one character can be expected to be received after the receiver drops CTS. Of course, as the receiver has no idea if the transmitter is *just* starting a transmission (all it knows is the results of the previous transmission and often doesn't have fine-grained temporal information about that, either -- nor the waveform distortions/skew in transit; i.e., you can't reliably infer what the transmitter is doing even with a 'scope probe on its TxD!), that character is possible regardless of whether you're driving the line with a 1402 or something fresh out of today's foundries! As Tx buffers have increased in depth, there are more possibilities for additional characters to be received after dropping CTS. I.e., flaws in how this information is "expedited" up/down the buffer. And, if you want to support XON/XOFF (and variants thereof), then you have to also expect some amount of additional delay (i.e., if you have to SEND an XOFF character, you have to ensure YOUR transmitter is idle -- which means waiting for 1 or more enqueued characters to clear it -- AND for the receiving UART to be able to receive the sent character and "process" it. Whether that is done in the driver or a higher level protocol handler can affect the latency in how quickly the remote transmitter actually "paces off". Bottom line, leave a bit of space in your Rx FIFO for several characters. I design my drivers to store the received character AND associated flags (i.e., 2 bytes per character). This allows the higher level protocol handler to notice if a character was received with a parity or framing error, overrun, etc. It also provides a convenient place to inject a "FIFO overrun" flag. I.e., "at this point in the character stream, the receive FIFO overflowed because something didn't stop sending as expected. As such, one or more characters are lost, here." [It also lets you promote BREAK (long space) handling to that protocol level instead of trying to handle it AND RECOVER FROM IT in the driver; drivers should always be lean/efficient -- do as little as possible] If you know exactly the protocol characteristics of the device with which you EXPECT to communicate, then you can (gamble on) tailoring the driver and handler to that particular device (at your own peril as "things inevitably change")
> Thanks in advance, Best Regards, Dave > > PS: I've always used a protocol layer that corrects dropped characters so > never had this impact an application, but using some parts like SiLabs > bluegiga for SPP don't give that option (at the layer of controlling the > Bluetooth device, or supporting a non-protocol client expecting a simple > ASCII data stream). Even worse, these things drop status messages into the > (application data) stream with no consistent header/delimiter - good luck > catching all possible Bluetooth events.
On Thu, 27 Oct 2016 13:21:01 -0700, Dave Nadler wrote:

> Hi all - Perhaps some of you have encountered this? > > The post linked below shows the Kinetis UART continues to transmit after > the receiver has de-asserted CTS: > https://community.nxp.com/thread/432154 Freescale engineers claim their > part is OK and its the other guys fault... > > Here's my question: As this is an asynchronous link, the receiver can > de-assert CTS at any time. What is the transmitter supposed to do? For > example, suppose CTS is de-asserted in the middle of transmitting a > character: Must the transmitter immediately stop, and restart > transmitting the character from the start bit when CTS is again asserted > (which in turn introduces a race condition around the end of character > transmission)? Or finish the current character transmission and then > pause (another race condition for "current character")? Is there any > specification on how this should be handled? Or even any consensus? > > Thanks in advance, > Best Regards, Dave > > PS: I've always used a protocol layer that corrects dropped characters > so never had this impact an application, but using some parts like > SiLabs bluegiga for SPP don't give that option (at the layer of > controlling the Bluetooth device, or supporting a non-protocol client > expecting a simple ASCII data stream). Even worse, these things drop > status messages into the (application data) stream with no consistent > header/delimiter - good luck catching all possible Bluetooth events.
I believe that the only reasonable thing to do would be to finish sending the character, then wait until CTS is asserted before sending. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com I'm looking for work -- see my website!
On 28.10.2016 г. 00:39, Tim Wescott wrote:
> On Thu, 27 Oct 2016 13:21:01 -0700, Dave Nadler wrote: > >> Hi all - Perhaps some of you have encountered this? >> >> The post linked below shows the Kinetis UART continues to transmit after >> the receiver has de-asserted CTS: >> https://community.nxp.com/thread/432154 Freescale engineers claim their >> part is OK and its the other guys fault... >> >> Here's my question: As this is an asynchronous link, the receiver can >> de-assert CTS at any time. What is the transmitter supposed to do? For >> example, suppose CTS is de-asserted in the middle of transmitting a >> character: Must the transmitter immediately stop, and restart >> transmitting the character from the start bit when CTS is again asserted >> (which in turn introduces a race condition around the end of character >> transmission)? Or finish the current character transmission and then >> pause (another race condition for "current character")? Is there any >> specification on how this should be handled? Or even any consensus? >> >> Thanks in advance, >> Best Regards, Dave >> >> PS: I've always used a protocol layer that corrects dropped characters >> so never had this impact an application, but using some parts like >> SiLabs bluegiga for SPP don't give that option (at the layer of >> controlling the Bluetooth device, or supporting a non-protocol client >> expecting a simple ASCII data stream). Even worse, these things drop >> status messages into the (application data) stream with no consistent >> header/delimiter - good luck catching all possible Bluetooth events. > > I believe that the only reasonable thing to do would be to finish sending > the character, then wait until CTS is asserted before sending. >
It is the normal thing to do indeed, all UARTs I have touched (the MC6850 ACIA being the first one some ages ago) do it this way. Except one - a Mostek 6550 or something like that. It would break the character up... thus making its CTS input unusable to me. Well, this was also a few ages ago, one or two less than the 6850 though :-). Dimiter ------------------------------------------------------ Dimiter Popoff, TGI http://www.tgi-sci.com ------------------------------------------------------ http://www.flickr.com/photos/didi_tgi/
Den torsdag den 27. oktober 2016 kl. 23.39.32 UTC+2 skrev Tim Wescott:
> On Thu, 27 Oct 2016 13:21:01 -0700, Dave Nadler wrote: > > > Hi all - Perhaps some of you have encountered this? > > > > The post linked below shows the Kinetis UART continues to transmit after > > the receiver has de-asserted CTS: > > https://community.nxp.com/thread/432154 Freescale engineers claim their > > part is OK and its the other guys fault... > > > > Here's my question: As this is an asynchronous link, the receiver can > > de-assert CTS at any time. What is the transmitter supposed to do? For > > example, suppose CTS is de-asserted in the middle of transmitting a > > character: Must the transmitter immediately stop, and restart > > transmitting the character from the start bit when CTS is again asserted > > (which in turn introduces a race condition around the end of character > > transmission)? Or finish the current character transmission and then > > pause (another race condition for "current character")? Is there any > > specification on how this should be handled? Or even any consensus? > > > > Thanks in advance, > > Best Regards, Dave > > > > PS: I've always used a protocol layer that corrects dropped characters > > so never had this impact an application, but using some parts like > > SiLabs bluegiga for SPP don't give that option (at the layer of > > controlling the Bluetooth device, or supporting a non-protocol client > > expecting a simple ASCII data stream). Even worse, these things drop > > status messages into the (application data) stream with no consistent > > header/delimiter - good luck catching all possible Bluetooth events. > > I believe that the only reasonable thing to do would be to finish sending > the character, then wait until CTS is asserted before sending.
yes, the uart should check CTS right before sending the start bit It seems the problem is that that uart has already committed to sending before the other end has gotten the full stopbit and a chance to set CTS maybe using two stop bits on the transmit side would work -Lasse
On 27/10/16 23:39, Tim Wescott wrote:
> On Thu, 27 Oct 2016 13:21:01 -0700, Dave Nadler wrote: > >> Hi all - Perhaps some of you have encountered this? >> >> The post linked below shows the Kinetis UART continues to transmit after >> the receiver has de-asserted CTS: >> https://community.nxp.com/thread/432154 Freescale engineers claim their >> part is OK and its the other guys fault... >> >> Here's my question: As this is an asynchronous link, the receiver can >> de-assert CTS at any time. What is the transmitter supposed to do? For >> example, suppose CTS is de-asserted in the middle of transmitting a >> character: Must the transmitter immediately stop, and restart >> transmitting the character from the start bit when CTS is again asserted >> (which in turn introduces a race condition around the end of character >> transmission)? Or finish the current character transmission and then >> pause (another race condition for "current character")? Is there any >> specification on how this should be handled? Or even any consensus? >> >> Thanks in advance, >> Best Regards, Dave >> >> PS: I've always used a protocol layer that corrects dropped characters >> so never had this impact an application, but using some parts like >> SiLabs bluegiga for SPP don't give that option (at the layer of >> controlling the Bluetooth device, or supporting a non-protocol client >> expecting a simple ASCII data stream). Even worse, these things drop >> status messages into the (application data) stream with no consistent >> header/delimiter - good luck catching all possible Bluetooth events. > > I believe that the only reasonable thing to do would be to finish sending > the character, then wait until CTS is asserted before sending. >
Yes, anything else would disrupt the low-level behaviour of the UART, which is designed to transfer in units of one character. If the transmitter broke off in the middle of the character, a receiver would see the start of the character followed by high bits. I also think it is odd to see something using hardware flow control in modern devices. Hardware flow control can be a real pain when you have buffers, FIFOs, DMA, etc. Flow control is usually handled at a higher protocol level now. Rather than using CTS/RTS, or XON/XOFF, you define it at a higher level such as replying to telegrams with NACK's. Or you just note that since your UART is running at perhaps 115kbps or less, and your microcontrollers are running at 50 MHz or more, you don't need any kind of flow control - each side is ready all the time.
On 2016-10-28, David Brown <david.brown@hesbynett.no> wrote:
> >> I believe that the only reasonable thing to do would be to finish sending >> the character, then wait until CTS is asserted before sending. > > Yes, anything else would disrupt the low-level behaviour of the > UART, which is designed to transfer in units of one character. If > the transmitter broke off in the middle of the character, a receiver > would see the start of the character followed by high bits.
Which is an entirely valid character assuming no parity. It has a 50% chance of being a valid character with parity enabled. Stopping the transmitter in mid-character is simply 100% broken.
> I also think it is odd to see something using hardware flow control in > modern devices. Hardware flow control can be a real pain when you have > buffers, FIFOs, DMA, etc.
Why? If hardware flow control is implemented properly (which means it's in HW), then it's completely transparent regardless of buffers, FIFOs, DMA, etc. Trying to implement hardware flow control in software is usually futile.
> Flow control is usually handled at a higher protocol level now. > Rather than using CTS/RTS, or XON/XOFF, you define it at a higher > level such as replying to telegrams with NACK's. Or you just note > that since your UART is running at perhaps 115kbps or less, and your > microcontrollers are running at 50 MHz or more, you don't need any > kind of flow control - each side is ready all the time.
-- Grant Edwards grant.b.edwards Yow! Civilization is fun! at Anyway, it keeps me busy!! gmail.com
On 28/10/16 16:23, Grant Edwards wrote:
> On 2016-10-28, David Brown <david.brown@hesbynett.no> wrote: >> >>> I believe that the only reasonable thing to do would be to finish sending >>> the character, then wait until CTS is asserted before sending. >> >> Yes, anything else would disrupt the low-level behaviour of the >> UART, which is designed to transfer in units of one character. If >> the transmitter broke off in the middle of the character, a receiver >> would see the start of the character followed by high bits. > > Which is an entirely valid character assuming no parity. It has a 50% > chance of being a valid character with parity enabled. Stopping the > transmitter in mid-character is simply 100% broken. > >> I also think it is odd to see something using hardware flow control in >> modern devices. Hardware flow control can be a real pain when you have >> buffers, FIFOs, DMA, etc. > > Why? If hardware flow control is implemented properly (which means > it's in HW), then it's completely transparent regardless of buffers, > FIFOs, DMA, etc. Trying to implement hardware flow control in > software is usually futile.
Often it is /not/ implemented entirely in hardware. Even if the hardware handles the FIFOs, DMA, etc., there are often other aspects such as timing and timeouts that get extra complications when there is hardware flow control. It is certainly possible to handle, but it is an extra complication - and IME it is rarely used these days.
> >> Flow control is usually handled at a higher protocol level now. >> Rather than using CTS/RTS, or XON/XOFF, you define it at a higher >> level such as replying to telegrams with NACK's. Or you just note >> that since your UART is running at perhaps 115kbps or less, and your >> microcontrollers are running at 50 MHz or more, you don't need any >> kind of flow control - each side is ready all the time. >
Hi Dave,

As others have pointed out, the current character in the transmitter
shift register is sent correctly.

Many years ago I had to deal with lots of modem datalinks, some also
with hardware handshaking.
I found, that one needs to expect up to *two* more characters after
asserting CTS. Usually, you get no or one more character, but be
prepared to get two.
I assumed this has to do with some internal buffers in the UART logic.

HTH
Wolfgang

-- 
From-address is spam trap
Use: wolfgang (dot) mahringer (at) sbg (dot) at
On Thursday, October 27, 2016 at 4:42:07 PM UTC-4, Don Y wrote:
> ...A TWX would handle this differently than a modern PC, etc....
Of course, as a 'modern' PC hasn't had a serial port in a decade ;-) Seriously Don, you haven't answered the question: Is there any specification on how this should be handled? Or even any consensus? The interface at issue here is between the Bluegiga/SiLabs Bluetooth module and the Kinetis microcontroller. The Bluegiga Bluetooth module is a black box; its behavior is fixed. I cannot change the receive buffering in this module. Sounds like most of you think that: 1) the Kinetis part should be more careful in assuring a valid CTS 2) the Bluegiga module is faulty: - for not processing at least one character after de-asserting CTS - for extremely short CTS de-assertion pulse, and - for consequently dropping characters transmitted by the Kinetis Yes?? Thanks, Best Regards, Dave