Skip to content

Commit

Permalink
Merge pull request #124 from jpbarraca/master
Browse files Browse the repository at this point in the history
 Timeout support for wait_for_edge (replaces PR #62)
  • Loading branch information
pdp7 authored Nov 24, 2016
2 parents 8b4f7f2 + 40e5cd3 commit cf9771a
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 10 deletions.
4 changes: 4 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ Waiting for an edge (GPIO.RISING, GPIO.FALLING, or GPIO.BOTH::

GPIO.wait_for_edge(channel, GPIO.RISING)

or
GPIO.wait_for_edge(channel, GPIO.RISING, timeout)

Detecting events::

GPIO.add_event_detect("P9_12", GPIO.FALLING)
Expand Down
6 changes: 3 additions & 3 deletions source/event_gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ void event_cleanup(void)
exports_cleanup();
}

int blocking_wait_for_edge(unsigned int gpio, unsigned int edge)
int blocking_wait_for_edge(unsigned int gpio, unsigned int edge, int timeout)
// standalone from all the event functions above
{
int fd = fd_lookup(gpio);
Expand Down Expand Up @@ -661,7 +661,7 @@ int blocking_wait_for_edge(unsigned int gpio, unsigned int edge)

// epoll for event
for (i = 0; i<2; i++) // first time triggers with current state, so ignore
if ((n = epoll_wait(epfd, &events, 1, -1)) == -1)
if ((n = epoll_wait(epfd, &events, 1, timeout)) == -1)
{
gpio_event_remove(gpio);
return 5;
Expand All @@ -684,5 +684,5 @@ int blocking_wait_for_edge(unsigned int gpio, unsigned int edge)

gpio_event_remove(gpio);
close(epfd);
return 0;
return (n == 1) ? 0 : -1;
}
2 changes: 1 addition & 1 deletion source/event_gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,6 @@ int gpio_event_remove(unsigned int gpio);
int gpio_is_evented(unsigned int gpio);
int event_initialise(void);
void event_cleanup(void);
int blocking_wait_for_edge(unsigned int gpio, unsigned int edge);
int blocking_wait_for_edge(unsigned int gpio, unsigned int edge, int timeout);

#endif
17 changes: 11 additions & 6 deletions source/py_gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,17 +435,20 @@ static PyObject *py_event_detected(PyObject *self, PyObject *args)
Py_RETURN_FALSE;
}

// python function py_wait_for_edge(gpio, edge)
// python function py_wait_for_edge(gpio, edge, timeout = -1)
static PyObject *py_wait_for_edge(PyObject *self, PyObject *args)
{
unsigned int gpio;
int edge, result;
int edge, result, timeout;
char *channel;
char error[30];
BBIO_err err;

if (!PyArg_ParseTuple(args, "si", &channel, &edge))
return NULL;
if (!PyArg_ParseTuple(args, "sii", &channel, &edge, &timeout)){
timeout = -1;
if (!PyArg_ParseTuple(args, "si", &channel, &edge))
return NULL;
}

err = get_gpio_number(channel, &gpio);
if (err != BBIO_OK)
Expand All @@ -466,12 +469,14 @@ static PyObject *py_wait_for_edge(PyObject *self, PyObject *args)
}

Py_BEGIN_ALLOW_THREADS // disable GIL
result = blocking_wait_for_edge(gpio, edge);
result = blocking_wait_for_edge(gpio, edge, timeout);
Py_END_ALLOW_THREADS // enable GIL

if (result == 0) {
Py_INCREF(Py_None);
return Py_None;
}else if (result == -1){
Py_RETURN_FALSE;
} else if (result == 2) {
PyErr_SetString(PyExc_RuntimeError, "Edge detection events already enabled for this GPIO channel");
return NULL;
Expand Down Expand Up @@ -537,7 +542,7 @@ PyMethodDef gpio_methods[] = {
{"remove_event_detect", py_remove_event_detect, METH_VARARGS, "Remove edge detection for a particular GPIO channel\ngpio - gpio channel"},
{"event_detected", py_event_detected, METH_VARARGS, "Returns True if an edge has occured on a given GPIO. You need to enable edge detection using add_event_detect() first.\ngpio - gpio channel"},
{"add_event_callback", (PyCFunction)py_add_event_callback, METH_VARARGS | METH_KEYWORDS, "Add a callback for an event already defined using add_event_detect()\ngpio - gpio channel\ncallback - a callback function\n[bouncetime] - Switch bounce timeout in ms"},
{"wait_for_edge", py_wait_for_edge, METH_VARARGS, "Wait for an edge.\ngpio - gpio channel\nedge - RISING, FALLING or BOTH"},
{"wait_for_edge", py_wait_for_edge, METH_VARARGS, "Wait for an edge.\ngpio - gpio channel\nedge - RISING, FALLING or BOTH\ntimeout (optional) - time to wait in miliseconds. -1 will wait forever (default)"},
{"gpio_function", py_gpio_function, METH_VARARGS, "Return the current GPIO function (IN, OUT, ALT0)\ngpio - gpio channel"},
{"setwarnings", py_setwarnings, METH_VARARGS, "Enable or disable warning messages"},
{NULL, NULL, 0, NULL}
Expand Down

0 comments on commit cf9771a

Please sign in to comment.