This commit is contained in:
joan 2014-03-13 15:50:23 +00:00
parent 8794220811
commit 78bbfe4668
16 changed files with 5017 additions and 721 deletions

View File

@ -13,17 +13,22 @@ OBJ2 = pigpiod_if.o command.o
LIB = $(LIB1) $(LIB2)
ALL = $(LIB) checklib pig2vcd pigpiod pigs
ALL = $(LIB) x_pigpio x_pigpiod_if pig2vcd pigpiod pigs
LL = -L. -lpigpio -lpthread -lrt
LL1 = -L. -lpigpio -lpthread -lrt
LL2 = -L. -lpigpiod_if -lpthread -lrt
all: $(ALL)
checklib: checklib.o $(LIB1)
$(CC) -o checklib checklib.c $(LL)
x_pigpio: x_pigpio.o $(LIB1)
$(CC) -o x_pigpio x_pigpio.c $(LL1)
x_pigpiod_if: x_pigpiod_if.o $(LIB2)
$(CC) -o x_pigpiod_if x_pigpiod_if.c $(LL2)
pigpiod: pigpiod.o $(LIB1)
$(CC) -o pigpiod pigpiod.c $(LL)
$(CC) -o pigpiod pigpiod.c $(LL1)
pigs: pigs.o command.o
$(CC) -o pigs pigs.c command.c
@ -35,6 +40,7 @@ clean:
rm -f *.o *.i *.s *~ $(ALL)
install: $(LIB)
sudo install -m 0755 -d /opt/pigpio/cgi
sudo install -m 0755 -d /usr/local/include
sudo install -m 0644 pigpio.h /usr/local/include
sudo install -m 0644 pigpiod_if.h /usr/local/include
@ -68,7 +74,8 @@ $(LIB2): $(OBJ2)
# generated using gcc -MM *.c
checklib.o: checklib.c pigpio.h
x_pigpio.o: x_pigpio.c pigpio.h
x_pigpiod_if.o: x_pigpiod_if.c
command.o: command.c pigpio.h command.h
pig2vcd.o: pig2vcd.c pigpio.h
pigpio.o: pigpio.c pigpio.h command.h

41
README
View File

@ -20,18 +20,28 @@ o the socket interface (pigs) in /usr/local/bin
o the utility pig2vcd in /usr/local/bin
o the Python module pigpio.py
TEST
TEST (optional)
To test the library do
sudo ./checklib
sudo ./x_pigpio
To text the pigpio daemon do
sudo pigpiod
./x_pigpiod_if # test the C I/F to the pigpio daemon
./x_pigpio.py # test the Python I/F to the pigpio daemon
./x_pigs # test the socket I/F to the pigpio daemon
./x_pipe # test the pipe I/F to the pigpio daemon
EXAMPLE CODE
checklib.c, pig2vcd.c, and pigpiod.c
show examples of interfacing with the pigpio library.
x_pigpio.c, pig2vcd.c, and pigpiod.c show examples of interfacing
with the pigpio library.
pigs.c and pigpio.py show examples of interfacing with the pigpiod daemon.
pigs.c, pigpio.py, x_pigpiod_if.c, x_pigpio.py, x_pigs, and x_pipe
show examples of interfacing with the pigpiod daemon.
DAEMON
@ -77,25 +87,6 @@ pythonx.y setup.py install
where x.y is the Python version.
If the pigpiod daemon is running you can test the Python module
by entering the following commands.
python
import pigpio
pigpio.start()
print(pigpio.get_current_tick())
print(hex(pigpio.read_bank_1()))
pigpio.stop()
help(pigpio)
quit()
STOP DAEMON
To stop the pigpiod daemon
@ -105,7 +96,7 @@ sudo killall pigpiod
RUNNING ON NON Pi's
You can access the pigpiod daemon running on the Pi from any machine which
can access it over the network. This access is via the socket interface.
is connected to it over the network. This access is via the socket interface.
In particular this allows you to use the following on non-Pi's.

544
command.c
View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 12+
This version is for pigpio version 13+
*/
#include <stdio.h>
@ -58,112 +58,175 @@ This version is for pigpio version 12+
7 cmd %x
8 MODES %d %c
9 PUD %d %c
10 PROG %s
10 PROC %s
11 WVAS %d %d %d %s
12 PROCR %d [%d]*10
13 WVAG %d %d %d [%d %d %d]*160
20 cmd m(0-150)
21 cmd v
22 cmd L
23 cmd
24 cmd m1(0-150) m2(0-150)
25 cmd p(0-9)
*/
cmdInfo_t cmdInfo[]=
{
/* num str vfyt retv ext */
/* num str vfyt retv */
{PI_CMD_BC1, "BC1", 7, 1},
{PI_CMD_BC2, "BC2", 7, 1},
{PI_CMD_BR1, "BR1", 1, 3},
{PI_CMD_BR2, "BR2", 1, 3},
{PI_CMD_BS1, "BS1", 7, 1},
{PI_CMD_BS2, "BS2", 7, 1},
{PI_CMD_HELP, "H", 6, 5},
{PI_CMD_HELP, "HELP", 6, 5},
{PI_CMD_HWVER, "HWVER", 1, 4},
{PI_CMD_MICRO, "MICRO", 21, 0},
{PI_CMD_MILLI, "MILLI", 21, 0},
{PI_CMD_MODEG, "MG" , 2, 2},
{PI_CMD_MODEG, "MODEG", 2, 2},
{PI_CMD_MODES, "M", 8, 0},
{PI_CMD_MODES, "MODES", 8, 0},
{PI_CMD_NB, "NB", 4, 0},
{PI_CMD_NC, "NC", 2, 0},
{PI_CMD_NO, "NO", 1, 2},
{PI_CMD_NP, "NP", 2, 0},
{PI_CMD_PFG, "PFG", 2, 2},
{PI_CMD_PFS, "PFS", 3, 2},
{PI_CMD_PIGPV, "PIGPV", 1, 4},
{PI_CMD_PRG, "PRG", 2, 2},
{PI_CMD_PROC, "PROC", 10, 2},
{PI_CMD_PROCD, "PROCD", 2, 2},
{PI_CMD_PROCP, "PROCP", 2, 7},
{PI_CMD_PROCR, "PROCR",12, 2},
{PI_CMD_PROCS, "PROCS", 2, 2},
{PI_CMD_PRRG, "PRRG", 2, 2},
{PI_CMD_PRS, "PRS", 3, 2},
{PI_CMD_PUD, "PUD", 9, 0},
{PI_CMD_PWM, "P", 3, 0},
{PI_CMD_PWM, "PWM", 3, 0},
{PI_CMD_READ, "R", 2, 2},
{PI_CMD_READ, "READ", 2, 2},
{PI_CMD_SERVO, "S", 3, 0},
{PI_CMD_SERVO, "SERVO", 3, 0},
{PI_CMD_SLR, "SLR", 3, 6},
{PI_CMD_SLRC, "SLRC", 2, 2},
{PI_CMD_SLRO, "SLRO", 3, 2},
{PI_CMD_TICK, "T", 1, 4},
{PI_CMD_TICK, "TICK", 1, 4},
{PI_CMD_TRIG, "TRIG", 5, 0},
{PI_CMD_WDOG, "WDOG", 3, 0},
{PI_CMD_WRITE, "W", 3, 0},
{PI_CMD_WRITE, "WRITE", 3, 0},
{PI_CMD_WVAG, "WVAG", 13, 2},
{PI_CMD_WVAS, "WVAS", 11, 2},
{PI_CMD_WVBSY, "WVBSY", 1, 2},
{PI_CMD_WVCLR, "WVCLR", 1, 2},
{PI_CMD_WVGO, "WVGO" , 1, 2},
{PI_CMD_WVGOR, "WVGOR", 1, 2},
{PI_CMD_WVHLT, "WVHLT", 1, 2},
{PI_CMD_WVSC, "WVSC", 2, 2},
{PI_CMD_WVSM, "WVSM", 2, 2},
{PI_CMD_WVSP, "WVSP", 2, 2},
{PI_CMD_ADDI , "ADDI" , 21, 0},
{PI_CMD_ADDV , "ADDV" , 20, 0},
{PI_CMD_ANDI , "ANDI" , 21, 0},
{PI_CMD_ANDV , "ANDV" , 20, 0},
{PI_CMD_CALL , "CALL" , 22, 0},
{PI_CMD_CMPI , "CMPI" , 21, 0},
{PI_CMD_CMPV , "CMPV" , 20, 0},
{PI_CMD_DCRA , "DCRA" , 23, 0},
{PI_CMD_DCRV , "DCRV" , 20, 0},
{PI_CMD_HALT , "HALT" , 23, 0},
{PI_CMD_INRA , "INRA" , 23, 0},
{PI_CMD_INRV , "INRV" , 20, 0},
{PI_CMD_JM , "JM" , 22, 0},
{PI_CMD_JMP , "JMP" , 22, 0},
{PI_CMD_JNZ , "JNZ" , 22, 0},
{PI_CMD_JP , "JP" , 22, 0},
{PI_CMD_JZ , "JZ" , 22, 0},
{PI_CMD_LABEL, "LABEL", 22, 0},
{PI_CMD_LDAI , "LDAI" , 21, 0},
{PI_CMD_LDAP , "LDAP" , 25, 0},
{PI_CMD_LDAV , "LDAV" , 20, 0},
{PI_CMD_LDPA , "LDPA" , 25, 0},
{PI_CMD_LDVA , "LDVA" , 20, 0},
{PI_CMD_LDVI , "LDVI" , 28, 0},
{PI_CMD_LDVV , "LDVV" , 24, 0},
{PI_CMD_ORI , "ORI" , 21, 0},
{PI_CMD_ORV , "ORV" , 20, 0},
{PI_CMD_POPA , "POPA" , 23, 0},
{PI_CMD_POPV , "POPV" , 20, 0},
{PI_CMD_PUSHA, "PUSHA", 23, 0},
{PI_CMD_PUSHV, "PUSHV", 20, 0},
{PI_CMD_RET , "RET" , 23, 0},
{PI_CMD_RAL , "RAL" , 21, 0},
{PI_CMD_RAR , "RAR" , 21, 0},
{PI_CMD_SUBI , "SUBI" , 21, 0},
{PI_CMD_SUBV , "SUBV" , 20, 0},
{PI_CMD_SWAPA, "SWAPA", 20, 0},
{PI_CMD_SWAPV, "SWAPV", 24, 0},
{PI_CMD_SYS , "SYS" , 27, 0},
{PI_CMD_WAITI, "WAITI", 21, 0},
{PI_CMD_WAITV, "WAITV", 20, 0},
{PI_CMD_XORI , "XORI" , 21, 0},
{PI_CMD_XORV , "XORV" , 20, 0},
{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_SLR, "SLR", 3, 6, 0},
{PI_CMD_SLRC, "SLRC", 2, 2, 0},
{PI_CMD_SLRO, "SLRO", 3, 2, 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 = "\
BC1 x Clear gpios x in bank 1.\n\
BC2 x Clear gpios x in bank 2.\n\
BC1 v Clear gpios defined by mask v in bank 1.\n\
BC2 v Clear gpios defined by mask v in bank 2.\n\
BR1 Read gpios bank 1.\n\
BR2 Read gpios bank 2.\n\
BS1 x Set gpios x in bank 1.\n\
BS2 x Set gpios x in bank 2.\n\
BS1 v Set gpios defined by mask v in bank 1.\n\
BS2 v Set gpios defined by mask v in bank 2.\n\
H Displays command help.\n\
HELP Displays command help.\n\
HWVER Return hardware version.\n\
M g m Set gpio g to mode m.\n\
MG g Get gpio g mode.\n\
MICRO v Delay for v microseconds.\n\
MILLI v Delay for v milliseconds.\n\
MODEG g Get gpio g mode.\n\
MODES g m Set gpio g to mode m.\n\
NB h x Start notifications on handle h with x.\n\
NB h v Start notifications on handle h for gpios defined by mask v.\n\
NC h Close notification handle h.\n\
NO Request notification handle.\n\
NP h Pause notifications on handle h.\n\
P u d Set PWM value for user gpio u to d.\n\
P u v Set PWM value for user gpio u to d.\n\
PFG u Get PWM frequency for user gpio u.\n\
PFS u d Set PWM frequency for user gpio u to d.\n\
PFS u v Set PWM frequency for user gpio u to d.\n\
PIGPV Return pigpio version.\n\
PRG u Get PWM range for user gpio u.\n\
PROC t Store text t of script.\n\
PROCD s Delete script s.\n\
PROCR s Run script s.\n\
PROCP s Get current status and parameter values for script s.\n\
PROCR s pars Run script s with up to 10 optional parameters.\n\
PROCS s Stop script s.\n\
PRRG u Get PWM real range for user gpio u.\n\
PRS u d Set PWM range for user gpio u to d.\n\
PRS u v Set PWM range for user gpio u to d.\n\
PUD g p Set gpio pull up/down for gpio g to p.\n\
PWM u d Set PWM value for user gpio u to d.\n\
PWM u v Set PWM value for user gpio u to d.\n\
R g Read gpio g.\n\
READ g Read gpio g.\n\
S u d Set servo value for user gpio u to d microseconds.\n\
SERVO u d Set servo value for user gpio u to d microseconds.\n\
SLR u d Read up to d bytes of serial data from user gpio u.\n\
S u v Set servo value for user gpio u to d microseconds.\n\
SERVO u v Set servo value for user gpio u to d microseconds.\n\
SLR u v Read up to d bytes of serial data from user gpio u.\n\
SLRC u Close user gpio u for serial data.\n\
SLRO u b Open user gpio u for serial data at b baud.\n\
T Return current tick.\n\
TICK Return current tick.\n\
TRIG u pl L Trigger level L for pl micros on user gpio u.\n\
W g L Write level L to gpio g.\n\
WDOG u d Set watchdog of d milliseconds on user gpio u.\n\
WDOG u v Set watchdog of d milliseconds on user gpio u.\n\
WRITE g L Write level L to gpio g.\n\
WVAG pulses Wave add generic pulses.\n\
WVAS u b o t Wave add serial data t to user gpio u at b baud.\n\
WVBSY Check if wave busy.\n\
WVCLR Wave clear.\n\
@ -173,20 +236,26 @@ WVHLT Wave stop.\n\
WVSC ws Wave get DMA control block stats.\n\
WVSM ws Wave get micros stats.\n\
WVSP ws Wave get pulses stats.\n\
.\n\
\n\
b = baud rate.\n\
d = decimal value.\n\
g = gpio (0-53).\n\
g = any gpio (0-53).\n\
h = handle (0-31).\n\
L = level (0-1).\n\
m = mode (RW540123).\n\
mask = a bit mask where (1<<g) is set for each gpio g of interest.\n\
o = offset (0-).\n\
p = pud (ODU).\n\
pars = 0 to 10 parameters for script.\n\
pl = pulse length (0-100).\n\
s = script id.\n\
pulses = 1 or more triplets of gpios on, gpios off, delay.\n\
s = script id (0-31).\n\
t = text.\n\
u = user gpio (0-31).\n\
x = hex value.\n\
v = value.\n\
ws = 0=now, 1=high, 2=max.\n\
\n\
Numbers may be entered as hex (prefix 0x), octal (prefix 0),\n\
otherwise they are assumed to be decimal.\n\
";
typedef struct
@ -248,6 +317,18 @@ static errInfo_t errInfo[]=
{PI_BAD_SER_OFFSET , "add serial data offset > 30 minute"},
{PI_GPIO_IN_USE , "gpio already in use"},
{PI_BAD_SERIAL_COUNT , "must read at least a byte at a time"},
{PI_BAD_PARAM_NUM , "script parameter must be 0-9"},
{PI_DUP_LABEL , "script has duplicate label"},
{PI_TOO_MANY_LABELS , "script has too many labels"},
{PI_BAD_SCRIPT_CMD , "illegal script command"},
{PI_BAD_VAR_NUM , "script variable must be 0-149"},
{PI_NO_SCRIPT_ROOM , "no more room for scripts"},
{PI_NO_MEMORY , "can't allocate temporary memory"},
{PI_SOCK_READ_FAILED , "socket read failed"},
{PI_SOCK_WRIT_FAILED , "socket write failed"},
{PI_TOO_MANY_PARAM , "too many script parameters > 10"},
{PI_NOT_HALTED , "script already running or failed"},
};
static char * fmtMdeStr="RW540123";
@ -264,65 +345,117 @@ static int cmdMatch(char * str)
return -1;
}
int cmdParse(char *buf, cmdCmd_t *cmd, int argc, char *argv[], gpioExtent_t *ext)
static int getNum(char *str, unsigned *val, uint8_t *opt, int flags)
{
char str[8];
int f, valid, idx, val, p;
int f, n, v;
*opt = 0;
f = sscanf(str, " %i %n", &v, &n);
if (f == 1)
{
*val = v;
*opt = CMD_NUMERIC;
return n;
}
if (flags & PARSE_FLAGS_PARAMS)
{
f = sscanf(str, " p%i %n", &v, &n);
if (f == 1)
{
*val = v;
*opt = CMD_PARAM;
return n;
}
}
if (flags & PARSE_FLAGS_VARS)
{
f = sscanf(str, " v%i %n", &v, &n);
if (f == 1)
{
*val = v;
*opt = CMD_VAR;
return n;
}
}
return 0;
}
static char intCmdStr[32];
char *cmdStr(void)
{
return intCmdStr;
}
int cmdParse(char *buf, uint32_t *p, void **v, gpioCtlParse_t *ctl)
{
int f, valid, idx, val, pp, pars, n, n2, i;
char *ptr;
char c, t;
char c;
int param[MAX_PARAM];
sscanf(buf, " %7s", str);
bzero(&ctl->opt, sizeof(ctl->opt));
cmd->cmd = -1;
sscanf(buf+ctl->eaten, " %31s", intCmdStr);
idx = cmdMatch(str);
p[0] = -1;
idx = cmdMatch(intCmdStr);
if (idx < 0) return idx;
sscanf(buf+ctl->eaten, " %*31s %n", &pp);
ctl->eaten += pp;
valid = 0;
cmd->cmd = cmdInfo[idx].cmd;
cmd->p1 = 0;
cmd->p2 = 0;
p[0] = cmdInfo[idx].cmd;
p[1] = 0;
p[2] = 0;
switch (cmdInfo[idx].vt)
{
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;
valid = 1;
break;
case 2: /* MODEG NC NP PFG PRG PROCD PROCR PROCS PRRG
case 2: /* MODEG NC NP PFG PRG PROCD PROCS PRRG
SLRC READ WVSC WVSM WVSP
*/
f = sscanf(buf, " %7s %d %c", str, &cmd->p1, &t);
if (f == 2) valid = 1;
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], ctl->flags);
if (ctl->opt[0]) valid = 1;
break;
case 3: /* PFS PRS PWM SERVO SLR SLRO WDOG WRITE
*/
f = sscanf(buf, " %7s %d %d %c", str, &cmd->p1, &cmd->p2, &t);
if (f == 3) valid = 1;
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], ctl->flags);
ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[1], ctl->flags);
if (ctl->opt[0] && ctl->opt[1]) valid = 1;
break;
case 4: /* NB
*/
f = sscanf(buf, " %7s %d %x %c", str, &cmd->p1, &cmd->p2, &t);
if (f == 3) valid = 1;
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], ctl->flags);
ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[1], ctl->flags);
if (ctl->opt[0] && ctl->opt[1]) valid = 1;
break;
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].size = sizeof(unsigned);
ext[0].ptr = &ext[0].data;
valid = 1;
}
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], ctl->flags);
ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[1], ctl->flags);
ctl->eaten += getNum(buf+ctl->eaten, &p[3], &ctl->opt[2], ctl->flags);
if (ctl->opt[0] && ctl->opt[1] && ctl->opt[2]) valid = 1;
break;
case 6: /* HELP
@ -332,21 +465,23 @@ int cmdParse(char *buf, cmdCmd_t *cmd, int argc, char *argv[], gpioExtent_t *ext
case 7: /* BC1 BC2 BS1 BS2
*/
f = sscanf(buf, " %7s %x %c", str, &cmd->p1, &t);
if (f == 2) valid = 1;
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], ctl->flags);
if (ctl->opt[0]) valid = 1;
break;
case 8: /* MODES
*/
f = sscanf(buf, " %7s %d %c %c", str, &cmd->p1, &c, &t);
if (f == 3)
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], ctl->flags);
f = sscanf(buf+ctl->eaten, " %c %n", &c, &n);
if (ctl->opt[0] && (f >= 1))
{
ctl->eaten += n;
val = toupper(c);
ptr = strchr(fmtMdeStr, val);
if (ptr != NULL)
{
val = ptr - fmtMdeStr;
cmd->p2 = val;
p[2] = val;
valid = 1;
}
}
@ -354,15 +489,17 @@ int cmdParse(char *buf, cmdCmd_t *cmd, int argc, char *argv[], gpioExtent_t *ext
case 9: /* PUD
*/
f = sscanf(buf, " %7s %d %c %c", str, &cmd->p1, &c, &t);
if (f == 3)
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], ctl->flags);
f = sscanf(buf+ctl->eaten, " %c %n", &c, &n);
if (ctl->opt[0] && (f >= 1))
{
ctl->eaten += n;
val = toupper(c);
ptr = strchr(fmtPudStr, val);
if (ptr != NULL)
{
val = ptr - fmtPudStr;
cmd->p2 = val;
p[2] = val;
valid = 1;
}
}
@ -370,51 +507,167 @@ int cmdParse(char *buf, cmdCmd_t *cmd, int argc, char *argv[], gpioExtent_t *ext
case 10: /* PROC
*/
if ((argc == 0) || (argc == 3))
{
if (argc == 3)
{
cmd->p1 = strlen(argv[2]);
ext[0].ptr = argv[2];
}
else /* pipe i/f */
{
sscanf(buf, "%*s %n", &p);
cmd->p1 = strlen(buf+p);
ext[0].ptr = buf+p;
}
ext[0].size = cmd->p1;
p[1] = strlen(buf+ctl->eaten);
v[1] = buf+ctl->eaten;
ctl->eaten += p[1];
valid = 1;
}
break;
case 11: /* WVAS
*/
if ((argc == 0) || (argc == 6))
{
f = sscanf(buf, " %*s %d %d %d %n",
&cmd->p1, &ext[0].data, &ext[1].data, &p);
if (f == 3)
{
ext[0].size = sizeof(unsigned);
ext[0].ptr = &ext[0].data;
ext[1].size = sizeof(unsigned);
ext[1].ptr = &ext[1].data;
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], ctl->flags);
ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[1], ctl->flags);
ctl->eaten += getNum(buf+ctl->eaten, &p[3], &ctl->opt[2], ctl->flags);
if (argc) /* pigs */
if (ctl->opt[0] && ctl->opt[1] && ctl->opt[2])
{
cmd->p2 = strlen(argv[5]);
ext[2].ptr = argv[5];
}
else /* pipe i/f */
{
cmd->p2 = strlen(buf+p);
ext[2].ptr = buf+p;
}
ext[2].size = cmd->p2;
p[4] = strlen(buf+ctl->eaten);
v[1] = buf+ctl->eaten;
ctl->eaten += p[4];
valid = 1;
}
break;
case 12: /* PROCR
*/
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], 0);
pars = 0;
while (pars < 10)
{
ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[1], 0);
if (ctl->opt[1]) param[pars++] = p[2];
else break;
}
p[2] = pars;
v[1] = param;
if (ctl->opt[0]) valid = 1;
break;
case 13: /* WVAG
*/
pars = 0;
while (pars < MAX_PARAM)
{
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], 0);
if (ctl->opt[0]) param[pars++] = p[1];
else break;
}
p[1] = pars/3;
v[1] = param;
if (pars && ((pars%3)==0)) valid = 1;
break;
case 20: /*
*/
f = sscanf(buf+ctl->eaten, " %d %n", &p[1], &n);
if ((f >= 1) && (p[1] >= 0) && (p[1] < MAX_SCRIPT_VARS))
{
ctl->eaten += n;
valid = 1;
}
break;
case 21: /*
*/
f = sscanf(buf+ctl->eaten, " %d %n", &p[1], &n);
if (f == 1)
{
ctl->eaten += n;
valid = 1;
}
break;
case 22: /*
*/
f = sscanf(buf+ctl->eaten, " %d %n", &p[1], &n);
if (f == 1)
{
ctl->eaten += n;
valid = 1;
}
break;
case 23: /*
*/
valid = 1;
break;
case 24: /*
*/
f = sscanf(buf+ctl->eaten, " %d %d %n", &p[1], &p[2], &n);
if ((f >= 2) &&
(p[1] >= 0) && (p[1] < MAX_SCRIPT_VARS) &&
(p[2] >= 0) && (p[2] < MAX_SCRIPT_VARS))
{
ctl->eaten += n;
valid = 1;
}
break;
case 25: /*
*/
f = sscanf(buf+ctl->eaten, " %d %n", &p[1], &n);
if ((f >= 1) && (p[1] >= 0) && (p[1] < MAX_SCRIPT_PARAMS))
{
ctl->eaten += n;
valid = 1;
}
break;
case 26: /*
*/
f = sscanf(buf+ctl->eaten, " %d %n", &p[1], &n);
if (f >= 1)
{
ctl->eaten += n;
valid = 1;
}
break;
case 27: /*
*/
f = sscanf(buf+ctl->eaten, " %*s%n %n", &n, &n2);
if ((f >= 0) && n)
{
valid = 1;
for (i=0; i<n; i++)
{
c = buf[ctl->eaten+i];
if ((!isalnum(c)) && (c != '_') && (c != '-'))
{
valid = 0;
break;
}
}
if (valid)
{
p[1] = n;
ctl->opt[0] = CMD_NUMERIC;
v[1]=buf+ctl->eaten;
ctl->eaten += n2;
}
}
break;
case 28: /*
*/
f = sscanf(buf+ctl->eaten, " %d %d %n", &p[1], &p[2], &n);
if ((f >= 2) && (p[1] >= 0) && (p[1] < MAX_SCRIPT_VARS))
{
ctl->eaten += n;
valid = 1;
}
break;
}
@ -432,3 +685,4 @@ char * cmdErrStr(int error)
}
return "unknown error";
}

View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 11+
This version is for pigpio version 13+
*/
#ifndef COMMAND_H
@ -37,23 +37,39 @@ This version is for pigpio version 11+
#include "pigpio.h"
#define MAX_PARAM 512
#define PARSE_FLAGS_PARAMS 1
#define PARSE_FLAGS_VARS 2
#define CMD_NUMERIC 1
#define CMD_PARAM 2
#define CMD_VAR 3
typedef struct
{
int flags;
int eaten;
uint8_t opt[8];
} gpioCtlParse_t;
typedef struct
{
int cmd; /* command number */
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 argc, char *argv[], gpioExtent_t * ext);
int cmdParse(char *buf, uint32_t *p, void **v, gpioCtlParse_t *ctlParse);
char *cmdErrStr(int error);
char *cmdStr(void);
#endif

1738
pigpio.c

File diff suppressed because it is too large Load Diff

234
pigpio.h
View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 12
This version is for pigpio version 13
*/
#ifndef PIGPIO_H
@ -86,7 +86,7 @@ This version is for pigpio version 12
#include <stdint.h>
#include <pthread.h>
#define PIGPIO_VERSION 12
#define PIGPIO_VERSION 13
/*-------------------------------------------------------------------------*/
@ -164,6 +164,7 @@ gpioStopThread Stop a previously started thread.
gpioStoreScript Store a script.
gpioRunScript Run a stored script.
gpioScriptStatus Get script status and parameters.
gpioStopScript Stop a running script.
gpioDeleteScript Delete a stored script.
@ -217,6 +218,12 @@ gpioCfgSocketPort Configure socket port.
extern "C" {
#endif
typedef struct
{
uint16_t func;
uint16_t size;
} gpioHeader_t;
typedef struct
{
uint32_t cmd;
@ -229,7 +236,7 @@ typedef struct
{
size_t size;
void *ptr;
int data;
uint32_t data;
} gpioExtent_t;
typedef struct
@ -253,6 +260,29 @@ typedef struct
uint32_t usDelay;
} gpioPulse_t;
#define WAVE_FLAG_READ 1
#define WAVE_FLAG_TICK 2
typedef struct
{
uint32_t gpioOn;
uint32_t gpioOff;
uint32_t usDelay;
uint32_t flags;
} gpioWave_t;
typedef struct
{
int clk; /* gpio for clock */
int mosi; /* gpio for MOSI */
int miso; /* gpio for MISO */
int ss_pol; /* slave select off state */
int ss_us; /* delay after slave select */
int clk_pol; /* clock off state */
int clk_pha; /* clock phase */
int clk_us; /* clock micros */
} gpioSPI_t;
typedef void (*gpioAlertFunc_t) (int gpio,
int level,
uint32_t tick);
@ -768,6 +798,8 @@ int gpioNotifyOpen(void);
handle.
*/
#define PI_NOTIFY_SLOTS 32
/*-------------------------------------------------------------------------*/
@ -915,7 +947,7 @@ int gpioWaveAddSerial(unsigned user_gpio,
the same waveform.
*/
#define PI_WAVE_BLOCKS 3
#define PI_WAVE_BLOCKS 4
#define PI_WAVE_MAX_PULSES (PI_WAVE_BLOCKS * 3000)
#define PI_WAVE_MAX_CHARS (PI_WAVE_BLOCKS * 256)
@ -924,8 +956,6 @@ int gpioWaveAddSerial(unsigned user_gpio,
#define PI_WAVE_MAX_MICROS (30 * 60 * 1000000) /* half an hour */
/*-------------------------------------------------------------------------*/
int gpioWaveTxStart(unsigned mode);
/*-------------------------------------------------------------------------*/
@ -1321,18 +1351,53 @@ int gpioStoreScript(char *script);
otherwise PI_BAD_SCRIPT.
*/
#define MAX_SCRIPT_LABELS 50
#define MAX_SCRIPT_VARS 150
#define MAX_SCRIPT_PARAMS 10
/* ----------------------------------------------------------------------- */
int gpioRunScript(int script_id);
int gpioRunScript(int script_id, unsigned numParam, uint32_t *param);
/* ----------------------------------------------------------------------- */
/* This function runs a stored script.
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID, or
PI_TOO_MANY_PARAM.
param is an array of up to 10 parameters which may be referenced in
the script as param 0 to param 9.
*/
/* ----------------------------------------------------------------------- */
int gpioScriptStatus(int script_id, uint32_t *param);
/* ----------------------------------------------------------------------- */
/* This function returns the run status of a stored script as well as
the current values of parameters 0 to 9.
The function returns greater than or equal to 0 if OK,
otherwise PI_BAD_SCRIPT_ID.
The run status may be
PI_SCRIPT_HALTED
PI_SCRIPT_RUNNING
PI_SCRIPT_WAITING
PI_SCRIPT_FAILED
The current value of script parameters 0 to 9 are returned in param.
*/
/* script status */
#define PI_SCRIPT_HALTED 0
#define PI_SCRIPT_RUNNING 1
#define PI_SCRIPT_WAITING 2
#define PI_SCRIPT_FAILED 3
/* ----------------------------------------------------------------------- */
int gpioStopScript(int script_id);
/* ----------------------------------------------------------------------- */
@ -1798,12 +1863,98 @@ int gpioCfgInternals(unsigned what,
Not intended for general use.
*/
/*-------------------------------------------------------------------------*/
int gpioWaveAddSPI(
gpioSPI_t *spi,
unsigned offset,
unsigned ss,
uint8_t *tx_bits,
unsigned num_tx_bits,
unsigned rx_bit_first,
unsigned rx_bit_last,
unsigned bits);
/*-------------------------------------------------------------------------*/
/* This function adds a waveform representing SPI data to the
existing waveform (if any). The SPI data starts offset microseconds
from the start of the waveform. ss is the slave select gpio. bits bits
are transferred. num_tx_bits are transmitted starting at the first bit.
The bits to transmit are read, most significant bit first, from tx_bits.
Gpio reads are made from rx_bit_first to rx_bit_last.
Returns the new total number of pulses in the current waveform if OK,
otherwise PI_BAD_USER_GPIO, PI_BAD_SER_OFFSET, or PI_TOO_MANY_PULSES.
*/
/* ----------------------------------------------------------------------- */
uint32_t waveGetRawOut(int pos);
/* ----------------------------------------------------------------------- */
/* Gets the wave output parameter stored at pos.
Not intended for general use.
*/
/* ----------------------------------------------------------------------- */
void waveSetRawOut(int pos, uint32_t value);
/* ----------------------------------------------------------------------- */
/* Sets the wave output parameter stored at pos to value.
Not intended for general use.
*/
/* ----------------------------------------------------------------------- */
uint32_t waveGetRawIn(int pos);
/* ----------------------------------------------------------------------- */
/* Gets the wave input value parameter stored at pos.
Not intended for general use.
*/
/* ----------------------------------------------------------------------- */
void waveSetRawIn(int pos, uint32_t value);
/* ----------------------------------------------------------------------- */
/* Sets the wave input value stored at pos to value.
Not intended for general use.
*/
/*-------------------------------------------------------------------------*/
int getBitInBytes(int bitPos, uint8_t *buf, int numBits);
/*-------------------------------------------------------------------------*/
/* Returns the value of the bit bitPos bits from the start of buf. Returns
0 if bitPos is greater than or equal to numBits.
*/
/* ----------------------------------------------------------------------- */
void putBitInBytes(int bitPos, uint8_t *buf, int val);
/*-------------------------------------------------------------------------*/
/* Sets the bit bitPos bits from the start of buf to val.
*/
/*-------------------------------------------------------------------------*/
double time_time(void);
/*-------------------------------------------------------------------------*/
/* Return the current time in seconds since the Epoch.
*/
/*-------------------------------------------------------------------------*/
void gpioWaveDump(void);
void time_sleep(double seconds);
/*-------------------------------------------------------------------------*/
/* Used to print a readable version of the current waveform to stdout.
/* Delay execution for a given number of seconds
*/
/*-------------------------------------------------------------------------*/
void gpioDumpWave(void);
/*-------------------------------------------------------------------------*/
/* Used to print a readable version of the current waveform to stderr.
Not intended for general use.
*/
/*-------------------------------------------------------------------------*/
void gpioDumpScript(int s);
/*-------------------------------------------------------------------------*/
/* Used to print a readable version of a script to stderr.
Not intended for general use.
*/
@ -1859,6 +2010,10 @@ void gpioWaveDump(void);
#define PI_CMD_SLRO 42
#define PI_CMD_SLR 43
#define PI_CMD_SLRC 44
#define PI_CMD_PROCP 45
#define PI_CMD_MICRO 46
#define PI_CMD_MILLI 47
/*
The following command only works on the socket interface.
@ -1872,6 +2027,53 @@ after this command is issued.
#define PI_CMD_NOIB 99
/* pseudo commands */
#define PI_CMD_SCRIPT 800
#define PI_CMD_ADDI 800
#define PI_CMD_ADDV 801
#define PI_CMD_ANDI 802
#define PI_CMD_ANDV 803
#define PI_CMD_CALL 804
#define PI_CMD_CMPI 805
#define PI_CMD_CMPV 806
#define PI_CMD_DCRA 807
#define PI_CMD_DCRV 808
#define PI_CMD_HALT 809
#define PI_CMD_INRA 810
#define PI_CMD_INRV 811
#define PI_CMD_JM 812
#define PI_CMD_JMP 813
#define PI_CMD_JNZ 814
#define PI_CMD_JP 815
#define PI_CMD_JZ 816
#define PI_CMD_LABEL 817
#define PI_CMD_LDAI 818
#define PI_CMD_LDAP 819
#define PI_CMD_LDAV 820
#define PI_CMD_LDPA 821
#define PI_CMD_LDVA 822
#define PI_CMD_LDVI 823
#define PI_CMD_LDVV 824
#define PI_CMD_ORI 827
#define PI_CMD_ORV 828
#define PI_CMD_POPA 829
#define PI_CMD_POPV 830
#define PI_CMD_PUSHA 831
#define PI_CMD_PUSHV 832
#define PI_CMD_RET 833
#define PI_CMD_RAL 834
#define PI_CMD_RAR 835
#define PI_CMD_SUBI 836
#define PI_CMD_SUBV 837
#define PI_CMD_SWAPA 838
#define PI_CMD_SWAPV 839
#define PI_CMD_SYS 840
#define PI_CMD_WAITI 841
#define PI_CMD_WAITV 842
#define PI_CMD_XORI 843
#define PI_CMD_XORV 844
/*-------------------------------------------------------------------------*/
@ -1930,7 +2132,17 @@ after this command is issued.
#define PI_BAD_SER_OFFSET -49 /* add serial data offset > 30 minutes */
#define PI_GPIO_IN_USE -50 /* gpio already in use */
#define PI_BAD_SERIAL_COUNT -51 /* must read at least a byte at a time */
#define PI_BAD_PARAM_NUM -52 /* script parameter must be 0-9 */
#define PI_DUP_LABEL -53 /* script has duplicate label */
#define PI_TOO_MANY_LABELS -54 /* script has too many labels */
#define PI_BAD_SCRIPT_CMD -55 /* illegal script command */
#define PI_BAD_VAR_NUM -56 /* script variable must be 0-149 */
#define PI_NO_SCRIPT_ROOM -57 /* no more room for scripts */
#define PI_NO_MEMORY -58 /* can't allocate temporary memory */
#define PI_SOCK_READ_FAILED -59 /* socket read failed */
#define PI_SOCK_WRIT_FAILED -60 /* socket write failed */
#define PI_TOO_MANY_PARAM -61 /* too many script parameters > 10 */
#define PI_NOT_HALTED -62 /* script already running or failed */
/*-------------------------------------------------------------------------*/

View File

@ -76,7 +76,7 @@ import threading
import os
import atexit
VERSION = "1.3"
VERSION = "1.4"
# gpio levels
@ -113,6 +113,13 @@ PUD_OFF = 0
PUD_DOWN = 1
PUD_UP = 2
# script run status
PI_SCRIPT_HALTED =0
PI_SCRIPT_RUNNING=1
PI_SCRIPT_WAITING=2
PI_SCRIPT_FAILED =3
# pigpio command numbers
_PI_CMD_MODES= 0
@ -160,6 +167,7 @@ _PI_CMD_PROCS=41
_PI_CMD_SLRO= 42
_PI_CMD_SLR= 43
_PI_CMD_SLRC= 44
_PI_CMD_PROCP=45
_PI_CMD_NOIB= 99
@ -218,6 +226,18 @@ PI_BAD_SCRIPT =-47
PI_BAD_SCRIPT_ID =-48
PI_BAD_SER_OFFSET =-49
PI_GPIO_IN_USE =-50
PI_BAD_SERIAL_COUNT =-51
PI_BAD_PARAM_NUM =-52
PI_DUP_LABEL =-53
PI_TOO_MANY_LABELS =-54
PI_BAD_SCRIPT_CMD =-55
PI_BAD_VAR_NUM =-56
PI_NO_SCRIPT_ROOM =-57
PI_NO_MEMORY =-58
PI_SOCK_READ_FAILED =-59
PI_SOCK_WRIT_FAILED =-60
PI_TOO_MANY_PARAM =-61
PI_NOT_HALTED =-62
# pigpio error text
@ -270,6 +290,19 @@ _errors=[
[PI_BAD_SCRIPT_ID , "unknown script id"],
[PI_BAD_SER_OFFSET , "add serial data offset > 30 minute"],
[PI_GPIO_IN_USE , "gpio already in use"],
[PI_BAD_SERIAL_COUNT , "must read at least a byte at a time"],
[PI_BAD_PARAM_NUM , "script parameter must be 0-9"],
[PI_DUP_LABEL , "script has duplicate label"],
[PI_TOO_MANY_LABELS , "script has too many labels"],
[PI_BAD_SCRIPT_CMD , "illegal script command"],
[PI_BAD_VAR_NUM , "script variable must be 0-149"],
[PI_NO_SCRIPT_ROOM , "no more room for scripts"],
[PI_NO_MEMORY , "can't allocate temporary memory"],
[PI_SOCK_READ_FAILED , "socket read failed"],
[PI_SOCK_WRIT_FAILED , "socket write failed"],
[PI_TOO_MANY_PARAM , "too many script parameters (> 10)"],
[PI_NOT_HALTED , "script already running or failed"],
]
_control = None
@ -348,8 +381,8 @@ def _pigpio_command(sock, cmd, p1, p2):
sock: command socket.
cmd: the command to be executed.
p1: command paramter 1 (if applicable).
p2: command paramter 2 (if applicable).
p1: command parameter 1 (if applicable).
p2: command parameter 2 (if applicable).
"""
if sock is not None:
sock.send(struct.pack('IIII', cmd, p1, p2, 0))
@ -364,8 +397,8 @@ def _pigpio_command_ext(sock, cmd, p1, p2, extents):
sock: command socket.
cmd: the command to be executed.
p1: command paramter 1 (if applicable).
p2: command paramter 2 (if applicable).
p1: command parameter 1 (if applicable).
p2: command parameter 2 (if applicable).
extents: additional data blocks
"""
if sock is not None:
@ -1676,15 +1709,57 @@ def store_script(script):
return _u2i(_pigpio_command_ext(
_control, _PI_CMD_PROC, len(script), 0, script))
def run_script(script_id):
def run_script(script_id, params=None):
"""
Runs a stored script.
Returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
script_id: script_id of stored script.
params: up to 10 parameters required by the script.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_PROCR, script_id, 0))
# I p1 script id
# I p2 number of parameters (0-10)
## (optional) extension ##
# I[] params
if params is not None:
msg = ""
for p in params:
msg += struct.pack("I", p)
nump = len(params)
extents = [msg]
else:
nump = 0
extents = []
return _u2i(_pigpio_command_ext(
_control, _PI_CMD_PROCR, script_id, nump, extents))
def script_status(script_id):
"""
This function returns the run status of a stored script as well as
the current values of parameters 0 to 9.
The function returns greater than or equal to 0 if OK,
otherwise PI_BAD_SCRIPT_ID.
The run status may be
PI_SCRIPT_HALTED
PI_SCRIPT_RUNNING
PI_SCRIPT_WAITING
PI_SCRIPT_FAILED
It returns a tuple of run status and a parameter list tuple. If the script
does not exist a negative error code will be returned in which
case the parameter tuple will be empty.
"""
status = _u2i(_pigpio_command(_control, _PI_CMD_PROCP, script_id, 0))
if status >= 0:
param = struct.unpack('IIIIIIIIII', _control.recv(40))
return status, param
return status, ()
def stop_script(script_id):
"""
@ -2015,7 +2090,8 @@ def start(host = os.getenv("PIGPIO_ADDR", ''),
print("Did you specify the correct Pi host/port in the")
print("pigpio.start() function? E.g. pigpio.start('soft', 8888))")
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
raise
return False
return True
def stop():
"""Release pigpio resources.

View File

@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
*/
/* PIGPIOD_IF_VERSION 3 */
/* PIGPIOD_IF_VERSION 4 */
#include <stdio.h>
#include <stdlib.h>
@ -534,10 +534,10 @@ int get_mode(unsigned gpio)
int set_pull_up_down(unsigned gpio, unsigned pud)
{return pigpio_command(gPigCommand, PI_CMD_PUD, gpio, pud);}
int read_gpio(unsigned gpio)
int gpio_read(unsigned gpio)
{return pigpio_command(gPigCommand, PI_CMD_READ, gpio, 0);}
int write_gpio(unsigned gpio, unsigned level)
int gpio_write(unsigned gpio, unsigned level)
{return pigpio_command(gPigCommand, PI_CMD_WRITE, gpio, level);}
int set_PWM_dutycycle(unsigned user_gpio, unsigned dutycycle)
@ -600,7 +600,7 @@ uint32_t get_current_tick(void)
uint32_t get_hardware_revision(void)
{return pigpio_command(gPigCommand, PI_CMD_HWVER, 0, 0);}
unsigned get_pigpio_version(void)
uint32_t get_pigpio_version(void)
{return pigpio_command(gPigCommand, PI_CMD_PIGPV, 0, 0);}
int wave_clear(void)
@ -725,8 +725,41 @@ int store_script(char *script)
return pigpio_command_ext(gPigCommand, PI_CMD_PROC, len, 0, 1, ext);
}
int run_script(unsigned script_id)
{return pigpio_command(gPigCommand, PI_CMD_PROCR, script_id, 0);}
int run_script(unsigned script_id, unsigned numPar, uint32_t *param)
{
gpioExtent_t ext[1];
/*
p1=script id
p2=number of parameters
## extension ##
uint32_t[] parameters
*/
ext[0].size = sizeof(uint32_t)*numPar;
ext[0].ptr = param;
return pigpio_command_ext
(gPigCommand, PI_CMD_PROCR, script_id, numPar, 1, ext);
}
int script_status(int script_id, uint32_t *param)
{
int status;
uint32_t p[MAX_SCRIPT_PARAMS];
status = pigpio_command(gPigCommand, PI_CMD_PROCP, script_id, 0);
if (status >= 0)
{
/* get the data */
recv(gPigCommand, p, sizeof(p), MSG_WAITALL);
if (param) memcpy(param, p, sizeof(p));
}
return status;
}
int stop_script(unsigned script_id)
{return pigpio_command(gPigCommand, PI_CMD_PROCS, script_id, 0);}

View File

@ -30,7 +30,7 @@ For more information, please refer to <http://unlicense.org/>
#include "pigpio.h"
#define PIGPIOD_IF_VERSION 3
#define PIGPIOD_IF_VERSION 4
typedef enum
{
@ -79,7 +79,7 @@ pthread_t *start_thread(gpioThreadFunc_t func, void *arg);
The function is passed the single argument arg.
The thread can be cancelled by passing the pointer to pthread_t to
gpioStopThread().
stop_thread().
*/
void stop_thread(pthread_t *pth);
@ -87,7 +87,7 @@ void stop_thread(pthread_t *pth);
No value is returned.
The thread to be stopped should have been started with gpioStartThread().
The thread to be stopped should have been started with start_thread().
*/
int pigpio_start(char *addrStr, char *portStr);
@ -139,7 +139,7 @@ int set_pull_up_down(unsigned gpio, unsigned pud);
pud: PUD_UP, PUD_DOWN, PUD_OFF.
*/
int read_gpio(unsigned gpio);
int gpio_read(unsigned gpio);
/* Read the gpio level.
Returns the gpio level if OK, otherwise PI_BAD_GPIO.
@ -147,7 +147,7 @@ int read_gpio(unsigned gpio);
gpio:0-53.
*/
int write_gpio(unsigned gpio, unsigned level);
int gpio_write(unsigned gpio, unsigned level);
/*
Write the gpio level.
@ -507,6 +507,12 @@ uint32_t get_hardware_revision(void);
hexadecimal number the function returns 0.
*/
uint32_t get_pigpio_version(void);
/*
Returns the pigpio version.
*/
int wave_clear(void);
/* This function initialises a new waveform.
@ -659,10 +665,31 @@ int store_script(char *script);
otherwise PI_BAD_SCRIPT.
*/
int run_script(unsigned script_id);
int run_script(unsigned script_id, unsigned numPar, uint32_t *param);
/* This function runs a stored script.
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID, or
PI_TOO_MANY_PARAM
param is an array of up to 10 parameters which may be referenced in
the script as param 0 to param 9..
*/
int script_status(int script_id, uint32_t *param);
/* This function returns the run status of a stored script as well
as the current values of parameters 0 to 9.
The function returns greater than or equal to 0 if OK,
otherwise PI_BAD_SCRIPT_ID.
The run status may be
PI_SCRIPT_HALTED
PI_SCRIPT_RUNNING
PI_SCRIPT_WAITING
PI_SCRIPT_FAILED
The current value of script parameters 0 to 9 are returned in param.
*/
int stop_script(unsigned script_id);
@ -684,7 +711,7 @@ int serial_read_open(unsigned user_gpio, unsigned baud);
or PI_GPIO_IN_USE.
The serial data is returned in a cyclic buffer and is read using
gpioSerialRead().
serial_read().
It is the caller's responsibility to read data from the cyclic buffer
in a timely fashion.

248
pigs.c
View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 12+
This version is for pigpio version 13+
*/
#include <stdio.h>
@ -47,6 +47,9 @@ This program provides a socket interface to some of
the commands available from pigpio.
*/
char command_buf[8192];
char response_buf[8192];
void fatal(char *fmt, ...)
{
char buf[128];
@ -103,76 +106,24 @@ static int openSocket(void)
return sock;
}
int main(int argc , char *argv[])
void print_result(int sock, int rv, cmdCmd_t cmd)
{
int sock, r, idx, i;
cmdCmd_t cmd;
gpioExtent_t ext[3];
char buf[1024];
int i, r;
uint32_t *p;
sock = openSocket();
r = cmd.res;
if (sock != -1)
{
switch(argc)
{
case 1:
exit(0);
case 2:
sprintf(buf, "%10s", argv[1]);
break;
case 3:
sprintf(buf, "%10s %10s", argv[1], argv[2]);
break;
case 4:
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:
fatal("what? 'pigs h' for help");
}
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].size, 0);
}
if (recv(sock, &cmd, sizeof(cmdCmd_t), MSG_WAITALL) ==
sizeof(cmdCmd_t))
{
switch (cmdInfo[idx].rv)
switch (rv)
{
case 0:
r = cmd.res;
if (r < 0) fatal("ERROR: %s", cmdErrStr(r));
break;
case 1:
r = cmd.res;
if (r < 0) fatal("ERROR: %s", cmdErrStr(r));
break;
case 2:
r = cmd.res;
if (r < 0) fatal("ERROR: %s", cmdErrStr(r));
else printf("%d\n", r);
break;
@ -189,23 +140,192 @@ int main(int argc , char *argv[])
printf(cmdUsage);
break;
case 6:
r = cmd.res;
case 6: /* SLR */
if (r < 0) fatal("ERROR: %s", cmdErrStr(r));
else if (r > 0)
{
recv(sock, &buf, r, MSG_WAITALL);
buf[r] = 0;
printf("%s", buf);
printf("%s", response_buf);
}
break;
case 7: /* PROCP */
if (r < 0) fatal("ERROR: %s", cmdErrStr(r));
else
{
printf("%d", r);
p = (uint32_t *)response_buf;
for (i=0; i<MAX_SCRIPT_PARAMS; i++)
{
printf(" %d", p[i]);
}
printf("\n");
}
break;
}
}
void get_extensions(int sock, int command, int res)
{
switch (command)
{
case PI_CMD_PROCP: /* PROCP */
if (res >= 0)
{
recv(sock,
response_buf,
sizeof(uint32_t)*MAX_SCRIPT_PARAMS,
MSG_WAITALL);
}
break;
case PI_CMD_SLR: /* SLR */
if (res > 0)
{
recv(sock, response_buf, res, MSG_WAITALL);
response_buf[res] = 0;
}
break;
}
}
void put_extensions(int sock, int command, uint32_t *p, void *v[])
{
switch (command)
{
case PI_CMD_PROC:
/*
p1=script length w[1]
p2=0
## extension ##
char[] script v[1]
*/
send(sock, v[1], p[1], 0);
break;
case PI_CMD_PROCR:
/*
p1=script id w[1]
p2=numParam w[2]
## extension ##
int[] param v[1]
*/
if (p[2]) send(sock, v[1], p[2]*sizeof(uint32_t), 0);
break;
case PI_CMD_TRIG:
/*
p1=user_gpio w[1]
p2=pulseLen w[2]
## extension ##
unsigned level w[3]
*/
send(sock, &p[3], 4, 0);
break;
case PI_CMD_WVAG:
/*
p1=pulses w[1]
p2=0
## extension ##
int[] param v[1]
*/
if (p[1]) send(sock, v[1], p[1]*sizeof(gpioPulse_t), 0);
break;
case PI_CMD_WVAS:
/*
p1=user_gpio w[1]
p2=numChar w[4]
## extension ##
unsigned baud w[2]
unsigned offset w[3]
char[] str v[1]
*/
send(sock, &p[2], 4, 0);
send(sock, &p[3], 4, 0);
send(sock, v[1], p[4], 0);
break;
}
}
int main(int argc , char *argv[])
{
int sock, command;
int idx, i, pp, l, len;
cmdCmd_t cmd;
uint32_t p[10];
void *v[10];
gpioCtlParse_t ctl;
sock = openSocket();
if (sock != -1)
{
command_buf[0] = 0;
l = 0;
pp = 0;
for (i=1; i<argc; i++)
{
l += (strlen(argv[i]) + 1);
if (l < sizeof(command_buf))
{sprintf(command_buf+pp, "%s ", argv[i]); pp=l;}
}
if (pp) {command_buf[--pp] = 0;}
ctl.flags = 0;
ctl.eaten = 0;
len = strlen(command_buf);
idx = 0;
while ((idx >= 0) && (ctl.eaten < len))
{
if ((idx=cmdParse(command_buf, p, v, &ctl)) >= 0)
{
command = p[0];
if (command < PI_CMD_SCRIPT)
{
cmd.cmd = command;
cmd.p1 = p[1];
cmd.p2 = p[2];
switch (command)
{
case PI_CMD_WVAS:
cmd.p2 = p[4];
break;
case PI_CMD_PROC:
cmd.p2 = 0;
break;
}
if (send(sock, &cmd, sizeof(cmdCmd_t), 0) == sizeof(cmdCmd_t))
{
put_extensions(sock, command, p, v);
if (recv(sock, &cmd, sizeof(cmdCmd_t), MSG_WAITALL) ==
sizeof(cmdCmd_t))
{
get_extensions(sock, command, cmd.res);
print_result(sock, cmdInfo[idx].rv, cmd);
}
else fatal("recv failed, %m");
}
else fatal("send failed, %m");
}
else fatal("what? 'pigs h' for help");
else fatal("%s only allowed within a script", cmdInfo[idx].name);
}
else fatal("%s? pigs h for help", cmdStr());
}
}
else fatal("connect failed, %m");

View File

@ -3,15 +3,15 @@
from distutils.core import setup
setup(name='pigpio',
version='1.3',
version='1.4',
author='joan',
author_email='joan@abyz.me.uk',
author_email='joan@abyz.co.uk',
maintainer='joan',
maintainer_email='joan@abyz.me.uk',
maintainer_email='joan@abyz.co.uk',
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',
long_description='Raspberry Pi Python module to access the pigpio daemon',
download_url='http://abyz.co.uk/rpi/pigpio/pigpio.zip',
license='TBD',
license='unlicense.org',
py_modules=['pigpio']
)

638
x_pigpio.c Normal file
View File

@ -0,0 +1,638 @@
/*
gcc -o x_pigpio x_pigpio.c -lpigpio -lrt -lpthread
sudo ./x_pigpio
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include "pigpio.h"
#define USERDATA 18249013
#define GPIO 4
void CHECK(int t, int st, int got, int expect, int pc, char *desc)
{
if ((got >= (((1E2-pc)*expect)/1E2)) && (got <= (((1E2+pc)*expect)/1E2)))
{
printf("TEST %2d.%-2d PASS (%s: %d)\n", t, st, desc, expect);
}
else
{
fprintf(stderr,
"TEST %2d.%-2d FAILED got %d (%s: %d)\n",
t, st, got, desc, expect);
}
}
void t0()
{
printf("Version.\n");
printf("pigpio version %d.\n", gpioVersion());
printf("Hardware revision %d.\n", gpioHardwareRevision());
}
void t1()
{
int v;
printf("Mode/PUD/read/write tests.\n");
gpioSetMode(GPIO, PI_INPUT);
v = gpioGetMode(GPIO);
CHECK(1, 1, v, 0, 0, "set mode, get mode");
gpioSetPullUpDown(GPIO, PI_PUD_UP);
v = gpioRead(GPIO);
CHECK(1, 2, v, 1, 0, "set pull up down, read");
gpioSetPullUpDown(GPIO, PI_PUD_DOWN);
v = gpioRead(GPIO);
CHECK(1, 3, v, 0, 0, "set pull up down, read");
gpioWrite(GPIO, PI_LOW);
v = gpioGetMode(GPIO);
CHECK(1, 4, v, 1, 0, "write, get mode");
v = gpioRead(GPIO);
CHECK(1, 5, v, 0, 0, "read");
gpioWrite(GPIO, PI_HIGH);
v = gpioRead(GPIO);
CHECK(1, 6, v, 1, 0, "write, read");
}
int t2_count=0;
void t2cb(int gpio, int level, uint32_t tick)
{
t2_count++;
}
void t2()
{
int f, r, rr, oc;
printf("PWM dutycycle/range/frequency tests.\n");
gpioSetPWMrange(GPIO, 255);
gpioSetPWMfrequency(GPIO, 0);
f = gpioGetPWMfrequency(GPIO);
CHECK(2, 1, f, 10, 0, "set PWM range, set/get PWM frequency");
gpioSetAlertFunc(GPIO, t2cb);
gpioPWM(GPIO, 0);
time_sleep(0.5); /* allow old notifications to flush */
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 2, f, 0, 0, "set PWM dutycycle, callback");
gpioPWM(GPIO, 128);
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 3, f, 40, 5, "set PWM dutycycle, callback");
gpioSetPWMfrequency(GPIO, 100);
f = gpioGetPWMfrequency(GPIO);
CHECK(2, 4, f, 100, 0, "set/get PWM frequency");
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 5, f, 400, 1, "callback");
gpioSetPWMfrequency(GPIO, 1000);
f = gpioGetPWMfrequency(GPIO);
CHECK(2, 6, f, 1000, 0, "set/get PWM frequency");
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 7, f, 4000, 1, "callback");
r = gpioGetPWMrange(GPIO);
CHECK(2, 8, r, 255, 0, "get PWM range");
rr = gpioGetPWMrealRange(GPIO);
CHECK(2, 9, rr, 200, 0, "get PWM real range");
gpioSetPWMrange(GPIO, 2000);
r = gpioGetPWMrange(GPIO);
CHECK(2, 10, r, 2000, 0, "set/get PWM range");
rr = gpioGetPWMrealRange(GPIO);
CHECK(2, 11, rr, 200, 0, "get PWM real range");
gpioPWM(GPIO, 0);
}
int t3_val = USERDATA;
int t3_reset=1;
int t3_count=0;
uint32_t t3_tick=0;
float t3_on=0.0;
float t3_off=0.0;
void t3cbf(int gpio, int level, uint32_t tick, void *userdata)
{
static int unreported = 1;
uint32_t td;
int *val;
val = userdata;
if (*val != USERDATA)
{
if (unreported)
{
fprintf
(
stderr,
"unexpected userdata %d (expected %d)\n",
*val, USERDATA
);
}
unreported = 0;
}
if (t3_reset)
{
t3_count = 0;
t3_on = 0.0;
t3_off = 0.0;
t3_reset = 0;
}
else
{
td = tick - t3_tick;
if (level == 0) t3_on += td;
else t3_off += td;
}
t3_count ++;
t3_tick = tick;
}
void t3()
{
int f, rr;
float on, off;
int t;
int pw[3]={500, 1500, 2500};
int dc[4]={20, 40, 60, 80};
printf("PWM/Servo pulse accuracy tests.\n");
gpioSetAlertFuncEx(GPIO, t3cbf, &t3_val); /* test extended alert */
for (t=0; t<3; t++)
{
gpioServo(GPIO, pw[t]);
time_sleep(1);
t3_reset = 1;
time_sleep(4);
on = t3_on;
off = t3_off;
CHECK(3, 1+t, (1E3*(on+off))/on, 2E7/pw[t], 1,
"set servo pulsewidth");
}
gpioServo(GPIO, 0);
gpioSetPWMfrequency(GPIO, 1000);
f = gpioGetPWMfrequency(GPIO);
CHECK(3, 4, f, 1000, 0, "set/get PWM frequency");
rr = gpioSetPWMrange(GPIO, 100);
CHECK(3, 5, rr, 200, 0, "set PWM range");
for (t=0; t<4; t++)
{
gpioPWM(GPIO, dc[t]);
time_sleep(1);
t3_reset = 1;
time_sleep(2);
on = t3_on;
off = t3_off;
CHECK(3, 6+t, (1E3*on)/(on+off), 1E1*dc[t], 1,
"set PWM dutycycle");
}
gpioPWM(GPIO, 0);
}
void t4()
{
int h, e, f, n, s, b, l, seq_ok, toggle_ok;
gpioReport_t r;
char p[32];
printf("Pipe notification tests.\n");
gpioSetPWMfrequency(GPIO, 0);
gpioPWM(GPIO, 0);
gpioSetPWMrange(GPIO, 100);
h = gpioNotifyOpen();
e = gpioNotifyBegin(h, (1<<4));
CHECK(4, 1, e, 0, 0, "notify open/begin");
time_sleep(1);
sprintf(p, "/dev/pigpio%d", h);
f = open(p, O_RDONLY);
gpioPWM(GPIO, 50);
time_sleep(4);
gpioPWM(GPIO, 0);
e = gpioNotifyPause(h);
CHECK(4, 2, e, 0, 0, "notify pause");
e = gpioNotifyClose(h);
CHECK(4, 3, e, 0, 0, "notify close");
n = 0;
s = 0;
l = 0;
seq_ok = 1;
toggle_ok = 1;
while (1)
{
b = read(f, &r, 12);
if (b == 12)
{
if (s != r.seqno) seq_ok = 0;
if (n) if (l != (r.level&(1<<4))) toggle_ok = 0;
if (r.level&(1<<4)) l = 0;
else l = (1<<4);
s++;
n++;
// printf("%d %d %d %X\n", r.seqno, r.flags, r.tick, r.level);
}
else break;
}
close(f);
CHECK(4, 4, seq_ok, 1, 0, "sequence numbers ok");
CHECK(4, 5, toggle_ok, 1, 0, "gpio toggled ok");
CHECK(4, 6, n, 80, 10, "number of notifications");
}
int t5_count = 0;
void t5cbf(int gpio, int level, uint32_t tick)
{
if (level == 0) t5_count++; /* falling edges */
}
void t5()
{
int BAUD=4800;
char *TEXT=
"\n\
Now is the winter of our discontent\n\
Made glorious summer by this sun of York;\n\
And all the clouds that lour'd upon our house\n\
In the deep bosom of the ocean buried.\n\
Now are our brows bound with victorious wreaths;\n\
Our bruised arms hung up for monuments;\n\
Our stern alarums changed to merry meetings,\n\
Our dreadful marches to delightful measures.\n\
Grim-visaged war hath smooth'd his wrinkled front;\n\
And now, instead of mounting barded steeds\n\
To fright the souls of fearful adversaries,\n\
He capers nimbly in a lady's chamber\n\
To the lascivious pleasing of a lute.\n\
";
gpioPulse_t wf[] =
{
{1<<GPIO, 0, 10000},
{0, 1<<GPIO, 30000},
{1<<GPIO, 0, 60000},
{0, 1<<GPIO, 100000},
};
int e, oc, c;
char text[2048];
printf("Waveforms & serial read/write tests.\n");
gpioSetAlertFunc(GPIO, t5cbf);
gpioSetMode(GPIO, PI_OUTPUT);
e = gpioWaveClear();
CHECK(5, 1, e, 0, 0, "callback, set mode, wave clear");
e = gpioWaveAddGeneric(4, wf);
CHECK(5, 2, e, 4, 0, "pulse, wave add generic");
e = gpioWaveTxStart(PI_WAVE_MODE_REPEAT);
CHECK(5, 3, e, 9, 0, "wave tx repeat");
oc = t5_count;
time_sleep(5);
c = t5_count - oc;
CHECK(5, 4, c, 50, 1, "callback");
e = gpioWaveTxStop();
CHECK(5, 5, e, 0, 0, "wave tx stop");
/* gpioSerialReadOpen changes the alert function */
e = gpioSerialReadOpen(GPIO, BAUD);
CHECK(5, 6, e, 0, 0, "serial read open");
gpioWaveClear();
e = gpioWaveAddSerial(GPIO, BAUD, 5000000, strlen(TEXT), TEXT);
CHECK(5, 7, e, 3405, 0, "wave clear, wave add serial");
e = gpioWaveTxStart(PI_WAVE_MODE_ONE_SHOT);
CHECK(5, 8, e, 6811, 0, "wave tx start");
CHECK(5, 9, 0, 0, 0, "NOT APPLICABLE");
CHECK(5, 10, 0, 0, 0, "NOT APPLICABLE");
while (gpioWaveTxBusy()) time_sleep(0.1);
time_sleep(0.1);
c = gpioSerialRead(GPIO, text, sizeof(text)-1);
if (c > 0) text[c] = 0;
CHECK(5, 11, strcmp(TEXT, text), 0, 0, "wave tx busy, serial read");
e = gpioSerialReadClose(GPIO);
CHECK(5, 12, e, 0, 0, "serial read close");
c = gpioWaveGetMicros();
CHECK(5, 13, c, 6158704, 0, "wave get micros");
c = gpioWaveGetHighMicros();
CHECK(5, 14, c, 6158704, 0, "wave get high micros");
c = gpioWaveGetMaxMicros();
CHECK(5, 15, c, 1800000000, 0, "wave get max micros");
c = gpioWaveGetPulses();
CHECK(5, 16, c, 3405, 0, "wave get pulses");
c = gpioWaveGetHighPulses();
CHECK(5, 17, c, 3405, 0, "wave get high pulses");
c = gpioWaveGetMaxPulses();
CHECK(5, 18, c, 12000, 0, "wave get max pulses");
c = gpioWaveGetCbs();
CHECK(5, 19, c, 6810, 0, "wave get cbs");
c = gpioWaveGetHighCbs();
CHECK(5, 20, c, 6810, 0, "wave get high cbs");
c = gpioWaveGetMaxCbs();
CHECK(5, 21, c, 25016, 0, "wave get max cbs");
}
int t6_count=0;
int t6_on=0;
uint32_t t6_on_tick=0;
void t6cbf(int gpio, int level, uint32_t tick)
{
if (level == 1)
{
t6_on_tick = tick;
t6_count++;
}
else
{
if (t6_on_tick) t6_on += (tick - t6_on_tick);
}
}
void t6()
{
int tp, t, p;
printf("Trigger tests\n");
gpioWrite(GPIO, PI_LOW);
tp = 0;
gpioSetAlertFunc(GPIO, t6cbf);
for (t=0; t<10; t++)
{
time_sleep(0.1);
p = 10 + (t*10);
tp += p;
gpioTrigger(4, p, 1);
}
time_sleep(0.2);
CHECK(6, 1, t6_count, 10, 0, "gpio trigger count");
CHECK(6, 2, t6_on, tp, 25, "gpio trigger pulse length");
}
int t7_count=0;
void t7cbf(int gpio, int level, uint32_t tick)
{
if (level == PI_TIMEOUT) t7_count++;
}
void t7()
{
int c, oc;
printf("Watchdog tests.\n");
/* type of edge shouldn't matter for watchdogs */
gpioSetAlertFunc(GPIO, t7cbf);
gpioSetWatchdog(GPIO, 10); /* 10 ms, 100 per second */
time_sleep(0.5);
oc = t7_count;
time_sleep(2);
c = t7_count - oc;
CHECK(7, 1, c, 200, 1, "set watchdog on count");
gpioSetWatchdog(GPIO, 0); /* 0 switches watchdog off */
time_sleep(0.5);
oc = t7_count;
time_sleep(2);
c = t7_count - oc;
CHECK(7, 2, c, 0, 1, "set watchdog off count");
}
void t8()
{
int v, t, i;
printf("Bank read/write tests.\n");
gpioWrite(GPIO, 0);
v = gpioRead_Bits_0_31() & (1<<GPIO);
CHECK(8, 1, v, 0, 0, "read bank 1");
gpioWrite(GPIO, 1);
v = gpioRead_Bits_0_31() & (1<<GPIO);
CHECK(8, 2, v, (1<<GPIO), 0, "read bank 1");
gpioWrite_Bits_0_31_Clear(1<<GPIO);
v = gpioRead(GPIO);
CHECK(8, 3, v, 0, 0, "clear bank 1");
gpioWrite_Bits_0_31_Set(1<<GPIO);
v = gpioRead(GPIO);
CHECK(8, 4, v, 1, 0, "set bank 1");
t = 0;
v = (1<<16);
for (i=0; i<100; i++)
{
if (gpioRead_Bits_32_53() & v) t++;
};
CHECK(8, 5, t, 60, 75, "read bank 2");
v = gpioWrite_Bits_32_53_Clear(0);
CHECK(8, 6, v, 0, 0, "clear bank 2");
CHECK(8, 7, 0, 0, 0, "NOT APPLICABLE");
v = gpioWrite_Bits_32_53_Set(0);
CHECK(8, 8, v, 0, 0, "set bank 2");
CHECK(8, 9, 0, 0, 0, "NOT APPLICABLE");
}
int t9_count = 0;
void t9cbf(int gpio, int level, uint32_t tick)
{
if (level == 1) t9_count++;
}
void t9()
{
int s, oc, c, e;
uint32_t p[10];
/*
100 loops per second
p0 number of loops
p1 GPIO
*/
char *script="\
ldap 0\
ldva 0\
label 0\
w p1 1\
milli 5\
w p1 0\
milli 5\
dcrv 0\
ldav 0\
ldpa 9\
jp 0";
printf("Script store/run/status/stop/delete tests.\n");
gpioWrite(GPIO, 0); /* need known state */
gpioSetAlertFunc(GPIO, t9cbf);
s = gpioStoreScript(script);
time_sleep(0.1);
oc = t9_count;
p[0] = 99;
p[1] = GPIO;
gpioRunScript(s, 2, p);
time_sleep(2);
c = t9_count - oc;
CHECK(9, 1, c, 100, 0, "store/run script");
oc = t9_count;
p[0] = 200;
p[1] = GPIO;
gpioRunScript(s, 2, p);
time_sleep(0.1);
while (1)
{
e = gpioScriptStatus(s, p);
if (e != PI_SCRIPT_RUNNING) break;
time_sleep(0.5);
}
c = t9_count - oc;
time_sleep(0.1);
CHECK(9, 2, c, 201, 0, "run script/script status");
oc = t9_count;
p[0] = 2000;
p[1] = GPIO;
gpioRunScript(s, 2, p);
time_sleep(0.1);
while (1)
{
e = gpioScriptStatus(s, p);
if (e != PI_SCRIPT_RUNNING) break;
if (p[9] < 1900) gpioStopScript(s);
time_sleep(0.1);
}
c = t9_count - oc;
time_sleep(0.1);
CHECK(9, 3, c, 110, 10, "run/stop script/script status");
e = gpioDeleteScript(s);
CHECK(9, 4, e, 0, 0, "delete script");
}
int main(int argc, char *argv[])
{
int t, status;
void (*test[])(void) = {t0, t1, t2, t3, t4, t5, t6, t7, t8, t9};
status = gpioInitialise();
if (status < 0)
{
fprintf(stderr, "pigpio initialisation failed.\n");
return 1;
}
for (t=0; t<10; t++) test[t]();
gpioTerminate();
return 0;
}

540
x_pigpio.py Executable file
View File

@ -0,0 +1,540 @@
#!/usr/bin/env python
import time
import struct
import pigpio
GPIO=4
def CHECK(t, st, got, expect, pc, desc):
if got >= (((1E2-pc)*expect)/1E2) and got <= (((1E2+pc)*expect)/1E2):
print("TEST {:2d}.{:<2d} PASS ({}: {:d})".format(t, st, desc, expect))
else:
print("TEST {:2d}.{:<2d} FAILED got {:d} ({}: {:d})".
format(t, st, got, desc, expect))
def t0():
print("Version.")
print("pigpio version {}.".format(pigpio.get_pigpio_version()))
print("Hardware revision {}.".format(pigpio.get_hardware_revision()))
def t1():
print("Mode/PUD/read/write tests.")
pigpio.set_mode(GPIO, pigpio.INPUT)
v = pigpio.get_mode(GPIO)
CHECK(1, 1, v, 0, 0, "set mode, get mode")
pigpio.set_pull_up_down(GPIO, pigpio.PUD_UP)
v = pigpio.read(GPIO)
CHECK(1, 2, v, 1, 0, "set pull up down, read")
pigpio.set_pull_up_down(GPIO, pigpio.PUD_DOWN)
v = pigpio.read(GPIO)
CHECK(1, 3, v, 0, 0, "set pull up down, read")
pigpio.write(GPIO, pigpio.LOW)
v = pigpio.get_mode(GPIO)
CHECK(1, 4, v, 1, 0, "write, get mode")
v = pigpio.read(GPIO)
CHECK(1, 5, v, 0, 0, "read")
pigpio.write(GPIO, pigpio.HIGH)
v = pigpio.read(GPIO)
CHECK(1, 6, v, 1, 0, "write, read")
t2_count=0
def t2cbf(gpio, level, tick):
global t2_count
t2_count += 1
def t2():
global t2_count
print("PWM dutycycle/range/frequency tests.")
pigpio.set_PWM_range(GPIO, 255)
pigpio.set_PWM_frequency(GPIO,0)
f = pigpio.get_PWM_frequency(GPIO)
CHECK(2, 1, f, 10, 0, "set PWM range, set/get PWM frequency")
t2cb = pigpio.callback(GPIO, pigpio.EITHER_EDGE, t2cbf)
pigpio.set_PWM_dutycycle(GPIO, 0)
time.sleep(0.5) # allow old notifications to flush
oc = t2_count
time.sleep(2)
f = t2_count - oc
CHECK(2, 2, f, 0, 0, "set PWM dutycycle, callback")
pigpio.set_PWM_dutycycle(GPIO, 128)
time.sleep(1)
oc = t2_count
time.sleep(2)
f = t2_count - oc
CHECK(2, 3, f, 40, 5, "set PWM dutycycle, callback")
pigpio.set_PWM_frequency(GPIO,100)
f = pigpio.get_PWM_frequency(GPIO)
CHECK(2, 4, f, 100, 0, "set/get PWM frequency")
time.sleep(1)
oc = t2_count
time.sleep(2)
f = t2_count - oc
CHECK(2, 5, f, 400, 1, "callback")
pigpio.set_PWM_frequency(GPIO,1000)
f = pigpio.get_PWM_frequency(GPIO)
CHECK(2, 6, f, 1000, 0, "set/get PWM frequency")
time.sleep(1)
oc = t2_count
time.sleep(2)
f = t2_count - oc
CHECK(2, 7, f, 4000, 1, "callback")
r = pigpio.get_PWM_range(GPIO)
CHECK(2, 8, r, 255, 0, "get PWM range")
rr = pigpio.get_PWM_real_range(GPIO)
CHECK(2, 9, rr, 200, 0, "get PWM real range")
pigpio.set_PWM_range(GPIO, 2000)
r = pigpio.get_PWM_range(GPIO)
CHECK(2, 10, r, 2000, 0, "set/get PWM range")
rr = pigpio.get_PWM_real_range(GPIO)
CHECK(2, 11, rr, 200, 0, "get PWM real range")
pigpio.set_PWM_dutycycle(GPIO, 0)
t3_reset=True
t3_count=0
t3_tick=0
t3_on=0.0
t3_off=0.0
def t3cbf(gpio, level, tick):
global t3_reset, t3_count, t3_tick, t3_on, t3_off
if t3_reset:
t3_count = 0
t3_on = 0.0
t3_off = 0.0
t3_reset = False
else:
td = pigpio.tickDiff(t3_tick, tick)
if level == 0:
t3_on += td
else:
t3_off += td
t3_count += 1
t3_tick = tick
def t3():
global t3_reset, t3_count, t3_on, t3_off
pw=[500.0, 1500.0, 2500.0]
dc=[0.2, 0.4, 0.6, 0.8]
print("PWM/Servo pulse accuracy tests.")
t3cb = pigpio.callback(GPIO, pigpio.EITHER_EDGE, t3cbf)
t = 0
for x in pw:
t += 1
pigpio.set_servo_pulsewidth(GPIO, x)
time.sleep(1)
t3_reset = True
time.sleep(4)
c = t3_count
on = t3_on
off = t3_off
CHECK(3, t, int((1E3*(on+off))/on), int(2E7/x), 1, "set servo pulsewidth")
pigpio.set_servo_pulsewidth(GPIO, 0)
pigpio.set_PWM_frequency(GPIO, 1000)
f = pigpio.get_PWM_frequency(GPIO)
CHECK(3, 4, f, 1000, 0, "set/get PWM frequency")
rr = pigpio.set_PWM_range(GPIO, 100)
CHECK(3, 5, rr, 200, 0, "set PWM range")
t = 5
for x in dc:
t += 1
pigpio.set_PWM_dutycycle(GPIO, x*100)
time.sleep(1)
t3_reset = True
time.sleep(2)
c = t3_count
on = t3_on
off = t3_off
CHECK(3, t, int((1E3*on)/(on+off)), int(1E3*x), 1, "set PWM dutycycle")
pigpio.set_PWM_dutycycle(GPIO, 0)
def t4():
print("Pipe notification tests.")
pigpio.set_PWM_frequency(GPIO, 0)
pigpio.set_PWM_dutycycle(GPIO, 0)
pigpio.set_PWM_range(GPIO, 100)
h = pigpio.notify_open()
e = pigpio.notify_begin(h, (1<<4))
CHECK(4, 1, e, 0, 0, "notify open/begin")
time.sleep(1)
with open("/dev/pigpio"+ str(h), "rb") as f:
pigpio.set_PWM_dutycycle(GPIO, 50)
time.sleep(4)
pigpio.set_PWM_dutycycle(GPIO, 0)
e = pigpio.notify_pause(h)
CHECK(4, 2, e, 0, 0, "notify pause")
e = pigpio.notify_close(h)
CHECK(4, 3, e, 0, 0, "notify close")
n = 0
s = 0
seq_ok = 1
toggle_ok = 1
while True:
chunk = f.read(12)
if len(chunk) == 12:
S, fl, t, v = struct.unpack('HHII', chunk)
if s != S:
seq_ok = 0
L = v & (1<<4)
if n:
if l != L:
toggle_ok = 0
if L:
l = 0
else:
l = (1<<4)
s += 1
n += 1
# print(S, fl, t, hex(v))
else:
break
f.close()
CHECK(4, 4, seq_ok, 1, 0, "sequence numbers ok")
CHECK(4, 5, toggle_ok, 1, 0, "gpio toggled ok")
CHECK(4, 6, n, 80, 10, "number of notifications")
t5_count = 0
def t5cbf(gpio, level, tick):
global t5_count
t5_count += 1
def t5():
global t5_count
BAUD=4800
TEXT="""
Now is the winter of our discontent
Made glorious summer by this sun of York;
And all the clouds that lour'd upon our house
In the deep bosom of the ocean buried.
Now are our brows bound with victorious wreaths;
Our bruised arms hung up for monuments;
Our stern alarums changed to merry meetings,
Our dreadful marches to delightful measures.
Grim-visaged war hath smooth'd his wrinkled front;
And now, instead of mounting barded steeds
To fright the souls of fearful adversaries,
He capers nimbly in a lady's chamber
To the lascivious pleasing of a lute.
"""
print("Waveforms & serial read/write tests.")
t5cb = pigpio.callback(GPIO, pigpio.FALLING_EDGE, t5cbf)
pigpio.set_mode(GPIO, pigpio.OUTPUT)
e = pigpio.wave_clear()
CHECK(5, 1, e, 0, 0, "callback, set mode, wave clear")
wf = []
wf.append(pigpio.pulse(1<<GPIO, 0, 10000))
wf.append(pigpio.pulse(0, 1<<GPIO, 30000))
wf.append(pigpio.pulse(1<<GPIO, 0, 60000))
wf.append(pigpio.pulse(0, 1<<GPIO, 100000))
e = pigpio.wave_add_generic(wf)
CHECK(5, 2, e, 4, 0, "pulse, wave add generic")
e = pigpio.wave_tx_repeat()
CHECK(5, 3, e, 9, 0, "wave tx repeat")
oc = t5_count
time.sleep(5)
c = t5_count - oc
CHECK(5, 4, c, 50, 1, "callback")
e = pigpio.wave_tx_stop()
CHECK(5, 5, e, 0, 0, "wave tx stop")
e = pigpio.serial_read_open(GPIO, BAUD)
CHECK(5, 6, e, 0, 0, "serial read open")
pigpio.wave_clear()
e = pigpio.wave_add_serial(GPIO, BAUD, 5000000, TEXT)
CHECK(5, 7, e, 3405, 0, "wave clear, wave add serial")
e = pigpio.wave_tx_start()
CHECK(5, 8, e, 6811, 0, "wave tx start")
oc = t5_count
time.sleep(3)
c = t5_count - oc
CHECK(5, 9, c, 0, 0, "callback")
oc = t5_count
while pigpio.wave_tx_busy():
time.sleep(0.1)
time.sleep(0.1)
c = t5_count - oc
CHECK(5, 10, c, 1702, 0, "wave tx busy, callback")
c, text = pigpio.serial_read(GPIO)
CHECK(5, 11, TEXT == text, True, 0, "wave tx busy, serial read");
e = pigpio.serial_read_close(GPIO)
CHECK(5, 12, e, 0, 0, "serial read close")
c = pigpio.wave_get_micros()
CHECK(5, 13, c, 6158704, 0, "wave get micros")
CHECK(5, 14, 0, 0, 0, "NOT APPLICABLE")
c = pigpio.wave_get_max_micros()
CHECK(5, 15, c, 1800000000, 0, "wave get max micros")
c = pigpio.wave_get_pulses()
CHECK(5, 16, c, 3405, 0, "wave get pulses")
CHECK(5, 17, 0, 0, 0, "NOT APPLICABLE")
c = pigpio.wave_get_max_pulses()
CHECK(5, 18, c, 12000, 0, "wave get max pulses")
c = pigpio.wave_get_cbs()
CHECK(5, 19, c, 6810, 0, "wave get cbs")
CHECK(5, 20, 0, 0, 0, "NOT APPLICABLE")
c = pigpio.wave_get_max_cbs()
CHECK(5, 21, c, 25016, 0, "wave get max cbs")
t6_count=0
t6_on=0
t6_on_tick=None
def t6cbf(gpio, level, tick):
global t6_count, t6_on, t6_on_tick
if level == 1:
t6_on_tick = tick
t6_count += 1
else:
if t6_on_tick is not None:
t6_on += pigpio.tickDiff(t6_on_tick, tick)
def t6():
global t6_count, t6_on
print("Trigger tests.")
pigpio.write(GPIO, pigpio.LOW)
tp = 0
t6cb = pigpio.callback(GPIO, pigpio.EITHER_EDGE, t6cbf)
for t in range(10):
time.sleep(0.1)
p = 10 + (t*10)
tp += p;
pigpio.gpio_trigger(4, p, 1)
time.sleep(0.5)
CHECK(6, 1, t6_count, 10, 0, "gpio trigger count")
CHECK(6, 2, t6_on, tp, 25, "gpio trigger pulse length")
t7_count=0
def t7cbf(gpio, level, tick):
global t7_count
if level == pigpio.TIMEOUT:
t7_count += 1
def t7():
global t7_count
print("Watchdog tests.")
# type of edge shouldn't matter for watchdogs
t7cb = pigpio.callback(GPIO, pigpio.FALLING_EDGE, t7cbf)
pigpio.set_watchdog(GPIO, 10) # 10 ms, 100 per second
time.sleep(0.5)
oc = t7_count
time.sleep(2)
c = t7_count - oc
CHECK(7, 1, c, 200, 1, "set watchdog on count")
pigpio.set_watchdog(GPIO, 0) # 0 switches watchdog off
time.sleep(0.5)
oc = t7_count
time.sleep(2)
c = t7_count - oc
CHECK(7, 2, c, 0, 1, "set watchdog off count")
def t8():
print("Bank read/write tests.")
pigpio.write(GPIO, 0)
v = pigpio.read_bank_1() & (1<<GPIO)
CHECK(8, 1, v, 0, 0, "read bank 1")
pigpio.write(GPIO, 1)
v = pigpio.read_bank_1() & (1<<GPIO)
CHECK(8, 2, v, (1<<GPIO), 0, "read bank 1")
pigpio.clear_bank_1(1<<GPIO)
v = pigpio.read(GPIO)
CHECK(8, 3, v, 0, 0, "clear bank 1")
pigpio.set_bank_1(1<<GPIO)
v = pigpio.read(GPIO)
CHECK(8, 4, v, 1, 0, "set bank 1")
t = 0
v = (1<<16)
for i in range(100):
if pigpio.read_bank_2() & v:
t += 1
CHECK(8, 5, t, 60, 75, "read bank 2")
v = pigpio.clear_bank_2(0)
CHECK(8, 6, v, 0, 0, "clear bank 2")
pigpio.exceptions = False
v = pigpio.clear_bank_2(0xffffff)
pigpio.exceptions = True
CHECK(8, 7, v, pigpio.PI_SOME_PERMITTED, 0, "clear bank 2")
v = pigpio.set_bank_2(0)
CHECK(8, 8, v, 0, 0, "set bank 2")
pigpio.exceptions = False
v = pigpio.set_bank_2(0xffffff)
pigpio.exceptions = True
CHECK(8, 9, v, pigpio.PI_SOME_PERMITTED, 0, "set bank 2")
def t9():
print("Script store/run/status/stop/delete tests.")
pigpio.write(GPIO, 0) # need known state
# 100 loops per second
# p0 number of loops
# p1 GPIO
script="""
ldap 0
ldva 0
label 0
w p1 1
milli 5
w p1 0
milli 5
dcrv 0
ldav 0
ldpa 9
jp 0"""
t9cb = pigpio.callback(GPIO)
s = pigpio.store_script(script)
oc = t9cb.tally()
pigpio.run_script(s, [99, GPIO])
time.sleep(2)
c = t9cb.tally() - oc
CHECK(9, 1, c, 100, 0, "store/run script")
oc = t9cb.tally()
pigpio.run_script(s, [200, GPIO])
while True:
e, p = pigpio.script_status(s)
if e != pigpio.PI_SCRIPT_RUNNING:
break
time.sleep(0.5)
c = t9cb.tally() - oc
time.sleep(0.1)
CHECK(9, 2, c, 201, 0, "run script/script status")
oc = t9cb.tally()
pigpio.run_script(s, [2000, GPIO])
while True:
e, p = pigpio.script_status(s)
if e != pigpio.PI_SCRIPT_RUNNING:
break
if p[9] < 1900:
pigpio.stop_script(s)
time.sleep(0.1)
c = t9cb.tally() - oc
time.sleep(0.1)
CHECK(9, 3, c, 110, 10, "run/stop script/script status")
e = pigpio.delete_script(s)
CHECK(9, 4, e, 0, 0, "delete script")
if pigpio.start(''): # must run notification test on localhost
print("Connected to pigpio daemon.")
test = [t0, t1, t2, t3, t4, t5, t6, t7, t8, t9]
for t in test:
t();
pigpio.stop()

620
x_pigpiod_if.c Normal file
View File

@ -0,0 +1,620 @@
/*
gcc -o x_pigpiod_if x_pigpiod_if.c -lpigpiod_if -lrt -lpthread
sudo ./x_pigpiod_if
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include "pigpiod_if.h"
#define GPIO 4
void CHECK(int t, int st, int got, int expect, int pc, char *desc)
{
if ((got >= (((1E2-pc)*expect)/1E2)) && (got <= (((1E2+pc)*expect)/1E2)))
{
printf("TEST %2d.%-2d PASS (%s: %d)\n", t, st, desc, expect);
}
else
{
fprintf(stderr,
"TEST %2d.%-2d FAILED got %d (%s: %d)\n",
t, st, got, desc, expect);
}
}
void t0()
{
printf("Version.\n");
printf("pigpio version %d.\n", get_pigpio_version());
printf("Hardware revision %d.\n", get_hardware_revision());
}
void t1()
{
int v;
printf("Mode/PUD/read/write tests.\n");
set_mode(GPIO, PI_INPUT);
v = get_mode(GPIO);
CHECK(1, 1, v, 0, 0, "set mode, get mode");
set_pull_up_down(GPIO, PI_PUD_UP);
v = gpio_read(GPIO);
CHECK(1, 2, v, 1, 0, "set pull up down, read");
set_pull_up_down(GPIO, PI_PUD_DOWN);
v = gpio_read(GPIO);
CHECK(1, 3, v, 0, 0, "set pull up down, read");
gpio_write(GPIO, PI_LOW);
v = get_mode(GPIO);
CHECK(1, 4, v, 1, 0, "write, get mode");
v = gpio_read(GPIO);
CHECK(1, 5, v, 0, 0, "read");
gpio_write(GPIO, PI_HIGH);
v = gpio_read(GPIO);
CHECK(1, 6, v, 1, 0, "write, read");
}
int t2_count=0;
void t2cb(unsigned gpio, unsigned level, uint32_t tick)
{
t2_count++;
}
void t2()
{
int f, r, rr, oc;
printf("PWM dutycycle/range/frequency tests.\n");
set_PWM_range(GPIO, 255);
set_PWM_frequency(GPIO, 0);
f = get_PWM_frequency(GPIO);
CHECK(2, 1, f, 10, 0, "set PWM range, set/get PWM frequency");
callback(GPIO, EITHER_EDGE, t2cb);
set_PWM_dutycycle(GPIO, 0);
time_sleep(0.5); /* allow old notifications to flush */
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 2, f, 0, 0, "set PWM dutycycle, callback");
set_PWM_dutycycle(GPIO, 128);
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 3, f, 40, 5, "set PWM dutycycle, callback");
set_PWM_frequency(GPIO, 100);
f = get_PWM_frequency(GPIO);
CHECK(2, 4, f, 100, 0, "set/get PWM frequency");
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 5, f, 400, 1, "callback");
set_PWM_frequency(GPIO, 1000);
f = get_PWM_frequency(GPIO);
CHECK(2, 6, f, 1000, 0, "set/get PWM frequency");
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 7, f, 4000, 1, "callback");
r = get_PWM_range(GPIO);
CHECK(2, 8, r, 255, 0, "get PWM range");
rr = get_PWM_real_range(GPIO);
CHECK(2, 9, rr, 200, 0, "get PWM real range");
set_PWM_range(GPIO, 2000);
r = get_PWM_range(GPIO);
CHECK(2, 10, r, 2000, 0, "set/get PWM range");
rr = get_PWM_real_range(GPIO);
CHECK(2, 11, rr, 200, 0, "get PWM real range");
set_PWM_dutycycle(GPIO, 0);
}
int t3_reset=1;
int t3_count=0;
uint32_t t3_tick=0;
float t3_on=0.0;
float t3_off=0.0;
void t3cbf(unsigned gpio, unsigned level, uint32_t tick)
{
uint32_t td;
if (t3_reset)
{
t3_count = 0;
t3_on = 0.0;
t3_off = 0.0;
t3_reset = 0;
}
else
{
td = tick - t3_tick;
if (level == 0) t3_on += td;
else t3_off += td;
}
t3_count ++;
t3_tick = tick;
}
void t3()
{
int pw[3]={500, 1500, 2500};
int dc[4]={20, 40, 60, 80};
int f, rr;
float on, off;
int t;
printf("PWM/Servo pulse accuracy tests.\n");
callback(GPIO, EITHER_EDGE, t3cbf);
for (t=0; t<3; t++)
{
set_servo_pulsewidth(GPIO, pw[t]);
time_sleep(1);
t3_reset = 1;
time_sleep(4);
on = t3_on;
off = t3_off;
CHECK(3, 1+t, (1000.0*(on+off))/on, 20000000.0/pw[t], 1,
"set servo pulsewidth");
}
set_servo_pulsewidth(GPIO, 0);
set_PWM_frequency(GPIO, 1000);
f = get_PWM_frequency(GPIO);
CHECK(3, 4, f, 1000, 0, "set/get PWM frequency");
rr = set_PWM_range(GPIO, 100);
CHECK(3, 5, rr, 200, 0, "set PWM range");
for (t=0; t<4; t++)
{
set_PWM_dutycycle(GPIO, dc[t]);
time_sleep(1);
t3_reset = 1;
time_sleep(2);
on = t3_on;
off = t3_off;
CHECK(3, 6+t, (1000.0*on)/(on+off), 10.0*dc[t], 1,
"set PWM dutycycle");
}
set_PWM_dutycycle(GPIO, 0);
}
void t4()
{
int h, e, f, n, s, b, l, seq_ok, toggle_ok;
gpioReport_t r;
char p[32];
printf("Pipe notification tests.\n");
set_PWM_frequency(GPIO, 0);
set_PWM_dutycycle(GPIO, 0);
set_PWM_range(GPIO, 100);
h = notify_open();
e = notify_begin(h, (1<<4));
CHECK(4, 1, e, 0, 0, "notify open/begin");
time_sleep(1);
sprintf(p, "/dev/pigpio%d", h);
f = open(p, O_RDONLY);
set_PWM_dutycycle(GPIO, 50);
time_sleep(4);
set_PWM_dutycycle(GPIO, 0);
e = notify_pause(h);
CHECK(4, 2, e, 0, 0, "notify pause");
e = notify_close(h);
CHECK(4, 3, e, 0, 0, "notify close");
n = 0;
s = 0;
l = 0;
seq_ok = 1;
toggle_ok = 1;
while (1)
{
b = read(f, &r, 12);
if (b == 12)
{
if (s != r.seqno) seq_ok = 0;
if (n) if (l != (r.level&(1<<4))) toggle_ok = 0;
if (r.level&(1<<4)) l = 0;
else l = (1<<4);
s++;
n++;
// printf("%d %d %d %X\n", r.seqno, r.flags, r.tick, r.level);
}
else break;
}
close(f);
CHECK(4, 4, seq_ok, 1, 0, "sequence numbers ok");
CHECK(4, 5, toggle_ok, 1, 0, "gpio toggled ok");
CHECK(4, 6, n, 80, 10, "number of notifications");
}
int t5_count = 0;
void t5cbf(unsigned gpio, unsigned level, uint32_t tick)
{
t5_count++;
}
void t5()
{
int BAUD=4800;
char *TEXT=
"\n\
Now is the winter of our discontent\n\
Made glorious summer by this sun of York;\n\
And all the clouds that lour'd upon our house\n\
In the deep bosom of the ocean buried.\n\
Now are our brows bound with victorious wreaths;\n\
Our bruised arms hung up for monuments;\n\
Our stern alarums changed to merry meetings,\n\
Our dreadful marches to delightful measures.\n\
Grim-visaged war hath smooth'd his wrinkled front;\n\
And now, instead of mounting barded steeds\n\
To fright the souls of fearful adversaries,\n\
He capers nimbly in a lady's chamber\n\
To the lascivious pleasing of a lute.\n\
";
gpioPulse_t wf[] =
{
{1<<GPIO, 0, 10000},
{0, 1<<GPIO, 30000},
{1<<GPIO, 0, 60000},
{0, 1<<GPIO, 100000},
};
int e, oc, c;
char text[2048];
printf("Waveforms & serial read/write tests.\n");
callback(GPIO, FALLING_EDGE, t5cbf);
set_mode(GPIO, PI_OUTPUT);
e = wave_clear();
CHECK(5, 1, e, 0, 0, "callback, set mode, wave clear");
e = wave_add_generic(4, wf);
CHECK(5, 2, e, 4, 0, "pulse, wave add generic");
e = wave_tx_repeat();
CHECK(5, 3, e, 9, 0, "wave tx repeat");
oc = t5_count;
time_sleep(5);
c = t5_count - oc;
CHECK(5, 4, c, 50, 1, "callback");
e = wave_tx_stop();
CHECK(5, 5, e, 0, 0, "wave tx stop");
e = serial_read_open(GPIO, BAUD);
CHECK(5, 6, e, 0, 0, "serial read open");
wave_clear();
e = wave_add_serial(GPIO, BAUD, 5000000, strlen(TEXT), TEXT);
CHECK(5, 7, e, 3405, 0, "wave clear, wave add serial");
e = wave_tx_start();
CHECK(5, 8, e, 6811, 0, "wave tx start");
oc = t5_count;
time_sleep(3);
c = t5_count - oc;
CHECK(5, 9, c, 0, 0, "callback");
oc = t5_count;
while (wave_tx_busy()) time_sleep(0.1);
time_sleep(0.1);
c = t5_count - oc;
CHECK(5, 10, c, 1702, 0, "wave tx busy, callback");
c = serial_read(GPIO, text, sizeof(text)-1);
if (c > 0) text[c] = 0; /* null terminate string */
CHECK(5, 11, strcmp(TEXT, text), 0, 0, "wave tx busy, serial read");
e = serial_read_close(GPIO);
CHECK(5, 12, e, 0, 0, "serial read close");
c = wave_get_micros();
CHECK(5, 13, c, 6158704, 0, "wave get micros");
c = wave_get_high_micros();
CHECK(5, 14, c, 6158704, 0, "wave get high micros");
c = wave_get_max_micros();
CHECK(5, 15, c, 1800000000, 0, "wave get max micros");
c = wave_get_pulses();
CHECK(5, 16, c, 3405, 0, "wave get pulses");
c = wave_get_high_pulses();
CHECK(5, 17, c, 3405, 0, "wave get high pulses");
c = wave_get_max_pulses();
CHECK(5, 18, c, 12000, 0, "wave get max pulses");
c = wave_get_cbs();
CHECK(5, 19, c, 6810, 0, "wave get cbs");
c = wave_get_high_cbs();
CHECK(5, 20, c, 6810, 0, "wave get high cbs");
c = wave_get_max_cbs();
CHECK(5, 21, c, 25016, 0, "wave get max cbs");
}
int t6_count=0;
int t6_on=0;
uint32_t t6_on_tick=0;
void t6cbf(unsigned gpio, unsigned level, uint32_t tick)
{
if (level == 1)
{
t6_on_tick = tick;
t6_count++;
}
else
{
if (t6_on_tick) t6_on += (tick - t6_on_tick);
}
}
void t6()
{
int tp, t, p;
printf("Trigger tests.\n");
gpio_write(GPIO, PI_LOW);
tp = 0;
callback(GPIO, EITHER_EDGE, t6cbf);
time_sleep(0.2);
for (t=0; t<10; t++)
{
time_sleep(0.1);
p = 10 + (t*10);
tp += p;
gpio_trigger(4, p, 1);
}
time_sleep(0.5);
CHECK(6, 1, t6_count, 10, 0, "gpio trigger count");
CHECK(6, 2, t6_on, tp, 25, "gpio trigger pulse length");
}
int t7_count=0;
void t7cbf(unsigned gpio, unsigned level, uint32_t tick)
{
if (level == PI_TIMEOUT) t7_count++;
}
void t7()
{
int c, oc;
printf("Watchdog tests.\n");
/* type of edge shouldn't matter for watchdogs */
callback(GPIO, FALLING_EDGE, t7cbf);
set_watchdog(GPIO, 10); /* 10 ms, 100 per second */
time_sleep(0.5);
oc = t7_count;
time_sleep(2);
c = t7_count - oc;
CHECK(7, 1, c, 200, 1, "set watchdog on count");
set_watchdog(GPIO, 0); /* 0 switches watchdog off */
time_sleep(0.5);
oc = t7_count;
time_sleep(2);
c = t7_count - oc;
CHECK(7, 2, c, 0, 1, "set watchdog off count");
}
void t8()
{
int v, t, i;
printf("Bank read/write tests.\n");
gpio_write(GPIO, 0);
v = read_bank_1() & (1<<GPIO);
CHECK(8, 1, v, 0, 0, "read bank 1");
gpio_write(GPIO, 1);
v = read_bank_1() & (1<<GPIO);
CHECK(8, 2, v, (1<<GPIO), 0, "read bank 1");
clear_bank_1(1<<GPIO);
v = gpio_read(GPIO);
CHECK(8, 3, v, 0, 0, "clear bank 1");
set_bank_1(1<<GPIO);
v = gpio_read(GPIO);
CHECK(8, 4, v, 1, 0, "set bank 1");
t = 0;
v = (1<<16);
for (i=0; i<100; i++)
{
if (read_bank_2() & v) t++;
};
CHECK(8, 5, t, 60, 75, "read bank 2");
v = clear_bank_2(0);
CHECK(8, 6, v, 0, 0, "clear bank 2");
v = clear_bank_2(0xffffff);
CHECK(8, 7, v, PI_SOME_PERMITTED, 0, "clear bank 2");
v = set_bank_2(0);
CHECK(8, 8, v, 0, 0, "set bank 2");
v = set_bank_2(0xffffff);
CHECK(8, 9, v, PI_SOME_PERMITTED, 0, "set bank 2");
}
int t9_count = 0;
void t9cbf(unsigned gpio, unsigned level, uint32_t tick)
{
t9_count++;
}
void t9()
{
int s, oc, c, e;
uint32_t p[10];
printf("Script store/run/status/stop/delete tests.\n");
gpio_write(GPIO, 0); /* need known state */
/*
100 loops per second
p0 number of loops
p1 GPIO
*/
char *script="\
ldap 0\
ldva 0\
label 0\
w p1 1\
milli 5\
w p1 0\
milli 5\
dcrv 0\
ldav 0\
ldpa 9\
jp 0";
callback(GPIO, RISING_EDGE, t9cbf);
s = store_script(script);
oc = t9_count;
p[0] = 99;
p[1] = GPIO;
run_script(s, 2, p);
time_sleep(2);
c = t9_count - oc;
CHECK(9, 1, c, 100, 0, "store/run script");
oc = t9_count;
p[0] = 200;
p[1] = GPIO;
run_script(s, 2, p);
while (1)
{
e = script_status(s, p);
if (e != PI_SCRIPT_RUNNING) break;
time_sleep(0.5);
}
c = t9_count - oc;
time_sleep(0.1);
CHECK(9, 2, c, 201, 0, "run script/script status");
oc = t9_count;
p[0] = 2000;
p[1] = GPIO;
run_script(s, 2, p);
while (1)
{
e = script_status(s, p);
if (e != PI_SCRIPT_RUNNING) break;
if (p[9] < 1900) stop_script(s);
time_sleep(0.1);
}
c = t9_count - oc;
time_sleep(0.1);
CHECK(9, 3, c, 110, 10, "run/stop script/script status");
e = delete_script(s);
CHECK(9, 4, e, 0, 0, "delete script");
}
int main(int argc, char *argv[])
{
int t, status;
void (*test[])(void) = {t0, t1, t2, t3, t4, t5, t6, t7, t8, t9};
status = pigpio_start(0, 0);
if (status < 0)
{
fprintf(stderr, "pigpio initialisation failed.\n");
return 1;
}
printf("Connected to pigpio daemon.\n");
for (t=0; t<10; t++) test[t]();
pigpio_stop();
return 0;
}

271
x_pigs Executable file
View File

@ -0,0 +1,271 @@
#!/bin/bash
GPIO=4
#
# This script serves as a confidence check that the socket interface to
# the pigpio library is ok.
#
# The script uses gpio 4 (P1-7). Make sure that nothing (or only a LED)
# is connected to gpio 4 before running the script.
#
# To run the script
# sudo pigpiod # if not already running on the Pi
# export PIGPIO_ADDR=pi_host # to specify the Pi if testing remotely
# ./x_pigs
#
s=$(pigs bc1 0)
if [[ $s = "" ]]; then echo "BC1 ok"; else echo "BC1 fail ($s)"; fi
s=$(pigs bc2 0)
if [[ $s = "" ]]; then echo "BC2 ok"; else echo "BC2 fail ($s)"; fi
s=$(pigs br1)
if [[ ${#s} = 8 ]]
then echo "BR1 ok"
else echo "BR1 fail ($s)"
fi
s=$(pigs br2)
if [[ ${#s} = 8 ]]
then echo "BR2 ok"
else echo "BR2 fail ($s)"
fi
s=$(pigs bs1 0)
if [[ $s = "" ]]; then echo "BS1 ok"; else echo "BS1 fail ($s)"; fi
s=$(pigs bs2 0)
if [[ $s = "" ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi
s=$(pigs h)
if [[ ${#s} = 2999 ]]; then echo "HELP ok"; else echo "HELP fail (${#s})"; fi
s=$(pigs hwver)
if [[ $s -ne 0 ]]; then echo "HWVER ok"; else echo "HWVER fail ($s)"; fi
s=$(pigs micro 1000)
if [[ $s = "" ]]; then echo "MICRO ok"; else echo "MICRO fail ($s)"; fi
s=$(pigs milli 10)
if [[ $s = "" ]]; then echo "MILLI ok"; else echo "MILLI fail ($s)"; fi
s=$(pigs modes $GPIO 0)
s=$(pigs modeg $GPIO)
if [[ $s = 4 ]]; then echo "MODEG ok"; else echo "MODEG fail ($s)"; fi
s=$(pigs m $GPIO r)
s=$(pigs mg $GPIO)
if [[ $s = 0 ]]; then echo "MODES ok"; else echo "MODES fail ($s)"; fi
h=$(pigs no)
if [[ $h -ge 0 && $h -le 31 ]]
then echo "NO($h) ok"
else echo "NO fail ($s)"
fi
s=$(pigs nb $h 0xabcd)
if [[ $s = "" ]]; then echo "NB($h) ok"; else echo "NB fail ($s)"; fi
s=$(pigs np $h)
if [[ $s = "" ]]; then echo "NP($h) ok"; else echo "NP fail ($s)"; fi
s=$(pigs nc $h)
if [[ $s = "" ]]; then echo "NC($h) ok"; else echo "NC fail ($s)"; fi
s=$(pigs pfs $GPIO 800)
if [[ $s = 800 ]]; then echo "PFG-a ok"; else echo "PFG-a fail ($s)"; fi
s=$(pigs pfg $GPIO)
if [[ $s = 800 ]]; then echo "PFG-b ok"; else echo "PFG-b fail ($s)"; fi
s=$(pigs pfs $GPIO 0)
if [[ $s = 10 ]]; then echo "PFS-a ok"; else echo "PFS-a fail ($s)"; fi
s=$(pigs pfs $GPIO 800)
if [[ $s = 800 ]]; then echo "PFS-b ok"; else echo "PFS-b fail ($s)"; fi
s=$(pigs pigpv)
if [[ $s = 13 ]]; then echo "PIGPV ok"; else echo "PIGPV fail ($s)"; fi
s=$(pigs prs $GPIO 255)
if [[ $s = 250 ]]; then echo "PRG-a ok"; else echo "PRG-a fail ($s)"; fi
s=$(pigs prg $GPIO)
if [[ $s = 255 ]]; then echo "PRG-b ok"; else echo "PRG-b fail ($s)"; fi
p=$(pigs proc ldap 0 ldpa 1 ldai 1234 ldpa 0 label 999 milli 1000 jmp 999)
if [[ $p -ge 0 && $p -le 31 ]]
then echo "PROC($p) ok"
else echo "PROC($p) fail ($s)"
fi
s=$(pigs procr $p 9876)
if [[ $s = 0 ]]; then echo "PROCR($p) ok"; else echo "PROCR($p) fail ($s)"; fi
s=$(pigs procp $p)
v=(${s// / })
if [[ ${v[0]} = 1 && ${v[1]} = 1234 && ${v[2]} = 9876 ]]
then echo "PROCP($p) ok"
else echo "PROCP($p) fail ($s)"
fi
s=$(pigs procs $p)
if [[ $s = 0 ]]; then echo "PROCS($p) ok"; else echo "PROCS($p) fail ($s)"; fi
s=$(pigs procd $p)
if [[ $s = 0 ]]; then echo "PROCD($p) ok"; else echo "PROCD($p) fail ($s)"; fi
s=$(pigs prrg $GPIO)
if [[ $s = 250 ]]; then echo "PRRG ok"; else echo "PRRG fail ($s)"; fi
s=$(pigs prs $GPIO 1000)
if [[ $s = 250 ]]; then echo "PRS-a ok"; else echo "PRS-a fail ($s)"; fi
s=$(pigs prg $GPIO)
if [[ $s = 1000 ]]; then echo "PRS-b ok"; else echo "PRS-b fail ($s)"; fi
s=$(pigs prs $GPIO 255)
if [[ $s = 250 ]]; then echo "PRS-c ok"; else echo "PRS-c fail ($s)"; fi
s=$(pigs prg $GPIO)
if [[ $s = 255 ]]; then echo "PRS-d ok"; else echo "PRS-d fail ($s)"; fi
s=$(pigs pud $GPIO u)
if [[ $s = "" ]]; then echo "PUD-a ok"; else echo "PUD-a fail ($s)"; fi
s=$(pigs r $GPIO)
if [[ $s = 1 ]]; then echo "PUD-b ok"; else echo "PUD-b fail ($s)"; fi
s=$(pigs pud $GPIO d)
if [[ $s = "" ]]; then echo "PUD-c ok"; else echo "PUD-c fail ($s)"; fi
s=$(pigs r $GPIO)
if [[ $s = 0 ]]; then echo "PUD-d ok"; else echo "PUD-d fail ($s)"; fi
s=$(pigs pud $GPIO o)
if [[ $s = "" ]]; then echo "PUD-e ok"; else echo "PUD-e fail ($s)"; fi
s=$(pigs p $GPIO 128)
if [[ $s = "" ]]; then echo "PWM-a ok"; else echo "PWM-a fail ($s)"; fi
s=$(pigs pwm $GPIO 64)
if [[ $s = "" ]]; then echo "PWM-b ok"; else echo "PWM-b fail ($s)"; fi
s=$(pigs pwm $GPIO 0)
if [[ $s = "" ]]; then echo "PWM-c ok"; else echo "PWM-c fail ($s)"; fi
s=$(pigs m $GPIO r)
if [[ $s = "" ]]; then echo "PWM-d ok"; else echo "PWM-d fail ($s)"; fi
s=$(pigs pud $GPIO u)
if [[ $s = "" ]]; then echo "READ-a ok"; else echo "READ-a fail ($s)"; fi
s=$(pigs r $GPIO)
if [[ $s = 1 ]]; then echo "READ-b ok"; else echo "READ-b fail ($s)"; fi
s=$(pigs pud $GPIO d)
if [[ $s = "" ]]; then echo "READ-c ok"; else echo "READ-c fail ($s)"; fi
s=$(pigs read $GPIO)
if [[ $s = 0 ]]; then echo "READ-d ok"; else echo "READ-d fail ($s)"; fi
s=$(pigs pud $GPIO o)
if [[ $s = "" ]]; then echo "READ-e ok"; else echo "READ-e fail ($s)"; fi
s=$(pigs s $GPIO 500)
if [[ $s = "" ]]; then echo "SERVO-a ok"; else echo "SERVO-a fail ($s)"; fi
s=$(pigs servo $GPIO 2500)
if [[ $s = "" ]]; then echo "SERVO-b ok"; else echo "SERVO-b fail ($s)"; fi
s=$(pigs servo $GPIO 0)
if [[ $s = "" ]]; then echo "SERVO-c ok"; else echo "SERVO-c fail ($s)"; fi
s=$(pigs w $GPIO 1)
if [[ $s = "" ]]; then echo "SERVO-d ok"; else echo "SERVO-d fail ($s)"; fi
s=$(pigs wvclr)
if [[ $s = 0 ]]; then echo "SLR-a ok"; else echo "SLR-a fail ($s)"; fi
s=$(pigs slro $GPIO 1200)
if [[ $s = 0 ]]; then echo "SLR-b ok"; else echo "SLR-b fail ($s)"; fi
s=$(pigs wvas $GPIO 1200 0 "my name is joan")
if [[ $s = 95 ]]; then echo "SLR-c ok"; else echo "SLR-c fail ($s)"; fi
s=$(pigs m $GPIO w)
if [[ $s = "" ]]; then echo "SLR-d ok"; else echo "SLR-d fail ($s)"; fi
s=$(pigs wvgo)
if [[ $s = 191 ]]; then echo "SLR-e ok"; else echo "SLR-e fail ($s)"; fi
sleep 0.1
s=$(pigs slr $GPIO 100)
if [[ $s = "my name is joan" ]]
then echo "SLR-f ok"
else echo "SLR-f fail with [$s]"
fi
s=$(pigs slrc $GPIO)
if [[ $s = 0 ]]; then echo "SLR-g ok"; else echo "SLR-g fail ($s)"; fi
t1=$(pigs t)
t2=$(pigs tick)
s=$(($t2-$t1))
if [[ $s -gt 0 && $s -lt 20000 ]]
then echo "TICK ok"
else echo "TICK fail($s)"
fi
pigs w $GPIO 1 # put in known state
s=$(pigs trig $GPIO 10 1)
if [[ $s = "" ]]; then echo "TRIG-a ok"; else echo "TRIG-a fail ($s)"; fi
s=$(pigs r $GPIO)
if [[ $s = 0 ]]; then echo "TRIG-b ok"; else echo "TRIG-b fail ($s)"; fi
s=$(pigs trig $GPIO 10 0)
if [[ $s = "" ]]; then echo "TRIG-c ok"; else echo "TRIG-c fail ($s)"; fi
s=$(pigs r $GPIO)
if [[ $s = 1 ]]; then echo "TRIG-d ok"; else echo "TRIG-d fail ($s)"; fi
s=$(pigs wdog $GPIO 1000)
if [[ $s = "" ]]; then echo "WDOG-a ok"; else echo "WDOG-a fail ($s)"; fi
s=$(pigs wdog $GPIO 0)
if [[ $s = "" ]]; then echo "WDOG-b ok"; else echo "WDOG-b fail ($s)"; fi
s=$(pigs w $GPIO 1)
if [[ $s = "" ]]; then echo "WRITE-a ok"; else echo "WRITE-a fail ($s)"; fi
s=$(pigs r $GPIO)
if [[ $s = 1 ]]; then echo "WRITE-b ok"; else echo "WRITE-b fail ($s)"; fi
s=$(pigs write $GPIO 0)
if [[ $s = "" ]]; then echo "WRITE-c ok"; else echo "WRITE-c fail ($s)"; fi
s=$(pigs r $GPIO)
if [[ $s = 0 ]]; then echo "WRITE-d ok"; else echo "WRITE-d fail ($s)"; fi
s=$(pigs wvclr )
if [[ $s = 0 ]]; then echo "WVCLR ok"; else echo "WVCLR fail ($s)"; fi
s=$(pigs wvas $GPIO 300 0 "this is then winter of my discontent made glorious")
if [[ $s = 309 ]]; then echo "WVAS ok"; else echo "WVAS fail ($s)"; fi
s=$(pigs wvag 16 0 5000000 0 16 5000000)
if [[ $s = 310 ]]; then echo "WVAG ok"; else echo "WVAG fail ($s)"; fi
s=$(pigs wvgo)
if [[ $s = 621 ]]; then echo "WVGO ok"; else echo "WVGO fail ($s)"; fi
s=$(pigs wvbsy)
if [[ $s = 1 ]]; then echo "WVBSY-a ok"; else echo "WVBSY-a fail ($s)"; fi
sleep 1
s=$(pigs wvbsy)
if [[ $s = 1 ]]; then echo "WVBSY-b ok"; else echo "WVBSY-b fail ($s)"; fi
s=$(pigs wvhlt)
if [[ $s = 0 ]]; then echo "WVHLT ok"; else echo "WVHLT fail ($s)"; fi
s=$(pigs wvbsy)
if [[ $s = 0 ]]; then echo "WVBSY-c ok"; else echo "WVBSY-c fail ($s)"; fi
s=$(pigs wvgor)
if [[ $s = 621 ]]; then echo "WVGOR ok"; else echo "WVGOR fail ($s)"; fi
s=$(pigs wvbsy)
if [[ $s = 1 ]]; then echo "WVBSY-d ok"; else echo "WVBSY-d fail ($s)"; fi
s=$(pigs wvhlt)
if [[ $s = 0 ]]; then echo "WVHLT ok"; else echo "WVHLT fail ($s)"; fi
s=$(pigs wvbsy)
if [[ $s = 0 ]]; then echo "WVBSY-e ok"; else echo "WVBSY-e fail ($s)"; fi
s=$(pigs wvsc 0)
if [[ $s = 620 ]]; then echo "WVSC-a ok"; else echo "WVSC-a fail ($s)"; fi
s=$(pigs wvsc 1)
if [[ $s -ge 620 ]]; then echo "WVSC-b ok"; else echo "WVSC-b fail ($s)"; fi
s=$(pigs wvsc 2)
if [[ $s = 25016 ]]; then echo "WVSC-c ok"; else echo "WVSC-c fail ($s)"; fi
s=$(pigs wvsm 0)
if [[ $s = 10000000 ]]; then echo "WVSM-a ok"; else echo "WVSM-a fail ($s)"; fi
s=$(pigs wvsm 1)
if [[ $s -ge 10000000 ]]; then echo "WVSM-b ok"; else echo "WVSM-b fail ($s)"; fi
s=$(pigs wvsm 2)
if [[ $s = 1800000000 ]]
then echo "WVSM-c ok"
else echo "WVSM-c fail ($s)"
fi
s=$(pigs wvsp 0)
if [[ $s = 310 ]]; then echo "WVSP-a ok"; else echo "WVSP-a fail ($s)"; fi
s=$(pigs wvsp 1)
if [[ $s -ge 310 ]]; then echo "WVSP-b ok"; else echo "WVSP-b fail ($s)"; fi
s=$(pigs wvsp 2)
if [[ $s = 12000 ]]; then echo "WVSP-c ok"; else echo "WVSP-c fail ($s)"; fi

373
x_pipe Executable file
View File

@ -0,0 +1,373 @@
#!/bin/bash
GPIO=4
#
# This script serves as a confidence check that the pipe interface to
# the pigpio library is ok.
#
# The script uses gpio 4 (P1-7). Make sure that nothing (or only a LED)
# is connected to gpio 4 before running the script.
#
# To run the script
# sudo pigpiod # if not already running
# ./x_pipe # on the Pi running pigpiod
#
echo "bc1 0" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "BC1 ok"; else echo "BC1 fail ($s)"; fi
echo "bc2 0" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "BC2 ok"; else echo "BC2 fail ($s)"; fi
echo "br1" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ ${#s} = 8 ]]
then echo "BR1 ok"
else echo "BR1 fail ($s)"
fi
echo "br2" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ ${#s} = 8 ]]
then echo "BR2 ok"
else echo "BR2 fail ($s)"
fi
echo "bs1 0" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "BS1 ok"; else echo "BS1 fail ($s)"; fi
echo "bs2 0" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi
echo "h" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = "BC1 v Clear gpios defined by mask v in bank 1." ]]
then echo "HELP-a ok"
else echo "HELP-a fail ($s)"
fi
read -t 1 -N 9000 </dev/pigout # dump rest of help
echo "help" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = "BC1 v Clear gpios defined by mask v in bank 1." ]]
then echo "HELP-b ok"
else echo "HELP-b fail ($s)"
fi
read -t 1 -N 9000 </dev/pigout # dump rest of help
echo "hwver" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s -ne 0 ]]; then echo "HWVER ok"; else echo "HWVER fail ($s)"; fi
echo "micro 1000" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "MICRO ok"; else echo "MICRO fail ($s)"; fi
echo "milli 10" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "MILLI ok"; else echo "MILLI fail ($s)"; fi
echo "modes $GPIO 0" >/dev/pigpio
read -t 1 s </dev/pigout
echo "modeg $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 4 ]]; then echo "MODEG ok"; else echo "MODEG fail ($s)"; fi
echo "m $GPIO r" >/dev/pigpio
read -t 1 s </dev/pigout
echo "mg $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "MODES ok"; else echo "MODES fail ($s)"; fi
echo "no" >/dev/pigpio
read -t 1 h </dev/pigout
if [[ $h -ge 0 && $h -le 31 ]]
then echo "NO($h) ok"
else echo "NO fail ($s)"
fi
echo "nb $h 0xabcd" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "NB($h) ok"; else echo "NB fail ($s)"; fi
echo "np $h" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "NP($h) ok"; else echo "NP fail ($s)"; fi
echo "nc $h" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "NC($h) ok"; else echo "NC fail ($s)"; fi
echo "pfs $GPIO 800" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 800 ]]; then echo "PFG-a ok"; else echo "PFG-a fail ($s)"; fi
echo "pfg $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 800 ]]; then echo "PFG-b ok"; else echo "PFG-b fail ($s)"; fi
echo "pfs $GPIO 0" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 10 ]]; then echo "PFS-a ok"; else echo "PFS-a fail ($s)"; fi
echo "pfs $GPIO 800" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 800 ]]; then echo "PFS-b ok"; else echo "PFS-b fail ($s)"; fi
echo "pigpv" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 13 ]]; then echo "PIGPV ok"; else echo "PIGPV fail ($s)"; fi
echo "prs $GPIO 255" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 250 ]]; then echo "PRG-a ok"; else echo "PRG-a fail ($s)"; fi
echo "prg $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 255 ]]; then echo "PRG-b ok"; else echo "PRG-b fail ($s)"; fi
echo "proc ldap 0 ldpa 1 ldai 29 ldpa 0 label 9 milli 1000 jmp 9" >/dev/pigpio
read -t 1 p </dev/pigout
if [[ $p -ge 0 && $p -le 31 ]]
then echo "PROC($p) ok"
else echo "PROC($p) fail ($s)"
fi
echo "procr $p 9876" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "PROCR($p) ok"; else echo "PROCR($p) fail ($s)"; fi
echo "procp $p" >/dev/pigpio
read -t 1 -a v </dev/pigout
if [[ ${v[0]} = 1 && ${v[1]} = 29 && ${v[2]} = 9876 ]]
then echo "PROCP($p) ok"
else echo "PROCP($p) fail ($s)"
fi
echo "procs $p" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "PROCS($p) ok"; else echo "PROCS($p) fail ($s)"; fi
echo "procd $p" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "PROCD($p) ok"; else echo "PROCD($p) fail ($s)"; fi
echo "prrg $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 250 ]]; then echo "PRRG ok"; else echo "PRRG fail ($s)"; fi
echo "prs $GPIO 1000" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 250 ]]; then echo "PRS-a ok"; else echo "PRS-a fail ($s)"; fi
echo "prg $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 1000 ]]; then echo "PRS-b ok"; else echo "PRS-b fail ($s)"; fi
echo "prs $GPIO 255" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 250 ]]; then echo "PRS-c ok"; else echo "PRS-c fail ($s)"; fi
echo "prg $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 255 ]]; then echo "PRS-d ok"; else echo "PRS-d fail ($s)"; fi
echo "pud $GPIO u" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "PUD-a ok"; else echo "PUD-a fail ($s)"; fi
echo "r $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 1 ]]; then echo "PUD-b ok"; else echo "PUD-b fail ($s)"; fi
echo "pud $GPIO d" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "PUD-c ok"; else echo "PUD-c fail ($s)"; fi
echo "r $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "PUD-d ok"; else echo "PUD-d fail ($s)"; fi
echo "pud $GPIO o" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "PUD-e ok"; else echo "PUD-e fail ($s)"; fi
echo "p $GPIO 128" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "PWM-a ok"; else echo "PWM-a fail ($s)"; fi
echo "pwm $GPIO 64" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "PWM-b ok"; else echo "PWM-b fail ($s)"; fi
echo "pwm $GPIO 0" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "PWM-c ok"; else echo "PWM-c fail ($s)"; fi
echo "m $GPIO r" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "PWM-d ok"; else echo "PWM-d fail ($s)"; fi
echo "pud $GPIO u" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "READ-a ok"; else echo "READ-a fail ($s)"; fi
echo "r $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 1 ]]; then echo "READ-b ok"; else echo "READ-b fail ($s)"; fi
echo "pud $GPIO d" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "READ-c ok"; else echo "READ-c fail ($s)"; fi
echo "read $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "READ-d ok"; else echo "READ-d fail ($s)"; fi
echo "pud $GPIO o" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "READ-e ok"; else echo "READ-e fail ($s)"; fi
echo "s $GPIO 500" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "SERVO-a ok"; else echo "SERVO-a fail ($s)"; fi
echo "servo $GPIO 2500" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "SERVO-b ok"; else echo "SERVO-b fail ($s)"; fi
echo "servo $GPIO 0" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "SERVO-c ok"; else echo "SERVO-c fail ($s)"; fi
echo "w $GPIO 1" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "SERVO-d ok"; else echo "SERVO-d fail ($s)"; fi
echo "wvclr" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "SLR-a ok"; else echo "SLR-a fail ($s)"; fi
echo "slro $GPIO 1200" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "SLR-b ok"; else echo "SLR-b fail ($s)"; fi
echo "wvas $GPIO 1200 0 my name is joan¬" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 105 ]]; then echo "SLR-c ok"; else echo "SLR-c fail ($s)"; fi
echo "m $GPIO w" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "SLR-d ok"; else echo "SLR-d fail ($s)"; fi
echo "wvgo" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 211 ]]; then echo "SLR-e ok"; else echo "SLR-e fail ($s)"; fi
sleep 0.2
echo "slr $GPIO 100" >/dev/pigpio
read -t 1 -d ¬ s </dev/pigout
if [[ $s = "my name is joan" ]]
then echo "SLR-f ok"
else echo "SLR-f fail with ($s)"
fi
read -t 1 s </dev/pigout # dump any junk
echo "slrc $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "SLR-g ok"; else echo "SLR-g fail ($s)"; fi
echo "t" >/dev/pigpio
echo "tick" >/dev/pigpio
read -t 1 t1 </dev/pigout
read -t 1 t2 </dev/pigout
s=$((t2-t1))
if [[ $s -gt 0 && $s -lt 5000 ]]
then echo "TICK ok"
else echo "TICK fail ($s)"
fi
pigs w $GPIO 1 # put in known state
echo "trig $GPIO 10 1" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "TRIG-a ok"; else echo "TRIG-a fail ($s)"; fi
echo "r $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "TRIG-b ok"; else echo "TRIG-b fail ($s)"; fi
echo "trig $GPIO 10 0" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "TRIG-c ok"; else echo "TRIG-c fail ($s)"; fi
echo "r $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 1 ]]; then echo "TRIG-d ok"; else echo "TRIG-d fail ($s)"; fi
echo "wdog $GPIO 1000" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "WDOG-a ok"; else echo "WDOG-a fail ($s)"; fi
echo "wdog $GPIO 0" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "WDOG-b ok"; else echo "WDOG-b fail ($s)"; fi
echo "w $GPIO 1" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "WRITE-a ok"; else echo "WRITE-a fail ($s)"; fi
echo "r $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 1 ]]; then echo "WRITE-b ok"; else echo "WRITE-b fail ($s)"; fi
echo "write $GPIO 0" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "WRITE-c ok"; else echo "WRITE-c fail ($s)"; fi
echo "r $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "WRITE-d ok"; else echo "WRITE-d fail ($s)"; fi
echo "wvclr" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "WVCLR ok"; else echo "WVCLR fail ($s)"; fi
echo "wvas $GPIO 300 0 this is the winter of my discontent" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 215 ]]; then echo "WVAS ok"; else echo "WVAS fail ($s)"; fi
echo "wvag 16 0 5000000 0 16 5000000" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 216 ]]; then echo "WVAG ok"; else echo "WVAG fail ($s)"; fi
echo "wvgo" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 433 ]]; then echo "WVGO ok"; else echo "WVGO fail ($s)"; fi
echo "wvbsy" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 1 ]]; then echo "WVBSY-a ok"; else echo "WVBSY-a fail ($s)"; fi
sleep 1
echo "wvbsy" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 1 ]]; then echo "WVBSY-b ok"; else echo "WVBSY-b fail ($s)"; fi
echo "wvhlt" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "WVHLT ok"; else echo "WVHLT fail ($s)"; fi
echo "wvbsy" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "WVBSY-c ok"; else echo "WVBSY-c fail ($s)"; fi
echo "wvgor" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 433 ]]; then echo "WVGOR ok"; else echo "WVGOR fail ($s)"; fi
echo "wvbsy" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 1 ]]; then echo "WVBSY-d ok"; else echo "WVBSY-d fail ($s)"; fi
echo "wvhlt" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "WVHLT ok"; else echo "WVHLT fail ($s)"; fi
echo "wvbsy" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "WVBSY-e ok"; else echo "WVBSY-e fail ($s)"; fi
echo "wvsc 0" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 432 ]]; then echo "WVSC-a ok"; else echo "WVSC-a fail ($s)"; fi
echo "wvsc 1" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s -ge 432 ]]; then echo "WVSC-b ok"; else echo "WVSC-b fail ($s)"; fi
echo "wvsc 2" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 25016 ]]; then echo "WVSC-c ok"; else echo "WVSC-c fail ($s)"; fi
echo "wvsm 0" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 10000000 ]]; then echo "WVSM-a ok"; else echo "WVSM-a fail ($s)"; fi
echo "wvsm 1" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s -ge 10000000 ]]; then echo "WVSM-b ok"; else echo "WVSM-b fail ($s)"; fi
echo "wvsm 2" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 1800000000 ]]
then echo "WVSM-c ok"
else echo "WVSM-c fail ($s)"
fi
echo "wvsp 0" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 216 ]]; then echo "WVSP-a ok"; else echo "WVSP-a fail ($s)"; fi
echo "wvsp 1" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s -ge 216 ]]; then echo "WVSP-b ok"; else echo "WVSP-b fail ($s)"; fi
echo "wvsp 2" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 12000 ]]; then echo "WVSP-c ok"; else echo "WVSP-c fail ($s)"; fi