From b9b74e88028f81e7b169a5e168102138e8c2c46c Mon Sep 17 00:00:00 2001 From: yzrh Date: Sat, 10 Oct 2020 17:16:14 +0000 Subject: Initial commit. --- src/gpio.c | 194 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 src/gpio.c (limited to 'src/gpio.c') diff --git a/src/gpio.c b/src/gpio.c new file mode 100644 index 0000000..9d4cde1 --- /dev/null +++ b/src/gpio.c @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2019-2020, yzrh + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include "gpio.h" + +#ifdef __FreeBSD__ + +int +gpio_config(int pin, int direction, int interrupt) +{ + int ret; + int fd = open("/dev/gpioc0", O_RDWR); + + if (fd == -1) { + fprintf(stderr, "GPIO configuration failure\n"); + return 1; + } + + struct gpio_pin pin_req = { + .gp_pin = pin, + .gp_caps = interrupt, + .gp_flags = direction + }; + + ret = ioctl(fd, GPIOSETCONFIG, &pin_req) == 0 ? 0 : 1; + close(fd); + return ret; +} + +int +gpio_write(int pin, int value) +{ + int ret; + int fd = open("/dev/gpioc0", O_RDWR); + + if (fd == -1) { + fprintf(stderr, "GPIO output failure\n"); + return 1; + } + + struct gpio_req req = { + .gp_pin = pin, + .gp_value = value + }; + + ret = ioctl(fd, GPIOSET, &req) == 0 ? 0 : 1; + close(fd); + return ret; +} + +int +gpio_read(int pin) +{ + int fd = open("/dev/gpioc0", O_RDWR); + + if (fd == -1) { + fprintf(stderr, "GPIO input failure\n"); + return 1; + } + + struct gpio_req req = { + .gp_pin = pin + }; + + ioctl(fd, GPIOGET, &req); + + close(fd); + return req.gp_value; +} + +#elif __linux__ + +int +gpio_export(int pin) +{ + int export = open("/sys/class/gpio/export", O_RDWR); + + if (export == -1) { + fprintf(stderr, "GPIO export failure\n"); + return 1; + } + + char buf[3]; + int buf_size = snprintf(buf, 3, "%d", pin); + write(export, buf, buf_size); + + close(export); + return 0; +} + +int +gpio_unexport(int pin) +{ + int unexport = open("/sys/class/gpio/unexport", O_RDWR); + + if (unexport == -1) { + fprintf(stderr, "GPIO unexport failure\n"); + return 1; + } + + char buf[3]; + int buf_size = snprintf(buf, 3, "%d", pin); + write(unexport, buf, buf_size); + + close(unexport); + return 0; +} + +int +gpio_config(int pin, int direction, int interrupt) +{ + char path[33]; + snprintf(path, 33, "/sys/class/gpio/gpio%d/direction", pin); + + int config = open(path, O_RDWR); + + if (config == -1) { + fprintf(stderr, "GPIO configuration failure\n"); + return 1; + } + + char buf[8]; + int buf_size = snprintf(buf, 8, "%s", direction == 0 ? "in" : "out"); + write(config, buf, buf_size); + + close(config); + + snprintf(path, 33, "/sys/class/gpio/gpio%d/edge", pin); + + config = open(path, O_RDWR); + + if (config == -1) { + fprintf(stderr, "GPIO configuration failure\n"); + return 1; + } + + buf_size = snprintf(buf, 8, "%s", + interrupt == 0 ? "falling" : "rising"); + write(config, buf, buf_size); + + close(config); + return 0; +} + +int +gpio_write(int pin, int value) +{ + char path[29]; + snprintf(path, 29, "/sys/class/gpio/gpio%d/value", pin); + + int config = open(path, O_RDWR); + + if (config == -1) { + fprintf(stderr, "GPIO output failure\n"); + return 1; + } + + char buf[2]; + int buf_size = snprintf(buf, 2, "%d", value); + write(config, buf, buf_size); + + close(config); + return 0; +} + +int +gpio_read(int pin) +{ + char path[29]; + snprintf(path, 29, "/sys/class/gpio/gpio%d/value", pin); + + int config = open(path, O_RDONLY); + + if (config == -1) { + fprintf(stderr, "GPIO input failure\n"); + return 1; + } + + char buf[2]; + read(config, buf, 2); + + close(config); + return atoi(buf); +} + +#endif /* __FreeBSD__ */ -- cgit v1.2.3