GPIO

From Gumstix User Wiki
Jump to: navigation, search

Overo GPIO

The Overo kernels support the sysfs gpio implementation for accessing GPIO from userspace.

This allows you to control GPIO from the command line this way

root@overo# echo 146 > /sys/class/gpio/export
root@overo:/sys/class/gpio# cat gpio146/direction
in
root@overo# echo out > /sys/class/gpio/gpio146/direction
root@overo:/sys/class/gpio# cat gpio146/direction
out
root@overo# cat /sys/class/gpio/gpio146/value
0
root@overo# echo 1 > /sys/class/gpio/gpio146/value
root@overo# cat /sys/class/gpio/gpio146/value
1

If you have an expansion card with a 40 pin header, then this will be controlling pin 27. You can use pin 1 for a ground. (If you don't have a meter, a p/n 276-0330 1.8V Red LED from Radio Shack works for testing.)

Schematics and pin-outs for the Gumstix expansion boards can be found here.

How It Works

See the kernel docs gpio.txt for an overview of gpio and the userspace sysfs interface. The "Sysfs Interface for Userspace (OPTIONAL)" section near the end discusses the userspace implementation.

See the OMAP35X Technical Reference Manual Section 7.6.3 PADCONFS Register Description and Table 7.5 Core Control Module PadConf Register Field in Section 7.4.4.3 Pad Multiplexing Register Fields for identifying the possible MUX configuration for each GPIO. For OVERO DM3730 see the Technical Reference Manual Section 13.6.3.2 PADCONFS Register Description.

Then see the U-Boot source code, board/overo/overo.h for how the pins on the Overo are actually being muxed. See include/asm-arm/arch-omap3/mux.h in the U-Boot tree for the definitions used in overo.h. The pins in mux mode M4 are already configured for GPIO.

Making Modifications

Currently all the GPIO multiplexing for the Overo's is being done by the bootloader U-Boot, so the conventional way to modify the pin muxing is to edit overo.h and rebuild U-Boot.

You can also change the mux configuration from within Linux. One simple approach is to do it from userspace accessing /dev/mem. A program devmem2 is part of the omap3-console-image and will work. See the remuxing example below.

If you are writing your own kernel module, you can also read/write the PADCONF registers the way you normally would after an ioremap.

Third, there is a Linux build config option CONFIG_OMAP_MUX, not normally enabled in the Overo configs, that will give you some additional utility functions to simplify mux changes within kernel or module code (see arch/arm/plat-omap/mux.c).

Finally, it looks like the Linux OMAP34xx pin muxing code is getting a complete overhaul. See this thread on the Linux OMAP mailing list. Judging from some posts on the Gumstix lists, it sounds like this will be available in 2.6.33.

Overo Kernel Usage

Just because pins are configured as GPIO in u-boot, doesn't necessarily mean you can use them. If you look at /sys/class/gpio on a default Overo, you'll get something like this.

root@overo:~# ls /sys/class/gpio
export	gpio164  gpio65       gpiochip160  gpiochip64
gpio15	gpio168  gpiochip0    gpiochip192  gpiochip96
gpio16	gpio176  gpiochip128  gpiochip32   unexport

The reason you see some GPIO already exported is because the linux code in arch/arm/mach-omap2/board-overo.c is explicitly exporting these pins for another use. Whether they are being used depends on the hardware you have attached. The kernel also uses pins configured as GPIO that it doesn't export. These depend on the board configuration and the kernel drivers being used.

To be more explicit, look inside board-overo.c, you'll see these definitions

#define OVERO_GPIO_BT_XGATE     15
#define OVERO_GPIO_W2W_NRESET   16
#define OVERO_GPIO_PENDOWN      114
#define OVERO_GPIO_BT_NRESET    164
#define OVERO_GPIO_USBH_CPEN    168
#define OVERO_GPIO_USBH_NRESET  183
...
#define OVERO_SMSC911X_GPIO    176
#define OVERO_SMSC911X2_GPIO   65
...
#define OVERO_GPIO_LCD_EN 144
#define OVERO_GPIO_LCD_BL 145

Follow their usage inside the file and you will be able to explain the /sys/class/gpio output you see above.

Input or Output

Pins configured as GPIO are sometimes also specified as being strictly input or output.

This can happen when they are mux'd or when they are explicitly exported by the kernel.

In either of those cases you won't be able to change the I/O direction from userspace.

Electrical Specifications

Voltage is 1.8v

Current specifications <TODO ???>

Usable Pins

Here's a few GPIO you can use immediately from userspace without any u-boot or kernel changes. It will however require that the specific GPIO isn't used by the attached expansion board.

40 Pin Expansion Header

Pin 4 - gpio114
It's the pendown signal on the touchscreen controller but it's available if you aren't using a expansion board with touchscreen support.
This pin can not be configured as output, it is input only (see OMAP35X Technical Reference Manual p. 3389). Pulled-low, reads 0 with no input, reads 1 with an input applied

Pin 19 - gpio170
The HDQ/1-Wire output. Not used unless you explicitly enable the 1-wire module.
User exportable
Output only - configured this way in the u-boot muxing

Pin 27 - gpio146
Pin 29 - gpio147
User exportable
Direction can be changed
Floating state

Pin 28 - gpio145
Pin 30 - gpio144
Used with LCD, but available if not using an LCD
Configured as output only when exported by the kernel in board-overo.h. Can't change direction from userspace without modifying kernel.
Set to ON by kernel during init (not all configs, see board-overo.c). This could be a problem for real use, but okay for testing.

Palo43 Board

LED D2 - gpio21
LED D3 - gpio22
Userspace exportable, set the direction as out
echo 0 > gpioxx/value to turn on, echo 1 > gpioxx/value to turn off

Switch - gpio14
Switch - gpio23
Userspace exportable, leave direction as in
With the switch open (not pushed) will register a value of 1
Push the switch and the value will be 0

Example: Changing the multiplexing for a pin

If you aren't using the first SPI bus, then there are 5 pins on the 40-pin expansion header that you could repurpose for GPIO.

Pin 3 - gpio171(spi1_clk)
Pin 5 - gpio172 (spi1_mosi)
Pin 6 - gpio174 (spi1_cs0)
Pin 7 - gpio173 (spi1_miso)
Pin 8 - gpio175 (spi1_cs1)

The first step is to find the appropriate PADCONF register address for each gpio from Table 7.5 of the TRM. Pay attention to whether it is the low or high order 16 bits for each gpio. You should come up with these values.

gpio171 : 0x4800 21C8
gpio172 : 0x4800 21CA
gpio173 : 0x4800 21CC
gpio174 : 0x4800 21CE
gpio175 : 0x4800 21D0

Using devmem2, here is how you could read the current PADCONF value for what could be gpio171

root@overo# devmem2 0x480021c8 h
...
Value at address 0x480021C8 (0x400201c8): 0x100

Which corresponds to a mux value of (IEN | PTD | DIS | M0) using the U-Boot mux.h definitions. Mux mode 0 for this pin is the spi1_clk configuration found by looking in Table 7.5 of the TRM.

To reconfigure pin 3 to be gpio171, as input or output with inputs pulled low, write 0x010C to the controlling PADCONF register. This would correspond to (IEN | PTD | EN | M4). The bit fields are defined in the TRM Section 7.6.3.

root@overo# devmem2 0x480021c8 h 0x10c

Now you can export and configure gpio171 from userspace like the example with gpio146 at the beginning. To make it visible in sysfs:

echo 172 > /sys/class/gpio/export

If you want this multiplexing to be permanent, then you would modify the U-Boot file board/overo/overo.h and rebuild U-Boot. If you are using OE, then you'll want to generate a patch file to be used in the u-boot-omap3 recipe.

There are additional pins on the header that can be reconfigured this way.

To reconfigure pins from within a kernel module the following code can be used:

void *addr = ioremap(spi1_clk, 4);
if (!addr)
{
 printk("Cannot ioremap 0x%lx\n", spi1_clk);
} else {
 printk("ioremap OK:  0x%lx\n", spi1_clk);
 iowrite32( 0x010C | (0x010C << 16), addr);
 iounmap(addr);
}

This will make both gpio171 and gpio172 input or output with inputs pulled low.

Interrupts on GPIO pins

Here is an example on setting up an interrupt on GPIO pin 23 from within a kernel module:

irqreturn_t gpio_irq_handler(int irq, void *dev_id) {
 static int cnt=0;
 printk("gpio_irq_handler %i\n", cnt++);
 return IRQ_HANDLED;
}

int gpio_irq= gpio_to_irq(23);
int ret = request_irq(gpio_irq, gpio_irq_handler, IRQF_TRIGGER_FALLING, "gpio irq handler", gpio_irq_handler);
if (ret)
 printk("gpio interrupt request failed\n");
else
 printk("gpio interrupt request succeeded\n");

GPIO Software for the Overo

Dave Hylands has written several software packages to facilitate GPIO programming on the Overos.

GPIO Event Driver allows multiple GPIO lines to be monitored from user-space.

User GPIO Driver is a reflection of the kernel's gpiolib API into user space.

More Links

Here is another article BeagleBoardPinMux talking about OMAP3 pin muxing.

Verdex GPIO

GPIO( n )


  • Logic level (3.3V) signals
  • 3-4mA max


all GPIO's information and examples should go here


todo


According to the PXA270 datasheet: http://pubs.gumstix.com/documents/PXA%20Documentation/PXA270/PXA270%20Electrical,%20Mechanical,%20and%20Thermal%20Specification%20%5b280002-005%5d.pdf most of the pins are limited to 3mA, and a few can go upto 4 mA (see page 5-9)




Accessing GPIO's from userland

If proc-gpio is a module, add it to /etc/modules or do a modprobe proc-gpio.

A number of files exist under /proc/gpio, one for each GPIO on the PXA processor.

If you cat one of these files, you get, eg:

# cat /proc/gpio/GPIO12
12 GPIO in set

That tells you — GPIO number, function (either GPIO, AF 1, AF 2, or AF 3), in|out, set|clear.

You can change any of those values, by writing to the file, eg:

# echo "AF1 out" > /proc/gpio/GPIO12

This sets GPIO12 to AF1, out mode. (In the case of GPIO12, the PXA defines this function as putting out the 32kHz clock signal.) this is currently case-sensitive

If you have the GPIO set to an output, and GPIO mode, you can set or clear the signal:

# echo "GPIO out set" > /proc/gpio/GPIO12
# echo "GPIO out clear" > /proc/gpio/GPIO12

The alternative functions are described in the PXA255 Developer's Manual (link should be found in the Featured links-box) section 4.1.2.

Alternative method to access GPIO's from userland

The User GPIO Driver provides a reflection of the kernel's gpiolib library into userspace.

gpio-event driver

The GPIO Event Driver allows gpio changes to be captured from user-space.