Post date: Oct 29, 2013 6:59:44 AM
Most of GPIO capabilities of Galileo board are exposed through Linux Sysfs interface, and can be controlled using file based I/O. I will show how to use some of these capabilities using simple shell commands. Of course instead of shell you can implement I/O using file manipulations from your program written using your favorite programming language.
The following command gives information about GPIO in the system and shows if an IO port was allocated to a module or Sysfs (user).
root@clanton:~# cat /sys/kernel/debug/gpio
GPIOs 0-1, platform/sch_gpio.2398, sch_gpio_core:
GPIOs 2-7, platform/sch_gpio.2398, sch_gpio_resume:
GPIOs 8-15, intel_cln_gip_gpio:
gpio-8 Â (SPI_CSÂ Â Â Â Â Â Â ) out hi
gpio-10Â (SPI_CSÂ Â Â Â Â Â Â ) out hi
gpio-13 (cy8c9540a-int    ) in hi
GPIOs 16-55, cy8c9540a, can sleep:
As you can see from the output all the GPIOs of Galileo board is divided into 4 chunks:
GPIOs 0-1 - Intel Quark X1000 - GPIO[9:8] pins. These are GPIO pins on Legacy I/O bridge. They are powered and active in S0 state only.
GPIOs 2-7 - Intel Quark X1000 - GPIO_SUS[5:0] pins. These are GPIO pins on Legacy I/O bridge. They are powered and active in S3 (suspend) and S0 states.
GPIOs 8-15 - Intel Quark X1000 - GPIO[7:0] pins. These are GPIO pins on GPIO controller. They are powered and active in S0 state only.
GPIOs 16-55 - Cypress CY8C9540A I/O Expander
To make GPIO port controllable from sysfs you'll need to export it. This is done by writing GPIO port number to /sys/class/gpio/export:
root@clanton:~# echo -n "27" > /sys/class/gpio/export
When this operation completes successfully a directory corresponding to the GPIO port number will appear in sysfs. In this case /sys/class/gpio/gpio27. Once you finished working with I/O you should un-export it by writing the GPIO port number to /sys/class/gpio/unexport.
I/O direction is set by writing "in" (for input) or "out" (for output) to /sys/class/gpio/gpioXX/direction file.
root@clanton:~# echo -n "out" > /sys/class/gpio/gpio27/direction
When configured for output GPIO ports that are connected to CY8C9520A can be configured to one of the following drive modes:
Resistive high, strong low (drive = pullup)
This is the default, but it not suitable for driving devices that source significant current, for example for driving an LED connected between GPIO port and GND (it will work though if the LED is connected between GPIO and 5V or 3.3V rails)
Resistive low, strong high (drive = pulldown)
Strong low and high (drive = strong)
This mode is appropriate for most applications.
High Z state (drive = hiz)
(CY8C9520A also supports open drain and open source drive modes, but it is not currently exposed through SysFS)
The drive mode is set by writing the mode string ("pullup", "pulldown", "strong", or "hiz") to /sys/class/gpio/gpioXX/drive.
root@clanton:~# echo -n "strong" > /sys/class/gpio/gpio27/drive
When GPIO port is configured for input the input value (0 or 1) can be read from /sys/class/gpio/gpioXX/value file.
root@clanton:~# cat /sys/class/gpio/gpio27/value
0
When GPIO port is configured for output the output value can be written to the same file:
root@clanton:~# echo -n "1" > /sys/class/gpio/gpio27/value
root@clanton:~# echo -n "0" > /sys/class/gpio/gpio27/value
Pulse width modulation (PWM) is a technique of simulating an analog output signal using a digital signal switched on and off repeatedly for certain intervals. It is widely used to regulate intensity of LEDs, to control speed of DC motors, and so on.
root@clanton:~# cat /sys/class/pwm/pwmchip0/npwm
8
In Galileo all PWM outputs are implemented using Cypress CY8C9540A. It supports 8 PWM channels, but only 6 are used in Galileo. They are mapped as follows:
root@clanton:~# echo -n "3" > /sys/class/pwm/pwmchip0/export
This is very similar to exporting GPIO above. Same as with GPIO once a port is exported a corresponding directory with control files will appear in Sysfs: /sys/class/pwm/pwmchip0/pwm3/enable in this case. And just as with GPIO when PWM port is no longer needed it should be un-exported by writing the port number to /sys/class/pwmchip0/unexport.
To enable a PWM on a port write "1" to a corresponding enable file. To disable a port write "0".
root@clanton:~# echo -n "1" > /sys/class/pwm/pwmchip0/pwm3/enable
To set a PWM period write period in nanoseconds to period file. In example below it is set to 1000000 nanoseconds or 1 millisecond:
root@clanton:~# echo -n "1000000" > /sys/class/pwm/pwmchip0/pwm3/period
To set a PWM duty cycle write its length in nanoseconds to duty_cycle file. In example below we set duty cycle to 50% (500000/1000000*100%):
root@clanton:~# echo -n "500000" > /sys/class/pwm/pwmchip0/pwm3/duty_cycle
Analog inputs in Galileo implemented using Analog Devices AD7298 ADC IC. This IC has 8 channels, but only 6 channels are connected in Galileo. The resolution of each channel is 12 bit. So resulting values will be in range 0 - 4095. 0 - input voltage 0V (ground), 4095 - input equals 5V (power supply).
In Sysfs analog inputs can be read from /sys/bus/iio/devices/iio:device0/in_voltageX_raw files. Since analog inputs are multiplexed with GPIO and I2C (in case of A4 and A5) it is needed to enable analog input first. Multiplexers are controlled using regular GPIO pins. Example below shows how to do that for A0. Refer to the table below to find out corresponding multiplexer ports for other analog ports.
root@clanton:~# echo -n "37" > /sys/class/gpio/export
root@clanton:~# echo -n "out" > /sys/class/gpio/gpio37/direction
root@clanton:~# echo -n "0" > /sys/class/gpio/gpio37/value
First echo command exports GPIO port 37 which is used to control A0 multiplexer. Second echo command configures that GPIO for output. Third echo command connects A0 to ADC chip.
Once analog port is connected, its value can be read from Sysfs:
root@clanton:~# cat /sys/bus/iio/devices/iio\:device0/in_voltage0_raw
2593
In addition to regular I/O through Sysfs Galileo supports fast I/O on digital pins 2 and 3 which can be connected using multiplexer directly to Intel Quark X1000. The fast I/O is done using /dev/uio0 device. I haven't tested this functionality yet and will report it later.
Digital pins 10 - 13 can be connected to Intel Quark X1000's SPI1 interface. I am not sure yet if this interface is exposed to userspace. I need to investigate it.
Pins A4 and A5 and also SDA and SCL pins can be connected to Intel Quark X1000's I2C interface. Again I haven't tried this functionality yet.
This is probably the most important (and the most confusing) part of this post. It took me a while to parse the schematic and the supplied Arduino code to come up with this diagram and table. Hopefully it will tell you exactly what to do if you want to use some pins for certain function.
Labels on the left size indicate names of ports in SysFS GPIO and PWM (where applicable) interfaces, or Intel Quark X1000 connections: ttyS0 for the serial port signals; SPI1 for SPI interface signals, and I2C for I2C signals. ADC inputs are named vin0 to vin7 and correspond to /sys/bus/iio/devices/iio:device0/in_voltage0_raw - /sys/bus/iio/devices/iio:device0/in_voltage7_raw respectively.
Labels on the right side indicate names of Arduino shield ports.
The trapezoid shaped things are bidirectional multiplexers (or switches). They are controlled by the signal coming on the top (selector input). When the selector value is 0 it connects 0 pin on the left side of multiplexer to the pin on the right side of multiplexer; when the selector value is 1 it connects pin 1 on the left side to the pin on the right side. To give an example if you want to connect Arduino A1 pin to ADC vin1, you'll need to set gpio36 to "0".
(Click on the diagram to zoom in)