V12
authorjoan <joan@abyz.me.uk>
Tue, 28 Jan 2014 23:07:05 +0000 (23:07 +0000)
committerjoan <joan@abyz.me.uk>
Tue, 28 Jan 2014 23:07:05 +0000 (23:07 +0000)
MakeRemote
command.c
pigpio.c
pigpio.h
pigpio.py
pigpiod_if.c
pigpiod_if.h
pigs.c
setup.py

index c27fc649d3079ff99e455a31d19fdf0b65411d89..0e3f83ade153826c754eb32442fc74e1ac9fedcf 100644 (file)
@@ -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
index a128a9dce28b971e22460b09d7a2ef5cdc18ff54..757b0824127509b938a49795c23b2e1a63208ae1 100644 (file)
--- a/command.c
+++ b/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)
index 2c378178966e2291547ca008064ba1e288ed6c1d..cde0e58b9b270308ec2503c071454dafa97c0cb4 100644 (file)
--- a/pigpio.c
+++ b/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,17 +1141,6 @@ static void myDoCommand(cmdCmd_t *cmd, gpioExtent_t *ext)
 
       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
@@ -1152,11 +1150,20 @@ static void myDoCommand(cmdCmd_t *cmd, gpioExtent_t *ext)
          }
          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);
@@ -1164,12 +1171,23 @@ static void myDoCommand(cmdCmd_t *cmd, gpioExtent_t *ext)
          }
          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++)
@@ -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;
+
+         /* 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 */
          {
@@ -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)
+      {
+        --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)
          {
@@ -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;
 
index cf91696298533a091a850ce40827902c3bf2e7b7..bf5fa891855e543918a2131c0694cfe78431049e 100644 (file)
--- a/pigpio.h
+++ b/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;
+   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.
 */
@@ -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     */
 
 
 /*-------------------------------------------------------------------------*/
index 0b40af8d027690ff91d6d89aa31d74b09457de89..dd74105978ce558448902d9eaffba19d219ffcf5 100644 (file)
--- a/pigpio.py
+++ b/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."""
index e6884fdc33d3db6ef5c8372eac2bf21c731d5992..4960150eeeb873fe6fb6b8a48773682e7879fbec 100644 (file)
@@ -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;
index 6c009e266760b10c7d974e3f7a40f1b349ddfc9a..c8e8fc5221d8429507cbcc05b60c16ae6de4d5a9 100644 (file)
@@ -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.
diff --git a/pigs.c b/pigs.c
index 4cd84c2c5aca0cd34026ae80dc1ce2863fd41178..4043c708a7d728f5196466cdb7c7b0087aad68c4 100644 (file)
--- a/pigs.c
+++ b/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");
index 270786bdd4d3d4f64fe7401ef479d2b0906dae6a..3a8ea36645eee211fef2dd878714c0e388a27ee3 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@
 from distutils.core import setup
 
 setup(name='pigpio',
-      version='1.2',
+      version='1.3',
       author='joan',
       author_email='joan@abyz.me.uk',
       maintainer='joan',