aboutsummaryrefslogtreecommitdiffstats
path: root/src/gpio.c
diff options
context:
space:
mode:
authoryzrh <yzrh@noema.org>2020-10-10 17:16:14 +0000
committeryzrh <yzrh@noema.org>2020-10-10 17:37:53 +0000
commitb9b74e88028f81e7b169a5e168102138e8c2c46c (patch)
tree2b8f9f8896db3a6871c56215acf71cb502fe7be4 /src/gpio.c
downloadsnake-sdl-b9b74e88028f81e7b169a5e168102138e8c2c46c.tar.gz
snake-sdl-b9b74e88028f81e7b169a5e168102138e8c2c46c.tar.zst
Initial commit.
Diffstat (limited to 'src/gpio.c')
-rw-r--r--src/gpio.c194
1 files changed, 194 insertions, 0 deletions
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 <yzrh@noema.org>
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#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__ */