mirror of
https://github.com/xtacocorex/CHIP_IO
synced 2025-07-20 04:43:21 +00:00
cleanup of brettcvz's read_byte function, added read_word since he really needs 12 bits of data. finally fixed the gpio cleanup() without argument issue once and for all, sorry for lying howientc
This commit is contained in:
@ -1,3 +1,10 @@
|
|||||||
|
0.3.5
|
||||||
|
---
|
||||||
|
* Merged in brettcvz's code to read a byte of data from the GPIO
|
||||||
|
- Cleaned the code up and expanded it (in the low level C code) to read up to 32 bits of data
|
||||||
|
- Presented 8 bit and 16 bits of data functions to the Python interface with brettcvz's read_byte() and my read_word()
|
||||||
|
* I think I finally fixed the GPIO.cleanup() code one and for all
|
||||||
|
|
||||||
0.3.4.1
|
0.3.4.1
|
||||||
---
|
---
|
||||||
* Quick fix as I borked XIO setup as inputs with the latest change that enabled PUD
|
* Quick fix as I borked XIO setup as inputs with the latest change that enabled PUD
|
||||||
|
@ -205,6 +205,15 @@ Polling inputs::
|
|||||||
else:
|
else:
|
||||||
print("LOW")
|
print("LOW")
|
||||||
|
|
||||||
|
Read lots of data::
|
||||||
|
|
||||||
|
# Get 8 bits of data in one shot
|
||||||
|
mybyte = GPIO.read_byte("LCD-D3")
|
||||||
|
# Get 16 bits of data in one shot
|
||||||
|
myword = GPIO.read_word("XIO-P4")
|
||||||
|
|
||||||
|
This code was initially added by brettcvz and I cleaned it up and expanded it.
|
||||||
|
|
||||||
The edge detection code below only works for the AP-EINT1, AP-EINT3, and XPO Pins on the CHIP.
|
The edge detection code below only works for the AP-EINT1, AP-EINT3, and XPO Pins on the CHIP.
|
||||||
|
|
||||||
Waiting for an edge (GPIO.RISING, GPIO.FALLING, or GPIO.BOTH::
|
Waiting for an edge (GPIO.RISING, GPIO.FALLING, or GPIO.BOTH::
|
||||||
|
2
setup.py
2
setup.py
@ -20,7 +20,7 @@ classifiers = ['Development Status :: 3 - Alpha',
|
|||||||
'Topic :: System :: Hardware']
|
'Topic :: System :: Hardware']
|
||||||
|
|
||||||
setup(name = 'CHIP_IO',
|
setup(name = 'CHIP_IO',
|
||||||
version = '0.3.4.1',
|
version = '0.3.5',
|
||||||
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',
|
||||||
|
@ -88,6 +88,6 @@ void define_constants(PyObject *module)
|
|||||||
module_debug = Py_BuildValue("i", DEBUG ? Py_True: Py_False);
|
module_debug = Py_BuildValue("i", DEBUG ? Py_True: Py_False);
|
||||||
PyModule_AddObject(module, "DEBUG", module_debug);
|
PyModule_AddObject(module, "DEBUG", module_debug);
|
||||||
|
|
||||||
version = Py_BuildValue("s", "0.3.4.1");
|
version = Py_BuildValue("s", "0.3.5");
|
||||||
PyModule_AddObject(module, "VERSION", version);
|
PyModule_AddObject(module, "VERSION", version);
|
||||||
}
|
}
|
||||||
|
@ -506,8 +506,7 @@ int gpio_get_value(int gpio, unsigned int *value)
|
|||||||
int fd = fd_lookup(gpio);
|
int fd = fd_lookup(gpio);
|
||||||
char ch;
|
char ch;
|
||||||
|
|
||||||
if (!fd)
|
if (!fd) {
|
||||||
{
|
|
||||||
if ((fd = open_value_file(gpio)) == -1) {
|
if ((fd = open_value_file(gpio)) == -1) {
|
||||||
char err[256];
|
char err[256];
|
||||||
snprintf(err, sizeof(err), "gpio_get_value: could not open GPIO %d value file", gpio);
|
snprintf(err, sizeof(err), "gpio_get_value: could not open GPIO %d value file", gpio);
|
||||||
@ -547,6 +546,58 @@ int gpio_get_value(int gpio, unsigned int *value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int gpio_get_more(int gpio, int bits, unsigned int *value)
|
||||||
|
{
|
||||||
|
int fd = fd_lookup(gpio);
|
||||||
|
char ch;
|
||||||
|
|
||||||
|
if (!fd) {
|
||||||
|
if ((fd = open_value_file(gpio)) == -1) {
|
||||||
|
char err[256];
|
||||||
|
snprintf(err, sizeof(err), "gpio_get_more: could not open GPIO %d value file", gpio);
|
||||||
|
add_error_msg(err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop for our number of bits
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < bits; i++) {
|
||||||
|
|
||||||
|
if (lseek(fd, 0, SEEK_SET) < 0) {
|
||||||
|
char err[256];
|
||||||
|
snprintf(err, sizeof(err), "gpio_get_more: could not seek GPIO %d (%s)", gpio, strerror(errno));
|
||||||
|
add_error_msg(err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ssize_t s = read(fd, &ch, sizeof(ch));
|
||||||
|
if (s < 0) {
|
||||||
|
char err[256];
|
||||||
|
snprintf(err, sizeof(err), "gpio_get_more: could not read GPIO %d (%s)", gpio, strerror(errno));
|
||||||
|
add_error_msg(err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch == '1') {
|
||||||
|
*value |= (1 << i);
|
||||||
|
} else if (ch == '0') {
|
||||||
|
*value |= (0 << i);
|
||||||
|
} else {
|
||||||
|
char err[256];
|
||||||
|
snprintf(err, sizeof(err), "gpio_get_more: unrecognized read GPIO %d (%c)", gpio, ch);
|
||||||
|
add_error_msg(err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (DEBUG) {
|
||||||
|
printf(" ** gpio_get_more: %c **\n", ch);
|
||||||
|
printf(" ** gpio_get_more: current value: %u **\n", *value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int gpio_set_edge(int gpio, unsigned int edge)
|
int gpio_set_edge(int gpio, unsigned int edge)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -69,6 +69,7 @@ int gpio_set_direction(int gpio, unsigned int in_flag);
|
|||||||
int gpio_get_direction(int gpio, unsigned int *value);
|
int gpio_get_direction(int gpio, unsigned int *value);
|
||||||
int gpio_set_value(int gpio, unsigned int value);
|
int gpio_set_value(int gpio, unsigned int value);
|
||||||
int gpio_get_value(int gpio, unsigned int *value);
|
int gpio_get_value(int gpio, unsigned int *value);
|
||||||
|
int gpio_get_more(int gpio, int bits, unsigned int *value);
|
||||||
int fd_lookup(int gpio);
|
int fd_lookup(int gpio);
|
||||||
int open_value_file(int gpio);
|
int open_value_file(int gpio);
|
||||||
|
|
||||||
|
@ -86,7 +86,6 @@ static int init_module(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void remember_gpio_direction(int gpio, int direction)
|
static void remember_gpio_direction(int gpio, int direction)
|
||||||
{
|
{
|
||||||
dyn_int_array_set(&gpio_direction, gpio, direction, -1);
|
dyn_int_array_set(&gpio_direction, gpio, direction, -1);
|
||||||
@ -118,10 +117,7 @@ static PyObject *py_cleanup(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||||||
event_cleanup();
|
event_cleanup();
|
||||||
} else {
|
} else {
|
||||||
if (get_gpio_number(channel, &gpio) < 0) {
|
if (get_gpio_number(channel, &gpio) < 0) {
|
||||||
char err[2000];
|
event_cleanup();
|
||||||
snprintf(err, sizeof(err), "Invalid channel %s. (%s)", channel, get_error_msg());
|
|
||||||
PyErr_SetString(PyExc_ValueError, err);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
gpio_unexport(gpio);
|
gpio_unexport(gpio);
|
||||||
}
|
}
|
||||||
@ -290,13 +286,12 @@ static PyObject *py_input_gpio(PyObject *self, PyObject *args)
|
|||||||
return py_value;
|
return py_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: Come up with a way to merge py_read_byte_gpio and py_read_word_gpio
|
||||||
// python function value = read_byte(channel)
|
// python function value = read_byte(channel)
|
||||||
static PyObject *py_read_byte_gpio(PyObject *self, PyObject *args)
|
static PyObject *py_read_byte_gpio(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
int gpio;
|
int gpio;
|
||||||
char *channel;
|
char *channel;
|
||||||
int i;
|
|
||||||
unsigned int bit;
|
|
||||||
unsigned int value = 0;
|
unsigned int value = 0;
|
||||||
PyObject *py_value;
|
PyObject *py_value;
|
||||||
|
|
||||||
@ -306,37 +301,63 @@ static PyObject *py_read_byte_gpio(PyObject *self, PyObject *args)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (get_gpio_number(channel, &gpio)) {
|
if (get_gpio_number(channel, &gpio)) {
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(channel, "XIO") == 0) {
|
|
||||||
int base_gpio = get_xio_base();
|
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
gpio = base_gpio + i;
|
|
||||||
if (gpio_get_value(gpio, &bit) < 0) {
|
|
||||||
char err[1024];
|
|
||||||
snprintf(err, sizeof(err), "Could not get bit ('%s')", get_error_msg());
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, err);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
value |= (bit << i);
|
|
||||||
}
|
|
||||||
} else if (strcmp(channel, "CSID") == 0) {
|
|
||||||
int base_gpio = 132;
|
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
gpio = base_gpio + i;
|
|
||||||
if (gpio_get_value(gpio, &bit) < 0) {
|
|
||||||
char err[1024];
|
|
||||||
snprintf(err, sizeof(err), "Could not get bit ('%s')", get_error_msg());
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, err);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
value |= (bit << i);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
PyErr_SetString(PyExc_ValueError, "Invalid channel");
|
PyErr_SetString(PyExc_ValueError, "Invalid channel");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check channel is set up as an input or output
|
||||||
|
if (!module_setup || (dyn_int_array_get(&gpio_direction, gpio, -1) == -1))
|
||||||
|
{
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "You must setup() the GPIO channel first");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We only want to get a 8 bits here
|
||||||
|
if (gpio_get_more(gpio, 8, &value) < 0) {
|
||||||
|
char err[1024];
|
||||||
|
snprintf(err, sizeof(err), "Could not get 8 bits of data ('%s')", get_error_msg());
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, err);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
py_value = Py_BuildValue("i", value);
|
||||||
|
|
||||||
|
return py_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// python function value = read_word(channel)
|
||||||
|
static PyObject *py_read_word_gpio(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
int gpio;
|
||||||
|
char *channel;
|
||||||
|
unsigned int value = 0;
|
||||||
|
PyObject *py_value;
|
||||||
|
|
||||||
|
clear_error_msg();
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "s", &channel))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (get_gpio_number(channel, &gpio)) {
|
||||||
|
PyErr_SetString(PyExc_ValueError, "Invalid channel");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check channel is set up as an input or output
|
||||||
|
if (!module_setup || (dyn_int_array_get(&gpio_direction, gpio, -1) == -1))
|
||||||
|
{
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "You must setup() the GPIO channel first");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We only want to get a 8 bits here
|
||||||
|
if (gpio_get_more(gpio, 16, &value) < 0) {
|
||||||
|
char err[1024];
|
||||||
|
snprintf(err, sizeof(err), "Could not get 16 bits of data ('%s')", get_error_msg());
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, err);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
py_value = Py_BuildValue("i", value);
|
py_value = Py_BuildValue("i", value);
|
||||||
|
|
||||||
return py_value;
|
return py_value;
|
||||||
@ -912,7 +933,8 @@ PyMethodDef gpio_methods[] = {
|
|||||||
{"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"},
|
{"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"},
|
||||||
{"output", py_output_gpio, METH_VARARGS, "Output to a GPIO channel\ngpio - gpio channel\nvalue - 0/1 or False/True or LOW/HIGH"},
|
{"output", py_output_gpio, METH_VARARGS, "Output to a GPIO channel\ngpio - gpio channel\nvalue - 0/1 or False/True or LOW/HIGH"},
|
||||||
{"input", py_input_gpio, METH_VARARGS, "Input from a GPIO channel. Returns HIGH=1=True or LOW=0=False\ngpio - gpio channel"},
|
{"input", py_input_gpio, METH_VARARGS, "Input from a GPIO channel. Returns HIGH=1=True or LOW=0=False\ngpio - gpio channel"},
|
||||||
{"read_byte", py_read_byte_gpio, METH_VARARGS, "Read a byte from a set of GPIO channels. Returns 8-bit integer\ngpio - gpio channel. Valid channels: 'XIO', 'CSID'"},
|
{"read_byte", py_read_byte_gpio, METH_VARARGS, "Read a byte (8 bits) from a set of GPIO channels. Returns 8-bits of integer data\ngpio - gpio channel."},
|
||||||
|
{"read_word", py_read_word_gpio, METH_VARARGS, "Read a word (16 bits) from a set of GPIO channels. Returns 16-bits of integer data\ngpio - gpio channel."},
|
||||||
{"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"},
|
{"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"},
|
||||||
{"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"},
|
||||||
|
@ -62,8 +62,7 @@ static PyObject *py_cleanup(PyObject *self, PyObject *args)
|
|||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
if (!get_key(channel, key)) {
|
if (!get_key(channel, key)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Invalid SOFTPWM key or name.");
|
softpwm_cleanup();
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
softpwm_disable(key);
|
softpwm_disable(key);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user