wiringPiISR python callback functionality
diff --git a/wiringpi.i b/wiringpi.i
index 92ca76a..c4e2f59 100644
--- a/wiringpi.i
+++ b/wiringpi.i
@@ -45,6 +45,195 @@
$2 = PyString_Size($input);
};
+// Grab a Python function object as a Python object.
+%typemap(in) PyObject *pyfunc {
+ if (!PyCallable_Check($1)) {
+ PyErr_SetString(PyExc_TypeError, "Need a callable object!");
+ return NULL;
+ }
+ $1 = $2;
+}
+
+%{
+
+// we need to have our own callbacks array
+PyObject* event_callback[64] = {0,};
+
+void _wiringPiISR_callback(int pinNumber) {
+ PyObject *result;
+
+ if (event_callback[pinNumber]) {
+ // this will acquire the GIL
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+
+ result = PyObject_CallFunction(event_callback[pinNumber], NULL);
+ if (result == NULL && PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ Py_XDECREF(result);
+
+ // release the GIL
+ SWIG_PYTHON_THREAD_END_BLOCK;
+ }
+}
+
+
+/* This is embarrasing, WiringPi does not support supplying args to the callback
+... so we have to create callback function for each of the pins :( */
+void _wiringPiISR_callback_pin0(void) { _wiringPiISR_callback(0); }
+void _wiringPiISR_callback_pin1(void) { _wiringPiISR_callback(1); }
+void _wiringPiISR_callback_pin2(void) { _wiringPiISR_callback(2); }
+void _wiringPiISR_callback_pin3(void) { _wiringPiISR_callback(3); }
+void _wiringPiISR_callback_pin4(void) { _wiringPiISR_callback(4); }
+void _wiringPiISR_callback_pin5(void) { _wiringPiISR_callback(5); }
+void _wiringPiISR_callback_pin6(void) { _wiringPiISR_callback(6); }
+void _wiringPiISR_callback_pin7(void) { _wiringPiISR_callback(7); }
+void _wiringPiISR_callback_pin8(void) { _wiringPiISR_callback(8); }
+void _wiringPiISR_callback_pin9(void) { _wiringPiISR_callback(9); }
+void _wiringPiISR_callback_pin10(void) { _wiringPiISR_callback(10); }
+void _wiringPiISR_callback_pin11(void) { _wiringPiISR_callback(11); }
+void _wiringPiISR_callback_pin12(void) { _wiringPiISR_callback(12); }
+void _wiringPiISR_callback_pin13(void) { _wiringPiISR_callback(13); }
+void _wiringPiISR_callback_pin14(void) { _wiringPiISR_callback(14); }
+void _wiringPiISR_callback_pin15(void) { _wiringPiISR_callback(15); }
+void _wiringPiISR_callback_pin16(void) { _wiringPiISR_callback(16); }
+void _wiringPiISR_callback_pin17(void) { _wiringPiISR_callback(17); }
+void _wiringPiISR_callback_pin18(void) { _wiringPiISR_callback(18); }
+void _wiringPiISR_callback_pin19(void) { _wiringPiISR_callback(19); }
+void _wiringPiISR_callback_pin20(void) { _wiringPiISR_callback(20); }
+void _wiringPiISR_callback_pin21(void) { _wiringPiISR_callback(21); }
+void _wiringPiISR_callback_pin22(void) { _wiringPiISR_callback(22); }
+void _wiringPiISR_callback_pin23(void) { _wiringPiISR_callback(23); }
+void _wiringPiISR_callback_pin24(void) { _wiringPiISR_callback(24); }
+void _wiringPiISR_callback_pin25(void) { _wiringPiISR_callback(25); }
+void _wiringPiISR_callback_pin26(void) { _wiringPiISR_callback(26); }
+void _wiringPiISR_callback_pin27(void) { _wiringPiISR_callback(27); }
+void _wiringPiISR_callback_pin28(void) { _wiringPiISR_callback(28); }
+void _wiringPiISR_callback_pin29(void) { _wiringPiISR_callback(29); }
+void _wiringPiISR_callback_pin30(void) { _wiringPiISR_callback(30); }
+void _wiringPiISR_callback_pin31(void) { _wiringPiISR_callback(31); }
+void _wiringPiISR_callback_pin32(void) { _wiringPiISR_callback(32); }
+void _wiringPiISR_callback_pin33(void) { _wiringPiISR_callback(33); }
+void _wiringPiISR_callback_pin34(void) { _wiringPiISR_callback(34); }
+void _wiringPiISR_callback_pin35(void) { _wiringPiISR_callback(35); }
+void _wiringPiISR_callback_pin36(void) { _wiringPiISR_callback(36); }
+void _wiringPiISR_callback_pin37(void) { _wiringPiISR_callback(37); }
+void _wiringPiISR_callback_pin38(void) { _wiringPiISR_callback(38); }
+void _wiringPiISR_callback_pin39(void) { _wiringPiISR_callback(39); }
+void _wiringPiISR_callback_pin40(void) { _wiringPiISR_callback(40); }
+void _wiringPiISR_callback_pin41(void) { _wiringPiISR_callback(41); }
+void _wiringPiISR_callback_pin42(void) { _wiringPiISR_callback(42); }
+void _wiringPiISR_callback_pin43(void) { _wiringPiISR_callback(43); }
+void _wiringPiISR_callback_pin44(void) { _wiringPiISR_callback(44); }
+void _wiringPiISR_callback_pin45(void) { _wiringPiISR_callback(45); }
+void _wiringPiISR_callback_pin46(void) { _wiringPiISR_callback(46); }
+void _wiringPiISR_callback_pin47(void) { _wiringPiISR_callback(47); }
+void _wiringPiISR_callback_pin48(void) { _wiringPiISR_callback(48); }
+void _wiringPiISR_callback_pin49(void) { _wiringPiISR_callback(49); }
+void _wiringPiISR_callback_pin50(void) { _wiringPiISR_callback(50); }
+void _wiringPiISR_callback_pin51(void) { _wiringPiISR_callback(51); }
+void _wiringPiISR_callback_pin52(void) { _wiringPiISR_callback(52); }
+void _wiringPiISR_callback_pin53(void) { _wiringPiISR_callback(53); }
+void _wiringPiISR_callback_pin54(void) { _wiringPiISR_callback(54); }
+void _wiringPiISR_callback_pin55(void) { _wiringPiISR_callback(55); }
+void _wiringPiISR_callback_pin56(void) { _wiringPiISR_callback(56); }
+void _wiringPiISR_callback_pin57(void) { _wiringPiISR_callback(57); }
+void _wiringPiISR_callback_pin58(void) { _wiringPiISR_callback(58); }
+void _wiringPiISR_callback_pin59(void) { _wiringPiISR_callback(59); }
+void _wiringPiISR_callback_pin60(void) { _wiringPiISR_callback(60); }
+void _wiringPiISR_callback_pin61(void) { _wiringPiISR_callback(61); }
+void _wiringPiISR_callback_pin62(void) { _wiringPiISR_callback(62); }
+void _wiringPiISR_callback_pin63(void) { _wiringPiISR_callback(63); }
+
+/* This function adds a new Python function object as a callback object */
+
+static void wiringPiISRWrapper(int pin, int mode, PyObject *PyFunc) {
+
+ // remove the old callback if any
+ if (event_callback[pin]) {
+ Py_XDECREF(event_callback[pin]);
+ }
+
+ // put new callback function
+ event_callback[pin] = PyFunc;
+ Py_INCREF(PyFunc);
+
+ // and now the ugly switch
+ void (*func)(void);
+ switch(pin) {
+ case 0: func = &_wiringPiISR_callback_pin0; break;
+ case 1: func = &_wiringPiISR_callback_pin1; break;
+ case 2: func = &_wiringPiISR_callback_pin2; break;
+ case 3: func = &_wiringPiISR_callback_pin3; break;
+ case 4: func = &_wiringPiISR_callback_pin4; break;
+ case 5: func = &_wiringPiISR_callback_pin5; break;
+ case 6: func = &_wiringPiISR_callback_pin6; break;
+ case 7: func = &_wiringPiISR_callback_pin7; break;
+ case 8: func = &_wiringPiISR_callback_pin8; break;
+ case 9: func = &_wiringPiISR_callback_pin9; break;
+ case 10: func = &_wiringPiISR_callback_pin10; break;
+ case 11: func = &_wiringPiISR_callback_pin11; break;
+ case 12: func = &_wiringPiISR_callback_pin12; break;
+ case 13: func = &_wiringPiISR_callback_pin13; break;
+ case 14: func = &_wiringPiISR_callback_pin14; break;
+ case 15: func = &_wiringPiISR_callback_pin15; break;
+ case 16: func = &_wiringPiISR_callback_pin16; break;
+ case 17: func = &_wiringPiISR_callback_pin17; break;
+ case 18: func = &_wiringPiISR_callback_pin18; break;
+ case 19: func = &_wiringPiISR_callback_pin19; break;
+ case 20: func = &_wiringPiISR_callback_pin20; break;
+ case 21: func = &_wiringPiISR_callback_pin21; break;
+ case 22: func = &_wiringPiISR_callback_pin22; break;
+ case 23: func = &_wiringPiISR_callback_pin23; break;
+ case 24: func = &_wiringPiISR_callback_pin24; break;
+ case 25: func = &_wiringPiISR_callback_pin25; break;
+ case 26: func = &_wiringPiISR_callback_pin26; break;
+ case 27: func = &_wiringPiISR_callback_pin27; break;
+ case 28: func = &_wiringPiISR_callback_pin28; break;
+ case 29: func = &_wiringPiISR_callback_pin29; break;
+ case 30: func = &_wiringPiISR_callback_pin30; break;
+ case 31: func = &_wiringPiISR_callback_pin31; break;
+ case 32: func = &_wiringPiISR_callback_pin32; break;
+ case 33: func = &_wiringPiISR_callback_pin33; break;
+ case 34: func = &_wiringPiISR_callback_pin34; break;
+ case 35: func = &_wiringPiISR_callback_pin35; break;
+ case 36: func = &_wiringPiISR_callback_pin36; break;
+ case 37: func = &_wiringPiISR_callback_pin37; break;
+ case 38: func = &_wiringPiISR_callback_pin38; break;
+ case 39: func = &_wiringPiISR_callback_pin39; break;
+ case 40: func = &_wiringPiISR_callback_pin40; break;
+ case 41: func = &_wiringPiISR_callback_pin41; break;
+ case 42: func = &_wiringPiISR_callback_pin42; break;
+ case 43: func = &_wiringPiISR_callback_pin43; break;
+ case 44: func = &_wiringPiISR_callback_pin44; break;
+ case 45: func = &_wiringPiISR_callback_pin45; break;
+ case 46: func = &_wiringPiISR_callback_pin46; break;
+ case 47: func = &_wiringPiISR_callback_pin47; break;
+ case 48: func = &_wiringPiISR_callback_pin48; break;
+ case 49: func = &_wiringPiISR_callback_pin49; break;
+ case 50: func = &_wiringPiISR_callback_pin50; break;
+ case 51: func = &_wiringPiISR_callback_pin51; break;
+ case 52: func = &_wiringPiISR_callback_pin52; break;
+ case 53: func = &_wiringPiISR_callback_pin53; break;
+ case 54: func = &_wiringPiISR_callback_pin54; break;
+ case 55: func = &_wiringPiISR_callback_pin55; break;
+ case 56: func = &_wiringPiISR_callback_pin56; break;
+ case 57: func = &_wiringPiISR_callback_pin57; break;
+ case 58: func = &_wiringPiISR_callback_pin58; break;
+ case 59: func = &_wiringPiISR_callback_pin59; break;
+ case 60: func = &_wiringPiISR_callback_pin60; break;
+ case 61: func = &_wiringPiISR_callback_pin61; break;
+ case 62: func = &_wiringPiISR_callback_pin62; break;
+ case 63: func = &_wiringPiISR_callback_pin63; break;
+ }
+
+ // register our dedicated function in WiringPi
+ wiringPiISR(pin, mode, func);
+}
+
+%}
+
extern int wiringPiFailure (int fatal, const char *message, ...) ;
extern struct wiringPiNodeStruct *wiringPiFindNode (int pin) ;
extern struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) ;
@@ -80,7 +269,13 @@
// Interrupts
extern int waitForInterrupt (int pin, int mS) ;
-extern int wiringPiISR (int pin, int mode, void (*function)(void)) ;
+
+// overlay normal function with our wrapper
+%rename("wiringPiISR") wiringPiISRWrapper (int pin, int mode, PyObject *PyFunc);
+static void wiringPiISRWrapper(int pin, int mode, PyObject *PyFunc);
+
+// note: native C function is not exported:
+//extern int wiringPiISR (int pin, int mode, void (*function)(void)) ;
// Threads
extern int piThreadCreate (void *(*fn)(void *)) ;