|
|
(One intermediate revision by the same user not shown) |
Line 1: |
Line 1: |
| <!-- Set release according to "release" parameter in URL and use RELEASE_SUMO_V1.0_VAR-SOM-MX8X as default
| | {{GPIO_SYSFS_DRAFT}} |
| --> {{#vardefine:RELEASE_PARAM|{{#urlget:release}}}} <!--
| |
| --> {{#lst:Yocto_Platform_Customization|{{#var:RELEASE_PARAM|RELEASE_SUMO_V1.0_VAR-SOM-MX8X}}}} <!--
| |
| --> {{PageHeader|{{#var:HARDWARE_NAME}} GPIO}} {{DocImage|category1=Yocto|category2={{#var:HARDWARE_NAME}}}} __toc__
| |
| | |
| = GPIO state =
| |
| The current state of the system's GPIOs can be obtained in user-mode, as shown in the following example:
| |
| {{#ifeq: {{#var:HARDWARE_NAME}} | VAR-SOM-MX8X |
| |
| <pre>
| |
| # cat /sys/kernel/debug/gpio
| |
| gpiochip0: GPIOs 0-31, parent: platform/5d080000.gpio, 5d080000.gpio:
| |
| gpio-12 ( |ov5640_mipi_reset ) out hi
| |
| gpio-16 ( |fsl_lpspi ) in hi
| |
| gpio-26 ( |ov5640_mipi_pwdn ) out lo
| |
| | |
| gpiochip1: GPIOs 32-63, parent: platform/5d090000.gpio, 5d090000.gpio:
| |
| gpio-32 ( |fsl_lpspi ) in hi
| |
| gpio-34 ( |phy-reset ) out hi
| |
| gpio-39 ( |reg_sd_pwr ) out hi
| |
| gpio-60 ( |reg_ethphy0 ) out hi
| |
| | |
| gpiochip2: GPIOs 64-95, parent: platform/5d0a0000.gpio, 5d0a0000.gpio:
| |
| | |
| gpiochip3: GPIOs 96-127, parent: platform/5d0b0000.gpio, 5d0b0000.gpio:
| |
| gpio-120 ( |cam_buf_en ) out hi
| |
| | |
| gpiochip4: GPIOs 128-159, parent: platform/5d0c0000.gpio, 5d0c0000.gpio:
| |
| gpio-149 ( |usb_otg1_vbus ) out hi
| |
| gpio-150 ( |cd ) in lo IRQ
| |
| | |
| gpiochip5: GPIOs 160-191, parent: platform/5d0d0000.gpio, 5d0d0000.gpio:
| |
| gpio-169 ( |connect ) in hi IRQ
| |
| | |
| gpiochip6: GPIOs 192-223, parent: platform/5d0e0000.gpio, 5d0e0000.gpio:
| |
| | |
| gpiochip7: GPIOs 224-255, parent: platform/5d0f0000.gpio, 5d0f0000.gpio:
| |
| | |
| gpiochip8: GPIOs 504-511, parent: i2c/1-0020, pca9534, can sleep:
| |
| gpio-504 ( |heartbeat ) out lo
| |
| gpio-505 ( |Back ) in hi IRQ
| |
| gpio-506 ( |Home ) in hi IRQ
| |
| gpio-507 ( |Menu ) in hi IRQ
| |
| gpio-508 ( |usb3_sel ) out lo
| |
| gpio-509 ( |phy-reset ) out hi
| |
| gpio-510 ( |reg_vselect ) out hi
| |
| gpio-511 ( |reg_ethphy1 ) out hi
| |
| </pre>
| |
| |
| |
| <pre>
| |
| # cat /sys/kernel/debug/gpio
| |
| gpiochip0: GPIOs 0-31, parent: platform/5d080000.gpio, 5d080000.gpio:
| |
| gpio-14 ( |cd ) in lo IRQ
| |
| gpio-18 ( |usb_otg1_vbus ) out hi
| |
| gpio-22 ( |cam_buf_en ) out hi
| |
| gpio-30 ( |sysfs ) out hi
| |
| | |
| gpiochip1: GPIOs 32-63, parent: platform/5d090000.gpio, 5d090000.gpio:
| |
| gpio-54 ( |hdmi_i2c_signal_rout) out lo
| |
| | |
| gpiochip2: GPIOs 64-95, parent: platform/5d0a0000.gpio, 5d0a0000.gpio:
| |
| gpio-77 ( |ads7846_pendown ) in hi IRQ
| |
| gpio-92 ( |phy-reset ) out hi
| |
| | |
| gpiochip3: GPIOs 96-127, parent: platform/5d0b0000.gpio, 5d0b0000.gpio:
| |
| gpio-100 ( |ov5640_mipi_pwdn ) out lo
| |
| gpio-102 ( |ov5640_mipi_reset ) out hi
| |
| gpio-106 ( |fsl_lpspi ) out hi
| |
| gpio-107 ( |connect ) in hi IRQ
| |
| gpio-120 ( |fsl_lpspi ) in hi
| |
| | |
| gpiochip4: GPIOs 128-159, parent: platform/5d0c0000.gpio, 5d0c0000.gpio:
| |
| gpio-154 ( |sysfs ) out lo
| |
| | |
| gpiochip5: GPIOs 160-191, parent: platform/5d0d0000.gpio, 5d0d0000.gpio:
| |
| | |
| gpiochip6: GPIOs 192-223, parent: platform/5d0e0000.gpio, 5d0e0000.gpio:
| |
| | |
| gpiochip7: GPIOs 224-255, parent: platform/5d0f0000.gpio, 5d0f0000.gpio:
| |
| | |
| gpiochip8: GPIOs 504-511, parent: i2c/1-0020, pca9534, can sleep:
| |
| gpio-504 ( |heartbeat ) out hi
| |
| gpio-505 ( |Back ) in hi IRQ
| |
| gpio-506 ( |Home ) in hi IRQ
| |
| gpio-507 ( |Menu ) in hi IRQ
| |
| gpio-508 ( |usb3_signal_route ) out lo
| |
| gpio-509 ( |phy-reset ) out hi
| |
| gpio-510 ( |reg_vselect ) out hi
| |
| gpio-511 ( |reg_ethphy1 ) out hi
| |
| </pre>
| |
| }}
| |
| | |
| Each GPIO is defined as in or out and the state is shown as lo or hi.<br>
| |
| For example pin {{#ifeq: {{#var:HARDWARE_NAME}}|VAR-SOM-MX8X|150|44}} is the SD card card-detect.
| |
| When an SD card is plugged in, the state will be:
| |
| | |
| gpio-{{#ifeq: {{#var:HARDWARE_NAME}}|VAR-SOM-MX8X|150|44}} ( |cd ) in lo IRQ
| |
| | |
| When the SD card is removed, the state will be:
| |
| | |
| gpio-{{#ifeq: {{#var:HARDWARE_NAME}}|VAR-SOM-MX8X|150|44}} ( |cd ) in hi IRQ
| |
| | |
| = Manipulating a single GPIO via /sys/class/gpio =
| |
| == Using a command line or a script ==
| |
| GPIOs in i.MX are grouped in groups of 32 pins.<br>
| |
| For example, GPIO0_3 belongs to the first group, pin 3. Its absolute number will be 3.<br>
| |
| GPIO4_21 will be 4*32+21=149.<br>
| |
| Assuming this GPIO is defined in your device tree, the following is an example of how to use it from userspace.<br>
| |
| <br>
| |
| To export the GPIO for userspace use:
| |
| <pre>
| |
| # echo 149 > /sys/class/gpio/export
| |
| </pre>
| |
| <br>
| |
| To configure as output:
| |
| <pre>
| |
| # echo out > /sys/class/gpio/gpio149/direction
| |
| </pre>
| |
| Set GPIO high:
| |
| <pre>
| |
| # echo 1 > /sys/class/gpio/gpio149/value
| |
| </pre>
| |
| Set GPIO low:
| |
| <pre>
| |
| # echo 0 > /sys/class/gpio/gpio149/value
| |
| </pre>
| |
| <br>
| |
| To configure as input:
| |
| <pre>
| |
| # echo in > /sys/class/gpio/gpio149/direction
| |
| </pre>
| |
| Read the current value:
| |
| <pre>
| |
| # cat /sys/class/gpio/gpio149/value
| |
| </pre>
| |
| <br>
| |
| To free the GPIO after you're done using it:
| |
| <pre>
| |
| # echo 149 > /sys/class/gpio/unexport
| |
| </pre>
| |
| | |
| == Using a C application ==
| |
| All of the command line operations above can be translated to C code:<br>
| |
| Reserve (export) the GPIO:<br>
| |
| <pre>
| |
| #define IMX_GPIO_NR(port, index) ((port)*32)+((index)&31))
| |
| | |
| int fd;
| |
| char buf[MAX_BUF];
| |
| int gpio = IMX_GPIO_NR(4, 21); /* Just an example */
| |
| | |
| fd = open("/sys/class/gpio/export", O_WRONLY);
| |
| | |
| sprintf(buf, "%d", gpio);
| |
| | |
| write(fd, buf, strlen(buf));
| |
| | |
| close(fd);
| |
| </pre>
| |
| Set the GPIO direction:<br>
| |
| <pre>
| |
| sprintf(buf, "/sys/class/gpio/gpio%d/direction", gpio);
| |
| | |
| fd = open(buf, O_WRONLY);
| |
| | |
| /* Set out direction */
| |
| write(fd, "out", 3);
| |
| /* Set in direction */
| |
| write(fd, "in", 2);
| |
| | |
| close(fd);
| |
| </pre>
| |
| | |
| In case of out direction set the GPIO value:
| |
| <pre>
| |
| sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);
| |
| | |
| fd = open(buf, O_WRONLY);
| |
| | |
| /* Set GPIO high status */
| |
| write(fd, "1", 1);
| |
| /* Set GPIO low status */
| |
| write(fd, "0", 1);
| |
| | |
| close(fd);
| |
| </pre>
| |
| | |
| In case of in direction get the current GPIO value:
| |
| <pre>
| |
| char value;
| |
| | |
| sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);
| |
| | |
| fd = open(buf, O_RDONLY);
| |
| | |
| read(fd, &value, 1);
| |
| | |
| if (value == '0') {
| |
| /* Current GPIO status low */
| |
| } else { | |
| /* Current GPIO status high */
| |
| } | |
| | |
| close(fd);
| |
| </pre>
| |
| | |
| Once finished, free (unexport) the GPIO:
| |
| <pre>
| |
| fd = open("/sys/class/gpio/unexport", O_WRONLY);
| |
| | |
| sprintf(buf, "%d", gpio);
| |
| | |
| write(fd, buf, strlen(buf));
| |
| | |
| close(fd);
| |
| </pre>
| |
| | |
| Important notes:<br>
| |
| * Remember that after the first read operation, the file pointer will move to the next position in the file, so to get a correct value for each read operation you simply have to set the file pointer at the beginning of the file before reading by using the following command:
| |
| <pre>
| |
| lseek(fd, 0, SEEK_SET);
| |
| </pre>
| |
| * This is only a short example. If you want to use it in your code, remember to add error handling to it.
| |
Manipulating a single GPIO via /sys/class/gpio
Using a command line or a script
GPIOs in i.MX are grouped in groups of 32 pins.
For example, GPIO0_3 belongs to the first group, pin 3. Its absolute number will be 3.
GPIO4_21 will be 4*32+21=149.
Assuming this GPIO is defined in your device tree, the following is an example of how to use it from userspace.
To export the GPIO for userspace use:
# echo 149 > /sys/class/gpio/export
To configure as output:
# echo out > /sys/class/gpio/gpio149/direction
Set GPIO high:
# echo 1 > /sys/class/gpio/gpio149/value
Set GPIO low:
# echo 0 > /sys/class/gpio/gpio149/value
To configure as input:
# echo in > /sys/class/gpio/gpio149/direction
Read the current value:
# cat /sys/class/gpio/gpio149/value
To free the GPIO after you're done using it:
# echo 149 > /sys/class/gpio/unexport
Using a C application
All of the command line operations above can be translated to C code:
Reserve (export) the GPIO:
#define IMX_GPIO_NR(port, index) ((port)*32)+((index)&31))
int fd;
char buf[MAX_BUF];
int gpio = IMX_GPIO_NR(4, 21); /* Just an example */
fd = open("/sys/class/gpio/export", O_WRONLY);
sprintf(buf, "%d", gpio);
write(fd, buf, strlen(buf));
close(fd);
Set the GPIO direction:
sprintf(buf, "/sys/class/gpio/gpio%d/direction", gpio);
fd = open(buf, O_WRONLY);
/* Set out direction */
write(fd, "out", 3);
/* Set in direction */
write(fd, "in", 2);
close(fd);
In case of out direction set the GPIO value:
sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);
fd = open(buf, O_WRONLY);
/* Set GPIO high status */
write(fd, "1", 1);
/* Set GPIO low status */
write(fd, "0", 1);
close(fd);
In case of in direction get the current GPIO value:
char value;
sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);
fd = open(buf, O_RDONLY);
read(fd, &value, 1);
if (value == '0') {
/* Current GPIO status low */
} else {
/* Current GPIO status high */
}
close(fd);
Once finished, free (unexport) the GPIO:
fd = open("/sys/class/gpio/unexport", O_WRONLY);
sprintf(buf, "%d", gpio);
write(fd, buf, strlen(buf));
close(fd);
Important notes:
- Remember that after the first read operation, the file pointer will move to the next position in the file, so to get a correct value for each read operation you simply have to set the file pointer at the beginning of the file before reading by using the following command:
lseek(fd, 0, SEEK_SET);
- This is only a short example. If you want to use it in your code, remember to add error handling to it.