EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

RS-485 direction switching with LPC2138/2148

Started by tilmannreh August 26, 2010
Hello,

I have designed a board with the LPC2148 that has RS-232 and RS-485 interfaces as jumper-selectable alternatives.

When it comes to switching the RS-485 transmitter enable, a problem arises. Even if I don't make use of the transmit FIFO and so the THRE status is somewhat delayed, the interrupt by THRE occurs too early for correct direction switching: the stop bit is cut off, so it's not actively driven on the bus.

In this configuration, it's not possible to simply read back the RS-485 data to detect when the last byte has completely been sent (leaving the receiver active during transmission) since this won't work if the board is jumpered for RS-232 - and I don't want to use an additional software configuration which must fit the jumper settings, nor would I like to automatically detect if there's a loopback to eventually determine the jumper settings (too risky to get wrong results).

I did a few tests with polling TEMT after the last THRE interrupt. This would basically solve the timing issue - then, the transmitter is switched off right in the center of the stop bit; that should be sufficient. However, the CPU would be locked in the UART ISR for several tens of microseconds, which is bad since there are some real-time tasks to do...

Searching the archives here, I found a few posts way back in 2004 and 2005, but without solutions that would be of any help in this case. Just many people complaining about the bad UART implementation... Why isn't it possible to generate an interrupt on TEMT??

Is there any news on this issue, or can anyone provide additional information or hints about how to correctly and efficiently turn off the RS-485 transmitter at the end of a sent telegram (and not before at least a part of the stop bit)?

Thanks in advance,
Tilmann

An Engineer's Guide to the LPC2100 Series

On Thu, 26 Aug 2010 13:55:47 -0000, you wrote:

>Hello,
>
>I have designed a board with the LPC2148 that has RS-232 and RS-485 interfaces as jumper-selectable alternatives.
>
>When it comes to switching the RS-485 transmitter enable, a problem arises. Even if I don't make use of the transmit FIFO and so the THRE status is somewhat delayed, the interrupt by THRE occurs too early for correct direction switching: the stop bit is cut off, so it's not actively driven on the bus.
>
>In this configuration, it's not possible to simply read back the RS-485 data to detect when the last byte has completely been sent (leaving the receiver active during transmission) since this won't work if the board is jumpered for RS-232 - and I don't want to use an additional software configuration which must fit the jumper settings, nor would I like to automatically detect if there's a loopback to eventually determine the jumper settings (too risky to get wrong results).
>
>I did a few tests with polling TEMT after the last THRE interrupt. This would basically solve the timing issue - then, the transmitter is switched off right in the center of the stop bit; that should be sufficient. However, the CPU would be locked in the UART ISR for several tens of microseconds, which is bad since there are some real-time tasks to do...
>
>Searching the archives here, I found a few posts way back in 2004 and 2005, but without solutions that would be of any help in this case. Just many people complaining about the bad UART implementation... Why isn't it possible to generate an interrupt on TEMT??
>
>Is there any news on this issue, or can anyone provide additional information or hints about how to correctly and efficiently turn off the RS-485 transmitter at the end of a sent telegram (and not before at least a part of the stop bit)?
>
>Thanks in advance,
>Tilmann

Later parts like the Cortex M3's can generate a TX enable in hardware.
For other parts I'd suggest using a timer interrupt or compare output.
When you send a byte you know pretty well how long it will take to complete, so on the first byte
clear the timer and increment the compare register by a byte time each time you send a byte, and
have the compare event de-assert TXE. On transmit empty you can clear/stop the timer to keep things
in sync.
With a RS485 transceiver, you should receive everything you send.
Enable RX interrupts and when you receive the character you sent, you
know that it is complete.
Mike Harrison wrote:
>
>
> On Thu, 26 Aug 2010 13:55:47 -0000, you wrote:
>
> >Hello,
> >
> >I have designed a board with the LPC2148 that has RS-232 and RS-485
> interfaces as jumper-selectable alternatives.
> >
> >When it comes to switching the RS-485 transmitter enable, a problem
> arises. Even if I don't make use of the transmit FIFO and so the THRE
> status is somewhat delayed, the interrupt by THRE occurs too early for
> correct direction switching: the stop bit is cut off, so it's not
> actively driven on the bus.
> >
> >In this configuration, it's not possible to simply read back the
> RS-485 data to detect when the last byte has completely been sent
> (leaving the receiver active during transmission) since this won't
> work if the board is jumpered for RS-232 - and I don't want to use an
> additional software configuration which must fit the jumper settings,
> nor would I like to automatically detect if there's a loopback to
> eventually determine the jumper settings (too risky to get wrong results).
> >
> >I did a few tests with polling TEMT after the last THRE interrupt.
> This would basically solve the timing issue - then, the transmitter is
> switched off right in the center of the stop bit; that should be
> sufficient. However, the CPU would be locked in the UART ISR for
> several tens of microseconds, which is bad since there are some
> real-time tasks to do...
> >
> >Searching the archives here, I found a few posts way back in 2004 and
> 2005, but without solutions that would be of any help in this case.
> Just many people complaining about the bad UART implementation... Why
> isn't it possible to generate an interrupt on TEMT??
> >
> >Is there any news on this issue, or can anyone provide additional
> information or hints about how to correctly and efficiently turn off
> the RS-485 transmitter at the end of a sent telegram (and not before
> at least a part of the stop bit)?
> >
> >Thanks in advance,
> >Tilmann
>
> Later parts like the Cortex M3's can generate a TX enable in hardware.
> For other parts I'd suggest using a timer interrupt or compare output.
> When you send a byte you know pretty well how long it will take to
> complete, so on the first byte
> clear the timer and increment the compare register by a byte time each
> time you send a byte, and
> have the compare event de-assert TXE. On transmit empty you can
> clear/stop the timer to keep things
> in sync.
----Original Message----
From: l...
[mailto:l...] On Behalf Of Dave Such
Sent: 26 August 2010 15:43 To: l...
Subject: Re: [lpc2000] RS-485 direction switching with
LPC2138/2148

> With a RS485 transceiver, you should receive everything
> you send. Enable RX interrupts and when you receive the
> character you sent, you know that it is complete.
>

Not on any RS485 transceiver I've ever used. The RX line is held high while in transmit mode.

--
Tim Mitchell

Maybe I should have said *can receive* instead of should receive

Tim Mitchell wrote:
>
>
> ----Original Message----
> From: l...
> [mailto:l... ] On
> Behalf Of Dave Such
> Sent: 26 August 2010 15:43 To: l...
>
> Subject: Re: [lpc2000] RS-485 direction switching with
> LPC2138/2148
>
> > With a RS485 transceiver, you should receive everything
> > you send. Enable RX interrupts and when you receive the
> > character you sent, you know that it is complete.
> > Not on any RS485 transceiver I've ever used. The RX line is held high
> while in transmit mode.
>
> --
> Tim Mitchell
--- In l..., "Tim Mitchell" wrote:

> > With a RS485 transceiver, you should receive everything
> > you send. Enable RX interrupts and when you receive the
> > character you sent, you know that it is complete.
> > Not on any RS485 transceiver I've ever used. The RX line is held high while in transmit mode.

It depends on how the transceiver is wired. All common transceivers have two separate enable lines for TX and RX - if they are connected, RX is deactivated during transmission; if RX enable is fixed, the receiver will also echo back everything that is sent.

Bit as already mentioned in the OP, in this product it is not possible to use loopback for detecting the end of transmission. (Take care that I explicitly mentioned this method, it's well known to me.)

Tilmann

----Original Message----
From: l...
[mailto:l...] On Behalf Of tilmannreh
Sent: 26 August 2010 16:06 To: l...
Subject: [lpc2000] Re: RS-485 direction switching with
LPC2138/2148

> --- In l..., "Tim Mitchell"
> wrote:
>
> > > With a RS485 transceiver, you should receive
> > > everything you send. Enable RX interrupts and when
> > > you receive the character you sent, you know that it
> > > is complete.
> > >
> >
> > Not on any RS485 transceiver I've ever used. The RX
> > line is held high while in transmit mode.
>
> It depends on how the transceiver is wired. All common
> transceivers have two separate enable lines for TX and RX
> - if they are connected, RX is deactivated during
> transmission; if RX enable is fixed, the receiver will
> also echo back everything that is sent.
>
> Bit as already mentioned in the OP, in this product it is
> not possible to use loopback for detecting the end of
> transmission. (Take care that I explicitly mentioned this
> method, it's well known to me.)

That's true, I hadn't thought of splitting the TX/RX enable.

One way I've used before is to send an extra dummy byte at the end of the packet. As the dummy byte is sent for transmission, you switch back to RX mode. The dummy byte never gets sent out onto the line. You might get a bit of a delay depending on the idle time between transmitting bytes.

--
Tim Mitchell

--- In l..., "Tim Mitchell" wrote:

> One way I've used before is to send an extra dummy byte at the end of the packet. As the dummy byte is sent for transmission, you switch back to RX mode. The dummy byte never gets sent out onto the line. You might get a bit of a delay depending on the idle time between transmitting bytes.
For this method, THRE unfortunately is too late. :-(

The THRE interrupt of the last sent byte actually occurs between the MSB of the byte and the stop bit - one bit early for switching TX off, eight bits late for sending a dummy byte.
(FIFO is not used, single byte handling.)

If only TEMT could generate an interrupt...

Tilmann

You could check if there are more data to transmit (inside THRE
interrupt) else you may wait and check TEMT bit or set a delay time
calculated as the time need to tx the last char plus some line delay
then toggle the trasceiver direction inputs.

Il 26/08/2010 17.22, tilmannreh ha scritto:
>
>
> --- In l... ,
> "Tim Mitchell" wrote:
>
> > One way I've used before is to send an extra dummy byte at the end
> of the packet. As the dummy byte is sent for transmission, you switch
> back to RX mode. The dummy byte never gets sent out onto the line. You
> might get a bit of a delay depending on the idle time between
> transmitting bytes.
>
> For this method, THRE unfortunately is too late. :-(
>
> The THRE interrupt of the last sent byte actually occurs between the
> MSB of the byte and the stop bit - one bit early for switching TX off,
> eight bits late for sending a dummy byte.
> (FIFO is not used, single byte handling.)
>
> If only TEMT could generate an interrupt...
>
> Tilmann
Hi,

the trick I did in my program is as follows (only works, if you do not
use parity usually): setup the parity as well and stick it to the
polarity of the stop bit (1 is suppose) and set the UART to 9 bit, then
you can use one of the flags indicating the FIFO is empty (don't
remember which one) giving you the exact time when you have to change
the direction.

The only disadvantage is, that you have to use 9 bits on your PC
(sending to the LPC21xx) as well, otherwise you would get invalid
characters on receiving on the LPC.

Best regards
Herbert

Am 26.08.2010 17:15, schrieb Tim Mitchell:
> ----Original Message----
> From: l...
> [mailto:l...] On Behalf Of tilmannreh
> Sent: 26 August 2010 16:06 To: l...
> Subject: [lpc2000] Re: RS-485 direction switching with
> LPC2138/2148
>
>> --- In l..., "Tim Mitchell"
>> wrote:
>>
>>>> With a RS485 transceiver, you should receive
>>>> everything you send. Enable RX interrupts and when
>>>> you receive the character you sent, you know that it
>>>> is complete.
>>>>
>>> Not on any RS485 transceiver I've ever used. The RX
>>> line is held high while in transmit mode.
>> It depends on how the transceiver is wired. All common
>> transceivers have two separate enable lines for TX and RX
>> - if they are connected, RX is deactivated during
>> transmission; if RX enable is fixed, the receiver will
>> also echo back everything that is sent.
>>
>> Bit as already mentioned in the OP, in this product it is
>> not possible to use loopback for detecting the end of
>> transmission. (Take care that I explicitly mentioned this
>> method, it's well known to me.)
> That's true, I hadn't thought of splitting the TX/RX enable.
>
> One way I've used before is to send an extra dummy byte at the end of the packet. As the dummy byte is sent for transmission, you switch back to RX mode. The dummy byte never gets sent out onto the line. You might get a bit of a delay depending on the idle time between transmitting bytes.

The 2024 Embedded Online Conference