BeagleBone and GPIO pin mux’ing

On my last BeagleBone post I have a relay driven through a transistor, the base of which is connected through a 1k0 resister to the pin 24 on the P8 pin header.  So how do we drive this pin?

The AM335x ARM Cortex™-A8 Processor can do a load more than the BGA package has connectors for, so to get around this “hardware limitation”, the pins can be set up for different functions.. enter pin muxing.

First we need to make sure the pin we want to use is in the correct mode! For this you’ll need to manual for your BeagleBone (its the SRM or System Reference Manual your looking for.. for latest rev, you’ll find it here). On the A6 rev manual head to page 48 and on.

The names for the pins (signal names) are shown beside the pin outs for the header connectors P8 (table 8, page 48) and P9 (table 11, page 53). If you login to your BeagleBone (as root, sudo, su -l or what ever you need to do!), you will see all these signal names (for mode 0) in the folder /sys/kernel/debug/omap_mux.

For my relay pin I need to set this to mode 7 (from table 10, page 51) can see the mode 7 signal name is “gpio1[1]”.  To find out the current mode, type:

cat /sys/kernel/debug/omap_mux/gpmc_ad1

That should return three lines:

name: gpmc_ad1.gpio1_1 (0x44e10804/0x804 = 0x0007), b NA, t NA
signals: gpmc_ad1 | mmc1_dat1 | NA | NA | NA | NA | NA | gpio1_1

From this we know that the pin is in the correct mode (7).  If it was not in the correct mode or a change of mode is required then it’s easy:

echo <mode> > /sys/kernel/debug/omap_mux/gpmc_ad1

There is a little more that can be done with the mode number, internal pull up resistors can be enabled or disabled.  The mode is made up from the following byte:

Bit 0 \
Bit 1 |- Mode
Bit 2 /
Bit 3: 1 - Pull disabled, 0 - Pull enabled
Bit 4: 1 - Pull up, 0 - Pull down
Bit 5: 1 - Input, 0 - Output

There are 66 GPIO pins between the two headers. These are 4 controllers driving these pins GPIO0, GPIO1, GPIO2 and GPIO3. To configure a pin we need to use a simple formula to find out the software GPIO reference for it or the GPIO pin number.

The pins GPIO number is made up of two parts: 1) The chips base number, 2) the pin number itself.  It’s all in the pin label: GPIO<base>_<pin_no>.

GPIO pin number = <base> x 32 + <pin_no>

For the physical pin GPIO1_1 [P8, pin 24] the GPIO pin number is found via this formula:

GPIO pin number = 1 x 32 + 1 = 33

Now we need get this pin ready to do something..  All IO ports on the BeagleBone are mapped to the file system (such in the Unix model for IO).  The file system location for this action is here: /sys/class/gpio. Getting a GPIO pin ready is done by “exporting” it.

echo 33 > /sys/class/gpio/export

This will cause a new folder to exist in the gpio directory…

gpio33 -> ../../devices/virtual/gpio/gpio33

We can go in and have a look inside this folder:

-rw-r--r-- 1 root root 4096 Nov  7 15:43 active_low
-rw-r--r-- 1 root root 4096 Nov  7 15:43 direction
-rw-r--r-- 1 root root 4096 Nov  7 15:43 edge
drwxr-xr-x 2 root root    0 Nov  7 15:43 power
lrwxrwxrwx 1 root root    0 Nov  7 15:42 subsystem -> ../../../../class/gpio
-rw-r--r-- 1 root root 4096 Nov  7 15:42 uevent
-rw-r--r-- 1 root root 4096 Nov  7 15:51 value

Set up the direction of the pin:

echo out > direction

Want to turn the port on/high…? easy:

echo 1 > value

Off again…

echo 0 > value

See what state it’s in?

cat value

Cool… I can hear my relay clicking on and off in the lab!

Some more info on this can be found here: