The external Interface

When you disassemble your unit you will find some solder pads right behind the IDE connector. This thread at www.openwrt.org shows the pinout and some pics and howto attach a UART-Chip there.

The pinout:

----------
> D0  D1 |
| D2  D3 |
| D4  D5 |
| D6  D7 |
| A0  A1 |
| A2  A3 |
|+5V /CS |
|/RD /WR |
|INT GND |
| NC  NC |
----------
where:
D0 - D7: are the data lines
A0 - A3: are the address lines
+5V: +5V Supply Voltage
/CS: chip select (active low)
/RD: read strobe (avtice low)
/WR: write strobe (active low)
INT: Interrupt input
GND: Signal Ground
NC: Not connected

Note: all signals are 3.3V signals!

But adding a UART

EXT_IF -> UART -> uC -> Display & Keys

is somehow stupid. Because it could look like that:

EXT_IF -> Display & Keys

So I started reading though the kernel sources and found the UART initialisation process in sbmips.c somewhere in the arch/mips/bcm9….. directory. But the function that where used like sb_gpioin didn’t leed me to success.

So i had a look at gpio.c (same directory as above). This is a kernel module for accessing GPIO (general purpose input output). Here the sb_gpioin and so functions were used again. I tried to hack some new lines there but, let us go to the next try:

kmod-diag: OpenWRT comes with a small module that is used to turn on/off the LED’s and to fetch some keypresses. While reading the source (diag.c) I realized the function: set_led_extif.

volatile u8 *addr = (volatile u8 *) KSEG1ADDR(EXTIF_UART) + (led->gpio & ~GPIO_TYPE_MASK);

The adress of the external interface is between 0xBF800000 and 0xBF80000F. Only the low nibble (the 0x0-0xF) will be seen at the external interface on address lines A0-A3.

volatile u8 *addr = (volatile u8 *) KSEG1ADDR(EXTIF_UART) + (address & 0x0F);

Where address is the low nibble. Using the pointer *addr data can be read and written.

*addr = 0xFF; // write 0xFF data = *addr; // read data

So that’s the trick.

But what do /WR, /RD and /CS do?

/WR: The slash (“/”) before the signals name tells you that the signal is active low. This means if a write transfer is handled by the bus this signals changes from HIGH to LOW before the transmission and changes back to HIGH after the transmission.

/RD: Same as above but signals that it’s a read instead of a write operation.

/CS: This signal goes low whenever an address between 0xBF800000 and 0xBF80000F is read or written. This additional signal is necassary do differ between for example 0xBF80000A and 0x2AD3456A (because only the last nibble the “A” would be seen on the address lines A0-A3).

Leave a Reply

Your email address will not be published. Required fields are marked *


4 × four =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>