This commit is contained in:
joan 2014-01-21 19:04:59 +00:00
parent 7f0cf5a014
commit 23e3b179ab
13 changed files with 1676 additions and 443 deletions

View File

@ -5,11 +5,11 @@ SIZE = size
CFLAGS = -O3 -Wall
ALL = libpigpiod_if.a pigs
ALL = libpigpiod_if.a pigs pigpio.py setup.py
all: $(ALL)
pigs: command.o
pigs: command.o pigs.o
$(CC) -o pigs pigs.c command.c
clean:
@ -41,7 +41,7 @@ $(LIB): $(OBJ)
# generated using gcc -MM *.c
command.o: command.c pigpio.h command.h
pigpiod.o: pigpiod.c pigpio.h command.h
pigpiod_if.o: pigpiod_if.c pigpio.h pigpiod_if.h
pigpiod.o: pigpiod.c pigpio.h
pigpiod_if.o: pigpiod_if.c pigpio.h pigpiod_if.h command.h
pigs.o: pigs.c pigpio.h command.h

View File

@ -72,7 +72,7 @@ checklib.o: checklib.c pigpio.h
command.o: command.c pigpio.h command.h
pig2vcd.o: pig2vcd.c pigpio.h
pigpio.o: pigpio.c pigpio.h command.h
pigpiod.o: pigpiod.c pigpio.h command.h
pigpiod.o: pigpiod.c pigpio.h
pigpiod_if.o: pigpiod_if.c pigpio.h command.h pigpiod_if.h
pigs.o: pigs.c pigpio.h command.h

3
README
View File

@ -31,8 +31,7 @@ EXAMPLE CODE
checklib.c, pig2vcd.c, and pigpiod.c
show examples of interfacing with the pigpio library.
pigs.c, pigpio.py, and test_pigpiod_if.c
show examples of interfacing with the pigpiod daemon.
pigs.c and pigpio.py show examples of interfacing with the pigpiod daemon.
DAEMON

273
command.c
View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 10+
This version is for pigpio version 11+
*/
#include <stdio.h>
@ -38,79 +38,144 @@ This version is for pigpio version 10+
#include "pigpio.h"
#include "command.h"
/* retv
pigs pipe
0 "" <0 ERR %d
1 "" <0 ERR %d
2 %d <0 ERR %d
3 %08X %08X
4 %u %u
5 HELP HELP
*/
/* vfyt
1 cmd
2 cmd %d
3 cmd %d %d
4 cmd %d %x
6 HELP
7 cmd %x
8 MODES %d %c
9 PUD %d %c
10 PROG %s
*/
cmdInfo_t cmdInfo[]=
{
{PI_CMD_BR1, "BR1", 1, 3},
{PI_CMD_BR2, "BR2", 1, 3},
{PI_CMD_BC1, "BC1", 7, 1},
{PI_CMD_BC2, "BC2", 7, 1},
{PI_CMD_BS1, "BS1", 7, 1},
{PI_CMD_BS2, "BS2", 7, 1},
{PI_CMD_HWVER, "HWVER", 1, 4},
{PI_CMD_MODES, "MODES", 8, 0},
{PI_CMD_MODES, "M", 8, 0},
{PI_CMD_MODEG, "MODEG", 2, 2},
{PI_CMD_MODEG, "MG" , 2, 2},
{PI_CMD_NO, "NO", 1, 2},
{PI_CMD_NB, "NB", 4, 0},
{PI_CMD_NP, "NP", 2, 0},
{PI_CMD_NC, "NC", 2, 0},
{PI_CMD_PWM, "PWM", 3, 0},
{PI_CMD_PWM, "P", 3, 0},
{PI_CMD_PFS, "PFS", 3, 2},
{PI_CMD_PFG, "PFG", 2, 2},
{PI_CMD_PRS, "PRS", 3, 2},
{PI_CMD_PRG, "PRG", 2, 2},
{PI_CMD_PRRG, "PRRG", 2, 2},
{PI_CMD_PUD, "PUD", 9, 0},
{PI_CMD_READ, "READ", 2, 2},
{PI_CMD_READ, "R", 2, 2},
{PI_CMD_SERVO, "SERVO", 3, 0},
{PI_CMD_SERVO, "S", 3, 0},
{PI_CMD_WRITE, "WRITE", 3, 0},
{PI_CMD_WRITE, "W", 3, 0},
{PI_CMD_WDOG, "WDOG", 3, 0},
{PI_CMD_TICK, "TICK", 1, 4},
{PI_CMD_TICK, "T", 1, 4},
{PI_CMD_HELP, "HELP", 6, 5},
{PI_CMD_HELP, "H", 6, 5},
{PI_CMD_PIGPV, "PIGPV", 1, 4},
/* num str vfyt retv ext */
{PI_CMD_BC1, "BC1", 7, 1, 0},
{PI_CMD_BC2, "BC2", 7, 1, 0},
{PI_CMD_BR1, "BR1", 1, 3, 0},
{PI_CMD_BR2, "BR2", 1, 3, 0},
{PI_CMD_BS1, "BS1", 7, 1, 0},
{PI_CMD_BS2, "BS2", 7, 1, 0},
{PI_CMD_HELP, "H", 6, 5, 0},
{PI_CMD_HELP, "HELP", 6, 5, 0},
{PI_CMD_HWVER, "HWVER", 1, 4, 0},
{PI_CMD_MODEG, "MG" , 2, 2, 0},
{PI_CMD_MODEG, "MODEG", 2, 2, 0},
{PI_CMD_MODES, "M", 8, 0, 0},
{PI_CMD_MODES, "MODES", 8, 0, 0},
{PI_CMD_NB, "NB", 4, 0, 0},
{PI_CMD_NC, "NC", 2, 0, 0},
{PI_CMD_NO, "NO", 1, 2, 0},
{PI_CMD_NP, "NP", 2, 0, 0},
{PI_CMD_PFG, "PFG", 2, 2, 0},
{PI_CMD_PFS, "PFS", 3, 2, 0},
{PI_CMD_PIGPV, "PIGPV", 1, 4, 0},
{PI_CMD_PRG, "PRG", 2, 2, 0},
{PI_CMD_PROC, "PROC", 10, 2, 1},
{PI_CMD_PROCD, "PROCD", 2, 2, 0},
{PI_CMD_PROCR, "PROCR", 2, 2, 0},
{PI_CMD_PROCS, "PROCS", 2, 2, 0},
{PI_CMD_PRRG, "PRRG", 2, 2, 0},
{PI_CMD_PRS, "PRS", 3, 2, 0},
{PI_CMD_PUD, "PUD", 9, 0, 0},
{PI_CMD_PWM, "P", 3, 0, 0},
{PI_CMD_PWM, "PWM", 3, 0, 0},
{PI_CMD_READ, "R", 2, 2, 0},
{PI_CMD_READ, "READ", 2, 2, 0},
{PI_CMD_SERVO, "S", 3, 0, 0},
{PI_CMD_SERVO, "SERVO", 3, 0, 0},
{PI_CMD_WDOG, "WDOG", 3, 0, 0},
{PI_CMD_WRITE, "W", 3, 0, 0},
{PI_CMD_WRITE, "WRITE", 3, 0, 0},
{PI_CMD_TICK, "T", 1, 4, 0},
{PI_CMD_TICK, "TICK", 1, 4, 0},
{PI_CMD_TRIG, "TRIG", 5, 0, 1},
{PI_CMD_WVAS, "WVAS", 11, 2, 3},
{PI_CMD_WVBSY, "WVBSY", 1, 2, 0},
{PI_CMD_WVCLR, "WVCLR", 1, 2, 0},
{PI_CMD_WVGO, "WVGO" , 1, 2, 0},
{PI_CMD_WVGOR, "WVGOR", 1, 2, 0},
{PI_CMD_WVHLT, "WVHLT", 1, 2, 0},
{PI_CMD_WVSC, "WVSC", 2, 2, 0},
{PI_CMD_WVSM, "WVSM", 2, 2, 0},
{PI_CMD_WVSP, "WVSP", 2, 2, 0},
};
char * cmdUsage = "\
BR1 read gpios bank 1\n\
BR2 read gpios bank 2\n\
BC1 x clear gpios in bank 1\n\
BC2 x clear gpios in bank 2\n\
BR1 read gpios bank 1\n\
BR2 read gpios bank 2\n\
BS1 x set gpios in bank 1\n\
BS2 x set gpios in bank 2\n\
H displays command help\n\
HELP displays command help\n\
HWVER return hardware version\n\
MODES/M g m set gpio mode\n\
MODEG/MG g get gpio mode\n\
NO request notification handle\n\
M g m set gpio mode\n\
MG g get gpio mode\n\
MODEG g get gpio mode\n\
MODES g m set gpio mode\n\
NB h x start notification\n\
NP h pause notification\n\
NC h close notification\n\
PWM/P u d set PWM value for gpio\n\
PFS u d set PWM frequency for gpio\n\
NO request notification handle\n\
NP h pause notification\n\
P u d set PWM value for gpio\n\
PFG u get PWM frequency for gpio\n\
PFS u d set PWM frequency for gpio\n\
PIGPV return pigpio version\n\
PRS u d set PWM range for gpio\n\
PRG u get PWM range for gpio\n\
PROC t validate and store script\n\
PROCD s delete script\n\
PROCR s run script\n\
PROCS s stop script\n\
PRRG u get PWM real range for gpio\n\
PRS u d set PWM range for gpio\n\
PUD g p set gpio pull up/down\n\
READ/R g read gpio\n\
SERVO/S u d set servo value for gpio\n\
WRITE/W g d write value to gpio\n\
PWM u d set PWM value for gpio\n\
R g read gpio\n\
READ g read gpio\n\
S u d set servo value for gpio\n\
SERVO u d set servo value for gpio\n\
T return current tick\n\
TICK return current tick\n\
TRIG u pl l trigger level l for pl micros on gpio\n\
W g l write level to gpio\n\
WDOG u d set watchdog on gpio\n\
TICK/T return current tick\n\
HELP/H displays command help\n\
WRITE g l write level to gpio\n\
WVAS u b t wave add serial data\n\
WVBSY check if wave busy\n\
WVCLR wave clear\n\
WVGO wave transmit\n\
WVGOR wave transmit repeat\n\
WVHLT wave stop\n\
WVSC ws wave get cbs stats\n\
WVSM ws wave get micros stats\n\
WVSP ws wave get pulses stats\n\
\n\
b = baud rate\n\
d = decimal value\n\
g = gpio (0-53)\n\
h = handle (0-31)\n\
l = level (0-1)\n\
m = mode (RW540123)\n\
p = pud (ODU)\n\
pl = pulse length (0-100)\n\
s = script id\n\
t = text\n\
u = user gpio (0-31)\n\
x = hex value\n\
";
@ -130,7 +195,7 @@ static errInfo_t errInfo[]=
{PI_BAD_LEVEL , "level not 0-1"},
{PI_BAD_PUD , "pud not 0-2"},
{PI_BAD_PULSEWIDTH , "pulsewidth not 0 or 500-2500"},
{PI_BAD_DUTYCYCLE , "dutycycle not 0-255"},
{PI_BAD_DUTYCYCLE , "dutycycle outside set range"},
{PI_BAD_TIMER , "timer not 0-9"},
{PI_BAD_MS , "ms not 10-60000"},
{PI_BAD_TIMETYPE , "timetype not 0-1"},
@ -165,6 +230,13 @@ static errInfo_t errInfo[]=
{PI_BAD_SERIAL_BUF , "bad (null) serial buf parameter"},
{PI_NOT_PERMITTED , "no permission to update gpio"},
{PI_SOME_PERMITTED , "no permission to update one or more gpios"},
{PI_BAD_WVSC_COMMND , "bad WVSC subcommand"},
{PI_BAD_WVSM_COMMND , "bad WVSM subcommand"},
{PI_BAD_WVSP_COMMND , "bad WVSP subcommand"},
{PI_BAD_PULSELEN , "trigger pulse > 100 microseconds"},
{PI_BAD_SCRIPT , "invalid script"},
{PI_BAD_SCRIPT_ID , "unknown script id"},
{PI_BAD_SER_OFFSET , "add serial data offset > 30 minute"},
};
static char * fmtMdeStr="RW540123";
@ -181,11 +253,11 @@ static int cmdMatch(char * str)
return -1;
}
int cmdParse(char * buf, cmdCmd_t * cmd)
int cmdParse(char *buf, cmdCmd_t *cmd, int argc, char *argv[], gpioExtent_t *ext)
{
char str[8];
int f, valid, idx, val;
char * ptr;
char *ptr;
char c, t;
sscanf(buf, " %7s", str);
@ -204,36 +276,57 @@ int cmdParse(char * buf, cmdCmd_t * cmd)
switch (cmdInfo[idx].vt)
{
case 1: /* BR1 BR2 HWVER PIGPV NO TICK */
case 1: /* BR1 BR2 HWVER NO PIGPV TICK WVBSY WVCLR WVGO WVGOR
WVHLT
*/
f = sscanf(buf, " %7s %c", str, &t);
if (f == 1) valid = 1;
break;
case 2: /* MODEG READ NC NP PFG PRG PRRG */
case 2: /* MODEG NC NP PFG PRG PROCD PROCR PROCS PRRG READ
WVSC WVSM WVSP
*/
f = sscanf(buf, " %7s %d %c", str, &cmd->p1, &t);
if (f == 2) valid = 1;
break;
case 3: /* WRITE PWM PRS PFS SERVO WDOG */
case 3: /* PFS PRS PWM SERVO WDOG WRITE
*/
f = sscanf(buf, " %7s %d %d %c", str, &cmd->p1, &cmd->p2, &t);
if (f == 3) valid = 1;
break;
case 4: /* NB */
case 4: /* NB
*/
f = sscanf(buf, " %7s %d %x %c", str, &cmd->p1, &cmd->p2, &t);
if (f == 3) valid = 1;
break;
case 6: /* HELP */
case 5: /* TRIG
*/
f = sscanf(buf, " %7s %d %d %d %c",
str, &cmd->p1, &cmd->p2, &ext[0].data, &t);
if (f == 4)
{
ext[0].n = sizeof(unsigned);
ext[0].ptr = &ext[0].data;
valid = 1;
}
break;
case 6: /* HELP
*/
valid = 1;
break;
case 7: /* BC1 BC2 BS1 BS2 */
case 7: /* BC1 BC2 BS1 BS2
*/
f = sscanf(buf, " %7s %x %c", str, &cmd->p1, &t);
if (f == 2) valid = 1;
break;
case 8: /* MODES */
case 8: /* MODES
*/
f = sscanf(buf, " %7s %d %c %c", str, &cmd->p1, &c, &t);
if (f == 3)
{
@ -248,7 +341,8 @@ int cmdParse(char * buf, cmdCmd_t * cmd)
}
break;
case 9: /* PUD */
case 9: /* PUD
*/
f = sscanf(buf, " %7s %d %c %c", str, &cmd->p1, &c, &t);
if (f == 3)
{
@ -262,28 +356,43 @@ int cmdParse(char * buf, cmdCmd_t * cmd)
}
}
break;
case 10: /* PROC
*/
if (argc == 3)
{
cmd->p1 = strlen(argv[2]);
ext[0].n = cmd->p1;
ext[0].ptr = argv[2];
valid = 1;
}
break;
case 11: /* WVAS
*/
if (argc == 6)
{
f = sscanf(buf, " %7s %d %d %d ",
str, &cmd->p1, &ext[0].data, &ext[1].data);
if (f == 4)
{
ext[0].n = sizeof(unsigned);
ext[0].ptr = &ext[0].data;
ext[1].n = sizeof(unsigned);
ext[1].ptr = &ext[1].data;
cmd->p2 = strlen(argv[5]);
ext[2].n = cmd->p2;
ext[2].ptr = argv[5];
valid = 1;
}
}
break;
}
if (valid) return idx;
else return -1;
}
void cmdFatal(char *fmt, ...)
{
char buf[128];
va_list ap;
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
fprintf(stderr, "%s\n", buf);
fflush(stderr);
exit(EXIT_FAILURE);
}
char * cmdErrStr(int error)
{
int i;

View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 7+
This version is for pigpio version 11+
*/
#ifndef COMMAND_H
@ -43,16 +43,17 @@ typedef struct
char * name; /* command name */
int vt; /* command verification type */
int rv; /* command return value type */
int ext; /* command has extensions */
} cmdInfo_t;
extern cmdInfo_t cmdInfo[];
extern char * cmdUsage;
int cmdParse(char * buf, cmdCmd_t * cmd);
int cmdParse
(char *buf, cmdCmd_t *cmd, int argc, char *argv[], gpioExtent_t * ext);
char * cmdErrStr(int error);
void cmdFatal(char *fmt, ...);
#endif

602
pigpio.c
View File

@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
*/
/* pigpio version 10 */
/* pigpio version 11 */
#include <stdio.h>
#include <string.h>
@ -752,7 +752,7 @@ static int wfcur=0;
static wfStats_t wfStats=
{
0, 0, -1,
0, 0, PI_WAVE_MAX_MICROS,
0, 0, PI_WAVE_MAX_PULSES,
0, 0, (PAGES_PER_BLOCK * CBS_PER_OPAGE)
};
@ -765,7 +765,7 @@ static volatile uint32_t notifyBits = 0;
static volatile int DMAstarted = 0;
static int libInitialised = 0;
static int libInitialised = 0;
static int pthAlertRunning = 0;
static int pthFifoRunning = 0;
@ -881,7 +881,7 @@ static uint32_t myGpioDelay(uint32_t micros)
start = systReg[SYST_CLO];
if (micros < 100) while ((systReg[SYST_CLO] - start) <= micros) ;
if (micros < 101) while ((systReg[SYST_CLO] - start) <= micros) ;
else myGpioSleep(micros/MILLION, micros%MILLION);
@ -977,104 +977,19 @@ static uint32_t myGetTick(int pos)
/* ----------------------------------------------------------------------- */
static void myDoCommand(cmdCmd_t * cmd)
static void myDoCommand(cmdCmd_t *cmd, gpioExtent_t *ext)
{
int p1, p2, res;
uint32_t mask;
int p1, p2, res, i;
uint32_t mask, tmp;
gpioPulse_t *pulse;
int masked;
p1 = cmd->p1;
p2 = cmd->p2;
res = 0;
res = cmd->res;
switch (cmd->cmd)
{
case PI_CMD_MODES:
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetMode(p1, p2);
else
{
PERM_ERROR("gpioSetMode: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_MODEG:
res = gpioGetMode(p1);
break;
case PI_CMD_PUD:
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetPullUpDown(p1, p2);
else
{
PERM_ERROR(
"gpioSetPullUpDown: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_READ:
res = gpioRead(p1);
break;
case PI_CMD_WRITE:
if (gpioMask & (uint64_t)(1<<p1)) res = gpioWrite(p1, p2);
else
{
PERM_ERROR("gpioWrite: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_PWM:
if (gpioMask & (uint64_t)(1<<p1)) res = gpioPWM(p1, p2);
else
{
PERM_ERROR("gpioPWM: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_PRS:
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetPWMrange(p1, p2);
else
{
PERM_ERROR(
"gpioSetPWMrange: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_PFS:
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetPWMfrequency(p1, p2);
else
{
PERM_ERROR(
"gpioSetPWMfrequency: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_SERVO:
if (gpioMask & (uint64_t)(1<<p1)) res = gpioServo(p1, p2);
else
{
PERM_ERROR("gpioServo: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_WDOG:
res = gpioSetWatchdog(p1, p2);
break;
case PI_CMD_BR1:
res = gpioRead_Bits_0_31();
break;
case PI_CMD_BR2:
res = gpioRead_Bits_32_53();
break;
case PI_CMD_BC1:
mask = gpioMask;
@ -1103,6 +1018,10 @@ static void myDoCommand(cmdCmd_t * cmd)
}
break;
case PI_CMD_BR1: res = gpioRead_Bits_0_31(); break;
case PI_CMD_BR2: res = gpioRead_Bits_32_53(); break;
case PI_CMD_BS1:
mask = gpioMask;
@ -1131,52 +1050,209 @@ static void myDoCommand(cmdCmd_t * cmd)
}
break;
case PI_CMD_TICK:
res = gpioTick();
case PI_CMD_HELP: break;
case PI_CMD_HWVER: res = gpioHardwareRevision(); break;
case PI_CMD_MODEG: res = gpioGetMode(p1); break;
case PI_CMD_MODES:
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetMode(p1, p2);
else
{
PERM_ERROR("gpioSetMode: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_HWVER:
res = gpioHardwareRevision();
case PI_CMD_NB: res = gpioNotifyBegin(p1, p2); break;
case PI_CMD_NC: res = gpioNotifyClose(p1); break;
case PI_CMD_NO: res = gpioNotifyOpen(); break;
case PI_CMD_NP: res = gpioNotifyPause(p1); break;
case PI_CMD_PFG: res = gpioGetPWMfrequency(p1); break;
case PI_CMD_PFS:
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetPWMfrequency(p1, p2);
else
{
PERM_ERROR(
"gpioSetPWMfrequency: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_PRG:
res = gpioGetPWMrange(p1);
case PI_CMD_PIGPV: res = gpioVersion(); break;
case PI_CMD_PRG: res = gpioGetPWMrange(p1); break;
case PI_CMD_PROC:
res = gpioStoreScript(ext[0].ptr);
break;
case PI_CMD_PFG:
res = gpioGetPWMfrequency(p1);
case PI_CMD_PROCD: res = gpioDeleteScript(p1); break;
case PI_CMD_PROCR: res = gpioRunScript(p1); break;
case PI_CMD_PROCS: res = gpioStopScript(p1); break;
case PI_CMD_PRRG: res = gpioGetPWMrealRange(p1); break;
case PI_CMD_PRS:
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetPWMrange(p1, p2);
else
{
PERM_ERROR(
"gpioSetPWMrange: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_PRRG:
res = gpioGetPWMrealRange(p1);
case PI_CMD_PUD:
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetPullUpDown(p1, p2);
else
{
PERM_ERROR(
"gpioSetPullUpDown: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_NO:
res = gpioNotifyOpen();
case PI_CMD_PWM:
if (gpioMask & (uint64_t)(1<<p1)) res = gpioPWM(p1, p2);
else
{
PERM_ERROR("gpioPWM: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_NB:
res = gpioNotifyBegin(p1, p2);
case PI_CMD_READ: res = gpioRead(p1); break;
case PI_CMD_WDOG: res = gpioSetWatchdog(p1, p2); break;
case PI_CMD_WRITE:
if (gpioMask & (uint64_t)(1<<p1)) res = gpioWrite(p1, p2);
else
{
PERM_ERROR("gpioWrite: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_NP:
res = gpioNotifyPause(p1);
case PI_CMD_SERVO:
if (gpioMask & (uint64_t)(1<<p1)) res = gpioServo(p1, p2);
else
{
PERM_ERROR("gpioServo: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_NC:
res = gpioNotifyClose(p1);
case PI_CMD_TICK: res = gpioTick(); break;
case PI_CMD_TRIG:
if (gpioMask & (uint64_t)(1<<p1))
res = gpioTrigger(p1, p2, *(int *) (ext[0].ptr));
else
{
PERM_ERROR("gpioTrigger: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_HELP:
case PI_CMD_WVAG:
/* need to mask off any non permitted gpios */
mask = gpioMask;
pulse = ext[0].ptr;
masked = 0;
for (i=0; i<p1; i++)
{
tmp = pulse[i].gpioOn & mask;
if (tmp != pulse[i].gpioOn)
{
pulse[i].gpioOn = tmp;
masked = 1;
}
tmp = pulse[i].gpioOff & mask;
if (tmp != pulse[i].gpioOff)
{
pulse[i].gpioOff = tmp;
masked = 1;
}
}
res = gpioWaveAddGeneric(p1, pulse);
/* report permission error unless another error occurred */
if (masked && (res >= 0)) res = PI_SOME_PERMITTED;
break;
case PI_CMD_PIGPV:
res = gpioVersion();
case PI_CMD_WVAS:
if (gpioMask & (uint64_t)(1<<p1))
res = gpioWaveAddSerial
(p1,
*(int *)(ext[0].ptr),
*(int *)(ext[1].ptr),
p2,
ext[2].ptr);
else
{
PERM_ERROR
("gpioWaveAddSerial: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
}
case PI_CMD_WVBSY: res = gpioWaveTxBusy(); break;
cmd->res = res;
case PI_CMD_WVCLR: res = gpioWaveClear(); break;
case PI_CMD_WVGO: res = gpioWaveTxStart(PI_WAVE_MODE_ONE_SHOT); break;
case PI_CMD_WVGOR: res = gpioWaveTxStart(PI_WAVE_MODE_REPEAT); break;
case PI_CMD_WVHLT: res = gpioWaveTxStop(); break;
case PI_CMD_WVSC:
switch(p1)
{
case 0: res = gpioWaveGetCbs(); break;
case 1: res = gpioWaveGetHighCbs(); break;
case 2: res = gpioWaveGetMaxCbs(); break;
default: res = -9999;
}
break;
case PI_CMD_WVSM:
switch(p1)
{
case 0: res = gpioWaveGetMicros(); break;
case 1: res = gpioWaveGetHighMicros(); break;
case 2: res = gpioWaveGetMaxMicros(); break;
default: res = -9999;
}
break;
case PI_CMD_WVSP:
switch(p1)
{
case 0: res = gpioWaveGetPulses(); break;
case 1: res = gpioWaveGetHighPulses(); break;
case 2: res = gpioWaveGetMaxPulses(); break;
default: res = -9999;
}
break;
}
cmd->res = res;
}
/* ----------------------------------------------------------------------- */
@ -2545,9 +2621,10 @@ static void * pthTimerTick(void *x)
static void * pthFifoThread(void *x)
{
char inBuf[128];
char inBuf[256];
int idx, flags;
cmdCmd_t cmd;
gpioExtent_t ext[3];
myCreatePipe(PI_INPFIFO, 0662);
@ -2569,9 +2646,9 @@ static void * pthFifoThread(void *x)
if (fgets(inBuf, sizeof(inBuf), inpFifo) == NULL)
SOFT_ERROR((void*)PI_INIT_FAILED, "fifo fgets failed (%m)");
if ((idx=cmdParse(inBuf, &cmd)) >= 0)
if ((idx=cmdParse(inBuf, &cmd, 0, NULL, ext)) >= 0)
{
myDoCommand(&cmd);
myDoCommand(&cmd, NULL);
switch (cmdInfo[idx].rv)
{
@ -2611,24 +2688,150 @@ static void * pthFifoThread(void *x)
/* ----------------------------------------------------------------------- */
static void * pthSocketThreadHandler(void *fdC)
static void *pthSocketThreadHandler(void *fdC)
{
int sock = *(int*)fdC;
cmdCmd_t cmd;
unsigned bytes;
char *memPtr;
gpioExtent_t ext[3];
unsigned tmp;
free(fdC);
while(1)
{
if (recv(sock, &cmd, sizeof(cmdCmd_t), 0) == sizeof(cmdCmd_t))
if (recv(sock, &cmd, sizeof(cmdCmd_t), MSG_WAITALL) == sizeof(cmdCmd_t))
{
if (cmd.cmd != PI_CMD_NOIB)
if (cmd.cmd == PI_CMD_NOIB)
{
myDoCommand(&cmd);
cmd.res = gpioNotifyOpenInBand(sock);
}
else if (cmd.cmd == PI_CMD_WVAG)
{
/*
p1=numPulses
p2=0
## extension ##
gpioPulse_t[] pulses
*/
bytes = cmd.p1 * sizeof(gpioPulse_t);
memPtr = malloc(bytes);
if (memPtr)
{
if (recv(sock, memPtr, bytes, MSG_WAITALL) == bytes)
{
ext[0].n = bytes;
ext[0].ptr = memPtr;
myDoCommand(&cmd, ext);
free(memPtr);
}
else
{
free(memPtr);
break;
}
}
else break;
}
else if (cmd.cmd == PI_CMD_WVAS)
{
/*
p1=user_gpio
p2=numChar
## extension ##
unsigned baud
unsigned offset
char[] str
*/
bytes = sizeof(unsigned) + sizeof(unsigned) + cmd.p2;
memPtr = malloc(bytes+1); /* add 1 for a nul terminator */
if (memPtr)
{
if (recv(sock, memPtr, bytes, MSG_WAITALL) == bytes)
{
ext[0].n = sizeof(unsigned);
ext[0].ptr = memPtr;
ext[1].n = sizeof(unsigned);
ext[1].ptr = memPtr + sizeof(unsigned);
ext[2].n = cmd.p2;
ext[2].ptr = memPtr + sizeof(unsigned) + sizeof(unsigned);
memPtr[bytes] = 0; /* may be duplicate terminator */
myDoCommand(&cmd, ext);
free(memPtr);
}
else
{
free(memPtr);
break;
}
}
else break;
}
else if (cmd.cmd == PI_CMD_PROC)
{
/*
p1=script length
p2=0
## extension ##
char[] script
*/
bytes = cmd.p1;
memPtr = malloc(bytes+1); /* add 1 for a nul terminator */
if (memPtr)
{
if (recv(sock, memPtr, bytes, MSG_WAITALL) == bytes)
{
ext[0].n = bytes;
ext[0].ptr = memPtr;
memPtr[bytes] = 0; /* may be duplicate terminator */
myDoCommand(&cmd, ext);
free(memPtr);
}
else
{
free(memPtr);
break;
}
}
else break;
}
else
{
cmd.res = gpioNotifyOpenInBand(sock);
switch (cmd.cmd)
{
case PI_CMD_TRIG:
/*
p1=user_gpio
p2=pulseLen
## extension ##
unsigned level
*/
ext[0].n = 4;
ext[0].ptr = &tmp;
if (recv(sock, &tmp, sizeof(unsigned), MSG_WAITALL) !=
sizeof(unsigned))
{
close(sock);
return 0;
}
break;
default:
break;
}
myDoCommand(&cmd, ext);
}
write(sock, &cmd, sizeof(cmdCmd_t));
@ -2647,10 +2850,8 @@ static void * pthSocketThreadHandler(void *fdC)
static void * pthSocketThread(void *x)
{
int fdC, c, *sock;
struct sockaddr_in server, client;
struct sockaddr_in client;
pthread_attr_t attr;
char * portStr;
unsigned port;
if (pthread_attr_init(&attr))
SOFT_ERROR((void*)PI_INIT_FAILED,
@ -2664,21 +2865,8 @@ static void * pthSocketThread(void *x)
SOFT_ERROR((void*)PI_INIT_FAILED,
"pthread_attr_setdetachstate failed (%m)");
fdSock = socket(AF_INET , SOCK_STREAM , 0);
if (fdSock == -1)
SOFT_ERROR((void*)PI_INIT_FAILED, "socket failed (%m)");
portStr = getenv(PI_ENVPORT);
if (portStr) port = atoi(portStr); else port = gpioCfg.socketPort;
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(port);
if (bind(fdSock,(struct sockaddr *)&server , sizeof(server)) < 0)
SOFT_ERROR((void*)PI_INIT_FAILED, "bind failed (%m)");
/* fdSock opened in gpioInitialise so that we can treat
failure to bind as fatal. */
listen(fdSock, 100);
@ -3264,7 +3452,7 @@ static void initClearGlobals(void)
wfStats.micros = 0;
wfStats.highMicros = 0;
wfStats.maxMicros = -1;
wfStats.maxMicros = PI_WAVE_MAX_MICROS;
wfStats.pulses = 0;
wfStats.highPulses = 0;
@ -3406,7 +3594,8 @@ static void initReleaseResources(void)
munmap(dmaVirt[i], PAGE_SIZE);
}
munmap(dmaVirt, PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *));
munmap(dmaVirt,
PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *));
}
dmaVirt = MAP_FAILED;
@ -3418,7 +3607,8 @@ static void initReleaseResources(void)
munmap(dmaPhys[i], PAGE_SIZE);
}
munmap(dmaPhys, PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *));
munmap(dmaPhys,
PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *));
}
dmaPhys = MAP_FAILED;
@ -3474,6 +3664,9 @@ static void initReleaseResources(void)
int gpioInitialise(void)
{
int i;
struct sockaddr_in server;
char * portStr;
unsigned port;
clock_gettime(CLOCK_REALTIME, &libStarted);
@ -3542,6 +3735,22 @@ int gpioInitialise(void)
if (!(gpioCfg.ifFlags & PI_DISABLE_SOCK_IF))
{
fdSock = socket(AF_INET , SOCK_STREAM , 0);
if (fdSock == -1)
SOFT_ERROR(PI_INIT_FAILED, "socket failed (%m)");
portStr = getenv(PI_ENVPORT);
if (portStr) port = atoi(portStr); else port = gpioCfg.socketPort;
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(port);
if (bind(fdSock,(struct sockaddr *)&server , sizeof(server)) < 0)
SOFT_ERROR(PI_INIT_FAILED, "bind to port %d failed (%m)", port);
if (pthread_create(&pthSocket, &pthAttr, pthSocketThread, &i))
SOFT_ERROR(PI_INIT_FAILED, "pthread_create socket failed (%m)");
@ -4127,15 +4336,16 @@ int gpioWaveAddGeneric(unsigned numPulses, gpioPulse_t * pulses)
int gpioWaveAddSerial(unsigned gpio,
unsigned baud,
unsigned offset,
unsigned numChar,
char * str)
char *str)
{
int i, b, p, lev, c, v;
unsigned bitDelay[10];
DBG(DBG_USER, "gpio=%d baud=%d numChar=%d str*=%08X",
gpio, baud, numChar, (uint32_t)str);
DBG(DBG_USER, "gpio=%d baud=%d offset=%d numChar=%d str=%s",
gpio, baud, offset, numChar, str);
CHECK_INITED;
@ -4149,6 +4359,9 @@ int gpioWaveAddSerial(unsigned gpio,
if (numChar > PI_WAVE_MAX_CHARS)
SOFT_ERROR(PI_TOO_MANY_CHARS, "too many chars (%d)", numChar);
if (offset > PI_WAVE_MAX_MICROS)
SOFT_ERROR(PI_BAD_SER_OFFSET, "offset too large (%d)", offset);
if (!numChar) return 0;
waveBitDelay(baud, bitDelay);
@ -4157,7 +4370,9 @@ int gpioWaveAddSerial(unsigned gpio,
wf[2][p].gpioOn = (1<<gpio);
wf[2][p].gpioOff = 0;
wf[2][p].usDelay = bitDelay[0];
if (offset > bitDelay[0]) wf[2][p].usDelay = offset;
else wf[2][p].usDelay = bitDelay[0];
for (i=0; i<numChar; i++)
{
@ -4609,6 +4824,35 @@ int gpioNotifyClose(unsigned handle)
return 0;
}
/* ----------------------------------------------------------------------- */
int gpioTrigger(unsigned gpio, unsigned pulseLen, unsigned level)
{
DBG(DBG_USER, "gpio=%d pulseLen=%d level=%d", gpio, pulseLen, level);
CHECK_INITED;
if (gpio > PI_MAX_USER_GPIO)
SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
if (level > PI_ON)
SOFT_ERROR(PI_BAD_LEVEL, "gpio %d, bad level (%d)", gpio, level);
if (pulseLen > PI_MAX_PULSELEN)
SOFT_ERROR(PI_BAD_PULSELEN,
"gpio %d, bad pulseLen (%d)", gpio, pulseLen);
if (level == PI_OFF) *(gpioReg + GPCLR0 + BANK) = BIT;
else *(gpioReg + GPSET0 + BANK) = BIT;
myGpioDelay(pulseLen);
if (level != PI_OFF) *(gpioReg + GPCLR0 + BANK) = BIT;
else *(gpioReg + GPSET0 + BANK) = BIT;
return 0;
}
/* ----------------------------------------------------------------------- */
@ -4769,7 +5013,7 @@ int gpioSetTimerFuncEx(unsigned id, unsigned ms, gpioTimerFuncEx_t f,
/* ----------------------------------------------------------------------- */
pthread_t *gpioStartThread(ThreadFunc_t func, void *arg)
pthread_t *gpioStartThread(gpioThreadFunc_t func, void *arg)
{
pthread_t *pth;
pthread_attr_t pthAttr;
@ -4818,6 +5062,58 @@ void gpioStopThread(pthread_t *pth)
}
}
/* ----------------------------------------------------------------------- */
int gpioStoreScript(char *script)
{
DBG(DBG_USER, "script=%s", script);
CHECK_INITED;
return PI_BAD_SCRIPT;
}
/* ----------------------------------------------------------------------- */
int gpioRunScript(int script_id)
{
DBG(DBG_USER, "script_id=%d", script_id);
CHECK_INITED;
return PI_BAD_SCRIPT_ID;
}
/* ----------------------------------------------------------------------- */
int gpioStopScript(int script_id)
{
DBG(DBG_USER, "script_id=%d", script_id);
CHECK_INITED;
return PI_BAD_SCRIPT_ID;
}
/* ----------------------------------------------------------------------- */
int gpioDeleteScript(int script_id)
{
DBG(DBG_USER, "script_id=%d", script_id);
CHECK_INITED;
return PI_BAD_SCRIPT_ID;
}
/* ----------------------------------------------------------------------- */
int gpioSetSignalFunc(unsigned signum, gpioSignalFunc_t f)

114
pigpio.h
View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 10
This version is for pigpio version 11
*/
#ifndef PIGPIO_H
@ -86,7 +86,7 @@ This version is for pigpio version 10
#include <stdint.h>
#include <pthread.h>
#define PIGPIO_VERSION 10
#define PIGPIO_VERSION 11
/*-------------------------------------------------------------------------*/
@ -148,6 +148,8 @@ gpioWaveGetCbs Length in cbs of the current waveform.
gpioWaveGetHighCbs Length of longest waveform so far.
gpioWaveGetMaxCbs Absolute maximum allowed cbs.
gpioTrigger Send a trigger pulse to a gpio.
gpioSetWatchdog Set a watchdog on a gpio.
gpioSetGetSamplesFunc Requests a gpio samples callback.
@ -159,6 +161,11 @@ gpioSetTimerFuncEx Request a regular timed callback, extended.
gpioStartThread Start a new thread.
gpioStopThread Stop a previously started thread.
gpioStoreScript Store a script.
gpioRunScript Run a stored script.
gpioStopScript Stop a running script.
gpioDeleteScript Delete a stored script.
gpioSetSignalFunc Request a signal callback.
gpioSetSignalFuncEx Request a signal callback, extended.
@ -217,6 +224,13 @@ typedef struct
uint32_t res;
} cmdCmd_t;
typedef struct
{
size_t n;
void *ptr;
int data;
} gpioExtent_t;
typedef struct
{
uint32_t tick;
@ -271,8 +285,7 @@ typedef void (*gpioGetSamplesFuncEx_t) (const gpioSample_t * samples,
int numSamples,
void * userdata);
typedef void *(ThreadFunc_t) (void *);
typedef void *(gpioThreadFunc_t) (void *);
/*
@ -881,7 +894,6 @@ int gpioWaveAddGeneric(unsigned numPulses, gpioPulse_t * pulses);
If the added waveform is intended to start after or within the existing
waveform then the first pulse should consist of a delay.
*/
@ -889,15 +901,17 @@ int gpioWaveAddGeneric(unsigned numPulses, gpioPulse_t * pulses);
/*-------------------------------------------------------------------------*/
int gpioWaveAddSerial(unsigned user_gpio,
unsigned baud,
unsigned offset,
unsigned numChar,
char * str);
/*-------------------------------------------------------------------------*/
/* This function adds a waveform representing serial data to the
existing waveform (if any).
existing waveform (if any). The serial data starts offset microseconds
from the start of the waveform.
Returns the new total number of pulses in the current waveform if OK,
otherwise PI_BAD_USER_GPIO, PI_BAD_WAVE_BAUD, PI_TOO_MANY_CHARS, or
PI_TOO_MANY_PULSES.
otherwise PI_BAD_USER_GPIO, PI_BAD_WAVE_BAUD, PI_TOO_MANY_CHARS,
PI_BAD_SER_OFFSET, or PI_TOO_MANY_PULSES.
NOTES:
@ -915,6 +929,8 @@ int gpioWaveAddSerial(unsigned user_gpio,
#define PI_WAVE_MIN_BAUD 100
#define PI_WAVE_MAX_BAUD 250000
#define PI_WAVE_MAX_MICROS (30 * 60 * 1000000) /* half an hour */
/*-------------------------------------------------------------------------*/
@ -923,7 +939,8 @@ int gpioWaveTxStart(unsigned mode);
/* This function transmits the current waveform. The mode determines
whether the waveform is sent once or cycles endlessly.
Returns 0 if OK, otherwise PI_BAD_WAVE_MODE.
Returns the number of DMA control blocks in the waveform if OK,
otherwise PI_BAD_WAVE_MODE.
*/
#define PI_WAVE_MODE_ONE_SHOT 0
@ -1112,6 +1129,19 @@ int gpioWaveGetMaxCbs(void);
/*-------------------------------------------------------------------------*/
int gpioTrigger(unsigned user_gpio, unsigned pulseLen, unsigned level);
/*-------------------------------------------------------------------------*/
/* This function sends a trigger pulse to a gpio. The gpio is set to
level for pulseLen microseconds and then reset to not level.
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_LEVEL,
or PI_BAD_PULSELEN.
*/
#define PI_MAX_PULSELEN 100
/*-------------------------------------------------------------------------*/
int gpioSetWatchdog(unsigned user_gpio,
unsigned timeout);
@ -1267,7 +1297,7 @@ int gpioSetTimerFuncEx(unsigned timer,
/* ----------------------------------------------------------------------- */
pthread_t *gpioStartThread(ThreadFunc_t func, void *arg);
pthread_t *gpioStartThread(gpioThreadFunc_t func, void *arg);
/*-------------------------------------------------------------------------*/
/* Starts a new thread of execution with func as the main routine.
@ -1327,6 +1357,46 @@ void gpioStopThread(pthread_t *pth);
*/
/* ----------------------------------------------------------------------- */
int gpioStoreScript(char *script);
/* ----------------------------------------------------------------------- */
/* This function stores a null terminated script for later execution.
The function returns a script id if the script is valid,
otherwise PI_BAD_SCRIPT.
*/
/* ----------------------------------------------------------------------- */
int gpioRunScript(int script_id);
/* ----------------------------------------------------------------------- */
/* This function runs a stored script.
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
*/
/* ----------------------------------------------------------------------- */
int gpioStopScript(int script_id);
/* ----------------------------------------------------------------------- */
/* This function stops a running script.
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
*/
/* ----------------------------------------------------------------------- */
int gpioDeleteScript(int script_id);
/* ----------------------------------------------------------------------- */
/* This function deletes a stored script.
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
*/
/*-------------------------------------------------------------------------*/
int gpioSetSignalFunc(unsigned signum,
@ -1816,6 +1886,21 @@ void gpioWaveDump(void);
#define PI_CMD_PRRG 24
#define PI_CMD_HELP 25
#define PI_CMD_PIGPV 26
#define PI_CMD_WVCLR 27
#define PI_CMD_WVAG 28
#define PI_CMD_WVAS 29
#define PI_CMD_WVGO 30
#define PI_CMD_WVGOR 31
#define PI_CMD_WVBSY 32
#define PI_CMD_WVHLT 33
#define PI_CMD_WVSM 34
#define PI_CMD_WVSP 35
#define PI_CMD_WVSC 36
#define PI_CMD_TRIG 37
#define PI_CMD_PROC 38
#define PI_CMD_PROCD 39
#define PI_CMD_PROCR 40
#define PI_CMD_PROCS 41
/*
The following command only works on the socket interface.
@ -1841,7 +1926,7 @@ after this command is issued.
#define PI_BAD_LEVEL -5 /* level not 0-1 */
#define PI_BAD_PUD -6 /* pud not 0-2 */
#define PI_BAD_PULSEWIDTH -7 /* pulsewidth not 0 or 500-2500 */
#define PI_BAD_DUTYCYCLE -8 /* dutycycle not 0-255 */
#define PI_BAD_DUTYCYCLE -8 /* dutycycle outside set range */
#define PI_BAD_TIMER -9 /* timer not 0-9 */
#define PI_BAD_MS -10 /* ms not 10-60000 */
#define PI_BAD_TIMETYPE -11 /* timetype not 0-1 */
@ -1878,6 +1963,13 @@ after this command is issued.
#define PI_BAD_SERIAL_BUF -40 /* bad (null) serial buf parameter */
#define PI_NOT_PERMITTED -41 /* gpio operation not permitted */
#define PI_SOME_PERMITTED -42 /* one or more gpios not permitted */
#define PI_BAD_WVSC_COMMND -43 /* bad WVSC subcommand */
#define PI_BAD_WVSM_COMMND -44 /* bad WVSM subcommand */
#define PI_BAD_WVSP_COMMND -45 /* bad WVSP subcommand */
#define PI_BAD_PULSELEN -46 /* trigger pulse length > 100 */
#define PI_BAD_SCRIPT -47 /* invalid script */
#define PI_BAD_SCRIPT_ID -48 /* unknown script id */
#define PI_BAD_SER_OFFSET -49 /* add serial data offset > 30 minutes */
/*-------------------------------------------------------------------------*/

526
pigpio.py
View File

@ -76,7 +76,7 @@ import threading
import os
import atexit
VERSION = "1.1"
VERSION = "1.2"
# gpio levels
@ -140,8 +140,28 @@ _PI_CMD_NC= 21
_PI_CMD_PRG= 22
_PI_CMD_PFG= 23
_PI_CMD_PRRG= 24
_PI_CMD_HELP= 25
_PI_CMD_PIGPV=26
_PI_CMD_WVCLR=27
_PI_CMD_WVAG= 28
_PI_CMD_WVAS= 29
_PI_CMD_WVGO= 30
_PI_CMD_WVGOR=31
_PI_CMD_WVBSY=32
_PI_CMD_WVHLT=33
_PI_CMD_WVSM= 34
_PI_CMD_WVSP= 35
_PI_CMD_WVSC= 36
_PI_CMD_TRIG= 37
_PI_CMD_PROC= 38
_PI_CMD_PROCD=39
_PI_CMD_PROCR=40
_PI_CMD_PROCS=41
_PI_CMD_NOIB= 99
# pigpio error numbers
_PI_INIT_FAILED =-1
@ -179,14 +199,21 @@ _PI_NOT_INITIALISED =-31
_PI_INITIALISED =-32
_PI_BAD_WAVE_MODE =-33
_PI_BAD_CFG_INTERNAL=-34
_PI_BAD_WAVE_BAUD =-35
_PI_TOO_MANY_PULSES =-36
_PI_TOO_MANY_CHARS =-37
PI_BAD_WAVE_BAUD =-35
PI_TOO_MANY_PULSES =-36
PI_TOO_MANY_CHARS =-37
_PI_NOT_SERIAL_GPIO =-38
_PI_BAD_SERIAL_STRUC=-39
_PI_BAD_SERIAL_BUF =-40
PI_NOT_PERMITTED =-41
PI_SOME_PERMITTED =-42
PI_BAD_WVSC_COMMND =-43
PI_BAD_WVSM_COMMND =-44
PI_BAD_WVSP_COMMND =-45
PI_BAD_PULSELEN =-46
PI_BAD_SCRIPT =-47
PI_BAD_SCRIPT_ID =-48
PI_BAD_SER_OFFSET =-49
# pigpio error text
@ -225,12 +252,19 @@ _errors=[
[_PI_INITIALISED , "function called after gpioInitialise"],
[_PI_BAD_WAVE_MODE , "waveform mode not 0-1"],
[_PI_BAD_CFG_INTERNAL , "bad parameter in gpioCfgInternals call"],
[_PI_BAD_WAVE_BAUD , "baud rate not 100-250000"],
[_PI_TOO_MANY_PULSES , "waveform has too many pulses"],
[_PI_TOO_MANY_CHARS , "waveform has too many chars"],
[PI_BAD_WAVE_BAUD , "baud rate not 100-250000"],
[PI_TOO_MANY_PULSES , "waveform has too many pulses"],
[PI_TOO_MANY_CHARS , "waveform has too many chars"],
[_PI_NOT_SERIAL_GPIO , "no serial read in progress on gpio"],
[PI_NOT_PERMITTED , "no permission to update gpio"],
[PI_SOME_PERMITTED , "no permission to update one or more gpios"]
[PI_SOME_PERMITTED , "no permission to update one or more gpios"],
[PI_BAD_WVSC_COMMND , "bad WVSC subcommand"],
[PI_BAD_WVSM_COMMND , "bad WVSM subcommand"],
[PI_BAD_WVSP_COMMND , "bad WVSP subcommand"],
[PI_BAD_PULSELEN , "trigger pulse length > 100"],
[PI_BAD_SCRIPT , "invalid script"],
[PI_BAD_SCRIPT_ID , "unknown script id"],
[PI_BAD_SER_OFFSET , "add serial data offset > 30 minute"],
]
_control = None
@ -262,7 +296,7 @@ def error(pigpio_error):
for e in _errors:
if e[0] == pigpio_error:
return e[1]
return "unknown error"
return "unknown error ({})".format(pigpio_error)
def tickDiff(tStart, tEnd):
"""Calculate the time difference between two ticks.
@ -304,7 +338,8 @@ def _u2i(number):
return v
def _pigpio_command(sock, cmd, p1, p2):
"""Executes a pigpio socket command.
"""
Executes a pigpio socket command.
sock: command socket.
cmd: the command to be executed.
@ -318,6 +353,27 @@ def _pigpio_command(sock, cmd, p1, p2):
else:
raise _pigpioError("*** Module not started, call pigpio.start() ***")
def _pigpio_command_ext(sock, cmd, p1, p2, extents):
"""
Executes an extended pigpio socket command.
sock: command socket.
cmd: the command to be executed.
p1: command paramter 1 (if applicable).
p2: command paramter 2 (if applicable).
extents: additional data blocks
"""
if sock is not None:
sock.send(struct.pack('IIII', cmd, p1, p2, 0))
for ext in extents:
sock.sendall(ext)
x, y, z, res = struct.unpack('IIII', sock.recv(16))
return res
else:
raise _pigpioError("*** Module not started, call pigpio.start() ***")
class _callback:
"""An ADT class to hold callback information."""
@ -462,8 +518,7 @@ def set_mode(gpio, mode):
pigpio.set_mode(10, pigpio.ALT2) # gpio 10 as ALT2
...
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_MODES, gpio, mode))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_MODES, gpio, mode))
def get_mode(gpio):
"""Get the gpio mode.
@ -482,8 +537,7 @@ def get_mode(gpio):
6
...
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_MODEG, gpio, 0))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_MODEG, gpio, 0))
def set_pull_up_down(gpio, pud):
"""Set or clear the gpio pull-up/down resistor.
@ -516,8 +570,7 @@ def set_pull_up_down(gpio, pud):
1
...
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_PUD, gpio, pud))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_PUD, gpio, pud))
def read(gpio):
"""Read the gpio level.
@ -545,8 +598,7 @@ def read(gpio):
1
...
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_READ, gpio, 0))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_READ, gpio, 0))
def write(gpio, level):
"""Write the gpio level.
@ -578,8 +630,7 @@ def write(gpio, level):
1
...
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_WRITE, gpio, level))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_WRITE, gpio, level))
def set_PWM_dutycycle(user_gpio, dutycycle):
"""Start (non-zero dutycycle) or stop (0) PWM pulses on the gpio.
@ -609,8 +660,7 @@ def set_PWM_dutycycle(user_gpio, dutycycle):
set_PWM_dutycycle(4, 255) # PWM full on
...
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_PWM, user_gpio, dutycycle))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_PWM, user_gpio, dutycycle))
def set_PWM_range(user_gpio, range_):
"""Set the range of PWM values to be used on the gpio.
@ -645,8 +695,7 @@ def set_PWM_range(user_gpio, range_):
pigpio.set_PWM_range(9, 3000) # now 750 1/4, 1500 1/2, 2250 3/4 on
...
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_PRS, user_gpio, range_))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_PRS, user_gpio, range_))
def get_PWM_range(user_gpio):
"""Get the range of PWM values being used on the gpio.
@ -674,8 +723,7 @@ def get_PWM_range(user_gpio):
3000
...
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_PRG, user_gpio, 0))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_PRG, user_gpio, 0))
def get_PWM_real_range(user_gpio):
"""Get the real underlying range of PWM values being used on the gpio.
@ -701,8 +749,7 @@ def get_PWM_real_range(user_gpio):
25
...
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_PRRG, user_gpio, 0))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_PRRG, user_gpio, 0))
def set_PWM_frequency(user_gpio, frequency):
"""Set the frequency (in Hz) of the PWM to be used on the gpio.
@ -759,8 +806,7 @@ def set_PWM_frequency(user_gpio, frequency):
8000
...
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_PFS, user_gpio, frequency))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_PFS, user_gpio, frequency))
def get_PWM_frequency(user_gpio):
"""Get the frequency of PWM being used on the gpio.
@ -788,8 +834,7 @@ def get_PWM_frequency(user_gpio):
8000
...
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_PFG, user_gpio, 0))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_PFG, user_gpio, 0))
def set_servo_pulsewidth(user_gpio, pulsewidth):
"""Start (500-2500) or stop (0) servo pulses on the gpio.
@ -845,8 +890,8 @@ def set_servo_pulsewidth(user_gpio, pulsewidth):
for m in moves:
pigpio.set_servo_pulsewidth(24, m[0]);
time.sleep(m[1])
message = str(m[1]) + " seconds @ " + str(m[0]) + " us"
print(message)
s = str(m[1]) + " seconds @ " + str(m[0]) + " us"
print(s)
pigpio.stop()
@ -875,8 +920,8 @@ def set_servo_pulsewidth(user_gpio, pulsewidth):
for m in moves:
pigpio.set_PWM_dutycycle(25, m[0]);
time.sleep(m[1])
message = str(m[1]) + " seconds @ " + str(m[0]) + " us"
print(message)
s = str(m[1]) + " seconds @ " + str(m[0]) + " us"
print(s)
pigpio.stop()
@ -888,8 +933,7 @@ def set_servo_pulsewidth(user_gpio, pulsewidth):
5 seconds @ 2000 us
0 seconds @ 1000 us
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_SERVO, user_gpio, pulsewidth))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_SERVO, user_gpio, pulsewidth))
def notify_open():
"""Get a free notification handle.
@ -917,8 +961,7 @@ def notify_open():
pigpio.notify_begin(h, 1234)
...
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_NO, 0, 0))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_NO, 0, 0))
def notify_begin(handle, bits):
"""Start notifications on a previously opened handle.
@ -951,8 +994,7 @@ def notify_begin(handle, bits):
I (32 bit) level
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_NB, handle, bits))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_NB, handle, bits))
def notify_pause(handle):
"""Pause notifications on a previously opened handle.
@ -976,8 +1018,7 @@ def notify_pause(handle):
...
...
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_NB, handle, 0))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_NB, handle, 0))
def notify_close(handle):
"""Stop notifications on a previously opened handle and
@ -997,8 +1038,7 @@ def notify_close(handle):
...
...
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_NC, handle, 0))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_NC, handle, 0))
def set_watchdog(user_gpio, timeout):
"""Sets a watchdog for a gpio.
@ -1030,8 +1070,8 @@ def set_watchdog(user_gpio, timeout):
import time
def cbf(g, L, t):
message = "gpio=" + str(g) + " level=" + str(L) + " at " + str(t)
print(message)
s = "gpio=" + str(g) + " level=" + str(L) + " at " + str(t)
print(s)
pigpio.start()
@ -1068,8 +1108,7 @@ def set_watchdog(user_gpio, timeout):
gpio=22 level=2 at 3551411622
watchdog cancelled, 5 second delay
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_WDOG, user_gpio, timeout))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_WDOG, user_gpio, timeout))
def read_bank_1():
"""Read the levels of the bank 1 gpios (gpios 0-31).
@ -1148,8 +1187,7 @@ def clear_bank_1(levels):
0b1111110010000
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_BC1, levels, 0))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_BC1, levels, 0))
def clear_bank_2(levels):
"""Clears gpios 32-53 if the corresponding bit (0-21) in levels is set.
@ -1164,8 +1202,7 @@ def clear_bank_2(levels):
See clear_bank_1() for an example.
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_BC2, levels, 0))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_BC2, levels, 0))
def set_bank_1(levels):
"""Sets gpios 0-31 if the corresponding bit in levels is set.
@ -1215,8 +1252,7 @@ def set_bank_1(levels):
0b1111111011111
0b1111110010000
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_BS1, levels, 0))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_BS1, levels, 0))
def set_bank_2(levels):
"""Sets gpios 32-53 if the corresponding bit (0-21) in levels is set.
@ -1231,8 +1267,7 @@ def set_bank_2(levels):
See set_bank_1() for an example.
"""
r=_u2i(_pigpio_command(_control, _PI_CMD_BS2, levels, 0))
return r
return _u2i(_pigpio_command(_control, _PI_CMD_BS2, levels, 0))
def get_current_tick():
"""Gets the current system tick.
@ -1257,9 +1292,9 @@ def get_current_tick():
t2 = pigpio.get_current_tick()
message = "5 seconds is " + str(pigpio.tickDiff(t1, t2)) + " ticks"
s = "5 seconds is " + str(pigpio.tickDiff(t1, t2)) + " ticks"
print(message)
print(s)
pigpio.stop()
@ -1308,6 +1343,365 @@ def get_hardware_revision():
"""
return _pigpio_command(_control, _PI_CMD_HWVER, 0, 0)
def get_pigpio_version():
"""
Returns the pigpio software version.
"""
return _pigpio_command(_control, _PI_CMD_PIGPV, 0, 0)
class pulse:
"""
An ADT class to hold pulse information.
"""
def __init__(self, gpio_on, gpio_off, delay):
"""
Initialises a pulse ADT.
gpio_on: the gpios to switch on at the start of the pulse.
gpio_off: the gpios to switch off at the start of the pulse.
delay: the delay in microseconds before the next pulse.
"""
self.gpio_on = gpio_on
self.gpio_off = gpio_off
self.delay = delay
def wave_clear():
"""
Initialises a new waveform.
Returns 0 if OK.
A waveform comprises one of more pulses.
A pulse specifies
1) the gpios to be switched on at the start of the pulse.
2) the gpios to be switched off at the start of the pulse.
3) the delay in microseconds before the next pulse.
Any or all the fields can be zero. It doesn't make any sense
to set all the fields to zero (the pulse will be ignored).
When a waveform is started each pulse is executed in order with
the specified delay between the pulse and the next.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVCLR, 0, 0))
def wave_add_generic(pulses):
"""
Adds a list of pulses to the current waveform.
Returns the new total number of pulses in the current waveform
if OK, otherwise PI_TOO_MANY_PULSES.
pulses: list of pulses to add to the waveform.
The pulses are interleaved in time order within the existing
waveform (if any).
Merging allows the waveform to be built in parts, that is the
settings for gpio#1 can be added, and then gpio#2 etc.
If the added waveform is intended to start after or within
the existing waveform then the first pulse should consist
solely of a delay.
Example
#!/usr/bin/env python
import time
import pigpio
class stepper:
def __init__(self, g1, g2, g3, g4):
self.g1 = g1
self.g2 = g2
self.g3 = g3
self.g4 = g4
self.all = (1<<g1 | 1<<g2 | 1<<g3 | 1<<g4)
pigpio.set_mode(g1, pigpio.OUTPUT)
pigpio.set_mode(g2, pigpio.OUTPUT)
pigpio.set_mode(g3, pigpio.OUTPUT)
pigpio.set_mode(g4, pigpio.OUTPUT)
def step_on(self, pos):
if pos == 0: return (1<<self.g4)
elif pos == 1: return (1<<self.g3 | 1<<self.g4)
elif pos == 2: return (1<<self.g3)
elif pos == 3: return (1<<self.g2 | 1<<self.g3)
elif pos == 4: return (1<<self.g2)
elif pos == 5: return (1<<self.g1 | 1<<self.g2)
elif pos == 6: return (1<<self.g1)
elif pos == 7: return (1<<self.g1 | 1<<self.g4)
else: return 0
def step_off(self, pos):
return self.step_on(pos) ^ self.all
pigpio.start()
s1 = stepper(14, 15, 18, 17)
s2 = stepper(24, 25, 8, 7)
f1=[] # pulses to drive stepper 1 forward
b2=[] # pulses to drive stepper 2 backward
for i in range(8):
f1.append(pigpio.pulse(s1.step_on(i), s1.step_off(i), 1200))
b2.append(pigpio.pulse(s2.step_on(7-i), s2.step_off(7-i), 1200))
pigpio.wave_clear() # initialise a new waveform
pigpio.wave_add_generic(f1) # add stepper 1 forward
pigpio.wave_add_generic(b2) # add stepper 2 backward
pigpio.wave_tx_repeat() # repeately transmit pulses
time.sleep(10)
pigpio.wave_tx_stop() # stop waveform
pigpio.stop()
"""
# pigpio message format
# I p1 number of pulses
# I p2 0
## extension ##
# III on/off/delay * number of pulses
msg = ""
for p in pulses:
msg += struct.pack("III", p.gpio_on, p.gpio_off, p.delay)
extents = [msg]
return _u2i(_pigpio_command_ext(
_control, _PI_CMD_WVAG, len(pulses), 0, extents))
def wave_add_serial(user_gpio, baud, offset, data):
"""
Adds a waveform representing serial data to the existing waveform
(if any). The serial data starts offset microseconds from the
start of the waveform.
Returns the new total number of pulses in the current waveform
if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_WAVE_BAUD,
PI_TOO_MANY_CHARS, PI_BAD_SER_OFFSET, or PI_TOO_MANY_PULSES.
user_gpio: gpio to transmit data. You must set the gpio mode
to output.
baud: baud rate to use.
offset: number of microseconds from the starts of the waveform.
data: the data to transmit.
The serial data is formatted as one start bit, eight data bits,
and one stop bit.
It is legal to add serial data streams with different baud rates
to the same waveform.
Example
#!/usr/bin/env python
import time
import pigpio
GPIO=24
pigpio.start()
pigpio.set_mode(TX_GPIO, pigpio.OUTPUT)
pigpio.wave_clear() # initialise waveform
for i in range(10):
pigpio.wave_add_serial(
GPIO, 9600, i*2000000, "{} seconds in.\r\n".format(i*2))
pigpio.wave_tx_start()
time.sleep(22)
pigpio.stop()
"""
# pigpio message format
# I p1 user_gpio
# I p2 len(data)
## extension ##
# I baud
# I offset
# s data
extents = [struct.pack("I", baud),struct.pack("I", offset), data]
return _u2i(_pigpio_command_ext(
_control, _PI_CMD_WVAS, user_gpio, len(data), extents))
def wave_tx_busy():
"""
Checks to see if a waveform is currently being transmitted.
Returns 1 if a waveform is currently being transmitted, otherwise 0.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVBSY, 0, 0))
def wave_tx_stop():
"""
Stops the transmission of the current waveform.
Returns 0 if OK.
This function is intended to stop a waveform started with
wave_tx_repeat().
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVHLT, 0, 0))
def wave_tx_start():
"""
Transmits the current waveform. The waveform is sent once.
Returns the number of cbs in the waveform if OK,
otherwise PI_BAD_WAVE_MODE.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVGO, 0, 0))
def wave_tx_repeat():
"""
Transmits the current waveform. The waveform repeats until
wave_tx_stop is called.
Returns the number of cbs in the waveform if OK,
otherwise PI_BAD_WAVE_MODE.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVGOR, 0, 0))
def wave_get_micros():
"""
Returns the length in microseconds of the current waveform.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVSM, 0, 0))
def wave_get_max_micros():
"""
Returns the maximum possible size of a waveform in microseconds.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVSM, 2, 0))
def wave_get_pulses():
"""
Returns the length in pulses of the current waveform.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVSP, 0, 0))
def wave_get_max_pulses():
"""
Returns the maximum possible size of a waveform in pulses.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVSP, 2, 0))
def wave_get_cbs():
"""
Returns the length in DMA control blocks of the current waveform.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVSC, 0, 0))
def wave_get_max_cbs():
"""
Returns the maximum possible size of a waveform in DMA control blocks.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVSC, 2, 0))
def gpio_trigger(user_gpio, pulse_len=10, level=1):
"""
Send a trigger pulse to a gpio. The gpio is set to
level for pulse_len microseconds and then reset to not level.
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_LEVEL,
PI_BAD_PULSELEN, or PI_NOT_PERMITTED.
user_gpio: gpio to pulse.
pulse_len: length of pulse in microseconds.
level: whether the pulse should be high or low.
Example
#!/usr/bin/env python
import time
import pigpio
GPIO=24
pigpio.start()
for i in range(10):
pigpio.gpio_trigger(GPIO, (i*5)+10, 1)
time.sleep(1)
pigpio.stop()
"""
# pigpio message format
# I p1 user_gpio
# I p2 pulse_len
## extension ##
# I level
extents = [struct.pack("I", level)]
return _u2i(_pigpio_command_ext(
_control, _PI_CMD_TRIG, user_gpio, pulse_len, extents))
def store_script(script):
"""
Store a script for later execution.
Returns a script id if OK, otherwise PI_BAD_SCRIPT.
"""
# I p1 script length
# I p2 0
## extension ##
# s script
return _u2i(_pigpio_command_ext(
_control, _PI_CMD_PROC, len(script), 0, script))
def run_script(script_id):
"""
Runs a stored script.
Returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
script_id: script_id of stored script.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_PROCR, script_id, 0))
def stop_script(script_id):
"""
Stops a running script.
Returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
script_id: script_id of stored script.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_PROCS, script_id, 0))
def delete_script(script_id):
"""
Deletes a stored script.
Returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
script_id: script_id of stored script.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_PROCD, script_id, 0))
class callback:
"""A class to provide gpio level change callbacks."""
@ -1332,8 +1726,8 @@ class callback:
import time
def cbf(g, L, t):
message = "gpio=" + str(g) + " level=" + str(L) + " at " + str(t)
print(message)
s = "gpio=" + str(g) + " level=" + str(L) + " at " + str(t)
print(s)
pigpio.start()
@ -1376,9 +1770,9 @@ class callback:
tally_2 = cb.tally()
message = "counted " + str(tally_2 - tally_1) + " edges"
s = "counted " + str(tally_2 - tally_1) + " edges"
print(message)
print(s)
cb.cancel()
@ -1411,9 +1805,9 @@ class callback:
tally_2 = cb.tally()
message = "counted " + str(tally_2 - tally_1) + " rising edges"
s = "counted " + str(tally_2 - tally_1) + " rising edges"
print(message)
print(s)
cb.cancel()

View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 7+
This version is for pigpio version 11+
*/
#include <sys/types.h>
@ -34,6 +34,7 @@ This version is for pigpio version 7+
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
@ -43,7 +44,6 @@ This version is for pigpio version 7+
#include <ctype.h>
#include "pigpio.h"
#include "command.h"
/*
This program starts the pigpio library as a daemon.
@ -61,6 +61,22 @@ static uint64_t updateMask = -1;
static FILE * errFifo;
void fatal(char *fmt, ...)
{
char buf[128];
va_list ap;
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
fprintf(stderr, "%s\n", buf);
fflush(stderr);
exit(EXIT_FAILURE);
}
void usage()
{
fprintf(stderr, "\n" \
@ -98,21 +114,21 @@ static void initOpts(int argc, char *argv[])
i = atoi(optarg);
if ((i >= PI_BUF_MILLIS_MIN) && (i <= PI_BUF_MILLIS_MAX))
bufferSizeMilliseconds = i;
else cmdFatal("invalid -b option (%d)", i);
else fatal("invalid -b option (%d)", i);
break;
case 'd':
i = atoi(optarg);
if ((i >= PI_MIN_DMA_CHANNEL) && (i <= PI_MAX_PRIMARY_CHANNEL))
DMAprimaryChannel = i;
else cmdFatal("invalid -d option (%d)", i);
else fatal("invalid -d option (%d)", i);
break;
case 'e':
i = atoi(optarg);
if ((i >= PI_MIN_DMA_CHANNEL) && (i <= PI_MAX_SECONDARY_CHANNEL))
DMAsecondaryChannel = i;
else cmdFatal("invalid -e option (%d)", i);
else fatal("invalid -e option (%d)", i);
break;
case 'f':
@ -127,7 +143,7 @@ static void initOpts(int argc, char *argv[])
i = atoi(optarg);
if ((i >= PI_MIN_SOCKET_PORT) && (i <= PI_MAX_SOCKET_PORT))
socketPort = i;
else cmdFatal("invalid -p option (%d)", i);
else fatal("invalid -p option (%d)", i);
break;
case 's':
@ -145,7 +161,7 @@ static void initOpts(int argc, char *argv[])
break;
default:
cmdFatal("invalid -s option (%d)", i);
fatal("invalid -s option (%d)", i);
break;
}
break;
@ -154,21 +170,21 @@ static void initOpts(int argc, char *argv[])
i = atoi(optarg);
if ((i >= PI_CLOCK_PWM) && (i <= PI_CLOCK_PCM))
clockPeripheral = i;
else cmdFatal("invalid -t option (%d)", i);
else fatal("invalid -t option (%d)", i);
break;
case 'u':
i = atoi(optarg);
if ((i >= PI_CLOCK_OSC) && (i <= PI_CLOCK_PLLD))
clockSource = i;
else cmdFatal("invalid -u option (%d)", i);
else fatal("invalid -u option (%d)", i);
break;
case 'x':
mask = strtoll(optarg, &endptr, 0);
printf("mask=%llx\n", mask);
if (!*endptr) updateMask = mask;
else cmdFatal("invalid -x option (%s)", optarg);
else fatal("invalid -x option (%s)", optarg);
break;
default: /* '?' */
@ -221,11 +237,11 @@ int main(int argc, char **argv)
/* Create a new SID for the child process */
if (setsid() < 0) cmdFatal("setsid failed (%m)");
if (setsid() < 0) fatal("setsid failed (%m)");
/* Change the current working directory */
if ((chdir("/")) < 0) cmdFatal("chdir failed (%m)");
if ((chdir("/")) < 0) fatal("chdir failed (%m)");
/* check command line parameters */
@ -252,7 +268,7 @@ int main(int argc, char **argv)
/* start library */
if (gpioInitialise()< 0) cmdFatal("Can't initialise pigpio library");
if (gpioInitialise()< 0) fatal("Can't initialise pigpio library");
/* create pipe for error reporting */
@ -261,7 +277,7 @@ int main(int argc, char **argv)
mkfifo(PI_ERRFIFO, 0664);
if (chmod(PI_ERRFIFO, 0664) < 0)
cmdFatal("chmod %s failed (%m)", PI_ERRFIFO);
fatal("chmod %s failed (%m)", PI_ERRFIFO);
errFifo = freopen(PI_ERRFIFO, "w+", stderr);

View File

@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
*/
/* PIGPIOD_IF_VERSION 1 */
/* PIGPIOD_IF_VERSION 2 */
#include <stdio.h>
#include <stdlib.h>
@ -97,10 +97,34 @@ static int pigpio_command(int fd, int command, int p1, int p2)
cmd.p2 = p2;
cmd.res = 0;
if (send(fd, &cmd, sizeof(cmdCmd_t), 0) != sizeof(cmdCmd_t))
return pigif_bad_send;
if (send(fd, &cmd, sizeof(cmd), 0) != sizeof(cmd)) return pigif_bad_send;
if (recv(fd, &cmd, sizeof(cmdCmd_t), MSG_WAITALL) != sizeof(cmdCmd_t))
if (recv(fd, &cmd, sizeof(cmd), MSG_WAITALL) != sizeof(cmd))
return pigif_bad_recv;
return cmd.res;
}
static int pigpio_command_ext
(int fd, int command, int p1, int p2, int extents, gpioExtent_t *ext)
{
int i;
cmdCmd_t cmd;
cmd.cmd = command;
cmd.p1 = p1;
cmd.p2 = p2;
cmd.res = 0;
if (send(fd, &cmd, sizeof(cmd), 0) != sizeof(cmd)) return pigif_bad_send;
for (i=0; i<extents; i++)
{
if (send(fd, ext[i].ptr, ext[i].n, 0) != ext[i].n)
return pigif_bad_send;
}
if (recv(fd, &cmd, sizeof(cmd), MSG_WAITALL) != sizeof(cmd))
return pigif_bad_recv;
return cmd.res;
@ -390,7 +414,7 @@ unsigned pigpiod_if_version(void)
return PIGPIOD_IF_VERSION;
}
pthread_t *start_thread(ThreadFunc_t func, void *arg)
pthread_t *start_thread(gpioThreadFunc_t func, void *arg)
{
pthread_t *pth;
pthread_attr_t pthAttr;
@ -501,144 +525,219 @@ void pigpio_stop(void)
}
int set_mode(int gpio, int mode)
{
return pigpio_command(gPigCommand, PI_CMD_MODES, gpio, mode);
}
{return pigpio_command(gPigCommand, PI_CMD_MODES, gpio, mode);}
int get_mode(int gpio)
{
return pigpio_command(gPigCommand, PI_CMD_MODEG, gpio, 0);
}
{return pigpio_command(gPigCommand, PI_CMD_MODEG, gpio, 0);}
int set_pull_up_down(int gpio, int pud)
{
return pigpio_command(gPigCommand, PI_CMD_PUD, gpio, pud);
}
{return pigpio_command(gPigCommand, PI_CMD_PUD, gpio, pud);}
int read_gpio(int gpio)
{
return pigpio_command(gPigCommand, PI_CMD_READ, gpio, 0);
}
{return pigpio_command(gPigCommand, PI_CMD_READ, gpio, 0);}
int write_gpio(int gpio, int level)
{
return pigpio_command(gPigCommand, PI_CMD_WRITE, gpio, level);
}
{return pigpio_command(gPigCommand, PI_CMD_WRITE, gpio, level);}
int set_PWM_dutycycle(int user_gpio, int dutycycle)
{
return pigpio_command(gPigCommand, PI_CMD_PWM, user_gpio, dutycycle);
}
{return pigpio_command(gPigCommand, PI_CMD_PWM, user_gpio, dutycycle);}
int set_PWM_range(int user_gpio, int range_)
{
return pigpio_command(gPigCommand, PI_CMD_PRS, user_gpio, range_);
}
{return pigpio_command(gPigCommand, PI_CMD_PRS, user_gpio, range_);}
int get_PWM_range(int user_gpio)
{
return pigpio_command(gPigCommand, PI_CMD_PRG, user_gpio, 0);
}
{return pigpio_command(gPigCommand, PI_CMD_PRG, user_gpio, 0);}
int get_PWM_real_range(int user_gpio)
{
return pigpio_command(gPigCommand, PI_CMD_PRRG, user_gpio, 0);
}
{return pigpio_command(gPigCommand, PI_CMD_PRRG, user_gpio, 0);}
int set_PWM_frequency(int user_gpio, int frequency)
{
return pigpio_command(gPigCommand, PI_CMD_PFS, user_gpio, frequency);
}
{return pigpio_command(gPigCommand, PI_CMD_PFS, user_gpio, frequency);}
int get_PWM_frequency(int user_gpio)
{
return pigpio_command(gPigCommand, PI_CMD_PFG, user_gpio, 0);
}
{return pigpio_command(gPigCommand, PI_CMD_PFG, user_gpio, 0);}
int set_servo_pulsewidth(int user_gpio, int pulsewidth)
{
return pigpio_command(gPigCommand, PI_CMD_SERVO, user_gpio, pulsewidth);
}
{return pigpio_command(gPigCommand, PI_CMD_SERVO, user_gpio, pulsewidth);}
int notify_open(void)
{
return pigpio_command(gPigCommand, PI_CMD_NO, 0, 0);
}
{return pigpio_command(gPigCommand, PI_CMD_NO, 0, 0);}
int notify_begin(int handle, uint32_t bits)
{
return pigpio_command(gPigCommand, PI_CMD_NB, handle, bits);
}
{return pigpio_command(gPigCommand, PI_CMD_NB, handle, bits);}
int notify_pause(int handle)
{
return pigpio_command(gPigCommand, PI_CMD_NB, handle, 0);
}
{return pigpio_command(gPigCommand, PI_CMD_NB, handle, 0);}
int notify_close(int handle)
{
return pigpio_command(gPigCommand, PI_CMD_NC, handle, 0);
}
{return pigpio_command(gPigCommand, PI_CMD_NC, handle, 0);}
int set_watchdog(int user_gpio, int timeout)
{
return pigpio_command(gPigCommand, PI_CMD_WDOG, user_gpio, timeout);
}
{return pigpio_command(gPigCommand, PI_CMD_WDOG, user_gpio, timeout);}
uint32_t read_bank_1(void)
{
return pigpio_command(gPigCommand, PI_CMD_BR1, 0, 0);
}
{return pigpio_command(gPigCommand, PI_CMD_BR1, 0, 0);}
uint32_t read_bank_2(void)
{
return pigpio_command(gPigCommand, PI_CMD_BR2, 0, 0);
}
{return pigpio_command(gPigCommand, PI_CMD_BR2, 0, 0);}
int clear_bank_1(uint32_t levels)
{
return pigpio_command(gPigCommand, PI_CMD_BC1, levels, 0);
}
{return pigpio_command(gPigCommand, PI_CMD_BC1, levels, 0);}
int clear_bank_2(uint32_t levels)
{
return pigpio_command(gPigCommand, PI_CMD_BC2, levels, 0);
}
{return pigpio_command(gPigCommand, PI_CMD_BC2, levels, 0);}
int set_bank_1(uint32_t levels)
{
return pigpio_command(gPigCommand, PI_CMD_BS1, levels, 0);
}
{return pigpio_command(gPigCommand, PI_CMD_BS1, levels, 0);}
int set_bank_2(uint32_t levels)
{
return pigpio_command(gPigCommand, PI_CMD_BS2, levels, 0);
}
{return pigpio_command(gPigCommand, PI_CMD_BS2, levels, 0);}
uint32_t get_current_tick(void)
{
return pigpio_command(gPigCommand, PI_CMD_TICK, 0, 0);
}
{return pigpio_command(gPigCommand, PI_CMD_TICK, 0, 0);}
uint32_t get_hardware_revision(void)
{
return pigpio_command(gPigCommand, PI_CMD_HWVER, 0, 0);
}
{return pigpio_command(gPigCommand, PI_CMD_HWVER, 0, 0);}
unsigned get_pigpio_version(void)
{return pigpio_command(gPigCommand, PI_CMD_PIGPV, 0, 0);}
int wave_clear(void)
{return pigpio_command(gPigCommand, PI_CMD_WVCLR, 0, 0);}
int wave_add_generic(unsigned numPulses, gpioPulse_t *pulses)
{
return pigpio_command(gPigCommand, PI_CMD_PIGPV, 0, 0);
gpioExtent_t ext[1];
/*
p1=numPulses
p2=0
## extension ##
gpioPulse_t[] pulses
*/
ext[0].n = numPulses * sizeof(gpioPulse_t);
ext[0].ptr = pulses;
return pigpio_command_ext(gPigCommand, PI_CMD_WVAG, numPulses, 0, 1, ext);
}
int wave_add_serial(
unsigned gpio, unsigned baud, unsigned offset, unsigned numChar, char *str)
{
gpioExtent_t ext[3];
/*
p1=gpio
p2=numChar
## extension ##
unsigned baud
unsigned offset
char[] str
*/
ext[0].n = sizeof(unsigned);
ext[0].ptr = &baud;
ext[1].n = sizeof(unsigned);
ext[1].ptr = &offset;
ext[2].n = numChar;
ext[2].ptr = str;
return pigpio_command_ext(gPigCommand, PI_CMD_WVAS, gpio, numChar, 3, ext);
}
int wave_tx_busy(void)
{return pigpio_command(gPigCommand, PI_CMD_WVBSY, 0, 0);}
int wave_tx_stop(void)
{return pigpio_command(gPigCommand, PI_CMD_WVHLT, 0, 0);}
int wave_tx_start(void)
{return pigpio_command(gPigCommand, PI_CMD_WVGO, 0, 0);}
int wave_tx_repeat(void)
{return pigpio_command(gPigCommand, PI_CMD_WVGOR, 0, 0);}
int wave_get_micros(void)
{return pigpio_command(gPigCommand, PI_CMD_WVSM, 0, 0);}
int wave_get_high_micros(void)
{return pigpio_command(gPigCommand, PI_CMD_WVSM, 1, 0);}
int wave_get_max_micros(void)
{return pigpio_command(gPigCommand, PI_CMD_WVSM, 2, 0);}
int wave_get_pulses(void)
{return pigpio_command(gPigCommand, PI_CMD_WVSP, 0, 0);}
int wave_get_high_pulses(void)
{return pigpio_command(gPigCommand, PI_CMD_WVSP, 1, 0);}
int wave_get_max_pulses(void)
{return pigpio_command(gPigCommand, PI_CMD_WVSP, 2, 0);}
int wave_get_cbs(void)
{return pigpio_command(gPigCommand, PI_CMD_WVSC, 0, 0);}
int wave_get_high_cbs(void)
{return pigpio_command(gPigCommand, PI_CMD_WVSC, 1, 0);}
int wave_get_max_cbs(void)
{return pigpio_command(gPigCommand, PI_CMD_WVSC, 2, 0);}
int gpio_trigger(unsigned gpio, unsigned pulseLen, unsigned level)
{
gpioExtent_t ext[1];
/*
p1=gpio
p2=pulseLen
## extension ##
unsigned level
*/
ext[0].n = sizeof(level);
ext[0].ptr = &level;
return pigpio_command_ext(gPigCommand, PI_CMD_TRIG, gpio, pulseLen, 1, ext);
}
int store_script(char *script)
{
unsigned len;
gpioExtent_t ext[1];
/*
p1=script length
p2=0
## extension ##
char[] script
*/
len = strlen(script);
ext[0].n = len;
ext[0].ptr = script;
return pigpio_command_ext(gPigCommand, PI_CMD_PROC, len, 0, 1, ext);
}
int run_script(int script_id)
{return pigpio_command(gPigCommand, PI_CMD_PROCR, script_id, 0);}
int stop_script(int script_id)
{return pigpio_command(gPigCommand, PI_CMD_PROCS, script_id, 0);}
int delete_script(int script_id)
{return pigpio_command(gPigCommand, PI_CMD_PROCD, script_id, 0);}
int callback(int gpio, int edge, CBFunc_t f)
{
return intCallback(gpio, edge, f, 0, 0);
}
{return intCallback(gpio, edge, f, 0, 0);}
int callback_ex(int gpio, int edge, CBFuncEx_t f, void *user)
{
return intCallback(gpio, edge, f, user, 1);
}
{return intCallback(gpio, edge, f, user, 1);}
int callback_cancel(int id)
{

View File

@ -30,7 +30,7 @@ For more information, please refer to <http://unlicense.org/>
#include "pigpio.h"
#define PIGPIOD_IF_VERSION 1
#define PIGPIOD_IF_VERSION 2
typedef enum
{
@ -70,7 +70,7 @@ const char *pigpio_error(int error);
unsigned pigpiod_if_version(void);
/* Return the pigpiod_if version. */
pthread_t *start_thread(ThreadFunc_t func, void *arg);
pthread_t *start_thread(gpioThreadFunc_t func, void *arg);
/* Starts a new thread of execution with func as the main routine.
Returns a pointer to pthread_t if OK, otherwise NULL.
@ -198,7 +198,6 @@ int set_PWM_range(int user_gpio, int range_);
The real value set by set_PWM_range is
(dutycycle * real range) / range.
*/
int get_PWM_range(int user_gpio);
@ -507,20 +506,213 @@ uint32_t get_hardware_revision(void);
hexadecimal number the function returns 0.
*/
int wave_clear(void);
/* This function initialises a new waveform.
Returns 0 if OK.
A waveform comprises one of more pulses. Each pulse consists of a
gpioPulse_t structure.
typedef struct
{
uint32_t gpioOn;
uint32_t gpioOff;
uint32_t usDelay;
} gpioPulse_t;
The fields specify
1) the gpios to be switched on at the start of the pulse.
2) the gpios to be switched off at the start of the pulse.
3) the delay in microseconds before the next pulse.
Any or all the fields can be zero. It doesn't make any sense to
set all the fields to zero (the pulse will be ignored).
When a waveform is started each pulse is executed in order with the
specified delay between the pulse and the next.
*/
int wave_tx_busy(void);
/* This function checks to see if a waveform is currently being
transmitted.
Returns 1 if a waveform is currently being transmitted, otherwise 0.
*/
int wave_tx_stop(void);
/* This function stops the transmission of the current waveform.
Returns 0 if OK.
This function is intended to stop a waveform started with the repeat mode.
*/
int wave_tx_start(void);
/* This function transmits the current waveform. The waveform is
sent once.
Returns the number of DMA control blocks in the waveform if OK,
otherwise PI_BAD_WAVE_MODE.
*/
int wave_tx_repeat(void);
/* This function transmits the current waveform. The waveform repeats
endlessly until wave_tx_stop is called.
Returns the number of DMA control blocks in the waveform if OK,
otherwise PI_BAD_WAVE_MODE.
*/
int wave_add_generic(unsigned numPulses, gpioPulse_t *pulses);
/* This function adds a number of pulses to the current waveform.
Returns the new total number of pulses in the current waveform if OK,
otherwise PI_TOO_MANY_PULSES.
The pulses are interleaved in time order within the existing waveform
(if any).
Merging allows the waveform to be built in parts, that is the settings
for gpio#1 can be added, and then gpio#2 etc.
If the added waveform is intended to start after or within the existing
waveform then the first pulse should consist solely of a delay.
*/
int wave_add_serial
(unsigned gpio, unsigned baud, unsigned offset, unsigned numChar, char *str);
/* This function adds a waveform representing serial data to the
existing waveform (if any). The serial data starts offset microseconds
from the start of the waveform.
Returns the new total number of pulses in the current waveform if OK,
otherwise PI_BAD_USER_GPIO, PI_BAD_WAVE_BAUD, PI_TOO_MANY_CHARS, or
PI_TOO_MANY_PULSES.
NOTES:
The serial data is formatted as one start bit, eight data bits, and one
stop bit.
It is legal to add serial data streams with different baud rates to
the same waveform.
*/
int wave_get_micros(void);
/* This function returns the length in microseconds of the current
waveform.
*/
int wave_get_high_micros(void);
/* This function returns the length in microseconds of the longest waveform
created since the pigpio daemon was started..
*/
int wave_get_max_micros(void);
/* This function returns the maximum possible size of a waveform in
microseconds.
*/
int wave_get_pulses(void);
/* This function returns the length in pulses of the current waveform.
*/
int wave_get_high_pulses(void);
/* This function returns the length in pulses of the longest waveform
created since the pigpio daemon was started..
*/
int wave_get_max_pulses(void);
/* This function returns the maximum possible size of a waveform in pulses.
*/
int wave_get_cbs(void);
/* This function returns the length in DMA control blocks of the current
waveform.
*/
int wave_get_high_cbs(void);
/* This function returns the length in DMA control blocks of the longest
waveform created since the pigpio daemon was started..
*/
int wave_get_max_cbs(void);
/* This function returns the maximum possible size of a waveform in DMA
control blocks.
*/
int gpio_trigger(unsigned gpio, unsigned pulseLen, unsigned level);
/* This function sends a trigger pulse to a gpio. The gpio is set to
level for pulseLen microseconds and then reset to not level.
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_LEVEL,
PI_BAD_PULSELEN, or PI_NOT_PERMITTED.
*/
int store_script(char *script);
/* This function stores a script for later execution.
The function returns a script id if the script is valid,
otherwise PI_BAD_SCRIPT.
*/
int run_script(int script_id);
/* This function runs a stored script.
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
*/
int stop_script(int script_id);
/* This function stops a running script.
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
*/
int delete_script(int script_id);
/* This function deletes a stored script.
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
*/
int callback(int gpio, int edge, CBFunc_t f);
/*
This function initialises a new callback.
The function returns a callback id if OK, otherwise pigif_bad_malloc,
pigif_duplicate_callback, or pigif_bad_callback.
The callback is called with the gpio, edge, and tick, whenever the
gpio has the identified edge.
*/
int callback_ex(int gpio, int edge, CBFuncEx_t f, void *user);
/*
This function initialises a new callback.
The function returns a callback id if OK, otherwise pigif_bad_malloc,
pigif_duplicate_callback, or pigif_bad_callback.
The callback is called with the gpio, edge, tick, and user, whenever
the gpio has the identified edge.
*/
int callback_cancel(int id);
/*
This function cancels a callback identified by its id.
The function returns 0 if OK, otherwise pigif_callback_not_found.
*/
int wait_for_edge(int gpio, int edge, double timeout);
/*
This function waits for edge on the gpio for up to timeout
seconds.
The function returns 1 if the edge occurred, otherwise 0.
The function returns when the edge occurs or after the timeout.
*/
#endif

63
pigs.c
View File

@ -26,11 +26,12 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 7+
This version is for pigpio version 11+
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
@ -42,10 +43,26 @@ This version is for pigpio version 7+
#include "command.h"
/*
This program provides a socket interface
to the commands available from pigpio.
This program provides a socket interface to some of
the commands available from pigpio.
*/
void fatal(char *fmt, ...)
{
char buf[128];
va_list ap;
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
fprintf(stderr, "%s\n", buf);
fflush(stderr);
exit(EXIT_FAILURE);
}
static int openSocket(void)
{
int sock, err;
@ -88,9 +105,10 @@ static int openSocket(void)
int main(int argc , char *argv[])
{
int sock, r, idx;
int sock, r, idx, i;
cmdCmd_t cmd;
char buf[128];
gpioExtent_t ext[3];
char buf[1024];
sock = openSocket();
@ -113,31 +131,48 @@ int main(int argc , char *argv[])
sprintf(buf, "%10s %10s %10s", argv[1], argv[2], argv[3]);
break;
case 5:
sprintf(buf, "%10s %10s %10s %10s",
argv[1], argv[2], argv[3], argv[4]);
break;
case 6:
sprintf(buf, "%10s %10s %10s %10s %10s",
argv[1], argv[2], argv[3], argv[4], argv[5]);
break;
default:
cmdFatal("what?");
fatal("what? 'pigs h' for help");
}
if ((idx=cmdParse(buf, &cmd)) >= 0)
if ((idx=cmdParse(buf, &cmd, argc, argv, ext)) >= 0)
{
if (send(sock, &cmd, sizeof(cmdCmd_t), 0) == sizeof(cmdCmd_t))
{
/* send extensions */
for (i=0; i<cmdInfo[idx].ext; i++)
{
send(sock, ext[i].ptr, ext[i].n, 0);
}
if (recv(sock, &cmd, sizeof(cmdCmd_t), 0) == sizeof(cmdCmd_t))
{
switch (cmdInfo[idx].rv)
{
case 0:
r = cmd.res;
if (r < 0) cmdFatal("ERROR: %s", cmdErrStr(r));
if (r < 0) fatal("ERROR: %s", cmdErrStr(r));
break;
case 1:
r = cmd.res;
if (r < 0) cmdFatal("ERROR: %s", cmdErrStr(r));
if (r < 0) fatal("ERROR: %s", cmdErrStr(r));
break;
case 2:
r = cmd.res;
if (r < 0) cmdFatal("ERROR: %s", cmdErrStr(r));
if (r < 0) fatal("ERROR: %s", cmdErrStr(r));
else printf("%d\n", r);
break;
@ -154,13 +189,13 @@ int main(int argc , char *argv[])
break;
}
}
else cmdFatal("recv failed, %m");
else fatal("recv failed, %m");
}
else cmdFatal("send failed, %m");
else fatal("send failed, %m");
}
else cmdFatal("what?");
else fatal("what? 'pigs h' for help");
}
else cmdFatal("connect failed, %m");
else fatal("connect failed, %m");
close(sock);

View File

@ -3,7 +3,7 @@
from distutils.core import setup
setup(name='pigpio',
version='1.1',
version='1.2',
author='joan',
author_email='joan@abyz.me.uk',
maintainer='joan',
@ -11,7 +11,7 @@ setup(name='pigpio',
url='http://abyz.co.uk/rpi/pigpio/python.html/',
description='Raspberry Pi gpio module',
long_description='Raspberry Pi Python module for access to the pigpio daemon',
download_url='http://abyz.co.uk/rpi/pigpio/pigpio.tar',
download_url='http://abyz.co.uk/rpi/pigpio/pigpio.zip',
license='TBD',
py_modules=['pigpio']
)