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
*/
/*
-This version is for pigpio version 11+
+This version is for pigpio version 12+
*/
#include <stdio.h>
3 %08X %08X
4 %u %u
5 HELP HELP
+6 %s <0 ERR
*/
/* vfyt
8 MODES %d %c
9 PUD %d %c
10 PROG %s
+11 WVAS %d %d %d %s
*/
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},
};
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
{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";
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;
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;
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;
}
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;
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)
For more information, please refer to <http://unlicense.org/>
*/
-/* pigpio version 11 */
+/* pigpio version 12 */
#include <stdio.h>
#include <string.h>
#define MAX_EMITS (PIPE_BUF / sizeof(gpioReport_t))
+#define SRX_BUF_SIZE 8192
+#define CMD_BUF_SIZE 2048
+
/* --------------------------------------------------------------- */
typedef void (*callbk_t) ();
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;
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;
/* ----------------------------------------------------------------------- */
-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;
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;
case PI_CMD_READ: res = gpioRead(p1); break;
- case PI_CMD_WDOG: res = gpioSetWatchdog(p1, p2); break;
-
- case PI_CMD_WRITE:
- if (gpioMask & (uint64_t)(1<<p1)) res = gpioWrite(p1, p2);
- else
- {
- PERM_ERROR("gpioWrite: gpio %d, no permission to update", p1);
- res = PI_NOT_PERMITTED;
- }
- break;
-
case PI_CMD_SERVO:
if (gpioMask & (uint64_t)(1<<p1)) res = gpioServo(p1, p2);
else
}
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 *) (ext[0].ptr));
+ res = gpioTrigger(p1, p2, *(int *) (iExt[0].ptr));
else
{
PERM_ERROR("gpioTrigger: gpio %d, no permission to update", p1);
}
break;
+ case PI_CMD_WDOG: res = gpioSetWatchdog(p1, p2); break;
+
+ case PI_CMD_WRITE:
+ if (gpioMask & (uint64_t)(1<<p1)) res = gpioWrite(p1, p2);
+ else
+ {
+ PERM_ERROR("gpioWrite: gpio %d, no permission to update", p1);
+ res = PI_NOT_PERMITTED;
+ }
+ break;
+
case PI_CMD_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++)
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
/* ----------------------------------------------------------------------- */
-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)
{
if (s->bit == 9)
{
- s->rxp->buf[s->rxp->writePos] = s->byte;
+ s->buf[s->writePos] = s->byte;
+
+ /* don't let writePos catch readPos */
+
+ newWritePos = s->writePos;
- if (++s->rxp->writePos >= s->rxp->bufSize) s->rxp->writePos = 0;
+ if (++newWritePos >= s->bufSize) newWritePos = 0;
+
+ if (newWritePos != s->readPos) s->writePos = newWritePos;
if (level == 0) /* true transition high->low, not a timeout */
{
s->startBitTick = tick;
s->nextBitDiff = s->halfBit;
}
- else s->bit = -1;
+ else
+ {
+ s->bit = -1;
+ gpioSetWatchdog(s->gpio, 0);
+ }
}
}
else
if (level == 0)
{
+ gpioSetWatchdog(s->gpio, s->timeout);
s->level = 0;
s->bit = 0;
s->startBitTick = tick;
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);
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)
+ {
+ --len;
+ buf[len] = 0; /* replace terminating */
+ }
+
+ if ((idx=cmdParse(buf, &cmd, 0, NULL, iExt)) >= 0)
{
- myDoCommand(&cmd, NULL);
+ oExt[0].ptr = buf;
+ oExt[0].size = CMD_BUF_SIZE-1;
+
+ myDoCommand(&cmd, iExt, oExt);
switch (cmdInfo[idx].rv)
{
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;
+
}
}
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);
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
{
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
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
{
## 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))
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;
}
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)
/*-------------------------------------------------------------------------*/
-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;
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);
case PI_WFRX_SERIAL:
+ free(wfRx[gpio].buf);
+
gpioSetWatchdog(gpio, 0); /* switch off timeouts */
gpioSetAlertFunc(gpio, NULL); /* cancel alert */
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;
*/
/*
-This version is for pigpio version 11
+This version is for pigpio version 12
*/
#ifndef PIGPIO_H
#include <stdint.h>
#include <pthread.h>
-#define PIGPIO_VERSION 11
+#define PIGPIO_VERSION 12
/*-------------------------------------------------------------------------*/
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.
typedef struct
{
- size_t n;
+ size_t size;
void *ptr;
int data;
} gpioExtent_t;
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);
/*-------------------------------------------------------------------------*/
-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;
+ in a timely fashion.
+*/
- 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;
+/*-------------------------------------------------------------------------*/
+int gpioSerialRead(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.
- if (rx.readPos >= rx.bufSize) rx.readPos = 0;
- }
- ...
- }
+ Returns the number of bytes copied if OK, otherwise PI_BAD_USER_GPIO
+ or PI_NOT_SERIAL_GPIO.
*/
/*-------------------------------------------------------------------------*/
-int gpioWaveSerialReadStop(unsigned user_gpio);
+int gpioSerialReadClose(unsigned user_gpio);
/*-------------------------------------------------------------------------*/
-/* This function stops reading serial data from a gpio.
+/* This function closes a gpio for reading serial data.
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_NOT_SERIAL_GPIO.
*/
#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.
#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 */
/*-------------------------------------------------------------------------*/
import os
import atexit
-VERSION = "1.2"
+VERSION = "1.3"
# gpio levels
_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
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
PI_BAD_SCRIPT =-47
PI_BAD_SCRIPT_ID =-48
PI_BAD_SER_OFFSET =-49
+PI_GPIO_IN_USE =-50
# pigpio error text
[_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"],
[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
"""
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."""
For more information, please refer to <http://unlicense.org/>
*/
-/* PIGPIOD_IF_VERSION 2 */
+/* PIGPIOD_IF_VERSION 3 */
#include <stdio.h>
#include <stdlib.h>
struct callback_s
{
+
int id;
int gpio;
int edge;
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;
}
}
}
-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;
}
}
-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)
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);
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);
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);
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;
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;
#include "pigpio.h"
-#define PIGPIOD_IF_VERSION 2
+#define PIGPIOD_IF_VERSION 3
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;
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.
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.
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,
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.
gpio:0-53.
*/
-int write_gpio(int gpio, int level);
+int write_gpio(unsigned gpio, unsigned level);
/*
Write the gpio 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,
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,
(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,
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,
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.
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.
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.
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.
I (32 bit) level
*/
-int notify_pause(int handle);
+int notify_pause(unsigned handle);
/*
Pause notifications on a previously opened 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.
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.
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.
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.
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.
*/
/*
-This version is for pigpio version 11+
+This version is for pigpio version 12+
*/
#include <stdio.h>
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)
{
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");
from distutils.core import setup
setup(name='pigpio',
- version='1.2',
+ version='1.3',
author='joan',
author_email='joan@abyz.me.uk',
maintainer='joan',