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.
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 |
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 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; |
A complete program that changes the LED pattern based on switch presses can be found here.
ToDo
ToDo
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 |
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); |
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); |
CLED_IOGET | Get LED state |
int color; |
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; |