int add_edge_detect(unsigned int gpio, unsigned int edge, int bouncetime) // return values: // 0 - Success // 1 - Edge detection already added // 2 - Other error { pthread_t threads; struct epoll_event ev; long t = 0; struct gpios *g; int i = -1; i = gpio_event_added(gpio); if (i == 0) { // event not already added if ((g = new_gpio(gpio)) == NULL) return 2; gpio_set_edge(gpio, edge); g->edge = edge; g->bouncetime = bouncetime; } else if (i == edge) { // get existing event g = get_gpio(gpio); if ((bouncetime != -666 && g->bouncetime != bouncetime) || // different event bouncetime used (g->thread_added)) // event already added return 1; } else { return 1; } // create epfd_thread if not already open if ((epfd_thread == -1) && ((epfd_thread = epoll_create(1)) == -1)) return 2; // add to epoll fd ev.events = EPOLLIN | EPOLLET | EPOLLPRI; ev.data.fd = g->value_fd; if (epoll_ctl(epfd_thread, EPOLL_CTL_ADD, g->value_fd, &ev) == -1) { remove_edge_detect(gpio); return 2; } g->thread_added = 1; // start poll thread if it is not already running if (!thread_running) { if (pthread_create(&threads, NULL, poll_thread, (void *)t) != 0) { remove_edge_detect(gpio); return 2; } } return 0; }
void event_cleanup(unsigned int gpio) // gpio of -666 means clean every channel used { while (gpio_list != NULL) { if ((gpio == -666) || (gpio_list->gpio == gpio)) remove_edge_detect(gpio_list->gpio); } thread_running = 0; }
int add_edge_detect(unsigned int gpio, unsigned int edge, unsigned int bouncetime) // return values: // 0 - Success // 1 - Edge detection already added // 2 - Other error { pthread_t threads; struct epoll_event ev; long t = 0; struct gpios *g; // check to see if this gpio has been added already if (gpio_event_added(gpio) != 0) return 1; // create epfd if not already open if ((epfd == -1) && ((epfd = epoll_create(1)) == -1)) return 2; if ((g = new_gpio(gpio)) == NULL) return 2; gpio_set_edge(gpio, edge); g->bouncetime = bouncetime; // add to epoll fd ev.events = EPOLLIN | EPOLLET | EPOLLPRI; ev.data.fd = g->value_fd; if (epoll_ctl(epfd, EPOLL_CTL_ADD, g->value_fd, &ev) == -1) { remove_edge_detect(gpio); return 2; } // start poll thread if it is not already running if (!thread_running) { if (pthread_create(&threads, NULL, poll_thread, (void *)t) != 0) { remove_edge_detect(gpio); return 2; } } return 0; }
// python function remove_event_detect(gpio) static PyObject *py_remove_event_detect(PyObject *self, PyObject *args) { unsigned int gpio; unsigned int sys_gpio; int channel; struct py_callback *cb = py_callbacks; struct py_callback *temp; struct py_callback *prev = NULL; if (!PyArg_ParseTuple(args, "i", &channel)) return NULL; if (get_gpio_number(channel, &gpio, &sys_gpio)) return NULL; // remove all python callbacks for gpio while (cb != NULL) { if (cb->gpio == gpio) { Py_XDECREF(cb->py_cb); if (prev == NULL) py_callbacks = cb->next; else prev->next = cb->next; temp = cb; cb = cb->next; free(temp); } else { prev = cb; cb = cb->next; } } if (check_gpio_priv()) return NULL; remove_edge_detect(sys_gpio); Py_RETURN_NONE; }
void event_cleanup(unsigned int gpio) // gpio of -666 means clean every channel used { struct gpios *g = gpio_list; struct gpios *temp = NULL; while (g != NULL) { if ((gpio == -666) || (g->gpio == gpio)) temp = g->next; remove_edge_detect(g->gpio); g = temp; } if (gpio_list == NULL) if (epfd_blocking != -1) close(epfd_blocking); epfd_blocking = -1; if (epfd_thread != -1) close(epfd_thread); epfd_thread = -1; thread_running = 0; }