Skip to content

Commit 8b4f7f2

Browse files
authored
Merge pull request #123 from bubbapizza/master
Added a delay parameter for GPIO.setup() for udev permissions
2 parents 4371949 + 9553b1a commit 8b4f7f2

File tree

2 files changed

+32
-21
lines changed

2 files changed

+32
-21
lines changed

source/event_gpio.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ int gpio_set_direction(unsigned int gpio, unsigned int in_flag)
233233
char filename[40];
234234
char direction[10] = { 0 };
235235

236+
if ((gpio >= USR_LED_GPIO_MIN) && (gpio <= USR_LED_GPIO_MAX)) {
237+
return 0; // direction is not applicable to the USR LED pins
238+
}
239+
236240
snprintf(filename, sizeof(filename), "/sys/class/gpio/gpio%d/direction", gpio);
237241
if ((fd = open(filename, O_WRONLY)) < 0)
238242
return -1;

source/py_gpio.c

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ SOFTWARE.
3333
#include "common.h"
3434
#include "event_gpio.h"
3535
#include "c_pinmux.h"
36+
#include <unistd.h>
3637

3738
static int gpio_warnings = 1;
3839

@@ -68,18 +69,22 @@ static PyObject *py_cleanup(PyObject *self, PyObject *args)
6869
Py_RETURN_NONE;
6970
}
7071

71-
// python function setup(channel, direction, pull_up_down=PUD_OFF, initial=None)
72+
// python function setup(channel, direction, pull_up_down=PUD_OFF, initial=None, delay=0)
7273
static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwargs)
7374
{
7475
unsigned int gpio;
7576
char *channel;
7677
int direction;
7778
int pud = PUD_OFF;
7879
int initial = 0;
80+
int delay = 0; // time in milliseconds to wait after exporting gpio pin
7981
BBIO_err err;
80-
static char *kwlist[] = {"channel", "direction", "pull_up_down", "initial", NULL};
82+
static char *kwlist[] = {"channel", "direction", "pull_up_down", "initial", "delay", NULL};
83+
int res;
84+
// char error[30];
8185

82-
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si|ii", kwlist, &channel, &direction, &pud, &initial))
86+
87+
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si|iii", kwlist, &channel, &direction, &pud, &initial, &delay))
8388
return NULL;
8489

8590
if (!module_setup) {
@@ -107,28 +112,30 @@ static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwar
107112
if (err != BBIO_OK)
108113
return NULL;
109114

110-
unsigned int count = 100000;
111-
int res = -1;
112-
do { // wait until gpio file appears on the filesystem
113-
res = gpio_export(gpio);
114-
} while(res != 0 && count-- > 0);
115-
if(count == 0)
116-
return NULL;
115+
// Export the GPIO pins using sysfs
116+
gpio_export(gpio);
117+
118+
// See if a delay was specified in order to give udev some time
119+
// to set file permissions.
120+
if (delay > 0)
121+
nanosleep((struct timespec[]){{0, delay * 1000000}}, NULL);
117122

118-
count = 100000;
119-
do {
120-
res = gpio_set_direction(gpio, direction);
121-
} while(res != 0 && count-- > 0);
122-
if(count == 0)
123+
// Set the pin direction and bail if we get an error.
124+
res = gpio_set_direction(gpio, direction);
125+
if(res != 0) {
126+
PyErr_SetString(PyExc_ValueError, "Set gpio direction failed, missing file or invalid permissions.");
123127
return NULL;
128+
}
124129

125130
if (direction == OUTPUT) {
126-
count = 100000;
127-
do {
128-
res = gpio_set_value(gpio, initial);
129-
} while(res != 0 && count-- > 0);
130-
if(count == 0)
131+
132+
// Set the pin value and bail if we get an error.
133+
res = gpio_set_value(gpio, initial);
134+
if(res != 0) {
135+
PyErr_SetString(PyExc_ValueError, "Set gpio value failed, missing file or invalid permissions.");
131136
return NULL;
137+
}
138+
132139
} else {
133140
if (pud == PUD_DOWN)
134141
set_pin_mode(channel, "gpio_pd");
@@ -522,7 +529,7 @@ static PyObject *py_setwarnings(PyObject *self, PyObject *args)
522529
static const char moduledocstring[] = "GPIO functionality of a BeagleBone using Python";
523530

524531
PyMethodDef gpio_methods[] = {
525-
{"setup", (PyCFunction)py_setup_channel, METH_VARARGS | METH_KEYWORDS, "Set up the GPIO channel, direction and (optional) pull/up down control\nchannel - Either: RPi board pin number (not BCM GPIO 00..nn number). Pins start from 1\n or : BCM GPIO number\ndirection - INPUT or OUTPUT\n[pull_up_down] - PUD_OFF (default), PUD_UP or PUD_DOWN\n[initial] - Initial value for an output channel"},
532+
{"setup", (PyCFunction)py_setup_channel, METH_VARARGS | METH_KEYWORDS, "Set up the GPIO channel, direction and (optional) pull/up down control\nchannel - Either: RPi board pin number (not BCM GPIO 00..nn number). Pins start from 1\n or : BCM GPIO number\ndirection - INPUT or OUTPUT\n[pull_up_down] - PUD_OFF (default), PUD_UP or PUD_DOWN\n[initial] - Initial value for an output channel\n[delay] - Time in milliseconds to wait after exporting gpio pin"},
526533
{"cleanup", py_cleanup, METH_VARARGS, "Clean up by resetting all GPIO channels that have been used by this program to INPUT with no pullup/pulldown and no event detection"},
527534
{"output", py_output_gpio, METH_VARARGS, "Output to a GPIO channel\ngpio - gpio channel\nvalue - 0/1 or False/True or LOW/HIGH"},
528535
{"input", py_input_gpio, METH_VARARGS, "Input from a GPIO channel. Returns HIGH=1=True or LOW=0=False\ngpio - gpio channel"},

0 commit comments

Comments
 (0)