mirror of https://github.com/joan2937/pigpio
V12
This commit is contained in:
parent
23e3b179ab
commit
8794220811
|
@ -5,9 +5,9 @@ SIZE = size
|
|||
|
||||
CFLAGS = -O3 -Wall
|
||||
|
||||
ALL = libpigpiod_if.a pigs pigpio.py setup.py
|
||||
ALL = libpigpiod_if.a pigs
|
||||
|
||||
all: $(ALL)
|
||||
all: $(ALL) pigpio.py setup.py
|
||||
|
||||
pigs: command.o pigs.o
|
||||
$(CC) -o pigs pigs.c command.c
|
||||
|
|
201
command.c
201
command.c
|
@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
|
|||
*/
|
||||
|
||||
/*
|
||||
This version is for pigpio version 11+
|
||||
This version is for pigpio version 12+
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -46,6 +46,7 @@ This version is for pigpio version 11+
|
|||
3 %08X %08X
|
||||
4 %u %u
|
||||
5 HELP HELP
|
||||
6 %s <0 ERR
|
||||
*/
|
||||
|
||||
/* vfyt
|
||||
|
@ -58,6 +59,7 @@ This version is for pigpio version 11+
|
|||
8 MODES %d %c
|
||||
9 PUD %d %c
|
||||
10 PROG %s
|
||||
11 WVAS %d %d %d %s
|
||||
*/
|
||||
|
||||
cmdInfo_t cmdInfo[]=
|
||||
|
@ -98,6 +100,9 @@ cmdInfo_t cmdInfo[]=
|
|||
{PI_CMD_READ, "READ", 2, 2, 0},
|
||||
{PI_CMD_SERVO, "S", 3, 0, 0},
|
||||
{PI_CMD_SERVO, "SERVO", 3, 0, 0},
|
||||
{PI_CMD_SLR, "SLR", 3, 6, 0},
|
||||
{PI_CMD_SLRC, "SLRC", 2, 2, 0},
|
||||
{PI_CMD_SLRO, "SLRO", 3, 2, 0},
|
||||
{PI_CMD_WDOG, "WDOG", 3, 0, 0},
|
||||
{PI_CMD_WRITE, "W", 3, 0, 0},
|
||||
{PI_CMD_WRITE, "WRITE", 3, 0, 0},
|
||||
|
@ -116,68 +121,72 @@ cmdInfo_t cmdInfo[]=
|
|||
};
|
||||
|
||||
char * cmdUsage = "\
|
||||
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\
|
||||
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\
|
||||
NC h close notification\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\
|
||||
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\
|
||||
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\
|
||||
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\
|
||||
BC1 x Clear gpios x in bank 1.\n\
|
||||
BC2 x Clear gpios x in bank 2.\n\
|
||||
BR1 Read gpios bank 1.\n\
|
||||
BR2 Read gpios bank 2.\n\
|
||||
BS1 x Set gpios x in bank 1.\n\
|
||||
BS2 x Set gpios x in bank 2.\n\
|
||||
H Displays command help.\n\
|
||||
HELP Displays command help.\n\
|
||||
HWVER Return hardware version.\n\
|
||||
M g m Set gpio g to mode m.\n\
|
||||
MG g Get gpio g mode.\n\
|
||||
MODEG g Get gpio g mode.\n\
|
||||
MODES g m Set gpio g to mode m.\n\
|
||||
NB h x Start notifications on handle h with x.\n\
|
||||
NC h Close notification handle h.\n\
|
||||
NO Request notification handle.\n\
|
||||
NP h Pause notifications on handle h.\n\
|
||||
P u d Set PWM value for user gpio u to d.\n\
|
||||
PFG u Get PWM frequency for user gpio u.\n\
|
||||
PFS u d Set PWM frequency for user gpio u to d.\n\
|
||||
PIGPV Return pigpio version.\n\
|
||||
PRG u Get PWM range for user gpio u.\n\
|
||||
PROC t Store text t of script.\n\
|
||||
PROCD s Delete script s.\n\
|
||||
PROCR s Run script s.\n\
|
||||
PROCS s Stop script s.\n\
|
||||
PRRG u Get PWM real range for user gpio u.\n\
|
||||
PRS u d Set PWM range for user gpio u to d.\n\
|
||||
PUD g p Set gpio pull up/down for gpio g to p.\n\
|
||||
PWM u d Set PWM value for user gpio u to d.\n\
|
||||
R g Read gpio g.\n\
|
||||
READ g Read gpio g.\n\
|
||||
S u d Set servo value for user gpio u to d microseconds.\n\
|
||||
SERVO u d Set servo value for user gpio u to d microseconds.\n\
|
||||
SLR u d Read up to d bytes of serial data from user gpio u.\n\
|
||||
SLRC u Close user gpio u for serial data.\n\
|
||||
SLRO u b Open user gpio u for serial data at b baud.\n\
|
||||
T Return current tick.\n\
|
||||
TICK Return current tick.\n\
|
||||
TRIG u pl L Trigger level L for pl micros on user gpio u.\n\
|
||||
W g L Write level L to gpio g.\n\
|
||||
WDOG u d Set watchdog of d milliseconds on user gpio u.\n\
|
||||
WRITE g L Write level L to gpio g.\n\
|
||||
WVAS u b o t Wave add serial data t to user gpio u at b baud.\n\
|
||||
WVBSY Check if wave busy.\n\
|
||||
WVCLR Wave clear.\n\
|
||||
WVGO Wave transmit.\n\
|
||||
WVGOR Wave transmit repeatedly.\n\
|
||||
WVHLT Wave stop.\n\
|
||||
WVSC ws Wave get DMA control block stats.\n\
|
||||
WVSM ws Wave get micros stats.\n\
|
||||
WVSP ws Wave get pulses stats.\n\
|
||||
.\n\
|
||||
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\
|
||||
o = offset (0-).\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\
|
||||
";
|
||||
|
||||
typedef struct
|
||||
|
@ -237,6 +246,8 @@ static errInfo_t errInfo[]=
|
|||
{PI_BAD_SCRIPT , "invalid script"},
|
||||
{PI_BAD_SCRIPT_ID , "unknown script id"},
|
||||
{PI_BAD_SER_OFFSET , "add serial data offset > 30 minute"},
|
||||
{PI_GPIO_IN_USE , "gpio already in use"},
|
||||
{PI_BAD_SERIAL_COUNT , "must read at least a byte at a time"},
|
||||
};
|
||||
|
||||
static char * fmtMdeStr="RW540123";
|
||||
|
@ -256,7 +267,7 @@ static int cmdMatch(char * str)
|
|||
int cmdParse(char *buf, cmdCmd_t *cmd, int argc, char *argv[], gpioExtent_t *ext)
|
||||
{
|
||||
char str[8];
|
||||
int f, valid, idx, val;
|
||||
int f, valid, idx, val, p;
|
||||
char *ptr;
|
||||
char c, t;
|
||||
|
||||
|
@ -276,21 +287,21 @@ int cmdParse(char *buf, cmdCmd_t *cmd, int argc, char *argv[], gpioExtent_t *ext
|
|||
|
||||
switch (cmdInfo[idx].vt)
|
||||
{
|
||||
case 1: /* BR1 BR2 HWVER NO PIGPV TICK WVBSY WVCLR WVGO WVGOR
|
||||
WVHLT
|
||||
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 NC NP PFG PRG PROCD PROCR PROCS PRRG READ
|
||||
WVSC WVSM WVSP
|
||||
case 2: /* MODEG NC NP PFG PRG PROCD PROCR PROCS PRRG
|
||||
SLRC READ WVSC WVSM WVSP
|
||||
*/
|
||||
f = sscanf(buf, " %7s %d %c", str, &cmd->p1, &t);
|
||||
if (f == 2) valid = 1;
|
||||
break;
|
||||
|
||||
case 3: /* PFS PRS PWM SERVO WDOG WRITE
|
||||
case 3: /* PFS PRS PWM SERVO SLR SLRO WDOG WRITE
|
||||
*/
|
||||
f = sscanf(buf, " %7s %d %d %c", str, &cmd->p1, &cmd->p2, &t);
|
||||
if (f == 3) valid = 1;
|
||||
|
@ -308,7 +319,7 @@ int cmdParse(char *buf, cmdCmd_t *cmd, int argc, char *argv[], gpioExtent_t *ext
|
|||
str, &cmd->p1, &cmd->p2, &ext[0].data, &t);
|
||||
if (f == 4)
|
||||
{
|
||||
ext[0].n = sizeof(unsigned);
|
||||
ext[0].size = sizeof(unsigned);
|
||||
ext[0].ptr = &ext[0].data;
|
||||
valid = 1;
|
||||
}
|
||||
|
@ -319,7 +330,7 @@ int cmdParse(char *buf, cmdCmd_t *cmd, int argc, char *argv[], gpioExtent_t *ext
|
|||
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;
|
||||
|
@ -359,38 +370,56 @@ int cmdParse(char *buf, cmdCmd_t *cmd, int argc, char *argv[], gpioExtent_t *ext
|
|||
|
||||
case 10: /* PROC
|
||||
*/
|
||||
if (argc == 3)
|
||||
if ((argc == 0) || (argc == 3))
|
||||
{
|
||||
cmd->p1 = strlen(argv[2]);
|
||||
ext[0].n = cmd->p1;
|
||||
ext[0].ptr = argv[2];
|
||||
if (argc == 3)
|
||||
{
|
||||
cmd->p1 = strlen(argv[2]);
|
||||
ext[0].ptr = argv[2];
|
||||
}
|
||||
else /* pipe i/f */
|
||||
{
|
||||
sscanf(buf, "%*s %n", &p);
|
||||
cmd->p1 = strlen(buf+p);
|
||||
ext[0].ptr = buf+p;
|
||||
}
|
||||
ext[0].size = cmd->p1;
|
||||
valid = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 11: /* WVAS
|
||||
*/
|
||||
if (argc == 6)
|
||||
if ((argc == 0) || (argc == 6))
|
||||
{
|
||||
f = sscanf(buf, " %7s %d %d %d ",
|
||||
str, &cmd->p1, &ext[0].data, &ext[1].data);
|
||||
if (f == 4)
|
||||
f = sscanf(buf, " %*s %d %d %d %n",
|
||||
&cmd->p1, &ext[0].data, &ext[1].data, &p);
|
||||
if (f == 3)
|
||||
{
|
||||
ext[0].n = sizeof(unsigned);
|
||||
ext[0].size = sizeof(unsigned);
|
||||
ext[0].ptr = &ext[0].data;
|
||||
ext[1].n = sizeof(unsigned);
|
||||
ext[1].size = sizeof(unsigned);
|
||||
ext[1].ptr = &ext[1].data;
|
||||
cmd->p2 = strlen(argv[5]);
|
||||
ext[2].n = cmd->p2;
|
||||
ext[2].ptr = argv[5];
|
||||
|
||||
if (argc) /* pigs */
|
||||
{
|
||||
cmd->p2 = strlen(argv[5]);
|
||||
ext[2].ptr = argv[5];
|
||||
}
|
||||
else /* pipe i/f */
|
||||
{
|
||||
cmd->p2 = strlen(buf+p);
|
||||
ext[2].ptr = buf+p;
|
||||
}
|
||||
|
||||
ext[2].size = cmd->p2;
|
||||
valid = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (valid) return idx;
|
||||
else return -1;
|
||||
if (valid) return idx; else return -1;
|
||||
}
|
||||
|
||||
char * cmdErrStr(int error)
|
||||
|
|
304
pigpio.c
304
pigpio.c
|
@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
|
|||
For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
/* pigpio version 11 */
|
||||
/* pigpio version 12 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -557,6 +557,9 @@ bit 0 READ_LAST_NOT_SET_ERROR
|
|||
|
||||
#define MAX_EMITS (PIPE_BUF / sizeof(gpioReport_t))
|
||||
|
||||
#define SRX_BUF_SIZE 8192
|
||||
#define CMD_BUF_SIZE 2048
|
||||
|
||||
/* --------------------------------------------------------------- */
|
||||
|
||||
typedef void (*callbk_t) ();
|
||||
|
@ -701,16 +704,21 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
gpioRx_t * rxp;
|
||||
uint32_t baud;
|
||||
uint32_t fullBit;
|
||||
uint32_t halfBit;
|
||||
uint32_t startBitTick;
|
||||
uint32_t nextBitDiff;
|
||||
int bit;
|
||||
int byte;
|
||||
int level;
|
||||
int mode;
|
||||
int gpio;
|
||||
char * buf;
|
||||
uint32_t bufSize;
|
||||
int readPos;
|
||||
int writePos;
|
||||
uint32_t baud;
|
||||
uint32_t fullBit;
|
||||
uint32_t halfBit;
|
||||
int timeout;
|
||||
uint32_t startBitTick;
|
||||
uint32_t nextBitDiff;
|
||||
int bit;
|
||||
int byte;
|
||||
int level;
|
||||
int mode;
|
||||
} wfRx_t;
|
||||
|
||||
|
||||
|
@ -757,7 +765,7 @@ static wfStats_t wfStats=
|
|||
0, 0, (PAGES_PER_BLOCK * CBS_PER_OPAGE)
|
||||
};
|
||||
|
||||
static wfRx_t wfRx[PI_MAX_USER_GPIO+1];
|
||||
static volatile wfRx_t wfRx[PI_MAX_USER_GPIO+1];
|
||||
|
||||
static volatile uint32_t alertBits = 0;
|
||||
static volatile uint32_t monitorBits = 0;
|
||||
|
@ -977,7 +985,8 @@ static uint32_t myGetTick(int pos)
|
|||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static void myDoCommand(cmdCmd_t *cmd, gpioExtent_t *ext)
|
||||
static void myDoCommand
|
||||
(cmdCmd_t *cmd, gpioExtent_t *iExt, gpioExtent_t *oExt)
|
||||
{
|
||||
int p1, p2, res, i;
|
||||
uint32_t mask, tmp;
|
||||
|
@ -1090,7 +1099,7 @@ static void myDoCommand(cmdCmd_t *cmd, gpioExtent_t *ext)
|
|||
case PI_CMD_PRG: res = gpioGetPWMrange(p1); break;
|
||||
|
||||
case PI_CMD_PROC:
|
||||
res = gpioStoreScript(ext[0].ptr);
|
||||
res = gpioStoreScript(iExt[0].ptr);
|
||||
break;
|
||||
|
||||
case PI_CMD_PROCD: res = gpioDeleteScript(p1); break;
|
||||
|
@ -1132,6 +1141,36 @@ static void myDoCommand(cmdCmd_t *cmd, gpioExtent_t *ext)
|
|||
|
||||
case PI_CMD_READ: res = gpioRead(p1); 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_SLRO: res = gpioSerialReadOpen(p1, p2); break;
|
||||
|
||||
case PI_CMD_SLR:
|
||||
if (p2 < oExt[0].size) oExt[0].size = p2;
|
||||
res = gpioSerialRead(p1, oExt[0].ptr, oExt[0].size);
|
||||
break;
|
||||
|
||||
case PI_CMD_SLRC: res = gpioSerialReadClose(p1); break;
|
||||
|
||||
case PI_CMD_TICK: res = gpioTick(); break;
|
||||
|
||||
case PI_CMD_TRIG:
|
||||
if (gpioMask & (uint64_t)(1<<p1))
|
||||
res = gpioTrigger(p1, p2, *(int *) (iExt[0].ptr));
|
||||
else
|
||||
{
|
||||
PERM_ERROR("gpioTrigger: gpio %d, no permission to update", p1);
|
||||
res = PI_NOT_PERMITTED;
|
||||
}
|
||||
break;
|
||||
|
||||
case PI_CMD_WDOG: res = gpioSetWatchdog(p1, p2); break;
|
||||
|
||||
case PI_CMD_WRITE:
|
||||
|
@ -1143,33 +1182,12 @@ static void myDoCommand(cmdCmd_t *cmd, gpioExtent_t *ext)
|
|||
}
|
||||
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_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_WVAG:
|
||||
|
||||
/* need to mask off any non permitted gpios */
|
||||
|
||||
mask = gpioMask;
|
||||
pulse = ext[0].ptr;
|
||||
pulse = iExt[0].ptr;
|
||||
masked = 0;
|
||||
|
||||
for (i=0; i<p1; i++)
|
||||
|
@ -1200,10 +1218,10 @@ static void myDoCommand(cmdCmd_t *cmd, gpioExtent_t *ext)
|
|||
if (gpioMask & (uint64_t)(1<<p1))
|
||||
res = gpioWaveAddSerial
|
||||
(p1,
|
||||
*(int *)(ext[0].ptr),
|
||||
*(int *)(ext[1].ptr),
|
||||
*(int *)(iExt[0].ptr),
|
||||
*(int *)(iExt[1].ptr),
|
||||
p2,
|
||||
ext[2].ptr);
|
||||
iExt[2].ptr);
|
||||
else
|
||||
{
|
||||
PERM_ERROR
|
||||
|
@ -1655,9 +1673,10 @@ static int wave2Cbs(unsigned mode)
|
|||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static void waveRxSerial(wfRx_t * s, int level, uint32_t tick)
|
||||
static void waveRxSerial(volatile wfRx_t *s, int level, uint32_t tick)
|
||||
{
|
||||
int diffTicks;
|
||||
int newWritePos;
|
||||
|
||||
if (s->bit >= 0)
|
||||
{
|
||||
|
@ -1680,9 +1699,15 @@ static void waveRxSerial(wfRx_t * s, int level, uint32_t tick)
|
|||
|
||||
if (s->bit == 9)
|
||||
{
|
||||
s->rxp->buf[s->rxp->writePos] = s->byte;
|
||||
s->buf[s->writePos] = s->byte;
|
||||
|
||||
if (++s->rxp->writePos >= s->rxp->bufSize) s->rxp->writePos = 0;
|
||||
/* don't let writePos catch readPos */
|
||||
|
||||
newWritePos = s->writePos;
|
||||
|
||||
if (++newWritePos >= s->bufSize) newWritePos = 0;
|
||||
|
||||
if (newWritePos != s->readPos) s->writePos = newWritePos;
|
||||
|
||||
if (level == 0) /* true transition high->low, not a timeout */
|
||||
{
|
||||
|
@ -1690,7 +1715,11 @@ static void waveRxSerial(wfRx_t * s, int level, uint32_t tick)
|
|||
s->startBitTick = tick;
|
||||
s->nextBitDiff = s->halfBit;
|
||||
}
|
||||
else s->bit = -1;
|
||||
else
|
||||
{
|
||||
s->bit = -1;
|
||||
gpioSetWatchdog(s->gpio, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1699,6 +1728,7 @@ static void waveRxSerial(wfRx_t * s, int level, uint32_t tick)
|
|||
|
||||
if (level == 0)
|
||||
{
|
||||
gpioSetWatchdog(s->gpio, s->timeout);
|
||||
s->level = 0;
|
||||
s->bit = 0;
|
||||
s->startBitTick = tick;
|
||||
|
@ -2621,10 +2651,12 @@ static void * pthTimerTick(void *x)
|
|||
|
||||
static void * pthFifoThread(void *x)
|
||||
{
|
||||
char inBuf[256];
|
||||
int idx, flags;
|
||||
char buf[CMD_BUF_SIZE];
|
||||
int idx, flags, len;
|
||||
cmdCmd_t cmd;
|
||||
gpioExtent_t ext[3];
|
||||
gpioExtent_t iExt[3];
|
||||
gpioExtent_t oExt[3];
|
||||
char *p;
|
||||
|
||||
myCreatePipe(PI_INPFIFO, 0662);
|
||||
|
||||
|
@ -2643,12 +2675,23 @@ static void * pthFifoThread(void *x)
|
|||
|
||||
while (1)
|
||||
{
|
||||
if (fgets(inBuf, sizeof(inBuf), inpFifo) == NULL)
|
||||
if (fgets(buf, sizeof(buf), inpFifo) == NULL)
|
||||
SOFT_ERROR((void*)PI_INIT_FAILED, "fifo fgets failed (%m)");
|
||||
|
||||
if ((idx=cmdParse(inBuf, &cmd, 0, NULL, ext)) >= 0)
|
||||
len = strlen(buf);
|
||||
|
||||
if (len)
|
||||
{
|
||||
myDoCommand(&cmd, NULL);
|
||||
--len;
|
||||
buf[len] = 0; /* replace terminating */
|
||||
}
|
||||
|
||||
if ((idx=cmdParse(buf, &cmd, 0, NULL, iExt)) >= 0)
|
||||
{
|
||||
oExt[0].ptr = buf;
|
||||
oExt[0].size = CMD_BUF_SIZE-1;
|
||||
|
||||
myDoCommand(&cmd, iExt, oExt);
|
||||
|
||||
switch (cmdInfo[idx].rv)
|
||||
{
|
||||
|
@ -2675,6 +2718,17 @@ static void * pthFifoThread(void *x)
|
|||
case 5:
|
||||
fprintf(outFifo, cmdUsage);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if (cmd.res < 0) fprintf(outFifo, "%d\n", cmd.res);
|
||||
else if (cmd.res > 0)
|
||||
{
|
||||
p = oExt[0].ptr;
|
||||
p[cmd.res] = 0;
|
||||
fprintf(outFifo, "%s", (char *)oExt[0].ptr);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2694,8 +2748,13 @@ static void *pthSocketThreadHandler(void *fdC)
|
|||
cmdCmd_t cmd;
|
||||
unsigned bytes;
|
||||
char *memPtr;
|
||||
gpioExtent_t ext[3];
|
||||
gpioExtent_t iExt[3];
|
||||
gpioExtent_t oExt[3];
|
||||
unsigned tmp;
|
||||
char buf[CMD_BUF_SIZE];
|
||||
|
||||
oExt[0].size = CMD_BUF_SIZE-1;
|
||||
oExt[0].ptr = buf;
|
||||
|
||||
free(fdC);
|
||||
|
||||
|
@ -2719,13 +2778,14 @@ static void *pthSocketThreadHandler(void *fdC)
|
|||
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);
|
||||
iExt[0].size = bytes;
|
||||
iExt[0].ptr = memPtr;
|
||||
myDoCommand(&cmd, iExt, oExt);
|
||||
free(memPtr);
|
||||
}
|
||||
else
|
||||
|
@ -2756,14 +2816,14 @@ static void *pthSocketThreadHandler(void *fdC)
|
|||
{
|
||||
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);
|
||||
iExt[0].size = sizeof(unsigned);
|
||||
iExt[0].ptr = memPtr;
|
||||
iExt[1].size = sizeof(unsigned);
|
||||
iExt[1].ptr = memPtr + sizeof(unsigned);
|
||||
iExt[2].size = cmd.p2;
|
||||
iExt[2].ptr = memPtr + sizeof(unsigned) + sizeof(unsigned);
|
||||
memPtr[bytes] = 0; /* may be duplicate terminator */
|
||||
myDoCommand(&cmd, ext);
|
||||
myDoCommand(&cmd, iExt, oExt);
|
||||
free(memPtr);
|
||||
}
|
||||
else
|
||||
|
@ -2787,24 +2847,24 @@ static void *pthSocketThreadHandler(void *fdC)
|
|||
bytes = cmd.p1;
|
||||
|
||||
memPtr = malloc(bytes+1); /* add 1 for a nul terminator */
|
||||
|
||||
if (memPtr)
|
||||
{
|
||||
if (recv(sock, memPtr, bytes, MSG_WAITALL) == bytes)
|
||||
if (bytes) /* script appended */
|
||||
{
|
||||
ext[0].n = bytes;
|
||||
ext[0].ptr = memPtr;
|
||||
memPtr[bytes] = 0; /* may be duplicate terminator */
|
||||
myDoCommand(&cmd, ext);
|
||||
free(memPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(memPtr);
|
||||
break;
|
||||
if (recv(sock, memPtr, bytes, MSG_WAITALL) != bytes)
|
||||
{
|
||||
free(memPtr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
iExt[0].size = bytes;
|
||||
iExt[0].ptr = memPtr;
|
||||
memPtr[bytes] = 0; /* may be duplicate terminator */
|
||||
myDoCommand(&cmd, iExt, oExt);
|
||||
free(memPtr);
|
||||
}
|
||||
else break;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2817,8 +2877,8 @@ static void *pthSocketThreadHandler(void *fdC)
|
|||
## extension ##
|
||||
unsigned level
|
||||
*/
|
||||
ext[0].n = 4;
|
||||
ext[0].ptr = &tmp;
|
||||
iExt[0].size = 4;
|
||||
iExt[0].ptr = &tmp;
|
||||
|
||||
if (recv(sock, &tmp, sizeof(unsigned), MSG_WAITALL) !=
|
||||
sizeof(unsigned))
|
||||
|
@ -2831,11 +2891,26 @@ static void *pthSocketThreadHandler(void *fdC)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
myDoCommand(&cmd, ext);
|
||||
myDoCommand(&cmd, iExt, oExt);
|
||||
}
|
||||
|
||||
write(sock, &cmd, sizeof(cmdCmd_t));
|
||||
|
||||
switch (cmd.cmd)
|
||||
{
|
||||
case PI_CMD_SLR: /* extension */
|
||||
|
||||
if (cmd.res > 0)
|
||||
{
|
||||
write(sock, oExt[0].ptr, cmd.res);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
@ -4347,6 +4422,9 @@ int gpioWaveAddSerial(unsigned gpio,
|
|||
DBG(DBG_USER, "gpio=%d baud=%d offset=%d numChar=%d str=%s",
|
||||
gpio, baud, offset, numChar, str);
|
||||
|
||||
DBG(DBG_USER, "l=%d s=%X e=%X",
|
||||
strlen(str), str[0], str[strlen(str)-1]);
|
||||
|
||||
CHECK_INITED;
|
||||
|
||||
if (gpio > PI_MAX_USER_GPIO)
|
||||
|
@ -4439,13 +4517,11 @@ int gpioWaveAddSerial(unsigned gpio,
|
|||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int gpioWaveSerialReadStart(unsigned gpio,
|
||||
unsigned baud,
|
||||
gpioRx_t *rxp)
|
||||
int gpioSerialReadOpen(unsigned gpio, unsigned baud)
|
||||
{
|
||||
int bitTime, timeoutMs;
|
||||
int bitTime, timeout;
|
||||
|
||||
DBG(DBG_USER, "gpio=%d baud=%d rxp*=%08X", gpio, baud, (uint32_t)rxp);
|
||||
DBG(DBG_USER, "gpio=%d baud=%d", gpio, baud);
|
||||
|
||||
CHECK_INITED;
|
||||
|
||||
|
@ -4456,37 +4532,75 @@ int gpioWaveSerialReadStart(unsigned gpio,
|
|||
SOFT_ERROR(PI_BAD_WAVE_BAUD,
|
||||
"gpio %d, bad baud rate (%d)", gpio, baud);
|
||||
|
||||
if (rxp == NULL)
|
||||
SOFT_ERROR(PI_BAD_SERIAL_STRUC, "Null structure pointer");
|
||||
|
||||
if (rxp->buf == NULL)
|
||||
SOFT_ERROR(PI_BAD_SERIAL_BUF, "Null buffer pointer");
|
||||
if (wfRx[gpio].mode != PI_WFRX_NONE)
|
||||
SOFT_ERROR(PI_GPIO_IN_USE, "gpio %d is already being used", gpio);
|
||||
|
||||
bitTime = MILLION / baud;
|
||||
|
||||
timeoutMs = ((12 * bitTime)+1000)/1000;
|
||||
timeout = (10 * bitTime)/1000;
|
||||
if (timeout < 1) timeout = 1;
|
||||
|
||||
wfRx[gpio].gpio = gpio;
|
||||
wfRx[gpio].buf = malloc(SRX_BUF_SIZE);
|
||||
wfRx[gpio].bufSize = SRX_BUF_SIZE;
|
||||
wfRx[gpio].mode = PI_WFRX_SERIAL;
|
||||
wfRx[gpio].baud = baud;
|
||||
wfRx[gpio].rxp = rxp;
|
||||
wfRx[gpio].baud = baud;
|
||||
wfRx[gpio].timeout = timeout;
|
||||
wfRx[gpio].fullBit = bitTime;
|
||||
wfRx[gpio].halfBit = bitTime/2;
|
||||
wfRx[gpio].rxp->readPos = 0;
|
||||
wfRx[gpio].rxp->writePos = 0;
|
||||
wfRx[gpio].readPos = 0;
|
||||
wfRx[gpio].writePos = 0;
|
||||
wfRx[gpio].bit = -1;
|
||||
|
||||
gpioSetWatchdog(gpio, timeoutMs); /* get a nudge if no change */
|
||||
|
||||
gpioSetAlertFunc(gpio, waveRxBit);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int gpioSerialRead(unsigned gpio, void *buf, size_t bufSize)
|
||||
{
|
||||
unsigned bytes=0, wpos;
|
||||
volatile wfRx_t *p;
|
||||
|
||||
DBG(DBG_USER, "gpio=%d buf=%08X bufSize=%d", gpio, (int)buf, bufSize);
|
||||
|
||||
CHECK_INITED;
|
||||
|
||||
if (gpio > PI_MAX_USER_GPIO)
|
||||
SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
|
||||
|
||||
if (bufSize == 0)
|
||||
SOFT_ERROR(PI_BAD_SERIAL_COUNT, "buffer size can't be zero");
|
||||
|
||||
if (wfRx[gpio].mode != PI_WFRX_SERIAL)
|
||||
SOFT_ERROR(PI_NOT_SERIAL_GPIO, "no serial read on gpio (%d)", gpio);
|
||||
|
||||
p = &wfRx[gpio];
|
||||
|
||||
if (p->readPos != p->writePos)
|
||||
{
|
||||
wpos = p->writePos;
|
||||
|
||||
if (wpos > p->readPos) bytes = wpos - p->readPos;
|
||||
else bytes = p->bufSize - p->readPos;
|
||||
|
||||
if (bytes > bufSize) bytes = bufSize;
|
||||
|
||||
memcpy(buf, p->buf+p->readPos, bytes);
|
||||
|
||||
p->readPos += bytes;
|
||||
|
||||
if (p->readPos >= p->bufSize) p->readPos = 0;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int gpioWaveSerialReadStop(unsigned gpio)
|
||||
int gpioSerialReadClose(unsigned gpio)
|
||||
{
|
||||
DBG(DBG_USER, "gpio=%d", gpio);
|
||||
|
||||
|
@ -4505,6 +4619,8 @@ int gpioWaveSerialReadStop(unsigned gpio)
|
|||
|
||||
case PI_WFRX_SERIAL:
|
||||
|
||||
free(wfRx[gpio].buf);
|
||||
|
||||
gpioSetWatchdog(gpio, 0); /* switch off timeouts */
|
||||
|
||||
gpioSetAlertFunc(gpio, NULL); /* cancel alert */
|
||||
|
@ -5067,6 +5183,8 @@ void gpioStopThread(pthread_t *pth)
|
|||
int gpioStoreScript(char *script)
|
||||
{
|
||||
DBG(DBG_USER, "script=%s", script);
|
||||
DBG(DBG_USER, "l=%d s=%X e=%X",
|
||||
strlen(script), script[0], script[strlen(script)-1]);
|
||||
|
||||
CHECK_INITED;
|
||||
|
||||
|
|
102
pigpio.h
102
pigpio.h
|
@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
|
|||
*/
|
||||
|
||||
/*
|
||||
This version is for pigpio version 11
|
||||
This version is for pigpio version 12
|
||||
*/
|
||||
|
||||
#ifndef PIGPIO_H
|
||||
|
@ -86,7 +86,7 @@ This version is for pigpio version 11
|
|||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define PIGPIO_VERSION 11
|
||||
#define PIGPIO_VERSION 12
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
|
@ -133,8 +133,9 @@ gpioWaveTxStart Transmits the waveform.
|
|||
gpioWaveTxBusy Checks to see if the waveform has ended.
|
||||
gpioWaveTxStop Aborts the current waveform.
|
||||
|
||||
gpioWaveSerialReadStart Reads serial data from a user gpio.
|
||||
gpioWaveSerialReadStop Stops reading serial data from a user gpio.
|
||||
gpioSerialReadOpen Opens a gpio for reading serial data.
|
||||
gpioSerialRead Reads serial data from a gpio.
|
||||
gpioSerialReadClose Closes a gpio for reading serial data.
|
||||
|
||||
gpioWaveGetMicros Length in microseconds of the current waveform.
|
||||
gpioWaveGetHighMicros Length of longest waveform so far.
|
||||
|
@ -226,7 +227,7 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
size_t n;
|
||||
size_t size;
|
||||
void *ptr;
|
||||
int data;
|
||||
} gpioExtent_t;
|
||||
|
@ -252,14 +253,6 @@ typedef struct
|
|||
uint32_t usDelay;
|
||||
} gpioPulse_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char * buf;
|
||||
uint32_t bufSize;
|
||||
int readPos;
|
||||
int writePos;
|
||||
} gpioRx_t;
|
||||
|
||||
typedef void (*gpioAlertFunc_t) (int gpio,
|
||||
int level,
|
||||
uint32_t tick);
|
||||
|
@ -974,76 +967,38 @@ int gpioWaveTxStop(void);
|
|||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int gpioWaveSerialReadStart(unsigned user_gpio,
|
||||
unsigned baud,
|
||||
gpioRx_t * rxp);
|
||||
int gpioSerialReadOpen(unsigned user_gpio, unsigned baud);
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/* This function starts the reception of serial data with the
|
||||
specified baud rate on a gpio.
|
||||
/* This function opens a gpio for reading serial data.
|
||||
|
||||
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_WAVE_BAUD,
|
||||
PI_BAD_SERIAL_STRUC, or PI_BAD_SERIAL_BUF.
|
||||
or PI_GPIO_IN_USE.
|
||||
|
||||
NOTES:
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char * buf;
|
||||
uint32_t bufSize;
|
||||
int readPos;
|
||||
int writePos;
|
||||
} gpioRx_t;
|
||||
|
||||
The serial data is returned in a cyclic buffer which MUST be allocated
|
||||
by the caller. The caller specifies the location and size of the
|
||||
buffer in buf and bufSize.
|
||||
The serial data is returned in a cyclic buffer and is read using
|
||||
gpioSerialRead().
|
||||
|
||||
It is the caller's responsibility to read data from the cyclic buffer
|
||||
in a timely fashion. Data is available when readPos is not equal to
|
||||
writePos.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
#define BUFSIZE 1000
|
||||
|
||||
char buf[BUFSIZE];
|
||||
int bytes, wpos;
|
||||
FILE * outFile;
|
||||
|
||||
gpioRx_t rx;
|
||||
|
||||
...
|
||||
|
||||
rx.buf = buf;
|
||||
rx.bufSize = sizeof(buf);
|
||||
|
||||
if (gpioWaveSerialReadStart(4, 38400, &rx) == 0)
|
||||
{
|
||||
...
|
||||
|
||||
while (rx.readPos != rx.writePos)
|
||||
{
|
||||
wpos = rx.writePos;
|
||||
|
||||
if (wpos > rx.readPos) bytes = wpos - rx.readPos;
|
||||
else bytes = rx.bufSize - rx.readPos;
|
||||
|
||||
fwrite(rx.buf+rx.readPos, 1, bytes, outFile);
|
||||
|
||||
rx.readPos += bytes;
|
||||
|
||||
if (rx.readPos >= rx.bufSize) rx.readPos = 0;
|
||||
}
|
||||
...
|
||||
}
|
||||
in a timely fashion.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int gpioWaveSerialReadStop(unsigned user_gpio);
|
||||
int gpioSerialRead(unsigned user_gpio, void *buf, size_t bufSize);
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/* This function stops reading serial data from a gpio.
|
||||
/* This function copies up to bufSize bytes of data read from the
|
||||
serial cyclic buffer to the buffer starting at buf.
|
||||
|
||||
Returns the number of bytes copied if OK, otherwise PI_BAD_USER_GPIO
|
||||
or PI_NOT_SERIAL_GPIO.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int gpioSerialReadClose(unsigned user_gpio);
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/* This function closes a gpio for reading serial data.
|
||||
|
||||
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_NOT_SERIAL_GPIO.
|
||||
*/
|
||||
|
@ -1901,6 +1856,9 @@ void gpioWaveDump(void);
|
|||
#define PI_CMD_PROCD 39
|
||||
#define PI_CMD_PROCR 40
|
||||
#define PI_CMD_PROCS 41
|
||||
#define PI_CMD_SLRO 42
|
||||
#define PI_CMD_SLR 43
|
||||
#define PI_CMD_SLRC 44
|
||||
|
||||
/*
|
||||
The following command only works on the socket interface.
|
||||
|
@ -1970,6 +1928,8 @@ after this command is issued.
|
|||
#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 */
|
||||
#define PI_GPIO_IN_USE -50 /* gpio already in use */
|
||||
#define PI_BAD_SERIAL_COUNT -51 /* must read at least a byte at a time */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
|
57
pigpio.py
57
pigpio.py
|
@ -76,7 +76,7 @@ import threading
|
|||
import os
|
||||
import atexit
|
||||
|
||||
VERSION = "1.2"
|
||||
VERSION = "1.3"
|
||||
|
||||
# gpio levels
|
||||
|
||||
|
@ -157,6 +157,9 @@ _PI_CMD_PROC= 38
|
|||
_PI_CMD_PROCD=39
|
||||
_PI_CMD_PROCR=40
|
||||
_PI_CMD_PROCS=41
|
||||
_PI_CMD_SLRO= 42
|
||||
_PI_CMD_SLR= 43
|
||||
_PI_CMD_SLRC= 44
|
||||
|
||||
|
||||
_PI_CMD_NOIB= 99
|
||||
|
@ -202,7 +205,7 @@ _PI_BAD_CFG_INTERNAL=-34
|
|||
PI_BAD_WAVE_BAUD =-35
|
||||
PI_TOO_MANY_PULSES =-36
|
||||
PI_TOO_MANY_CHARS =-37
|
||||
_PI_NOT_SERIAL_GPIO =-38
|
||||
PI_NOT_SERIAL_GPIO =-38
|
||||
_PI_BAD_SERIAL_STRUC=-39
|
||||
_PI_BAD_SERIAL_BUF =-40
|
||||
PI_NOT_PERMITTED =-41
|
||||
|
@ -214,6 +217,7 @@ PI_BAD_PULSELEN =-46
|
|||
PI_BAD_SCRIPT =-47
|
||||
PI_BAD_SCRIPT_ID =-48
|
||||
PI_BAD_SER_OFFSET =-49
|
||||
PI_GPIO_IN_USE =-50
|
||||
|
||||
# pigpio error text
|
||||
|
||||
|
@ -252,10 +256,10 @@ _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_NOT_SERIAL_GPIO , "no serial read in progress on gpio"],
|
||||
[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_BAD_WVSC_COMMND , "bad WVSC subcommand"],
|
||||
|
@ -265,6 +269,7 @@ _errors=[
|
|||
[PI_BAD_SCRIPT , "invalid script"],
|
||||
[PI_BAD_SCRIPT_ID , "unknown script id"],
|
||||
[PI_BAD_SER_OFFSET , "add serial data offset > 30 minute"],
|
||||
[PI_GPIO_IN_USE , "gpio already in use"],
|
||||
]
|
||||
|
||||
_control = None
|
||||
|
@ -1701,6 +1706,46 @@ def delete_script(script_id):
|
|||
"""
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_PROCD, script_id, 0))
|
||||
|
||||
def serial_read_open(user_gpio, baud):
|
||||
"""
|
||||
This function opens a gpio for reading serial data.
|
||||
|
||||
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_WAVE_BAUD,
|
||||
or PI_GPIO_IN_USE.
|
||||
|
||||
The serial data is held in a cyclic buffer and is read using
|
||||
gpioSerialRead().
|
||||
|
||||
It is the caller's responsibility to read data from the cyclic buffer
|
||||
in a timely fashion.
|
||||
"""
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_SLRO, user_gpio, baud))
|
||||
|
||||
def serial_read(user_gpio):
|
||||
"""
|
||||
This function returns data from the serial cyclic buffer.
|
||||
|
||||
It returns a tuple of status and string. The status will be the
|
||||
length, possibly 0, of the returned string if OK. Otherwise a
|
||||
negative error code will be returned in which case the string
|
||||
will be null.
|
||||
"""
|
||||
bytes = _u2i(_pigpio_command(_control, _PI_CMD_SLR, user_gpio, 10000))
|
||||
if bytes > 0:
|
||||
buf = ""
|
||||
while len(buf) < bytes: buf += _control.recv(bytes-len(buf))
|
||||
return bytes, buf
|
||||
return bytes, ""
|
||||
|
||||
|
||||
def serial_read_close(user_gpio):
|
||||
"""
|
||||
This function closes a gpio for reading serial data.
|
||||
|
||||
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_NOT_SERIAL_GPIO.
|
||||
"""
|
||||
return _u2i(_pigpio_command(_control, _PI_CMD_SLRC, user_gpio, 0))
|
||||
|
||||
|
||||
class callback:
|
||||
"""A class to provide gpio level change callbacks."""
|
||||
|
|
87
pigpiod_if.c
87
pigpiod_if.c
|
@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
|
|||
For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
/* PIGPIOD_IF_VERSION 2 */
|
||||
/* PIGPIOD_IF_VERSION 3 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -59,6 +59,7 @@ typedef void (*CBF_t) ();
|
|||
|
||||
struct callback_s
|
||||
{
|
||||
|
||||
int id;
|
||||
int gpio;
|
||||
int edge;
|
||||
|
@ -120,7 +121,7 @@ static int pigpio_command_ext
|
|||
|
||||
for (i=0; i<extents; i++)
|
||||
{
|
||||
if (send(fd, ext[i].ptr, ext[i].n, 0) != ext[i].n)
|
||||
if (send(fd, ext[i].ptr, ext[i].size, 0) != ext[i].size)
|
||||
return pigif_bad_send;
|
||||
}
|
||||
|
||||
|
@ -288,12 +289,12 @@ static void findNotifyBits(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void _wfe(int gpio, int level, uint32_t tick, void *user)
|
||||
static void _wfe(unsigned gpio, unsigned level, uint32_t tick, void *user)
|
||||
{
|
||||
*(int *)user = 1;
|
||||
}
|
||||
|
||||
static int intCallback(int gpio, int edge, void *f, void *user, int ex)
|
||||
static int intCallback(unsigned gpio, unsigned edge, void *f, void *user, int ex)
|
||||
{
|
||||
static int id = 0;
|
||||
callback_t *p;
|
||||
|
@ -524,55 +525,55 @@ void pigpio_stop(void)
|
|||
}
|
||||
}
|
||||
|
||||
int set_mode(int gpio, int mode)
|
||||
int set_mode(unsigned gpio, unsigned mode)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_MODES, gpio, mode);}
|
||||
|
||||
int get_mode(int gpio)
|
||||
int get_mode(unsigned gpio)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_MODEG, gpio, 0);}
|
||||
|
||||
int set_pull_up_down(int gpio, int pud)
|
||||
int set_pull_up_down(unsigned gpio, unsigned pud)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PUD, gpio, pud);}
|
||||
|
||||
int read_gpio(int gpio)
|
||||
int read_gpio(unsigned gpio)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_READ, gpio, 0);}
|
||||
|
||||
int write_gpio(int gpio, int level)
|
||||
int write_gpio(unsigned gpio, unsigned level)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_WRITE, gpio, level);}
|
||||
|
||||
int set_PWM_dutycycle(int user_gpio, int dutycycle)
|
||||
int set_PWM_dutycycle(unsigned user_gpio, unsigned dutycycle)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PWM, user_gpio, dutycycle);}
|
||||
|
||||
int set_PWM_range(int user_gpio, int range_)
|
||||
int set_PWM_range(unsigned user_gpio, unsigned range_)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PRS, user_gpio, range_);}
|
||||
|
||||
int get_PWM_range(int user_gpio)
|
||||
int get_PWM_range(unsigned user_gpio)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PRG, user_gpio, 0);}
|
||||
|
||||
int get_PWM_real_range(int user_gpio)
|
||||
int get_PWM_real_range(unsigned user_gpio)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PRRG, user_gpio, 0);}
|
||||
|
||||
int set_PWM_frequency(int user_gpio, int frequency)
|
||||
int set_PWM_frequency(unsigned user_gpio, unsigned frequency)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PFS, user_gpio, frequency);}
|
||||
|
||||
int get_PWM_frequency(int user_gpio)
|
||||
int get_PWM_frequency(unsigned user_gpio)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PFG, user_gpio, 0);}
|
||||
|
||||
int set_servo_pulsewidth(int user_gpio, int pulsewidth)
|
||||
int set_servo_pulsewidth(unsigned user_gpio, unsigned pulsewidth)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_SERVO, user_gpio, pulsewidth);}
|
||||
|
||||
int notify_open(void)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_NO, 0, 0);}
|
||||
|
||||
int notify_begin(int handle, uint32_t bits)
|
||||
int notify_begin(unsigned handle, uint32_t bits)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_NB, handle, bits);}
|
||||
|
||||
int notify_pause(int handle)
|
||||
int notify_pause(unsigned handle)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_NB, handle, 0);}
|
||||
|
||||
int notify_close(int handle)
|
||||
int notify_close(unsigned handle)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_NC, handle, 0);}
|
||||
|
||||
int set_watchdog(int user_gpio, int timeout)
|
||||
int set_watchdog(unsigned user_gpio, unsigned timeout)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_WDOG, user_gpio, timeout);}
|
||||
|
||||
uint32_t read_bank_1(void)
|
||||
|
@ -616,7 +617,7 @@ int wave_add_generic(unsigned numPulses, gpioPulse_t *pulses)
|
|||
gpioPulse_t[] pulses
|
||||
*/
|
||||
|
||||
ext[0].n = numPulses * sizeof(gpioPulse_t);
|
||||
ext[0].size = numPulses * sizeof(gpioPulse_t);
|
||||
ext[0].ptr = pulses;
|
||||
|
||||
return pigpio_command_ext(gPigCommand, PI_CMD_WVAG, numPulses, 0, 1, ext);
|
||||
|
@ -636,13 +637,13 @@ int wave_add_serial(
|
|||
char[] str
|
||||
*/
|
||||
|
||||
ext[0].n = sizeof(unsigned);
|
||||
ext[0].size = sizeof(unsigned);
|
||||
ext[0].ptr = &baud;
|
||||
|
||||
ext[1].n = sizeof(unsigned);
|
||||
ext[1].size = sizeof(unsigned);
|
||||
ext[1].ptr = &offset;
|
||||
|
||||
ext[2].n = numChar;
|
||||
ext[2].size = numChar;
|
||||
ext[2].ptr = str;
|
||||
|
||||
return pigpio_command_ext(gPigCommand, PI_CMD_WVAS, gpio, numChar, 3, ext);
|
||||
|
@ -698,7 +699,7 @@ int gpio_trigger(unsigned gpio, unsigned pulseLen, unsigned level)
|
|||
unsigned level
|
||||
*/
|
||||
|
||||
ext[0].n = sizeof(level);
|
||||
ext[0].size = sizeof(level);
|
||||
ext[0].ptr = &level;
|
||||
|
||||
return pigpio_command_ext(gPigCommand, PI_CMD_TRIG, gpio, pulseLen, 1, ext);
|
||||
|
@ -718,28 +719,48 @@ int store_script(char *script)
|
|||
|
||||
len = strlen(script);
|
||||
|
||||
ext[0].n = len;
|
||||
ext[0].size = len;
|
||||
ext[0].ptr = script;
|
||||
|
||||
return pigpio_command_ext(gPigCommand, PI_CMD_PROC, len, 0, 1, ext);
|
||||
}
|
||||
|
||||
int run_script(int script_id)
|
||||
int run_script(unsigned script_id)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PROCR, script_id, 0);}
|
||||
|
||||
int stop_script(int script_id)
|
||||
int stop_script(unsigned script_id)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PROCS, script_id, 0);}
|
||||
|
||||
int delete_script(int script_id)
|
||||
int delete_script(unsigned script_id)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_PROCD, script_id, 0);}
|
||||
|
||||
int callback(int gpio, int edge, CBFunc_t f)
|
||||
int serial_read_open(unsigned gpio, unsigned baud)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_SLRO, gpio, baud);}
|
||||
|
||||
int serial_read(unsigned gpio, void *buf, size_t bufSize)
|
||||
{
|
||||
int bytes;
|
||||
|
||||
bytes = pigpio_command(gPigCommand, PI_CMD_SLR, gpio, bufSize);
|
||||
|
||||
if (bytes > 0)
|
||||
{
|
||||
/* get the data */
|
||||
recv(gPigCommand, buf, bytes, MSG_WAITALL);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
int serial_read_close(unsigned gpio)
|
||||
{return pigpio_command(gPigCommand, PI_CMD_SLRC, gpio, 0);}
|
||||
|
||||
int callback(unsigned gpio, unsigned edge, CBFunc_t f)
|
||||
{return intCallback(gpio, edge, f, 0, 0);}
|
||||
|
||||
int callback_ex(int gpio, int edge, CBFuncEx_t f, void *user)
|
||||
int callback_ex(unsigned gpio, unsigned edge, CBFuncEx_t f, void *user)
|
||||
{return intCallback(gpio, edge, f, user, 1);}
|
||||
|
||||
int callback_cancel(int id)
|
||||
int callback_cancel(unsigned id)
|
||||
{
|
||||
callback_t *p;
|
||||
|
||||
|
@ -766,7 +787,7 @@ int callback_cancel(int id)
|
|||
return pigif_callback_not_found;
|
||||
}
|
||||
|
||||
int wait_for_edge(int gpio, int edge, double timeout)
|
||||
int wait_for_edge(unsigned gpio, unsigned edge, double timeout)
|
||||
{
|
||||
int triggered = 0;
|
||||
int id;
|
||||
|
|
82
pigpiod_if.h
82
pigpiod_if.h
|
@ -30,7 +30,7 @@ For more information, please refer to <http://unlicense.org/>
|
|||
|
||||
#include "pigpio.h"
|
||||
|
||||
#define PIGPIOD_IF_VERSION 2
|
||||
#define PIGPIOD_IF_VERSION 3
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -45,12 +45,13 @@ typedef enum
|
|||
pigif_bad_callback = -2008,
|
||||
pigif_notify_failed = -2009,
|
||||
pigif_callback_not_found = -2010,
|
||||
} piscopeError_t;
|
||||
} pigifError_t;
|
||||
|
||||
|
||||
typedef void (*CBFunc_t) (int gpio, int level, uint32_t tick);
|
||||
typedef void (*CBFunc_t) (unsigned gpio, unsigned level, uint32_t tick);
|
||||
|
||||
typedef void (*CBFuncEx_t)(int gpio, int level, uint32_t tick, void * user);
|
||||
typedef void (*CBFuncEx_t)
|
||||
(unsigned gpio, unsigned level, uint32_t tick, void * user);
|
||||
|
||||
typedef struct callback_s callback_t;
|
||||
|
||||
|
@ -110,7 +111,7 @@ void pigpio_stop(void);
|
|||
resources used by the library.
|
||||
*/
|
||||
|
||||
int set_mode(int gpio, int mode);
|
||||
int set_mode(unsigned gpio, unsigned mode);
|
||||
/* Set the gpio mode.
|
||||
|
||||
gpio: 0-53.
|
||||
|
@ -120,7 +121,7 @@ int set_mode(int gpio, int mode);
|
|||
or PI_NOT_PERMITTED.
|
||||
*/
|
||||
|
||||
int get_mode(int gpio);
|
||||
int get_mode(unsigned gpio);
|
||||
/* Get the gpio mode.
|
||||
|
||||
Returns the gpio mode if OK, otherwise PI_BAD_GPIO.
|
||||
|
@ -128,7 +129,7 @@ int get_mode(int gpio);
|
|||
gpio: 0-53.
|
||||
*/
|
||||
|
||||
int set_pull_up_down(int gpio, int pud);
|
||||
int set_pull_up_down(unsigned gpio, unsigned pud);
|
||||
/* Set or clear the gpio pull-up/down resistor.
|
||||
|
||||
Returns 0 if OK, otherwise PI_BAD_GPIO, PI_BAD_PUD,
|
||||
|
@ -138,7 +139,7 @@ int set_pull_up_down(int gpio, int pud);
|
|||
pud: PUD_UP, PUD_DOWN, PUD_OFF.
|
||||
*/
|
||||
|
||||
int read_gpio(int gpio);
|
||||
int read_gpio(unsigned gpio);
|
||||
/* Read the gpio level.
|
||||
|
||||
Returns the gpio level if OK, otherwise PI_BAD_GPIO.
|
||||
|
@ -146,7 +147,7 @@ int read_gpio(int gpio);
|
|||
gpio:0-53.
|
||||
*/
|
||||
|
||||
int write_gpio(int gpio, int level);
|
||||
int write_gpio(unsigned gpio, unsigned level);
|
||||
/*
|
||||
Write the gpio level.
|
||||
|
||||
|
@ -161,7 +162,7 @@ int write_gpio(int gpio, int level);
|
|||
If PWM or servo pulses are active on the gpio they are switched off.
|
||||
*/
|
||||
|
||||
int set_PWM_dutycycle(int user_gpio, int dutycycle);
|
||||
int set_PWM_dutycycle(unsigned user_gpio, unsigned dutycycle);
|
||||
/* Start (non-zero dutycycle) or stop (0) PWM pulses on the gpio.
|
||||
|
||||
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_DUTYCYCLE,
|
||||
|
@ -175,7 +176,7 @@ int set_PWM_dutycycle(int user_gpio, int dutycycle);
|
|||
The set_PWM_range() function can change the default range of 255.
|
||||
*/
|
||||
|
||||
int set_PWM_range(int user_gpio, int range_);
|
||||
int set_PWM_range(unsigned user_gpio, unsigned range_);
|
||||
/* Set the range of PWM values to be used on the gpio.
|
||||
|
||||
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_DUTYRANGE,
|
||||
|
@ -200,7 +201,7 @@ int set_PWM_range(int user_gpio, int range_);
|
|||
(dutycycle * real range) / range.
|
||||
*/
|
||||
|
||||
int get_PWM_range(int user_gpio);
|
||||
int get_PWM_range(unsigned user_gpio);
|
||||
/* Get the range of PWM values being used on the gpio.
|
||||
|
||||
Returns the dutycycle range used for the gpio if OK,
|
||||
|
@ -209,7 +210,7 @@ int get_PWM_range(int user_gpio);
|
|||
user_gpio: 0-31.
|
||||
*/
|
||||
|
||||
int get_PWM_real_range(int user_gpio);
|
||||
int get_PWM_real_range(unsigned user_gpio);
|
||||
/* Get the real underlying range of PWM values being used on the gpio.
|
||||
|
||||
Returns the real range used for the gpio if OK,
|
||||
|
@ -218,7 +219,7 @@ int get_PWM_real_range(int user_gpio);
|
|||
user_gpio: 0-31.
|
||||
*/
|
||||
|
||||
int set_PWM_frequency(int user_gpio, int frequency);
|
||||
int set_PWM_frequency(unsigned user_gpio, unsigned frequency);
|
||||
/*
|
||||
Set the frequency (in Hz) of the PWM to be used on the gpio.
|
||||
|
||||
|
@ -257,7 +258,7 @@ int set_PWM_frequency(int user_gpio, int frequency);
|
|||
125, 100, 80, 50, 40, 25, 20, 10, 5
|
||||
*/
|
||||
|
||||
int get_PWM_frequency(int user_gpio);
|
||||
int get_PWM_frequency(unsigned user_gpio);
|
||||
/*
|
||||
Get the frequency of PWM being used on the gpio.
|
||||
|
||||
|
@ -267,7 +268,7 @@ int get_PWM_frequency(int user_gpio);
|
|||
user_gpio: 0-31.
|
||||
*/
|
||||
|
||||
int set_servo_pulsewidth(int user_gpio, int pulsewidth);
|
||||
int set_servo_pulsewidth(unsigned user_gpio, unsigned pulsewidth);
|
||||
/*
|
||||
Start (500-2500) or stop (0) servo pulses on the gpio.
|
||||
|
||||
|
@ -330,7 +331,7 @@ int notify_open(void);
|
|||
read from /dev/pigpio15.
|
||||
*/
|
||||
|
||||
int notify_begin(int handle, uint32_t bits);
|
||||
int notify_begin(unsigned handle, uint32_t bits);
|
||||
/*
|
||||
Start notifications on a previously opened handle.
|
||||
|
||||
|
@ -352,7 +353,7 @@ int notify_begin(int handle, uint32_t bits);
|
|||
I (32 bit) level
|
||||
*/
|
||||
|
||||
int notify_pause(int handle);
|
||||
int notify_pause(unsigned handle);
|
||||
/*
|
||||
Pause notifications on a previously opened handle.
|
||||
|
||||
|
@ -364,7 +365,7 @@ int notify_pause(int handle);
|
|||
notify_begin() is called again.
|
||||
*/
|
||||
|
||||
int notify_close(int handle);
|
||||
int notify_close(unsigned handle);
|
||||
/*
|
||||
Stop notifications on a previously opened handle and
|
||||
release the handle for reuse.
|
||||
|
@ -374,7 +375,7 @@ int notify_close(int handle);
|
|||
handle: 0-31 (as returned by notify_open())
|
||||
*/
|
||||
|
||||
int set_watchdog(int user_gpio, int timeout);
|
||||
int set_watchdog(unsigned user_gpio, unsigned timeout);
|
||||
/*
|
||||
Sets a watchdog for a gpio.
|
||||
|
||||
|
@ -658,25 +659,52 @@ int store_script(char *script);
|
|||
otherwise PI_BAD_SCRIPT.
|
||||
*/
|
||||
|
||||
int run_script(int script_id);
|
||||
int run_script(unsigned 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);
|
||||
int stop_script(unsigned 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);
|
||||
int delete_script(unsigned 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);
|
||||
int serial_read_open(unsigned user_gpio, unsigned baud);
|
||||
/* This function opens a gpio for reading serial data.
|
||||
|
||||
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_WAVE_BAUD,
|
||||
or PI_GPIO_IN_USE.
|
||||
|
||||
The serial data is returned in a cyclic buffer and is read using
|
||||
gpioSerialRead().
|
||||
|
||||
It is the caller's responsibility to read data from the cyclic buffer
|
||||
in a timely fashion.
|
||||
*/
|
||||
|
||||
int serial_read(unsigned user_gpio, void *buf, size_t bufSize);
|
||||
/* This function copies up to bufSize bytes of data read from the
|
||||
serial cyclic buffer to the buffer starting at buf.
|
||||
|
||||
Returns the number of bytes copied if OK, otherwise PI_BAD_USER_GPIO
|
||||
or PI_NOT_SERIAL_GPIO.
|
||||
*/
|
||||
|
||||
int serial_read_close(unsigned user_gpio);
|
||||
/* This function closes a gpio for reading serial data.
|
||||
|
||||
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_NOT_SERIAL_GPIO.
|
||||
*/
|
||||
|
||||
int callback(unsigned gpio, unsigned edge, CBFunc_t f);
|
||||
/*
|
||||
This function initialises a new callback.
|
||||
|
||||
|
@ -687,7 +715,7 @@ int callback(int gpio, int edge, CBFunc_t f);
|
|||
gpio has the identified edge.
|
||||
*/
|
||||
|
||||
int callback_ex(int gpio, int edge, CBFuncEx_t f, void *user);
|
||||
int callback_ex(unsigned gpio, unsigned edge, CBFuncEx_t f, void *user);
|
||||
/*
|
||||
This function initialises a new callback.
|
||||
|
||||
|
@ -698,14 +726,14 @@ int callback_ex(int gpio, int edge, CBFuncEx_t f, void *user);
|
|||
the gpio has the identified edge.
|
||||
*/
|
||||
|
||||
int callback_cancel(int id);
|
||||
int callback_cancel(unsigned 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);
|
||||
int wait_for_edge(unsigned gpio, unsigned edge, double timeout);
|
||||
/*
|
||||
This function waits for edge on the gpio for up to timeout
|
||||
seconds.
|
||||
|
|
18
pigs.c
18
pigs.c
|
@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
|
|||
*/
|
||||
|
||||
/*
|
||||
This version is for pigpio version 11+
|
||||
This version is for pigpio version 12+
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -153,10 +153,11 @@ int main(int argc , char *argv[])
|
|||
|
||||
for (i=0; i<cmdInfo[idx].ext; i++)
|
||||
{
|
||||
send(sock, ext[i].ptr, ext[i].n, 0);
|
||||
send(sock, ext[i].ptr, ext[i].size, 0);
|
||||
}
|
||||
|
||||
if (recv(sock, &cmd, sizeof(cmdCmd_t), 0) == sizeof(cmdCmd_t))
|
||||
if (recv(sock, &cmd, sizeof(cmdCmd_t), MSG_WAITALL) ==
|
||||
sizeof(cmdCmd_t))
|
||||
{
|
||||
switch (cmdInfo[idx].rv)
|
||||
{
|
||||
|
@ -187,6 +188,17 @@ int main(int argc , char *argv[])
|
|||
case 5:
|
||||
printf(cmdUsage);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
r = cmd.res;
|
||||
if (r < 0) fatal("ERROR: %s", cmdErrStr(r));
|
||||
else if (r > 0)
|
||||
{
|
||||
recv(sock, &buf, r, MSG_WAITALL);
|
||||
buf[r] = 0;
|
||||
printf("%s", buf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else fatal("recv failed, %m");
|
||||
|
|
Loading…
Reference in New Issue