]> rtime.felk.cvut.cz Git - coffee/mt-apps.git/commitdiff
mt_gpio.c (libgpiod example, unusable - no debouncing)
authorJiří Matěják <jiri.matejak@fel.cvut.cz>
Fri, 4 May 2018 10:13:13 +0000 (12:13 +0200)
committerJiří Matěják <jiri.matejak@fel.cvut.cz>
Fri, 4 May 2018 10:14:34 +0000 (12:14 +0200)
mt_gpio.c [new file with mode: 0644]

diff --git a/mt_gpio.c b/mt_gpio.c
new file mode 100644 (file)
index 0000000..b6391b1
--- /dev/null
+++ b/mt_gpio.c
@@ -0,0 +1,110 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <linux/input.h>
+#include <linux/input-event-codes.h>
+
+#include "mt_gpio.h"
+#include "signal_exit.h"
+#include "json_helpers.h"
+
+static void gpio_cb(EV_P_ ev_io *w_, int revents)
+{
+    static char *type = "gpio";
+
+    ev_io_gpio *w = (ev_io_gpio *)w_;
+    struct gpiod_line_event e;
+    int fd = w->fd;
+    char key = w->key;
+
+    if (gpiod_line_event_read_fd(w->w.fd, &e) == -1) {
+        perror("gpiod_line_event_read_fd");
+        return;
+    }
+
+    JSON_START();
+    JSON_STR(type);
+    JSON_NEXT();
+    JSON_CHAR(key);
+    JSON_END();
+}
+
+int mt_gpio_init(mt_gpio_t *self, struct ev_loop *loop, int fd)
+{
+    struct gpiod_chip *chip;
+    struct gpiod_line *line;
+    ev_io_gpio *w;
+    int lfd;
+
+    size_t i;
+
+    for (i = 0; i < GPIO_COUNT; i++) {
+        chip = gpiod_chip_open_by_number(pins[i].chip);
+        if (!chip) {
+            perror("gpiod_chip_open");
+            break;
+        }
+        line = gpiod_chip_get_line(chip, pins[i].offset);
+        if (!line) {
+            gpiod_chip_close(chip);
+            perror("gpiod_chip_get_line");
+            break;
+        }
+        if (gpiod_line_event_request_rising(line, GPIO_CONSUMER, GPIO_ACTIVE_LOW) == -1) {
+            gpiod_chip_close(chip);
+            perror("gpiod_line_event_request_rising");
+            break;
+        }
+        lfd = gpiod_line_event_get_fd(line);
+        if (lfd == -1) {
+            perror("gpiod_line_event_get_fd");
+            gpiod_chip_close(chip);
+            break;
+        }
+
+        self->chip[i] = chip;
+        w = &(self->w[i]);
+        w->fd = fd;
+        w->key = pins[i].key;
+        ev_io_init(&(w->w), gpio_cb, lfd, EV_READ);
+        ev_io_start(loop, (ev_io *)w);
+    }
+
+    if (i < GPIO_COUNT) {
+        for (size_t j = 0; j < i; j++) {
+            gpiod_chip_close(self->chip[j]);
+        }
+        return -1;
+    }
+
+    return 0;
+}
+
+void mt_gpio_deinit(mt_gpio_t *self)
+{
+    for (size_t i = 0; i < GPIO_COUNT; i++) {
+        gpiod_chip_close(self->chip[i]);
+    }
+}
+
+#ifndef NO_MAIN
+int main(int argc, char **argv)
+{
+    struct ev_loop *loop = EV_DEFAULT;
+    mt_gpio_t gpio;
+
+    set_signal_exit(loop);
+
+    if (mt_gpio_init(&gpio, loop, STDOUT_FILENO) != 0) {
+        return -1;
+    }
+
+    ev_run(loop, 0);
+
+    mt_gpio_deinit(&gpio);
+
+    return 0;
+}
+#endif