Reply by Dave Nadler October 16, 20142014-10-16
On Thursday, October 16, 2014 7:30:32 AM UTC+2, rickman wrote:
> Personally I prefer to use hardware which is designed for the job and > will handle the driver enable properly.
Me too. And I prefer datasheets that match the hardware, and so forth. Then, I wake up from that nice dream, and deal with reality ;-)
Reply by David Brown October 16, 20142014-10-16
On 16/10/14 07:30, rickman wrote:

> > Personally I prefer to use hardware which is designed for the job and > will handle the driver enable properly. >
You'll get no arguments on that point. The trick of sending an extra byte is a way to make things work with non-ideal hardware - but better hardware is always nicer.
Reply by Grant Edwards October 16, 20142014-10-16
On 2014-10-16, rickman <gnuarm@gmail.com> wrote:
> On 10/15/2014 10:24 AM, Grant Edwards wrote: >> On 2014-10-15, rickman <gnuarm@gmail.com> wrote: >>> On 10/14/2014 5:35 PM, David Brown wrote: >>> >>>> It can often work fine - at worst, the receiver sees a brief noise at >>>> the end of the telegram itself, and that is easily ignored. >>>> >>>> However, if you are worried that the "transmission complete" interrupt >>>> might be delayed too long, then clearly the same thing will apply to the >>>> final "transmit character" interrupt for your extra character. So it is >>>> a useful trick if you don't have a "transmission complete" interrupt >>>> signal, but not for the problem at hand here. >>> >>> Is all of this based on the idea that the transmitter empty interrupt is >>> not valid in some way? >> >> We're talking about a 16550. There _is_no_ transmitter empty >> interrupt. There is a transmit holding register empty interrupt, but >> that happens _before_ transmission of the last byte has begun. > > I don't know who "we" is, but the OP never said what UART he is using. > I had the impression it was a UART within an MCU from his initial post > where he refers to "some microcontrollers" toggling an output. Did he > say he is using a '550' type UART?
Sorry, I must have gotten this confused with a different thread. -- Grant Edwards grant.b.edwards Yow! I'm ZIPPY the PINHEAD at and I'm totally committed gmail.com to the festive mode.
Reply by pozzugno October 16, 20142014-10-16
Il 16/10/2014 11:05, rickman ha scritto:
> On 10/16/2014 2:36 AM, pozzugno wrote:
> Do you know if your transmitter empty interrupt works properly or is > this what prompted the entire thread?
AVR micros have two transmitter interrupts: register empty and transmit complete. The transmit complete interrupt should disable the RS485 driver and it seems work well.
> I was looking at some of the USB dongles for RS-485 a while back and > some of them make it clear that the driver is controlled directly by the > transmitter empty and so the last char gets out of the module correctly.
No, AVRs (and many many micros smaller and bigger) can't directly control the RS485 driver/direction.
Reply by rickman October 16, 20142014-10-16
On 10/16/2014 2:36 AM, pozzugno wrote:
> Il 16/10/2014 07:17, rickman ha scritto: >> On 10/15/2014 10:24 AM, Grant Edwards wrote: >>> On 2014-10-15, rickman <gnuarm@gmail.com> wrote: >>>> >>>> Is all of this based on the idea that the transmitter empty >>>> interrupt is >>>> not valid in some way? >>> >>> We're talking about a 16550. There _is_no_ transmitter empty >>> interrupt. There is a transmit holding register empty interrupt, but >>> that happens _before_ transmission of the last byte has begun. >> >> I don't know who "we" is, but the OP never said what UART he is using. I >> had the impression it was a UART within an MCU from his initial post >> where he refers to "some microcontrollers" toggling an output. Did he >> say he is using a '550' type UART? > > Yes, I'm using a UART peripheral integrated in microcontrollers, like > PICs from Microchip or AVRs from Atmel.
Do you know if your transmitter empty interrupt works properly or is this what prompted the entire thread? I was looking at some of the USB dongles for RS-485 a while back and some of them make it clear that the driver is controlled directly by the transmitter empty and so the last char gets out of the module correctly. -- Rick
Reply by rickman October 16, 20142014-10-16
On 10/16/2014 3:01 AM, pozzugno wrote:
> > I was thinking about your suggestions, but it seems to me it doesn't > work well. > > Others suggested to send some dummy bytes, keeping the RS485 driver > *disabled*. Only after those bytes are really shifted out, the driver > could be enabled. In other words, you use the UART hardware also for > timing, without the need to use other peripherals (such as > timers/counters). > > Your suggestion seems better: send some sync bytes at the beginning, > with the RS485 driver *enabled*. My protocol can be used with this > approach, because it is inspired to HDLC. Every frame starts and ends > with a sync byte. If the sync byte appears in the payload data, it is > escaped (as in HDLC or SLIP protocols).
The block start and end bytes are important, but if they are not unique you have to escape them in your data which implies a message handling layer in your software. Or you can use a UART that recognizes the start characters. If you use sync data transmission rather than async this is common.
> The device could send N sync bytes without problems. The receiver will > see N empty frames and will discard them silently. In this way it's > even more simple to introduce a delay before the answer.
How is N sync bytes equivalent to a bunch of empty frames? Is your sync byte unique?
> But I think it doesn't work. Bytes are send asyncronously and the > receiver must syncronize to the start bit of each byte. If the slave > sends 2 sync bytes in the front of each frame, without a delay, and the > master toggles direction in the middle of the two sync bytes, the master > will receive one or two wrong bytes or detect frame errors, depending on > the precise time and transitions pattern. > > Moreover, if the payload is transmitted immediately after sync bytes, as > really happens, the overall frame could be corrupted. > > *Perhaps* this technique works well only if the preamble bytes are 0xFF, > because they appears on the wire just as a single start bit (all the > other bits, including stop bits, are at the idle level). > > --- ------------------ ------------------ -......... > | | PREAMBLE | | PREAMBLE | | START OF FRAME > | | 0xFF | | 0xFF | | > ---- ---- ---- > ^ ^ ^ > A B C > > If the master toggles direction at time A, it will receive the two > preamble bytes correctly and could discard them. The frame is received > correctly. > If it toggles direction at time C, it will receive only one preamble > byte correctly and could discard it. The frame is received correctly. > > What happens it the master toggles direction at time B, in the middle of > a start bit? I don't know if the UART detects a start bit on the > high-to-low edge or on the low level. In the first case, I think > there's no problem. In the second case, what happens?
I'm not sure I see a problem. UARTs typically see the falling edge as the start of the start bit, but check at least once in the middle of the bit to see if it was just noise. Too short a pulse and it is discarded. Long enough and it will be seen as a start bit. Since the UART starts looking for a new start bit in the middle of the stop bit (approximately) such a start bit timing discrepancy will not create a problem although this leaves no room for timing variation between the two ends. As long as point B is in the first preamble char and not the last it should be ok. But if you can be sure the driver disable will be at worst case no later than C, why can't the slave just hold of sending the start of frame for another char? Your approach will work, but it is no better than sending chars without enabling the slave's driver in the first place. In fact, if you know when the master driver will be off the bus, you can get your message out once character more quickly by not sending the last preamble byte. -- Rick
Reply by Tauno Voipio October 16, 20142014-10-16
On 16.10.14 10:01, pozzugno wrote:

> *Perhaps* this technique works well only if the preamble bytes are 0xFF, > because they appears on the wire just as a single start bit (all the > other bits, including stop bits, are at the idle level). > > --- ------------------ ------------------ -......... > | | PREAMBLE | | PREAMBLE | | START OF FRAME > | | 0xFF | | 0xFF | | > ---- ---- ---- > ^ ^ ^ > A B C
It does - I have been using it for years (20+) in several different RS-485 links. You need also a reliable way of recognizing frame boundaries, to get the framing right. I'm using an encapsulation similar to PPP (RFC1662) which also gives the possibility to exclude the preamble bytes from valid frame data. -- Tauno Voipio
Reply by pozzugno October 16, 20142014-10-16
Il 13/10/2014 17:20, Grant Edwards ha scritto:
> On 2014-10-13, pozzugno <pozzugno@gmail.com> wrote: > >> If a node on the bus is very fast and starts transmitting (the master) >> or answering (one slave) immediately after receving the last byte, but >> when the previous transmitting node is executing other ISRs, the final >> result is a corrupted transmission. >> >> What is the solution? I think the only solution is to define, at the >> design time, a minimum interval between the receiving of the last byte >> from one node and the transmission of the first byte. > > Or put a some disposable preamble bytes on the front of messages. This > is pretty common when using half-duplex modems: the padding bytes give > the modems time to "turn-around" and get carrier established, PLLs > locked, etc.
I was thinking about your suggestions, but it seems to me it doesn't work well. Others suggested to send some dummy bytes, keeping the RS485 driver *disabled*. Only after those bytes are really shifted out, the driver could be enabled. In other words, you use the UART hardware also for timing, without the need to use other peripherals (such as timers/counters). Your suggestion seems better: send some sync bytes at the beginning, with the RS485 driver *enabled*. My protocol can be used with this approach, because it is inspired to HDLC. Every frame starts and ends with a sync byte. If the sync byte appears in the payload data, it is escaped (as in HDLC or SLIP protocols). The device could send N sync bytes without problems. The receiver will see N empty frames and will discard them silently. In this way it's even more simple to introduce a delay before the answer. But I think it doesn't work. Bytes are send asyncronously and the receiver must syncronize to the start bit of each byte. If the slave sends 2 sync bytes in the front of each frame, without a delay, and the master toggles direction in the middle of the two sync bytes, the master will receive one or two wrong bytes or detect frame errors, depending on the precise time and transitions pattern. Moreover, if the payload is transmitted immediately after sync bytes, as really happens, the overall frame could be corrupted. *Perhaps* this technique works well only if the preamble bytes are 0xFF, because they appears on the wire just as a single start bit (all the other bits, including stop bits, are at the idle level). --- ------------------ ------------------ -......... | | PREAMBLE | | PREAMBLE | | START OF FRAME | | 0xFF | | 0xFF | | ---- ---- ---- ^ ^ ^ A B C If the master toggles direction at time A, it will receive the two preamble bytes correctly and could discard them. The frame is received correctly. If it toggles direction at time C, it will receive only one preamble byte correctly and could discard it. The frame is received correctly. What happens it the master toggles direction at time B, in the middle of a start bit? I don't know if the UART detects a start bit on the high-to-low edge or on the low level. In the first case, I think there's no problem. In the second case, what happens?
Reply by pozzugno October 16, 20142014-10-16
Il 16/10/2014 07:17, rickman ha scritto:
> On 10/15/2014 10:24 AM, Grant Edwards wrote: >> On 2014-10-15, rickman <gnuarm@gmail.com> wrote: >>> On 10/14/2014 5:35 PM, David Brown wrote: >>> >>>> It can often work fine - at worst, the receiver sees a brief noise at >>>> the end of the telegram itself, and that is easily ignored. >>>> >>>> However, if you are worried that the "transmission complete" interrupt >>>> might be delayed too long, then clearly the same thing will apply to >>>> the >>>> final "transmit character" interrupt for your extra character. So >>>> it is >>>> a useful trick if you don't have a "transmission complete" interrupt >>>> signal, but not for the problem at hand here. >>> >>> Is all of this based on the idea that the transmitter empty interrupt is >>> not valid in some way? >> >> We're talking about a 16550. There _is_no_ transmitter empty >> interrupt. There is a transmit holding register empty interrupt, but >> that happens _before_ transmission of the last byte has begun. > > I don't know who "we" is, but the OP never said what UART he is using. I > had the impression it was a UART within an MCU from his initial post > where he refers to "some microcontrollers" toggling an output. Did he > say he is using a '550' type UART?
Yes, I'm using a UART peripheral integrated in microcontrollers, like PICs from Microchip or AVRs from Atmel.
Reply by rickman October 16, 20142014-10-16
On 10/15/2014 3:47 AM, David Brown wrote:
> On 15/10/14 08:00, rickman wrote: >> On 10/14/2014 5:35 PM, David Brown wrote: >>> On 14/10/14 20:20, rickman wrote: >>>> On 10/14/2014 12:58 PM, Dave Nadler wrote: >>>>> On Monday, October 13, 2014 9:02:33 PM UTC+2, upsid...@downunder.com >>>>> wrote: >>>>>> ...you can't get an interrupt, when the last bit of >>>>>> the last character is actually shifted out of the Tx shift register. >>>>> >>>>> Sure you can, just append N dummy TX bytes where "N" is the TX FIFO >>>>> depth. >>>>> >>>>> But check it on the scope!! >>>> >>>> That is a very dangerous way to control the driver enable. Most likely >>>> the interrupt will happen when the start bit is sent which means the >>>> output will already be sending the start bit when the driver is >>>> disabled. >>>> >>> >>> It can often work fine - at worst, the receiver sees a brief noise at >>> the end of the telegram itself, and that is easily ignored. >>> >>> However, if you are worried that the "transmission complete" interrupt >>> might be delayed too long, then clearly the same thing will apply to the >>> final "transmit character" interrupt for your extra character. So it is >>> a useful trick if you don't have a "transmission complete" interrupt >>> signal, but not for the problem at hand here. >> >> Is all of this based on the idea that the transmitter empty interrupt is >> not valid in some way? >> > > No, my point was that Dave's suggestion of sending an extra byte is not > "very dangerous" as you suggest, and can be a useful trick. It is not > needed here as the OP has a "transmission complete" interrupt which > triggers when the final send is complete. Many other microcontrollers > and UARTs don't have a suitable interrupt on the final character (or > have flaws with it, such as an interrupt that triggers at the start of > the stop bit - turning off the driver at that point can cause > hard-to-trace problems). For such micros, sending an extra byte can be > a good solution.
I just don't know that putting the glitch on the bus is a good idea. Minimizing the glitch depends on a fast response to the interrupt which is most of what this thread has been discussing. A slow response puts a larger glitch on the bus. Personally I prefer to use hardware which is designed for the job and will handle the driver enable properly. -- Rick