Skip to content
Snippets Groups Projects
Commit 72d6ad97 authored by Ivica Bukvic's avatar Ivica Bukvic
Browse files

*added new externals for raspberry pi (disis_gpio for digital I/O and...

*added new externals for raspberry pi (disis_gpio for digital I/O and disis_spi for analog I/O using mcp3008 A/D converter). Provided preliminary help files. PWM on gpio needs to be tested further. So does the build script. TODO: add this to the installer, including 4755 chown_gpio script.
parent ea50b01c
No related branches found
No related tags found
No related merge requests found
Showing
with 372 additions and 417 deletions
curdir=`pwd`
git clone git://git.drogon.net/wiringPi
cd wiringPi/ && git pull && cd wiringPi/ && make static
cd $curdir
make
exit 0
sudo chown -R $USER:$USER /sys/class/gpio/*
sudo chown $USER:$USER /sys/class/gpio/gpio*/*
exit 0
#N canvas 423 183 777 495 10;
#X obj 27 312 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
#X floatatom 424 428 5 0 0 0 - - -, f 5;
#X obj 424 449 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
-1 -1;
#X obj 27 333 metro 50;
#X msg 210 126 open;
#X msg 251 126 close;
#X msg 26 68 export 27;
#X msg 215 68 unexport;
#X msg 26 126 direction in;
#X msg 115 126 direction out;
#X obj 424 407 disis_gpio 27;
#X msg 164 68 export;
#X msg 26 211 togglepwm \$1;
#X obj 26 189 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
#X msg 89 333 pwm \$1;
#X obj 89 312 nbx 5 14 0 1023 0 0 empty empty empty 0 -8 0 10 -262144
-1 -1 0 256 0;
#X text 150 312 pwm range is 0-1023;
#X msg 95 68 export 18;
#X floatatom 499 428 5 0 0 0 - - -, f 5;
#X text 24 27 1st export the desired pin or use "export" without an
argument if you have pin already specified via previous export call
or as a creation argument;
#X text 24 107 2nd set the direction \, and open the pin;
#X text 24 170 3rd (optional) enable hardware pwm (works only on pin
18);
#X text 24 250 4th either start sending data by sending float 0 or
1 to a regular pin or a 0-1023 range to a pwm (18) pin. If receiving
data \, start the metro to get updates through the first outlet. Metro
is not needed if only sending data.;
#X text 536 428 status (0=closed \, 1 open);
#X text 336 427 incoming data;
#X obj 424 312 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
#X text 444 311 if communicating to a pin without pwm (accepts 0 or
1);
#X text 512 406 optional arg sets the pin number;
#X connect 0 0 3 0;
#X connect 1 0 2 0;
#X connect 3 0 10 0;
#X connect 4 0 10 0;
#X connect 5 0 10 0;
#X connect 6 0 10 0;
#X connect 7 0 10 0;
#X connect 8 0 10 0;
#X connect 9 0 10 0;
#X connect 10 0 1 0;
#X connect 10 1 18 0;
#X connect 11 0 10 0;
#X connect 12 0 10 0;
#X connect 13 0 12 0;
#X connect 14 0 10 0;
#X connect 15 0 14 0;
#X connect 17 0 10 0;
#X connect 25 0 10 0;
......@@ -14,6 +14,8 @@
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include "g_canvas.h"
#include "wiringPi/wiringPi/wiringPi.h"
static t_class *disis_gpio_class;
......@@ -24,61 +26,143 @@ typedef struct _disis_gpio
{
t_object x_obj;
t_outlet *x_out1;
t_outlet *x_out2;
int x_pin;
int x_export;
int x_fdvalue;
int x_dir;
int x_pwm;
//int x_pwmrange;
t_symbol *x_chown;
} t_disis_gpio;
static void disis_gpio_enable(t_disis_gpio *x, t_float f, t_float dir)
static void disis_gpio_close(t_disis_gpio *x);
static void disis_gpio_reflectstatus(t_disis_gpio *x) {
if (x->x_fdvalue >= 0) {
outlet_float(x->x_out2, 1);
} else {
outlet_float(x->x_out2, 0);
}
}
static int disis_gpio_isvalidpin(int pin) {
int ret;
switch (pin) {
case 0:
case 4:
case 7:
case 8:
case 17:
case 18:
case 22:
case 23:
case 24:
case 25:
case 27:
ret = 1;
break;
default:
ret = 0;
post("disis_gpio: invalid pin number");
break;
}
return(ret);
}
static void disis_gpio_export(t_disis_gpio *x, t_float f)
{
char buf[1024];
if (f != 0) {
if (dir) {
sprintf(buf, "gpio export %d out\n", x->x_pin);
} else {
sprintf(buf, "gpio export %d in\n", x->x_pin);
if (x->x_export) {
post("disis_gpio: already exported");
return;
}
if ((int)f != 0 || x->x_pin != 0) {
if ( ((int)f != 0 && disis_gpio_isvalidpin((int)f)) || ((int)f == 0 && disis_gpio_isvalidpin(x->x_pin)) ) {
if ((int)f != 0)
x->x_pin = (int)f;
x->x_export = 1;
post("disis_gpio: exporting pin %d\n", x->x_pin);
if (system(x->x_chown->s_name) < 0) { // first to adjust permissions for /sys/class/gpio so that we can export
post("disis_gpio: failed setting permissions to /sys/class/gpio folder");
x->x_export = 0;
}
char buf[1024];
//sprintf(buf, "gpio export %d %s\n", x->x_pin, dir->s_name);
sprintf(buf, "echo %d > /sys/class/gpio/export\n", x->x_pin);
if (system(buf) < 0) {
post("disis_gpio: failed to export requested pin");
x->x_export = 0;
}
if (system(x->x_chown->s_name) < 0) { // to adjust permissions within the exported gpio pin
post("disis_gpio: failed setting permissions to /sys/class/gpio/gpio* subfolders");
x->x_export = 0;
}
}
} else sprintf(buf, "gpio unexport %d\n", x->x_pin);
system(buf);
} else {
post("disis_gpio: invalid pin number (0)");
}
}
static void disis_gpio_output(t_disis_gpio *x, t_float f)
static void disis_gpio_unexport(t_disis_gpio *x)
{
char buf[1024];
x->x_dir = f;
if (f != 0)
sprintf(buf, "gpio -g mode %d out\n",
x->x_pin);
else sprintf(buf, "gpio -g mode %d in\n",
x->x_pin);
system(buf);
if (x->x_export) {
char buf[1024];
if (x->x_fdvalue >= 0) {
disis_gpio_close(x);
}
//sprintf(buf, "gpio unexport %d\n", x->x_pin);
sprintf(buf, "echo %d > /sys/class/gpio/unexport\n", x->x_pin);
if (system(buf) < 0) {
post("disis_gpio: failed to unexport requested pin");
}
x->x_export = 0;
}
}
static void disis_gpio_open(t_disis_gpio *x, t_float f)
static void disis_gpio_direction(t_disis_gpio *x, t_symbol *dir)
{
if (strlen(dir->s_name) > 0) {
char buf[1024];
int d = -1;
if (!strcmp(dir->s_name, "in")) d = 0;
else if (!strcmp(dir->s_name, "out")) d = 1;
if (d >= 0) {
x->x_dir = d;
//sprintf(buf, "gpio -g mode %d %s\n", x->x_pin, dir->s_name);
sprintf(buf, "echo %s > /sys/class/gpio/gpio%d/direction\n", dir->s_name, x->x_pin);
if (system(buf) < 0) {
post("disis_gpio: failed to set pin direction");
}
}
}
}
static void disis_gpio_open(t_disis_gpio *x)
{
char buf[1024];
sprintf(buf, "/sys/class/gpio/gpio%d/value", x->x_pin);
if (f != 0)
if (x->x_fdvalue >= 0)
post("disis_gpio: already open");
else
{
if (x->x_fdvalue >= 0)
post("disis_gpio: already open");
else
{
x->x_fdvalue = open(buf, O_RDWR);
if (x->x_fdvalue < 0)
post("%s: %s", buf, strerror(errno));
x->x_fdvalue = open(buf, O_RDWR);
if (x->x_fdvalue < 0) {
post("%s: %s", buf, strerror(errno));
}
}
disis_gpio_reflectstatus(x);
}
static void disis_gpio_close(t_disis_gpio *x)
{
if (x->x_fdvalue < 0)
post("disis_gpio: already closed");
else
{
if (x->x_fdvalue < 0)
post("disis_gpio: already closed");
else
{
close(x->x_fdvalue);
x->x_fdvalue = -1;
}
close(x->x_fdvalue);
x->x_fdvalue = -1;
}
disis_gpio_reflectstatus(x);
}
static void disis_gpio_float(t_disis_gpio *x, t_float f)
......@@ -94,6 +178,45 @@ static void disis_gpio_float(t_disis_gpio *x, t_float f)
}
}
static void disis_gpio_pwm(t_disis_gpio *x, t_float val)
{
if (x->x_fdvalue != -1 && x->x_pwm && x->x_pin == 18) {
pwmWrite (x->x_pin, (int)val);
} else {
post("disis_gpio: pwm messages can be only sent to opened pin 18 with togglepwm enabled");
}
}
static void disis_gpio_togglepwm(t_disis_gpio *x, t_float on)
{
if (x->x_fdvalue != -1 && x->x_pin == 18) {
if (x->x_pwm == (int)on) {
if (x->x_pwm)
post("disis_gpio: pwm already enabled");
else
post("disis_gpio: pwm already disabled");
} else {
x->x_pwm = (int)on;
if (x->x_pwm)
pinMode(x->x_pin, PWM_OUTPUT);
else
pinMode(x->x_pin, OUTPUT);
}
} else {
post("disis_gpio: you can toggle pwm only on opened pin 18");
}
}
/*static void disis_gpio_pwmrange(t_disis_gpio *x, t_float r)
{
if (x->x_fdvalue != -1 && x->x_pwm && x->x_pin == 18) {
pwmSetRange((int)r);
x->x_pwmrange = (int)r;
} else {
post("disis_gpio: you can toggle pwm only on opened pin 18 with togglepwm enabled");
}
}*/
static void disis_gpio_bang(t_disis_gpio *x)
{
char buf[1024];
......@@ -123,13 +246,25 @@ static void disis_gpio_bang(t_disis_gpio *x)
}
}
static void disis_gpio_free(t_disis_gpio *x) {
disis_gpio_unexport(x);
}
static void *disis_gpio_new(t_floatarg f)
{
if (!disis_gpio_isvalidpin((int)f)) return(NULL);
t_disis_gpio *x = (t_disis_gpio *)pd_new(disis_gpio_class);
x->x_out1 = outlet_new(&x->x_obj, gensym("float"));
x->x_out2 = outlet_new(&x->x_obj, gensym("float"));
x->x_fdvalue = -1;
x->x_pin = f;
x->x_export = 0;
x->x_dir = 0;
x->x_pwm = 0;
//x->x_pwmrange = 0;
char buf[FILENAME_MAX];
canvas_makefilename(glist_getcanvas((t_glist*)canvas_getcurrent()), "@pd_extra/disis_gpio/chown_gpio&", buf, FILENAME_MAX);
x->x_chown = gensym(buf);
return (x);
}
......@@ -137,13 +272,20 @@ static void *disis_gpio_new(t_floatarg f)
void disis_gpio_setup(void)
{
disis_gpio_class = class_new(gensym("disis_gpio"), (t_newmethod)disis_gpio_new,
0, sizeof(t_disis_gpio), 0, A_DEFFLOAT, 0);
class_addmethod(disis_gpio_class, (t_method)disis_gpio_enable, gensym("enable"),
A_DEFFLOAT, A_DEFFLOAT, 0);
class_addmethod(disis_gpio_class, (t_method)disis_gpio_output, gensym("output"),
A_FLOAT, 0);
class_addmethod(disis_gpio_class, (t_method)disis_gpio_open, gensym("open"),
(t_method)disis_gpio_free, sizeof(t_disis_gpio), 0, A_DEFFLOAT, 0);
class_addmethod(disis_gpio_class, (t_method)disis_gpio_export, gensym("export"),
A_DEFFLOAT, 0);
class_addmethod(disis_gpio_class, (t_method)disis_gpio_unexport, gensym("unexport"), 0);
class_addmethod(disis_gpio_class, (t_method)disis_gpio_direction, gensym("direction"),
A_DEFSYMBOL, 0);
class_addmethod(disis_gpio_class, (t_method)disis_gpio_open, gensym("open"), 0);
class_addmethod(disis_gpio_class, (t_method)disis_gpio_close, gensym("close"), 0);
class_addmethod(disis_gpio_class, (t_method)disis_gpio_pwm, gensym("pwm"),
A_FLOAT, 0);
class_addmethod(disis_gpio_class, (t_method)disis_gpio_togglepwm, gensym("togglepwm"),
A_FLOAT, 0);
//class_addmethod(disis_gpio_class, (t_method)disis_gpio_pwmrange, gensym("pwmrange"),
// A_FLOAT, 0);
class_addfloat(disis_gpio_class, disis_gpio_float);
class_addbang(disis_gpio_class, disis_gpio_bang);
}
NAME=disis_gpio
CSYM=$(NAME)
APPENDFLAGS=wiringPi/wiringPi/libwiringPi.a
include ../makefile.include
#N canvas 187 97 450 300 10;
#X obj 82 58 gpio 4;
#X msg 73 21 open 1;
#X msg 134 22 open 0;
#X obj 215 24 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
#X obj 255 24 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
-1;
#X floatatom 94 96 5 0 0 0 - - -;
#X obj 95 122 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
-1;
#X obj 231 62 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
#X obj 231 93 metro 1;
#X obj 175 149 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
#X obj 175 180 metro 1;
#X connect 1 0 0 0;
#X connect 2 0 0 0;
#X connect 3 0 0 0;
#X connect 4 0 0 0;
#X connect 5 0 6 0;
#X connect 7 0 8 0;
#X connect 8 0 0 0;
#X connect 9 0 10 0;
#N canvas 640 214 566 406 10;
#X obj 26 304 disis_spi, f 51;
#X msg 26 197 open;
#X msg 202 197 close;
#X floatatom 26 347 5 0 0 0 - - -, f 5;
#X floatatom 349 347 5 0 0 0 - - -, f 5;
#X msg 69 197 open /dev/spidev0.0;
#X obj 209 262 metro 100;
#X obj 209 238 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
#X floatatom 63 347 5 0 0 0 - - -, f 5;
#X floatatom 101 347 5 0 0 0 - - -, f 5;
#X floatatom 139 347 5 0 0 0 - - -, f 5;
#X floatatom 177 347 5 0 0 0 - - -, f 5;
#X floatatom 215 347 5 0 0 0 - - -, f 5;
#X floatatom 253 347 5 0 0 0 - - -, f 5;
#X floatatom 291 347 5 0 0 0 - - -, f 5;
#X text 27 367 8 channels of incoming analog data (range 0-1023);
#X text 387 347 status (0=closed \, 1=open);
#X text 231 238 toggle metro on to get updates;
#X obj 23 111 pddplink http://moderndevice.com/product/lots-of-pots-lop-board-for-raspberry-pi/
;
#X text 23 20 disi_spi works with mcp3008 A/D converter and provides
8 analog inputs into Raspberry Pi. The easiest way to get mcp3008
installed on Raspberry Pi is to use Lots of Pots shield made and sold
by Modern Device (you can get the cheaper NOP board without the pots
so that you can wire other sensors): ;
#X text 23 151 The open the device simply press open (the implied devicename
is /dev/spidev0.0) or do open <devicename>. To close device press close.
;
#X connect 0 0 3 0;
#X connect 0 1 8 0;
#X connect 0 2 9 0;
#X connect 0 3 10 0;
#X connect 0 4 11 0;
#X connect 0 5 12 0;
#X connect 0 6 13 0;
#X connect 0 7 14 0;
#X connect 0 8 4 0;
#X connect 1 0 0 0;
#X connect 2 0 0 0;
#X connect 5 0 0 0;
#X connect 6 0 0 0;
#X connect 7 0 6 0;
......@@ -12,14 +12,6 @@
* It can be only 0.5, 1, 2, 4, 8, 16, 32 MHz.
* Will use 1MHz for now and test it further.
* spifd -> file descriptor for the SPI device
*
* The class contains two constructors that initialize the above
* variables and then open the appropriate spidev device using spiOpen().
* The class contains one destructor that automatically closes the spidev
* device when object is destroyed by calling spiClose().
* The spiWriteRead() function sends the data "data" of length "length"
* to the spidevice and at the same time receives data of the same length.
* Resulting data is stored in the "data" variable after the function call.
* ****************************************************************************/
#include "m_pd.h"
#include <unistd.h>
......@@ -30,17 +22,22 @@
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
static t_class *disis_spi_class;
//#define FILE_PREFIX "/sys/class/gpio/"
//#define FILE_EXPORT FILE_PREFIX "export"
typedef struct _disis_spi
{
t_object x_obj;
t_outlet *x_out1;
t_outlet *x_out2;
t_outlet *x_out3;
t_outlet *x_out4;
t_outlet *x_out5;
t_outlet *x_out6;
t_outlet *x_out7;
t_outlet *x_out8;
t_outlet *x_out9;
t_symbol *spidev;
unsigned char mode;
unsigned char bitsPerWord;
......@@ -55,21 +52,23 @@ static int disis_spi_close(t_disis_spi *spi);
static void disis_spi_free(t_disis_spi *spi);
/**********************************************************
* disis_spi_open() :function is called by the constructor.
* disis_spi_open() :function is called by the "open" command
* It is responsible for opening the spidev device
* "devspi" and then setting up the spidev interface.
* private member variables are used to configure spidev.
* They must be set appropriately by constructor before calling
* member variables are used to configure spidev.
* They must be set appropriately before calling
* this function.
* *********************************************************/
static void disis_spi_open(t_disis_spi *spi, t_symbol *devspi){
int statusVal = 0;
if (devspi == &s_)
if (strlen(devspi->s_name) == 0) {
spi->spidev = gensym("/dev/spidev0.0");
else
} else {
spi->spidev = devspi;
spi->spifd = open(devspi->s_name, O_RDWR);
}
spi->spifd = open(spi->spidev->s_name, O_RDWR);
if(spi->spifd < 0) {
statusVal = -1;
pd_error(spi, "could not open SPI device");
goto spi_output;
}
......@@ -116,18 +115,19 @@ static void disis_spi_open(t_disis_spi *spi, t_symbol *devspi){
goto spi_output;
}
spi_output:
outlet_float(spi->x_out2, statusVal);
if (!statusVal) statusVal = 1;
else statusVal = 0;
outlet_float(spi->x_out9, statusVal);
}
/***********************************************************
* disis_spi_close(): Responsible for closing the spidev interface.
* Called in destructor
* *********************************************************/
static int disis_spi_close(t_disis_spi *spi){
int statusVal = -1;
if (spi->spifd == -1) {
pd_error(spi, "disis_spi: device not open\n");
pd_error(spi, "disis_spi: device not open");
return(-1);
}
statusVal = close(spi->spifd);
......@@ -135,7 +135,9 @@ static int disis_spi_close(t_disis_spi *spi){
pd_error(spi, "disis_spi: could not close SPI device");
exit(1);
}
return statusVal;
outlet_float(spi->x_out9, 0);
spi->spifd = -1;
return(statusVal);
}
/********************************************************************
......@@ -195,32 +197,44 @@ static int disis_spi_write_read(t_disis_spi *spi, unsigned char *data, int lengt
* byte3 = b7 - b0
*
* after conversion must merge data[1] and data[2] to get final result
*
*
*
* *********************************************************************/
static void disis_spi_bang(t_disis_spi *spi)
{
int a2dVal = 0;
if (spi->spifd == -1) {
pd_error(spi, "device not open %d", spi->spifd);
return;
}
int a2dVal[8];
int a2dChannel = 0;
unsigned char data[3];
data[0] = 1; // first byte transmitted -> start bit
data[1] = 0b10000000 |( ((a2dChannel & 7) << 4)); // second byte transmitted -> (SGL/DIF = 1, D2=D1=D0=0)
data[2] = 0; // third byte transmitted....don't care
for (a2dChannel = 0; a2dChannel < 8; a2dChannel++) {
data[0] = 1; // first byte transmitted -> start bit
data[1] = 0b10000000 |( ((a2dChannel & 7) << 4)); // second byte transmitted -> (SGL/DIF = 1, D2=D1=D0=0)
data[2] = 0; // third byte transmitted....don't care
disis_spi_write_read(spi, data, sizeof(data));
disis_spi_write_read(spi, data, sizeof(data));
a2dVal[a2dChannel] = 0;
a2dVal[a2dChannel] = (data[1]<< 8) & 0b1100000000; //merge data[1] & data[2] to get result
a2dVal[a2dChannel] |= (data[2] & 0xff);
//fprintf(stderr,"%d\n", a2dVal);
}
a2dVal = 0;
a2dVal = (data[1]<< 8) & 0b1100000000; //merge data[1] & data[2] to get result
a2dVal |= (data[2] & 0xff);
fprintf(stderr,"%d\n", a2dVal);
outlet_float(spi->x_out1, a2dVal);
outlet_float(spi->x_out8, a2dVal[7]);
outlet_float(spi->x_out7, a2dVal[6]);
outlet_float(spi->x_out6, a2dVal[5]);
outlet_float(spi->x_out5, a2dVal[4]);
outlet_float(spi->x_out4, a2dVal[3]);
outlet_float(spi->x_out3, a2dVal[2]);
outlet_float(spi->x_out2, a2dVal[1]);
outlet_float(spi->x_out1, a2dVal[0]);
}
/*************************************************
* init function. lets user set obj variables
* init function.
* ***********************************************/
static t_disis_spi *disis_spi_new(t_symbol *devspi){
t_disis_spi *spi = (t_disis_spi *)pd_new(disis_spi_class);
......@@ -228,6 +242,13 @@ static t_disis_spi *disis_spi_new(t_symbol *devspi){
//t_disis_spi *a2d = disis_spi_new("/dev/spidev0.0", spi_MODE_0, 1000000, 8);
spi->x_out1 = outlet_new(&spi->x_obj, gensym("float"));
spi->x_out2 = outlet_new(&spi->x_obj, gensym("float"));
spi->x_out3 = outlet_new(&spi->x_obj, gensym("float"));
spi->x_out4 = outlet_new(&spi->x_obj, gensym("float"));
spi->x_out5 = outlet_new(&spi->x_obj, gensym("float"));
spi->x_out6 = outlet_new(&spi->x_obj, gensym("float"));
spi->x_out7 = outlet_new(&spi->x_obj, gensym("float"));
spi->x_out8 = outlet_new(&spi->x_obj, gensym("float"));
spi->x_out9 = outlet_new(&spi->x_obj, gensym("float"));
spi->spidev = devspi;
spi->mode = SPI_MODE_0;
spi->bitsPerWord = 8;
......
......@@ -203,7 +203,7 @@ int main(void)
{
t_spi *a2d = spi_new("/dev/spidev0.0", SPI_MODE_0, 1000000, 8);
int a2dVal = 0;
int a2dChannel = 0;
int a2dChannel = 1;
unsigned char data[3];
while(1)
......
/* gpio - Pi gpio pins via /sys/etc */
/* see http://elinux.org/RPi_Low-level_peripherals */
/* Copyright Miller Puckette - BSD license */
#include "m_pd.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
static t_class *gpio_class;
#define FILE_PREFIX "/sys/class/gpio/"
#define FILE_EXPORT FILE_PREFIX "export"
typedef struct _gpio
{
t_object x_obj;
t_outlet *x_out1;
int x_pin;
int x_fdvalue;
} t_gpio;
static void gpio_enable(t_gpio *x, t_float f)
{
char buf[1024];
if (f != 0)
sprintf(buf, "echo %d > /sys/class/gpio/export\n", x->x_pin);
else sprintf(buf, "echo %d > /sys/class/gpio/unexport\n", x->x_pin);
system(buf);
}
static void gpio_output(t_gpio *x, t_float f)
{
char buf[1024];
if (f != 0)
sprintf(buf, "echo out > /sys/class/gpio/gpio%d/direction\n",
x->x_pin);
else sprintf(buf, "echo in > /sys/class/gpio/gpio%d/direction\n",
x->x_pin);
system(buf);
}
static void gpio_open(t_gpio *x, t_float f)
{
char buf[1024];
sprintf(buf, "/sys/class/gpio/gpio%d/value", x->x_pin);
if (f != 0)
{
if (x->x_fdvalue >= 0)
post("gpio: already open");
else
{
x->x_fdvalue = open(buf, O_RDWR);
if (x->x_fdvalue < 0)
post("%s: %s", buf, strerror(errno));
}
}
else
{
if (x->x_fdvalue < 0)
post("gpio: already closed");
else
{
close(x->x_fdvalue);
x->x_fdvalue = -1;
}
}
}
static void gpio_float(t_gpio *x, t_float f)
{
char buf[1024];
if (x->x_fdvalue < 0)
pd_error(x, "gpio: not open");
else
{
sprintf(buf, "%d\n", (f != 0));
if (write(x->x_fdvalue, buf, strlen(buf)) < (int)strlen(buf))
pd_error(x, "gpio_float: %s", strerror(errno));
}
}
static void gpio_bang(t_gpio *x)
{
char buf[1024];
if (x->x_fdvalue < 0)
pd_error(x, "gpio: not open");
else
{
int rval = lseek(x->x_fdvalue, 0, 0);
if (rval < 0)
{
pd_error(x, "gpio_bang (seek): %s", strerror(errno));
return;
}
rval = read(x->x_fdvalue, buf, sizeof(buf)-1);
if (rval < 0)
{
pd_error(x, "gpio_bang (read): %s", strerror(errno));
return;
}
buf[rval] = 0;
if (sscanf(buf, "%d", &rval) < 1)
{
pd_error(x, "gpio_bang: couldn't parse string: %s", buf);
return;
}
outlet_float(x->x_out1, rval);
}
}
static void *gpio_new(t_floatarg f)
{
t_gpio *x = (t_gpio *)pd_new(gpio_class);
x->x_out1 = outlet_new(&x->x_obj, gensym("float"));
x->x_fdvalue = -1;
x->x_pin = f;
return (x);
}
void gpio_setup(void)
{
gpio_class = class_new(gensym("gpio"), (t_newmethod)gpio_new,
0, sizeof(t_gpio), 0, A_DEFFLOAT, 0);
class_addmethod(gpio_class, (t_method)gpio_enable, gensym("enable"),
A_FLOAT, 0);
class_addmethod(gpio_class, (t_method)gpio_output, gensym("output"),
A_FLOAT, 0);
class_addmethod(gpio_class, (t_method)gpio_open, gensym("open"),
A_FLOAT, 0);
class_addfloat(gpio_class, gpio_float);
class_addbang(gpio_class, gpio_bang);
}
/* gpio - Pi gpio pins via /sys/etc */
/* see http://elinux.org/RPi_Low-level_peripherals */
/* Copyright Miller Puckette - BSD license */
#include "m_pd.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
static t_class *gpio_class;
#define FILE_PREFIX "/sys/class/gpio/"
#define FILE_EXPORT FILE_PREFIX "export"
typedef struct _gpio
{
t_object x_obj;
t_outlet *x_out1;
int x_pin;
int x_fdvalue;
} t_gpio;
static void gpio_enable(t_gpio *x, t_float f)
{
char buf[1024];
if (f != 0)
sprintf(buf, "echo %d > /sys/class/gpio/export\n", x->x_pin);
else sprintf(buf, "echo %d > /sys/class/gpio/unexport\n", x->x_pin);
system(buf);
}
static void gpio_output(t_gpio *x, t_float f)
{
char buf[1024];
if (f != 0)
sprintf(buf, "echo out > /sys/class/gpio/gpio%d/direction\n",
x->x_pin);
else sprintf(buf, "echo in > /sys/class/gpio/gpio%d/direction\n",
x->x_pin);
system(buf);
}
static void gpio_open(t_gpio *x, t_float f)
{
char buf[1024];
sprintf(buf, "/sys/class/gpio/gpio%d/value", x->x_pin);
if (f != 0)
{
if (x->x_fdvalue >= 0)
post("gpio: already open");
else
{
x->x_fdvalue = open(buf, O_RDWR);
if (x->x_fdvalue < 0)
post("%s: %s", buf, strerror(errno));
}
}
else
{
if (x->x_fdvalue < 0)
post("gpio: already closed");
else
{
close(x->x_fdvalue);
x->x_fdvalue = -1;
}
}
}
static void gpio_float(t_gpio *x, t_float f)
{
char buf[1024];
if (x->x_fdvalue < 0)
pd_error(x, "gpio: not open");
else
{
sprintf(buf, "%d\n", (f != 0));
if (write(x->x_fdvalue, buf, strlen(buf)) < (int)strlen(buf))
pd_error(x, "gpio_float: %s", strerror(errno));
}
}
static void gpio_bang(t_gpio *x)
{
char buf[1024];
if (x->x_fdvalue < 0)
pd_error(x, "gpio: not open");
else
{
int rval = lseek(x->x_fdvalue, 0, 0);
if (rval < 0)
{
pd_error(x, "gpio_bang (seek): %s", strerror(errno));
return;
}
rval = read(x->x_fdvalue, buf, sizeof(buf)-1);
if (rval < 0)
{
pd_error(x, "gpio_bang (read): %s", strerror(errno));
return;
}
buf[rval] = 0;
if (sscanf(buf, "%d", &rval) < 1)
{
pd_error(x, "gpio_bang: couldn't parse string: %s", buf);
return;
}
outlet_float(x->x_out1, rval);
}
}
static void *gpio_new(t_floatarg f)
{
t_gpio *x = (t_gpio *)pd_new(gpio_class);
x->x_out1 = outlet_new(&x->x_obj, gensym("float"));
x->x_fdvalue = -1;
x->x_pin = f;
return (x);
}
void gpio_setup(void)
{
gpio_class = class_new(gensym("gpio"), (t_newmethod)gpio_new,
0, sizeof(t_gpio), 0, A_DEFFLOAT, 0);
class_addmethod(gpio_class, (t_method)gpio_enable, gensym("enable"),
A_FLOAT, 0);
class_addmethod(gpio_class, (t_method)gpio_output, gensym("output"),
A_FLOAT, 0);
class_addmethod(gpio_class, (t_method)gpio_open, gensym("open"),
A_FLOAT, 0);
class_addfloat(gpio_class, gpio_float);
class_addbang(gpio_class, gpio_bang);
}
File deleted
NAME=gpio
CSYM=$(NAME)
include ../makefile.include
#N canvas 187 97 450 300 10;
#X obj 82 58 gpio 4;
#X msg 73 21 open 1;
#X msg 134 22 open 0;
#X obj 215 24 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
#X obj 255 24 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
-1;
#X floatatom 94 96 5 0 0 0 - - -;
#X obj 95 122 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
-1;
#X obj 231 62 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
#X obj 231 93 metro 1;
#X obj 175 149 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
#X obj 175 180 metro 1;
#X connect 1 0 0 0;
#X connect 2 0 0 0;
#X connect 3 0 0 0;
#X connect 4 0 0 0;
#X connect 5 0 6 0;
#X connect 7 0 8 0;
#X connect 8 0 0 0;
#X connect 9 0 10 0;
cd disis_gpio
./build.sh
chmod 4755 chown_gpio
cd ../
cd disis_spi
make
cd ../
exit 0
current: l_i386 l_ia64
# which OS to compile for
UNAME := $(shell uname -s)
ifeq ($(UNAME),Linux)
......@@ -36,6 +34,11 @@ endif
ifeq ($(UNAME_MACHINE),ppc)
ARCH = powerpc
endif
ifeq ($(UNAME_MACHINE),armv6l)
ARCH = l_arm
endif
current: $(ARCH)
# ----------------------- Windows -----------------------
......@@ -62,6 +65,7 @@ PDNTLIB = $(PDNTLDIR)\libc.lib \
l_i386: $(NAME).l_i386
l_ia64: $(NAME).l_ia64
l_arm: $(NAME).l_arm
.SUFFIXES: .l_i386 .l_ia64 .l_arm
......@@ -75,21 +79,21 @@ LINUXINCLUDE = $(UNIXINCLUDE)
.c.l_i386:
$(CC) $(LINUXCFLAGS) $(LINUXINCLUDE) -m32 -o $*.o -c $*.c
$(CC) -m32 -shared -o $*.l_i386 $*.o -lc -lm
$(CC) -m32 -shared -o $*.l_i386 $*.o -lc -lm $(APPENDFLAGS)
strip --strip-unneeded $*.l_i386
rm -f $*.o
mv $(NAME).l_i386 $(NAME).pd_linux
.c.l_ia64:
cc $(LINUXCFLAGS) $(LINUXINCLUDE) -fPIC -o $*.o -c $*.c
ld -shared -o $*.l_ia64 $*.o -lc -lm
ld -shared -o $*.l_ia64 $*.o -lc -lm $(APPENDFLAGS)
strip --strip-unneeded $*.l_ia64
rm $*.o
mv $(NAME).l_ia64 $(NAME).pd_linux
.c.l_arm:
cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c
ld -shared -o $*.l_arm $*.o -lc -lm
ld -shared -o $*.l_arm $*.o -lc -lm $(APPENDFLAGS)
strip --strip-unneeded $*.l_arm
rm $*.o
mv $(NAME).l_arm $(NAME).pd_linux
......@@ -100,7 +104,7 @@ ifeq ($(ARCH),l_ia64)
make l_ia64
endif
ifeq ($(ARCH),l_arm)
make l_arm
make l_arm
endif
ifeq ($(ARCH),l_i386)
make l_i386
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment