mirror of https://github.com/joan2937/pigpio
V11
This commit is contained in:
parent
7f0cf5a014
commit
23e3b179ab
|
@ -5,11 +5,11 @@ SIZE = size
|
|||
|
||||
CFLAGS = -O3 -Wall
|
||||
|
||||
ALL = libpigpiod_if.a pigs
|
||||
ALL = libpigpiod_if.a pigs pigpio.py setup.py
|
||||
|
||||
all: $(ALL)
|
||||
|
||||
pigs: command.o
|
||||
pigs: command.o pigs.o
|
||||
$(CC) -o pigs pigs.c command.c
|
||||
|
||||
clean:
|
||||
|
@ -41,7 +41,7 @@ $(LIB): $(OBJ)
|
|||
# generated using gcc -MM *.c
|
||||
|
||||
command.o: command.c pigpio.h command.h
|
||||
pigpiod.o: pigpiod.c pigpio.h command.h
|
||||
pigpiod_if.o: pigpiod_if.c pigpio.h pigpiod_if.h
|
||||
pigpiod.o: pigpiod.c pigpio.h
|
||||
pigpiod_if.o: pigpiod_if.c pigpio.h pigpiod_if.h command.h
|
||||
pigs.o: pigs.c pigpio.h command.h
|
||||
|
||||
|
|
2
Makefile
2
Makefile
|
@ -72,7 +72,7 @@ checklib.o: checklib.c pigpio.h
|
|||
command.o: command.c pigpio.h command.h
|
||||
pig2vcd.o: pig2vcd.c pigpio.h
|
||||
pigpio.o: pigpio.c pigpio.h command.h
|
||||
pigpiod.o: pigpiod.c pigpio.h command.h
|
||||
pigpiod.o: pigpiod.c pigpio.h
|
||||
pigpiod_if.o: pigpiod_if.c pigpio.h command.h pigpiod_if.h
|
||||
pigs.o: pigs.c pigpio.h command.h
|
||||
|
||||
|
|
3
README
3
README
|
@ -31,8 +31,7 @@ EXAMPLE CODE
|
|||
checklib.c, pig2vcd.c, and pigpiod.c
|
||||
show examples of interfacing with the pigpio library.
|
||||
|
||||
pigs.c, pigpio.py, and test_pigpiod_if.c
|
||||
show examples of interfacing with the pigpiod daemon.
|
||||
pigs.c and pigpio.py show examples of interfacing with the pigpiod daemon.
|
||||
|
||||
DAEMON
|
||||
|
||||
|
|
273
command.c
273
command.c
|
@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
|
|||
*/
|
||||
|
||||
/*
|
||||
This version is for pigpio version 10+
|
||||
This version is for pigpio version 11+
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -38,79 +38,144 @@ This version is for pigpio version 10+
|
|||
#include "pigpio.h"
|
||||
#include "command.h"
|
||||
|
||||
/* retv
|
||||
pigs pipe
|
||||
0 "" <0 ERR %d
|
||||
1 "" <0 ERR %d
|
||||
2 %d <0 ERR %d
|
||||
3 %08X %08X
|
||||
4 %u %u
|
||||
5 HELP HELP
|
||||
*/
|
||||
|
||||
/* vfyt
|
||||
1 cmd
|
||||
2 cmd %d
|
||||
3 cmd %d %d
|
||||
4 cmd %d %x
|
||||
6 HELP
|
||||
7 cmd %x
|
||||
8 MODES %d %c
|
||||
9 PUD %d %c
|
||||
10 PROG %s
|
||||
*/
|
||||
|
||||
cmdInfo_t cmdInfo[]=
|
||||
{
|
||||
{PI_CMD_BR1, "BR1", 1, 3},
|
||||
{PI_CMD_BR2, "BR2", 1, 3},
|
||||
{PI_CMD_BC1, "BC1", 7, 1},
|
||||
{PI_CMD_BC2, "BC2", 7, 1},
|
||||
{PI_CMD_BS1, "BS1", 7, 1},
|
||||
{PI_CMD_BS2, "BS2", 7, 1},
|
||||
{PI_CMD_HWVER, "HWVER", 1, 4},
|
||||
{PI_CMD_MODES, "MODES", 8, 0},
|
||||
{PI_CMD_MODES, "M", 8, 0},
|
||||
{PI_CMD_MODEG, "MODEG", 2, 2},
|
||||
{PI_CMD_MODEG, "MG" , 2, 2},
|
||||
{PI_CMD_NO, "NO", 1, 2},
|
||||
{PI_CMD_NB, "NB", 4, 0},
|
||||
{PI_CMD_NP, "NP", 2, 0},
|
||||
{PI_CMD_NC, "NC", 2, 0},
|
||||
{PI_CMD_PWM, "PWM", 3, 0},
|
||||
{PI_CMD_PWM, "P", 3, 0},
|
||||
{PI_CMD_PFS, "PFS", 3, 2},
|
||||
{PI_CMD_PFG, "PFG", 2, 2},
|
||||
{PI_CMD_PRS, "PRS", 3, 2},
|
||||
{PI_CMD_PRG, "PRG", 2, 2},
|
||||
{PI_CMD_PRRG, "PRRG", 2, 2},
|
||||
{PI_CMD_PUD, "PUD", 9, 0},
|
||||
{PI_CMD_READ, "READ", 2, 2},
|
||||
{PI_CMD_READ, "R", 2, 2},
|
||||
{PI_CMD_SERVO, "SERVO", 3, 0},
|
||||
{PI_CMD_SERVO, "S", 3, 0},
|
||||
{PI_CMD_WRITE, "WRITE", 3, 0},
|
||||
{PI_CMD_WRITE, "W", 3, 0},
|
||||
{PI_CMD_WDOG, "WDOG", 3, 0},
|
||||
{PI_CMD_TICK, "TICK", 1, 4},
|
||||
{PI_CMD_TICK, "T", 1, 4},
|
||||
{PI_CMD_HELP, "HELP", 6, 5},
|
||||
{PI_CMD_HELP, "H", 6, 5},
|
||||
{PI_CMD_PIGPV, "PIGPV", 1, 4},
|
||||
/* num str vfyt retv ext */
|
||||
|
||||
{PI_CMD_BC1, "BC1", 7, 1, 0},
|
||||
{PI_CMD_BC2, "BC2", 7, 1, 0},
|
||||
{PI_CMD_BR1, "BR1", 1, 3, 0},
|
||||
{PI_CMD_BR2, "BR2", 1, 3, 0},
|
||||
{PI_CMD_BS1, "BS1", 7, 1, 0},
|
||||
{PI_CMD_BS2, "BS2", 7, 1, 0},
|
||||
{PI_CMD_HELP, "H", 6, 5, 0},
|
||||
{PI_CMD_HELP, "HELP", 6, 5, 0},
|
||||
{PI_CMD_HWVER, "HWVER", 1, 4, 0},
|
||||
{PI_CMD_MODEG, "MG" , 2, 2, 0},
|
||||
{PI_CMD_MODEG, "MODEG", 2, 2, 0},
|
||||
{PI_CMD_MODES, "M", 8, 0, 0},
|
||||
{PI_CMD_MODES, "MODES", 8, 0, 0},
|
||||
{PI_CMD_NB, "NB", 4, 0, 0},
|
||||
{PI_CMD_NC, "NC", 2, 0, 0},
|
||||
{PI_CMD_NO, "NO", 1, 2, 0},
|
||||
{PI_CMD_NP, "NP", 2, 0, 0},
|
||||
{PI_CMD_PFG, "PFG", 2, 2, 0},
|
||||
{PI_CMD_PFS, "PFS", 3, 2, 0},
|
||||
{PI_CMD_PIGPV, "PIGPV", 1, 4, 0},
|
||||
{PI_CMD_PRG, "PRG", 2, 2, 0},
|
||||
{PI_CMD_PROC, "PROC", 10, 2, 1},
|
||||
{PI_CMD_PROCD, "PROCD", 2, 2, 0},
|
||||
{PI_CMD_PROCR, "PROCR", 2, 2, 0},
|
||||
{PI_CMD_PROCS, "PROCS", 2, 2, 0},
|
||||
{PI_CMD_PRRG, "PRRG", 2, 2, 0},
|
||||
{PI_CMD_PRS, "PRS", 3, 2, 0},
|
||||
{PI_CMD_PUD, "PUD", 9, 0, 0},
|
||||
{PI_CMD_PWM, "P", 3, 0, 0},
|
||||
{PI_CMD_PWM, "PWM", 3, 0, 0},
|
||||
{PI_CMD_READ, "R", 2, 2, 0},
|
||||
{PI_CMD_READ, "READ", 2, 2, 0},
|
||||
{PI_CMD_SERVO, "S", 3, 0, 0},
|
||||
{PI_CMD_SERVO, "SERVO", 3, 0, 0},
|
||||
{PI_CMD_WDOG, "WDOG", 3, 0, 0},
|
||||
{PI_CMD_WRITE, "W", 3, 0, 0},
|
||||
{PI_CMD_WRITE, "WRITE", 3, 0, 0},
|
||||
{PI_CMD_TICK, "T", 1, 4, 0},
|
||||
{PI_CMD_TICK, "TICK", 1, 4, 0},
|
||||
{PI_CMD_TRIG, "TRIG", 5, 0, 1},
|
||||
{PI_CMD_WVAS, "WVAS", 11, 2, 3},
|
||||
{PI_CMD_WVBSY, "WVBSY", 1, 2, 0},
|
||||
{PI_CMD_WVCLR, "WVCLR", 1, 2, 0},
|
||||
{PI_CMD_WVGO, "WVGO" , 1, 2, 0},
|
||||
{PI_CMD_WVGOR, "WVGOR", 1, 2, 0},
|
||||
{PI_CMD_WVHLT, "WVHLT", 1, 2, 0},
|
||||
{PI_CMD_WVSC, "WVSC", 2, 2, 0},
|
||||
{PI_CMD_WVSM, "WVSM", 2, 2, 0},
|
||||
{PI_CMD_WVSP, "WVSP", 2, 2, 0},
|
||||
};
|
||||
|
||||
char * cmdUsage = "\
|
||||
BR1 read gpios bank 1\n\
|
||||
BR2 read gpios bank 2\n\
|
||||
BC1 x clear gpios in bank 1\n\
|
||||
BC2 x clear gpios in bank 2\n\
|
||||
BR1 read gpios bank 1\n\
|
||||
BR2 read gpios bank 2\n\
|
||||
BS1 x set gpios in bank 1\n\
|
||||
BS2 x set gpios in bank 2\n\
|
||||
H displays command help\n\
|
||||
HELP displays command help\n\
|
||||
HWVER return hardware version\n\
|
||||
MODES/M g m set gpio mode\n\
|
||||
MODEG/MG g get gpio mode\n\
|
||||
NO request notification handle\n\
|
||||
M g m set gpio mode\n\
|
||||
MG g get gpio mode\n\
|
||||
MODEG g get gpio mode\n\
|
||||
MODES g m set gpio mode\n\
|
||||
NB h x start notification\n\
|
||||
NP h pause notification\n\
|
||||
NC h close notification\n\
|
||||
PWM/P u d set PWM value for gpio\n\
|
||||
PFS u d set PWM frequency for gpio\n\
|
||||
NO request notification handle\n\
|
||||
NP h pause notification\n\
|
||||
P u d set PWM value for gpio\n\
|
||||
PFG u get PWM frequency for gpio\n\
|
||||
PFS u d set PWM frequency for gpio\n\
|
||||
PIGPV return pigpio version\n\
|
||||
PRS u d set PWM range for gpio\n\
|
||||
PRG u get PWM range for gpio\n\
|
||||
PROC t validate and store script\n\
|
||||
PROCD s delete script\n\
|
||||
PROCR s run script\n\
|
||||
PROCS s stop script\n\
|
||||
PRRG u get PWM real range for gpio\n\
|
||||
PRS u d set PWM range for gpio\n\
|
||||
PUD g p set gpio pull up/down\n\
|
||||
READ/R g read gpio\n\
|
||||
SERVO/S u d set servo value for gpio\n\
|
||||
WRITE/W g d write value to gpio\n\
|
||||
PWM u d set PWM value for gpio\n\
|
||||
R g read gpio\n\
|
||||
READ g read gpio\n\
|
||||
S u d set servo value for gpio\n\
|
||||
SERVO u d set servo value for gpio\n\
|
||||
T return current tick\n\
|
||||
TICK return current tick\n\
|
||||
TRIG u pl l trigger level l for pl micros on gpio\n\
|
||||
W g l write level to gpio\n\
|
||||
WDOG u d set watchdog on gpio\n\
|
||||
TICK/T return current tick\n\
|
||||
HELP/H displays command help\n\
|
||||
WRITE g l write level to gpio\n\
|
||||
WVAS u b t wave add serial data\n\
|
||||
WVBSY check if wave busy\n\
|
||||
WVCLR wave clear\n\
|
||||
WVGO wave transmit\n\
|
||||
WVGOR wave transmit repeat\n\
|
||||
WVHLT wave stop\n\
|
||||
WVSC ws wave get cbs stats\n\
|
||||
WVSM ws wave get micros stats\n\
|
||||
WVSP ws wave get pulses stats\n\
|
||||
\n\
|
||||
b = baud rate\n\
|
||||
d = decimal value\n\
|
||||
g = gpio (0-53)\n\
|
||||
h = handle (0-31)\n\
|
||||
l = level (0-1)\n\
|
||||
m = mode (RW540123)\n\
|
||||
p = pud (ODU)\n\
|
||||
pl = pulse length (0-100)\n\
|
||||
s = script id\n\
|
||||
t = text\n\
|
||||
u = user gpio (0-31)\n\
|
||||
x = hex value\n\
|
||||
";
|
||||
|
@ -130,7 +195,7 @@ static errInfo_t errInfo[]=
|
|||
{PI_BAD_LEVEL , "level not 0-1"},
|
||||
{PI_BAD_PUD , "pud not 0-2"},
|
||||
{PI_BAD_PULSEWIDTH , "pulsewidth not 0 or 500-2500"},
|
||||
{PI_BAD_DUTYCYCLE , "dutycycle not 0-255"},
|
||||
{PI_BAD_DUTYCYCLE , "dutycycle outside set range"},
|
||||
{PI_BAD_TIMER , "timer not 0-9"},
|
||||
{PI_BAD_MS , "ms not 10-60000"},
|
||||
{PI_BAD_TIMETYPE , "timetype not 0-1"},
|
||||
|
@ -165,6 +230,13 @@ static errInfo_t errInfo[]=
|
|||
{PI_BAD_SERIAL_BUF , "bad (null) serial buf parameter"},
|
||||
{PI_NOT_PERMITTED , "no permission to update gpio"},
|
||||
{PI_SOME_PERMITTED , "no permission to update one or more gpios"},
|
||||
{PI_BAD_WVSC_COMMND , "bad WVSC subcommand"},
|
||||
{PI_BAD_WVSM_COMMND , "bad WVSM subcommand"},
|
||||
{PI_BAD_WVSP_COMMND , "bad WVSP subcommand"},
|
||||
{PI_BAD_PULSELEN , "trigger pulse > 100 microseconds"},
|
||||
{PI_BAD_SCRIPT , "invalid script"},
|
||||
{PI_BAD_SCRIPT_ID , "unknown script id"},
|
||||
{PI_BAD_SER_OFFSET , "add serial data offset > 30 minute"},
|
||||
};
|
||||
|
||||
static char * fmtMdeStr="RW540123";
|
||||
|
@ -181,11 +253,11 @@ static int cmdMatch(char * str)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int cmdParse(char * buf, cmdCmd_t * cmd)
|
||||
int cmdParse(char *buf, cmdCmd_t *cmd, int argc, char *argv[], gpioExtent_t *ext)
|
||||
{
|
||||
char str[8];
|
||||
int f, valid, idx, val;
|
||||
char * ptr;
|
||||
char *ptr;
|
||||
char c, t;
|
||||
|
||||
sscanf(buf, " %7s", str);
|
||||
|
@ -204,36 +276,57 @@ int cmdParse(char * buf, cmdCmd_t * cmd)
|
|||
|
||||
switch (cmdInfo[idx].vt)
|
||||
{
|
||||
case 1: /* BR1 BR2 HWVER PIGPV NO TICK */
|
||||
case 1: /* BR1 BR2 HWVER NO PIGPV TICK WVBSY WVCLR WVGO WVGOR
|
||||
WVHLT
|
||||
*/
|
||||
f = sscanf(buf, " %7s %c", str, &t);
|
||||
if (f == 1) valid = 1;
|
||||
break;
|
||||
|
||||
case 2: /* MODEG READ NC NP PFG PRG PRRG */
|
||||
case 2: /* MODEG NC NP PFG PRG PROCD PROCR PROCS PRRG READ
|
||||
WVSC WVSM WVSP
|
||||
*/
|
||||
f = sscanf(buf, " %7s %d %c", str, &cmd->p1, &t);
|
||||
if (f == 2) valid = 1;
|
||||
break;
|
||||
|
||||
case 3: /* WRITE PWM PRS PFS SERVO WDOG */
|
||||
|
||||
case 3: /* PFS PRS PWM SERVO WDOG WRITE
|
||||
*/
|
||||
f = sscanf(buf, " %7s %d %d %c", str, &cmd->p1, &cmd->p2, &t);
|
||||
if (f == 3) valid = 1;
|
||||
break;
|
||||
|
||||
case 4: /* NB */
|
||||
|
||||
case 4: /* NB
|
||||
*/
|
||||
f = sscanf(buf, " %7s %d %x %c", str, &cmd->p1, &cmd->p2, &t);
|
||||
if (f == 3) valid = 1;
|
||||
break;
|
||||
|
||||
case 6: /* HELP */
|
||||
|
||||
case 5: /* TRIG
|
||||
*/
|
||||
f = sscanf(buf, " %7s %d %d %d %c",
|
||||
str, &cmd->p1, &cmd->p2, &ext[0].data, &t);
|
||||
if (f == 4)
|
||||
{
|
||||
ext[0].n = sizeof(unsigned);
|
||||
ext[0].ptr = &ext[0].data;
|
||||
valid = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6: /* HELP
|
||||
*/
|
||||
valid = 1;
|
||||
break;
|
||||
|
||||
case 7: /* BC1 BC2 BS1 BS2 */
|
||||
|
||||
case 7: /* BC1 BC2 BS1 BS2
|
||||
*/
|
||||
f = sscanf(buf, " %7s %x %c", str, &cmd->p1, &t);
|
||||
if (f == 2) valid = 1;
|
||||
break;
|
||||
|
||||
case 8: /* MODES */
|
||||
|
||||
case 8: /* MODES
|
||||
*/
|
||||
f = sscanf(buf, " %7s %d %c %c", str, &cmd->p1, &c, &t);
|
||||
if (f == 3)
|
||||
{
|
||||
|
@ -248,7 +341,8 @@ int cmdParse(char * buf, cmdCmd_t * cmd)
|
|||
}
|
||||
break;
|
||||
|
||||
case 9: /* PUD */
|
||||
case 9: /* PUD
|
||||
*/
|
||||
f = sscanf(buf, " %7s %d %c %c", str, &cmd->p1, &c, &t);
|
||||
if (f == 3)
|
||||
{
|
||||
|
@ -262,28 +356,43 @@ int cmdParse(char * buf, cmdCmd_t * cmd)
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 10: /* PROC
|
||||
*/
|
||||
if (argc == 3)
|
||||
{
|
||||
cmd->p1 = strlen(argv[2]);
|
||||
ext[0].n = cmd->p1;
|
||||
ext[0].ptr = argv[2];
|
||||
valid = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 11: /* WVAS
|
||||
*/
|
||||
if (argc == 6)
|
||||
{
|
||||
f = sscanf(buf, " %7s %d %d %d ",
|
||||
str, &cmd->p1, &ext[0].data, &ext[1].data);
|
||||
if (f == 4)
|
||||
{
|
||||
ext[0].n = sizeof(unsigned);
|
||||
ext[0].ptr = &ext[0].data;
|
||||
ext[1].n = sizeof(unsigned);
|
||||
ext[1].ptr = &ext[1].data;
|
||||
cmd->p2 = strlen(argv[5]);
|
||||
ext[2].n = cmd->p2;
|
||||
ext[2].ptr = argv[5];
|
||||
valid = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (valid) return idx;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
void cmdFatal(char *fmt, ...)
|
||||
{
|
||||
char buf[128];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
|
||||
fflush(stderr);
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
char * cmdErrStr(int error)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
|
|||
*/
|
||||
|
||||
/*
|
||||
This version is for pigpio version 7+
|
||||
This version is for pigpio version 11+
|
||||
*/
|
||||
|
||||
#ifndef COMMAND_H
|
||||
|
@ -43,16 +43,17 @@ typedef struct
|
|||
char * name; /* command name */
|
||||
int vt; /* command verification type */
|
||||
int rv; /* command return value type */
|
||||
int ext; /* command has extensions */
|
||||
} cmdInfo_t;
|
||||
|
||||
extern cmdInfo_t cmdInfo[];
|
||||
|
||||
extern char * cmdUsage;
|
||||
|
||||
int cmdParse(char * buf, cmdCmd_t * cmd);
|
||||
int cmdParse
|
||||
(char *buf, cmdCmd_t *cmd, int argc, char *argv[], gpioExtent_t * ext);
|
||||
|
||||
char * cmdErrStr(int error);
|
||||
|
||||
void cmdFatal(char *fmt, ...);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
602
pigpio.c
602
pigpio.c
|
@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
|
|||
For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
/* pigpio version 10 */
|
||||
/* pigpio version 11 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -752,7 +752,7 @@ static int wfcur=0;
|
|||
|
||||
static wfStats_t wfStats=
|
||||
{
|
||||
0, 0, -1,
|
||||
0, 0, PI_WAVE_MAX_MICROS,
|
||||
0, 0, PI_WAVE_MAX_PULSES,
|
||||
0, 0, (PAGES_PER_BLOCK * CBS_PER_OPAGE)
|
||||
};
|
||||
|
@ -765,7 +765,7 @@ static volatile uint32_t notifyBits = 0;
|
|||
|
||||
static volatile int DMAstarted = 0;
|
||||
|
||||
static int libInitialised = 0;
|
||||
static int libInitialised = 0;
|
||||
|
||||
static int pthAlertRunning = 0;
|
||||
static int pthFifoRunning = 0;
|
||||
|
@ -881,7 +881,7 @@ static uint32_t myGpioDelay(uint32_t micros)
|
|||
|
||||
start = systReg[SYST_CLO];
|
||||
|
||||
if (micros < 100) while ((systReg[SYST_CLO] - start) <= micros) ;
|
||||
if (micros < 101) while ((systReg[SYST_CLO] - start) <= micros) ;
|
||||
|
||||
else myGpioSleep(micros/MILLION, micros%MILLION);
|
||||
|
||||
|
@ -977,104 +977,19 @@ static uint32_t myGetTick(int pos)
|
|||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static void myDoCommand(cmdCmd_t * cmd)
|
||||
static void myDoCommand(cmdCmd_t *cmd, gpioExtent_t *ext)
|
||||
{
|
||||
int p1, p2, res;
|
||||
uint32_t mask;
|
||||
int p1, p2, res, i;
|
||||
uint32_t mask, tmp;
|
||||
gpioPulse_t *pulse;
|
||||
int masked;
|
||||
|
||||
p1 = cmd->p1;
|
||||
p2 = cmd->p2;
|
||||
|
||||
res = 0;
|
||||
res = cmd->res;
|
||||
|
||||
switch (cmd->cmd)
|
||||
{
|
||||
case PI_CMD_MODES:
|
||||
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetMode(p1, p2);
|
||||
else
|
||||
{
|
||||
PERM_ERROR("gpioSetMode: gpio %d, no permission to update", p1);
|
||||
res = PI_NOT_PERMITTED;
|
||||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_MODEG:
|
||||
res = gpioGetMode(p1);
|
||||
break;
|
||||
|
||||
case PI_CMD_PUD:
|
||||
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetPullUpDown(p1, p2);
|
||||
else
|
||||
{
|
||||
PERM_ERROR(
|
||||
"gpioSetPullUpDown: gpio %d, no permission to update", p1);
|
||||
res = PI_NOT_PERMITTED;
|
||||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_READ:
|
||||
res = gpioRead(p1);
|
||||
break;
|
||||
|
||||
case PI_CMD_WRITE:
|
||||
if (gpioMask & (uint64_t)(1<<p1)) res = gpioWrite(p1, p2);
|
||||
else
|
||||
{
|
||||
PERM_ERROR("gpioWrite: gpio %d, no permission to update", p1);
|
||||
res = PI_NOT_PERMITTED;
|
||||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_PWM:
|
||||
if (gpioMask & (uint64_t)(1<<p1)) res = gpioPWM(p1, p2);
|
||||
else
|
||||
{
|
||||
PERM_ERROR("gpioPWM: gpio %d, no permission to update", p1);
|
||||
res = PI_NOT_PERMITTED;
|
||||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_PRS:
|
||||
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetPWMrange(p1, p2);
|
||||
else
|
||||
{
|
||||
PERM_ERROR(
|
||||
"gpioSetPWMrange: gpio %d, no permission to update", p1);
|
||||
res = PI_NOT_PERMITTED;
|
||||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_PFS:
|
||||
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetPWMfrequency(p1, p2);
|
||||
else
|
||||
{
|
||||
PERM_ERROR(
|
||||
"gpioSetPWMfrequency: gpio %d, no permission to update", p1);
|
||||
res = PI_NOT_PERMITTED;
|
||||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_SERVO:
|
||||
if (gpioMask & (uint64_t)(1<<p1)) res = gpioServo(p1, p2);
|
||||
else
|
||||
{
|
||||
PERM_ERROR("gpioServo: gpio %d, no permission to update", p1);
|
||||
res = PI_NOT_PERMITTED;
|
||||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_WDOG:
|
||||
res = gpioSetWatchdog(p1, p2);
|
||||
break;
|
||||
|
||||
case PI_CMD_BR1:
|
||||
res = gpioRead_Bits_0_31();
|
||||
break;
|
||||
|
||||
case PI_CMD_BR2:
|
||||
res = gpioRead_Bits_32_53();
|
||||
break;
|
||||
|
||||
case PI_CMD_BC1:
|
||||
mask = gpioMask;
|
||||
|
||||
|
@ -1103,6 +1018,10 @@ static void myDoCommand(cmdCmd_t * cmd)
|
|||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_BR1: res = gpioRead_Bits_0_31(); break;
|
||||
|
||||
case PI_CMD_BR2: res = gpioRead_Bits_32_53(); break;
|
||||
|
||||
case PI_CMD_BS1:
|
||||
mask = gpioMask;
|
||||
|
||||
|
@ -1131,52 +1050,209 @@ static void myDoCommand(cmdCmd_t * cmd)
|
|||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_TICK:
|
||||
res = gpioTick();
|
||||
case PI_CMD_HELP: break;
|
||||
|
||||
case PI_CMD_HWVER: res = gpioHardwareRevision(); break;
|
||||
|
||||
case PI_CMD_MODEG: res = gpioGetMode(p1); break;
|
||||
|
||||
case PI_CMD_MODES:
|
||||
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetMode(p1, p2);
|
||||
else
|
||||
{
|
||||
PERM_ERROR("gpioSetMode: gpio %d, no permission to update", p1);
|
||||
res = PI_NOT_PERMITTED;
|
||||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_HWVER:
|
||||
res = gpioHardwareRevision();
|
||||
case PI_CMD_NB: res = gpioNotifyBegin(p1, p2); break;
|
||||
|
||||
case PI_CMD_NC: res = gpioNotifyClose(p1); break;
|
||||
|
||||
case PI_CMD_NO: res = gpioNotifyOpen(); break;
|
||||
|
||||
case PI_CMD_NP: res = gpioNotifyPause(p1); break;
|
||||
|
||||
case PI_CMD_PFG: res = gpioGetPWMfrequency(p1); break;
|
||||
|
||||
case PI_CMD_PFS:
|
||||
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetPWMfrequency(p1, p2);
|
||||
else
|
||||
{
|
||||
PERM_ERROR(
|
||||
"gpioSetPWMfrequency: gpio %d, no permission to update", p1);
|
||||
res = PI_NOT_PERMITTED;
|
||||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_PRG:
|
||||
res = gpioGetPWMrange(p1);
|
||||
case PI_CMD_PIGPV: res = gpioVersion(); break;
|
||||
|
||||
case PI_CMD_PRG: res = gpioGetPWMrange(p1); break;
|
||||
|
||||
case PI_CMD_PROC:
|
||||
res = gpioStoreScript(ext[0].ptr);
|
||||
break;
|
||||
|
||||
case PI_CMD_PFG:
|
||||
res = gpioGetPWMfrequency(p1);
|
||||
case PI_CMD_PROCD: res = gpioDeleteScript(p1); break;
|
||||
|
||||
case PI_CMD_PROCR: res = gpioRunScript(p1); break;
|
||||
|
||||
case PI_CMD_PROCS: res = gpioStopScript(p1); break;
|
||||
|
||||
case PI_CMD_PRRG: res = gpioGetPWMrealRange(p1); break;
|
||||
|
||||
case PI_CMD_PRS:
|
||||
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetPWMrange(p1, p2);
|
||||
else
|
||||
{
|
||||
PERM_ERROR(
|
||||
"gpioSetPWMrange: gpio %d, no permission to update", p1);
|
||||
res = PI_NOT_PERMITTED;
|
||||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_PRRG:
|
||||
res = gpioGetPWMrealRange(p1);
|
||||
case PI_CMD_PUD:
|
||||
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetPullUpDown(p1, p2);
|
||||
else
|
||||
{
|
||||
PERM_ERROR(
|
||||
"gpioSetPullUpDown: gpio %d, no permission to update", p1);
|
||||
res = PI_NOT_PERMITTED;
|
||||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_NO:
|
||||
res = gpioNotifyOpen();
|
||||
case PI_CMD_PWM:
|
||||
if (gpioMask & (uint64_t)(1<<p1)) res = gpioPWM(p1, p2);
|
||||
else
|
||||
{
|
||||
PERM_ERROR("gpioPWM: gpio %d, no permission to update", p1);
|
||||
res = PI_NOT_PERMITTED;
|
||||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_NB:
|
||||
res = gpioNotifyBegin(p1, p2);
|
||||
case PI_CMD_READ: res = gpioRead(p1); break;
|
||||
|
||||
case PI_CMD_WDOG: res = gpioSetWatchdog(p1, p2); break;
|
||||
|
||||
case PI_CMD_WRITE:
|
||||
if (gpioMask & (uint64_t)(1<<p1)) res = gpioWrite(p1, p2);
|
||||
else
|
||||
{
|
||||
PERM_ERROR("gpioWrite: gpio %d, no permission to update", p1);
|
||||
res = PI_NOT_PERMITTED;
|
||||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_NP:
|
||||
res = gpioNotifyPause(p1);
|
||||
case PI_CMD_SERVO:
|
||||
if (gpioMask & (uint64_t)(1<<p1)) res = gpioServo(p1, p2);
|
||||
else
|
||||
{
|
||||
PERM_ERROR("gpioServo: gpio %d, no permission to update", p1);
|
||||
res = PI_NOT_PERMITTED;
|
||||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_NC:
|
||||
res = gpioNotifyClose(p1);
|
||||
case PI_CMD_TICK: res = gpioTick(); break;
|
||||
|
||||
case PI_CMD_TRIG:
|
||||
if (gpioMask & (uint64_t)(1<<p1))
|
||||
res = gpioTrigger(p1, p2, *(int *) (ext[0].ptr));
|
||||
else
|
||||
{
|
||||
PERM_ERROR("gpioTrigger: gpio %d, no permission to update", p1);
|
||||
res = PI_NOT_PERMITTED;
|
||||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_HELP:
|
||||
case PI_CMD_WVAG:
|
||||
|
||||
/* need to mask off any non permitted gpios */
|
||||
|
||||
mask = gpioMask;
|
||||
pulse = ext[0].ptr;
|
||||
masked = 0;
|
||||
|
||||
for (i=0; i<p1; i++)
|
||||
{
|
||||
tmp = pulse[i].gpioOn & mask;
|
||||
if (tmp != pulse[i].gpioOn)
|
||||
{
|
||||
pulse[i].gpioOn = tmp;
|
||||
masked = 1;
|
||||
}
|
||||
|
||||
tmp = pulse[i].gpioOff & mask;
|
||||
if (tmp != pulse[i].gpioOff)
|
||||
{
|
||||
pulse[i].gpioOff = tmp;
|
||||
masked = 1;
|
||||
}
|
||||
}
|
||||
|
||||
res = gpioWaveAddGeneric(p1, pulse);
|
||||
|
||||
/* report permission error unless another error occurred */
|
||||
if (masked && (res >= 0)) res = PI_SOME_PERMITTED;
|
||||
|
||||
break;
|
||||
|
||||
case PI_CMD_PIGPV:
|
||||
res = gpioVersion();
|
||||
case PI_CMD_WVAS:
|
||||
if (gpioMask & (uint64_t)(1<<p1))
|
||||
res = gpioWaveAddSerial
|
||||
(p1,
|
||||
*(int *)(ext[0].ptr),
|
||||
*(int *)(ext[1].ptr),
|
||||
p2,
|
||||
ext[2].ptr);
|
||||
else
|
||||
{
|
||||
PERM_ERROR
|
||||
("gpioWaveAddSerial: gpio %d, no permission to update", p1);
|
||||
res = PI_NOT_PERMITTED;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
case PI_CMD_WVBSY: res = gpioWaveTxBusy(); break;
|
||||
|
||||
cmd->res = res;
|
||||
case PI_CMD_WVCLR: res = gpioWaveClear(); break;
|
||||
|
||||
case PI_CMD_WVGO: res = gpioWaveTxStart(PI_WAVE_MODE_ONE_SHOT); break;
|
||||
|
||||
case PI_CMD_WVGOR: res = gpioWaveTxStart(PI_WAVE_MODE_REPEAT); break;
|
||||
|
||||
case PI_CMD_WVHLT: res = gpioWaveTxStop(); break;
|
||||
|
||||
case PI_CMD_WVSC:
|
||||
switch(p1)
|
||||
{
|
||||
case 0: res = gpioWaveGetCbs(); break;
|
||||
case 1: res = gpioWaveGetHighCbs(); break;
|
||||
case 2: res = gpioWaveGetMaxCbs(); break;
|
||||
default: res = -9999;
|
||||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_WVSM:
|
||||
switch(p1)
|
||||
{
|
||||
case 0: res = gpioWaveGetMicros(); break;
|
||||
case 1: res = gpioWaveGetHighMicros(); break;
|
||||
case 2: res = gpioWaveGetMaxMicros(); break;
|
||||
default: res = -9999;
|
||||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_WVSP:
|
||||
switch(p1)
|
||||
{
|
||||
case 0: res = gpioWaveGetPulses(); break;
|
||||
case 1: res = gpioWaveGetHighPulses(); break;
|
||||
case 2: res = gpioWaveGetMaxPulses(); break;
|
||||
default: res = -9999;
|
||||
}
|
||||
break;
|
||||
}
|
||||
cmd->res = res;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
@ -2545,9 +2621,10 @@ static void * pthTimerTick(void *x)
|
|||
|
||||
static void * pthFifoThread(void *x)
|
||||
{
|
||||
char inBuf[128];
|
||||
char inBuf[256];
|
||||
int idx, flags;
|
||||
cmdCmd_t cmd;
|
||||
gpioExtent_t ext[3];
|
||||
|
||||
myCreatePipe(PI_INPFIFO, 0662);
|
||||
|
||||
|
@ -2569,9 +2646,9 @@ static void * pthFifoThread(void *x)
|
|||
if (fgets(inBuf, sizeof(inBuf), inpFifo) == NULL)
|
||||
SOFT_ERROR((void*)PI_INIT_FAILED, "fifo fgets failed (%m)");
|
||||
|
||||
if ((idx=cmdParse(inBuf, &cmd)) >= 0)
|
||||
if ((idx=cmdParse(inBuf, &cmd, 0, NULL, ext)) >= 0)
|
||||
{
|
||||
myDoCommand(&cmd);
|
||||
myDoCommand(&cmd, NULL);
|
||||
|
||||
switch (cmdInfo[idx].rv)
|
||||
{
|
||||
|
@ -2611,24 +2688,150 @@ static void * pthFifoThread(void *x)
|
|||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static void * pthSocketThreadHandler(void *fdC)
|
||||
static void *pthSocketThreadHandler(void *fdC)
|
||||
{
|
||||
int sock = *(int*)fdC;
|
||||
cmdCmd_t cmd;
|
||||
|
||||
unsigned bytes;
|
||||
char *memPtr;
|
||||
gpioExtent_t ext[3];
|
||||
unsigned tmp;
|
||||
|
||||
free(fdC);
|
||||
|
||||
while(1)
|
||||
{
|
||||
if (recv(sock, &cmd, sizeof(cmdCmd_t), 0) == sizeof(cmdCmd_t))
|
||||
if (recv(sock, &cmd, sizeof(cmdCmd_t), MSG_WAITALL) == sizeof(cmdCmd_t))
|
||||
{
|
||||
if (cmd.cmd != PI_CMD_NOIB)
|
||||
if (cmd.cmd == PI_CMD_NOIB)
|
||||
{
|
||||
myDoCommand(&cmd);
|
||||
cmd.res = gpioNotifyOpenInBand(sock);
|
||||
}
|
||||
else if (cmd.cmd == PI_CMD_WVAG)
|
||||
{
|
||||
/*
|
||||
p1=numPulses
|
||||
p2=0
|
||||
## extension ##
|
||||
gpioPulse_t[] pulses
|
||||
*/
|
||||
|
||||
bytes = cmd.p1 * sizeof(gpioPulse_t);
|
||||
|
||||
memPtr = malloc(bytes);
|
||||
if (memPtr)
|
||||
{
|
||||
if (recv(sock, memPtr, bytes, MSG_WAITALL) == bytes)
|
||||
{
|
||||
ext[0].n = bytes;
|
||||
ext[0].ptr = memPtr;
|
||||
myDoCommand(&cmd, ext);
|
||||
free(memPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(memPtr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else break;
|
||||
|
||||
}
|
||||
else if (cmd.cmd == PI_CMD_WVAS)
|
||||
{
|
||||
/*
|
||||
p1=user_gpio
|
||||
p2=numChar
|
||||
## extension ##
|
||||
unsigned baud
|
||||
unsigned offset
|
||||
char[] str
|
||||
*/
|
||||
|
||||
bytes = sizeof(unsigned) + sizeof(unsigned) + cmd.p2;
|
||||
|
||||
memPtr = malloc(bytes+1); /* add 1 for a nul terminator */
|
||||
|
||||
if (memPtr)
|
||||
{
|
||||
if (recv(sock, memPtr, bytes, MSG_WAITALL) == bytes)
|
||||
{
|
||||
ext[0].n = sizeof(unsigned);
|
||||
ext[0].ptr = memPtr;
|
||||
ext[1].n = sizeof(unsigned);
|
||||
ext[1].ptr = memPtr + sizeof(unsigned);
|
||||
ext[2].n = cmd.p2;
|
||||
ext[2].ptr = memPtr + sizeof(unsigned) + sizeof(unsigned);
|
||||
memPtr[bytes] = 0; /* may be duplicate terminator */
|
||||
myDoCommand(&cmd, ext);
|
||||
free(memPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(memPtr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else break;
|
||||
|
||||
}
|
||||
else if (cmd.cmd == PI_CMD_PROC)
|
||||
{
|
||||
/*
|
||||
p1=script length
|
||||
p2=0
|
||||
## extension ##
|
||||
char[] script
|
||||
*/
|
||||
|
||||
bytes = cmd.p1;
|
||||
|
||||
memPtr = malloc(bytes+1); /* add 1 for a nul terminator */
|
||||
if (memPtr)
|
||||
{
|
||||
if (recv(sock, memPtr, bytes, MSG_WAITALL) == bytes)
|
||||
{
|
||||
ext[0].n = bytes;
|
||||
ext[0].ptr = memPtr;
|
||||
memPtr[bytes] = 0; /* may be duplicate terminator */
|
||||
myDoCommand(&cmd, ext);
|
||||
free(memPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(memPtr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else break;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.res = gpioNotifyOpenInBand(sock);
|
||||
switch (cmd.cmd)
|
||||
{
|
||||
case PI_CMD_TRIG:
|
||||
/*
|
||||
p1=user_gpio
|
||||
p2=pulseLen
|
||||
## extension ##
|
||||
unsigned level
|
||||
*/
|
||||
ext[0].n = 4;
|
||||
ext[0].ptr = &tmp;
|
||||
|
||||
if (recv(sock, &tmp, sizeof(unsigned), MSG_WAITALL) !=
|
||||
sizeof(unsigned))
|
||||
{
|
||||
close(sock);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
myDoCommand(&cmd, ext);
|
||||
}
|
||||
|
||||
write(sock, &cmd, sizeof(cmdCmd_t));
|
||||
|
@ -2647,10 +2850,8 @@ static void * pthSocketThreadHandler(void *fdC)
|
|||
static void * pthSocketThread(void *x)
|
||||
{
|
||||
int fdC, c, *sock;
|
||||
struct sockaddr_in server, client;
|
||||
struct sockaddr_in client;
|
||||
pthread_attr_t attr;
|
||||
char * portStr;
|
||||
unsigned port;
|
||||
|
||||
if (pthread_attr_init(&attr))
|
||||
SOFT_ERROR((void*)PI_INIT_FAILED,
|
||||
|
@ -2664,21 +2865,8 @@ static void * pthSocketThread(void *x)
|
|||
SOFT_ERROR((void*)PI_INIT_FAILED,
|
||||
"pthread_attr_setdetachstate failed (%m)");
|
||||
|
||||
fdSock = socket(AF_INET , SOCK_STREAM , 0);
|
||||
|
||||
if (fdSock == -1)
|
||||
SOFT_ERROR((void*)PI_INIT_FAILED, "socket failed (%m)");
|
||||
|
||||
portStr = getenv(PI_ENVPORT);
|
||||
|
||||
if (portStr) port = atoi(portStr); else port = gpioCfg.socketPort;
|
||||
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_addr.s_addr = INADDR_ANY;
|
||||
server.sin_port = htons(port);
|
||||
|
||||
if (bind(fdSock,(struct sockaddr *)&server , sizeof(server)) < 0)
|
||||
SOFT_ERROR((void*)PI_INIT_FAILED, "bind failed (%m)");
|
||||
/* fdSock opened in gpioInitialise so that we can treat
|
||||
failure to bind as fatal. */
|
||||
|
||||
listen(fdSock, 100);
|
||||
|
||||
|
@ -3264,7 +3452,7 @@ static void initClearGlobals(void)
|
|||
|
||||
wfStats.micros = 0;
|
||||
wfStats.highMicros = 0;
|
||||
wfStats.maxMicros = -1;
|
||||
wfStats.maxMicros = PI_WAVE_MAX_MICROS;
|
||||
|
||||
wfStats.pulses = 0;
|
||||
wfStats.highPulses = 0;
|
||||
|
@ -3406,7 +3594,8 @@ static void initReleaseResources(void)
|
|||
munmap(dmaVirt[i], PAGE_SIZE);
|
||||
}
|
||||
|
||||
munmap(dmaVirt, PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *));
|
||||
munmap(dmaVirt,
|
||||
PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *));
|
||||
}
|
||||
|
||||
dmaVirt = MAP_FAILED;
|
||||
|
@ -3418,7 +3607,8 @@ static void initReleaseResources(void)
|
|||
munmap(dmaPhys[i], PAGE_SIZE);
|
||||
}
|
||||
|
||||
munmap(dmaPhys, PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *));
|
||||
munmap(dmaPhys,
|
||||
PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *));
|
||||
}
|
||||
|
||||
dmaPhys = MAP_FAILED;
|
||||
|
@ -3474,6 +3664,9 @@ static void initReleaseResources(void)
|
|||
int gpioInitialise(void)
|
||||
{
|
||||
int i;
|
||||
struct sockaddr_in server;
|
||||
char * portStr;
|
||||
unsigned port;
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &libStarted);
|
||||
|
||||
|
@ -3542,6 +3735,22 @@ int gpioInitialise(void)
|
|||
|
||||
if (!(gpioCfg.ifFlags & PI_DISABLE_SOCK_IF))
|
||||
{
|
||||
fdSock = socket(AF_INET , SOCK_STREAM , 0);
|
||||
|
||||
if (fdSock == -1)
|
||||
SOFT_ERROR(PI_INIT_FAILED, "socket failed (%m)");
|
||||
|
||||
portStr = getenv(PI_ENVPORT);
|
||||
|
||||
if (portStr) port = atoi(portStr); else port = gpioCfg.socketPort;
|
||||
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_addr.s_addr = INADDR_ANY;
|
||||
server.sin_port = htons(port);
|
||||
|
||||
if (bind(fdSock,(struct sockaddr *)&server , sizeof(server)) < 0)
|
||||
SOFT_ERROR(PI_INIT_FAILED, "bind to port %d failed (%m)", port);
|
||||
|
||||
if (pthread_create(&pthSocket, &pthAttr, pthSocketThread, &i))
|
||||
SOFT_ERROR(PI_INIT_FAILED, "pthread_create socket failed (%m)");
|
||||
|
||||
|
@ -4127,15 +4336,16 @@ int gpioWaveAddGeneric(unsigned numPulses, gpioPulse_t * pulses)
|
|||
|
||||
int gpioWaveAddSerial(unsigned gpio,
|
||||
unsigned baud,
|
||||
unsigned offset,
|
||||
unsigned numChar,
|
||||
char * str)
|
||||
char *str)
|
||||
{
|
||||
int i, b, p, lev, c, v;
|
||||
|
||||
unsigned bitDelay[10];
|
||||
|
||||
DBG(DBG_USER, "gpio=%d baud=%d numChar=%d str*=%08X",
|
||||
gpio, baud, numChar, (uint32_t)str);
|
||||
DBG(DBG_USER, "gpio=%d baud=%d offset=%d numChar=%d str=%s",
|
||||
gpio, baud, offset, numChar, str);
|
||||
|
||||
CHECK_INITED;
|
||||
|
||||
|
@ -4149,6 +4359,9 @@ int gpioWaveAddSerial(unsigned gpio,
|
|||
if (numChar > PI_WAVE_MAX_CHARS)
|
||||
SOFT_ERROR(PI_TOO_MANY_CHARS, "too many chars (%d)", numChar);
|
||||
|
||||
if (offset > PI_WAVE_MAX_MICROS)
|
||||
SOFT_ERROR(PI_BAD_SER_OFFSET, "offset too large (%d)", offset);
|
||||
|
||||
if (!numChar) return 0;
|
||||
|
||||
waveBitDelay(baud, bitDelay);
|
||||
|
@ -4157,7 +4370,9 @@ int gpioWaveAddSerial(unsigned gpio,
|
|||
|
||||
wf[2][p].gpioOn = (1<<gpio);
|
||||
wf[2][p].gpioOff = 0;
|
||||
wf[2][p].usDelay = bitDelay[0];
|
||||
|
||||
if (offset > bitDelay[0]) wf[2][p].usDelay = offset;
|
||||
else wf[2][p].usDelay = bitDelay[0];
|
||||
|
||||
for (i=0; i<numChar; i++)
|
||||
{
|
||||
|
@ -4609,6 +4824,35 @@ int gpioNotifyClose(unsigned handle)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
int gpioTrigger(unsigned gpio, unsigned pulseLen, unsigned level)
|
||||
{
|
||||
DBG(DBG_USER, "gpio=%d pulseLen=%d level=%d", gpio, pulseLen, level);
|
||||
|
||||
CHECK_INITED;
|
||||
|
||||
if (gpio > PI_MAX_USER_GPIO)
|
||||
SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
|
||||
|
||||
if (level > PI_ON)
|
||||
SOFT_ERROR(PI_BAD_LEVEL, "gpio %d, bad level (%d)", gpio, level);
|
||||
|
||||
if (pulseLen > PI_MAX_PULSELEN)
|
||||
SOFT_ERROR(PI_BAD_PULSELEN,
|
||||
"gpio %d, bad pulseLen (%d)", gpio, pulseLen);
|
||||
|
||||
if (level == PI_OFF) *(gpioReg + GPCLR0 + BANK) = BIT;
|
||||
else *(gpioReg + GPSET0 + BANK) = BIT;
|
||||
|
||||
myGpioDelay(pulseLen);
|
||||
|
||||
if (level != PI_OFF) *(gpioReg + GPCLR0 + BANK) = BIT;
|
||||
else *(gpioReg + GPSET0 + BANK) = BIT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
|
@ -4769,7 +5013,7 @@ int gpioSetTimerFuncEx(unsigned id, unsigned ms, gpioTimerFuncEx_t f,
|
|||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
pthread_t *gpioStartThread(ThreadFunc_t func, void *arg)
|
||||
pthread_t *gpioStartThread(gpioThreadFunc_t func, void *arg)
|
||||
{
|
||||
pthread_t *pth;
|
||||
pthread_attr_t pthAttr;
|
||||
|
@ -4818,6 +5062,58 @@ void gpioStopThread(pthread_t *pth)
|
|||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
int gpioStoreScript(char *script)
|
||||
{
|
||||
DBG(DBG_USER, "script=%s", script);
|
||||
|
||||
CHECK_INITED;
|
||||
|
||||
return PI_BAD_SCRIPT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
int gpioRunScript(int script_id)
|
||||
{
|
||||
DBG(DBG_USER, "script_id=%d", script_id);
|
||||
|
||||
CHECK_INITED;
|
||||
|
||||
return PI_BAD_SCRIPT_ID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
int gpioStopScript(int script_id)
|
||||
{
|
||||
DBG(DBG_USER, "script_id=%d", script_id);
|
||||
|
||||
CHECK_INITED;
|
||||
|
||||
return PI_BAD_SCRIPT_ID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
int gpioDeleteScript(int script_id)
|
||||
{
|
||||
DBG(DBG_USER, "script_id=%d", script_id);
|
||||
|
||||
CHECK_INITED;
|
||||
|
||||
return PI_BAD_SCRIPT_ID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
int gpioSetSignalFunc(unsigned signum, gpioSignalFunc_t f)
|
||||
|
|
114
pigpio.h
114
pigpio.h
|
@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
|
|||
*/
|
||||
|
||||
/*
|
||||
This version is for pigpio version 10
|
||||
This version is for pigpio version 11
|
||||
*/
|
||||
|
||||
#ifndef PIGPIO_H
|
||||
|
@ -86,7 +86,7 @@ This version is for pigpio version 10
|
|||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define PIGPIO_VERSION 10
|
||||
#define PIGPIO_VERSION 11
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
|
@ -148,6 +148,8 @@ gpioWaveGetCbs Length in cbs of the current waveform.
|
|||
gpioWaveGetHighCbs Length of longest waveform so far.
|
||||
gpioWaveGetMaxCbs Absolute maximum allowed cbs.
|
||||
|
||||
gpioTrigger Send a trigger pulse to a gpio.
|
||||
|
||||
gpioSetWatchdog Set a watchdog on a gpio.
|
||||
|
||||
gpioSetGetSamplesFunc Requests a gpio samples callback.
|
||||
|
@ -159,6 +161,11 @@ gpioSetTimerFuncEx Request a regular timed callback, extended.
|
|||
gpioStartThread Start a new thread.
|
||||
gpioStopThread Stop a previously started thread.
|
||||
|
||||
gpioStoreScript Store a script.
|
||||
gpioRunScript Run a stored script.
|
||||
gpioStopScript Stop a running script.
|
||||
gpioDeleteScript Delete a stored script.
|
||||
|
||||
gpioSetSignalFunc Request a signal callback.
|
||||
gpioSetSignalFuncEx Request a signal callback, extended.
|
||||
|
||||
|
@ -217,6 +224,13 @@ typedef struct
|
|||
uint32_t res;
|
||||
} cmdCmd_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t n;
|
||||
void *ptr;
|
||||
int data;
|
||||
} gpioExtent_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t tick;
|
||||
|
@ -271,8 +285,7 @@ typedef void (*gpioGetSamplesFuncEx_t) (const gpioSample_t * samples,
|
|||
int numSamples,
|
||||
void * userdata);
|
||||
|
||||
typedef void *(ThreadFunc_t) (void *);
|
||||
|
||||
typedef void *(gpioThreadFunc_t) (void *);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -881,7 +894,6 @@ int gpioWaveAddGeneric(unsigned numPulses, gpioPulse_t * pulses);
|
|||
|
||||
If the added waveform is intended to start after or within the existing
|
||||
waveform then the first pulse should consist of a delay.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
@ -889,15 +901,17 @@ int gpioWaveAddGeneric(unsigned numPulses, gpioPulse_t * pulses);
|
|||
/*-------------------------------------------------------------------------*/
|
||||
int gpioWaveAddSerial(unsigned user_gpio,
|
||||
unsigned baud,
|
||||
unsigned offset,
|
||||
unsigned numChar,
|
||||
char * str);
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/* This function adds a waveform representing serial data to the
|
||||
existing waveform (if any).
|
||||
existing waveform (if any). The serial data starts offset microseconds
|
||||
from the start of the waveform.
|
||||
|
||||
Returns the new total number of pulses in the current waveform if OK,
|
||||
otherwise PI_BAD_USER_GPIO, PI_BAD_WAVE_BAUD, PI_TOO_MANY_CHARS, or
|
||||
PI_TOO_MANY_PULSES.
|
||||
otherwise PI_BAD_USER_GPIO, PI_BAD_WAVE_BAUD, PI_TOO_MANY_CHARS,
|
||||
PI_BAD_SER_OFFSET, or PI_TOO_MANY_PULSES.
|
||||
|
||||
NOTES:
|
||||
|
||||
|
@ -915,6 +929,8 @@ int gpioWaveAddSerial(unsigned user_gpio,
|
|||
#define PI_WAVE_MIN_BAUD 100
|
||||
#define PI_WAVE_MAX_BAUD 250000
|
||||
|
||||
#define PI_WAVE_MAX_MICROS (30 * 60 * 1000000) /* half an hour */
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -923,7 +939,8 @@ int gpioWaveTxStart(unsigned mode);
|
|||
/* This function transmits the current waveform. The mode determines
|
||||
whether the waveform is sent once or cycles endlessly.
|
||||
|
||||
Returns 0 if OK, otherwise PI_BAD_WAVE_MODE.
|
||||
Returns the number of DMA control blocks in the waveform if OK,
|
||||
otherwise PI_BAD_WAVE_MODE.
|
||||
*/
|
||||
|
||||
#define PI_WAVE_MODE_ONE_SHOT 0
|
||||
|
@ -1112,6 +1129,19 @@ int gpioWaveGetMaxCbs(void);
|
|||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int gpioTrigger(unsigned user_gpio, unsigned pulseLen, unsigned level);
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/* This function sends a trigger pulse to a gpio. The gpio is set to
|
||||
level for pulseLen microseconds and then reset to not level.
|
||||
|
||||
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_LEVEL,
|
||||
or PI_BAD_PULSELEN.
|
||||
*/
|
||||
|
||||
#define PI_MAX_PULSELEN 100
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int gpioSetWatchdog(unsigned user_gpio,
|
||||
unsigned timeout);
|
||||
|
@ -1267,7 +1297,7 @@ int gpioSetTimerFuncEx(unsigned timer,
|
|||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
pthread_t *gpioStartThread(ThreadFunc_t func, void *arg);
|
||||
pthread_t *gpioStartThread(gpioThreadFunc_t func, void *arg);
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/* Starts a new thread of execution with func as the main routine.
|
||||
|
||||
|
@ -1327,6 +1357,46 @@ void gpioStopThread(pthread_t *pth);
|
|||
*/
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
int gpioStoreScript(char *script);
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/* This function stores a null terminated script for later execution.
|
||||
|
||||
The function returns a script id if the script is valid,
|
||||
otherwise PI_BAD_SCRIPT.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
int gpioRunScript(int script_id);
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/* This function runs a stored script.
|
||||
|
||||
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
int gpioStopScript(int script_id);
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/* This function stops a running script.
|
||||
|
||||
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
int gpioDeleteScript(int script_id);
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/* This function deletes a stored script.
|
||||
|
||||
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int gpioSetSignalFunc(unsigned signum,
|
||||
|
@ -1816,6 +1886,21 @@ void gpioWaveDump(void);
|
|||
#define PI_CMD_PRRG 24
|
||||
#define PI_CMD_HELP 25
|
||||
#define PI_CMD_PIGPV 26
|
||||
#define PI_CMD_WVCLR 27
|
||||
#define PI_CMD_WVAG 28
|
||||
#define PI_CMD_WVAS 29
|
||||
#define PI_CMD_WVGO 30
|
||||
#define PI_CMD_WVGOR 31
|
||||
#define PI_CMD_WVBSY 32
|
||||
#define PI_CMD_WVHLT 33
|
||||
#define PI_CMD_WVSM 34
|
||||
#define PI_CMD_WVSP 35
|
||||
#define PI_CMD_WVSC 36
|
||||
#define PI_CMD_TRIG 37
|
||||
#define PI_CMD_PROC 38
|
||||
#define PI_CMD_PROCD 39
|
||||
#define PI_CMD_PROCR 40
|
||||
#define PI_CMD_PROCS 41
|
||||
|
||||
/*
|
||||
The following command only works on the socket interface.
|
||||
|
@ -1841,7 +1926,7 @@ after this command is issued.
|
|||
#define PI_BAD_LEVEL -5 /* level not 0-1 */
|
||||
#define PI_BAD_PUD -6 /* pud not 0-2 */
|
||||
#define PI_BAD_PULSEWIDTH -7 /* pulsewidth not 0 or 500-2500 */
|
||||
#define PI_BAD_DUTYCYCLE -8 /* dutycycle not 0-255 */
|
||||
#define PI_BAD_DUTYCYCLE -8 /* dutycycle outside set range */
|
||||
#define PI_BAD_TIMER -9 /* timer not 0-9 */
|
||||
#define PI_BAD_MS -10 /* ms not 10-60000 */
|
||||
#define PI_BAD_TIMETYPE -11 /* timetype not 0-1 */
|
||||
|
@ -1878,6 +1963,13 @@ after this command is issued.
|
|||
#define PI_BAD_SERIAL_BUF -40 /* bad (null) serial buf parameter */
|
||||
#define PI_NOT_PERMITTED -41 /* gpio operation not permitted */
|
||||
#define PI_SOME_PERMITTED -42 /* one or more gpios not permitted */
|
||||
#define PI_BAD_WVSC_COMMND -43 /* bad WVSC subcommand */
|
||||
#define PI_BAD_WVSM_COMMND -44 /* bad WVSM subcommand */
|
||||
#define PI_BAD_WVSP_COMMND -45 /* bad WVSP subcommand */
|
||||
#define PI_BAD_PULSELEN -46 /* trigger pulse length > 100 */
|
||||
#define PI_BAD_SCRIPT -47 /* invalid script */
|
||||
#define PI_BAD_SCRIPT_ID -48 /* unknown script id */
|
||||
#define PI_BAD_SER_OFFSET -49 /* add serial data offset > 30 minutes */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
|
526
pigpio.py
526
pigpio.py
|
@ -76,7 +76,7 @@ import threading
|
|||
import os
|
||||
import atexit
|
||||
|
||||
VERSION = "1.1"
|
||||
VERSION = "1.2"
|
||||
|
||||
# gpio levels
|
||||
|
||||
|
@ -140,8 +140,28 @@ _PI_CMD_NC= 21
|
|||
_PI_CMD_PRG= 22
|
||||
_PI_CMD_PFG= 23
|
||||
_PI_CMD_PRRG= 24
|
||||
_PI_CMD_HELP= 25
|
||||
_PI_CMD_PIGPV=26
|
||||
_PI_CMD_WVCLR=27
|
||||
_PI_CMD_WVAG= 28
|
||||
_PI_CMD_WVAS= 29
|
||||
_PI_CMD_WVGO= 30
|
||||
_PI_CMD_WVGOR=31
|
||||
_PI_CMD_WVBSY=32
|
||||
_PI_CMD_WVHLT=33
|
||||
_PI_CMD_WVSM= 34
|
||||
_PI_CMD_WVSP= 35
|
||||
_PI_CMD_WVSC= 36
|
||||
_PI_CMD_TRIG= 37
|
||||
_PI_CMD_PROC= 38
|
||||
_PI_CMD_PROCD=39
|
||||
_PI_CMD_PROCR=40
|
||||
_PI_CMD_PROCS=41
|
||||
|
||||
|
||||
_PI_CMD_NOIB= 99
|
||||
|
||||
|
||||
# pigpio error numbers
|
||||
|
||||
_PI_INIT_FAILED =-1
|
||||
|
@ -179,14 +199,21 @@ _PI_NOT_INITIALISED =-31
|
|||
_PI_INITIALISED =-32
|
||||
_PI_BAD_WAVE_MODE =-33
|
||||
_PI_BAD_CFG_INTERNAL=-34
|
||||
_PI_BAD_WAVE_BAUD =-35
|
||||
_PI_TOO_MANY_PULSES =-36
|
||||
_PI_TOO_MANY_CHARS =-37
|
||||
PI_BAD_WAVE_BAUD =-35
|
||||
PI_TOO_MANY_PULSES =-36
|
||||
PI_TOO_MANY_CHARS =-37
|
||||
_PI_NOT_SERIAL_GPIO =-38
|
||||
_PI_BAD_SERIAL_STRUC=-39
|
||||
_PI_BAD_SERIAL_BUF =-40
|
||||
PI_NOT_PERMITTED =-41
|
||||
PI_SOME_PERMITTED =-42
|
||||
PI_BAD_WVSC_COMMND =-43
|
||||
PI_BAD_WVSM_COMMND =-44
|
||||
PI_BAD_WVSP_COMMND =-45
|
||||
PI_BAD_PULSELEN =-46
|
||||
PI_BAD_SCRIPT =-47
|
||||
PI_BAD_SCRIPT_ID =-48
|
||||
PI_BAD_SER_OFFSET =-49
|
||||
|
||||
# pigpio error text
|
||||
|
||||
|
@ -225,12 +252,19 @@ _errors=[
|
|||
[_PI_INITIALISED , "function called after gpioInitialise"],
|
||||
[_PI_BAD_WAVE_MODE , "waveform mode not 0-1"],
|
||||
[_PI_BAD_CFG_INTERNAL , "bad parameter in gpioCfgInternals call"],
|
||||
[_PI_BAD_WAVE_BAUD , "baud rate not 100-250000"],
|
||||
[_PI_TOO_MANY_PULSES , "waveform has too many pulses"],
|
||||
[_PI_TOO_MANY_CHARS , "waveform has too many chars"],
|
||||
[PI_BAD_WAVE_BAUD , "baud rate not 100-250000"],
|
||||
[PI_TOO_MANY_PULSES , "waveform has too many pulses"],
|
||||
[PI_TOO_MANY_CHARS , "waveform has too many chars"],
|
||||
[_PI_NOT_SERIAL_GPIO , "no serial read in progress on gpio"],
|
||||
[PI_NOT_PERMITTED , "no permission to update gpio"],
|
||||
[PI_SOME_PERMITTED , "no permission to update one or more gpios"]
|
||||
[PI_SOME_PERMITTED , "no permission to update one or more gpios"],
|
||||
[PI_BAD_WVSC_COMMND , "bad WVSC subcommand"],
|
||||
[PI_BAD_WVSM_COMMND , "bad WVSM subcommand"],
|
||||
[PI_BAD_WVSP_COMMND , "bad WVSP subcommand"],
|
||||
[PI_BAD_PULSELEN , "trigger pulse length > 100"],
|
||||
[PI_BAD_SCRIPT , "invalid script"],
|
||||
[PI_BAD_SCRIPT_ID , "unknown script id"],
|
||||
[PI_BAD_SER_OFFSET , "add serial data offset > 30 minute"],
|
||||
]
|
||||
|
||||
_control = None
|
||||
|
@ -262,7 +296,7 @@ def error(pigpio_error):
|
|||
for e in _errors:
|
||||
if e[0] == pigpio_error:
|
||||
return e[1]
|
||||
return "unknown error"
|
||||
return "unknown error ({})".format(pigpio_error)
|
||||
|
||||
def tickDiff(tStart, tEnd):
|
||||
"""Calculate the time difference between two ticks.
|
||||
|
@ -304,7 +338,8 @@ def _u2i(number):
|
|||
return v
|
||||
|
||||
def _pigpio_command(sock, cmd, p1, p2):
|
||||
"""Executes a pigpio socket command.
|
||||
"""
|
||||
Executes a pigpio socket command.
|
||||
|
||||
sock: command socket.
|
||||
cmd: the command to be executed.
|
||||
|
@ -318,6 +353,27 @@ def _pigpio_command(sock, cmd, p1, p2):
|
|||
else:
|
||||
raise _pigpioError("*** Module not started, call pigpio.start() ***")
|
||||
|
||||
def _pigpio_command_ext(sock, cmd, p1, p2, extents):
|
||||
"""
|
||||
Executes an extended pigpio socket command.
|
||||
|
||||
sock: command socket.
|
||||
cmd: the command to be executed.
|
||||
p1: command paramter 1 (if applicable).
|
||||
p2: command paramter 2 (if applicable).
|
||||
extents: additional data blocks
|
||||
"""
|
||||
if sock is not None:
|
||||
sock.send(struct.pack('IIII', cmd, p1, p2, 0))
|
||||
|
||||
for ext in extents:
|
||||
sock.sendall(ext)
|
||||
|
||||
x, y, z, res = struct.unpack('IIII', sock.recv(16))
|
||||
return res
|
||||
else:
|
||||
raise _pigpioError("*** Module not started, call pigpio.start() ***")
|
||||
|
||||
class _callback:
|
||||
"""An ADT class to hold callback information."""
|
||||
|
||||
|
@ -462,8 +518,7 @@ def set_mode(gpio, mode):
|
|||
pigpio.set_mode(10, pigpio.ALT2) # gpio 10 as ALT2
|
||||
...
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_MODES, gpio, mode))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_MODES, gpio, mode))
|
||||
|
||||
def get_mode(gpio):
|
||||
"""Get the gpio mode.
|
||||
|
@ -482,8 +537,7 @@ def get_mode(gpio):
|
|||
6
|
||||
...
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_MODEG, gpio, 0))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_MODEG, gpio, 0))
|
||||
|
||||
def set_pull_up_down(gpio, pud):
|
||||
"""Set or clear the gpio pull-up/down resistor.
|
||||
|
@ -516,8 +570,7 @@ def set_pull_up_down(gpio, pud):
|
|||
1
|
||||
...
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_PUD, gpio, pud))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_PUD, gpio, pud))
|
||||
|
||||
def read(gpio):
|
||||
"""Read the gpio level.
|
||||
|
@ -545,8 +598,7 @@ def read(gpio):
|
|||
1
|
||||
...
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_READ, gpio, 0))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_READ, gpio, 0))
|
||||
|
||||
def write(gpio, level):
|
||||
"""Write the gpio level.
|
||||
|
@ -578,8 +630,7 @@ def write(gpio, level):
|
|||
1
|
||||
...
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_WRITE, gpio, level))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_WRITE, gpio, level))
|
||||
|
||||
def set_PWM_dutycycle(user_gpio, dutycycle):
|
||||
"""Start (non-zero dutycycle) or stop (0) PWM pulses on the gpio.
|
||||
|
@ -609,8 +660,7 @@ def set_PWM_dutycycle(user_gpio, dutycycle):
|
|||
set_PWM_dutycycle(4, 255) # PWM full on
|
||||
...
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_PWM, user_gpio, dutycycle))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_PWM, user_gpio, dutycycle))
|
||||
|
||||
def set_PWM_range(user_gpio, range_):
|
||||
"""Set the range of PWM values to be used on the gpio.
|
||||
|
@ -645,8 +695,7 @@ def set_PWM_range(user_gpio, range_):
|
|||
pigpio.set_PWM_range(9, 3000) # now 750 1/4, 1500 1/2, 2250 3/4 on
|
||||
...
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_PRS, user_gpio, range_))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_PRS, user_gpio, range_))
|
||||
|
||||
def get_PWM_range(user_gpio):
|
||||
"""Get the range of PWM values being used on the gpio.
|
||||
|
@ -674,8 +723,7 @@ def get_PWM_range(user_gpio):
|
|||
3000
|
||||
...
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_PRG, user_gpio, 0))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_PRG, user_gpio, 0))
|
||||
|
||||
def get_PWM_real_range(user_gpio):
|
||||
"""Get the real underlying range of PWM values being used on the gpio.
|
||||
|
@ -701,8 +749,7 @@ def get_PWM_real_range(user_gpio):
|
|||
25
|
||||
...
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_PRRG, user_gpio, 0))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_PRRG, user_gpio, 0))
|
||||
|
||||
def set_PWM_frequency(user_gpio, frequency):
|
||||
"""Set the frequency (in Hz) of the PWM to be used on the gpio.
|
||||
|
@ -759,8 +806,7 @@ def set_PWM_frequency(user_gpio, frequency):
|
|||
8000
|
||||
...
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_PFS, user_gpio, frequency))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_PFS, user_gpio, frequency))
|
||||
|
||||
def get_PWM_frequency(user_gpio):
|
||||
"""Get the frequency of PWM being used on the gpio.
|
||||
|
@ -788,8 +834,7 @@ def get_PWM_frequency(user_gpio):
|
|||
8000
|
||||
...
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_PFG, user_gpio, 0))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_PFG, user_gpio, 0))
|
||||
|
||||
def set_servo_pulsewidth(user_gpio, pulsewidth):
|
||||
"""Start (500-2500) or stop (0) servo pulses on the gpio.
|
||||
|
@ -845,8 +890,8 @@ def set_servo_pulsewidth(user_gpio, pulsewidth):
|
|||
for m in moves:
|
||||
pigpio.set_servo_pulsewidth(24, m[0]);
|
||||
time.sleep(m[1])
|
||||
message = str(m[1]) + " seconds @ " + str(m[0]) + " us"
|
||||
print(message)
|
||||
s = str(m[1]) + " seconds @ " + str(m[0]) + " us"
|
||||
print(s)
|
||||
|
||||
pigpio.stop()
|
||||
|
||||
|
@ -875,8 +920,8 @@ def set_servo_pulsewidth(user_gpio, pulsewidth):
|
|||
for m in moves:
|
||||
pigpio.set_PWM_dutycycle(25, m[0]);
|
||||
time.sleep(m[1])
|
||||
message = str(m[1]) + " seconds @ " + str(m[0]) + " us"
|
||||
print(message)
|
||||
s = str(m[1]) + " seconds @ " + str(m[0]) + " us"
|
||||
print(s)
|
||||
|
||||
pigpio.stop()
|
||||
|
||||
|
@ -888,8 +933,7 @@ def set_servo_pulsewidth(user_gpio, pulsewidth):
|
|||
5 seconds @ 2000 us
|
||||
0 seconds @ 1000 us
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_SERVO, user_gpio, pulsewidth))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_SERVO, user_gpio, pulsewidth))
|
||||
|
||||
def notify_open():
|
||||
"""Get a free notification handle.
|
||||
|
@ -917,8 +961,7 @@ def notify_open():
|
|||
pigpio.notify_begin(h, 1234)
|
||||
...
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_NO, 0, 0))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_NO, 0, 0))
|
||||
|
||||
def notify_begin(handle, bits):
|
||||
"""Start notifications on a previously opened handle.
|
||||
|
@ -951,8 +994,7 @@ def notify_begin(handle, bits):
|
|||
I (32 bit) level
|
||||
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_NB, handle, bits))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_NB, handle, bits))
|
||||
|
||||
def notify_pause(handle):
|
||||
"""Pause notifications on a previously opened handle.
|
||||
|
@ -976,8 +1018,7 @@ def notify_pause(handle):
|
|||
...
|
||||
...
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_NB, handle, 0))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_NB, handle, 0))
|
||||
|
||||
def notify_close(handle):
|
||||
"""Stop notifications on a previously opened handle and
|
||||
|
@ -997,8 +1038,7 @@ def notify_close(handle):
|
|||
...
|
||||
...
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_NC, handle, 0))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_NC, handle, 0))
|
||||
|
||||
def set_watchdog(user_gpio, timeout):
|
||||
"""Sets a watchdog for a gpio.
|
||||
|
@ -1030,8 +1070,8 @@ def set_watchdog(user_gpio, timeout):
|
|||
import time
|
||||
|
||||
def cbf(g, L, t):
|
||||
message = "gpio=" + str(g) + " level=" + str(L) + " at " + str(t)
|
||||
print(message)
|
||||
s = "gpio=" + str(g) + " level=" + str(L) + " at " + str(t)
|
||||
print(s)
|
||||
|
||||
pigpio.start()
|
||||
|
||||
|
@ -1068,8 +1108,7 @@ def set_watchdog(user_gpio, timeout):
|
|||
gpio=22 level=2 at 3551411622
|
||||
watchdog cancelled, 5 second delay
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_WDOG, user_gpio, timeout))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_WDOG, user_gpio, timeout))
|
||||
|
||||
def read_bank_1():
|
||||
"""Read the levels of the bank 1 gpios (gpios 0-31).
|
||||
|
@ -1148,8 +1187,7 @@ def clear_bank_1(levels):
|
|||
0b1111110010000
|
||||
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_BC1, levels, 0))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_BC1, levels, 0))
|
||||
|
||||
def clear_bank_2(levels):
|
||||
"""Clears gpios 32-53 if the corresponding bit (0-21) in levels is set.
|
||||
|
@ -1164,8 +1202,7 @@ def clear_bank_2(levels):
|
|||
|
||||
See clear_bank_1() for an example.
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_BC2, levels, 0))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_BC2, levels, 0))
|
||||
|
||||
def set_bank_1(levels):
|
||||
"""Sets gpios 0-31 if the corresponding bit in levels is set.
|
||||
|
@ -1215,8 +1252,7 @@ def set_bank_1(levels):
|
|||
0b1111111011111
|
||||
0b1111110010000
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_BS1, levels, 0))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_BS1, levels, 0))
|
||||
|
||||
def set_bank_2(levels):
|
||||
"""Sets gpios 32-53 if the corresponding bit (0-21) in levels is set.
|
||||
|
@ -1231,8 +1267,7 @@ def set_bank_2(levels):
|
|||
|
||||
See set_bank_1() for an example.
|
||||
"""
|
||||
r=_u2i(_pigpio_command(_control, _PI_CMD_BS2, levels, 0))
|
||||
return r
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_BS2, levels, 0))
|
||||
|
||||
def get_current_tick():
|
||||
"""Gets the current system tick.
|
||||
|
@ -1257,9 +1292,9 @@ def get_current_tick():
|
|||
|
||||
t2 = pigpio.get_current_tick()
|
||||
|
||||
message = "5 seconds is " + str(pigpio.tickDiff(t1, t2)) + " ticks"
|
||||
s = "5 seconds is " + str(pigpio.tickDiff(t1, t2)) + " ticks"
|
||||
|
||||
print(message)
|
||||
print(s)
|
||||
|
||||
pigpio.stop()
|
||||
|
||||
|
@ -1308,6 +1343,365 @@ def get_hardware_revision():
|
|||
"""
|
||||
return _pigpio_command(_control, _PI_CMD_HWVER, 0, 0)
|
||||
|
||||
def get_pigpio_version():
|
||||
"""
|
||||
Returns the pigpio software version.
|
||||
"""
|
||||
return _pigpio_command(_control, _PI_CMD_PIGPV, 0, 0)
|
||||
|
||||
class pulse:
|
||||
"""
|
||||
An ADT class to hold pulse information.
|
||||
"""
|
||||
|
||||
def __init__(self, gpio_on, gpio_off, delay):
|
||||
"""
|
||||
Initialises a pulse ADT.
|
||||
|
||||
gpio_on: the gpios to switch on at the start of the pulse.
|
||||
gpio_off: the gpios to switch off at the start of the pulse.
|
||||
delay: the delay in microseconds before the next pulse.
|
||||
"""
|
||||
self.gpio_on = gpio_on
|
||||
self.gpio_off = gpio_off
|
||||
self.delay = delay
|
||||
|
||||
def wave_clear():
|
||||
"""
|
||||
Initialises a new waveform.
|
||||
|
||||
Returns 0 if OK.
|
||||
|
||||
A waveform comprises one of more pulses.
|
||||
|
||||
A pulse specifies
|
||||
|
||||
1) the gpios to be switched on at the start of the pulse.
|
||||
2) the gpios to be switched off at the start of the pulse.
|
||||
3) the delay in microseconds before the next pulse.
|
||||
|
||||
Any or all the fields can be zero. It doesn't make any sense
|
||||
to set all the fields to zero (the pulse will be ignored).
|
||||
|
||||
When a waveform is started each pulse is executed in order with
|
||||
the specified delay between the pulse and the next.
|
||||
"""
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_WVCLR, 0, 0))
|
||||
|
||||
def wave_add_generic(pulses):
|
||||
"""
|
||||
Adds a list of pulses to the current waveform.
|
||||
|
||||
Returns the new total number of pulses in the current waveform
|
||||
if OK, otherwise PI_TOO_MANY_PULSES.
|
||||
|
||||
pulses: list of pulses to add to the waveform.
|
||||
|
||||
The pulses are interleaved in time order within the existing
|
||||
waveform (if any).
|
||||
|
||||
Merging allows the waveform to be built in parts, that is the
|
||||
settings for gpio#1 can be added, and then gpio#2 etc.
|
||||
|
||||
If the added waveform is intended to start after or within
|
||||
the existing waveform then the first pulse should consist
|
||||
solely of a delay.
|
||||
|
||||
Example
|
||||
|
||||
#!/usr/bin/env python
|
||||
|
||||
import time
|
||||
import pigpio
|
||||
|
||||
class stepper:
|
||||
|
||||
def __init__(self, g1, g2, g3, g4):
|
||||
self.g1 = g1
|
||||
self.g2 = g2
|
||||
self.g3 = g3
|
||||
self.g4 = g4
|
||||
self.all = (1<<g1 | 1<<g2 | 1<<g3 | 1<<g4)
|
||||
|
||||
pigpio.set_mode(g1, pigpio.OUTPUT)
|
||||
pigpio.set_mode(g2, pigpio.OUTPUT)
|
||||
pigpio.set_mode(g3, pigpio.OUTPUT)
|
||||
pigpio.set_mode(g4, pigpio.OUTPUT)
|
||||
|
||||
def step_on(self, pos):
|
||||
if pos == 0: return (1<<self.g4)
|
||||
elif pos == 1: return (1<<self.g3 | 1<<self.g4)
|
||||
elif pos == 2: return (1<<self.g3)
|
||||
elif pos == 3: return (1<<self.g2 | 1<<self.g3)
|
||||
elif pos == 4: return (1<<self.g2)
|
||||
elif pos == 5: return (1<<self.g1 | 1<<self.g2)
|
||||
elif pos == 6: return (1<<self.g1)
|
||||
elif pos == 7: return (1<<self.g1 | 1<<self.g4)
|
||||
else: return 0
|
||||
|
||||
def step_off(self, pos):
|
||||
return self.step_on(pos) ^ self.all
|
||||
|
||||
pigpio.start()
|
||||
|
||||
s1 = stepper(14, 15, 18, 17)
|
||||
s2 = stepper(24, 25, 8, 7)
|
||||
|
||||
f1=[] # pulses to drive stepper 1 forward
|
||||
b2=[] # pulses to drive stepper 2 backward
|
||||
|
||||
for i in range(8):
|
||||
f1.append(pigpio.pulse(s1.step_on(i), s1.step_off(i), 1200))
|
||||
b2.append(pigpio.pulse(s2.step_on(7-i), s2.step_off(7-i), 1200))
|
||||
|
||||
pigpio.wave_clear() # initialise a new waveform
|
||||
|
||||
pigpio.wave_add_generic(f1) # add stepper 1 forward
|
||||
pigpio.wave_add_generic(b2) # add stepper 2 backward
|
||||
|
||||
pigpio.wave_tx_repeat() # repeately transmit pulses
|
||||
|
||||
time.sleep(10)
|
||||
|
||||
pigpio.wave_tx_stop() # stop waveform
|
||||
|
||||
pigpio.stop()
|
||||
"""
|
||||
# pigpio message format
|
||||
|
||||
# I p1 number of pulses
|
||||
# I p2 0
|
||||
## extension ##
|
||||
# III on/off/delay * number of pulses
|
||||
msg = ""
|
||||
for p in pulses:
|
||||
msg += struct.pack("III", p.gpio_on, p.gpio_off, p.delay)
|
||||
extents = [msg]
|
||||
return _u2i(_pigpio_command_ext(
|
||||
_control, _PI_CMD_WVAG, len(pulses), 0, extents))
|
||||
|
||||
def wave_add_serial(user_gpio, baud, offset, data):
|
||||
"""
|
||||
Adds a waveform representing serial data to the existing waveform
|
||||
(if any). The serial data starts offset microseconds from the
|
||||
start of the waveform.
|
||||
|
||||
Returns the new total number of pulses in the current waveform
|
||||
if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_WAVE_BAUD,
|
||||
PI_TOO_MANY_CHARS, PI_BAD_SER_OFFSET, or PI_TOO_MANY_PULSES.
|
||||
|
||||
user_gpio: gpio to transmit data. You must set the gpio mode
|
||||
to output.
|
||||
baud: baud rate to use.
|
||||
offset: number of microseconds from the starts of the waveform.
|
||||
data: the data to transmit.
|
||||
|
||||
The serial data is formatted as one start bit, eight data bits,
|
||||
and one stop bit.
|
||||
|
||||
It is legal to add serial data streams with different baud rates
|
||||
to the same waveform.
|
||||
|
||||
Example
|
||||
|
||||
#!/usr/bin/env python
|
||||
|
||||
import time
|
||||
|
||||
import pigpio
|
||||
|
||||
GPIO=24
|
||||
|
||||
pigpio.start()
|
||||
|
||||
pigpio.set_mode(TX_GPIO, pigpio.OUTPUT)
|
||||
|
||||
pigpio.wave_clear() # initialise waveform
|
||||
|
||||
for i in range(10):
|
||||
pigpio.wave_add_serial(
|
||||
GPIO, 9600, i*2000000, "{} seconds in.\r\n".format(i*2))
|
||||
|
||||
pigpio.wave_tx_start()
|
||||
|
||||
time.sleep(22)
|
||||
|
||||
pigpio.stop()
|
||||
"""
|
||||
# pigpio message format
|
||||
|
||||
# I p1 user_gpio
|
||||
# I p2 len(data)
|
||||
## extension ##
|
||||
# I baud
|
||||
# I offset
|
||||
# s data
|
||||
extents = [struct.pack("I", baud),struct.pack("I", offset), data]
|
||||
return _u2i(_pigpio_command_ext(
|
||||
_control, _PI_CMD_WVAS, user_gpio, len(data), extents))
|
||||
|
||||
def wave_tx_busy():
|
||||
"""
|
||||
Checks to see if a waveform is currently being transmitted.
|
||||
|
||||
Returns 1 if a waveform is currently being transmitted, otherwise 0.
|
||||
"""
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_WVBSY, 0, 0))
|
||||
|
||||
def wave_tx_stop():
|
||||
"""
|
||||
Stops the transmission of the current waveform.
|
||||
|
||||
Returns 0 if OK.
|
||||
|
||||
This function is intended to stop a waveform started with
|
||||
wave_tx_repeat().
|
||||
"""
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_WVHLT, 0, 0))
|
||||
|
||||
def wave_tx_start():
|
||||
"""
|
||||
Transmits the current waveform. The waveform is sent once.
|
||||
|
||||
Returns the number of cbs in the waveform if OK,
|
||||
otherwise PI_BAD_WAVE_MODE.
|
||||
"""
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_WVGO, 0, 0))
|
||||
|
||||
def wave_tx_repeat():
|
||||
"""
|
||||
Transmits the current waveform. The waveform repeats until
|
||||
wave_tx_stop is called.
|
||||
|
||||
Returns the number of cbs in the waveform if OK,
|
||||
otherwise PI_BAD_WAVE_MODE.
|
||||
"""
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_WVGOR, 0, 0))
|
||||
|
||||
def wave_get_micros():
|
||||
"""
|
||||
Returns the length in microseconds of the current waveform.
|
||||
"""
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_WVSM, 0, 0))
|
||||
|
||||
def wave_get_max_micros():
|
||||
"""
|
||||
Returns the maximum possible size of a waveform in microseconds.
|
||||
"""
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_WVSM, 2, 0))
|
||||
|
||||
def wave_get_pulses():
|
||||
"""
|
||||
Returns the length in pulses of the current waveform.
|
||||
"""
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_WVSP, 0, 0))
|
||||
|
||||
def wave_get_max_pulses():
|
||||
"""
|
||||
Returns the maximum possible size of a waveform in pulses.
|
||||
"""
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_WVSP, 2, 0))
|
||||
|
||||
def wave_get_cbs():
|
||||
"""
|
||||
Returns the length in DMA control blocks of the current waveform.
|
||||
"""
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_WVSC, 0, 0))
|
||||
|
||||
def wave_get_max_cbs():
|
||||
"""
|
||||
Returns the maximum possible size of a waveform in DMA control blocks.
|
||||
"""
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_WVSC, 2, 0))
|
||||
|
||||
def gpio_trigger(user_gpio, pulse_len=10, level=1):
|
||||
"""
|
||||
Send a trigger pulse to a gpio. The gpio is set to
|
||||
level for pulse_len microseconds and then reset to not level.
|
||||
|
||||
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_LEVEL,
|
||||
PI_BAD_PULSELEN, or PI_NOT_PERMITTED.
|
||||
|
||||
user_gpio: gpio to pulse.
|
||||
pulse_len: length of pulse in microseconds.
|
||||
level: whether the pulse should be high or low.
|
||||
|
||||
Example
|
||||
|
||||
#!/usr/bin/env python
|
||||
|
||||
import time
|
||||
|
||||
import pigpio
|
||||
|
||||
GPIO=24
|
||||
|
||||
pigpio.start()
|
||||
|
||||
for i in range(10):
|
||||
pigpio.gpio_trigger(GPIO, (i*5)+10, 1)
|
||||
time.sleep(1)
|
||||
|
||||
pigpio.stop()
|
||||
|
||||
"""
|
||||
# pigpio message format
|
||||
|
||||
# I p1 user_gpio
|
||||
# I p2 pulse_len
|
||||
## extension ##
|
||||
# I level
|
||||
|
||||
extents = [struct.pack("I", level)]
|
||||
|
||||
return _u2i(_pigpio_command_ext(
|
||||
_control, _PI_CMD_TRIG, user_gpio, pulse_len, extents))
|
||||
|
||||
def store_script(script):
|
||||
"""
|
||||
Store a script for later execution.
|
||||
|
||||
Returns a script id if OK, otherwise PI_BAD_SCRIPT.
|
||||
"""
|
||||
# I p1 script length
|
||||
# I p2 0
|
||||
## extension ##
|
||||
# s script
|
||||
|
||||
return _u2i(_pigpio_command_ext(
|
||||
_control, _PI_CMD_PROC, len(script), 0, script))
|
||||
|
||||
def run_script(script_id):
|
||||
"""
|
||||
Runs a stored script.
|
||||
|
||||
Returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
|
||||
|
||||
script_id: script_id of stored script.
|
||||
"""
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_PROCR, script_id, 0))
|
||||
|
||||
def stop_script(script_id):
|
||||
"""
|
||||
Stops a running script.
|
||||
|
||||
Returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
|
||||
|
||||
script_id: script_id of stored script.
|
||||
"""
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_PROCS, script_id, 0))
|
||||
|
||||
def delete_script(script_id):
|
||||
"""
|
||||
Deletes a stored script.
|
||||
|
||||
Returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
|
||||
|
||||
script_id: script_id of stored script.
|
||||
"""
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_PROCD, script_id, 0))
|
||||
|
||||
|
||||
class callback:
|
||||
"""A class to provide gpio level change callbacks."""
|
||||
|
||||
|
@ -1332,8 +1726,8 @@ class callback:
|
|||
import time
|
||||
|
||||
def cbf(g, L, t):
|
||||
message = "gpio=" + str(g) + " level=" + str(L) + " at " + str(t)
|
||||
print(message)
|
||||
s = "gpio=" + str(g) + " level=" + str(L) + " at " + str(t)
|
||||
print(s)
|
||||
|
||||
pigpio.start()
|
||||
|
||||
|
@ -1376,9 +1770,9 @@ class callback:
|
|||
|
||||
tally_2 = cb.tally()
|
||||
|
||||
message = "counted " + str(tally_2 - tally_1) + " edges"
|
||||
s = "counted " + str(tally_2 - tally_1) + " edges"
|
||||
|
||||
print(message)
|
||||
print(s)
|
||||
|
||||
cb.cancel()
|
||||
|
||||
|
@ -1411,9 +1805,9 @@ class callback:
|
|||
|
||||
tally_2 = cb.tally()
|
||||
|
||||
message = "counted " + str(tally_2 - tally_1) + " rising edges"
|
||||
s = "counted " + str(tally_2 - tally_1) + " rising edges"
|
||||
|
||||
print(message)
|
||||
print(s)
|
||||
|
||||
cb.cancel()
|
||||
|
||||
|
|
44
pigpiod.c
44
pigpiod.c
|
@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
|
|||
*/
|
||||
|
||||
/*
|
||||
This version is for pigpio version 7+
|
||||
This version is for pigpio version 11+
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -34,6 +34,7 @@ This version is for pigpio version 7+
|
|||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
@ -43,7 +44,6 @@ This version is for pigpio version 7+
|
|||
#include <ctype.h>
|
||||
|
||||
#include "pigpio.h"
|
||||
#include "command.h"
|
||||
|
||||
/*
|
||||
This program starts the pigpio library as a daemon.
|
||||
|
@ -61,6 +61,22 @@ static uint64_t updateMask = -1;
|
|||
|
||||
static FILE * errFifo;
|
||||
|
||||
void fatal(char *fmt, ...)
|
||||
{
|
||||
char buf[128];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
|
||||
fflush(stderr);
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void usage()
|
||||
{
|
||||
fprintf(stderr, "\n" \
|
||||
|
@ -98,21 +114,21 @@ static void initOpts(int argc, char *argv[])
|
|||
i = atoi(optarg);
|
||||
if ((i >= PI_BUF_MILLIS_MIN) && (i <= PI_BUF_MILLIS_MAX))
|
||||
bufferSizeMilliseconds = i;
|
||||
else cmdFatal("invalid -b option (%d)", i);
|
||||
else fatal("invalid -b option (%d)", i);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
i = atoi(optarg);
|
||||
if ((i >= PI_MIN_DMA_CHANNEL) && (i <= PI_MAX_PRIMARY_CHANNEL))
|
||||
DMAprimaryChannel = i;
|
||||
else cmdFatal("invalid -d option (%d)", i);
|
||||
else fatal("invalid -d option (%d)", i);
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
i = atoi(optarg);
|
||||
if ((i >= PI_MIN_DMA_CHANNEL) && (i <= PI_MAX_SECONDARY_CHANNEL))
|
||||
DMAsecondaryChannel = i;
|
||||
else cmdFatal("invalid -e option (%d)", i);
|
||||
else fatal("invalid -e option (%d)", i);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
|
@ -127,7 +143,7 @@ static void initOpts(int argc, char *argv[])
|
|||
i = atoi(optarg);
|
||||
if ((i >= PI_MIN_SOCKET_PORT) && (i <= PI_MAX_SOCKET_PORT))
|
||||
socketPort = i;
|
||||
else cmdFatal("invalid -p option (%d)", i);
|
||||
else fatal("invalid -p option (%d)", i);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
|
@ -145,7 +161,7 @@ static void initOpts(int argc, char *argv[])
|
|||
break;
|
||||
|
||||
default:
|
||||
cmdFatal("invalid -s option (%d)", i);
|
||||
fatal("invalid -s option (%d)", i);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -154,21 +170,21 @@ static void initOpts(int argc, char *argv[])
|
|||
i = atoi(optarg);
|
||||
if ((i >= PI_CLOCK_PWM) && (i <= PI_CLOCK_PCM))
|
||||
clockPeripheral = i;
|
||||
else cmdFatal("invalid -t option (%d)", i);
|
||||
else fatal("invalid -t option (%d)", i);
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
i = atoi(optarg);
|
||||
if ((i >= PI_CLOCK_OSC) && (i <= PI_CLOCK_PLLD))
|
||||
clockSource = i;
|
||||
else cmdFatal("invalid -u option (%d)", i);
|
||||
else fatal("invalid -u option (%d)", i);
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
mask = strtoll(optarg, &endptr, 0);
|
||||
printf("mask=%llx\n", mask);
|
||||
if (!*endptr) updateMask = mask;
|
||||
else cmdFatal("invalid -x option (%s)", optarg);
|
||||
else fatal("invalid -x option (%s)", optarg);
|
||||
break;
|
||||
|
||||
default: /* '?' */
|
||||
|
@ -221,11 +237,11 @@ int main(int argc, char **argv)
|
|||
|
||||
/* Create a new SID for the child process */
|
||||
|
||||
if (setsid() < 0) cmdFatal("setsid failed (%m)");
|
||||
if (setsid() < 0) fatal("setsid failed (%m)");
|
||||
|
||||
/* Change the current working directory */
|
||||
|
||||
if ((chdir("/")) < 0) cmdFatal("chdir failed (%m)");
|
||||
if ((chdir("/")) < 0) fatal("chdir failed (%m)");
|
||||
|
||||
/* check command line parameters */
|
||||
|
||||
|
@ -252,7 +268,7 @@ int main(int argc, char **argv)
|
|||
|
||||
/* start library */
|
||||
|
||||
if (gpioInitialise()< 0) cmdFatal("Can't initialise pigpio library");
|
||||
if (gpioInitialise()< 0) fatal("Can't initialise pigpio library");
|
||||
|
||||
/* create pipe for error reporting */
|
||||
|
||||
|
@ -261,7 +277,7 @@ int main(int argc, char **argv)
|
|||
mkfifo(PI_ERRFIFO, 0664);
|
||||
|
||||
if (chmod(PI_ERRFIFO, 0664) < 0)
|
||||
cmdFatal("chmod %s failed (%m)", PI_ERRFIFO);
|
||||
fatal("chmod %s failed (%m)", PI_ERRFIFO);
|
||||
|
||||
errFifo = freopen(PI_ERRFIFO, "w+", stderr);
|
||||
|
||||
|
|
273
pigpiod_if.c
273
pigpiod_if.c
|
@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
|
|||
For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
/* PIGPIOD_IF_VERSION 1 */
|
||||
/* PIGPIOD_IF_VERSION 2 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -97,10 +97,34 @@ static int pigpio_command(int fd, int command, int p1, int p2)
|
|||
cmd.p2 = p2;
|
||||
cmd.res = 0;
|
||||
|
||||
if (send(fd, &cmd, sizeof(cmdCmd_t), 0) != sizeof(cmdCmd_t))
|
||||
return pigif_bad_send;
|
||||
if (send(fd, &cmd, sizeof(cmd), 0) != sizeof(cmd)) return pigif_bad_send;
|
||||
|
||||
if (recv(fd, &cmd, sizeof(cmdCmd_t), MSG_WAITALL) != sizeof(cmdCmd_t))
|
||||
if (recv(fd, &cmd, sizeof(cmd), MSG_WAITALL) != sizeof(cmd))
|
||||
return pigif_bad_recv;
|
||||
|
||||
return cmd.res;
|
||||
}
|
||||
|
||||
static int pigpio_command_ext
|
||||
(int fd, int command, int p1, int p2, int extents, gpioExtent_t *ext)
|
||||
{
|
||||
int i;
|
||||
cmdCmd_t cmd;
|
||||
|
||||
cmd.cmd = command;
|
||||
cmd.p1 = p1;
|
||||
cmd.p2 = p2;
|
||||
cmd.res = 0;
|
||||
|
||||
if (send(fd, &cmd, sizeof(cmd), 0) != sizeof(cmd)) return pigif_bad_send;
|
||||
|
||||
for (i=0; i<extents; i++)
|
||||
{
|
||||
if (send(fd, ext[i].ptr, ext[i].n, 0) != ext[i].n)
|
||||
return pigif_bad_send;
|
||||
}
|
||||
|
||||
if (recv(fd, &cmd, sizeof(cmd), MSG_WAITALL) != sizeof(cmd))
|
||||
return pigif_bad_recv;
|
||||
|
||||
return cmd.res;
|
||||
|
@ -390,7 +414,7 @@ unsigned pigpiod_if_version(void)
|
|||
return PIGPIOD_IF_VERSION;
|
||||
}
|
||||
|
||||
pthread_t *start_thread(ThreadFunc_t func, void *arg)
|
||||
pthread_t *start_thread(gpioThreadFunc_t func, void *arg)
|
||||
{
|
||||
pthread_t *pth;
|
||||
pthread_attr_t pthAttr;
|
||||
|
@ -501,144 +525,219 @@ void pigpio_stop(void)
|
|||
}
|
||||
|
||||
int set_mode(int gpio, int mode)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_MODES, gpio, mode);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_MODES, gpio, mode);}
|
||||
|
||||
int get_mode(int gpio)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_MODEG, gpio, 0);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_MODEG, gpio, 0);}
|
||||
|
||||
int set_pull_up_down(int gpio, int pud)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_PUD, gpio, pud);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PUD, gpio, pud);}
|
||||
|
||||
int read_gpio(int gpio)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_READ, gpio, 0);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_READ, gpio, 0);}
|
||||
|
||||
int write_gpio(int gpio, int level)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_WRITE, gpio, level);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_WRITE, gpio, level);}
|
||||
|
||||
int set_PWM_dutycycle(int user_gpio, int dutycycle)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_PWM, user_gpio, dutycycle);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PWM, user_gpio, dutycycle);}
|
||||
|
||||
int set_PWM_range(int user_gpio, int range_)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_PRS, user_gpio, range_);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PRS, user_gpio, range_);}
|
||||
|
||||
int get_PWM_range(int user_gpio)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_PRG, user_gpio, 0);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PRG, user_gpio, 0);}
|
||||
|
||||
int get_PWM_real_range(int user_gpio)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_PRRG, user_gpio, 0);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PRRG, user_gpio, 0);}
|
||||
|
||||
int set_PWM_frequency(int user_gpio, int frequency)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_PFS, user_gpio, frequency);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PFS, user_gpio, frequency);}
|
||||
|
||||
int get_PWM_frequency(int user_gpio)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_PFG, user_gpio, 0);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PFG, user_gpio, 0);}
|
||||
|
||||
int set_servo_pulsewidth(int user_gpio, int pulsewidth)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_SERVO, user_gpio, pulsewidth);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_SERVO, user_gpio, pulsewidth);}
|
||||
|
||||
int notify_open(void)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_NO, 0, 0);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_NO, 0, 0);}
|
||||
|
||||
int notify_begin(int handle, uint32_t bits)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_NB, handle, bits);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_NB, handle, bits);}
|
||||
|
||||
int notify_pause(int handle)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_NB, handle, 0);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_NB, handle, 0);}
|
||||
|
||||
int notify_close(int handle)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_NC, handle, 0);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_NC, handle, 0);}
|
||||
|
||||
int set_watchdog(int user_gpio, int timeout)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_WDOG, user_gpio, timeout);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_WDOG, user_gpio, timeout);}
|
||||
|
||||
uint32_t read_bank_1(void)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_BR1, 0, 0);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_BR1, 0, 0);}
|
||||
|
||||
uint32_t read_bank_2(void)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_BR2, 0, 0);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_BR2, 0, 0);}
|
||||
|
||||
int clear_bank_1(uint32_t levels)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_BC1, levels, 0);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_BC1, levels, 0);}
|
||||
|
||||
int clear_bank_2(uint32_t levels)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_BC2, levels, 0);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_BC2, levels, 0);}
|
||||
|
||||
int set_bank_1(uint32_t levels)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_BS1, levels, 0);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_BS1, levels, 0);}
|
||||
|
||||
int set_bank_2(uint32_t levels)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_BS2, levels, 0);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_BS2, levels, 0);}
|
||||
|
||||
uint32_t get_current_tick(void)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_TICK, 0, 0);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_TICK, 0, 0);}
|
||||
|
||||
uint32_t get_hardware_revision(void)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_HWVER, 0, 0);
|
||||
}
|
||||
{return pigpio_command(gPigCommand, PI_CMD_HWVER, 0, 0);}
|
||||
|
||||
unsigned get_pigpio_version(void)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PIGPV, 0, 0);}
|
||||
|
||||
int wave_clear(void)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_WVCLR, 0, 0);}
|
||||
|
||||
int wave_add_generic(unsigned numPulses, gpioPulse_t *pulses)
|
||||
{
|
||||
return pigpio_command(gPigCommand, PI_CMD_PIGPV, 0, 0);
|
||||
gpioExtent_t ext[1];
|
||||
|
||||
/*
|
||||
p1=numPulses
|
||||
p2=0
|
||||
## extension ##
|
||||
gpioPulse_t[] pulses
|
||||
*/
|
||||
|
||||
ext[0].n = numPulses * sizeof(gpioPulse_t);
|
||||
ext[0].ptr = pulses;
|
||||
|
||||
return pigpio_command_ext(gPigCommand, PI_CMD_WVAG, numPulses, 0, 1, ext);
|
||||
}
|
||||
|
||||
int wave_add_serial(
|
||||
unsigned gpio, unsigned baud, unsigned offset, unsigned numChar, char *str)
|
||||
{
|
||||
gpioExtent_t ext[3];
|
||||
|
||||
/*
|
||||
p1=gpio
|
||||
p2=numChar
|
||||
## extension ##
|
||||
unsigned baud
|
||||
unsigned offset
|
||||
char[] str
|
||||
*/
|
||||
|
||||
ext[0].n = sizeof(unsigned);
|
||||
ext[0].ptr = &baud;
|
||||
|
||||
ext[1].n = sizeof(unsigned);
|
||||
ext[1].ptr = &offset;
|
||||
|
||||
ext[2].n = numChar;
|
||||
ext[2].ptr = str;
|
||||
|
||||
return pigpio_command_ext(gPigCommand, PI_CMD_WVAS, gpio, numChar, 3, ext);
|
||||
}
|
||||
|
||||
int wave_tx_busy(void)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_WVBSY, 0, 0);}
|
||||
|
||||
int wave_tx_stop(void)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_WVHLT, 0, 0);}
|
||||
|
||||
int wave_tx_start(void)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_WVGO, 0, 0);}
|
||||
|
||||
int wave_tx_repeat(void)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_WVGOR, 0, 0);}
|
||||
|
||||
int wave_get_micros(void)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_WVSM, 0, 0);}
|
||||
|
||||
int wave_get_high_micros(void)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_WVSM, 1, 0);}
|
||||
|
||||
int wave_get_max_micros(void)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_WVSM, 2, 0);}
|
||||
|
||||
int wave_get_pulses(void)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_WVSP, 0, 0);}
|
||||
|
||||
int wave_get_high_pulses(void)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_WVSP, 1, 0);}
|
||||
|
||||
int wave_get_max_pulses(void)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_WVSP, 2, 0);}
|
||||
|
||||
int wave_get_cbs(void)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_WVSC, 0, 0);}
|
||||
|
||||
int wave_get_high_cbs(void)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_WVSC, 1, 0);}
|
||||
|
||||
int wave_get_max_cbs(void)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_WVSC, 2, 0);}
|
||||
|
||||
int gpio_trigger(unsigned gpio, unsigned pulseLen, unsigned level)
|
||||
{
|
||||
gpioExtent_t ext[1];
|
||||
|
||||
/*
|
||||
p1=gpio
|
||||
p2=pulseLen
|
||||
## extension ##
|
||||
unsigned level
|
||||
*/
|
||||
|
||||
ext[0].n = sizeof(level);
|
||||
ext[0].ptr = &level;
|
||||
|
||||
return pigpio_command_ext(gPigCommand, PI_CMD_TRIG, gpio, pulseLen, 1, ext);
|
||||
}
|
||||
|
||||
int store_script(char *script)
|
||||
{
|
||||
unsigned len;
|
||||
gpioExtent_t ext[1];
|
||||
|
||||
/*
|
||||
p1=script length
|
||||
p2=0
|
||||
## extension ##
|
||||
char[] script
|
||||
*/
|
||||
|
||||
len = strlen(script);
|
||||
|
||||
ext[0].n = len;
|
||||
ext[0].ptr = script;
|
||||
|
||||
return pigpio_command_ext(gPigCommand, PI_CMD_PROC, len, 0, 1, ext);
|
||||
}
|
||||
|
||||
int run_script(int script_id)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PROCR, script_id, 0);}
|
||||
|
||||
int stop_script(int script_id)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PROCS, script_id, 0);}
|
||||
|
||||
int delete_script(int script_id)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PROCD, script_id, 0);}
|
||||
|
||||
int callback(int gpio, int edge, CBFunc_t f)
|
||||
{
|
||||
return intCallback(gpio, edge, f, 0, 0);
|
||||
}
|
||||
{return intCallback(gpio, edge, f, 0, 0);}
|
||||
|
||||
int callback_ex(int gpio, int edge, CBFuncEx_t f, void *user)
|
||||
{
|
||||
return intCallback(gpio, edge, f, user, 1);
|
||||
}
|
||||
{return intCallback(gpio, edge, f, user, 1);}
|
||||
|
||||
int callback_cancel(int id)
|
||||
{
|
||||
|
|
198
pigpiod_if.h
198
pigpiod_if.h
|
@ -30,7 +30,7 @@ For more information, please refer to <http://unlicense.org/>
|
|||
|
||||
#include "pigpio.h"
|
||||
|
||||
#define PIGPIOD_IF_VERSION 1
|
||||
#define PIGPIOD_IF_VERSION 2
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -70,7 +70,7 @@ const char *pigpio_error(int error);
|
|||
unsigned pigpiod_if_version(void);
|
||||
/* Return the pigpiod_if version. */
|
||||
|
||||
pthread_t *start_thread(ThreadFunc_t func, void *arg);
|
||||
pthread_t *start_thread(gpioThreadFunc_t func, void *arg);
|
||||
/* Starts a new thread of execution with func as the main routine.
|
||||
|
||||
Returns a pointer to pthread_t if OK, otherwise NULL.
|
||||
|
@ -198,7 +198,6 @@ int set_PWM_range(int user_gpio, int range_);
|
|||
|
||||
The real value set by set_PWM_range is
|
||||
(dutycycle * real range) / range.
|
||||
|
||||
*/
|
||||
|
||||
int get_PWM_range(int user_gpio);
|
||||
|
@ -507,20 +506,213 @@ uint32_t get_hardware_revision(void);
|
|||
hexadecimal number the function returns 0.
|
||||
*/
|
||||
|
||||
int wave_clear(void);
|
||||
/* This function initialises a new waveform.
|
||||
|
||||
Returns 0 if OK.
|
||||
|
||||
A waveform comprises one of more pulses. Each pulse consists of a
|
||||
gpioPulse_t structure.
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t gpioOn;
|
||||
uint32_t gpioOff;
|
||||
uint32_t usDelay;
|
||||
} gpioPulse_t;
|
||||
|
||||
The fields specify
|
||||
|
||||
1) the gpios to be switched on at the start of the pulse.
|
||||
2) the gpios to be switched off at the start of the pulse.
|
||||
3) the delay in microseconds before the next pulse.
|
||||
|
||||
Any or all the fields can be zero. It doesn't make any sense to
|
||||
set all the fields to zero (the pulse will be ignored).
|
||||
|
||||
When a waveform is started each pulse is executed in order with the
|
||||
specified delay between the pulse and the next.
|
||||
*/
|
||||
|
||||
int wave_tx_busy(void);
|
||||
/* This function checks to see if a waveform is currently being
|
||||
transmitted.
|
||||
|
||||
Returns 1 if a waveform is currently being transmitted, otherwise 0.
|
||||
*/
|
||||
|
||||
int wave_tx_stop(void);
|
||||
/* This function stops the transmission of the current waveform.
|
||||
|
||||
Returns 0 if OK.
|
||||
|
||||
This function is intended to stop a waveform started with the repeat mode.
|
||||
*/
|
||||
|
||||
int wave_tx_start(void);
|
||||
/* This function transmits the current waveform. The waveform is
|
||||
sent once.
|
||||
|
||||
Returns the number of DMA control blocks in the waveform if OK,
|
||||
otherwise PI_BAD_WAVE_MODE.
|
||||
*/
|
||||
|
||||
int wave_tx_repeat(void);
|
||||
/* This function transmits the current waveform. The waveform repeats
|
||||
endlessly until wave_tx_stop is called.
|
||||
|
||||
Returns the number of DMA control blocks in the waveform if OK,
|
||||
otherwise PI_BAD_WAVE_MODE.
|
||||
*/
|
||||
|
||||
int wave_add_generic(unsigned numPulses, gpioPulse_t *pulses);
|
||||
/* This function adds a number of pulses to the current waveform.
|
||||
|
||||
Returns the new total number of pulses in the current waveform if OK,
|
||||
otherwise PI_TOO_MANY_PULSES.
|
||||
|
||||
The pulses are interleaved in time order within the existing waveform
|
||||
(if any).
|
||||
|
||||
Merging allows the waveform to be built in parts, that is the settings
|
||||
for gpio#1 can be added, and then gpio#2 etc.
|
||||
|
||||
If the added waveform is intended to start after or within the existing
|
||||
waveform then the first pulse should consist solely of a delay.
|
||||
*/
|
||||
|
||||
int wave_add_serial
|
||||
(unsigned gpio, unsigned baud, unsigned offset, unsigned numChar, char *str);
|
||||
/* This function adds a waveform representing serial data to the
|
||||
existing waveform (if any). The serial data starts offset microseconds
|
||||
from the start of the waveform.
|
||||
|
||||
Returns the new total number of pulses in the current waveform if OK,
|
||||
otherwise PI_BAD_USER_GPIO, PI_BAD_WAVE_BAUD, PI_TOO_MANY_CHARS, or
|
||||
PI_TOO_MANY_PULSES.
|
||||
|
||||
NOTES:
|
||||
|
||||
The serial data is formatted as one start bit, eight data bits, and one
|
||||
stop bit.
|
||||
|
||||
It is legal to add serial data streams with different baud rates to
|
||||
the same waveform.
|
||||
*/
|
||||
|
||||
int wave_get_micros(void);
|
||||
/* This function returns the length in microseconds of the current
|
||||
waveform.
|
||||
*/
|
||||
|
||||
int wave_get_high_micros(void);
|
||||
/* This function returns the length in microseconds of the longest waveform
|
||||
created since the pigpio daemon was started..
|
||||
*/
|
||||
|
||||
int wave_get_max_micros(void);
|
||||
/* This function returns the maximum possible size of a waveform in
|
||||
microseconds.
|
||||
*/
|
||||
|
||||
int wave_get_pulses(void);
|
||||
/* This function returns the length in pulses of the current waveform.
|
||||
*/
|
||||
|
||||
int wave_get_high_pulses(void);
|
||||
/* This function returns the length in pulses of the longest waveform
|
||||
created since the pigpio daemon was started..
|
||||
*/
|
||||
|
||||
int wave_get_max_pulses(void);
|
||||
/* This function returns the maximum possible size of a waveform in pulses.
|
||||
*/
|
||||
|
||||
int wave_get_cbs(void);
|
||||
/* This function returns the length in DMA control blocks of the current
|
||||
waveform.
|
||||
*/
|
||||
|
||||
int wave_get_high_cbs(void);
|
||||
/* This function returns the length in DMA control blocks of the longest
|
||||
waveform created since the pigpio daemon was started..
|
||||
*/
|
||||
|
||||
int wave_get_max_cbs(void);
|
||||
/* This function returns the maximum possible size of a waveform in DMA
|
||||
control blocks.
|
||||
*/
|
||||
|
||||
int gpio_trigger(unsigned gpio, unsigned pulseLen, unsigned level);
|
||||
/* This function sends a trigger pulse to a gpio. The gpio is set to
|
||||
level for pulseLen microseconds and then reset to not level.
|
||||
|
||||
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_LEVEL,
|
||||
PI_BAD_PULSELEN, or PI_NOT_PERMITTED.
|
||||
*/
|
||||
|
||||
int store_script(char *script);
|
||||
/* This function stores a script for later execution.
|
||||
|
||||
The function returns a script id if the script is valid,
|
||||
otherwise PI_BAD_SCRIPT.
|
||||
*/
|
||||
|
||||
int run_script(int script_id);
|
||||
/* This function runs a stored script.
|
||||
|
||||
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
|
||||
*/
|
||||
|
||||
int stop_script(int script_id);
|
||||
/* This function stops a running script.
|
||||
|
||||
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
|
||||
*/
|
||||
|
||||
int delete_script(int script_id);
|
||||
/* This function deletes a stored script.
|
||||
|
||||
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
|
||||
*/
|
||||
|
||||
int callback(int gpio, int edge, CBFunc_t f);
|
||||
/*
|
||||
This function initialises a new callback.
|
||||
|
||||
The function returns a callback id if OK, otherwise pigif_bad_malloc,
|
||||
pigif_duplicate_callback, or pigif_bad_callback.
|
||||
|
||||
The callback is called with the gpio, edge, and tick, whenever the
|
||||
gpio has the identified edge.
|
||||
*/
|
||||
|
||||
int callback_ex(int gpio, int edge, CBFuncEx_t f, void *user);
|
||||
/*
|
||||
This function initialises a new callback.
|
||||
|
||||
The function returns a callback id if OK, otherwise pigif_bad_malloc,
|
||||
pigif_duplicate_callback, or pigif_bad_callback.
|
||||
|
||||
The callback is called with the gpio, edge, tick, and user, whenever
|
||||
the gpio has the identified edge.
|
||||
*/
|
||||
|
||||
int callback_cancel(int id);
|
||||
/*
|
||||
This function cancels a callback identified by its id.
|
||||
|
||||
The function returns 0 if OK, otherwise pigif_callback_not_found.
|
||||
*/
|
||||
|
||||
int wait_for_edge(int gpio, int edge, double timeout);
|
||||
/*
|
||||
This function waits for edge on the gpio for up to timeout
|
||||
seconds.
|
||||
|
||||
The function returns 1 if the edge occurred, otherwise 0.
|
||||
|
||||
The function returns when the edge occurs or after the timeout.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
63
pigs.c
63
pigs.c
|
@ -26,11 +26,12 @@ For more information, please refer to <http://unlicense.org/>
|
|||
*/
|
||||
|
||||
/*
|
||||
This version is for pigpio version 7+
|
||||
This version is for pigpio version 11+
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -42,10 +43,26 @@ This version is for pigpio version 7+
|
|||
#include "command.h"
|
||||
|
||||
/*
|
||||
This program provides a socket interface
|
||||
to the commands available from pigpio.
|
||||
This program provides a socket interface to some of
|
||||
the commands available from pigpio.
|
||||
*/
|
||||
|
||||
void fatal(char *fmt, ...)
|
||||
{
|
||||
char buf[128];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
|
||||
fflush(stderr);
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static int openSocket(void)
|
||||
{
|
||||
int sock, err;
|
||||
|
@ -88,9 +105,10 @@ static int openSocket(void)
|
|||
|
||||
int main(int argc , char *argv[])
|
||||
{
|
||||
int sock, r, idx;
|
||||
int sock, r, idx, i;
|
||||
cmdCmd_t cmd;
|
||||
char buf[128];
|
||||
gpioExtent_t ext[3];
|
||||
char buf[1024];
|
||||
|
||||
sock = openSocket();
|
||||
|
||||
|
@ -113,31 +131,48 @@ int main(int argc , char *argv[])
|
|||
sprintf(buf, "%10s %10s %10s", argv[1], argv[2], argv[3]);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
sprintf(buf, "%10s %10s %10s %10s",
|
||||
argv[1], argv[2], argv[3], argv[4]);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
sprintf(buf, "%10s %10s %10s %10s %10s",
|
||||
argv[1], argv[2], argv[3], argv[4], argv[5]);
|
||||
break;
|
||||
|
||||
default:
|
||||
cmdFatal("what?");
|
||||
fatal("what? 'pigs h' for help");
|
||||
}
|
||||
|
||||
if ((idx=cmdParse(buf, &cmd)) >= 0)
|
||||
if ((idx=cmdParse(buf, &cmd, argc, argv, ext)) >= 0)
|
||||
{
|
||||
if (send(sock, &cmd, sizeof(cmdCmd_t), 0) == sizeof(cmdCmd_t))
|
||||
{
|
||||
/* send extensions */
|
||||
|
||||
for (i=0; i<cmdInfo[idx].ext; i++)
|
||||
{
|
||||
send(sock, ext[i].ptr, ext[i].n, 0);
|
||||
}
|
||||
|
||||
if (recv(sock, &cmd, sizeof(cmdCmd_t), 0) == sizeof(cmdCmd_t))
|
||||
{
|
||||
switch (cmdInfo[idx].rv)
|
||||
{
|
||||
case 0:
|
||||
r = cmd.res;
|
||||
if (r < 0) cmdFatal("ERROR: %s", cmdErrStr(r));
|
||||
if (r < 0) fatal("ERROR: %s", cmdErrStr(r));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
r = cmd.res;
|
||||
if (r < 0) cmdFatal("ERROR: %s", cmdErrStr(r));
|
||||
if (r < 0) fatal("ERROR: %s", cmdErrStr(r));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
r = cmd.res;
|
||||
if (r < 0) cmdFatal("ERROR: %s", cmdErrStr(r));
|
||||
if (r < 0) fatal("ERROR: %s", cmdErrStr(r));
|
||||
else printf("%d\n", r);
|
||||
break;
|
||||
|
||||
|
@ -154,13 +189,13 @@ int main(int argc , char *argv[])
|
|||
break;
|
||||
}
|
||||
}
|
||||
else cmdFatal("recv failed, %m");
|
||||
else fatal("recv failed, %m");
|
||||
}
|
||||
else cmdFatal("send failed, %m");
|
||||
else fatal("send failed, %m");
|
||||
}
|
||||
else cmdFatal("what?");
|
||||
else fatal("what? 'pigs h' for help");
|
||||
}
|
||||
else cmdFatal("connect failed, %m");
|
||||
else fatal("connect failed, %m");
|
||||
|
||||
close(sock);
|
||||
|
||||
|
|
4
setup.py
4
setup.py
|
@ -3,7 +3,7 @@
|
|||
from distutils.core import setup
|
||||
|
||||
setup(name='pigpio',
|
||||
version='1.1',
|
||||
version='1.2',
|
||||
author='joan',
|
||||
author_email='joan@abyz.me.uk',
|
||||
maintainer='joan',
|
||||
|
@ -11,7 +11,7 @@ setup(name='pigpio',
|
|||
url='http://abyz.co.uk/rpi/pigpio/python.html/',
|
||||
description='Raspberry Pi gpio module',
|
||||
long_description='Raspberry Pi Python module for access to the pigpio daemon',
|
||||
download_url='http://abyz.co.uk/rpi/pigpio/pigpio.tar',
|
||||
download_url='http://abyz.co.uk/rpi/pigpio/pigpio.zip',
|
||||
license='TBD',
|
||||
py_modules=['pigpio']
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue