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:
# 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
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
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
*/
/*
-This version is for pigpio version 10+
+This version is for pigpio version 11+
*/
#include <stdio.h>
#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\
";
{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"},
{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";
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);
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)
{
}
break;
- case 9: /* PUD */
+ case 9: /* PUD
+ */
f = sscanf(buf, " %7s %d %c %c", str, &cmd->p1, &c, &t);
if (f == 3)
{
}
}
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;
*/
/*
-This version is for pigpio version 7+
+This version is for pigpio version 11+
*/
#ifndef COMMAND_H
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
+
For more information, please refer to <http://unlicense.org/>
*/
-/* pigpio version 10 */
+/* pigpio version 11 */
#include <stdio.h>
#include <string.h>
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)
};
static volatile int DMAstarted = 0;
-static int libInitialised = 0;
+static int libInitialised = 0;
static int pthAlertRunning = 0;
static int pthFifoRunning = 0;
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);
/* ----------------------------------------------------------------------- */
-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
+ case PI_CMD_BC1:
+ mask = gpioMask;
+
+ res = gpioWrite_Bits_0_31_Clear(p1&mask);
+
+ if ((mask | p1) != mask)
{
- PERM_ERROR("gpioSetMode: gpio %d, no permission to update", p1);
- res = PI_NOT_PERMITTED;
+ PERM_ERROR(
+ "gpioWrite_Bits_0_31_Clear: bad levels %08X (permissions %08X)",
+ p1, mask);
+ res = PI_SOME_PERMITTED;
}
break;
- case PI_CMD_MODEG:
- res = gpioGetMode(p1);
+ case PI_CMD_BC2:
+ mask = gpioMask>>32;
+
+ res = gpioWrite_Bits_32_53_Clear(p1&mask);
+
+ if ((mask | p1) != mask)
+ {
+ PERM_ERROR(
+ "gpioWrite_Bits_32_53_Clear: bad levels %08X (permissions %08X)",
+ p1, mask);
+ res = PI_SOME_PERMITTED;
+ }
break;
- case PI_CMD_PUD:
- if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetPullUpDown(p1, p2);
- else
+ 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;
+
+ res = gpioWrite_Bits_0_31_Set(p1&mask);
+
+ if ((mask | p1) != mask)
{
PERM_ERROR(
- "gpioSetPullUpDown: gpio %d, no permission to update", p1);
- res = PI_NOT_PERMITTED;
+ "gpioWrite_Bits_0_31_Set: bad levels %08X (permissions %08X)",
+ p1, mask);
+ res = PI_SOME_PERMITTED;
}
break;
- case PI_CMD_READ:
- res = gpioRead(p1);
+ case PI_CMD_BS2:
+ mask = gpioMask>>32;
+
+ res = gpioWrite_Bits_32_53_Set(p1&mask);
+
+ if ((mask | p1) != mask)
+ {
+ PERM_ERROR(
+ "gpioWrite_Bits_32_53_Set: bad levels %08X (permissions %08X)",
+ p1, mask);
+ res = PI_SOME_PERMITTED;
+ }
break;
- case PI_CMD_WRITE:
- if (gpioMask & (uint64_t)(1<<p1)) res = gpioWrite(p1, p2);
+ 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("gpioWrite: gpio %d, no permission to update", p1);
+ PERM_ERROR("gpioSetMode: 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);
+ 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("gpioPWM: gpio %d, no permission to update", p1);
+ PERM_ERROR(
+ "gpioSetPWMfrequency: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
+ 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_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
}
break;
- case PI_CMD_PFS:
- if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetPWMfrequency(p1, p2);
+ case PI_CMD_PUD:
+ if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetPullUpDown(p1, p2);
else
{
PERM_ERROR(
- "gpioSetPWMfrequency: gpio %d, no permission to update", p1);
+ "gpioSetPullUpDown: 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);
+ case PI_CMD_PWM:
+ if (gpioMask & (uint64_t)(1<<p1)) res = gpioPWM(p1, p2);
else
{
- PERM_ERROR("gpioServo: gpio %d, no permission to update", p1);
+ PERM_ERROR("gpioPWM: 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_READ: res = gpioRead(p1); break;
- case PI_CMD_BC1:
- mask = gpioMask;
+ case PI_CMD_WDOG: res = gpioSetWatchdog(p1, p2); break;
- res = gpioWrite_Bits_0_31_Clear(p1&mask);
-
- if ((mask | p1) != mask)
+ case PI_CMD_WRITE:
+ if (gpioMask & (uint64_t)(1<<p1)) res = gpioWrite(p1, p2);
+ else
{
- PERM_ERROR(
- "gpioWrite_Bits_0_31_Clear: bad levels %08X (permissions %08X)",
- p1, mask);
- res = PI_SOME_PERMITTED;
+ PERM_ERROR("gpioWrite: gpio %d, no permission to update", p1);
+ res = PI_NOT_PERMITTED;
}
break;
- case PI_CMD_BC2:
- mask = gpioMask>>32;
-
- res = gpioWrite_Bits_32_53_Clear(p1&mask);
-
- if ((mask | p1) != mask)
+ case PI_CMD_SERVO:
+ if (gpioMask & (uint64_t)(1<<p1)) res = gpioServo(p1, p2);
+ else
{
- PERM_ERROR(
- "gpioWrite_Bits_32_53_Clear: bad levels %08X (permissions %08X)",
- p1, mask);
- res = PI_SOME_PERMITTED;
+ PERM_ERROR("gpioServo: gpio %d, no permission to update", p1);
+ res = PI_NOT_PERMITTED;
}
break;
- case PI_CMD_BS1:
- mask = gpioMask;
-
- res = gpioWrite_Bits_0_31_Set(p1&mask);
+ case PI_CMD_TICK: res = gpioTick(); break;
- if ((mask | p1) != mask)
+ case PI_CMD_TRIG:
+ if (gpioMask & (uint64_t)(1<<p1))
+ res = gpioTrigger(p1, p2, *(int *) (ext[0].ptr));
+ else
{
- PERM_ERROR(
- "gpioWrite_Bits_0_31_Set: bad levels %08X (permissions %08X)",
- p1, mask);
- res = PI_SOME_PERMITTED;
+ PERM_ERROR("gpioTrigger: gpio %d, no permission to update", p1);
+ res = PI_NOT_PERMITTED;
}
break;
- case PI_CMD_BS2:
- mask = gpioMask>>32;
+ case PI_CMD_WVAG:
- res = gpioWrite_Bits_32_53_Set(p1&mask);
+ /* need to mask off any non permitted gpios */
- if ((mask | p1) != mask)
+ mask = gpioMask;
+ pulse = ext[0].ptr;
+ masked = 0;
+
+ for (i=0; i<p1; i++)
{
- PERM_ERROR(
- "gpioWrite_Bits_32_53_Set: bad levels %08X (permissions %08X)",
- p1, mask);
- res = PI_SOME_PERMITTED;
+ 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;
+ }
}
- break;
- case PI_CMD_TICK:
- res = gpioTick();
- break;
+ res = gpioWaveAddGeneric(p1, pulse);
- case PI_CMD_HWVER:
- res = gpioHardwareRevision();
- break;
+ /* report permission error unless another error occurred */
+ if (masked && (res >= 0)) res = PI_SOME_PERMITTED;
- case PI_CMD_PRG:
- res = gpioGetPWMrange(p1);
break;
- case PI_CMD_PFG:
- res = gpioGetPWMfrequency(p1);
+ 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_PRRG:
- res = gpioGetPWMrealRange(p1);
- break;
+ case PI_CMD_WVBSY: res = gpioWaveTxBusy(); break;
- case PI_CMD_NO:
- res = gpioNotifyOpen();
- break;
+ case PI_CMD_WVCLR: res = gpioWaveClear(); break;
- case PI_CMD_NB:
- res = gpioNotifyBegin(p1, p2);
- break;
+ case PI_CMD_WVGO: res = gpioWaveTxStart(PI_WAVE_MODE_ONE_SHOT); break;
- case PI_CMD_NP:
- res = gpioNotifyPause(p1);
- break;
+ case PI_CMD_WVGOR: res = gpioWaveTxStart(PI_WAVE_MODE_REPEAT); break;
- case PI_CMD_NC:
- res = gpioNotifyClose(p1);
- break;
+ case PI_CMD_WVHLT: res = gpioWaveTxStop(); break;
- case PI_CMD_HELP:
+ 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_PIGPV:
- res = gpioVersion();
+ 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;
- }
-
- cmd->res = res;
+ 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;
}
/* ----------------------------------------------------------------------- */
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);
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)
{
/* ----------------------------------------------------------------------- */
-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));
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,
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);
wfStats.micros = 0;
wfStats.highMicros = 0;
- wfStats.maxMicros = -1;
+ wfStats.maxMicros = PI_WAVE_MAX_MICROS;
wfStats.pulses = 0;
wfStats.highPulses = 0;
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;
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;
int gpioInitialise(void)
{
int i;
+ struct sockaddr_in server;
+ char * portStr;
+ unsigned port;
clock_gettime(CLOCK_REALTIME, &libStarted);
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)");
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;
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);
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++)
{
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;
+}
+
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
-pthread_t *gpioStartThread(ThreadFunc_t func, void *arg)
+pthread_t *gpioStartThread(gpioThreadFunc_t func, void *arg)
{
pthread_t *pth;
pthread_attr_t pthAttr;
}
}
+/* ----------------------------------------------------------------------- */
+
+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)
*/
/*
-This version is for pigpio version 10
+This version is for pigpio version 11
*/
#ifndef PIGPIO_H
#include <stdint.h>
#include <pthread.h>
-#define PIGPIO_VERSION 10
+#define PIGPIO_VERSION 11
/*-------------------------------------------------------------------------*/
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.
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.
uint32_t res;
} cmdCmd_t;
+typedef struct
+{
+ size_t n;
+ void *ptr;
+ int data;
+} gpioExtent_t;
+
typedef struct
{
uint32_t tick;
int numSamples,
void * userdata);
-typedef void *(ThreadFunc_t) (void *);
-
+typedef void *(gpioThreadFunc_t) (void *);
/*
If the added waveform is intended to start after or within the existing
waveform then the first pulse should consist of a delay.
-
*/
/*-------------------------------------------------------------------------*/
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:
#define PI_WAVE_MIN_BAUD 100
#define PI_WAVE_MAX_BAUD 250000
+#define PI_WAVE_MAX_MICROS (30 * 60 * 1000000) /* half an hour */
+
/*-------------------------------------------------------------------------*/
/* 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
+/*-------------------------------------------------------------------------*/
+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);
/* ----------------------------------------------------------------------- */
-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.
*/
+/* ----------------------------------------------------------------------- */
+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,
#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.
#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 */
#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 */
/*-------------------------------------------------------------------------*/
import os
import atexit
-VERSION = "1.1"
+VERSION = "1.2"
# gpio levels
_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
_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
[_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
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.
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.
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."""
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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()
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()
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.
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.
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.
...
...
"""
- 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
...
...
"""
- 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.
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()
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).
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.
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.
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.
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.
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()
"""
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."""
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()
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()
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()
*/
/*
-This version is for pigpio version 7+
+This version is for pigpio version 11+
*/
#include <sys/types.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <ctype.h>
#include "pigpio.h"
-#include "command.h"
/*
This program starts the pigpio library as a daemon.
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" \
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':
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':
break;
default:
- cmdFatal("invalid -s option (%d)", i);
+ fatal("invalid -s option (%d)", i);
break;
}
break;
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: /* '?' */
/* 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 */
/* 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 */
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);
For more information, please refer to <http://unlicense.org/>
*/
-/* PIGPIOD_IF_VERSION 1 */
+/* PIGPIOD_IF_VERSION 2 */
#include <stdio.h>
#include <stdlib.h>
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;
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;
}
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);}
+
+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_HWVER, 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);
}
-unsigned get_pigpio_version(void)
+int wave_add_serial(
+ unsigned gpio, unsigned baud, unsigned offset, unsigned numChar, char *str)
{
- return pigpio_command(gPigCommand, PI_CMD_PIGPV, 0, 0);
+ 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 callback(int gpio, int edge, CBFunc_t f)
+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)
{
- return intCallback(gpio, edge, f, 0, 0);
+ 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 callback_ex(int gpio, int edge, CBFuncEx_t f, void *user)
+int store_script(char *script)
{
- return intCallback(gpio, edge, f, user, 1);
+ 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);}
+
+int callback_ex(int gpio, int edge, CBFuncEx_t f, void *user)
+ {return intCallback(gpio, edge, f, user, 1);}
+
int callback_cancel(int id)
{
callback_t *p;
#include "pigpio.h"
-#define PIGPIOD_IF_VERSION 1
+#define PIGPIOD_IF_VERSION 2
typedef enum
{
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.
The real value set by set_PWM_range is
(dutycycle * real range) / range.
-
*/
int get_PWM_range(int user_gpio);
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
*/
/*
-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>
#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;
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();
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;
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);
from distutils.core import setup
setup(name='pigpio',
- version='1.1',
+ version='1.2',
author='joan',
author_email='joan@abyz.me.uk',
maintainer='joan',
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']
)