Expanding GPIO outputs with a shift-register

Luiz Otavio O Souza lists.br at gmail.com
Sat Feb 26 13:16:22 UTC 2011


Hello folks,

I've been playing around with GPIO on a variety of devices (RS, RSPRO, TP-Link routers, ubiquiti devices, etc.) and some of them have a limited number of available gpio pins.

I've put together some information about using simple and cheap CMOS shift-and-store bus register (4094) to expand the GPIO outputs: http://loos.no-ip.org/routerstation/gpio-sr.html

You only need 3 available gpio pins (yes, it is not _that_ cheap ;)) and you can make up to 32 outputs (8 outputs per chip, up to 4 cascaded chips).

The same could be done for inputs, using a similar 4021 (but then you probably want something better, like a PCF8574 i2c gpio expander, which uses only two gpio pins... but we're talking about a cheap and straightforward solution this time...).

CAUTION: I've been using this schematic also as a level shifter (3.3v -> 5v), but the GPIO pins for RS/RSPRO are 3.3v _ONLY_, you have to avoid any 5v outputs to be connected on GPIO pins !

If you want to be on the safe side, please use the NXP bi-directional level shifter: http://www.nxp.com/news/backgrounders/bg_esc9727/index.html

Once you have everything in place, you should see something like this on your dmesg:

gpio0: <Atheros AR71XX GPIO driver> on apb0
gpio0: [GIANT-LOCKED]
gpioc0: <GPIO controller> on gpio0
gpiobus0: <GPIO bus> on gpio0
gpioled0: <GPIO led> at pin(s) 2 on gpiobus0
gpioshiftreg0: <GPIO Shift-Register expander> at pin(s) 5-7 on gpiobus0
gpioc1: <GPIO controller> on gpioshiftreg0
gpiobus1: <GPIO bus> on gpioshiftreg0

And then the output of gpioctl for the default pins and the shift-register outputs pins:

rspro-01# gpioctl -f /dev/gpioc0 -lv
pin 00: 1       GPIOpin1<IN>, caps:<IN,OUT>
pin 01: 1       GPIOpin2<IN>, caps:<IN,OUT>
pin 02: 0       RFled<OUT>, caps:<IN,OUT>
pin 03: 1       GPIOpin3<IN>, caps:<IN,OUT>
pin 04: 1       GPIOpin4<IN>, caps:<IN,OUT>
pin 05: 0       GPIOpin5<OUT>, caps:<IN,OUT>
pin 06: 1       GPIOpin6<OUT>, caps:<IN,OUT>
pin 07: 0       GPIOpin7<OUT>, caps:<IN,OUT>
pin 08: 1       SW4<IN>, caps:<IN,OUT>
rspro-01# gpioctl -f /dev/gpioc1 -lv
pin 00: 0       Output0<OUT>, caps:<OUT>
pin 01: 1       Output1<OUT>, caps:<OUT>
pin 02: 1       Output2<OUT>, caps:<OUT>
pin 03: 0       Output3<OUT>, caps:<OUT>
pin 04: 1       Output4<OUT>, caps:<OUT>
pin 05: 1       Output5<OUT>, caps:<OUT>
pin 06: 1       Output6<OUT>, caps:<OUT>
pin 07: 1       Output7<OUT>, caps:<OUT>

As an example, i've built a simple circuit to drive a HD44780 20X4 LCD display (using LCDProc from ports - the driver will be available soon):

http://loos.no-ip.org/routerstation/gpio.html
http://loos.no-ip.org/routerstation/images/16.html
http://loos.no-ip.org/routerstation/images/17.html
http://loos.no-ip.org/routerstation/images/18.html

I hope this could be useful for those who are starting with gpio.

Cheers,
Luiz


More information about the freebsd-embedded mailing list