Date: Sun, 12 Sep 1999 00:02:53 +0200 (CEST) From: hmo@sep.hamburg.com (Helge Oldach) To: freebsd-doc@freebsd.org Cc: j@ida.interface-business.de Subject: 12.4.3.2.3. Support for Cheap Multi-UART Cards Message-ID: <199909112202.AAA05385@sep.hamburg.com>
next in thread | raw e-mail | index | archive | help
Folks, here is a chapter for The Handbook concerning cheap multi-UART cards. Hope the chapter numbering is still right, please change ad lib. 12.4.3.2.3. Support for Cheap Multi-UART Cards Ever wondered about FreeBSD support for your 20$ multi-I/O card with two (ore more) COM ports, sharing IRQs? Here's how: Usually the only option to support these kind of boards is to use a distinct IRQ for each port. For example, if your CPU board has an on-board COM1 port (aka sio0 - I/O address 0x3F8 and IRQ 4) and you have an extension board with two UARTs, you'll commonly need to configure them as COM2 (aka sio1 - I/O address 0x2F8 and IRQ 3), and the third port (aka sio2) as I/O 0x3E8 and IRQ 5. Obviously this is a waste of IRQ ressources, as it should be basically possible to run both extension board ports using a single IRQ with the COM_MULTIPORT configuration described in the previous sections. Such cheap I/O boards commonly have a 4 by 3 jumper matrix for the COM ports, similar to the following: o o o * Port A | o * o * Port B | o * o o IRQ 2 3 4 5 Shown here is port A wired for IRQ 5 and port B wired for IRQ 3. The IRQ columns on your specific board may vary - other boards may supply jumpers for IRQs 3, 4, 5, and 7 instead. One could conclude that wiring both ports for IRQ 3 using a handcrafted wire-made jumper covering all three connection points in the IRQ 3 column would solve the issue, but nope: You cannot duplicate IRQ 3 because the output drivers of each UART are wired in a "totem pole" fashion, so if one of the UARTs drives IRQ 3, the output signal won't be what you would expect. Depending on the implementation of the extension board or your motherboard, the IRQ 3 line will continuously stay up, or always stay low. Solution: You need to decouple the IRQ drivers for the two UARTs, so that the IRQ line of the board only goes up if (and only if) one of the UARTs asserts a IRQ, and stays low otherwise. The solution was proposed by Jörg Wunsch <j@ida.interface-business.de>: To solder up a wired-or consisting of two diodes (Germanium or Schottky-types strongly preferred) and a 1 kOhm resistor. Here's the schematic, starting from the 4 by 3 jumper field above: Diode +---------->|-------+ / | o * o o | 1 kOhm Port A +----|######|-------+ o * o o | | Port B `-------------------+ ==+== o * o o | Ground \ | +--------->|-------+ IRQ 2 3 4 5 Diode The cathodes of the diodes are connected to a common point, together with a 1 kOhm pull-down resistor. It is essential to connect the resistor to ground to avoid floating of the IRQ line on the bus. Now we're ready to configure a kernel. Staying with this example, we would configure: # standard on-board COM1 port device sio0 at isa? port "IO_COM1" tty flags 0x10 # patched-up multi-I/O extension board options COM_MULTIPORT device sio1 at isa? port "IO_COM2" tty flags 0x205 device sio2 at isa? port "IO_COM3" tty flags 0x205 irq 3 Note that the "flags" setting for sio1 and sio2 is truely essential; refer to sio(4) for details. (Generally, the "2" in the "flags" attribute refers to "sio2" which holds the IRQ, and you surely want a "5" low nibble.) With kernel verbose mode turned on this should yield something similar to this: sio0: irq maps: 0x1 0x11 0x1 0x1 sio0 at 0x3f8-0x3ff irq 4 flags 0x10 on isa sio0: type 16550A sio1: irq maps: 0x1 0x9 0x1 0x1 sio1 at 0x2f8-0x2ff flags 0x205 on isa sio1: type 16550A (multiport) sio2: irq maps: 0x1 0x9 0x1 0x1 sio2 at 0x3e8-0x3ef irq 3 flags 0x205 on isa sio2: type 16550A (multiport master) Though /sys/i386/isa/sio.c is somewhat cryptic with its use of the "irq maps" array above, the basic idea is that you observe 0x1 in the first, third, and fourth place. This means that the corresponding IRQ was set upon output and cleared after, which is just what we would expect. If your kernel doesn't display this behaviour, most likely there is something wrong with your wiring. Regards, Helge To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-doc" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199909112202.AAA05385>