diff --git a/api/maa/gpio.h b/api/maa/gpio.h index f14f5e6..75ffbd5 100644 --- a/api/maa/gpio.h +++ b/api/maa/gpio.h @@ -115,9 +115,10 @@ maa_result_t maa_gpio_edge_mode(maa_gpio_context dev, gpio_edge_t mode); * @param edge The edge mode to set the gpio into * @param fptr Function pointer to function to be called when interupt is * triggered + * @param args Arguments passed to the interrupt handler (fptr) * @return Result of operation */ -maa_result_t maa_gpio_isr(maa_gpio_context dev, gpio_edge_t edge, void (*fptr)(void)); +maa_result_t maa_gpio_isr(maa_gpio_context dev, gpio_edge_t edge, void (*fptr)(void *), void * args); /** * Stop the current interupt watcher on this Gpio, and set the Gpio edge mode diff --git a/api/maa/gpio.hpp b/api/maa/gpio.hpp index 1ba84c5..bc2a513 100644 --- a/api/maa/gpio.hpp +++ b/api/maa/gpio.hpp @@ -104,17 +104,21 @@ class Gpio { return maa_gpio_edge_mode(m_gpio, (gpio_edge_t) mode); } #if defined(SWIGPYTHON) - maa_result_t isr(Edge mode, PyObject *pyfunc) { - return maa_gpio_isr(m_gpio, (gpio_edge_t) mode, (void (*) ()) pyfunc); + maa_result_t isr(Edge mode, PyObject *pyfunc, PyObject* args) { + return maa_gpio_isr(m_gpio, (gpio_edge_t) mode, (void (*) (void *)) pyfunc, (void *) args); } #else /** * Sets a callback to be called when pin value changes * + * @param mode The edge mode to set + * @param fptr Function pointer to function to be called when interupt is + * triggered + * @param args Arguments passed to the interrupt handler (fptr) * @return Result of operation */ - maa_result_t isr(Edge mode, void (*fptr)(void)) { - return maa_gpio_isr(m_gpio, (gpio_edge_t) mode, fptr); + maa_result_t isr(Edge mode, void (*fptr)(void *), void * args) { + return maa_gpio_isr(m_gpio, (gpio_edge_t) mode, fptr, args); } #endif /** diff --git a/examples/isr_pin6.c b/examples/isr_pin6.c index 9f64ae9..65a987d 100644 --- a/examples/isr_pin6.c +++ b/examples/isr_pin6.c @@ -29,7 +29,7 @@ static volatile int counter = 0; static volatile int oldcounter = 0; -void interrupt (void) { +void interrupt (void * args) { ++counter; } @@ -47,7 +47,7 @@ int main () gpio_edge_t edge = MAA_GPIO_EDGE_BOTH; - maa_gpio_isr(x, edge, &interrupt); + maa_gpio_isr(x, edge, &interrupt, NULL); for(;;) { if(counter != oldcounter) { diff --git a/examples/python/hello_isr.py b/examples/python/hello_isr.py index 3afa44f..3e4a9f4 100644 --- a/examples/python/hello_isr.py +++ b/examples/python/hello_isr.py @@ -2,9 +2,9 @@ import pymaa as maa -def test(): +def test(args): print("wooo") x = maa.Gpio(6) x.dir(maa.DIR_IN) -x.isr(maa.EDGE_BOTH, test) +x.isr(maa.EDGE_BOTH, test, test) diff --git a/src/gpio/gpio.c b/src/gpio/gpio.c index 6ee7448..da833c9 100644 --- a/src/gpio/gpio.c +++ b/src/gpio/gpio.c @@ -48,7 +48,8 @@ struct _gpio { int pin; /**< the pin number, as known to the os. */ int phy_pin; /**< pin passed to clean init. -1 none and raw*/ int value_fp; /**< the file pointer to the value of the gpio */ - void (* isr)(); /**< the interupt service request */ + void (* isr)(void *); /**< the interupt service request */ + void *isr_args; /**< args return when interupt service request triggered */ pthread_t thread_id; /**< the isr handler thread id */ int isr_value_fp; /**< the isr file pointer on the value */ maa_boolean_t owner; /**< If this context originally exported the pin */ @@ -183,12 +184,24 @@ maa_gpio_interrupt_handler(void* arg) // nessecary but especially if doing IO (like print()) python will segfault // if we do not hold a lock on the GIL PyGILState_STATE gilstate = PyGILState_Ensure(); - - PyEval_CallObject((PyObject*)dev->isr, NULL); + PyObject *arglist; + PyObject *ret; + arglist = Py_BuildValue("(i)", dev->isr_args); + if (arglist == NULL) { + fprintf(stdout, "Py_BuildValue NULL\n"); + } else { + ret = PyEval_CallObject((PyObject*)dev->isr, arglist); + if (ret == NULL) { + fprintf(stdout, "PyEval_CallObject failed\n"); + } else { + Py_DECREF(ret); + } + Py_DECREF(arglist); + } PyGILState_Release (gilstate); #else - dev->isr(); + dev->isr(dev->isr_args); #endif pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); } else { @@ -196,7 +209,7 @@ maa_gpio_interrupt_handler(void* arg) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); close(dev->isr_value_fp); dev->isr_value_fp = -1; - return NULL; + return NULL; } } } @@ -248,15 +261,19 @@ maa_gpio_edge_mode(maa_gpio_context dev, gpio_edge_t mode) } maa_result_t -maa_gpio_isr(maa_gpio_context dev, gpio_edge_t mode, void (*fptr)(void)) +maa_gpio_isr(maa_gpio_context dev, gpio_edge_t mode, void (*fptr)(void *), void * args) { // we only allow one isr per maa_gpio_context if (dev->thread_id != 0) { return MAA_ERROR_NO_RESOURCES; } - maa_gpio_edge_mode(dev, mode); + if (MAA_SUCCESS != maa_gpio_edge_mode(dev, mode)) { + return MAA_ERROR_UNSPECIFIED; + } + dev->isr = fptr; + dev->isr_args = args; pthread_create (&dev->thread_id, NULL, maa_gpio_interrupt_handler, (void *) dev); return MAA_SUCCESS;