From: Jiří Matěják Date: Fri, 4 May 2018 10:13:13 +0000 (+0200) Subject: mt_gpio.c (libgpiod example, unusable - no debouncing) X-Git-Url: https://rtime.felk.cvut.cz/gitweb/coffee/mt-apps.git/commitdiff_plain/955c9f2acce97d2514589019676fed2773569ba3 mt_gpio.c (libgpiod example, unusable - no debouncing) --- diff --git a/mt_gpio.c b/mt_gpio.c new file mode 100644 index 0000000..b6391b1 --- /dev/null +++ b/mt_gpio.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include +#include +#include + +#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