diff --git a/MakeRemote b/MakeRemote
index e0f6361..c27fc64 100644
--- a/MakeRemote
+++ b/MakeRemote
@@ -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
diff --git a/Makefile b/Makefile
index 6ce0b3d..9b1e561 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/README b/README
index ba15cb6..8737d36 100644
--- a/README
+++ b/README
@@ -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
diff --git a/command.c b/command.c
index 80b3801..a128a9d 100644
--- a/command.c
+++ b/command.c
@@ -26,7 +26,7 @@ For more information, please refer to
*/
/*
-This version is for pigpio version 10+
+This version is for pigpio version 11+
*/
#include
@@ -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;
diff --git a/command.h b/command.h
index 6ace8c7..bdffefb 100644
--- a/command.h
+++ b/command.h
@@ -26,7 +26,7 @@ For more information, please refer to
*/
/*
-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
+
diff --git a/pigpio.c b/pigpio.c
index 510b45a..2c37817 100644
--- a/pigpio.c
+++ b/pigpio.c
@@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to
*/
-/* pigpio version 10 */
+/* pigpio version 11 */
#include
#include
@@ -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<= 0)) res = PI_SOME_PERMITTED;
+
break;
- case PI_CMD_PIGPV:
- res = gpioVersion();
+ case PI_CMD_WVAS:
+ if (gpioMask & (uint64_t)(1<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< bitDelay[0]) wf[2][p].usDelay = offset;
+ else wf[2][p].usDelay = bitDelay[0];
for (i=0; i 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)
diff --git a/pigpio.h b/pigpio.h
index f4faaa0..cf91696 100644
--- a/pigpio.h
+++ b/pigpio.h
@@ -26,7 +26,7 @@ For more information, please refer to
*/
/*
-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
#include
-#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 */
/*-------------------------------------------------------------------------*/
diff --git a/pigpio.py b/pigpio.py
index c9e4be5..0b40af8 100644
--- a/pigpio.py
+++ b/pigpio.py
@@ -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<
*/
/*
-This version is for pigpio version 7+
+This version is for pigpio version 11+
*/
#include
@@ -34,6 +34,7 @@ This version is for pigpio version 7+
#include
#include
#include
+#include
#include
#include
#include
@@ -43,7 +44,6 @@ This version is for pigpio version 7+
#include
#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);
diff --git a/pigpiod_if.c b/pigpiod_if.c
index 6f095cb..e6884fd 100644
--- a/pigpiod_if.c
+++ b/pigpiod_if.c
@@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to
*/
-/* PIGPIOD_IF_VERSION 1 */
+/* PIGPIOD_IF_VERSION 2 */
#include
#include
@@ -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
#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
diff --git a/pigs.c b/pigs.c
index 7115304..4cd84c2 100644
--- a/pigs.c
+++ b/pigs.c
@@ -26,11 +26,12 @@ For more information, please refer to
*/
/*
-This version is for pigpio version 7+
+This version is for pigpio version 11+
*/
#include
#include
+#include
#include
#include
#include
@@ -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