rpi_gpio 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,36 @@
1
+ /*
2
+ Copyright (c) 2013-2014 Ben Croston
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ this software and associated documentation files (the "Software"), to deal in
6
+ the Software without restriction, including without limitation the rights to
7
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8
+ of the Software, and to permit persons to whom the Software is furnished to do
9
+ so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ SOFTWARE.
21
+ */
22
+
23
+ #define NO_EDGE 0
24
+ #define RISING_EDGE 1
25
+ #define FALLING_EDGE 2
26
+ #define BOTH_EDGE 3
27
+
28
+ int add_edge_detect(unsigned int gpio, unsigned int edge, int bouncetime);
29
+ void remove_edge_detect(unsigned int gpio);
30
+ int add_edge_callback(unsigned int gpio, void (*func)(unsigned int gpio));
31
+ int event_detected(unsigned int gpio);
32
+ int gpio_event_added(unsigned int gpio);
33
+ int event_initialise(void);
34
+ void event_cleanup(unsigned int gpio);
35
+ void event_cleanup_all(void);
36
+ int blocking_wait_for_edge(unsigned int gpio, unsigned int edge, int bouncetime);
@@ -0,0 +1,1048 @@
1
+ /*
2
+ Copyright (c) 2012-2015 Ben Croston
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ this software and associated documentation files (the "Software"), to deal in
6
+ the Software without restriction, including without limitation the rights to
7
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8
+ of the Software, and to permit persons to whom the Software is furnished to do
9
+ so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ SOFTWARE.
21
+ */
22
+
23
+ #include "Python.h"
24
+ #include "c_gpio.h"
25
+ #include "event_gpio.h"
26
+ #include "py_pwm.h"
27
+ #include "cpuinfo.h"
28
+ #include "constants.h"
29
+ #include "common.h"
30
+
31
+ static PyObject *rpi_revision; // deprecated
32
+ static PyObject *board_info;
33
+ static int gpio_warnings = 1;
34
+
35
+ struct py_callback
36
+ {
37
+ unsigned int gpio;
38
+ PyObject *py_cb;
39
+ struct py_callback *next;
40
+ };
41
+ static struct py_callback *py_callbacks = NULL;
42
+
43
+ static int mmap_gpio_mem(void)
44
+ {
45
+ int result;
46
+
47
+ if (module_setup)
48
+ return 0;
49
+
50
+ result = setup();
51
+ if (result == SETUP_DEVMEM_FAIL)
52
+ {
53
+ PyErr_SetString(PyExc_RuntimeError, "No access to /dev/mem. Try running as root!");
54
+ return 1;
55
+ } else if (result == SETUP_MALLOC_FAIL) {
56
+ PyErr_NoMemory();
57
+ return 2;
58
+ } else if (result == SETUP_MMAP_FAIL) {
59
+ PyErr_SetString(PyExc_RuntimeError, "Mmap of GPIO registers failed");
60
+ return 3;
61
+ } else { // result == SETUP_OK
62
+ module_setup = 1;
63
+ return 0;
64
+ }
65
+ }
66
+
67
+ // python function cleanup(channel=None)
68
+ static PyObject *py_cleanup(PyObject *self, PyObject *args, PyObject *kwargs)
69
+ {
70
+ int i;
71
+ int chancount = -666;
72
+ int found = 0;
73
+ int channel = -666;
74
+ unsigned int gpio;
75
+ PyObject *chanlist = NULL;
76
+ PyObject *chantuple = NULL;
77
+ PyObject *tempobj;
78
+ static char *kwlist[] = {"channel", NULL};
79
+
80
+ void cleanup_one(void)
81
+ {
82
+ // clean up any /sys/class exports
83
+ event_cleanup(gpio);
84
+
85
+ // set everything back to input
86
+ if (gpio_direction[gpio] != -1) {
87
+ setup_gpio(gpio, INPUT, PUD_OFF);
88
+ gpio_direction[gpio] = -1;
89
+ found = 1;
90
+ }
91
+ }
92
+
93
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, &chanlist))
94
+ return NULL;
95
+
96
+ if (chanlist == NULL) { // channel kwarg not set
97
+ // do nothing
98
+ #if PY_MAJOR_VERSION > 2
99
+ } else if (PyLong_Check(chanlist)) {
100
+ channel = (int)PyLong_AsLong(chanlist);
101
+ #else
102
+ } else if (PyInt_Check(chanlist)) {
103
+ channel = (int)PyInt_AsLong(chanlist);
104
+ #endif
105
+ if (PyErr_Occurred())
106
+ return NULL;
107
+ chanlist = NULL;
108
+ } else if (PyList_Check(chanlist)) {
109
+ chancount = PyList_Size(chanlist);
110
+ } else if (PyTuple_Check(chanlist)) {
111
+ chantuple = chanlist;
112
+ chanlist = NULL;
113
+ chancount = PyTuple_Size(chantuple);
114
+ } else {
115
+ // raise exception
116
+ PyErr_SetString(PyExc_ValueError, "Channel must be an integer or list/tuple of integers");
117
+ return NULL;
118
+ }
119
+
120
+ if (module_setup && !setup_error) {
121
+ if (channel == -666 && chancount == -666) { // channel not set - cleanup everything
122
+ // clean up any /sys/class exports
123
+ event_cleanup_all();
124
+
125
+ // set everything back to input
126
+ for (i=0; i<54; i++) {
127
+ if (gpio_direction[i] != -1) {
128
+ setup_gpio(i, INPUT, PUD_OFF);
129
+ gpio_direction[i] = -1;
130
+ found = 1;
131
+ }
132
+ }
133
+ gpio_mode = MODE_UNKNOWN;
134
+ } else if (channel != -666) { // channel was an int indicating single channel
135
+ if (get_gpio_number(channel, &gpio))
136
+ return NULL;
137
+ cleanup_one();
138
+ } else { // channel was a list/tuple
139
+ for (i=0; i<chancount; i++) {
140
+ if (chanlist) {
141
+ if ((tempobj = PyList_GetItem(chanlist, i)) == NULL) {
142
+ return NULL;
143
+ }
144
+ } else { // assume chantuple
145
+ if ((tempobj = PyTuple_GetItem(chantuple, i)) == NULL) {
146
+ return NULL;
147
+ }
148
+ }
149
+
150
+ #if PY_MAJOR_VERSION > 2
151
+ if (PyLong_Check(tempobj)) {
152
+ channel = (int)PyLong_AsLong(tempobj);
153
+ #else
154
+ if (PyInt_Check(tempobj)) {
155
+ channel = (int)PyInt_AsLong(tempobj);
156
+ #endif
157
+ if (PyErr_Occurred())
158
+ return NULL;
159
+ } else {
160
+ PyErr_SetString(PyExc_ValueError, "Channel must be an integer");
161
+ return NULL;
162
+ }
163
+
164
+ if (get_gpio_number(channel, &gpio))
165
+ return NULL;
166
+ cleanup_one();
167
+ }
168
+ }
169
+ }
170
+
171
+ // check if any channels set up - if not warn about misuse of GPIO.cleanup()
172
+ if (!found && gpio_warnings) {
173
+ PyErr_WarnEx(NULL, "No channels have been set up yet - nothing to clean up! Try cleaning up at the end of your program instead!", 1);
174
+ }
175
+
176
+ Py_RETURN_NONE;
177
+ }
178
+
179
+ // python function setup(channel(s), direction, pull_up_down=PUD_OFF, initial=None)
180
+ static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwargs)
181
+ {
182
+ unsigned int gpio;
183
+ int channel = -1;
184
+ int direction;
185
+ int i, chancount;
186
+ PyObject *chanlist = NULL;
187
+ PyObject *chantuple = NULL;
188
+ PyObject *tempobj;
189
+ int pud = PUD_OFF + PY_PUD_CONST_OFFSET;
190
+ int initial = -1;
191
+ static char *kwlist[] = {"channel", "direction", "pull_up_down", "initial", NULL};
192
+ int func;
193
+
194
+ int setup_one(void) {
195
+ if (get_gpio_number(channel, &gpio))
196
+ return 0;
197
+
198
+ func = gpio_function(gpio);
199
+ if (gpio_warnings && // warnings enabled and
200
+ ((func != 0 && func != 1) || // (already one of the alt functions or
201
+ (gpio_direction[gpio] == -1 && func == 1))) // already an output not set from this program)
202
+ {
203
+ PyErr_WarnEx(NULL, "This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.", 1);
204
+ }
205
+
206
+ // warn about pull/up down on i2c channels
207
+ if (rpiinfo.p1_revision == 0) { // compute module - do nothing
208
+ } else if ((rpiinfo.p1_revision == 1 && (gpio == 0 || gpio == 1)) ||
209
+ (gpio == 2 || gpio == 3)) {
210
+ PyErr_WarnEx(NULL, "A physical pull up resistor is fitted on this channel!", 1);
211
+ }
212
+
213
+ if (direction == OUTPUT && (initial == LOW || initial == HIGH)) {
214
+ output_gpio(gpio, initial);
215
+ }
216
+ setup_gpio(gpio, direction, pud);
217
+ gpio_direction[gpio] = direction;
218
+ return 1;
219
+ }
220
+
221
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii", kwlist, &chanlist, &direction, &pud, &initial))
222
+ return NULL;
223
+
224
+ #if PY_MAJOR_VERSION > 2
225
+ if (PyLong_Check(chanlist)) {
226
+ channel = (int)PyLong_AsLong(chanlist);
227
+ #else
228
+ if (PyInt_Check(chanlist)) {
229
+ channel = (int)PyInt_AsLong(chanlist);
230
+ #endif
231
+ if (PyErr_Occurred())
232
+ return NULL;
233
+ chanlist = NULL;
234
+ } else if PyList_Check(chanlist) {
235
+ // do nothing
236
+ } else if PyTuple_Check(chanlist) {
237
+ chantuple = chanlist;
238
+ chanlist = NULL;
239
+ } else {
240
+ // raise exception
241
+ PyErr_SetString(PyExc_ValueError, "Channel must be an integer or list/tuple of integers");
242
+ return NULL;
243
+ }
244
+
245
+ // check module has been imported cleanly
246
+ if (setup_error)
247
+ {
248
+ PyErr_SetString(PyExc_RuntimeError, "Module not imported correctly!");
249
+ return NULL;
250
+ }
251
+
252
+ if (mmap_gpio_mem())
253
+ return NULL;
254
+
255
+ if (direction != INPUT && direction != OUTPUT) {
256
+ PyErr_SetString(PyExc_ValueError, "An invalid direction was passed to setup()");
257
+ return 0;
258
+ }
259
+
260
+ if (direction == OUTPUT)
261
+ pud = PUD_OFF + PY_PUD_CONST_OFFSET;
262
+
263
+ pud -= PY_PUD_CONST_OFFSET;
264
+ if (pud != PUD_OFF && pud != PUD_DOWN && pud != PUD_UP) {
265
+ PyErr_SetString(PyExc_ValueError, "Invalid value for pull_up_down - should be either PUD_OFF, PUD_UP or PUD_DOWN");
266
+ return NULL;
267
+ }
268
+
269
+ if (chanlist) {
270
+ chancount = PyList_Size(chanlist);
271
+ } else if (chantuple) {
272
+ chancount = PyTuple_Size(chantuple);
273
+ } else {
274
+ if (!setup_one())
275
+ return NULL;
276
+ Py_RETURN_NONE;
277
+ }
278
+
279
+ for (i=0; i<chancount; i++) {
280
+ if (chanlist) {
281
+ if ((tempobj = PyList_GetItem(chanlist, i)) == NULL) {
282
+ return NULL;
283
+ }
284
+ } else { // assume chantuple
285
+ if ((tempobj = PyTuple_GetItem(chantuple, i)) == NULL) {
286
+ return NULL;
287
+ }
288
+ }
289
+
290
+ #if PY_MAJOR_VERSION > 2
291
+ if (PyLong_Check(tempobj)) {
292
+ channel = (int)PyLong_AsLong(tempobj);
293
+ #else
294
+ if (PyInt_Check(tempobj)) {
295
+ channel = (int)PyInt_AsLong(tempobj);
296
+ #endif
297
+ if (PyErr_Occurred())
298
+ return NULL;
299
+ } else {
300
+ PyErr_SetString(PyExc_ValueError, "Channel must be an integer");
301
+ return NULL;
302
+ }
303
+
304
+ if (!setup_one())
305
+ return NULL;
306
+ }
307
+
308
+ Py_RETURN_NONE;
309
+ }
310
+
311
+ // python function output(channel(s), value(s))
312
+ static PyObject *py_output_gpio(PyObject *self, PyObject *args)
313
+ {
314
+ unsigned int gpio;
315
+ int channel = -1;
316
+ int value = -1;
317
+ int i;
318
+ PyObject *chanlist = NULL;
319
+ PyObject *valuelist = NULL;
320
+ PyObject *chantuple = NULL;
321
+ PyObject *valuetuple = NULL;
322
+ PyObject *tempobj = NULL;
323
+ int chancount = -1;
324
+ int valuecount = -1;
325
+
326
+ int output(void) {
327
+ if (get_gpio_number(channel, &gpio))
328
+ return 0;
329
+
330
+ if (gpio_direction[gpio] != OUTPUT)
331
+ {
332
+ PyErr_SetString(PyExc_RuntimeError, "The GPIO channel has not been set up as an OUTPUT");
333
+ return 0;
334
+ }
335
+
336
+ if (check_gpio_priv())
337
+ return 0;
338
+
339
+ output_gpio(gpio, value);
340
+ return 1;
341
+ }
342
+
343
+ if (!PyArg_ParseTuple(args, "OO", &chanlist, &valuelist))
344
+ return NULL;
345
+
346
+ #if PY_MAJOR_VERSION >= 3
347
+ if (PyLong_Check(chanlist)) {
348
+ channel = (int)PyLong_AsLong(chanlist);
349
+ #else
350
+ if (PyInt_Check(chanlist)) {
351
+ channel = (int)PyInt_AsLong(chanlist);
352
+ #endif
353
+ if (PyErr_Occurred())
354
+ return NULL;
355
+ chanlist = NULL;
356
+ } else if (PyList_Check(chanlist)) {
357
+ // do nothing
358
+ } else if (PyTuple_Check(chanlist)) {
359
+ chantuple = chanlist;
360
+ chanlist = NULL;
361
+ } else {
362
+ PyErr_SetString(PyExc_ValueError, "Channel must be an integer or list/tuple of integers");
363
+ return NULL;
364
+ }
365
+
366
+ #if PY_MAJOR_VERSION >= 3
367
+ if (PyLong_Check(valuelist)) {
368
+ value = (int)PyLong_AsLong(valuelist);
369
+ #else
370
+ if (PyInt_Check(valuelist)) {
371
+ value = (int)PyInt_AsLong(valuelist);
372
+ #endif
373
+ if (PyErr_Occurred())
374
+ return NULL;
375
+ valuelist = NULL;
376
+ } else if (PyList_Check(valuelist)) {
377
+ // do nothing
378
+ } else if (PyTuple_Check(valuelist)) {
379
+ valuetuple = valuelist;
380
+ valuelist = NULL;
381
+ } else {
382
+ PyErr_SetString(PyExc_ValueError, "Value must be an integer/boolean or a list/tuple of integers/booleans");
383
+ return NULL;
384
+ }
385
+
386
+ if (chanlist)
387
+ chancount = PyList_Size(chanlist);
388
+ if (chantuple)
389
+ chancount = PyTuple_Size(chantuple);
390
+ if (valuelist)
391
+ valuecount = PyList_Size(valuelist);
392
+ if (valuetuple)
393
+ valuecount = PyTuple_Size(valuetuple);
394
+ if ((chancount != -1 && chancount != valuecount && valuecount != -1) || (chancount == -1 && valuecount != -1)) {
395
+ PyErr_SetString(PyExc_RuntimeError, "Number of channels != number of values");
396
+ return NULL;
397
+ }
398
+
399
+ if (chancount == -1) {
400
+ if (!output())
401
+ return NULL;
402
+ Py_RETURN_NONE;
403
+ }
404
+
405
+ for (i=0; i<chancount; i++) {
406
+ // get channel number
407
+ if (chanlist) {
408
+ if ((tempobj = PyList_GetItem(chanlist, i)) == NULL) {
409
+ return NULL;
410
+ }
411
+ } else { // assume chantuple
412
+ if ((tempobj = PyTuple_GetItem(chantuple, i)) == NULL) {
413
+ return NULL;
414
+ }
415
+ }
416
+
417
+ #if PY_MAJOR_VERSION >= 3
418
+ if (PyLong_Check(tempobj)) {
419
+ channel = (int)PyLong_AsLong(tempobj);
420
+ #else
421
+ if (PyInt_Check(tempobj)) {
422
+ channel = (int)PyInt_AsLong(tempobj);
423
+ #endif
424
+ if (PyErr_Occurred())
425
+ return NULL;
426
+ } else {
427
+ PyErr_SetString(PyExc_ValueError, "Channel must be an integer");
428
+ return NULL;
429
+ }
430
+
431
+ // get value
432
+ if (valuecount > 0) {
433
+ if (valuelist) {
434
+ if ((tempobj = PyList_GetItem(valuelist, i)) == NULL) {
435
+ return NULL;
436
+ }
437
+ } else { // assume valuetuple
438
+ if ((tempobj = PyTuple_GetItem(valuetuple, i)) == NULL) {
439
+ return NULL;
440
+ }
441
+ }
442
+ #if PY_MAJOR_VERSION >= 3
443
+ if (PyLong_Check(tempobj)) {
444
+ value = (int)PyLong_AsLong(tempobj);
445
+ #else
446
+ if (PyInt_Check(tempobj)) {
447
+ value = (int)PyInt_AsLong(tempobj);
448
+ #endif
449
+ if (PyErr_Occurred())
450
+ return NULL;
451
+ } else {
452
+ PyErr_SetString(PyExc_ValueError, "Value must be an integer or boolean");
453
+ return NULL;
454
+ }
455
+ }
456
+ if (!output())
457
+ return NULL;
458
+ }
459
+
460
+ Py_RETURN_NONE;
461
+ }
462
+
463
+ // python function value = input(channel)
464
+ static PyObject *py_input_gpio(PyObject *self, PyObject *args)
465
+ {
466
+ unsigned int gpio;
467
+ int channel;
468
+ PyObject *value;
469
+
470
+ if (!PyArg_ParseTuple(args, "i", &channel))
471
+ return NULL;
472
+
473
+ if (get_gpio_number(channel, &gpio))
474
+ return NULL;
475
+
476
+ // check channel is set up as an input or output
477
+ if (gpio_direction[gpio] != INPUT && gpio_direction[gpio] != OUTPUT)
478
+ {
479
+ PyErr_SetString(PyExc_RuntimeError, "You must setup() the GPIO channel first");
480
+ return NULL;
481
+ }
482
+
483
+ if (check_gpio_priv())
484
+ return NULL;
485
+
486
+ if (input_gpio(gpio)) {
487
+ value = Py_BuildValue("i", HIGH);
488
+ } else {
489
+ value = Py_BuildValue("i", LOW);
490
+ }
491
+ return value;
492
+ }
493
+
494
+ // python function setmode(mode)
495
+ static PyObject *py_setmode(PyObject *self, PyObject *args)
496
+ {
497
+ int new_mode;
498
+
499
+ if (!PyArg_ParseTuple(args, "i", &new_mode))
500
+ return NULL;
501
+
502
+ if (gpio_mode != MODE_UNKNOWN && new_mode != gpio_mode)
503
+ {
504
+ PyErr_SetString(PyExc_ValueError, "A different mode has already been set!");
505
+ return NULL;
506
+ }
507
+
508
+ if (setup_error)
509
+ {
510
+ PyErr_SetString(PyExc_RuntimeError, "Module not imported correctly!");
511
+ return NULL;
512
+ }
513
+
514
+ gpio_mode = new_mode;
515
+
516
+ if (gpio_mode != BOARD && gpio_mode != BCM)
517
+ {
518
+ PyErr_SetString(PyExc_ValueError, "An invalid mode was passed to setmode()");
519
+ return NULL;
520
+ }
521
+
522
+ if (rpiinfo.p1_revision == 0 && gpio_mode == BOARD)
523
+ {
524
+ PyErr_SetString(PyExc_RuntimeError, "BOARD numbering system not applicable on compute module");
525
+ return NULL;
526
+ }
527
+ Py_RETURN_NONE;
528
+ }
529
+
530
+ // python function getmode()
531
+ static PyObject *py_getmode(PyObject *self, PyObject *args)
532
+ {
533
+ PyObject *value;
534
+
535
+ if (setup_error)
536
+ {
537
+ PyErr_SetString(PyExc_RuntimeError, "Module not imported correctly!");
538
+ return NULL;
539
+ }
540
+
541
+ value = Py_BuildValue("i", gpio_mode);
542
+ return value;
543
+ }
544
+
545
+ static unsigned int chan_from_gpio(unsigned int gpio)
546
+ {
547
+ int chan;
548
+ int chans;
549
+
550
+ if (gpio_mode == BCM)
551
+ return gpio;
552
+ if (rpiinfo.p1_revision == 0) // not applicable for compute module
553
+ return -1;
554
+ else if (rpiinfo.p1_revision == 1 || rpiinfo.p1_revision == 2)
555
+ chans = 26;
556
+ else
557
+ chans = 40;
558
+ for (chan=1; chan<=chans; chan++)
559
+ if (*(*pin_to_gpio+chan) == gpio)
560
+ return chan;
561
+ return -1;
562
+ }
563
+
564
+ static void run_py_callbacks(unsigned int gpio)
565
+ {
566
+ PyObject *result;
567
+ PyGILState_STATE gstate;
568
+ struct py_callback *cb = py_callbacks;
569
+
570
+ while (cb != NULL)
571
+ {
572
+ if (cb->gpio == gpio) {
573
+ // run callback
574
+ gstate = PyGILState_Ensure();
575
+ result = PyObject_CallFunction(cb->py_cb, "i", chan_from_gpio(gpio));
576
+ if (result == NULL && PyErr_Occurred()){
577
+ PyErr_Print();
578
+ PyErr_Clear();
579
+ }
580
+ Py_XDECREF(result);
581
+ PyGILState_Release(gstate);
582
+ }
583
+ cb = cb->next;
584
+ }
585
+ }
586
+
587
+ static int add_py_callback(unsigned int gpio, PyObject *cb_func)
588
+ {
589
+ struct py_callback *new_py_cb;
590
+ struct py_callback *cb = py_callbacks;
591
+
592
+ // add callback to py_callbacks list
593
+ new_py_cb = malloc(sizeof(struct py_callback));
594
+ if (new_py_cb == 0)
595
+ {
596
+ PyErr_NoMemory();
597
+ return -1;
598
+ }
599
+ new_py_cb->py_cb = cb_func;
600
+ Py_XINCREF(cb_func); // Add a reference to new callback
601
+ new_py_cb->gpio = gpio;
602
+ new_py_cb->next = NULL;
603
+ if (py_callbacks == NULL) {
604
+ py_callbacks = new_py_cb;
605
+ } else {
606
+ // add to end of list
607
+ while (cb->next != NULL)
608
+ cb = cb->next;
609
+ cb->next = new_py_cb;
610
+ }
611
+ add_edge_callback(gpio, run_py_callbacks);
612
+ return 0;
613
+ }
614
+
615
+ // python function add_event_callback(gpio, callback)
616
+ static PyObject *py_add_event_callback(PyObject *self, PyObject *args, PyObject *kwargs)
617
+ {
618
+ unsigned int gpio;
619
+ int channel;
620
+ PyObject *cb_func;
621
+ char *kwlist[] = {"gpio", "callback", NULL};
622
+
623
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO|i", kwlist, &channel, &cb_func))
624
+ return NULL;
625
+
626
+ if (!PyCallable_Check(cb_func))
627
+ {
628
+ PyErr_SetString(PyExc_TypeError, "Parameter must be callable");
629
+ return NULL;
630
+ }
631
+
632
+ if (get_gpio_number(channel, &gpio))
633
+ return NULL;
634
+
635
+ // check channel is set up as an input
636
+ if (gpio_direction[gpio] != INPUT)
637
+ {
638
+ PyErr_SetString(PyExc_RuntimeError, "You must setup() the GPIO channel as an input first");
639
+ return NULL;
640
+ }
641
+
642
+ if (!gpio_event_added(gpio))
643
+ {
644
+ PyErr_SetString(PyExc_RuntimeError, "Add event detection using add_event_detect first before adding a callback");
645
+ return NULL;
646
+ }
647
+
648
+ if (add_py_callback(gpio, cb_func) != 0)
649
+ return NULL;
650
+
651
+ Py_RETURN_NONE;
652
+ }
653
+
654
+ // python function add_event_detect(gpio, edge, callback=None, bouncetime=None)
655
+ static PyObject *py_add_event_detect(PyObject *self, PyObject *args, PyObject *kwargs)
656
+ {
657
+ unsigned int gpio;
658
+ int channel, edge, result;
659
+ int bouncetime = -666;
660
+ PyObject *cb_func = NULL;
661
+ char *kwlist[] = {"gpio", "edge", "callback", "bouncetime", NULL};
662
+
663
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|Oi", kwlist, &channel, &edge, &cb_func, &bouncetime))
664
+ return NULL;
665
+
666
+ if (cb_func != NULL && !PyCallable_Check(cb_func))
667
+ {
668
+ PyErr_SetString(PyExc_TypeError, "Parameter must be callable");
669
+ return NULL;
670
+ }
671
+
672
+ if (get_gpio_number(channel, &gpio))
673
+ return NULL;
674
+
675
+ // check channel is set up as an input
676
+ if (gpio_direction[gpio] != INPUT)
677
+ {
678
+ PyErr_SetString(PyExc_RuntimeError, "You must setup() the GPIO channel as an input first");
679
+ return NULL;
680
+ }
681
+
682
+ // is edge valid value
683
+ edge -= PY_EVENT_CONST_OFFSET;
684
+ if (edge != RISING_EDGE && edge != FALLING_EDGE && edge != BOTH_EDGE)
685
+ {
686
+ PyErr_SetString(PyExc_ValueError, "The edge must be set to RISING, FALLING or BOTH");
687
+ return NULL;
688
+ }
689
+
690
+ if (bouncetime <= 0 && bouncetime != -666)
691
+ {
692
+ PyErr_SetString(PyExc_ValueError, "Bouncetime must be greater than 0");
693
+ return NULL;
694
+ }
695
+
696
+ if (check_gpio_priv())
697
+ return NULL;
698
+
699
+ if ((result = add_edge_detect(gpio, edge, bouncetime)) != 0) // starts a thread
700
+ {
701
+ if (result == 1)
702
+ {
703
+ PyErr_SetString(PyExc_RuntimeError, "Conflicting edge detection already enabled for this GPIO channel");
704
+ return NULL;
705
+ } else {
706
+ PyErr_SetString(PyExc_RuntimeError, "Failed to add edge detection");
707
+ return NULL;
708
+ }
709
+ }
710
+
711
+ if (cb_func != NULL)
712
+ if (add_py_callback(gpio, cb_func) != 0)
713
+ return NULL;
714
+
715
+ Py_RETURN_NONE;
716
+ }
717
+
718
+ // python function remove_event_detect(gpio)
719
+ static PyObject *py_remove_event_detect(PyObject *self, PyObject *args)
720
+ {
721
+ unsigned int gpio;
722
+ int channel;
723
+ struct py_callback *cb = py_callbacks;
724
+ struct py_callback *temp;
725
+ struct py_callback *prev = NULL;
726
+
727
+ if (!PyArg_ParseTuple(args, "i", &channel))
728
+ return NULL;
729
+
730
+ if (get_gpio_number(channel, &gpio))
731
+ return NULL;
732
+
733
+ // remove all python callbacks for gpio
734
+ while (cb != NULL)
735
+ {
736
+ if (cb->gpio == gpio)
737
+ {
738
+ Py_XDECREF(cb->py_cb);
739
+ if (prev == NULL)
740
+ py_callbacks = cb->next;
741
+ else
742
+ prev->next = cb->next;
743
+ temp = cb;
744
+ cb = cb->next;
745
+ free(temp);
746
+ } else {
747
+ prev = cb;
748
+ cb = cb->next;
749
+ }
750
+ }
751
+
752
+ if (check_gpio_priv())
753
+ return NULL;
754
+
755
+ remove_edge_detect(gpio);
756
+
757
+ Py_RETURN_NONE;
758
+ }
759
+
760
+ // python function value = event_detected(channel)
761
+ static PyObject *py_event_detected(PyObject *self, PyObject *args)
762
+ {
763
+ unsigned int gpio;
764
+ int channel;
765
+
766
+ if (!PyArg_ParseTuple(args, "i", &channel))
767
+ return NULL;
768
+
769
+ if (get_gpio_number(channel, &gpio))
770
+ return NULL;
771
+
772
+ if (event_detected(gpio))
773
+ Py_RETURN_TRUE;
774
+ else
775
+ Py_RETURN_FALSE;
776
+ }
777
+
778
+ // python function wait_for_edge(channel, edge, bouncetime=None)
779
+ static PyObject *py_wait_for_edge(PyObject *self, PyObject *args, PyObject *kwargs)
780
+ {
781
+ unsigned int gpio;
782
+ int channel, edge, result;
783
+ int bouncetime = -666; // None
784
+
785
+ static char *kwlist[] = {"channel", "edge", "bouncetime", NULL};
786
+
787
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i", kwlist, &channel, &edge, &bouncetime))
788
+ return NULL;
789
+
790
+ if (get_gpio_number(channel, &gpio))
791
+ return NULL;
792
+
793
+ // check channel is setup as an input
794
+ if (gpio_direction[gpio] != INPUT)
795
+ {
796
+ PyErr_SetString(PyExc_RuntimeError, "You must setup() the GPIO channel as an input first");
797
+ return NULL;
798
+ }
799
+
800
+ // is edge a valid value?
801
+ edge -= PY_EVENT_CONST_OFFSET;
802
+ if (edge != RISING_EDGE && edge != FALLING_EDGE && edge != BOTH_EDGE)
803
+ {
804
+ PyErr_SetString(PyExc_ValueError, "The edge must be set to RISING, FALLING or BOTH");
805
+ return NULL;
806
+ }
807
+
808
+ if (bouncetime <= 0 && bouncetime != -666)
809
+ {
810
+ PyErr_SetString(PyExc_ValueError, "Bouncetime must be greater than 0");
811
+ return NULL;
812
+ }
813
+
814
+ if (check_gpio_priv())
815
+ return NULL;
816
+
817
+ Py_BEGIN_ALLOW_THREADS // disable GIL
818
+ result = blocking_wait_for_edge(gpio, edge, bouncetime);
819
+ Py_END_ALLOW_THREADS // enable GIL
820
+
821
+ if (result == 0) {
822
+ Py_INCREF(Py_None);
823
+ return Py_None;
824
+ } else if (result == 1) {
825
+ PyErr_SetString(PyExc_RuntimeError, "Conflicting edge detection events already exist for this GPIO channel");
826
+ return NULL;
827
+ } else {
828
+ PyErr_SetString(PyExc_RuntimeError, "Error waiting for edge");
829
+ return NULL;
830
+ }
831
+
832
+ Py_RETURN_NONE;
833
+ }
834
+
835
+ // python function value = gpio_function(channel)
836
+ static PyObject *py_gpio_function(PyObject *self, PyObject *args)
837
+ {
838
+ unsigned int gpio;
839
+ int channel;
840
+ int f;
841
+ PyObject *func;
842
+
843
+ if (!PyArg_ParseTuple(args, "i", &channel))
844
+ return NULL;
845
+
846
+ if (get_gpio_number(channel, &gpio))
847
+ return NULL;
848
+
849
+ if (mmap_gpio_mem())
850
+ return NULL;
851
+
852
+ f = gpio_function(gpio);
853
+ switch (f)
854
+ {
855
+ case 0 : f = INPUT; break;
856
+ case 1 : f = OUTPUT; break;
857
+
858
+ // ALT 0
859
+ case 4 : switch (gpio)
860
+ {
861
+ case 0 :
862
+ case 1 :
863
+ case 2 :
864
+ case 3 : f = I2C; break;
865
+
866
+ case 7 :
867
+ case 8 :
868
+ case 9 :
869
+ case 10 :
870
+ case 11 : f = SPI; break;
871
+
872
+ case 12 :
873
+ case 13 : f = PWM; break;
874
+
875
+ case 14 :
876
+ case 15 : f = SERIAL; break;
877
+
878
+ case 28 :
879
+ case 29 : f = I2C; break;
880
+
881
+ default : f = MODE_UNKNOWN; break;
882
+ }
883
+ break;
884
+
885
+ // ALT 5
886
+ case 2 : if (gpio == 18 || gpio == 19) f = PWM; else f = MODE_UNKNOWN;
887
+ break;
888
+
889
+ // ALT 4
890
+ case 3 : switch (gpio)
891
+
892
+ {
893
+ case 16 :
894
+ case 17 :
895
+ case 18 :
896
+ case 19 :
897
+ case 20 :
898
+ case 21 : f = SPI; break;
899
+ default : f = MODE_UNKNOWN; break;
900
+ }
901
+ break;
902
+
903
+ default : f = MODE_UNKNOWN; break;
904
+
905
+ }
906
+ func = Py_BuildValue("i", f);
907
+ return func;
908
+ }
909
+
910
+ // python function setwarnings(state)
911
+ static PyObject *py_setwarnings(PyObject *self, PyObject *args)
912
+ {
913
+ if (!PyArg_ParseTuple(args, "i", &gpio_warnings))
914
+ return NULL;
915
+
916
+ if (setup_error)
917
+ {
918
+ PyErr_SetString(PyExc_RuntimeError, "Module not imported correctly!");
919
+ return NULL;
920
+ }
921
+
922
+ Py_RETURN_NONE;
923
+ }
924
+
925
+ static const char moduledocstring[] = "GPIO functionality of a Raspberry Pi using Python";
926
+
927
+ PyMethodDef rpi_gpio_methods[] = {
928
+ {"setup", (PyCFunction)py_setup_channel, METH_VARARGS | METH_KEYWORDS, "Set up a GPIO channel or list of channels with a direction and (optional) pull/up down control\nchannel - either board pin number or BCM number depending on which mode is set.\ndirection - IN or OUT\n[pull_up_down] - PUD_OFF (default), PUD_UP or PUD_DOWN\n[initial] - Initial value for an output channel"},
929
+ {"cleanup", (PyCFunction)py_cleanup, METH_VARARGS | METH_KEYWORDS, "Clean up by resetting all GPIO channels that have been used by this program to INPUT with no pullup/pulldown and no event detection\n[channel] - individual channel or list/tuple of channels to clean up. Default - clean every channel that has been used."},
930
+ {"output", py_output_gpio, METH_VARARGS, "Output to a GPIO channel or list of channels\nchannel - either board pin number or BCM number depending on which mode is set.\nvalue - 0/1 or False/True or LOW/HIGH"},
931
+ {"input", py_input_gpio, METH_VARARGS, "Input from a GPIO channel. Returns HIGH=1=True or LOW=0=False\nchannel - either board pin number or BCM number depending on which mode is set."},
932
+ {"setmode", py_setmode, METH_VARARGS, "Set up numbering mode to use for channels.\nBOARD - Use Raspberry Pi board numbers\nBCM - Use Broadcom GPIO 00..nn numbers"},
933
+ {"getmode", py_getmode, METH_VARARGS, "Get numbering mode used for channel numbers.\nReturns BOARD, BCM or UNKNOWN"},
934
+ {"add_event_detect", (PyCFunction)py_add_event_detect, METH_VARARGS | METH_KEYWORDS, "Enable edge detection events for a particular GPIO channel.\nchannel - either board pin number or BCM number depending on which mode is set.\nedge - RISING, FALLING or BOTH\n[callback] - A callback function for the event (optional)\n[bouncetime] - Switch bounce timeout in ms for callback"},
935
+ {"remove_event_detect", py_remove_event_detect, METH_VARARGS, "Remove edge detection for a particular GPIO channel\nchannel - either board pin number or BCM number depending on which mode is set."},
936
+ {"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.\nchannel - either board pin number or BCM number depending on which mode is set."},
937
+ {"add_event_callback", (PyCFunction)py_add_event_callback, METH_VARARGS | METH_KEYWORDS, "Add a callback for an event already defined using add_event_detect()\nchannel - either board pin number or BCM number depending on which mode is set.\ncallback - a callback function"},
938
+ {"wait_for_edge", (PyCFunction)py_wait_for_edge, METH_VARARGS | METH_KEYWORDS, "Wait for an edge.\nchannel - either board pin number or BCM number depending on which mode is set.\nedge - RISING, FALLING or BOTH\n[bouncetime] - time allowed between calls to allow for switchbounce"},
939
+ {"gpio_function", py_gpio_function, METH_VARARGS, "Return the current GPIO function (IN, OUT, PWM, SERIAL, I2C, SPI)\nchannel - either board pin number or BCM number depending on which mode is set."},
940
+ {"setwarnings", py_setwarnings, METH_VARARGS, "Enable or disable warning messages"},
941
+ {NULL, NULL, 0, NULL}
942
+ };
943
+
944
+ #if PY_MAJOR_VERSION > 2
945
+ static struct PyModuleDef rpigpiomodule = {
946
+ PyModuleDef_HEAD_INIT,
947
+ "RPi.GPIO", // name of module
948
+ moduledocstring, // module documentation, may be NULL
949
+ -1, // size of per-interpreter state of the module, or -1 if the module keeps state in global variables.
950
+ rpi_gpio_methods
951
+ };
952
+ #endif
953
+
954
+ #if PY_MAJOR_VERSION > 2
955
+ PyMODINIT_FUNC PyInit_GPIO(void)
956
+ #else
957
+ PyMODINIT_FUNC initGPIO(void)
958
+ #endif
959
+ {
960
+ int i;
961
+ PyObject *module = NULL;
962
+
963
+ #if PY_MAJOR_VERSION > 2
964
+ if ((module = PyModule_Create(&rpigpiomodule)) == NULL)
965
+ return NULL;
966
+ #else
967
+ if ((module = Py_InitModule3("RPi.GPIO", rpi_gpio_methods, moduledocstring)) == NULL)
968
+ return;
969
+ #endif
970
+
971
+ define_constants(module);
972
+
973
+ for (i=0; i<54; i++)
974
+ gpio_direction[i] = -1;
975
+
976
+ // detect board revision and set up accordingly
977
+ if (get_rpi_info(&rpiinfo))
978
+ {
979
+ PyErr_SetString(PyExc_RuntimeError, "This module can only be run on a Raspberry Pi!");
980
+ setup_error = 1;
981
+ #if PY_MAJOR_VERSION > 2
982
+ return NULL;
983
+ #else
984
+ return;
985
+ #endif
986
+ }
987
+ board_info = Py_BuildValue("{sissssssssss}",
988
+ "P1_REVISION",rpiinfo.p1_revision,
989
+ "REVISION",&rpiinfo.revision,
990
+ "TYPE",rpiinfo.type,
991
+ "MANUFACTURER",rpiinfo.manufacturer,
992
+ "PROCESSOR",rpiinfo.processor,
993
+ "RAM",rpiinfo.ram);
994
+ PyModule_AddObject(module, "RPI_INFO", board_info);
995
+
996
+ if (rpiinfo.p1_revision == 1) {
997
+ pin_to_gpio = &pin_to_gpio_rev1;
998
+ } else if (rpiinfo.p1_revision == 2) {
999
+ pin_to_gpio = &pin_to_gpio_rev2;
1000
+ } else { // assume model B+ or A+ or 2B
1001
+ pin_to_gpio = &pin_to_gpio_rev3;
1002
+ }
1003
+
1004
+ rpi_revision = Py_BuildValue("i", rpiinfo.p1_revision); // deprecated
1005
+ PyModule_AddObject(module, "RPI_REVISION", rpi_revision); // deprecated
1006
+
1007
+ // Add PWM class
1008
+ if (PWM_init_PWMType() == NULL)
1009
+ #if PY_MAJOR_VERSION > 2
1010
+ return NULL;
1011
+ #else
1012
+ return;
1013
+ #endif
1014
+ Py_INCREF(&PWMType);
1015
+ PyModule_AddObject(module, "PWM", (PyObject*)&PWMType);
1016
+
1017
+ if (!PyEval_ThreadsInitialized())
1018
+ PyEval_InitThreads();
1019
+
1020
+ // register exit functions - last declared is called first
1021
+ if (Py_AtExit(cleanup) != 0)
1022
+ {
1023
+ setup_error = 1;
1024
+ cleanup();
1025
+ #if PY_MAJOR_VERSION > 2
1026
+ return NULL;
1027
+ #else
1028
+ return;
1029
+ #endif
1030
+ }
1031
+
1032
+ if (Py_AtExit(event_cleanup_all) != 0)
1033
+ {
1034
+ setup_error = 1;
1035
+ cleanup();
1036
+ #if PY_MAJOR_VERSION > 2
1037
+ return NULL;
1038
+ #else
1039
+ return;
1040
+ #endif
1041
+ }
1042
+
1043
+ #if PY_MAJOR_VERSION > 2
1044
+ return module;
1045
+ #else
1046
+ return;
1047
+ #endif
1048
+ }