This commit is contained in:
joan 2014-01-28 23:07:05 +00:00
parent 23e3b179ab
commit 8794220811
9 changed files with 535 additions and 322 deletions

View File

@ -5,9 +5,9 @@ SIZE = size
CFLAGS = -O3 -Wall 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 pigs: command.o pigs.o
$(CC) -o pigs pigs.c command.c $(CC) -o pigs pigs.c command.c

189
command.c
View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/ */
/* /*
This version is for pigpio version 11+ This version is for pigpio version 12+
*/ */
#include <stdio.h> #include <stdio.h>
@ -46,6 +46,7 @@ This version is for pigpio version 11+
3 %08X %08X 3 %08X %08X
4 %u %u 4 %u %u
5 HELP HELP 5 HELP HELP
6 %s <0 ERR
*/ */
/* vfyt /* vfyt
@ -58,6 +59,7 @@ This version is for pigpio version 11+
8 MODES %d %c 8 MODES %d %c
9 PUD %d %c 9 PUD %d %c
10 PROG %s 10 PROG %s
11 WVAS %d %d %d %s
*/ */
cmdInfo_t cmdInfo[]= cmdInfo_t cmdInfo[]=
@ -98,6 +100,9 @@ cmdInfo_t cmdInfo[]=
{PI_CMD_READ, "READ", 2, 2, 0}, {PI_CMD_READ, "READ", 2, 2, 0},
{PI_CMD_SERVO, "S", 3, 0, 0}, {PI_CMD_SERVO, "S", 3, 0, 0},
{PI_CMD_SERVO, "SERVO", 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_WDOG, "WDOG", 3, 0, 0},
{PI_CMD_WRITE, "W", 3, 0, 0}, {PI_CMD_WRITE, "W", 3, 0, 0},
{PI_CMD_WRITE, "WRITE", 3, 0, 0}, {PI_CMD_WRITE, "WRITE", 3, 0, 0},
@ -116,68 +121,72 @@ cmdInfo_t cmdInfo[]=
}; };
char * cmdUsage = "\ char * cmdUsage = "\
BC1 x clear gpios in bank 1\n\ BC1 x Clear gpios x in bank 1.\n\
BC2 x clear gpios in bank 2\n\ BC2 x Clear gpios x in bank 2.\n\
BR1 read gpios bank 1\n\ BR1 Read gpios bank 1.\n\
BR2 read gpios bank 2\n\ BR2 Read gpios bank 2.\n\
BS1 x set gpios in bank 1\n\ BS1 x Set gpios x in bank 1.\n\
BS2 x set gpios in bank 2\n\ BS2 x Set gpios x in bank 2.\n\
H displays command help\n\ H Displays command help.\n\
HELP displays command help\n\ HELP Displays command help.\n\
HWVER return hardware version\n\ HWVER Return hardware version.\n\
M g m set gpio mode\n\ M g m Set gpio g to mode m.\n\
MG g get gpio mode\n\ MG g Get gpio g mode.\n\
MODEG g get gpio mode\n\ MODEG g Get gpio g mode.\n\
MODES g m set gpio mode\n\ MODES g m Set gpio g to mode m.\n\
NB h x start notification\n\ NB h x Start notifications on handle h with x.\n\
NC h close notification\n\ NC h Close notification handle h.\n\
NO request notification handle\n\ NO Request notification handle.\n\
NP h pause notification\n\ NP h Pause notifications on handle h.\n\
P u d set PWM value for gpio\n\ P u d Set PWM value for user gpio u to d.\n\
PFG u get PWM frequency for gpio\n\ PFG u Get PWM frequency for user gpio u.\n\
PFS u d set PWM frequency for gpio\n\ PFS u d Set PWM frequency for user gpio u to d.\n\
PIGPV return pigpio version\n\ PIGPV Return pigpio version.\n\
PRG u get PWM range for gpio\n\ PRG u Get PWM range for user gpio u.\n\
PROC t validate and store script\n\ PROC t Store text t of script.\n\
PROCD s delete script\n\ PROCD s Delete script s.\n\
PROCR s run script\n\ PROCR s Run script s.\n\
PROCS s stop script\n\ PROCS s Stop script s.\n\
PRRG u get PWM real range for gpio\n\ PRRG u Get PWM real range for user gpio u.\n\
PRS u d set PWM range for gpio\n\ PRS u d Set PWM range for user gpio u to d.\n\
PUD g p set gpio pull up/down\n\ PUD g p Set gpio pull up/down for gpio g to p.\n\
PWM u d set PWM value for gpio\n\ PWM u d Set PWM value for user gpio u to d.\n\
R g read gpio\n\ R g Read gpio g.\n\
READ g read gpio\n\ READ g Read gpio g.\n\
S u d set servo value for gpio\n\ S u d Set servo value for user gpio u to d microseconds.\n\
SERVO u d set servo value for gpio\n\ SERVO u d Set servo value for user gpio u to d microseconds.\n\
T return current tick\n\ SLR u d Read up to d bytes of serial data from user gpio u.\n\
TICK return current tick\n\ SLRC u Close user gpio u for serial data.\n\
TRIG u pl l trigger level l for pl micros on gpio\n\ SLRO u b Open user gpio u for serial data at b baud.\n\
W g l write level to gpio\n\ T Return current tick.\n\
WDOG u d set watchdog on gpio\n\ TICK Return current tick.\n\
WRITE g l write level to gpio\n\ TRIG u pl L Trigger level L for pl micros on user gpio u.\n\
WVAS u b t wave add serial data\n\ W g L Write level L to gpio g.\n\
WVBSY check if wave busy\n\ WDOG u d Set watchdog of d milliseconds on user gpio u.\n\
WVCLR wave clear\n\ WRITE g L Write level L to gpio g.\n\
WVGO wave transmit\n\ WVAS u b o t Wave add serial data t to user gpio u at b baud.\n\
WVGOR wave transmit repeat\n\ WVBSY Check if wave busy.\n\
WVHLT wave stop\n\ WVCLR Wave clear.\n\
WVSC ws wave get cbs stats\n\ WVGO Wave transmit.\n\
WVSM ws wave get micros stats\n\ WVGOR Wave transmit repeatedly.\n\
WVSP ws wave get pulses stats\n\ WVHLT Wave stop.\n\
\n\ WVSC ws Wave get DMA control block stats.\n\
b = baud rate\n\ WVSM ws Wave get micros stats.\n\
d = decimal value\n\ WVSP ws Wave get pulses stats.\n\
g = gpio (0-53)\n\ .\n\
h = handle (0-31)\n\ b = baud rate.\n\
l = level (0-1)\n\ d = decimal value.\n\
m = mode (RW540123)\n\ g = gpio (0-53).\n\
p = pud (ODU)\n\ h = handle (0-31).\n\
pl = pulse length (0-100)\n\ L = level (0-1).\n\
s = script id\n\ m = mode (RW540123).\n\
t = text\n\ o = offset (0-).\n\
u = user gpio (0-31)\n\ p = pud (ODU).\n\
x = hex value\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 typedef struct
@ -237,6 +246,8 @@ static errInfo_t errInfo[]=
{PI_BAD_SCRIPT , "invalid script"}, {PI_BAD_SCRIPT , "invalid script"},
{PI_BAD_SCRIPT_ID , "unknown script id"}, {PI_BAD_SCRIPT_ID , "unknown script id"},
{PI_BAD_SER_OFFSET , "add serial data offset > 30 minute"}, {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"; 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) int cmdParse(char *buf, cmdCmd_t *cmd, int argc, char *argv[], gpioExtent_t *ext)
{ {
char str[8]; char str[8];
int f, valid, idx, val; int f, valid, idx, val, p;
char *ptr; char *ptr;
char c, t; 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) switch (cmdInfo[idx].vt)
{ {
case 1: /* BR1 BR2 HWVER NO PIGPV TICK WVBSY WVCLR WVGO WVGOR case 1: /* BR1 BR2 HWVER NO PIGPV TICK WVBSY WVCLR WVGO
WVHLT WVGOR WVHLT
*/ */
f = sscanf(buf, " %7s %c", str, &t); f = sscanf(buf, " %7s %c", str, &t);
if (f == 1) valid = 1; if (f == 1) valid = 1;
break; break;
case 2: /* MODEG NC NP PFG PRG PROCD PROCR PROCS PRRG READ case 2: /* MODEG NC NP PFG PRG PROCD PROCR PROCS PRRG
WVSC WVSM WVSP SLRC READ WVSC WVSM WVSP
*/ */
f = sscanf(buf, " %7s %d %c", str, &cmd->p1, &t); f = sscanf(buf, " %7s %d %c", str, &cmd->p1, &t);
if (f == 2) valid = 1; if (f == 2) valid = 1;
break; 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); f = sscanf(buf, " %7s %d %d %c", str, &cmd->p1, &cmd->p2, &t);
if (f == 3) valid = 1; 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); str, &cmd->p1, &cmd->p2, &ext[0].data, &t);
if (f == 4) if (f == 4)
{ {
ext[0].n = sizeof(unsigned); ext[0].size = sizeof(unsigned);
ext[0].ptr = &ext[0].data; ext[0].ptr = &ext[0].data;
valid = 1; valid = 1;
} }
@ -359,38 +370,56 @@ int cmdParse(char *buf, cmdCmd_t *cmd, int argc, char *argv[], gpioExtent_t *ext
case 10: /* PROC case 10: /* PROC
*/ */
if ((argc == 0) || (argc == 3))
{
if (argc == 3) if (argc == 3)
{ {
cmd->p1 = strlen(argv[2]); cmd->p1 = strlen(argv[2]);
ext[0].n = cmd->p1;
ext[0].ptr = 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; valid = 1;
} }
break; break;
case 11: /* WVAS case 11: /* WVAS
*/ */
if (argc == 6) if ((argc == 0) || (argc == 6))
{ {
f = sscanf(buf, " %7s %d %d %d ", f = sscanf(buf, " %*s %d %d %d %n",
str, &cmd->p1, &ext[0].data, &ext[1].data); &cmd->p1, &ext[0].data, &ext[1].data, &p);
if (f == 4) if (f == 3)
{ {
ext[0].n = sizeof(unsigned); ext[0].size = sizeof(unsigned);
ext[0].ptr = &ext[0].data; ext[0].ptr = &ext[0].data;
ext[1].n = sizeof(unsigned); ext[1].size = sizeof(unsigned);
ext[1].ptr = &ext[1].data; ext[1].ptr = &ext[1].data;
if (argc) /* pigs */
{
cmd->p2 = strlen(argv[5]); cmd->p2 = strlen(argv[5]);
ext[2].n = cmd->p2;
ext[2].ptr = 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; valid = 1;
} }
} }
break; break;
} }
if (valid) return idx; if (valid) return idx; else return -1;
else return -1;
} }
char * cmdErrStr(int error) char * cmdErrStr(int error)

280
pigpio.c
View File

@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/> For more information, please refer to <http://unlicense.org/>
*/ */
/* pigpio version 11 */ /* pigpio version 12 */
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -557,6 +557,9 @@ bit 0 READ_LAST_NOT_SET_ERROR
#define MAX_EMITS (PIPE_BUF / sizeof(gpioReport_t)) #define MAX_EMITS (PIPE_BUF / sizeof(gpioReport_t))
#define SRX_BUF_SIZE 8192
#define CMD_BUF_SIZE 2048
/* --------------------------------------------------------------- */ /* --------------------------------------------------------------- */
typedef void (*callbk_t) (); typedef void (*callbk_t) ();
@ -701,10 +704,15 @@ typedef struct
typedef struct typedef struct
{ {
gpioRx_t * rxp; int gpio;
char * buf;
uint32_t bufSize;
int readPos;
int writePos;
uint32_t baud; uint32_t baud;
uint32_t fullBit; uint32_t fullBit;
uint32_t halfBit; uint32_t halfBit;
int timeout;
uint32_t startBitTick; uint32_t startBitTick;
uint32_t nextBitDiff; uint32_t nextBitDiff;
int bit; int bit;
@ -757,7 +765,7 @@ static wfStats_t wfStats=
0, 0, (PAGES_PER_BLOCK * CBS_PER_OPAGE) 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 alertBits = 0;
static volatile uint32_t monitorBits = 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; int p1, p2, res, i;
uint32_t mask, tmp; 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_PRG: res = gpioGetPWMrange(p1); break;
case PI_CMD_PROC: case PI_CMD_PROC:
res = gpioStoreScript(ext[0].ptr); res = gpioStoreScript(iExt[0].ptr);
break; break;
case PI_CMD_PROCD: res = gpioDeleteScript(p1); 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_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_WDOG: res = gpioSetWatchdog(p1, p2); break;
case PI_CMD_WRITE: case PI_CMD_WRITE:
@ -1143,33 +1182,12 @@ static void myDoCommand(cmdCmd_t *cmd, gpioExtent_t *ext)
} }
break; 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: case PI_CMD_WVAG:
/* need to mask off any non permitted gpios */ /* need to mask off any non permitted gpios */
mask = gpioMask; mask = gpioMask;
pulse = ext[0].ptr; pulse = iExt[0].ptr;
masked = 0; masked = 0;
for (i=0; i<p1; i++) 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)) if (gpioMask & (uint64_t)(1<<p1))
res = gpioWaveAddSerial res = gpioWaveAddSerial
(p1, (p1,
*(int *)(ext[0].ptr), *(int *)(iExt[0].ptr),
*(int *)(ext[1].ptr), *(int *)(iExt[1].ptr),
p2, p2,
ext[2].ptr); iExt[2].ptr);
else else
{ {
PERM_ERROR 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 diffTicks;
int newWritePos;
if (s->bit >= 0) if (s->bit >= 0)
{ {
@ -1680,9 +1699,15 @@ static void waveRxSerial(wfRx_t * s, int level, uint32_t tick)
if (s->bit == 9) 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 */ 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->startBitTick = tick;
s->nextBitDiff = s->halfBit; s->nextBitDiff = s->halfBit;
} }
else s->bit = -1; else
{
s->bit = -1;
gpioSetWatchdog(s->gpio, 0);
}
} }
} }
else else
@ -1699,6 +1728,7 @@ static void waveRxSerial(wfRx_t * s, int level, uint32_t tick)
if (level == 0) if (level == 0)
{ {
gpioSetWatchdog(s->gpio, s->timeout);
s->level = 0; s->level = 0;
s->bit = 0; s->bit = 0;
s->startBitTick = tick; s->startBitTick = tick;
@ -2621,10 +2651,12 @@ static void * pthTimerTick(void *x)
static void * pthFifoThread(void *x) static void * pthFifoThread(void *x)
{ {
char inBuf[256]; char buf[CMD_BUF_SIZE];
int idx, flags; int idx, flags, len;
cmdCmd_t cmd; cmdCmd_t cmd;
gpioExtent_t ext[3]; gpioExtent_t iExt[3];
gpioExtent_t oExt[3];
char *p;
myCreatePipe(PI_INPFIFO, 0662); myCreatePipe(PI_INPFIFO, 0662);
@ -2643,12 +2675,23 @@ static void * pthFifoThread(void *x)
while (1) 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)"); 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) switch (cmdInfo[idx].rv)
{ {
@ -2675,6 +2718,17 @@ static void * pthFifoThread(void *x)
case 5: case 5:
fprintf(outFifo, cmdUsage); fprintf(outFifo, cmdUsage);
break; 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; cmdCmd_t cmd;
unsigned bytes; unsigned bytes;
char *memPtr; char *memPtr;
gpioExtent_t ext[3]; gpioExtent_t iExt[3];
gpioExtent_t oExt[3];
unsigned tmp; unsigned tmp;
char buf[CMD_BUF_SIZE];
oExt[0].size = CMD_BUF_SIZE-1;
oExt[0].ptr = buf;
free(fdC); free(fdC);
@ -2719,13 +2778,14 @@ static void *pthSocketThreadHandler(void *fdC)
bytes = cmd.p1 * sizeof(gpioPulse_t); bytes = cmd.p1 * sizeof(gpioPulse_t);
memPtr = malloc(bytes); memPtr = malloc(bytes);
if (memPtr) if (memPtr)
{ {
if (recv(sock, memPtr, bytes, MSG_WAITALL) == bytes) if (recv(sock, memPtr, bytes, MSG_WAITALL) == bytes)
{ {
ext[0].n = bytes; iExt[0].size = bytes;
ext[0].ptr = memPtr; iExt[0].ptr = memPtr;
myDoCommand(&cmd, ext); myDoCommand(&cmd, iExt, oExt);
free(memPtr); free(memPtr);
} }
else else
@ -2756,14 +2816,14 @@ static void *pthSocketThreadHandler(void *fdC)
{ {
if (recv(sock, memPtr, bytes, MSG_WAITALL) == bytes) if (recv(sock, memPtr, bytes, MSG_WAITALL) == bytes)
{ {
ext[0].n = sizeof(unsigned); iExt[0].size = sizeof(unsigned);
ext[0].ptr = memPtr; iExt[0].ptr = memPtr;
ext[1].n = sizeof(unsigned); iExt[1].size = sizeof(unsigned);
ext[1].ptr = memPtr + sizeof(unsigned); iExt[1].ptr = memPtr + sizeof(unsigned);
ext[2].n = cmd.p2; iExt[2].size = cmd.p2;
ext[2].ptr = memPtr + sizeof(unsigned) + sizeof(unsigned); iExt[2].ptr = memPtr + sizeof(unsigned) + sizeof(unsigned);
memPtr[bytes] = 0; /* may be duplicate terminator */ memPtr[bytes] = 0; /* may be duplicate terminator */
myDoCommand(&cmd, ext); myDoCommand(&cmd, iExt, oExt);
free(memPtr); free(memPtr);
} }
else else
@ -2787,24 +2847,24 @@ static void *pthSocketThreadHandler(void *fdC)
bytes = cmd.p1; bytes = cmd.p1;
memPtr = malloc(bytes+1); /* add 1 for a nul terminator */ memPtr = malloc(bytes+1); /* add 1 for a nul terminator */
if (memPtr) if (memPtr)
{ {
if (recv(sock, memPtr, bytes, MSG_WAITALL) == bytes) if (bytes) /* script appended */
{ {
ext[0].n = bytes; if (recv(sock, memPtr, bytes, MSG_WAITALL) != bytes)
ext[0].ptr = memPtr;
memPtr[bytes] = 0; /* may be duplicate terminator */
myDoCommand(&cmd, ext);
free(memPtr);
}
else
{ {
free(memPtr); free(memPtr);
break; 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 break;
} }
else else
{ {
@ -2817,8 +2877,8 @@ static void *pthSocketThreadHandler(void *fdC)
## extension ## ## extension ##
unsigned level unsigned level
*/ */
ext[0].n = 4; iExt[0].size = 4;
ext[0].ptr = &tmp; iExt[0].ptr = &tmp;
if (recv(sock, &tmp, sizeof(unsigned), MSG_WAITALL) != if (recv(sock, &tmp, sizeof(unsigned), MSG_WAITALL) !=
sizeof(unsigned)) sizeof(unsigned))
@ -2831,11 +2891,26 @@ static void *pthSocketThreadHandler(void *fdC)
default: default:
break; break;
} }
myDoCommand(&cmd, ext); myDoCommand(&cmd, iExt, oExt);
} }
write(sock, &cmd, sizeof(cmdCmd_t)); 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; else break;
} }
@ -4347,6 +4422,9 @@ int gpioWaveAddSerial(unsigned gpio,
DBG(DBG_USER, "gpio=%d baud=%d offset=%d numChar=%d str=%s", DBG(DBG_USER, "gpio=%d baud=%d offset=%d numChar=%d str=%s",
gpio, baud, offset, numChar, str); gpio, baud, offset, numChar, str);
DBG(DBG_USER, "l=%d s=%X e=%X",
strlen(str), str[0], str[strlen(str)-1]);
CHECK_INITED; CHECK_INITED;
if (gpio > PI_MAX_USER_GPIO) if (gpio > PI_MAX_USER_GPIO)
@ -4439,13 +4517,11 @@ int gpioWaveAddSerial(unsigned gpio,
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
int gpioWaveSerialReadStart(unsigned gpio, int gpioSerialReadOpen(unsigned gpio, unsigned baud)
unsigned baud,
gpioRx_t *rxp)
{ {
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; CHECK_INITED;
@ -4456,37 +4532,75 @@ int gpioWaveSerialReadStart(unsigned gpio,
SOFT_ERROR(PI_BAD_WAVE_BAUD, SOFT_ERROR(PI_BAD_WAVE_BAUD,
"gpio %d, bad baud rate (%d)", gpio, baud); "gpio %d, bad baud rate (%d)", gpio, baud);
if (rxp == NULL) if (wfRx[gpio].mode != PI_WFRX_NONE)
SOFT_ERROR(PI_BAD_SERIAL_STRUC, "Null structure pointer"); SOFT_ERROR(PI_GPIO_IN_USE, "gpio %d is already being used", gpio);
if (rxp->buf == NULL)
SOFT_ERROR(PI_BAD_SERIAL_BUF, "Null buffer pointer");
bitTime = MILLION / baud; 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].mode = PI_WFRX_SERIAL;
wfRx[gpio].baud = baud; wfRx[gpio].baud = baud;
wfRx[gpio].rxp = rxp; wfRx[gpio].timeout = timeout;
wfRx[gpio].baud = baud;
wfRx[gpio].fullBit = bitTime; wfRx[gpio].fullBit = bitTime;
wfRx[gpio].halfBit = bitTime/2; wfRx[gpio].halfBit = bitTime/2;
wfRx[gpio].rxp->readPos = 0; wfRx[gpio].readPos = 0;
wfRx[gpio].rxp->writePos = 0; wfRx[gpio].writePos = 0;
wfRx[gpio].bit = -1; wfRx[gpio].bit = -1;
gpioSetWatchdog(gpio, timeoutMs); /* get a nudge if no change */
gpioSetAlertFunc(gpio, waveRxBit); gpioSetAlertFunc(gpio, waveRxBit);
return 0; 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); DBG(DBG_USER, "gpio=%d", gpio);
@ -4505,6 +4619,8 @@ int gpioWaveSerialReadStop(unsigned gpio)
case PI_WFRX_SERIAL: case PI_WFRX_SERIAL:
free(wfRx[gpio].buf);
gpioSetWatchdog(gpio, 0); /* switch off timeouts */ gpioSetWatchdog(gpio, 0); /* switch off timeouts */
gpioSetAlertFunc(gpio, NULL); /* cancel alert */ gpioSetAlertFunc(gpio, NULL); /* cancel alert */
@ -5067,6 +5183,8 @@ void gpioStopThread(pthread_t *pth)
int gpioStoreScript(char *script) int gpioStoreScript(char *script)
{ {
DBG(DBG_USER, "script=%s", 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; CHECK_INITED;

102
pigpio.h
View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/ */
/* /*
This version is for pigpio version 11 This version is for pigpio version 12
*/ */
#ifndef PIGPIO_H #ifndef PIGPIO_H
@ -86,7 +86,7 @@ This version is for pigpio version 11
#include <stdint.h> #include <stdint.h>
#include <pthread.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. gpioWaveTxBusy Checks to see if the waveform has ended.
gpioWaveTxStop Aborts the current waveform. gpioWaveTxStop Aborts the current waveform.
gpioWaveSerialReadStart Reads serial data from a user gpio. gpioSerialReadOpen Opens a gpio for reading serial data.
gpioWaveSerialReadStop Stops reading serial data from a user gpio. gpioSerialRead Reads serial data from a gpio.
gpioSerialReadClose Closes a gpio for reading serial data.
gpioWaveGetMicros Length in microseconds of the current waveform. gpioWaveGetMicros Length in microseconds of the current waveform.
gpioWaveGetHighMicros Length of longest waveform so far. gpioWaveGetHighMicros Length of longest waveform so far.
@ -226,7 +227,7 @@ typedef struct
typedef struct typedef struct
{ {
size_t n; size_t size;
void *ptr; void *ptr;
int data; int data;
} gpioExtent_t; } gpioExtent_t;
@ -252,14 +253,6 @@ typedef struct
uint32_t usDelay; uint32_t usDelay;
} gpioPulse_t; } gpioPulse_t;
typedef struct
{
char * buf;
uint32_t bufSize;
int readPos;
int writePos;
} gpioRx_t;
typedef void (*gpioAlertFunc_t) (int gpio, typedef void (*gpioAlertFunc_t) (int gpio,
int level, int level,
uint32_t tick); uint32_t tick);
@ -974,76 +967,38 @@ int gpioWaveTxStop(void);
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
int gpioWaveSerialReadStart(unsigned user_gpio, int gpioSerialReadOpen(unsigned user_gpio, unsigned baud);
unsigned baud,
gpioRx_t * rxp);
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
/* This function starts the reception of serial data with the /* This function opens a gpio for reading serial data.
specified baud rate on a gpio.
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_WAVE_BAUD, 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: The serial data is returned in a cyclic buffer and is read using
gpioSerialRead().
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.
It is the caller's responsibility to read data from the cyclic buffer 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 in a timely fashion.
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;
}
...
}
*/ */
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
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. 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_PROCD 39
#define PI_CMD_PROCR 40 #define PI_CMD_PROCR 40
#define PI_CMD_PROCS 41 #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. 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 -47 /* invalid script */
#define PI_BAD_SCRIPT_ID -48 /* unknown script id */ #define PI_BAD_SCRIPT_ID -48 /* unknown script id */
#define PI_BAD_SER_OFFSET -49 /* add serial data offset > 30 minutes */ #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 */
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/

View File

@ -76,7 +76,7 @@ import threading
import os import os
import atexit import atexit
VERSION = "1.2" VERSION = "1.3"
# gpio levels # gpio levels
@ -157,6 +157,9 @@ _PI_CMD_PROC= 38
_PI_CMD_PROCD=39 _PI_CMD_PROCD=39
_PI_CMD_PROCR=40 _PI_CMD_PROCR=40
_PI_CMD_PROCS=41 _PI_CMD_PROCS=41
_PI_CMD_SLRO= 42
_PI_CMD_SLR= 43
_PI_CMD_SLRC= 44
_PI_CMD_NOIB= 99 _PI_CMD_NOIB= 99
@ -202,7 +205,7 @@ _PI_BAD_CFG_INTERNAL=-34
PI_BAD_WAVE_BAUD =-35 PI_BAD_WAVE_BAUD =-35
PI_TOO_MANY_PULSES =-36 PI_TOO_MANY_PULSES =-36
PI_TOO_MANY_CHARS =-37 PI_TOO_MANY_CHARS =-37
_PI_NOT_SERIAL_GPIO =-38 PI_NOT_SERIAL_GPIO =-38
_PI_BAD_SERIAL_STRUC=-39 _PI_BAD_SERIAL_STRUC=-39
_PI_BAD_SERIAL_BUF =-40 _PI_BAD_SERIAL_BUF =-40
PI_NOT_PERMITTED =-41 PI_NOT_PERMITTED =-41
@ -214,6 +217,7 @@ PI_BAD_PULSELEN =-46
PI_BAD_SCRIPT =-47 PI_BAD_SCRIPT =-47
PI_BAD_SCRIPT_ID =-48 PI_BAD_SCRIPT_ID =-48
PI_BAD_SER_OFFSET =-49 PI_BAD_SER_OFFSET =-49
PI_GPIO_IN_USE =-50
# pigpio error text # pigpio error text
@ -255,7 +259,7 @@ _errors=[
[PI_BAD_WAVE_BAUD , "baud rate not 100-250000"], [PI_BAD_WAVE_BAUD , "baud rate not 100-250000"],
[PI_TOO_MANY_PULSES , "waveform has too many pulses"], [PI_TOO_MANY_PULSES , "waveform has too many pulses"],
[PI_TOO_MANY_CHARS , "waveform has too many chars"], [PI_TOO_MANY_CHARS , "waveform has too many chars"],
[_PI_NOT_SERIAL_GPIO , "no serial read in progress on gpio"], [PI_NOT_SERIAL_GPIO , "no serial read in progress on gpio"],
[PI_NOT_PERMITTED , "no permission to update 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_WVSC_COMMND , "bad WVSC subcommand"],
@ -265,6 +269,7 @@ _errors=[
[PI_BAD_SCRIPT , "invalid script"], [PI_BAD_SCRIPT , "invalid script"],
[PI_BAD_SCRIPT_ID , "unknown script id"], [PI_BAD_SCRIPT_ID , "unknown script id"],
[PI_BAD_SER_OFFSET , "add serial data offset > 30 minute"], [PI_BAD_SER_OFFSET , "add serial data offset > 30 minute"],
[PI_GPIO_IN_USE , "gpio already in use"],
] ]
_control = None _control = None
@ -1701,6 +1706,46 @@ def delete_script(script_id):
""" """
return _u2i(_pigpio_command(_control, _PI_CMD_PROCD, script_id, 0)) 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: class callback:
"""A class to provide gpio level change callbacks.""" """A class to provide gpio level change callbacks."""

View File

@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/> For more information, please refer to <http://unlicense.org/>
*/ */
/* PIGPIOD_IF_VERSION 2 */ /* PIGPIOD_IF_VERSION 3 */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -59,6 +59,7 @@ typedef void (*CBF_t) ();
struct callback_s struct callback_s
{ {
int id; int id;
int gpio; int gpio;
int edge; int edge;
@ -120,7 +121,7 @@ static int pigpio_command_ext
for (i=0; i<extents; i++) 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; 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; *(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; static int id = 0;
callback_t *p; 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);} {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);} {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);} {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);} {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);} {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);} {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_);} {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);} {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);} {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);} {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);} {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);} {return pigpio_command(gPigCommand, PI_CMD_SERVO, user_gpio, pulsewidth);}
int notify_open(void) 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) int notify_begin(unsigned 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) int notify_pause(unsigned handle)
{return pigpio_command(gPigCommand, PI_CMD_NB, handle, 0);} {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);} {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);} {return pigpio_command(gPigCommand, PI_CMD_WDOG, user_gpio, timeout);}
uint32_t read_bank_1(void) uint32_t read_bank_1(void)
@ -616,7 +617,7 @@ int wave_add_generic(unsigned numPulses, gpioPulse_t *pulses)
gpioPulse_t[] pulses gpioPulse_t[] pulses
*/ */
ext[0].n = numPulses * sizeof(gpioPulse_t); ext[0].size = numPulses * sizeof(gpioPulse_t);
ext[0].ptr = pulses; ext[0].ptr = pulses;
return pigpio_command_ext(gPigCommand, PI_CMD_WVAG, numPulses, 0, 1, ext); return pigpio_command_ext(gPigCommand, PI_CMD_WVAG, numPulses, 0, 1, ext);
@ -636,13 +637,13 @@ int wave_add_serial(
char[] str char[] str
*/ */
ext[0].n = sizeof(unsigned); ext[0].size = sizeof(unsigned);
ext[0].ptr = &baud; ext[0].ptr = &baud;
ext[1].n = sizeof(unsigned); ext[1].size = sizeof(unsigned);
ext[1].ptr = &offset; ext[1].ptr = &offset;
ext[2].n = numChar; ext[2].size = numChar;
ext[2].ptr = str; ext[2].ptr = str;
return pigpio_command_ext(gPigCommand, PI_CMD_WVAS, gpio, numChar, 3, ext); 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 unsigned level
*/ */
ext[0].n = sizeof(level); ext[0].size = sizeof(level);
ext[0].ptr = &level; ext[0].ptr = &level;
return pigpio_command_ext(gPigCommand, PI_CMD_TRIG, gpio, pulseLen, 1, ext); return pigpio_command_ext(gPigCommand, PI_CMD_TRIG, gpio, pulseLen, 1, ext);
@ -718,28 +719,48 @@ int store_script(char *script)
len = strlen(script); len = strlen(script);
ext[0].n = len; ext[0].size = len;
ext[0].ptr = script; ext[0].ptr = script;
return pigpio_command_ext(gPigCommand, PI_CMD_PROC, len, 0, 1, ext); 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);} {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);} {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);} {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);} {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);} {return intCallback(gpio, edge, f, user, 1);}
int callback_cancel(int id) int callback_cancel(unsigned id)
{ {
callback_t *p; callback_t *p;
@ -766,7 +787,7 @@ int callback_cancel(int id)
return pigif_callback_not_found; 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 triggered = 0;
int id; int id;

View File

@ -30,7 +30,7 @@ For more information, please refer to <http://unlicense.org/>
#include "pigpio.h" #include "pigpio.h"
#define PIGPIOD_IF_VERSION 2 #define PIGPIOD_IF_VERSION 3
typedef enum typedef enum
{ {
@ -45,12 +45,13 @@ typedef enum
pigif_bad_callback = -2008, pigif_bad_callback = -2008,
pigif_notify_failed = -2009, pigif_notify_failed = -2009,
pigif_callback_not_found = -2010, 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; typedef struct callback_s callback_t;
@ -110,7 +111,7 @@ void pigpio_stop(void);
resources used by the library. resources used by the library.
*/ */
int set_mode(int gpio, int mode); int set_mode(unsigned gpio, unsigned mode);
/* Set the gpio mode. /* Set the gpio mode.
gpio: 0-53. gpio: 0-53.
@ -120,7 +121,7 @@ int set_mode(int gpio, int mode);
or PI_NOT_PERMITTED. or PI_NOT_PERMITTED.
*/ */
int get_mode(int gpio); int get_mode(unsigned gpio);
/* Get the gpio mode. /* Get the gpio mode.
Returns the gpio mode if OK, otherwise PI_BAD_GPIO. Returns the gpio mode if OK, otherwise PI_BAD_GPIO.
@ -128,7 +129,7 @@ int get_mode(int gpio);
gpio: 0-53. 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. /* Set or clear the gpio pull-up/down resistor.
Returns 0 if OK, otherwise PI_BAD_GPIO, PI_BAD_PUD, 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. pud: PUD_UP, PUD_DOWN, PUD_OFF.
*/ */
int read_gpio(int gpio); int read_gpio(unsigned gpio);
/* Read the gpio level. /* Read the gpio level.
Returns the gpio level if OK, otherwise PI_BAD_GPIO. Returns the gpio level if OK, otherwise PI_BAD_GPIO.
@ -146,7 +147,7 @@ int read_gpio(int gpio);
gpio:0-53. gpio:0-53.
*/ */
int write_gpio(int gpio, int level); int write_gpio(unsigned gpio, unsigned level);
/* /*
Write the gpio 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. 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. /* Start (non-zero dutycycle) or stop (0) PWM pulses on the gpio.
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_DUTYCYCLE, 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. 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. /* Set the range of PWM values to be used on the gpio.
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_DUTYRANGE, 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. (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. /* Get the range of PWM values being used on the gpio.
Returns the dutycycle range used for the gpio if OK, 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. 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. /* Get the real underlying range of PWM values being used on the gpio.
Returns the real range used for the gpio if OK, 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. 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. 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 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. 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. 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. Start (500-2500) or stop (0) servo pulses on the gpio.
@ -330,7 +331,7 @@ int notify_open(void);
read from /dev/pigpio15. 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. Start notifications on a previously opened handle.
@ -352,7 +353,7 @@ int notify_begin(int handle, uint32_t bits);
I (32 bit) level I (32 bit) level
*/ */
int notify_pause(int handle); int notify_pause(unsigned handle);
/* /*
Pause notifications on a previously opened handle. Pause notifications on a previously opened handle.
@ -364,7 +365,7 @@ int notify_pause(int handle);
notify_begin() is called again. notify_begin() is called again.
*/ */
int notify_close(int handle); int notify_close(unsigned handle);
/* /*
Stop notifications on a previously opened handle and Stop notifications on a previously opened handle and
release the handle for reuse. release the handle for reuse.
@ -374,7 +375,7 @@ int notify_close(int handle);
handle: 0-31 (as returned by notify_open()) 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. Sets a watchdog for a gpio.
@ -658,25 +659,52 @@ int store_script(char *script);
otherwise PI_BAD_SCRIPT. otherwise PI_BAD_SCRIPT.
*/ */
int run_script(int script_id); int run_script(unsigned script_id);
/* This function runs a stored script. /* This function runs a stored script.
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID. The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
*/ */
int stop_script(int script_id); int stop_script(unsigned script_id);
/* This function stops a running script. /* This function stops a running script.
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID. 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. /* This function deletes a stored script.
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID. The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
*/ */
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. This function initialises a new callback.
@ -687,7 +715,7 @@ int callback(int gpio, int edge, CBFunc_t f);
gpio has the identified edge. 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. 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. 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. This function cancels a callback identified by its id.
The function returns 0 if OK, otherwise pigif_callback_not_found. 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 This function waits for edge on the gpio for up to timeout
seconds. seconds.

18
pigs.c
View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/ */
/* /*
This version is for pigpio version 11+ This version is for pigpio version 12+
*/ */
#include <stdio.h> #include <stdio.h>
@ -153,10 +153,11 @@ int main(int argc , char *argv[])
for (i=0; i<cmdInfo[idx].ext; i++) 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) switch (cmdInfo[idx].rv)
{ {
@ -187,6 +188,17 @@ int main(int argc , char *argv[])
case 5: case 5:
printf(cmdUsage); printf(cmdUsage);
break; 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"); else fatal("recv failed, %m");

View File

@ -3,7 +3,7 @@
from distutils.core import setup from distutils.core import setup
setup(name='pigpio', setup(name='pigpio',
version='1.2', version='1.3',
author='joan', author='joan',
author_email='joan@abyz.me.uk', author_email='joan@abyz.me.uk',
maintainer='joan', maintainer='joan',