static int gpio_wait(int pin) { char path[BUFFER_MAX]; int fd; snprintf(path, BUFFER_MAX, "/sys/class/gpio/gpio%d/value", pin); fd = open(path, O_RDONLY); if (-1 == fd) { fprintf(stderr, "Failed to open gpio for reading!\n"); return -1; } read(fd, path, 3); struct pollfd p = { .fd = fd, .events = POLLPRI|POLLERR, }; int r = poll(&p, 1, -1); if(r != 1) { fprintf(stderr, "poll() failed!\n"); close(fd); return -1; } close(fd); return 0; } int main(int argv, char** argc) { if(gpio_export(PIN)) { return 1; } gpio_direction(PIN, IN); setup(); setup_gpio(POUT, OUTPUT, PUD_OFF); while(1) { gpio_edge(PIN, RISING); gpio_wait(PIN); output_gpio(POUT, HIGH); gpio_edge(PIN, FALLING); gpio_wait(PIN); output_gpio(POUT, LOW); } if(gpio_unexport(PIN)) { return 1; } return 0; }
// python function setup(channel, direction, pull_up_down=PUD_OFF, initial=None) static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwargs) { unsigned int gpio; int channel, direction; int pud = PUD_OFF + PY_PUD_CONST_OFFSET; int initial = -1; static char *kwlist[] = {"channel", "direction", "pull_up_down", "initial", NULL}; int func; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|ii", kwlist, &channel, &direction, &pud, &initial)) return NULL; // check module has been imported cleanly if (setup_error) { PyErr_SetString(PyExc_RuntimeError, "Module not imported correctly!"); return NULL; } // run init_module if module not set up if (!module_setup && (init_module() != SETUP_OK)) return NULL; if (get_gpio_number(channel, &gpio)) return NULL; if (direction != INPUT && direction != OUTPUT) { PyErr_SetString(PyExc_ValueError, "An invalid direction was passed to setup()"); return NULL; } if (direction == OUTPUT) pud = PUD_OFF + PY_PUD_CONST_OFFSET; pud -= PY_PUD_CONST_OFFSET; if (pud != PUD_OFF && pud != PUD_DOWN && pud != PUD_UP) { PyErr_SetString(PyExc_ValueError, "Invalid value for pull_up_down - should be either PUD_OFF, PUD_UP or PUD_DOWN"); return NULL; } func = gpio_function(gpio); if (gpio_warnings && // warnings enabled and ((func != 0 && func != 1) || // (already one of the alt functions or (gpio_direction[gpio] == -1 && func == 1))) // already an output not set from this program) { PyErr_WarnEx(NULL, "This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.", 1); } if (direction == OUTPUT && (initial == LOW || initial == HIGH)) { output_gpio(gpio, initial); } setup_gpio(gpio, direction, pud); gpio_direction[gpio] = direction; Py_RETURN_NONE; }
void irpause() { struct timespec ts = { .tv_sec = 0, .tv_nsec = 450000 }; while(nanosleep(&ts, &ts) < 0 && errno == EINTR) ; } void write_byte(uint8_t byte) { for(int i = 0; i < 8; i++) { if(byte & 1) { output_gpio(gpio_pin, HIGH); } irpause(); if(byte & 1) { output_gpio(gpio_pin, LOW); } irpause(); byte >>= 1; } } int main(int argc, const char** argv) { if(argc < 2 || !(gpio_pin = atoi(argv[1]))) { fprintf(stderr, "usage: irtx <gpio pin>\n"); } if(setup() != SETUP_OK) { fprintf(stderr, "could not set up GPIO\n"); } setup_gpio(gpio_pin, OUTPUT, PUD_OFF); write_byte('X'); cleanup(); }
// python function setup(channel, direction, pull_up_down=PUD_OFF, initial=None) static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwargs) { unsigned int gpio; int channel, direction; int pud = PUD_OFF; int initial = -1; static char *kwlist[] = {"channel", "direction", "pull_up_down", "initial", NULL}; int func; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|ii", kwlist, &channel, &direction, &pud, &initial)) return NULL; if (get_gpio_number(channel, &gpio)) return NULL; if (direction != INPUT && direction != OUTPUT) { PyErr_SetString(InvalidDirectionException, "An invalid direction was passed to setup()"); return NULL; } if (direction == OUTPUT) pud = PUD_OFF; if (pud != PUD_OFF && pud != PUD_DOWN && pud != PUD_UP) { PyErr_SetString(InvalidPullException, "Invalid value for pull_up_down - should be either PUD_OFF, PUD_UP or PUD_DOWN"); return NULL; } func = gpio_function(gpio); if (gpio_warnings && // warnings enabled and ((func != 0 && func != 1) || // (already one of the alt functions or (gpio_direction[gpio] == -1 && func == 1))) // already an output not set from this program) { PyErr_WarnEx(NULL, "This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.", 1); } // printf("Setup GPIO %d direction %d pud %d\n", gpio, direction, pud); if (direction == OUTPUT && (initial == LOW || initial == HIGH)) { // printf("Writing intial value %d\n",initial); output_gpio(gpio, initial); } setup_gpio(gpio, direction, pud); gpio_direction[gpio] = direction; Py_INCREF(Py_None); return Py_None; }
// python function setup(channel, direction, pull_up_down=PUD_OFF, initial=None) static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwargs) { unsigned int gpio; int channel, direction; unsigned int sys_gpio; int pud = PUD_OFF + PY_PUD_CONST_OFFSET; static char *kwlist[] = {"channel", "direction", "pull_up_down", "initial", NULL}; int initial = -1; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|ii", kwlist, &channel, &direction, &pud, &initial)) return NULL; // check module has been imported cleanly if (setup_error) { PyErr_SetString(PyExc_RuntimeError, "Module not imported correctly!"); return NULL; } if (get_gpio_number(channel, &gpio, &sys_gpio)){ return NULL; } if (direction != INPUT && direction != OUTPUT) { PyErr_SetString(PyExc_ValueError, "An invalid direction was passed to setup()"); return NULL; } if (direction == OUTPUT) pud = PUD_OFF + PY_PUD_CONST_OFFSET; pud -= PY_PUD_CONST_OFFSET; if (pud != PUD_OFF && pud != PUD_DOWN && pud != PUD_UP) { PyErr_SetString(PyExc_ValueError, "Invalid value for pull_up_down - should be either PUD_OFF, PUD_UP or PUD_DOWN"); return NULL; } if (direction == OUTPUT && (initial == LOW || initial == HIGH)) { output_gpio(gpio, initial); } setup_gpio(gpio, direction, pud); gpio_direction[sys_gpio] = direction; Py_RETURN_NONE; }
// python function output(channel, value) static PyObject *py_output_gpio(PyObject *self, PyObject *args) { int gpio, channel, value; if (!PyArg_ParseTuple(args, "ii", &channel, &value)) return NULL; if (gpio_mode != BOARD && gpio_mode != BCM) { PyErr_SetString(ModeNotSetException, "Please set mode using GPIO.setmode(GPIO.BOARD) or GPIO.setmode(GPIO.BCM)"); return NULL; } if ( (gpio_mode == BCM && (channel < 0 || channel > 53)) || (gpio_mode == BOARD && (channel < 1 || channel > 26)) ) { PyErr_SetString(InvalidChannelException, "The channel sent is invalid on a Raspberry Pi"); return NULL; } if (gpio_mode == BOARD) { gpio = pin_to_gpio[channel]; if (gpio == -1) { PyErr_SetString(InvalidChannelException, "The channel sent is invalid on a Raspberry Pi"); return NULL; } } else // gpio_mode == BCM { gpio = channel; } if (gpio_direction[gpio] != OUTPUT) { PyErr_SetString(WrongDirectionException, "The GPIO channel has not been set up or is set up in the wrong direction"); return NULL; } // printf("Output GPIO %d value %d\n", gpio, value); output_gpio(gpio, value); Py_INCREF(Py_None); return Py_None; }
// python function output(channel, value) without direction check static PyObject* py_forceoutput_gpio(PyObject *self, PyObject *args) { int gpio, channel, value; if (!PyArg_ParseTuple(args, "ii", &channel, &value)) return NULL; // printf("Output GPIO %d value %d\n", gpio, value); if ((gpio = channel_to_gpio(channel)) < 0) return NULL; output_gpio(gpio, value); Py_INCREF(Py_None); return Py_None; }
// python function output(channel, value) static PyObject *py_output_gpio(PyObject *self, PyObject *args) { unsigned int gpio; int channel, value; if (!PyArg_ParseTuple(args, "ii", &channel, &value)) return NULL; if (get_gpio_number(channel, &gpio)) return NULL; if (gpio_direction[gpio] != OUTPUT) { PyErr_SetString(PyExc_RuntimeError, "The GPIO channel has not been set up as an OUTPUT"); return NULL; } output_gpio(gpio, value); Py_RETURN_NONE; }
// python function output(channel, value) static PyObject* py_output_gpio(PyObject *self, PyObject *args) { int gpio, channel, value; if (!PyArg_ParseTuple(args, "ii", &channel, &value)) return NULL; if ((gpio = channel_to_gpio(channel)) < 0) return NULL; if (gpio_direction[gpio] != OUTPUT) { PyErr_SetString(WrongDirectionException, "The GPIO channel has not been set up as an OUTPUT"); return NULL; } // printf("Output GPIO %d value %d\n", gpio, value); output_gpio(gpio, value); Py_INCREF(Py_None); return Py_None; }