This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Half Duplex RS485


On 2008-01-23, Laurie Gellatly <laurie.gellatly@netic.com> wrote:

>>I imagine that RTS is shutting off too soon.  The problem is
>>that pc_serial_stop_xmit() is called when the driver has no
>>more data to send _to_ the UART.  That's not when you need to
>>shut off RTS.  You need to shut off RTS when the UART is done
>>sending data and both the FIFO and shift register are empty.
>>
>>You're probably shutting off RTS while the UART still has data
>>in the tx FIFO and the tx shift register.
> 
> Funny thing is that it appears that the first part of the 
> transmission is lost.

Ah. 

If you look at io/serial.c, you can see that the serial_write()
function calls start_xmit() _after_ it's done filling up the
UART's tx fifo (the UART will start sending when the first byte
is written to the tx fifo).  RTS needs to be asserted before
any data is written to the tx fifo.  That means that
start_xmit() is being called too late: the first byte is
already on it's way out of the UART before start_xmit() is
called.  If your protocol allows it, adding an extra "idle"
byte to the beginning of the message will probably fix that.

Off the top of my head, here are a couple other options:

 1) Add code to the low-level driver's putc() method that
    asserts RTS _before_ it transfers the byte to the UART tx
    fifo.

 2) Add another driver hook that is called by serial_write()
    before it fills the tx fifo.

 3) Always leave the UART in a mode where the transmit logic is
    disabled until it's enabled by a call to start_xmit(). IOW,
    when the last bit it in a transmission has been sent not
    only do you de-assert RTS, you also shut off the UART's
    transmit hw so that the next time somebody fills up the tx
    fifo nothing goes out until start_xmit() is called.

Number 1) is probably the simplest.
    
> Grant, do you know if the LPC series have 'broken' UARTS?
> Specifically LPC2212 and LPC2103? U0TSR looks promising as an
> indication of when the bits 'have left the building' - is it
> accurate or do I need to add a time delay?

I don't know -- I've never worked with the LPC parts.  The vast
majority of the the parts I've used have been OK (many don't
provide an interrupt, but at least the status bit worked
correctly when polled).  IIRC, the ones that I had problems
with were a UART in one of Motorola's old uControllers (don't
remember which one, but it was from about 10-15 years ago) and
a couple different PC motherboard chipsets.

At one point I modified the Linux PC UART driver to support
half-duplex operation, but it never worked reliably, so I just
gave up and bought serial cards that had UARTs which supported
half-duplex mode.  Now that I think about it, I also built a
little 9-pin pass-through dongle with a one-shot in it that
controlled RTS.  It worked pretty well also (for the one baud
rate it was designed for), but since the first bit was usually
mangled, it only worked on protocols where the messages had
training preambles.

-- 
Grant Edwards                   grante             Yow! We are now enjoying
                                  at               total mutual interaction in
                               visi.com            an imaginary hot tub ...


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]