Re: Half-duplex rs-485 on full-duplex UART.

From: Lennart Sorensen
Date: Fri Jun 27 2008 - 09:49:23 EST


On Fri, Jun 27, 2008 at 12:56:26AM +0400, Sergey Lapin wrote:
> I have a device with normal serial ports (at91sam9260-based) and
> RS-485 half-duplex transceiver
> installed for it and 1 GPIO for duplex control, 1=writing, 0=reading.
> A problem is that I need to hack serial driver to support this GPIO
> control, which I don't like.
> I just need to set it to 1 before transmission and back to 0 when
> transmission ends.
>
> Most important thing is to set this bit to 1 before transfer starts,
> so I can't just poll UART registers
> from tasklet. So I had to hack into serial driver for that.
>
> So questions are:
>
> 1. Is there some generic enough mechanism in kernel to handle such
> tasks? so I mean external
> serial transcievers support?
>
> 2. Is there any way to implement this task without touching, in my
> case, drivers/serial/atmel_serial.c?

There are a few serial ports in linux that have RS485 support.
crisv10.c for example appears to support RS485.

The way that seems most common (as far as I know) is that drive the
transmit/receive direction using the RTS line, which if the serial port
has one would already support software control. The user application
would then set RTS, transmit the data, wait for the transmit buffer to
empty, and then when it is empty, toggle the RTS off again, and then
wait for the reply.

The simpler method if you have access to a good UART (like many of the
exars) is to simply let the hardware manage it. You can enable
autors485 mode in which whenever there is data to transmit, RTS is
asserted, and a few clock cycles after the transmit FIFO empties, the
RTS is deasserted and receive can happen. In this case the user space
doesn't even need to have a clue about RS485, although in most cases the
application already needed to know about RS485 so it may not be that
much of a gain, but it sure makes it more efficient to not have to wait
for the UART to drain the transmit FIFO.

I think having the user application control the send/receive switch
makes more sense than the driver, but perhaps it doesn't in your case.

--
Len Sorensen
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/