mirror of
https://github.com/xtacocorex/CHIP_IO
synced 2025-07-20 04:43:21 +00:00
pull up/down feature addition to close #48. fixed gpio cleanup() function again, 3rd time is a charm. version bump to 0.3.4
This commit is contained in:
@ -1,3 +1,8 @@
|
|||||||
|
0.3.4
|
||||||
|
---
|
||||||
|
* Pull Up/Pull Down resistor setting now available for the R8 GPIO.
|
||||||
|
* Some general cleanup
|
||||||
|
|
||||||
0.3.3
|
0.3.3
|
||||||
----
|
----
|
||||||
* Added Debug printing for all the capabilities with the toggle_debug() function
|
* Added Debug printing for all the capabilities with the toggle_debug() function
|
||||||
|
@ -191,6 +191,15 @@ Inputs work similarly to outputs.::
|
|||||||
import CHIP_IO.GPIO as GPIO
|
import CHIP_IO.GPIO as GPIO
|
||||||
GPIO.setup("CSID0", GPIO.IN)
|
GPIO.setup("CSID0", GPIO.IN)
|
||||||
|
|
||||||
|
Other options when setting up pins::
|
||||||
|
|
||||||
|
# Specify pull up/pull down settings on a pin
|
||||||
|
GPIO.setup("CSID0", GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
||||||
|
# Specify initial value for an output
|
||||||
|
GPIO.setup("CSID0", GPIO.OUT, initial=1)
|
||||||
|
|
||||||
|
Pull Up/Down values are only for pins that are provided by the R8, the XIO are not capable of this. The allowable values are: PUD_OFF, PUD_UP, and PUD_DOWN.
|
||||||
|
|
||||||
Polling inputs::
|
Polling inputs::
|
||||||
|
|
||||||
if GPIO.input("CSID0"):
|
if GPIO.input("CSID0"):
|
||||||
|
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.3',
|
version = '0.3.4',
|
||||||
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',
|
||||||
|
@ -249,6 +249,22 @@ int gpio_number(pins_t *pin)
|
|||||||
return gpio_num;
|
return gpio_num;
|
||||||
} /* gpio_number */
|
} /* gpio_number */
|
||||||
|
|
||||||
|
int gpio_pud_capable(pins_t *pin)
|
||||||
|
{
|
||||||
|
int capable = -1;
|
||||||
|
|
||||||
|
switch (pin->base_method) {
|
||||||
|
case BASE_METHOD_AS_IS:
|
||||||
|
capable = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BASE_METHOD_XIO:
|
||||||
|
capable = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return capable;
|
||||||
|
}
|
||||||
|
|
||||||
int lookup_gpio_by_key(const char *key)
|
int lookup_gpio_by_key(const char *key)
|
||||||
{
|
{
|
||||||
@ -283,6 +299,39 @@ int lookup_gpio_by_altname(const char *altname)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lookup_pud_capable_by_key(const char *key)
|
||||||
|
{
|
||||||
|
pins_t *p;
|
||||||
|
for (p = pins_info; p->key != NULL; ++p) {
|
||||||
|
if (strcmp(p->key, key) == 0) {
|
||||||
|
return gpio_pud_capable(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lookup_pud_capable_by_name(const char *name)
|
||||||
|
{
|
||||||
|
pins_t *p;
|
||||||
|
for (p = pins_info; p->name != NULL; ++p) {
|
||||||
|
if (strcmp(p->name, name) == 0) {
|
||||||
|
return gpio_pud_capable(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lookup_pud_capable_by_altname(const char *altname)
|
||||||
|
{
|
||||||
|
pins_t *p;
|
||||||
|
for (p = pins_info; p->altname != NULL; ++p) {
|
||||||
|
if (strcmp(p->altname, altname) == 0) {
|
||||||
|
return gpio_pud_capable(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int lookup_ain_by_key(const char *key)
|
int lookup_ain_by_key(const char *key)
|
||||||
{
|
{
|
||||||
pins_t *p;
|
pins_t *p;
|
||||||
@ -396,17 +445,29 @@ int get_gpio_number(const char *key, int *gpio)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int compute_port_pin(const char *key, int *port, int *pin)
|
int compute_port_pin(const char *key, int gpio, int *port, int *pin)
|
||||||
{
|
{
|
||||||
int gpio;
|
int capable = 0;
|
||||||
int rtn;
|
int rtn = -1;
|
||||||
|
|
||||||
rtn = get_gpio_number(key, &gpio);
|
capable = lookup_pud_capable_by_key(key);
|
||||||
|
if (capable < 0) {
|
||||||
// Method from:
|
capable = lookup_pud_capable_by_name(key);
|
||||||
//https://bbs.nextthing.co/t/chippy-gonzales-fast-gpio/14056/6?u=xtacocorex
|
if (capable < 0) {
|
||||||
*port = gpio / 32;
|
capable = lookup_gpio_by_altname(key);
|
||||||
*pin = gpio % 32;
|
if (capable < 0) {
|
||||||
|
capable = 0; // default to false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (capable) {
|
||||||
|
// Method from:
|
||||||
|
// https://bbs.nextthing.co/t/chippy-gonzales-fast-gpio/14056/6?u=xtacocorex
|
||||||
|
*port = gpio / 32;
|
||||||
|
*pin = gpio % 32;
|
||||||
|
rtn = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
@ -92,9 +92,13 @@ int DEBUG;
|
|||||||
|
|
||||||
int get_xio_base(void);
|
int get_xio_base(void);
|
||||||
int gpio_number(pins_t *pin);
|
int gpio_number(pins_t *pin);
|
||||||
|
int gpio_pud_capable(pins_t *pin);
|
||||||
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);
|
||||||
|
int lookup_pud_capable_by_key(const char *key);
|
||||||
|
int lookup_pud_capable_by_name(const char *name);
|
||||||
|
int lookup_pud_capable_by_altname(const char *altname);
|
||||||
int lookup_ain_by_key(const char *key);
|
int lookup_ain_by_key(const char *key);
|
||||||
int lookup_ain_by_name(const char *name);
|
int lookup_ain_by_name(const char *name);
|
||||||
int copy_key_by_key(const char *input_key, char *key);
|
int copy_key_by_key(const char *input_key, char *key);
|
||||||
@ -113,4 +117,4 @@ void clear_error_msg(void);
|
|||||||
char *get_error_msg(void);
|
char *get_error_msg(void);
|
||||||
void add_error_msg(char *msg);
|
void add_error_msg(char *msg);
|
||||||
void toggle_debug(void);
|
void toggle_debug(void);
|
||||||
int compute_port_pin(const char *key, int *port, int *pin);
|
int compute_port_pin(const char *key, int gpio, int *port, int *pin);
|
||||||
|
@ -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.3");
|
version = Py_BuildValue("s", "0.3.4");
|
||||||
PyModule_AddObject(module, "VERSION", version);
|
PyModule_AddObject(module, "VERSION", version);
|
||||||
}
|
}
|
||||||
|
@ -38,17 +38,23 @@ SOFTWARE.
|
|||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include "event_gpio.h"
|
#include "event_gpio.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
const char *stredge[4] = {"none", "rising", "falling", "both"};
|
const char *stredge[4] = {"none", "rising", "falling", "both"};
|
||||||
|
|
||||||
|
// Memory Map for PUD
|
||||||
|
uint8_t *memmap;
|
||||||
|
|
||||||
// file descriptors
|
// file descriptors
|
||||||
struct fdx
|
struct fdx
|
||||||
{
|
{
|
||||||
@ -85,6 +91,63 @@ dyn_int_array_t *event_occurred = NULL;
|
|||||||
int thread_running = 0;
|
int thread_running = 0;
|
||||||
int epfd = -1;
|
int epfd = -1;
|
||||||
|
|
||||||
|
// Thanks to WereCatf and Chippy-Gonzales for the Memory Mapping code/help
|
||||||
|
int map_pio_memory()
|
||||||
|
{
|
||||||
|
if (DEBUG)
|
||||||
|
printf(" ** map_pio_memory: opening /dev/mem **\n");
|
||||||
|
int fd = open("/dev/mem", O_RDWR|O_SYNC);
|
||||||
|
if(fd < 0) {
|
||||||
|
char err[256];
|
||||||
|
snprintf(err, sizeof(err), "map_pio_memory: could not open /dev/mem (%s)", strerror(errno));
|
||||||
|
add_error_msg(err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// uint32_t addr = 0x01c20800 & ~(getpagesize() - 1);
|
||||||
|
//Requires memmap to be on pagesize-boundary
|
||||||
|
if (DEBUG)
|
||||||
|
printf(" ** map_pio_memory: mapping memory **\n");
|
||||||
|
memmap = (uint8_t *)mmap(NULL, getpagesize()*2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x01C20000);
|
||||||
|
if(memmap == NULL) {
|
||||||
|
char err[256];
|
||||||
|
snprintf(err, sizeof(err), "map_pio_memory: mmap failed (%s)", strerror(errno));
|
||||||
|
add_error_msg(err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
//Set memmap to point to PIO-registers
|
||||||
|
if (DEBUG)
|
||||||
|
printf(" ** map_pio_memory: moving to pio registers **\n");
|
||||||
|
memmap=memmap+0x800;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gpio_get_pud(int port, int pin)
|
||||||
|
{
|
||||||
|
if (DEBUG)
|
||||||
|
printf(" ** gpio_get_pud: port %d, pin %d **\n", port, pin);
|
||||||
|
volatile uint32_t *pioMem32, *configRegister;
|
||||||
|
pioMem32=(uint32_t *)(memmap+port*0x24+0x1c); //0x1c == pull-register
|
||||||
|
configRegister=pioMem32+(pin >> 4);
|
||||||
|
return *configRegister >> ((pin & 15) * 2) & 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gpio_set_pud(int port, int pin, uint8_t value)
|
||||||
|
{
|
||||||
|
if (DEBUG)
|
||||||
|
printf(" ** gpio_set_pud: port %d, pin %d, value %d **\n", port, pin, value);
|
||||||
|
value &= 3;
|
||||||
|
volatile uint32_t *pioMem32, *configRegister;
|
||||||
|
uint32_t mask;
|
||||||
|
pioMem32=(uint32_t *)(memmap+port*0x24+0x1c); //0x1c == pull-register
|
||||||
|
configRegister=pioMem32+(pin >> 4);
|
||||||
|
mask = ~(3 << ((pin & 15) * 2));
|
||||||
|
*configRegister &= mask;
|
||||||
|
*configRegister |= value << ((pin & 15) * 2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int gpio_export(int gpio)
|
int gpio_export(int gpio)
|
||||||
{
|
{
|
||||||
@ -119,7 +182,7 @@ int gpio_export(int gpio)
|
|||||||
|
|
||||||
// add to list
|
// add to list
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
printf(" ** gpio_export: creating data struct **\n");
|
printf(" ** gpio_export: creating data struct **\n");
|
||||||
new_gpio = malloc(sizeof(struct gpio_exp)); ASSRT(new_gpio != NULL);
|
new_gpio = malloc(sizeof(struct gpio_exp)); ASSRT(new_gpio != NULL);
|
||||||
|
|
||||||
new_gpio->gpio = gpio;
|
new_gpio->gpio = gpio;
|
||||||
|
@ -36,6 +36,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#define NO_EDGE 0
|
#define NO_EDGE 0
|
||||||
#define RISING_EDGE 1
|
#define RISING_EDGE 1
|
||||||
#define FALLING_EDGE 2
|
#define FALLING_EDGE 2
|
||||||
@ -54,6 +56,12 @@ SOFTWARE.
|
|||||||
#define PUD_DOWN 1
|
#define PUD_DOWN 1
|
||||||
#define PUD_UP 2
|
#define PUD_UP 2
|
||||||
|
|
||||||
|
extern uint8_t *memmap;
|
||||||
|
|
||||||
|
int map_pio_memory(void);
|
||||||
|
int gpio_get_pud(int port, int pin);
|
||||||
|
int gpio_set_pud(int port, int pin, uint8_t value);
|
||||||
|
|
||||||
int gpio_export(int gpio);
|
int gpio_export(int gpio);
|
||||||
int gpio_unexport(int gpio);
|
int gpio_unexport(int gpio);
|
||||||
void exports_cleanup(void);
|
void exports_cleanup(void);
|
||||||
|
163
source/py_gpio.c
163
source/py_gpio.c
@ -58,8 +58,29 @@ struct py_callback
|
|||||||
};
|
};
|
||||||
static struct py_callback *py_callbacks = NULL;
|
static struct py_callback *py_callbacks = NULL;
|
||||||
|
|
||||||
|
// python function toggle_debug()
|
||||||
|
static PyObject *py_toggle_debug(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
// toggle debug printing
|
||||||
|
toggle_debug();
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
static int init_module(void)
|
static int init_module(void)
|
||||||
{
|
{
|
||||||
|
clear_error_msg();
|
||||||
|
|
||||||
|
if (map_pio_memory() < 0) {
|
||||||
|
char err[2000];
|
||||||
|
snprintf(err, sizeof(err), "init_module error (%s)", get_error_msg());
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, err);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we make it here, we're good to go
|
||||||
|
if (DEBUG)
|
||||||
|
printf(" ** init_module: setup complete **\n");
|
||||||
module_setup = 1;
|
module_setup = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -93,7 +114,7 @@ static PyObject *py_cleanup(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The !channel fixes issues #50
|
// The !channel fixes issues #50
|
||||||
if (!channel || strcmp(channel, "") == 0) {
|
if (channel == NULL || strcmp(channel, "\0") == 0) {
|
||||||
event_cleanup();
|
event_cleanup();
|
||||||
} else {
|
} else {
|
||||||
if (get_gpio_number(channel, &gpio) < 0) {
|
if (get_gpio_number(channel, &gpio) < 0) {
|
||||||
@ -111,68 +132,91 @@ static PyObject *py_cleanup(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||||||
// python function setup(channel, direction, pull_up_down=PUD_OFF, initial=None)
|
// python function setup(channel, direction, pull_up_down=PUD_OFF, initial=None)
|
||||||
static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwargs)
|
static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
int gpio;
|
int gpio;
|
||||||
char *channel;
|
char *channel;
|
||||||
int direction;
|
int direction;
|
||||||
int pud = PUD_OFF;
|
int pud = PUD_OFF;
|
||||||
int initial = 0;
|
int initial = 0;
|
||||||
static char *kwlist[] = {"channel", "direction", "pull_up_down", "initial", NULL};
|
static char *kwlist[] = {"channel", "direction", "pull_up_down", "initial", NULL};
|
||||||
|
|
||||||
clear_error_msg();
|
clear_error_msg();
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si|ii", kwlist, &channel, &direction, &pud, &initial))
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si|ii", kwlist, &channel, &direction, &pud, &initial))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!module_setup) {
|
if (!module_setup) {
|
||||||
init_module();
|
init_module();
|
||||||
}
|
}
|
||||||
|
|
||||||
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()");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (direction == OUTPUT)
|
// Force pud to be off if we're configured for output
|
||||||
pud = PUD_OFF;
|
if (direction == OUTPUT) {
|
||||||
|
pud = PUD_OFF;
|
||||||
if (pud != PUD_OFF && pud != PUD_DOWN && pud != PUD_UP)
|
}
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_ValueError, "Invalid value for pull_up_down - should be either PUD_OFF, PUD_UP or PUD_DOWN");
|
if (pud != PUD_OFF && pud != PUD_DOWN && pud != PUD_UP)
|
||||||
return NULL;
|
{
|
||||||
}
|
PyErr_SetString(PyExc_ValueError, "Invalid value for pull_up_down - should be either PUD_OFF, PUD_UP or PUD_DOWN");
|
||||||
|
return NULL;
|
||||||
if (get_gpio_number(channel, &gpio) < 0) {
|
}
|
||||||
char err[2000];
|
|
||||||
snprintf(err, sizeof(err), "Invalid channel %s. (%s)", channel, get_error_msg());
|
if (get_gpio_number(channel, &gpio) < 0) {
|
||||||
PyErr_SetString(PyExc_ValueError, err);
|
char err[2000];
|
||||||
return NULL;
|
snprintf(err, sizeof(err), "Invalid channel %s. (%s)", channel, get_error_msg());
|
||||||
}
|
PyErr_SetString(PyExc_ValueError, err);
|
||||||
|
return NULL;
|
||||||
if (gpio_export(gpio) < 0) {
|
}
|
||||||
char err[2000];
|
|
||||||
snprintf(err, sizeof(err), "Error setting up channel %s, maybe already exported? (%s)", channel, get_error_msg());
|
if (gpio_export(gpio) < 0) {
|
||||||
PyErr_SetString(PyExc_RuntimeError, err);
|
char err[2000];
|
||||||
return NULL;
|
snprintf(err, sizeof(err), "Error setting up channel %s, maybe already exported? (%s)", channel, get_error_msg());
|
||||||
}
|
PyErr_SetString(PyExc_RuntimeError, err);
|
||||||
if (gpio_set_direction(gpio, direction) < 0) {
|
return NULL;
|
||||||
char err[2000];
|
}
|
||||||
snprintf(err, sizeof(err), "Error setting direction %d on channel %s. (%s)", direction, channel, get_error_msg());
|
if (gpio_set_direction(gpio, direction) < 0) {
|
||||||
PyErr_SetString(PyExc_RuntimeError, err);
|
char err[2000];
|
||||||
return NULL;
|
snprintf(err, sizeof(err), "Error setting direction %d on channel %s. (%s)", direction, channel, get_error_msg());
|
||||||
}
|
PyErr_SetString(PyExc_RuntimeError, err);
|
||||||
if (direction == OUTPUT) {
|
return NULL;
|
||||||
if (gpio_set_value(gpio, initial) < 0) {
|
}
|
||||||
|
|
||||||
|
// Pull Up/Down
|
||||||
|
int port, pin;
|
||||||
|
if (compute_port_pin(channel, gpio, &port, &pin) < 0) {
|
||||||
|
char err[2000];
|
||||||
|
snprintf(err, sizeof(err), "Pull Up/Down setting not capable for %s. (%s)", channel, get_error_msg());
|
||||||
|
PyErr_SetString(PyExc_ValueError, err);
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
// Set the PUD
|
||||||
|
gpio_set_pud(port, pin, pud);
|
||||||
|
// Check it was set properly
|
||||||
|
int pudr = gpio_get_pud(port, pin);
|
||||||
|
if (pudr != pud) {
|
||||||
|
char err[2000];
|
||||||
|
snprintf(err, sizeof(err), "Error setting pull up down %d on channel %s", pud, channel);
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, err);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direction == OUTPUT) {
|
||||||
|
if (gpio_set_value(gpio, initial) < 0) {
|
||||||
char err[2000];
|
char err[2000];
|
||||||
snprintf(err, sizeof(err), "Error setting initial value %d on channel %s. (%s)", initial, channel, get_error_msg());
|
snprintf(err, sizeof(err), "Error setting initial value %d on channel %s. (%s)", initial, channel, get_error_msg());
|
||||||
PyErr_SetString(PyExc_RuntimeError, err);
|
PyErr_SetString(PyExc_RuntimeError, err);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
remember_gpio_direction(gpio, direction);
|
remember_gpio_direction(gpio, direction);
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
} /* py_setup_channel */
|
} /* py_setup_channel */
|
||||||
|
|
||||||
|
|
||||||
@ -831,6 +875,7 @@ PyMethodDef gpio_methods[] = {
|
|||||||
{"selftest", py_selftest, METH_VARARGS, "Internal unit tests"},
|
{"selftest", py_selftest, METH_VARARGS, "Internal unit tests"},
|
||||||
{"direction", (PyCFunction)py_set_direction, METH_VARARGS | METH_KEYWORDS, "Change direction of gpio channel. Either INPUT or OUTPUT\n" },
|
{"direction", (PyCFunction)py_set_direction, METH_VARARGS | METH_KEYWORDS, "Change direction of gpio channel. Either INPUT or OUTPUT\n" },
|
||||||
{"setmode", (PyCFunction)py_setmode, METH_VARARGS, "Dummy function that does nothing but maintain compatibility with RPi.GPIO\n" },
|
{"setmode", (PyCFunction)py_setmode, METH_VARARGS, "Dummy function that does nothing but maintain compatibility with RPi.GPIO\n" },
|
||||||
|
{"toggle_debug", py_toggle_debug, METH_VARARGS, "Toggles the enabling/disabling of Debug print output"},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,6 +34,15 @@ SOFTWARE.
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "c_softpwm.h"
|
#include "c_softpwm.h"
|
||||||
|
|
||||||
|
// python function toggle_debug()
|
||||||
|
static PyObject *py_toggle_debug(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
// toggle debug printing
|
||||||
|
toggle_debug();
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
// python function cleanup(channel=None)
|
// python function cleanup(channel=None)
|
||||||
static PyObject *py_cleanup(PyObject *self, PyObject *args)
|
static PyObject *py_cleanup(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
@ -48,8 +57,9 @@ static PyObject *py_cleanup(PyObject *self, PyObject *args)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// The !channel fixes issue #50
|
// The !channel fixes issue #50
|
||||||
if (!channel || strcmp(channel, "") == 0) {
|
if (channel == NULL || strcmp(channel, "\0") == 0) {
|
||||||
softpwm_cleanup();
|
softpwm_cleanup();
|
||||||
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
if (!get_key(channel, key)) {
|
if (!get_key(channel, key)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Invalid SOFTPWM key or name.");
|
PyErr_SetString(PyExc_ValueError, "Invalid SOFTPWM key or name.");
|
||||||
@ -195,11 +205,12 @@ static PyObject *py_set_frequency(PyObject *self, PyObject *args, PyObject *kwar
|
|||||||
static const char moduledocstring[] = "Software PWM functionality of a CHIP using Python";
|
static const char moduledocstring[] = "Software PWM functionality of a CHIP using Python";
|
||||||
|
|
||||||
PyMethodDef pwm_methods[] = {
|
PyMethodDef pwm_methods[] = {
|
||||||
{ "start", (PyCFunction)py_start_channel, METH_VARARGS | METH_KEYWORDS, "Set up and start the PWM channel. channel can be in the form of 'XIO-P0', or 'U14_13'"},
|
{"start", (PyCFunction)py_start_channel, METH_VARARGS | METH_KEYWORDS, "Set up and start the PWM channel. channel can be in the form of 'XIO-P0', or 'U14_13'"},
|
||||||
{ "stop", (PyCFunction)py_stop_channel, METH_VARARGS | METH_KEYWORDS, "Stop the PWM channel. channel can be in the form of 'XIO-P0', or 'U14_13'"},
|
{"stop", (PyCFunction)py_stop_channel, METH_VARARGS | METH_KEYWORDS, "Stop the PWM channel. channel can be in the form of 'XIO-P0', or 'U14_13'"},
|
||||||
{ "set_duty_cycle", (PyCFunction)py_set_duty_cycle, METH_VARARGS, "Change the duty cycle\ndutycycle - between 0.0 and 100.0" },
|
{"set_duty_cycle", (PyCFunction)py_set_duty_cycle, METH_VARARGS, "Change the duty cycle\ndutycycle - between 0.0 and 100.0" },
|
||||||
{ "set_frequency", (PyCFunction)py_set_frequency, METH_VARARGS, "Change the frequency\nfrequency - frequency in Hz (freq > 0.0)" },
|
{"set_frequency", (PyCFunction)py_set_frequency, METH_VARARGS, "Change the frequency\nfrequency - frequency in Hz (freq > 0.0)" },
|
||||||
{ "cleanup", (PyCFunction)py_cleanup, METH_VARARGS, "Clean up by resetting all GPIO channels that have been used by this program to INPUT with no pullup/pulldown and no event detection"},
|
{"cleanup", (PyCFunction)py_cleanup, METH_VARARGS, "Clean up by resetting all GPIO channels that have been used by this program to INPUT with no pullup/pulldown and no event detection"},
|
||||||
|
{"toggle_debug", py_toggle_debug, METH_VARARGS, "Toggles the enabling/disabling of Debug print output"},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user