Bug 49039 - [sio] [patch] add support for RS485 hardware where direction is controlled by RTS line
Summary: [sio] [patch] add support for RS485 hardware where direction is controlled by...
Status: Closed Overcome By Events
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 4.7-RELEASE
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-03-08 23:10 UTC by Luuk van Dijk
Modified: 2017-08-26 03:43 UTC (History)
2 users (show)

See Also:


Attachments
file.diff (1.45 KB, patch)
2003-03-08 23:10 UTC, Luuk van Dijk
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Luuk van Dijk 2003-03-08 23:10:00 UTC
The abovementioned single board PC contains two 16550A's, one of which is
jumper-configurable to drive an RS485 line, instead of the traditional RS232.
The RS485 bus is much used in industrial environments: it is a two-line
interface, to which multiple senders and listeners can be connected.

The main difference from a software point of view is that the RS485 is half
duplex, and has to be switced from 'receive' to 'transmit' mode and back in
some way.  The designers of this board have chosen to use the RTS handshake
signal to drive rx/tx mode, a solution that also allows dirt-cheap (<10$)
home made converters from RS232 to RS485, with nothing but voltage level 
converters.
A full fledged RS232 to 485 converter on the other hand has to contain a
complete microcontroller to detect and decide which way the traffic flows,
which makes them far more expensive (>100$). 

Problem with this design is that the hardware has to be switched back to
receive mode fast enough not to lose data from responding parties on the
bus. In practice this is within a word-length of data on the bus.  By 
ioctl'ing and termios from userland, the timeresolution is about 10ms
which is way to slow.  the best solution is to do it deep in the interupt
handler for the serial port.  The patch below has been tested and works fine
at least at 9600 baud.

Fix: The patch below implements the desired behaviour on sio's that
have flag 0x04, but not 0x01 set in the kernel config (0x04 otherwise
only has meaning for multiport sio's, = 0x01  ). 
this way one can easily select at kernel compile time which ports
need this.  It is trivial to change this to use the DSR instead of RTS.
This is all for 4.7, as I haven't gotten around to 5.0 yet.

How-To-Repeat: 
connect an oscilloscope to an RS485 bus connected in the above described manner,
and initiate some traffic on the bus. You will notice bus contention by the
fact that the voltage changes, but doesn't change polarity.  This is because
one transmitter keeps the bus high, and the other tries to drive it low.
you really need a storage scope to study this stuff, so I was really lucky
to have borrowed one, otherwise I'd never have guessed why my RS485 didn't
work.