1
0
mirror of https://github.com/xtacocorex/CHIP_IO synced 2025-07-19 20:33: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:
Robert Wolterman
2017-01-29 22:58:41 +00:00
parent 6beacbb382
commit cd85e2b5eb
8 changed files with 130 additions and 41 deletions

View File

@ -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
---
* Quick fix as I borked XIO setup as inputs with the latest change that enabled PUD

View File

@ -205,6 +205,15 @@ Polling inputs::
else:
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.
Waiting for an edge (GPIO.RISING, GPIO.FALLING, or GPIO.BOTH::

View File

@ -20,7 +20,7 @@ classifiers = ['Development Status :: 3 - Alpha',
'Topic :: System :: Hardware']
setup(name = 'CHIP_IO',
version = '0.3.4.1',
version = '0.3.5',
author = 'Robert Wolterman',
author_email = 'robert.wolterman@gmail.com',
description = 'A module to control CHIP IO channels',

View File

@ -88,6 +88,6 @@ void define_constants(PyObject *module)
module_debug = Py_BuildValue("i", DEBUG ? Py_True: Py_False);
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);
}

View File

@ -506,8 +506,7 @@ int gpio_get_value(int gpio, unsigned int *value)
int fd = fd_lookup(gpio);
char ch;
if (!fd)
{
if (!fd) {
if ((fd = open_value_file(gpio)) == -1) {
char err[256];
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;
}
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 fd;

View File

@ -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_set_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 open_value_file(int gpio);

View File

@ -86,7 +86,6 @@ static int init_module(void)
return 0;
}
static void remember_gpio_direction(int gpio, int direction)
{
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();
} else {
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;
event_cleanup();
}
gpio_unexport(gpio);
}
@ -290,13 +286,12 @@ static PyObject *py_input_gpio(PyObject *self, PyObject *args)
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)
static PyObject *py_read_byte_gpio(PyObject *self, PyObject *args)
{
int gpio;
char *channel;
int i;
unsigned int bit;
unsigned int value = 0;
PyObject *py_value;
@ -306,37 +301,63 @@ static PyObject *py_read_byte_gpio(PyObject *self, PyObject *args)
return NULL;
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");
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);
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"},
{"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"},
{"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"},
{"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"},

View File

@ -62,8 +62,7 @@ static PyObject *py_cleanup(PyObject *self, PyObject *args)
return NULL;
} else {
if (!get_key(channel, key)) {
PyErr_SetString(PyExc_ValueError, "Invalid SOFTPWM key or name.");
return NULL;
softpwm_cleanup();
}
softpwm_disable(key);
}