}
int gpiod_line_event_wait(struct gpiod_line *line,
- const struct timespec *timeout,
- struct gpiod_line_event *event)
+ const struct timespec *timeout)
{
struct gpiod_line_bulk bulk;
gpiod_line_bulk_init(&bulk);
gpiod_line_bulk_add(&bulk, line);
- return gpiod_line_event_wait_bulk(&bulk, timeout, event);
+ return gpiod_line_event_wait_bulk(&bulk, timeout, NULL);
}
int gpiod_line_event_wait_bulk(struct gpiod_line_bulk *bulk,
const struct timespec *timeout,
- struct gpiod_line_event *event)
+ unsigned int *index)
{
struct pollfd fds[GPIOD_REQUEST_MAX_LINES];
- struct gpioevent_data evdata;
struct gpiod_line *line;
unsigned int i;
int status;
- ssize_t rd;
memset(fds, 0, sizeof(fds));
- memset(&evdata, 0, sizeof(evdata));
/* TODO Check if all lines are requested. */
}
for (i = 0; !fds[i].revents; i++);
+ if (index)
+ *index = i;
+
+ return 1;
+}
+
+int gpiod_line_event_read(struct gpiod_line *line,
+ struct gpiod_line_event *event)
+{
+ struct gpioevent_data evdata;
+ ssize_t rd;
- rd = read(fds[i].fd, &evdata, sizeof(evdata));
+ memset(&evdata, 0, sizeof(evdata));
+
+ rd = read(line->event.fd, &evdata, sizeof(evdata));
if (rd < 0) {
last_error_from_errno();
return -1;
return -1;
}
- event->line = bulk->lines[i];
+ event->line = line;
event->event_type = evdata.id == GPIOEVENT_EVENT_RISING_EDGE
? GPIOD_EVENT_RISING_EDGE
: GPIOD_EVENT_FALLING_EDGE;
nsec_to_timespec(evdata.timestamp, &event->ts);
- return 1;
+ return 0;
}
int gpiod_line_event_get_fd(struct gpiod_line *line)
* @brief Wait for an event on a single line.
* @param line GPIO line object.
* @param timeout Wait time limit.
- * @param event Buffer to which the event data will be copied.
* @return 0 if wait timed out, -1 if an error occurred, 1 if an event
* occurred.
*/
int gpiod_line_event_wait(struct gpiod_line *line,
- const struct timespec *timeout,
- struct gpiod_line_event *event) GPIOD_API;
+ const struct timespec *timeout) GPIOD_API;
/**
* @brief Wait for the first event on a set of lines.
* @param bulk Set of GPIO lines to monitor.
* @param timeout Wait time limit.
- * @param event Buffer to which the event data will be copied.
+ * @param index The position of the line on which an event occured is stored
+ * in this variable. Can be NULL, in which case the index will
+ * not be stored.
* @return 0 if wait timed out, -1 if an error occurred, 1 if an event
* occurred.
*/
int gpiod_line_event_wait_bulk(struct gpiod_line_bulk *bulk,
const struct timespec *timeout,
- struct gpiod_line_event *event) GPIOD_API;
+ unsigned int *index) GPIOD_API;
-/*
- * FIXME for this to make sense we need a routine to read events from a file
- * descriptor too.
+/**
+ * @brief Read the last event from the GPIO line.
+ * @param line GPIO line object.
+ * @param event Buffer to which the event data will be copied.
+ * @return 0 if the event was read correctly, -1 on error.
+ */
+int gpiod_line_event_read(struct gpiod_line *line,
+ struct gpiod_line_event *event) GPIOD_API;
+
+/**
+ * @brief Get the event file descriptor.
+ * @param line GPIO line object.
+ * @return Number of the event file descriptor or -1 on error.
+ *
+ * Users may want to poll the event file descriptor on their own. This routine
+ * allows to access it.
*/
int gpiod_line_event_get_fd(struct gpiod_line *line) GPIOD_API;
timeout.tv_sec = 1;
timeout.tv_nsec = 0;
- status = gpiod_line_event_wait(line, &timeout, &event);
+ status = gpiod_line_event_wait(line, &timeout);
if (status < 0) {
fprintf(stderr,
"%s: error waiting for line event: %s\n",
continue;
}
+ status = gpiod_line_event_read(line, &event);
+ if (status < 0) {
+ fprintf(stderr,
+ "%s: error reading the line event: %s\n",
+ argv[0], gpiod_strerror(gpiod_errno()));
+ return EXIT_FAILURE;
+ }
+
printf("GPIO EVENT: %s [%ld.%ld]\n",
event.event_type == GPIOD_EVENT_FALLING_EDGE
? "FALLING EDGE"