mirror of
https://github.com/xtacocorex/CHIP_IO
synced 2025-07-20 12:53:22 +00:00
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
84df4376f8 | |||
906beb0257 | |||
00cd5c09ad | |||
c87b0ca72a | |||
ff7bf2fa1c | |||
af9555fcdf | |||
e7db735a2f | |||
e3a077bf82 | |||
a0b2ac12a6 |
@ -1,3 +1,18 @@
|
|||||||
|
0.7.1
|
||||||
|
---
|
||||||
|
* Merged in PR #79
|
||||||
|
* Merged in PR #80
|
||||||
|
* Added message notifying user of the gpio set direction retry
|
||||||
|
|
||||||
|
0.7.0
|
||||||
|
---
|
||||||
|
* Added ability to specify GPIO only as a number, this doesn't work for PWM/SPWM/LRADC/SERVO
|
||||||
|
|
||||||
|
0.6.2
|
||||||
|
---
|
||||||
|
* Implementation for #77 - ability to push up binary pypi
|
||||||
|
* Implementation for #75 - wait_for_edge timeout
|
||||||
|
|
||||||
0.6.1
|
0.6.1
|
||||||
---
|
---
|
||||||
* Fixing implementation for #76
|
* Fixing implementation for #76
|
||||||
|
10
Makefile
10
Makefile
@ -1,10 +1,16 @@
|
|||||||
# PyPi Packaging
|
# PyPi Packaging
|
||||||
package: clean
|
package: clean
|
||||||
@echo " ** PACKAGING FOR PYPI **"
|
@echo " ** PACKAGING FOR PYPI **"
|
||||||
python setup.py sdist
|
python setup.py sdist bdist_wheel
|
||||||
|
python3 setup.py bdist_wheel
|
||||||
|
|
||||||
|
# PyPi Packaging
|
||||||
|
package3: package
|
||||||
|
@echo " ** PACKAGING FOR PYPI **"
|
||||||
|
python3 setup.py bdist_wheel
|
||||||
|
|
||||||
# PyPi Publishing
|
# PyPi Publishing
|
||||||
publish: package
|
publish: package package3
|
||||||
@echo " ** UPLOADING TO PYPI **"
|
@echo " ** UPLOADING TO PYPI **"
|
||||||
twine upload dist/*
|
twine upload dist/*
|
||||||
|
|
||||||
|
@ -255,7 +255,7 @@ You can quickly change a pins direction::
|
|||||||
GPIO.direction("XIO-P3", GPIO.OUT)
|
GPIO.direction("XIO-P3", GPIO.OUT)
|
||||||
GPIO.direction("XIO-P3", GPIO.IN)
|
GPIO.direction("XIO-P3", GPIO.IN)
|
||||||
|
|
||||||
You can also re-setup a pin in order to change direction, not that this is a slower operation::
|
You can also re-setup a pin in order to change direction, note that this is a slower operation::
|
||||||
|
|
||||||
GPIO.setup("XIO-P3", GPIO.OUT)
|
GPIO.setup("XIO-P3", GPIO.OUT)
|
||||||
GPIO.setup("XIO-P3", GPIO.IN)
|
GPIO.setup("XIO-P3", GPIO.IN)
|
||||||
|
36
debian/changelog
vendored
36
debian/changelog
vendored
@ -1,23 +1,43 @@
|
|||||||
|
chip-io (0.7.1-1) unstable; urgency=low
|
||||||
|
|
||||||
|
* Merged PR#79 and#80
|
||||||
|
* Added logging to tell user of the 1 second sleep before retry on setting gpio direction
|
||||||
|
|
||||||
|
-- Robert Wolterman <robert.wolterman@gmail.com> Sun, 12 Nov 2017 07:40:00 -0600
|
||||||
|
|
||||||
|
chip-io (0.7.0-1) unstable; urgency=low
|
||||||
|
|
||||||
|
* Added ability to specify GPIO only as a number, this doesn't work for PWM/SPWM/LRADC/SERVO
|
||||||
|
|
||||||
|
-- Robert Wolterman <robert.wolterman@gmail.com> Wed, 13 Sep 2017 09:51:00 -0600
|
||||||
|
|
||||||
|
chip-io (0.6.2-1) unstable; urgency=low
|
||||||
|
|
||||||
|
* Implementation for number 77 ability to push up binary pypi
|
||||||
|
* Implementation for number 75 wait for edge timeout
|
||||||
|
|
||||||
|
-- Robert Wolterman <robert.wolterman@gmail.com> Sun, 03 Sep 2017 21:34:00 -0600
|
||||||
|
|
||||||
chip-io (0.6.1-1) unstable; urgency=low
|
chip-io (0.6.1-1) unstable; urgency=low
|
||||||
|
|
||||||
* Fixing implementation for #76
|
* Fixing implementation for #76
|
||||||
|
|
||||||
-- Robert Wolterman <robert.wolterman@gmail.com> Wed, 09 Aug 2017 23:09:00 -0600
|
-- Robert Wolterman <robert.wolterman@gmail.com> Wed, 09 Aug 2017 23:09:00 -0600
|
||||||
|
|
||||||
chip-io (0.6.0-1) unstable; urgency=low
|
chip-io (0.6.0-1) unstable; urgency=low
|
||||||
|
|
||||||
* Random comment cleanup
|
* Random comment cleanup
|
||||||
* Implement fix for #76
|
* Implement fix for #76
|
||||||
* API documentation added
|
* API documentation added
|
||||||
* Closing #74
|
* Closing #74
|
||||||
|
|
||||||
-- Robert Wolterman <robert.wolterman@gmail.com> Wed, 09 Aug 2017 22:50:00 -0600
|
-- Robert Wolterman <robert.wolterman@gmail.com> Wed, 09 Aug 2017 22:50:00 -0600
|
||||||
|
|
||||||
chip-io (0.5.9-1) unstable; urgency=low
|
chip-io (0.5.9-1) unstable; urgency=low
|
||||||
|
|
||||||
* Merged PR#70 to enable the underlying C code to be used properly in C based code
|
* Merged PR#70 to enable the underlying C code to be used properly in C based code
|
||||||
* Updated README to add missing pins on the CHIP Pro that are available as GPIO
|
* Updated README to add missing pins on the CHIP Pro that are available as GPIO
|
||||||
* Updated README to denote pins that are available for Edge Detection
|
* Updated README to denote pins that are available for Edge Detection
|
||||||
|
|
||||||
-- Robert Wolterman <robert.wolterman@gmail.com> Tue, 08 Jun 2017 20:03:00 -0600
|
-- Robert Wolterman <robert.wolterman@gmail.com> Tue, 08 Jun 2017 20:03:00 -0600
|
||||||
|
|
||||||
|
4
debian/files
vendored
4
debian/files
vendored
@ -1,2 +1,2 @@
|
|||||||
python-chip-io_0.6.1-1_armhf.deb python optional
|
python-chip-io_0.7.1-1_armhf.deb python optional
|
||||||
python3-chip-io_0.6.1-1_armhf.deb python optional
|
python3-chip-io_0.7.1-1_armhf.deb python optional
|
||||||
|
19
docs/gpio.md
19
docs/gpio.md
@ -5,6 +5,8 @@ Import the GPIO module as follows
|
|||||||
import CHIP_IO.GPIO as GPIO
|
import CHIP_IO.GPIO as GPIO
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Note: As of version 0.7.0, all GPIO functions can use the SYSFS pin number for a GPIO for control, a la RPi.GPIO.
|
||||||
|
|
||||||
### toggle_debug()
|
### toggle_debug()
|
||||||
Enable/Disable the Debug
|
Enable/Disable the Debug
|
||||||
|
|
||||||
@ -56,6 +58,7 @@ Setup a GPIO pin. If pin is already configure, it will reconfigure.
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
GPIO.setup("CSID0", GPIO.IN)
|
GPIO.setup("CSID0", GPIO.IN)
|
||||||
|
GPIO.setup(132, GPIO.IN)
|
||||||
GPIO.setup("CSID3", GPIO.OUT, initial=1)
|
GPIO.setup("CSID3", GPIO.OUT, initial=1)
|
||||||
GPIO.setup("CSID2", GPIO.IN, GPIO.PUD_UP)
|
GPIO.setup("CSID2", GPIO.IN, GPIO.PUD_UP)
|
||||||
```
|
```
|
||||||
@ -76,6 +79,7 @@ Cleanup GPIO. If not channel input, all GPIO will be cleaned up
|
|||||||
```python
|
```python
|
||||||
GPIO.cleanup()
|
GPIO.cleanup()
|
||||||
GPIO.cleanup("CSID3")
|
GPIO.cleanup("CSID3")
|
||||||
|
GPIO.cleanup(132)
|
||||||
```
|
```
|
||||||
|
|
||||||
### output(channel, value)
|
### output(channel, value)
|
||||||
@ -97,6 +101,7 @@ Write a value to a GPIO pin.
|
|||||||
GPIO.output("XIO-P7", GPIO.LOW)
|
GPIO.output("XIO-P7", GPIO.LOW)
|
||||||
GPIO.output("CSID0", 1)
|
GPIO.output("CSID0", 1)
|
||||||
GPIO.output("CSID0", 0)
|
GPIO.output("CSID0", 0)
|
||||||
|
GPIO.output(132, 1)
|
||||||
```
|
```
|
||||||
|
|
||||||
### input(channel)
|
### input(channel)
|
||||||
@ -114,6 +119,7 @@ Read a GPIO pin once.
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
value = GPIO.input("XIO-P7")
|
value = GPIO.input("XIO-P7")
|
||||||
|
value = GPIO.input(1013)
|
||||||
```
|
```
|
||||||
|
|
||||||
### read_byte(channel)
|
### read_byte(channel)
|
||||||
@ -131,6 +137,7 @@ Read a GPIO pin multiple times to fill up 8 bits.
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
bits = GPIO.read_byte("XIO-P7")
|
bits = GPIO.read_byte("XIO-P7")
|
||||||
|
bits = GPIO.read_byte(135)
|
||||||
```
|
```
|
||||||
|
|
||||||
### read_word(channel)
|
### read_word(channel)
|
||||||
@ -148,6 +155,7 @@ Read a GPIO pin multiple times to fill up 16 bits.
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
bits = GPIO.read_word("XIO-P7")
|
bits = GPIO.read_word("XIO-P7")
|
||||||
|
bits = GPIO.read_word(134)
|
||||||
```
|
```
|
||||||
|
|
||||||
### add_event_detect(channel, edge, callback=None, bouncetime=0)
|
### add_event_detect(channel, edge, callback=None, bouncetime=0)
|
||||||
@ -171,6 +179,7 @@ Add event detection to a pin. Refer to main table for which pins are able to use
|
|||||||
GPIO.add_event_detect("AP-EINT3", GPIO.RISING_EDGE, mycallback)
|
GPIO.add_event_detect("AP-EINT3", GPIO.RISING_EDGE, mycallback)
|
||||||
GPIO.add_event_detect("XIO-P7", GPIO.FALLING_EDGE, bouncetime=30)
|
GPIO.add_event_detect("XIO-P7", GPIO.FALLING_EDGE, bouncetime=30)
|
||||||
GPIO.add_event_detect("XIO-P7", GPIO.RISING_EDGE, mycallback, 45)
|
GPIO.add_event_detect("XIO-P7", GPIO.RISING_EDGE, mycallback, 45)
|
||||||
|
GPIO.add_event_detect(1013, GPIO.BOTH_EDGE)
|
||||||
```
|
```
|
||||||
|
|
||||||
### remove_event_detect(channel)
|
### remove_event_detect(channel)
|
||||||
@ -188,6 +197,7 @@ Remove a pins event detection. Refer to main table for which pins are able to us
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
GPIO.remove_event_detect("XIO-P7")
|
GPIO.remove_event_detect("XIO-P7")
|
||||||
|
GPIO.remove_event_detect(1013)
|
||||||
```
|
```
|
||||||
|
|
||||||
### event_detected(channel)
|
### event_detected(channel)
|
||||||
@ -205,6 +215,7 @@ Function to determine if an event was detected on a pin. Pin must have an event
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
have_event = GPIO.event_detected("XIO-P5")
|
have_event = GPIO.event_detected("XIO-P5")
|
||||||
|
have_event = GPIO.event_detected(1014)
|
||||||
```
|
```
|
||||||
|
|
||||||
### add_event_callback(channel, callback, bouncetime=0)
|
### add_event_callback(channel, callback, bouncetime=0)
|
||||||
@ -225,15 +236,17 @@ Add callback function to a pin that has been setup for edge detection. Refer to
|
|||||||
```python
|
```python
|
||||||
GPIO.add_event_callback("AP-EINT3", mycallback)
|
GPIO.add_event_callback("AP-EINT3", mycallback)
|
||||||
GPIO.add_event_callback("XIO-P7", mycallback, 45)
|
GPIO.add_event_callback("XIO-P7", mycallback, 45)
|
||||||
|
GPIO.add_event_callback(1013, mycallback)
|
||||||
```
|
```
|
||||||
|
|
||||||
### wait_for_edge(channel, edge)
|
### wait_for_edge(channel, edge, timeout=-1)
|
||||||
Wait for an edge to be detected. This is a blocking function. Refer to main table for which pins are able to use edge detection.
|
Wait for an edge to be detected. This is a blocking function. Refer to main table for which pins are able to use edge detection.
|
||||||
|
|
||||||
* Parameters
|
* Parameters
|
||||||
|
|
||||||
channel - GPIO Pin
|
channel - GPIO Pin
|
||||||
edge - edge: RISING_EDGE, FALLING_EDGE, BOTH_EDGE
|
edge - edge: RISING_EDGE, FALLING_EDGE, BOTH_EDGE
|
||||||
|
timeout - timeout in milliseconds to wait before exiting function (optional)
|
||||||
|
|
||||||
* Returns
|
* Returns
|
||||||
|
|
||||||
@ -245,6 +258,8 @@ Wait for an edge to be detected. This is a blocking function. Refer to main tab
|
|||||||
GPIO.wait_for_edge("XIO-P3", GPIO.RISING_EDGE)
|
GPIO.wait_for_edge("XIO-P3", GPIO.RISING_EDGE)
|
||||||
GPIO.wait_for_edge("AP-EINT3", GPIO.BOTH_EDGE)
|
GPIO.wait_for_edge("AP-EINT3", GPIO.BOTH_EDGE)
|
||||||
GPIO.wait_for_edge("I2S-DI", GPIO.FALLING_EDGE)
|
GPIO.wait_for_edge("I2S-DI", GPIO.FALLING_EDGE)
|
||||||
|
GPIO.wait_for_edge("XIO-P3", GPIO.RISING_EDGE, 40)
|
||||||
|
GPIO.wait_for_edge(1013, GPIO.BOTH_EDGE, 35)
|
||||||
```
|
```
|
||||||
|
|
||||||
### gpio_function(channel)
|
### gpio_function(channel)
|
||||||
@ -262,6 +277,7 @@ Function to report get a GPIO Pins directioj
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
funct = GPIO.gpio_function("CSID0")
|
funct = GPIO.gpio_function("CSID0")
|
||||||
|
funct = GPIO.gpio_function(132)
|
||||||
```
|
```
|
||||||
|
|
||||||
### setwarnings(state)
|
### setwarnings(state)
|
||||||
@ -332,6 +348,7 @@ Function to set the direction of an exported GPIO pin
|
|||||||
```python
|
```python
|
||||||
GPIO.set_direction("XIO-P0", GPIO.OUT)
|
GPIO.set_direction("XIO-P0", GPIO.OUT)
|
||||||
GPIO.set_direction("XIO-P1", GPIO.IN)
|
GPIO.set_direction("XIO-P1", GPIO.IN)
|
||||||
|
GPIO.set_direction(1013, GPIO.OUT)
|
||||||
```
|
```
|
||||||
|
|
||||||
[home](./index.md)
|
[home](./index.md)
|
||||||
|
6
setup.cfg
Normal file
6
setup.cfg
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[bdist_wheel]
|
||||||
|
universal = 1
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
license_file = LICENSE
|
||||||
|
|
2
setup.py
2
setup.py
@ -13,7 +13,7 @@ classifiers = ['Development Status :: 3 - Alpha',
|
|||||||
'Topic :: System :: Hardware']
|
'Topic :: System :: Hardware']
|
||||||
|
|
||||||
setup(name = 'CHIP_IO',
|
setup(name = 'CHIP_IO',
|
||||||
version = '0.6.1',
|
version = '0.7.1',
|
||||||
author = 'Robert Wolterman',
|
author = 'Robert Wolterman',
|
||||||
author_email = 'robert.wolterman@gmail.com',
|
author_email = 'robert.wolterman@gmail.com',
|
||||||
description = 'A module to control CHIP IO channels',
|
description = 'A module to control CHIP IO channels',
|
||||||
|
@ -371,6 +371,28 @@ int gpio_pud_capable(pins_t *pin)
|
|||||||
return capable;
|
return capable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lookup_gpio_by_number(const char *num) {
|
||||||
|
// Convert the char to an int
|
||||||
|
char *ptr;
|
||||||
|
long ret;
|
||||||
|
int gpnum;
|
||||||
|
ret = strtol(num, &ptr, 10);
|
||||||
|
if (ret == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// If we make it here, lets look for the data
|
||||||
|
pins_t *p;
|
||||||
|
for (p = pins_info; p->key != NULL; ++p) {
|
||||||
|
gpnum = gpio_number(p);
|
||||||
|
// If the number of the gpio pin matches the input
|
||||||
|
// we are
|
||||||
|
if (gpnum == (int)ret) {
|
||||||
|
return gpnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int lookup_gpio_by_key(const char *key)
|
int lookup_gpio_by_key(const char *key)
|
||||||
{
|
{
|
||||||
pins_t *p;
|
pins_t *p;
|
||||||
@ -541,10 +563,13 @@ int get_gpio_number(const char *key, int *gpio)
|
|||||||
if (*gpio <= 0) {
|
if (*gpio <= 0) {
|
||||||
*gpio = lookup_gpio_by_name(key);
|
*gpio = lookup_gpio_by_name(key);
|
||||||
if (*gpio <= 0) {
|
if (*gpio <= 0) {
|
||||||
*gpio = lookup_gpio_by_altname(key);
|
*gpio = lookup_gpio_by_altname(key);
|
||||||
if (*gpio <=0) {
|
if (*gpio <=0) {
|
||||||
status = -1; /* error */
|
*gpio = lookup_gpio_by_number(key);
|
||||||
}
|
if (*gpio <= 0) {
|
||||||
|
status = -1; /* error */
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
|
@ -94,6 +94,7 @@ int get_xio_base(void);
|
|||||||
int is_this_chippro(void);
|
int is_this_chippro(void);
|
||||||
int gpio_number(pins_t *pin);
|
int gpio_number(pins_t *pin);
|
||||||
int gpio_pud_capable(pins_t *pin);
|
int gpio_pud_capable(pins_t *pin);
|
||||||
|
int lookup_gpio_by_number(const char *num);
|
||||||
int lookup_gpio_by_key(const char *key);
|
int lookup_gpio_by_key(const char *key);
|
||||||
int lookup_gpio_by_name(const char *name);
|
int lookup_gpio_by_name(const char *name);
|
||||||
int lookup_gpio_by_altname(const char *altname);
|
int lookup_gpio_by_altname(const char *altname);
|
||||||
|
@ -85,6 +85,6 @@ void define_constants(PyObject *module)
|
|||||||
bcm = Py_BuildValue("i", BCM);
|
bcm = Py_BuildValue("i", BCM);
|
||||||
PyModule_AddObject(module, "BCM", bcm);
|
PyModule_AddObject(module, "BCM", bcm);
|
||||||
|
|
||||||
version = Py_BuildValue("s", "0.6.1");
|
version = Py_BuildValue("s", "0.7.1");
|
||||||
PyModule_AddObject(module, "VERSION", version);
|
PyModule_AddObject(module, "VERSION", version);
|
||||||
}
|
}
|
||||||
|
@ -383,11 +383,23 @@ int gpio_set_direction(int gpio, unsigned int in_flag)
|
|||||||
char filename[MAX_FILENAME]; filename[0] = '\0';
|
char filename[MAX_FILENAME]; filename[0] = '\0';
|
||||||
|
|
||||||
snprintf(filename, sizeof(filename), "/sys/class/gpio/gpio%d/direction", gpio); BUF2SMALL(filename);
|
snprintf(filename, sizeof(filename), "/sys/class/gpio/gpio%d/direction", gpio); BUF2SMALL(filename);
|
||||||
|
|
||||||
if ((fd = open(filename, O_WRONLY)) < 0) {
|
if ((fd = open(filename, O_WRONLY)) < 0) {
|
||||||
|
// NOTIFY THAT WE'RE GOING TO SLEEP AND RETRY
|
||||||
char err[256];
|
char err[256];
|
||||||
snprintf(err, sizeof(err), "gpio_set_direction: could not open '%s' (%s)", filename, strerror(errno));
|
snprintf(err, sizeof(err), "gpio_set_direction: could not open '%s', sleeping for 1 second and retrying", filename);
|
||||||
add_error_msg(err);
|
add_error_msg(err);
|
||||||
return -1;
|
// if called as non-root, udev may need time to adjust file
|
||||||
|
// permissions after setting up gpio
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
// TRY AGAIN AND IF THIS TIME FAILS, KICK OUT
|
||||||
|
if ((fd = open(filename, O_WRONLY)) < 0) {
|
||||||
|
char err[256];
|
||||||
|
snprintf(err, sizeof(err), "gpio_set_direction: could not open '%s' (%s)", filename, strerror(errno));
|
||||||
|
add_error_msg(err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char direction[16];
|
char direction[16];
|
||||||
@ -1027,7 +1039,7 @@ void event_cleanup(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// blocking_wait_for_edge assumes the caller has ensured the GPIO is already exported.
|
// blocking_wait_for_edge assumes the caller has ensured the GPIO is already exported.
|
||||||
int blocking_wait_for_edge(int gpio, unsigned int edge)
|
int blocking_wait_for_edge(int gpio, unsigned int edge, int timeout)
|
||||||
// standalone from all the event functions above
|
// standalone from all the event functions above
|
||||||
{
|
{
|
||||||
int fd = fd_lookup(gpio);
|
int fd = fd_lookup(gpio);
|
||||||
@ -1082,7 +1094,7 @@ int blocking_wait_for_edge(int gpio, unsigned int edge)
|
|||||||
// epoll for event
|
// epoll for event
|
||||||
for (i = 0; i<2; i++) // first time triggers with current state, so ignore
|
for (i = 0; i<2; i++) // first time triggers with current state, so ignore
|
||||||
{
|
{
|
||||||
if ((n = epoll_wait(epfd, &events, 1, -1)) == -1)
|
if ((n = epoll_wait(epfd, &events, 1, timeout)) == -1)
|
||||||
{
|
{
|
||||||
gpio_event_remove(gpio);
|
gpio_event_remove(gpio);
|
||||||
return 5;
|
return 5;
|
||||||
|
@ -86,4 +86,4 @@ int gpio_event_remove(int gpio);
|
|||||||
int gpio_is_evented(int gpio);
|
int gpio_is_evented(int gpio);
|
||||||
int event_initialise(void);
|
int event_initialise(void);
|
||||||
void event_cleanup(void);
|
void event_cleanup(void);
|
||||||
int blocking_wait_for_edge(int gpio, unsigned int edge);
|
int blocking_wait_for_edge(int gpio, unsigned int edge, int timeout);
|
||||||
|
213
source/py_gpio.c
213
source/py_gpio.c
@ -36,6 +36,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
@ -129,13 +130,23 @@ static PyObject *py_cleanup(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||||||
{
|
{
|
||||||
int gpio;
|
int gpio;
|
||||||
char *channel;
|
char *channel;
|
||||||
|
int inchan;
|
||||||
static char *kwlist[] = {"channel", NULL};
|
static char *kwlist[] = {"channel", NULL};
|
||||||
|
|
||||||
clear_error_msg();
|
clear_error_msg();
|
||||||
|
|
||||||
// Channel is optional
|
// Channel is optional
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", kwlist, &channel)) {
|
// Try to parse the string
|
||||||
return NULL;
|
int rtn;
|
||||||
|
rtn = PyArg_ParseTupleAndKeywords(args, kwargs, "|s", kwlist, &channel);
|
||||||
|
if (!rtn) {
|
||||||
|
// Fall into here are try to parse an int
|
||||||
|
rtn = PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &inchan);
|
||||||
|
if (!rtn) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// We make it here, we can convert inchan to a string for us to ensure it's valid
|
||||||
|
asprintf(&channel, "%i", inchan);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The !channel fixes issues #50
|
// The !channel fixes issues #50
|
||||||
@ -157,6 +168,7 @@ static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwar
|
|||||||
int gpio;
|
int gpio;
|
||||||
int allowed = -1;
|
int allowed = -1;
|
||||||
char *channel;
|
char *channel;
|
||||||
|
int inchan;
|
||||||
int direction;
|
int direction;
|
||||||
int pud = PUD_OFF;
|
int pud = PUD_OFF;
|
||||||
int initial = 0;
|
int initial = 0;
|
||||||
@ -164,13 +176,30 @@ static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwar
|
|||||||
|
|
||||||
clear_error_msg();
|
clear_error_msg();
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si|ii", kwlist, &channel, &direction, &pud, &initial))
|
// Try to parse the string
|
||||||
return NULL;
|
int rtn;
|
||||||
|
rtn = PyArg_ParseTupleAndKeywords(args, kwargs, "si|ii", kwlist, &channel, &direction, &pud, &initial);
|
||||||
|
if (!rtn) {
|
||||||
|
// Fall into here are try to parse an int
|
||||||
|
rtn = PyArg_ParseTupleAndKeywords(args, kwargs, "ii|ii", kwlist, &inchan, &direction, &pud, &initial);
|
||||||
|
if (!rtn) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// We make it here, we can convert inchan to a string for us to ensure it's valid
|
||||||
|
asprintf(&channel, "%i", inchan);
|
||||||
|
}
|
||||||
|
|
||||||
if (!module_setup) {
|
if (!module_setup) {
|
||||||
init_module();
|
init_module();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (get_gpio_number(channel, &gpio) < 0) {
|
||||||
|
char err[2000];
|
||||||
|
snprintf(err, sizeof(err), "Invalid channel %s. (%s)", channel, get_error_msg());
|
||||||
|
PyErr_SetString(PyExc_ValueError, err);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (direction != INPUT && direction != OUTPUT)
|
if (direction != INPUT && direction != OUTPUT)
|
||||||
{
|
{
|
||||||
PyErr_SetString(PyExc_ValueError, "An invalid direction was passed to setup()");
|
PyErr_SetString(PyExc_ValueError, "An invalid direction was passed to setup()");
|
||||||
@ -263,19 +292,29 @@ static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwar
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
} /* py_setup_channel */
|
} /* py_setup_channel */
|
||||||
|
|
||||||
|
|
||||||
// python function output(channel, value)
|
// python function output(channel, value)
|
||||||
static PyObject *py_output_gpio(PyObject *self, PyObject *args)
|
static PyObject *py_output_gpio(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
int gpio;
|
int gpio;
|
||||||
int value;
|
int value;
|
||||||
char *channel;
|
char *channel;
|
||||||
|
int inchan;
|
||||||
int allowed = -1;
|
int allowed = -1;
|
||||||
|
|
||||||
clear_error_msg();
|
clear_error_msg();
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "si", &channel, &value))
|
// Try to parse the string
|
||||||
return NULL;
|
int rtn;
|
||||||
|
rtn = PyArg_ParseTuple(args, "si", &channel, &value);
|
||||||
|
if (!rtn) {
|
||||||
|
// Fall into here are try to parse an int
|
||||||
|
rtn = PyArg_ParseTuple(args, "ii", &inchan, &value);
|
||||||
|
if (!rtn) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// We make it here, we can convert inchan to a string for us to ensure it's valid
|
||||||
|
asprintf(&channel, "%i", inchan);
|
||||||
|
}
|
||||||
|
|
||||||
if (get_gpio_number(channel, &gpio)) {
|
if (get_gpio_number(channel, &gpio)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Invalid channel");
|
PyErr_SetString(PyExc_ValueError, "Invalid channel");
|
||||||
@ -322,14 +361,25 @@ static PyObject *py_input_gpio(PyObject *self, PyObject *args)
|
|||||||
{
|
{
|
||||||
int gpio;
|
int gpio;
|
||||||
char *channel;
|
char *channel;
|
||||||
|
int inchan;
|
||||||
unsigned int value;
|
unsigned int value;
|
||||||
PyObject *py_value;
|
PyObject *py_value;
|
||||||
int allowed = -1;
|
int allowed = -1;
|
||||||
|
|
||||||
clear_error_msg();
|
clear_error_msg();
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s", &channel))
|
// Try to parse the string
|
||||||
return NULL;
|
int rtn;
|
||||||
|
rtn = PyArg_ParseTuple(args, "s", &channel);
|
||||||
|
if (!rtn) {
|
||||||
|
// Fall into here are try to parse an int
|
||||||
|
rtn = PyArg_ParseTuple(args, "i", &inchan);
|
||||||
|
if (!rtn) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// We make it here, we can convert inchan to a string for us to ensure it's valid
|
||||||
|
asprintf(&channel, "%i", inchan);
|
||||||
|
}
|
||||||
|
|
||||||
if (get_gpio_number(channel, &gpio)) {
|
if (get_gpio_number(channel, &gpio)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Invalid channel");
|
PyErr_SetString(PyExc_ValueError, "Invalid channel");
|
||||||
@ -376,14 +426,25 @@ static PyObject *py_read_byte_gpio(PyObject *self, PyObject *args)
|
|||||||
{
|
{
|
||||||
int gpio;
|
int gpio;
|
||||||
char *channel;
|
char *channel;
|
||||||
|
int inchan;
|
||||||
unsigned int value = 0;
|
unsigned int value = 0;
|
||||||
PyObject *py_value;
|
PyObject *py_value;
|
||||||
int allowed = -1;
|
int allowed = -1;
|
||||||
|
|
||||||
clear_error_msg();
|
clear_error_msg();
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s", &channel))
|
// Try to parse the string
|
||||||
return NULL;
|
int rtn;
|
||||||
|
rtn = PyArg_ParseTuple(args, "s", &channel);
|
||||||
|
if (!rtn) {
|
||||||
|
// Fall into here are try to parse an int
|
||||||
|
rtn = PyArg_ParseTuple(args, "i", &inchan);
|
||||||
|
if (!rtn) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// We make it here, we can convert inchan to a string for us to ensure it's valid
|
||||||
|
asprintf(&channel, "%i", inchan);
|
||||||
|
}
|
||||||
|
|
||||||
if (get_gpio_number(channel, &gpio)) {
|
if (get_gpio_number(channel, &gpio)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Invalid channel");
|
PyErr_SetString(PyExc_ValueError, "Invalid channel");
|
||||||
@ -430,14 +491,25 @@ static PyObject *py_read_word_gpio(PyObject *self, PyObject *args)
|
|||||||
{
|
{
|
||||||
int gpio;
|
int gpio;
|
||||||
char *channel;
|
char *channel;
|
||||||
|
int inchan;
|
||||||
unsigned int value = 0;
|
unsigned int value = 0;
|
||||||
PyObject *py_value;
|
PyObject *py_value;
|
||||||
int allowed = -1;
|
int allowed = -1;
|
||||||
|
|
||||||
clear_error_msg();
|
clear_error_msg();
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s", &channel))
|
// Try to parse the string
|
||||||
return NULL;
|
int rtn;
|
||||||
|
rtn = PyArg_ParseTuple(args, "s", &channel);
|
||||||
|
if (!rtn) {
|
||||||
|
// Fall into here are try to parse an int
|
||||||
|
rtn = PyArg_ParseTuple(args, "i", &inchan);
|
||||||
|
if (!rtn) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// We make it here, we can convert inchan to a string for us to ensure it's valid
|
||||||
|
asprintf(&channel, "%i", inchan);
|
||||||
|
}
|
||||||
|
|
||||||
if (get_gpio_number(channel, &gpio)) {
|
if (get_gpio_number(channel, &gpio)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Invalid channel");
|
PyErr_SetString(PyExc_ValueError, "Invalid channel");
|
||||||
@ -557,6 +629,7 @@ static PyObject *py_add_event_callback(PyObject *self, PyObject *args, PyObject
|
|||||||
{
|
{
|
||||||
int gpio;
|
int gpio;
|
||||||
char *channel;
|
char *channel;
|
||||||
|
int inchan;
|
||||||
int allowed = -1;
|
int allowed = -1;
|
||||||
unsigned int bouncetime = 0;
|
unsigned int bouncetime = 0;
|
||||||
PyObject *cb_func;
|
PyObject *cb_func;
|
||||||
@ -564,8 +637,18 @@ static PyObject *py_add_event_callback(PyObject *self, PyObject *args, PyObject
|
|||||||
|
|
||||||
clear_error_msg();
|
clear_error_msg();
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO|i", kwlist, &channel, &cb_func, &bouncetime))
|
// Try to parse the string
|
||||||
return NULL;
|
int rtn;
|
||||||
|
rtn = PyArg_ParseTupleAndKeywords(args, kwargs, "sO|i", kwlist, &channel, &cb_func, &bouncetime);
|
||||||
|
if (!rtn) {
|
||||||
|
// Fall into here are try to parse an int
|
||||||
|
rtn = PyArg_ParseTupleAndKeywords(args, kwargs, "iO|i", kwlist, &inchan, &cb_func, &bouncetime);
|
||||||
|
if (!rtn) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// We make it here, we can convert inchan to a string for us to ensure it's valid
|
||||||
|
asprintf(&channel, "%i", inchan);
|
||||||
|
}
|
||||||
|
|
||||||
if (!PyCallable_Check(cb_func))
|
if (!PyCallable_Check(cb_func))
|
||||||
{
|
{
|
||||||
@ -628,6 +711,7 @@ static PyObject *py_add_event_detect(PyObject *self, PyObject *args, PyObject *k
|
|||||||
{
|
{
|
||||||
int gpio;
|
int gpio;
|
||||||
char *channel;
|
char *channel;
|
||||||
|
int inchan;
|
||||||
int edge, result;
|
int edge, result;
|
||||||
unsigned int bouncetime = 0;
|
unsigned int bouncetime = 0;
|
||||||
int allowed = -1;
|
int allowed = -1;
|
||||||
@ -636,8 +720,18 @@ static PyObject *py_add_event_detect(PyObject *self, PyObject *args, PyObject *k
|
|||||||
|
|
||||||
clear_error_msg();
|
clear_error_msg();
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si|Oi", kwlist, &channel, &edge, &cb_func, &bouncetime))
|
// Try to parse the string
|
||||||
return NULL;
|
int rtn;
|
||||||
|
rtn = PyArg_ParseTupleAndKeywords(args, kwargs, "si|Oi", kwlist, &channel, &edge, &cb_func, &bouncetime);
|
||||||
|
if (!rtn) {
|
||||||
|
// Fall into here are try to parse an int
|
||||||
|
rtn = PyArg_ParseTupleAndKeywords(args, kwargs, "ii|Oi", kwlist, &inchan, &edge, &cb_func, &bouncetime);
|
||||||
|
if (!rtn) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// We make it here, we can convert inchan to a string for us to ensure it's valid
|
||||||
|
asprintf(&channel, "%i", inchan);
|
||||||
|
}
|
||||||
|
|
||||||
if (cb_func != NULL && !PyCallable_Check(cb_func))
|
if (cb_func != NULL && !PyCallable_Check(cb_func))
|
||||||
{
|
{
|
||||||
@ -714,6 +808,7 @@ static PyObject *py_remove_event_detect(PyObject *self, PyObject *args)
|
|||||||
{
|
{
|
||||||
int gpio;
|
int gpio;
|
||||||
char *channel;
|
char *channel;
|
||||||
|
int inchan;
|
||||||
struct py_callback *cb = py_callbacks;
|
struct py_callback *cb = py_callbacks;
|
||||||
struct py_callback *temp;
|
struct py_callback *temp;
|
||||||
struct py_callback *prev = NULL;
|
struct py_callback *prev = NULL;
|
||||||
@ -721,8 +816,18 @@ static PyObject *py_remove_event_detect(PyObject *self, PyObject *args)
|
|||||||
|
|
||||||
clear_error_msg();
|
clear_error_msg();
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s", &channel))
|
// Try to parse the string
|
||||||
return NULL;
|
int rtn;
|
||||||
|
rtn = PyArg_ParseTuple(args, "s", &channel);
|
||||||
|
if (!rtn) {
|
||||||
|
// Fall into here are try to parse an int
|
||||||
|
rtn = PyArg_ParseTuple(args, "i", &inchan);
|
||||||
|
if (!rtn) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// We make it here, we can convert inchan to a string for us to ensure it's valid
|
||||||
|
asprintf(&channel, "%i", inchan);
|
||||||
|
}
|
||||||
|
|
||||||
if (get_gpio_number(channel, &gpio)) {
|
if (get_gpio_number(channel, &gpio)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Invalid channel");
|
PyErr_SetString(PyExc_ValueError, "Invalid channel");
|
||||||
@ -784,12 +889,23 @@ static PyObject *py_event_detected(PyObject *self, PyObject *args)
|
|||||||
{
|
{
|
||||||
int gpio;
|
int gpio;
|
||||||
char *channel;
|
char *channel;
|
||||||
|
int inchan;
|
||||||
int allowed = -1;
|
int allowed = -1;
|
||||||
|
|
||||||
clear_error_msg();
|
clear_error_msg();
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s", &channel))
|
// Try to parse the string
|
||||||
return NULL;
|
int rtn;
|
||||||
|
rtn = PyArg_ParseTuple(args, "s", &channel);
|
||||||
|
if (!rtn) {
|
||||||
|
// Fall into here are try to parse an int
|
||||||
|
rtn = PyArg_ParseTuple(args, "i", &inchan);
|
||||||
|
if (!rtn) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// We make it here, we can convert inchan to a string for us to ensure it's valid
|
||||||
|
asprintf(&channel, "%i", inchan);
|
||||||
|
}
|
||||||
|
|
||||||
if (get_gpio_number(channel, &gpio)) {
|
if (get_gpio_number(channel, &gpio)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Invalid channel");
|
PyErr_SetString(PyExc_ValueError, "Invalid channel");
|
||||||
@ -817,19 +933,32 @@ static PyObject *py_event_detected(PyObject *self, PyObject *args)
|
|||||||
Py_RETURN_FALSE;
|
Py_RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// python function py_wait_for_edge(gpio, edge)
|
// python function py_wait_for_edge(gpio, edge, timeout = -1)
|
||||||
static PyObject *py_wait_for_edge(PyObject *self, PyObject *args)
|
static PyObject *py_wait_for_edge(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
int gpio;
|
int gpio;
|
||||||
int edge, result;
|
int edge, result, timeout;
|
||||||
char *channel;
|
char *channel;
|
||||||
|
int inchan;
|
||||||
char error[81];
|
char error[81];
|
||||||
int allowed = -1;
|
int allowed = -1;
|
||||||
|
|
||||||
clear_error_msg();
|
clear_error_msg();
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "si", &channel, &edge))
|
timeout = -1;
|
||||||
return NULL;
|
|
||||||
|
// Try to parse the string
|
||||||
|
int rtn;
|
||||||
|
rtn = PyArg_ParseTuple(args, "si|i", &channel, &edge, &timeout);
|
||||||
|
if (!rtn) {
|
||||||
|
// Fall into here are try to parse an int
|
||||||
|
rtn = PyArg_ParseTuple(args, "ii|i", &inchan, &edge, &timeout);
|
||||||
|
if (!rtn) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// We make it here, we can convert inchan to a string for us to ensure it's valid
|
||||||
|
asprintf(&channel, "%i", inchan);
|
||||||
|
}
|
||||||
|
|
||||||
if (get_gpio_number(channel, &gpio)) {
|
if (get_gpio_number(channel, &gpio)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Invalid channel");
|
PyErr_SetString(PyExc_ValueError, "Invalid channel");
|
||||||
@ -877,7 +1006,7 @@ static PyObject *py_wait_for_edge(PyObject *self, PyObject *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS // disable GIL
|
Py_BEGIN_ALLOW_THREADS // disable GIL
|
||||||
result = blocking_wait_for_edge(gpio, edge);
|
result = blocking_wait_for_edge(gpio, edge, timeout);
|
||||||
Py_END_ALLOW_THREADS // enable GIL
|
Py_END_ALLOW_THREADS // enable GIL
|
||||||
|
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
@ -902,12 +1031,23 @@ static PyObject *py_gpio_function(PyObject *self, PyObject *args)
|
|||||||
unsigned int value;
|
unsigned int value;
|
||||||
PyObject *func;
|
PyObject *func;
|
||||||
char *channel;
|
char *channel;
|
||||||
|
int inchan;
|
||||||
int allowed = -1;
|
int allowed = -1;
|
||||||
|
|
||||||
clear_error_msg();
|
clear_error_msg();
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s", &channel))
|
// Try to parse the string
|
||||||
return NULL;
|
int rtn;
|
||||||
|
rtn = PyArg_ParseTuple(args, "s", &channel);
|
||||||
|
if (!rtn) {
|
||||||
|
// Fall into here are try to parse an int
|
||||||
|
rtn = PyArg_ParseTuple(args, "i", &inchan);
|
||||||
|
if (!rtn) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// We make it here, we can convert inchan to a string for us to ensure it's valid
|
||||||
|
asprintf(&channel, "%i", inchan);
|
||||||
|
}
|
||||||
|
|
||||||
if (get_gpio_number(channel, &gpio)) {
|
if (get_gpio_number(channel, &gpio)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Invalid channel");
|
PyErr_SetString(PyExc_ValueError, "Invalid channel");
|
||||||
@ -1115,14 +1255,25 @@ static PyObject *py_set_direction(PyObject *self, PyObject *args, PyObject *kwar
|
|||||||
{
|
{
|
||||||
int gpio;
|
int gpio;
|
||||||
char *channel;
|
char *channel;
|
||||||
|
int inchan;
|
||||||
int direction;
|
int direction;
|
||||||
int allowed = -1;
|
int allowed = -1;
|
||||||
static char *kwlist[] = { "channel", "direction", NULL };
|
static char *kwlist[] = { "channel", "direction", NULL };
|
||||||
|
|
||||||
clear_error_msg();
|
clear_error_msg();
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si", kwlist, &channel, &direction))
|
// Try to parse the string
|
||||||
return NULL;
|
int rtn;
|
||||||
|
rtn = PyArg_ParseTupleAndKeywords(args, kwargs, "si", kwlist, &channel, &direction);
|
||||||
|
if (!rtn) {
|
||||||
|
// Fall into here are try to parse an int
|
||||||
|
rtn = PyArg_ParseTupleAndKeywords(args, kwargs, "ii", kwlist, &inchan, &direction);
|
||||||
|
if (!rtn) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// We make it here, we can convert inchan to a string for us to ensure it's valid
|
||||||
|
asprintf(&channel, "%i", inchan);
|
||||||
|
}
|
||||||
|
|
||||||
if (!module_setup) {
|
if (!module_setup) {
|
||||||
init_module();
|
init_module();
|
||||||
@ -1179,7 +1330,7 @@ PyMethodDef gpio_methods[] = {
|
|||||||
{"remove_event_detect", py_remove_event_detect, METH_VARARGS, "Remove edge detection for a particular GPIO channel\ngpio - gpio channel"},
|
{"remove_event_detect", py_remove_event_detect, METH_VARARGS, "Remove edge detection for a particular GPIO channel\ngpio - gpio channel"},
|
||||||
{"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.\ngpio - gpio channel"},
|
{"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.\ngpio - gpio channel"},
|
||||||
{"add_event_callback", (PyCFunction)py_add_event_callback, METH_VARARGS | METH_KEYWORDS, "Add a callback for an event already defined using add_event_detect()\ngpio - gpio channel\ncallback - a callback function\n[bouncetime] - Switch bounce timeout in ms"},
|
{"add_event_callback", (PyCFunction)py_add_event_callback, METH_VARARGS | METH_KEYWORDS, "Add a callback for an event already defined using add_event_detect()\ngpio - gpio channel\ncallback - a callback function\n[bouncetime] - Switch bounce timeout in ms"},
|
||||||
{"wait_for_edge", py_wait_for_edge, METH_VARARGS, "Wait for an edge.\ngpio - gpio channel\nedge - RISING, FALLING or BOTH"},
|
{"wait_for_edge", py_wait_for_edge, METH_VARARGS, "Wait for an edge.\ngpio - gpio channel\nedge - RISING, FALLING or BOTH\ntimeout (optional) - time to wait in miliseconds. -1 will wait forever (default)"},
|
||||||
{"gpio_function", py_gpio_function, METH_VARARGS, "Return the current GPIO function (IN, OUT, ALT0)\ngpio - gpio channel"},
|
{"gpio_function", py_gpio_function, METH_VARARGS, "Return the current GPIO function (IN, OUT, ALT0)\ngpio - gpio channel"},
|
||||||
{"setwarnings", py_setwarnings, METH_VARARGS, "Enable or disable warning messages"},
|
{"setwarnings", py_setwarnings, METH_VARARGS, "Enable or disable warning messages"},
|
||||||
{"get_gpio_base", py_gpio_base, METH_VARARGS, "Get the XIO base number for sysfs"},
|
{"get_gpio_base", py_gpio_base, METH_VARARGS, "Get the XIO base number for sysfs"},
|
||||||
|
Reference in New Issue
Block a user