How To Use GPIOs
(Controlling LEDs)

Version 0.02
August 3, 2004

The PXA 255 has 85 GPIO (General Purpose Input Output) pins which are used to control and respond to various devices: serial IO, the USB host controller, PCMCIA buss, LEDs, switches, and many others. In combination with an oscilloscope or signal processor, they are invaluable for debugging. The GPIOs are managed by 27 registers that map specific behaviors to each pin: input, output, interrupt characteristics, alternate functions, and others. Detailed information can be found in:

This document provides a starting point for those interested in working with GPIOs. It begins with a look at using the command line interface to do some simple operations, followed by programmatic controls in user and kernel space. Finally, there is a description of LED specific interfaces.

 

Controlling GPIOs from the Command Line

GPIO control is mapped directly to the /proc file system making GPIO management easy. BE WARNED: Because GPIOs are used for communication between the PXA processor and critical Stargate components, changing the setting of a GPIO pin may have far reaching and  unexpected consequences.

As an example, let's begin with reading the state of switch 2. From the command line type the following:

Reading from GPIOs

echo r10 > /proc/platx/gpio/GPCTL               # create a gpio10 entry
cat /proc/platx/gpio/gpio10                     # read from GPIO pin 10

echo i10 > /proc/platx/gpio/GPCTL               # make GPIO pin 10 an input pin
                                                #   if s10 or c10 were used to set it

The echo command creates the gpio10 read entry for GPIO pin 10 in the proc file system. If you were to do an ls on /proc/platx/gpio before the echo command, GPCTL is the only entry. After the echo, you will also find the gpio10 entry. The cat reads the current state of pin 10 and displays a 0 if the button is pressed and 1 otherwise.

If, on the other hand, you want to set or clear the state of GPIO 10, you can enter the following commands.

Writing to GPIOs

echo s10 > /proc/platx/gpio/GPCTL               # set GPIO pin 10
echo c10 > /proc/platx/gpio/GPCTL               # clear GPIO pin 10

At first we may feel that we should not use GPIO 10 for output because it has a switch attached to it. As long as we do not close the switch when we have it set for output GPIO 10 can be used for other things. Soldering wires to the switch pins, and connecting an oscilloscope to these wires makes an effective debugging tool. Toggling a GPIO pin from a program has substantially less overhead than sending debug statements to the console or a file. In addition, the software component under test may not be able to send information to the file system or console. (See the sections on controlling GPIOs from C.)

 

 

If you want to set GPIO 10 to tri-state, you can enter the following command.

Setting Tri-state for GPIOs

echo i10 > /proc/platx/gpio/GPCTL             # set GPIO pin 10 to tri-state

 

You can find the code that implements this in the kernel:
    kernel/drivers/platx/gpiomon.c

 

Controlling GPIOs from a C Program in User Space

Controlling GPIOs from a C program is a mater of mapping our command line actions into file processing statements. For example, the following code reads from GPIO 10.

Reading from GPIOs

#define GPIO_CONTROL "/proc/platx/gpio/GPCTL"
#define SWITCH2 "/proc/platx/gpio/gpio10"
#define BUF_SIZE 4

...

int gpioControl;
gpioControl = open(GPIO_CONTROL, O_WRONLY|O_NOCTTY|O_NDELAY);
write (gpioControl,"r10", 3);
close (gpioControl);

int switch2;
char buffer[BUF_SIZE];
switch2 = open(SWITCH2, O_RDONLY|O_NOCTTY|O_NDELAY);
read(switch2, buffer, BUF_SIZE-1);
close(switch2);

A complete program that changes the LED pattern based on switch presses can be found here.

 

Controlling GPIOs from a C Program in Kernel Space

ToDo

 

Controlling GPIO Interrupts

ToDo

 

Controlling LEDs using the ledconfig Program (available in 7.2)

LEDs are connected to GPIOs and can be controlled with the techniques above.

LED color GPIO pin
red 62
green 63
yellow 64

However, it is much easier to control the LEDs using the ledconfig program. For example, to turn on the red LED you can type:

Turning on the red LED (green and yellow go off)

ledconfig -A                     # turn off auto mode
ledconfig -r                     # turn on the red LED

When controlling any of the GPIOs, you must be aware of any other program which may be setting or reading it.  For example, if you do not turn off the auto mode above, any changes you make to the LEDs will be short lived. Above, ledconfig is used to turn off LED control by one of the kernel processes. Be aware that there may be other processes, for example ledd, that are running in the background and controlling the LEDs.

ledconfig commands

-h               print help
-q               print which LEDs are on
-r               turn on red
-g               turn on green
-b               turn on yellow - once it was blue
-o               turn all LEDs off
-a               turn on auto mode
-A               turn off auto mode

 

Controlling LEDs using ioctl

We can also use the same techniques for controlling LEDs in C programs that we used for GPIO. However, this technique is not portable. The ioctl interface provides a better alternative. For example, to we can turn on the red LED as follows:

Turning on the red LED (green and yellow go off)

#include "led.h"

...

leds = open(LEDS, O_RDWR);
ioctl (leds, CLED_IOSTOPAUTO);
ioctl (leds, CLED_IOSET, RED);

A complete program that changes the LED pattern based on switch presses can be found here: readSwitch.c and led.h.

The following table shows additional LED ioctl features.

constant (led.h) semantics  example
GREEN
RED
YELLOW
Color constants <see below>
CLED_IOSET Set LED state

ioctl (leds, CLED_IOSET, RED);
ioctl (leds, CLED_IOSET, RED | YELLOW);

CLED_IOGET Get LED state

int color;
ioctl (leds, CLED_IOGET, &color);
printf ("%s %s %s\n",
  color & RED    ? "red"    : ".",
  color & GREEN  ? "green"  : ".",
  color & YELLOW ? "yellow" : ".");

CLED_IOSTARTAUTO Start the auto display pattern

ioctl (leds, CLED_IOSTARTAUTO);

CLED_IOSTOPAUTO Stop the auto display pattern

ioctl (leds, CLED_IOSTOPAUTO);

CLED_IOAUTOSTATUS Determine if the auto display pattern in set

int status;
ioctl (leds, CLED_IOAUTOSTATUS, &status);