/* * C Implementation: gpio * * Description: * * * Author: Paolo Zebelloni , (C) 2014 * * Copyright: See COPYING file that comes with this distribution * */ #include "gpio.h" #include "output.h" #ifdef __Windows__ /* Added for building on Windows * * Daniel Beer , 3 Mar 2015 */ int gpio_export ( unsigned int gpio ) { printc_err("gpio: GPIO interface not supported on Windows\n"); return -1; } int gpio_unexport ( unsigned int gpio ) { printc_err("gpio: GPIO interface not supported on Windows\n"); return -1; } int gpio_set_dir ( unsigned int gpio, unsigned int out_flag ) { printc_err("gpio: GPIO interface not supported on Windows\n"); return -1; } int gpio_set_value ( unsigned int gpio, unsigned int value ) { printc_err("gpio: GPIO interface not supported on Windows\n"); return -1; } int gpio_set_value_fd (int fd, int value) { printc_err("gpio: GPIO interface not supported on Windows\n"); return -1; } int gpio_get_value ( unsigned int gpio ) { return 0; } int gpio_get_value_fd (int fd, unsigned int gpio) { return 0; } int gpio_open_fd (unsigned int gpio) { printc_err("gpio: GPIO interface not supported on Windows\n"); return -1; } #else #include #include #include #include #include #include #include #include #include #define SYSFS_GPIO_DIR "/sys/class/gpio" #define MAX_BUF 64 /** * Before a Linux application can configure and use a GPIO, the GPIO first has to be exported to user. * Each GPIO is not accessible from user space until the GPIO has been exported. * You can only export a GPIO that isn't owned by a Linux kernel driver * @param gpio GPIO number * @return 0 if OK, -1 if fails */ int gpio_export ( unsigned int gpio ) { int fd, len; char buf[MAX_BUF]; fd = open ( SYSFS_GPIO_DIR "/export", O_WRONLY ); if ( fd < 0 ) { pr_error ( "gpio/export" ); return -1; } len = snprintf ( buf, sizeof ( buf ), "%d", gpio ); write ( fd, buf, len ); close ( fd ); return 0; } /** * Complement of gpio_export(). * @param gpio GPIO number * @return 0 if OK, -1 if fails */ int gpio_unexport ( unsigned int gpio ) { int fd, len; char buf[MAX_BUF]; fd = open ( SYSFS_GPIO_DIR "/unexport", O_WRONLY ); if ( fd < 0 ) { pr_error ( "gpio/unexport" ); return -1; } len = snprintf ( buf, sizeof ( buf ), "%d", gpio ); write ( fd, buf, len ); close ( fd ); return 0; } /** * To avoid hardware issues where two devices are driving the same signal, GPIOs default to be configured as an input. * If you want to use the GPIO as an output, you need to change the configuration * @param gpio GPIO number * @param out_flag TRUE means OUT, FALSE means IN * @return 0 if OK, -1 if fails */ int gpio_set_dir ( unsigned int gpio, unsigned int out_flag ) { int fd; char buf[MAX_BUF]; snprintf ( buf, MAX_BUF, SYSFS_GPIO_DIR "/gpio%d/direction", gpio ); fd = open ( buf, O_WRONLY ); if ( fd < 0 ) { pr_error ( "gpio/direction" ); return -1; } if ( out_flag ) write ( fd, "out", 4 ); else write ( fd, "in", 3 ); close ( fd ); return 0; } /** * Set HI or LO state to GPIO (output) pin. * @param gpio GPIO number * @param value TRUE means HI, FALSE means LO * @return 0 if OK, -1 if fails */ int gpio_set_value ( unsigned int gpio, unsigned int value ) { int fd; char buf[MAX_BUF]; snprintf ( buf, MAX_BUF, SYSFS_GPIO_DIR "/gpio%d/value", gpio ); fd = open ( buf, O_WRONLY ); if ( fd < 0 ) { pr_error ( "gpio/set-value" ); return -1; } write ( fd, value ? "1" : "0", 2 ); close ( fd ); return 0; } /** * Read state of GPIO (input) pin. * @param gpio GPIO number * @return 0 if LO, 1 if HI, -1 if fails */ int gpio_get_value ( unsigned int gpio ) { int fd; char buf[MAX_BUF]; char ch; snprintf ( buf, MAX_BUF, SYSFS_GPIO_DIR "/gpio%d/value", gpio ); fd = open ( buf, O_RDONLY ); if ( fd < 0 ) { pr_error ( "gpio/get-value" ); return -1; } read ( fd, &ch, 1 ); close ( fd ); return ( ch != '0' ); } /** * Opens GPIO (input/output) pin file descriptor * @param gpio GPIO number * @return file descriptor, -1 if fails */ int gpio_open_fd ( unsigned int gpio ) { int fd; char buf[MAX_BUF]; snprintf ( buf, MAX_BUF, SYSFS_GPIO_DIR "/gpio%d/value", gpio ); fd = open ( buf, O_RDWR ); if ( fd < 0 ) { pr_error ( "gpio/get-value" ); return -1; } return fd; } /** * Sets GPIO (output) value with given file descriptor * @param file descriptor * @param gpio GPIO number * @return 0 if OK, -1 if fails */ int gpio_set_value_fd (int fd, int value) { ssize_t ret; char gpio_value = value + '0'; ret = write (fd, &gpio_value, 1); if (ret != 1) { printf("Error setting value gpio\n"); return -1; } return 0; } /** * Read state of GPIO (input) pin, with file descriptor * @param file descriptor * @param gpio GPIO number * @return 0 if LO, 1 if HI, -1 if fails */ int gpio_get_value_fd (int fd, unsigned int gpio) { ssize_t ret; char value; ret = pread (fd, &value, 1, 0); if (ret != 1) { printf("Error getting value of gpio %u\n", gpio); return -1; } return value == '1'; } #endif