V46
authorjoan <joan@abyz.co.uk>
Thu, 18 Feb 2016 21:51:10 +0000 (21:51 +0000)
committerjoan <joan@abyz.co.uk>
Thu, 18 Feb 2016 21:51:10 +0000 (21:51 +0000)
command.c
pigpio.3
pigpio.c
pigpio.h
pigpio.py
pigpiod_if2.3
pigpiod_if2.c
pigpiod_if2.h
pigs.1
setup.py
x_pigs

index 6bd6fae6efbb8a76e65d8c4393794eeb4592ba60..32b59de0f654d09436186401b079ffa299863dd7 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 39+
+This version is for pigpio version 46+
 */
 
 #include <stdio.h>
@@ -185,6 +185,7 @@ cmdInfo_t cmdInfo[]=
    {PI_CMD_WVSM,  "WVSM",  112, 2}, // gpioWaveGet*Micros
    {PI_CMD_WVSP,  "WVSP",  112, 2}, // gpioWaveGet*Pulses
    {PI_CMD_WVTX,  "WVTX",  112, 2}, // gpioWaveTxSend
+   {PI_CMD_WVTXM, "WVTXM", 121, 2}, // gpioWaveTxSend
    {PI_CMD_WVTXR, "WVTXR", 112, 2}, // gpioWaveTxSend
 
    {PI_CMD_ADD  , "ADD"  , 111, 0},
@@ -345,6 +346,7 @@ WVSC 0,1,2       Wave get DMA control block stats\n\
 WVSM 0,1,2       Wave get micros stats\n\
 WVSP 0,1,2       Wave get pulses stats\n\
 WVTX wid         Transmit wave as one-shot\n\
+WVTXM wid wmde   Transmit wave using mode\n\
 WVTXR wid        Transmit wave repeatedly\n\
 \n\
 \n\
@@ -682,7 +684,7 @@ int cmdParse(
          break;
 
       case 121: /* HC I2CRD  I2CRR  I2CRW  I2CWB I2CWQ  P  PFS  PRS
-                   PWM  S  SERVO  SLR  SLRI  W  WDOG  WRITE
+                   PWM  S  SERVO  SLR  SLRI  W  WDOG  WRITE WVTXM
 
                    Two positive parameters.
                 */
index a534ab0c709ec05e825629327e8ea7ed2506f33a..c4dd556ffe9645817f09cb903c66659597a77268 100644 (file)
--- a/pigpio.3
+++ b/pigpio.3
@@ -1968,6 +1968,14 @@ Returns 0 if OK, otherwise PI_BAD_WAVE_ID.
 .IP "" 4
 This function transmits the waveform with id wave_id.  The mode
 determines whether the waveform is sent once or cycles endlessly.
+The SYNC variants wait for the current waveform to reach the
+end of a cycle or finish before starting the new waveform.
+
+.br
+
+.br
+WARNING: bad things may happen if you delete the previous
+waveform before it has been synced to the new waveform.
 
 .br
 
@@ -1981,7 +1989,9 @@ NOTE: Any hardware PWM started by \fBgpioHardwarePWM\fP will be cancelled.
 .EX
   wave_id: >=0, as returned by \fBgpioWaveCreate\fP
 .br
-wave_mode: 0 (PI_WAVE_MODE_ONE_SHOT), 1 (PI_WAVE_MODE_REPEAT)
+wave_mode: PI_WAVE_MODE_ONE_SHOT, PI_WAVE_MODE_REPEAT,
+.br
+           PI_WAVE_MODE_ONE_SHOT_SYNC, PI_WAVE_MODE_REPEAT_SYNC
 .br
 
 .EE
@@ -7540,17 +7550,23 @@ A number identifying a waveform created by \fBgpioWaveCreate\fP.
 .br
 
 .br
-The mode of waveform transmission, whether it is sent once or cycles
-repeatedly.
+The mode determines if the waveform is sent once or cycles
+repeatedly.  The SYNC variants wait for the current waveform
+to reach the end of a cycle or finish before starting the new
+waveform.
 
 .br
 
 .br
 
 .EX
-PI_WAVE_MODE_ONE_SHOT 0
+PI_WAVE_MODE_ONE_SHOT      0
 .br
-PI_WAVE_MODE_REPEAT   1
+PI_WAVE_MODE_REPEAT        1
+.br
+PI_WAVE_MODE_ONE_SHOT_SYNC 2
+.br
+PI_WAVE_MODE_REPEAT_SYNC   3
 .br
 
 .EE
@@ -7801,6 +7817,10 @@ A 16-bit word value.
 #define PI_CMD_NOIB  99
 .br
 
+.br
+#define PI_CMD_WVTXM 100
+.br
+
 .br
 
 .EE
@@ -7877,7 +7897,7 @@ A 16-bit word value.
 .br
 #define PI_INITIALISED      -32 // function called after gpioInitialise
 .br
-#define PI_BAD_WAVE_MODE    -33 // waveform mode not 0-1
+#define PI_BAD_WAVE_MODE    -33 // waveform mode not 0-3
 .br
 #define PI_BAD_CFG_INTERNAL -34 // bad parameter in gpioCfgInternals call
 .br
index d7625f7a245a97a242b7ededc5e5eb3eea356104..f8a038f7192ec66ee1bc130f419c6ef2adef76d5 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 45 */
+/* pigpio version 46 */
 
 /* include ------------------------------------------------------- */
 
@@ -1133,6 +1133,9 @@ static int libInitialised = 0;
 /* initialise every gpioInitialise */
 
 static struct timespec libStarted;
+
+static uint32_t reportedLevel = 0;
+
 static int waveClockInited = 0;
 
 static volatile gpioStats_t gpioStats;
@@ -1165,6 +1168,8 @@ static int waveOutBotOOL = PI_WAVE_COUNT_PAGES*OOL_PER_OPAGE;
 static int waveOutTopOOL = NUM_WAVE_OOL;
 static int waveOutCount = 0;
 
+static uint32_t *waveEndPtr = NULL;
+
 static volatile uint32_t alertBits   = 0;
 static volatile uint32_t monitorBits = 0;
 static volatile uint32_t notifyBits  = 0;
@@ -2179,6 +2184,9 @@ static int myDoCommand(uint32_t *p, unsigned bufSize, char *buf)
       case PI_CMD_WVTX:
          res = gpioWaveTxSend(p[1], PI_WAVE_MODE_ONE_SHOT); break;
 
+      case PI_CMD_WVTXM:
+         res = gpioWaveTxSend(p[1], p[2]); break;
+
       case PI_CMD_WVTXR:
          res = gpioWaveTxSend(p[1], PI_WAVE_MODE_REPEAT); break;
 
@@ -5253,9 +5261,8 @@ static void alertNoiseFilter(gpioSample_t *sample, int numSamples)
    }
 }
 
-uint32_t _reportedLevel, _changedBits;
-
-static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
+static void alertEmit(
+   gpioSample_t *sample, int numSamples, uint32_t changedBits, uint32_t eTick)
 {
    uint32_t oldLevel, newLevel;
    int32_t diff;
@@ -5268,7 +5275,7 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
    char fifo[32];
    gpioReport_t report[MAX_REPORT];
 
-   if (_changedBits)
+   if (changedBits)
    {
       if (gpioGetSamples.func)
       {
@@ -5286,9 +5293,9 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
 
    /* call alert callbacks for each bit transition */
 
-   if (_changedBits & alertBits)
+   if (changedBits & alertBits)
    {
-      oldLevel = (_reportedLevel & alertBits);
+      oldLevel = (reportedLevel & alertBits);
 
       for (d=0; d<numSamples; d++)
       {
@@ -5328,28 +5335,31 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
 
    timeoutBits = 0;
 
-   for (b=0; b<=PI_MAX_USER_GPIO; b++)
+   if (wdogBits)
    {
-      if (gpioAlert[b].wdSteadyUs)
+      for (b=0; b<=PI_MAX_USER_GPIO; b++)
       {
-         diff = eTick - gpioAlert[b].wdTick;
-
-         if (diff >= gpioAlert[b].wdSteadyUs)
+         if (gpioAlert[b].wdSteadyUs)
          {
-            timeoutBits |= (1<<b);
+            diff = eTick - gpioAlert[b].wdTick;
 
-            gpioAlert[b].wdTick = eTick;
-
-            if (gpioAlert[b].func)
+            if (diff >= gpioAlert[b].wdSteadyUs)
             {
-               if (gpioAlert[b].ex)
-               {
-                  (gpioAlert[b].func)
-                     (b, PI_TIMEOUT, eTick, gpioAlert[b].userdata);
-               }
-               else
+               timeoutBits |= (1<<b);
+
+               gpioAlert[b].wdTick = eTick;
+
+               if (gpioAlert[b].func)
                {
-                  (gpioAlert[b].func)(b, PI_TIMEOUT, eTick);
+                  if (gpioAlert[b].ex)
+                  {
+                     (gpioAlert[b].func)(b, PI_TIMEOUT, eTick,
+                                            gpioAlert[b].userdata);
+                  }
+                  else
+                  {
+                     (gpioAlert[b].func)(b, PI_TIMEOUT, eTick);
+                  }
                }
             }
          }
@@ -5360,7 +5370,6 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
    {
       if (gpioNotify[n].state == PI_NOTIFY_CLOSING)
       {
-
          if (gpioNotify[n].pipe)
          {
             DBG(DBG_INTERNAL, "close notify pipe %d", gpioNotify[n].fd);
@@ -5372,7 +5381,6 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
          }
 
          gpioNotify[n].state = PI_NOTIFY_CLOSED;
-
       }
       else if (gpioNotify[n].state == PI_NOTIFY_RUNNING)
       {
@@ -5386,12 +5394,12 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
             notification.
 
             bits         is the set of notification bits
-            _changedBits is the set of changed bits
+            changedBits is the set of changed bits
          */
 
-         if (_changedBits & bits)
+         if (changedBits & bits)
          {
-            oldLevel = _reportedLevel & bits;
+            oldLevel = reportedLevel & bits;
 
             for (d=0; d<numSamples; d++)
             {
@@ -5434,7 +5442,7 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
                   if (numSamples)
                      newLevel = sample[numSamples-1].level;
                   else
-                     newLevel = _reportedLevel;
+                     newLevel = reportedLevel;
 
                   report[emit].seqno = seqno;
                   report[emit].flags = PI_NTFY_FLAGS_WDOG |
@@ -5455,7 +5463,7 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
                if (numSamples)
                   newLevel = sample[numSamples-1].level;
                else
-                  newLevel = _reportedLevel;
+                  newLevel = reportedLevel;
 
                report[emit].seqno = seqno;
                report[emit].flags = PI_NTFY_FLAGS_ALIVE;
@@ -5516,7 +5524,10 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
                            err/sizeof(gpioReport_t), max_emits);
                      }
                   }
-                  else gpioStats.goodPipeWrite++;
+                  else
+                  {
+                     gpioStats.goodPipeWrite++;
+                  }
 
                   emitted += max_emits;
                   emit    -= max_emits;
@@ -5554,7 +5565,10 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
                            err/sizeof(gpioReport_t), emit);
                      }
                   }
-                  else gpioStats.goodPipeWrite++;
+                  else
+                  {
+                     gpioStats.goodPipeWrite++;
+                  }
 
                   emitted += emit;
                   emit = 0;
@@ -5566,20 +5580,20 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
       }
    }
 
-   if (_changedBits & scriptBits)
+   if (changedBits & scriptBits)
    {
       for (n=0; n<PI_MAX_SCRIPTS; n++)
       {
          if ((gpioScript[n].state     == PI_SCRIPT_IN_USE)  &&
              (gpioScript[n].run_state == PI_SCRIPT_WAITING) &&
-             (gpioScript[n].waitBits & _changedBits))
+             (gpioScript[n].waitBits & changedBits))
          {
             pthread_mutex_lock(&gpioScript[n].pthMutex);
 
             if (gpioScript[n].run_state == PI_SCRIPT_WAITING)
             {
                gpioScript[n].changedBits =
-                  gpioScript[n].waitBits & _changedBits;
+                  gpioScript[n].waitBits & changedBits;
                pthread_cond_signal(&gpioScript[n].pthCond);
             }
 
@@ -5588,7 +5602,7 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
       }
    }
 
-   if (numSamples) _reportedLevel = sample[numSamples-1].level;
+   if (numSamples) reportedLevel = sample[numSamples-1].level;
 }
 
 static void alertWdogCheck(gpioSample_t *sample, int numSamples)
@@ -5629,10 +5643,11 @@ static void * pthAlertThread(void *x)
    uint32_t oldLevel, newLevel, level;
    uint32_t oldSlot,  newSlot;
    uint32_t expected, ft, sTick;
+   uint32_t changedBits;
    int32_t diff, minDiff, stickInited;
    int cycle, pulse;
    int numSamples, ticks, i;
-   int rp, compactedSamples, totalSamples;
+   int rp, reports, totalSamples;
    int stopped;
    int moreToDo;
    gpioSample_t sample[MAX_SAMPLE];
@@ -5643,7 +5658,9 @@ static void * pthAlertThread(void *x)
 
    spinWhileStarting();
 
-   _reportedLevel = gpioReg[GPLEV0];
+   reportedLevel = gpioReg[GPLEV0];
+
+   oldLevel = reportedLevel;
 
    oldSlot = dmaCurrentSlot(dmaNowAtICB());
 
@@ -5782,53 +5799,52 @@ static void * pthAlertThread(void *x)
 
       /* Compact samples */
 
-      _changedBits = 0;
-      oldLevel = _reportedLevel & monitorBits;
-
-      compactedSamples = 0;
+      changedBits = 0;
+      oldLevel &= monitorBits;
+      reports = 0;
       totalSamples = 0;
 
       for (rp=0; rp<numSamples; rp++)
       {
-         level = sample[rp].level;
-
-         newLevel = (level & monitorBits);
+         newLevel = (sample[rp].level & monitorBits);
 
          if (newLevel != oldLevel)
          {
-            sample[compactedSamples].tick  = sample[rp].tick;
-            sample[compactedSamples].level = level;
-            _changedBits |= (newLevel ^ oldLevel);
+            sample[reports].tick  = sample[rp].tick;
+            sample[reports].level = sample[rp].level;
+            changedBits |= (newLevel ^ oldLevel);
             oldLevel = newLevel;
 
-            compactedSamples++;
-            if (compactedSamples >= MAX_REPORT)
+            reports++;
+
+            if (reports >= MAX_REPORT)
             {
-               totalSamples += compactedSamples;
+               totalSamples += reports;
 
                /* Rebase watchdog timeouts */
-               if (wdogBits) alertWdogCheck(sample, compactedSamples);
+               if (wdogBits) alertWdogCheck(sample, reports);
 
-               gpioStats.numSamples += compactedSamples;
+               gpioStats.numSamples += reports;
 
-               alertEmit(sample, compactedSamples, sample[rp].tick);
+               alertEmit(sample, reports, changedBits, sample[rp].tick);
 
-               compactedSamples = 0;
+               changedBits = 0;
+               reports = 0;
             }
          }
       }
 
-      if (compactedSamples)
+      if (reports)
       {
-         totalSamples += compactedSamples;
+         totalSamples += reports;
 
          /* Rebase watchdog timeouts */
-         if (wdogBits) alertWdogCheck(sample, compactedSamples);
+         if (wdogBits) alertWdogCheck(sample, reports);
 
-         gpioStats.numSamples += compactedSamples;
+         gpioStats.numSamples += reports;
       }
 
-      alertEmit(sample, compactedSamples, sTick);
+      alertEmit(sample, reports, changedBits, sTick);
 
       if (totalSamples > gpioStats.maxSamples)
          gpioStats.maxSamples = numSamples;
@@ -8346,6 +8362,8 @@ int gpioWaveClear(void)
 
    waveOutCount = 0;
 
+   waveEndPtr = NULL;
+
    return 0;
 }
 
@@ -8818,7 +8836,7 @@ int gpioWaveTxSend(unsigned wave_id, unsigned wave_mode)
    if ((wave_id >= waveOutCount) || waveInfo[wave_id].deleted)
       SOFT_ERROR(PI_BAD_WAVE_ID, "bad wave id (%d)", wave_id);
 
-   if (wave_mode > PI_WAVE_MODE_REPEAT)
+   if (wave_mode > PI_WAVE_MODE_REPEAT_SYNC)
       SOFT_ERROR(PI_BAD_WAVE_MODE, "bad wave mode (%d)", wave_mode);
 
    if (!waveClockInited)
@@ -8828,16 +8846,28 @@ int gpioWaveTxSend(unsigned wave_id, unsigned wave_mode)
       waveClockInited = 1;
    }
 
-   dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
+   p = rawWaveCBAdr(waveInfo[wave_id].topCB);
 
-   dmaOut[DMA_CONBLK_AD] = 0;
+   if ((wave_mode & 1) == PI_WAVE_MODE_ONE_SHOT)
+      p->next = 0;
+   else
+      p->next = waveCbPOadr(waveInfo[wave_id].botCB+1);
 
-   p = rawWaveCBAdr(waveInfo[wave_id].topCB);
+   if (waveEndPtr && (wave_mode > PI_WAVE_MODE_REPEAT))
+   {
+      *waveEndPtr = waveCbPOadr(waveInfo[wave_id].botCB+1);
 
-   if (wave_mode == PI_WAVE_MODE_ONE_SHOT) p->next = 0;
-   else p->next = waveCbPOadr(waveInfo[wave_id].botCB+1);
+      if (!dmaOut[DMA_CONBLK_AD])
+      {
+         initDMAgo((uint32_t *)dmaOut, waveCbPOadr(waveInfo[wave_id].botCB));
+      }
+   }
+   else
+   {
+      initDMAgo((uint32_t *)dmaOut, waveCbPOadr(waveInfo[wave_id].botCB));
+   }
 
-   initDMAgo((uint32_t *)dmaOut, waveCbPOadr(waveInfo[wave_id].botCB));
+   waveEndPtr = &p->next;
 
    /* for compatability with the deprecated gpioWaveTxStart return the
       number of cbs
@@ -9035,7 +9065,7 @@ int gpioWaveChain(char *buf, unsigned bufSize)
    rawCbs_t *p;
    int i, wid, cmd, loop, counters;
    unsigned cycles;
-   uint32_t repeat, next;
+   uint32_t repeat, next, *endPtr;
    int stk_pos[10], stk_lev=0;
 
    cb = 0;
@@ -9053,8 +9083,9 @@ int gpioWaveChain(char *buf, unsigned bufSize)
    }
 
    dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
-
    dmaOut[DMA_CONBLK_AD] = 0;
+   waveEndPtr = NULL;
+   endPtr = NULL;
 
    /* add delay cb at start of DMA */
 
@@ -9242,6 +9273,7 @@ int gpioWaveChain(char *buf, unsigned bufSize)
             p->dst = (uint32_t) (&dmaOBus[0]->periphData);
             p->length = 4;
             p->next = waveCbPOadr(chainGetCB(loop));
+            endPtr = &p->next;
          }
          else
             SOFT_ERROR(PI_BAD_CHAIN_CMD,
@@ -9290,8 +9322,12 @@ int gpioWaveChain(char *buf, unsigned bufSize)
    p->length = 4;
    p->next = 0;
 
+   if (!endPtr) endPtr = &p->next;
+
    initDMAgo((uint32_t *)dmaOut, waveCbPOadr(chainGetCB(0)));
 
+   waveEndPtr = endPtr;
+
    return 0;
 }
 
@@ -9318,9 +9354,10 @@ int gpioWaveTxStop(void)
    CHECK_INITED;
 
    dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
-
    dmaOut[DMA_CONBLK_AD] = 0;
 
+   waveEndPtr = NULL;
+
    return 0;
 }
 
index 3c8d329610a560721a49f9e9ab5afeced456a63b..3be23d4c2258598fd408b79770abcf8755c369e8 100644 (file)
--- a/pigpio.h
+++ b/pigpio.h
@@ -31,7 +31,7 @@ For more information, please refer to <http://unlicense.org/>
 #include <stdint.h>
 #include <pthread.h>
 
-#define PIGPIO_VERSION 45
+#define PIGPIO_VERSION 46
 
 /*TEXT
 
@@ -599,8 +599,10 @@ typedef void *(gpioThreadFunc_t) (void *);
 
 /* wave tx mode */
 
-#define PI_WAVE_MODE_ONE_SHOT 0
-#define PI_WAVE_MODE_REPEAT   1
+#define PI_WAVE_MODE_ONE_SHOT      0
+#define PI_WAVE_MODE_REPEAT        1
+#define PI_WAVE_MODE_ONE_SHOT_SYNC 2
+#define PI_WAVE_MODE_REPEAT_SYNC   3
 
 /* I2C, SPI, SER */
 
@@ -1748,12 +1750,18 @@ int gpioWaveTxSend(unsigned wave_id, unsigned wave_mode);
 /*D
 This function transmits the waveform with id wave_id.  The mode
 determines whether the waveform is sent once or cycles endlessly.
+The SYNC variants wait for the current waveform to reach the
+end of a cycle or finish before starting the new waveform.
+
+WARNING: bad things may happen if you delete the previous
+waveform before it has been synced to the new waveform.
 
 NOTE: Any hardware PWM started by [*gpioHardwarePWM*] will be cancelled.
 
 . .
   wave_id: >=0, as returned by [*gpioWaveCreate*]
-wave_mode: 0 (PI_WAVE_MODE_ONE_SHOT), 1 (PI_WAVE_MODE_REPEAT)
+wave_mode: PI_WAVE_MODE_ONE_SHOT, PI_WAVE_MODE_REPEAT,
+           PI_WAVE_MODE_ONE_SHOT_SYNC, PI_WAVE_MODE_REPEAT_SYNC
 . .
 
 Returns the number of DMA control blocks in the waveform if OK,
@@ -4780,12 +4788,16 @@ A number identifying a waveform created by [*gpioWaveCreate*].
 
 wave_mode::
 
-The mode of waveform transmission, whether it is sent once or cycles
-repeatedly.
+The mode determines if the waveform is sent once or cycles
+repeatedly.  The SYNC variants wait for the current waveform
+to reach the end of a cycle or finish before starting the new
+waveform.
 
 . .
-PI_WAVE_MODE_ONE_SHOT 0
-PI_WAVE_MODE_REPEAT   1
+PI_WAVE_MODE_ONE_SHOT      0
+PI_WAVE_MODE_REPEAT        1
+PI_WAVE_MODE_ONE_SHOT_SYNC 2
+PI_WAVE_MODE_REPEAT_SYNC   3
 . .
 
 wVal::0-65535 (Hex 0x0-0xFFFF, Octal 0-0177777)
@@ -4910,6 +4922,8 @@ PARAMS*/
 
 #define PI_CMD_NOIB  99
 
+#define PI_CMD_WVTXM 100
+
 /*DEF_E*/
 
 /*
@@ -5005,7 +5019,7 @@ after this command is issued.
 #define PI_BAD_SECO_CHANNEL -30 // DMA secondary channel not 0-6
 #define PI_NOT_INITIALISED  -31 // function called before gpioInitialise
 #define PI_INITIALISED      -32 // function called after gpioInitialise
-#define PI_BAD_WAVE_MODE    -33 // waveform mode not 0-1
+#define PI_BAD_WAVE_MODE    -33 // waveform mode not 0-3
 #define PI_BAD_CFG_INTERNAL -34 // bad parameter in gpioCfgInternals call
 #define PI_BAD_WAVE_BAUD    -35 // baud rate not 50-250K(RX)/50-1M(TX)
 #define PI_TOO_MANY_PULSES  -36 // waveform has too many pulses
index 4aa486f73c68fb3a39d54adce255cd13a7317a27..b960fdfdd8752bd9447806c5d40e6f1160c96f6b 100644 (file)
--- a/pigpio.py
+++ b/pigpio.py
@@ -180,6 +180,7 @@ wave_delete               Deletes one or more waveforms
 
 wave_send_once            Transmits a waveform once
 wave_send_repeat          Transmits a waveform repeatedly
+wave_send_using_mode      Transmits a waveform in the chosen mode
 
 wave_chain                Transmits a chain of waveforms
 
@@ -268,7 +269,7 @@ import threading
 import os
 import atexit
 
-VERSION = "1.26"
+VERSION = "1.27"
 
 exceptions = True
 
@@ -321,6 +322,13 @@ NTFY_FLAGS_ALIVE = (1 << 6)
 NTFY_FLAGS_WDOG  = (1 << 5)
 NTFY_FLAGS_GPIO  = 31
 
+# wave modes
+
+WAVE_MODE_ONE_SHOT     =0
+WAVE_MODE_REPEAT       =1
+WAVE_MODE_ONE_SHOT_SYNC=2
+WAVE_MODE_REPEAT_SYNC  =3
+
 # pigpio command numbers
 
 _PI_CMD_MODES= 0
@@ -445,6 +453,8 @@ _PI_CMD_CSI  =96
 _PI_CMD_FG   =97
 _PI_CMD_FN   =98
 
+_PI_CMD_WVTXM=100
+
 # pigpio error numbers
 
 _PI_INIT_FAILED     =-1
@@ -1995,6 +2005,40 @@ class pi():
       """
       return _u2i(_pigpio_command(self.sl, _PI_CMD_WVTXR, wave_id, 0))
 
+   def wave_send_using_mode(self, wave_id, mode):
+      """
+      Transmits the waveform with id wave_id using mode mode.
+
+      wave_id:= >=0 (as returned by a prior call to [*wave_create*]).
+         mode:= WAVE_MODE_ONE_SHOT, WAVE_MODE_REPEAT,
+                WAVE_MODE_ONE_SHOT_SYNC, or WAVE_MODE_REPEAT_SYNC.
+
+      WAVE_MODE_ONE_SHOT: same as [*wave_send_once*].
+
+      WAVE_MODE_REPEAT same as [*wave_send_repeat*].
+
+      WAVE_MODE_ONE_SHOT_SYNC same as [*wave_send_once*] but tries
+      to sync with the previous waveform.
+
+      WAVE_MODE_REPEAT_SYNC same as [*wave_send_repeat*] but tries
+      to sync with the previous waveform.
+
+      WARNING: bad things may happen if you delete the previous
+      waveform before it has been synced to the new waveform.
+
+      NOTE: Any hardware PWM started by [*hardware_PWM*] will
+      be cancelled.
+
+      wave_id:= >=0 (as returned by a prior call to [*wave_create*]).
+
+      Returns the number of DMA control blocks used in the waveform.
+
+      ...
+      cbs = pi.wave_send_using_mode(wid, WAVE_MODE_REPEAT_SYNC)
+      ...
+      """
+      return _u2i(_pigpio_command(self.sl, _PI_CMD_WVTXM, wave_id, mode))
+
    def wave_tx_busy(self):
       """
       Returns 1 if a waveform is currently being transmitted,
@@ -4025,7 +4069,10 @@ def xref():
    SET = 1 
    TIMEOUT = 2 # only returned for a watchdog timeout
 
-   mode: 0-7
+   mode:
+
+   1.The operational mode of a gpio, normally INPUT or OUTPUT.
+
    ALT0 = 4 
    ALT1 = 5 
    ALT2 = 6 
@@ -4035,6 +4082,13 @@ def xref():
    INPUT = 0 
    OUTPUT = 1
 
+   2. The mode of waveform transmission.
+
+   WAVE_MODE_ONE_SHOT = 0 
+   WAVE_MODE_REPEAT = 1 
+   WAVE_MODE_ONE_SHOT_SYNC = 2 
+   WAVE_MODE_REPEAT_SYNC = 3
+
    offset: 0-
    The offset wave data starts from the beginning of the waveform
    being currently defined.
index 533519c057363921d5605d02cdd21812f25a8d5d..44fe60e9091e0abd1f1e9bc7b3fec3691d514cae 100644 (file)
@@ -1093,8 +1093,8 @@ Sets a glitch filter on a gpio.
 .br
 Level changes on the gpio are not reported unless the level
 has been stable for at least \fBsteady\fP microseconds.  The
-level is then reported.  Level changes of less than \fBsteady\fP
-microseconds are ignored.
+level is then reported.  Level changes of less than
+\fBsteady\fP microseconds are ignored.
 
 .br
 
@@ -1398,8 +1398,8 @@ Frequencies above 30MHz are unlikely to work.
 .br
 
 .br
-NOTE: Any waveform started by \fBwave_send_once\fP, \fBwave_send_repeat\fP,
-or \fBwave_chain\fP will be cancelled.
+NOTE: Any waveform started by \fBwave_send_*\fP or \fBwave_chain\fP
+will be cancelled.
 
 .br
 
@@ -1943,6 +1943,65 @@ wave_id: >=0, as returned by \fBwave_create\fP.
 Returns the number of DMA control blocks in the waveform if OK,
 otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
 
+.IP "\fBint wave_send_using_mode(int pi, unsigned wave_id, unsigned mode)\fP"
+.IP "" 4
+Transmits the waveform with id wave_id using mode mode.
+
+.br
+
+.br
+
+.EX
+     pi: 0- (as returned by \fBpigpio_start\fP).
+.br
+wave_id: >=0, as returned by \fBwave_create\fP.
+.br
+   mode: PI_WAVE_MODE_ONE_SHOT, PI_WAVE_MODE_REPEAT,
+.br
+         PI_WAVE_MODE_ONE_SHOT_SYNC, or PI_WAVE_MODE_REPEAT_SYNC.
+.br
+
+.EE
+
+.br
+
+.br
+PI_WAVE_MODE_ONE_SHOT: same as \fBwave_send_once\fP.
+
+.br
+
+.br
+PI_WAVE_MODE_REPEAT same as \fBwave_send_repeat\fP.
+
+.br
+
+.br
+PI_WAVE_MODE_ONE_SHOT_SYNC same as \fBwave_send_once\fP but tries
+to sync with the previous waveform.
+
+.br
+
+.br
+PI_WAVE_MODE_REPEAT_SYNC same as \fBwave_send_repeat\fP but tries
+to sync with the previous waveform.
+
+.br
+
+.br
+WARNING: bad things may happen if you delete the previous
+waveform before it has been synced to the new waveform.
+
+.br
+
+.br
+NOTE: Any hardware PWM started by \fBhardware_PWM\fP will be cancelled.
+
+.br
+
+.br
+Returns the number of DMA control blocks in the waveform if OK,
+otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
+
 .IP "\fBint wave_chain(int pi, char *buf, unsigned bufSize)\fP"
 .IP "" 4
 This function transmits a chain of waveforms.
@@ -4721,8 +4780,8 @@ PI_TIMEOUT 2
 
 .br
 
-.IP "\fBmode\fP: 0-7" 0
-The operational mode of a gpio, normally INPUT or OUTPUT.
+.IP "\fBmode\fP" 0
+1. The operational mode of a gpio, normally INPUT or OUTPUT.
 
 .br
 
@@ -4750,6 +4809,27 @@ PI_ALT5 2
 
 .br
 
+.br
+2. The mode of waveform transmission.
+
+.br
+
+.br
+
+.EX
+PI_WAVE_MODE_ONE_SHOT      0
+.br
+PI_WAVE_MODE_REPEAT        1
+.br
+PI_WAVE_MODE_ONE_SHOT_SYNC 2
+.br
+PI_WAVE_MODE_REPEAT_SYNC   3
+.br
+
+.EE
+
+.br
+
 .br
 
 .IP "\fBnumBytes\fP" 0
index 8067e97d9ec11a33a4d09ccb4a81256eb41feb6d..e5971f269ec99e29d0af15f77a475f2b755c5d5e 100644 (file)
@@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 For more information, please refer to <http://unlicense.org/>
 */
 
-/* PIGPIOD_IF2_VERSION 2 */
+/* PIGPIOD_IF2_VERSION 3 */
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -852,6 +852,9 @@ int wave_send_once(int pi, unsigned wave_id)
 int wave_send_repeat(int pi, unsigned wave_id)
    {return pigpio_command(pi, PI_CMD_WVTXR, wave_id, 0, 1);}
 
+int wave_send_using_mode(int pi, unsigned wave_id, unsigned mode)
+   {return pigpio_command(pi, PI_CMD_WVTXM, wave_id, mode, 1);}
+
 int wave_chain(int pi, char *buf, unsigned bufSize)
 {
    gpioExtent_t ext[1];
index 60d4101efb1277fc27afd1b913aeb81e8ef4d67b..51846c4cb3d3b412c82753b31b6b0cd1de899840 100644 (file)
@@ -30,7 +30,7 @@ For more information, please refer to <http://unlicense.org/>
 
 #include "pigpio.h"
 
-#define PIGPIOD_IF2_VERSION 2
+#define PIGPIOD_IF2_VERSION 3
 
 /*TEXT
 
@@ -190,6 +190,7 @@ wave_delete                Deletes one or more waveforms
 
 wave_send_once             Transmits a waveform once
 wave_send_repeat           Transmits a waveform repeatedly
+wave_send_using_mode       Transmits a waveform in the chosen mode
 
 wave_chain                 Transmits a chain of waveforms
 
@@ -825,8 +826,8 @@ Sets a glitch filter on a gpio.
 
 Level changes on the gpio are not reported unless the level
 has been stable for at least [*steady*] microseconds.  The
-level is then reported.  Level changes of less than [*steady*]
-microseconds are ignored.
+level is then reported.  Level changes of less than
+[*steady*] microseconds are ignored.
 
 . .
        pi: 0- (as returned by [*pigpio_start*]).
@@ -1006,8 +1007,8 @@ int hardware_PWM(int pi, unsigned gpio, unsigned PWMfreq, uint32_t PWMduty);
 Starts hardware PWM on a gpio at the specified frequency and dutycycle.
 Frequencies above 30MHz are unlikely to work.
 
-NOTE: Any waveform started by [*wave_send_once*], [*wave_send_repeat*],
-or [*wave_chain*] will be cancelled.
+NOTE: Any waveform started by [*wave_send_**] or [*wave_chain*]
+will be cancelled.
 
 This function is only valid if the pigpio main clock is PCM.  The
 main clock defaults to PCM but may be overridden when the pigpio
@@ -1276,6 +1277,7 @@ Wave ids are allocated in order, 0, 1, 2, etc.
 Returns 0 if OK, otherwise PI_BAD_WAVE_ID.
 D*/
 
+
 /*F*/
 int wave_send_once(int pi, unsigned wave_id);
 /*D
@@ -1293,6 +1295,7 @@ Returns the number of DMA control blocks in the waveform if OK,
 otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
 D*/
 
+
 /*F*/
 int wave_send_repeat(int pi, unsigned wave_id);
 /*D
@@ -1311,6 +1314,38 @@ Returns the number of DMA control blocks in the waveform if OK,
 otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
 D*/
 
+
+/*F*/
+int wave_send_using_mode(int pi, unsigned wave_id, unsigned mode);
+/*D
+Transmits the waveform with id wave_id using mode mode.
+
+. .
+     pi: 0- (as returned by [*pigpio_start*]).
+wave_id: >=0, as returned by [*wave_create*].
+   mode: PI_WAVE_MODE_ONE_SHOT, PI_WAVE_MODE_REPEAT,
+         PI_WAVE_MODE_ONE_SHOT_SYNC, or PI_WAVE_MODE_REPEAT_SYNC.
+. .
+
+PI_WAVE_MODE_ONE_SHOT: same as [*wave_send_once*].
+
+PI_WAVE_MODE_REPEAT same as [*wave_send_repeat*].
+
+PI_WAVE_MODE_ONE_SHOT_SYNC same as [*wave_send_once*] but tries
+to sync with the previous waveform.
+
+PI_WAVE_MODE_REPEAT_SYNC same as [*wave_send_repeat*] but tries
+to sync with the previous waveform.
+
+WARNING: bad things may happen if you delete the previous
+waveform before it has been synced to the new waveform.
+
+NOTE: Any hardware PWM started by [*hardware_PWM*] will be cancelled.
+
+Returns the number of DMA control blocks in the waveform if OK,
+otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
+D*/
+
 /*F*/
 int wave_chain(int pi, char *buf, unsigned bufSize);
 /*D
@@ -2858,8 +2893,8 @@ reported as PI_TIMEOUT.  See [*set_watchdog*].
 PI_TIMEOUT 2
 . .
 
-mode::0-7
-The operational mode of a gpio, normally INPUT or OUTPUT.
+mode::
+1. The operational mode of a gpio, normally INPUT or OUTPUT.
 
 . .
 PI_INPUT 0
@@ -2872,6 +2907,15 @@ PI_ALT4 3
 PI_ALT5 2
 . .
 
+2. The mode of waveform transmission.
+
+. .
+PI_WAVE_MODE_ONE_SHOT      0
+PI_WAVE_MODE_REPEAT        1
+PI_WAVE_MODE_ONE_SHOT_SYNC 2
+PI_WAVE_MODE_REPEAT_SYNC   3
+. .
+
 numBytes::
 The number of bytes used to store characters in a string.  Depending
 on the number of bits per character there may be 1, 2, or 4 bytes
@@ -2997,7 +3041,7 @@ A SPI channel, 0-2.
 spi_flags::
 See [*spi_open*].
 
-steady :: 0-300000
+steady:: 0-300000
 
 The number of microseconds level changes must be stable for
 before reporting the level changed ([*set_glitch_filter*]) or triggering
diff --git a/pigs.1 b/pigs.1
index d46ec028f07f17a789eab07a7eb10a6516f682a6..2340e1c77a90252eb05f8e3acc562a9d7abee637 100644 (file)
--- a/pigs.1
+++ b/pigs.1
@@ -3700,6 +3700,51 @@ ERROR: non existent wave id
 
 .br
 
+.IP "\fBWVTXM wid wmde\fP - Transmits waveform using mode"
+.IP "" 4
+
+.br
+This command transmits the waveform with id \fBwid\fP using mode \fBwmde\fP.
+
+.br
+The mode may be send once (0), send repeatedly (1), send once but
+first sync with previous wave (2), or send repeatedly but first
+sync with previous wave (3).
+
+.br
+WARNING: bad things may happen if you delete the previous
+waveform before it has been synced to the new waveform.
+
+.br
+NOTE: Any hardware PWM started by \fBHP\fP will be cancelled.
+
+.br
+Upon success the number of DMA control blocks in the waveform is returned.
+On error a negative status code will be returned.
+
+.br
+
+\fBExample\fP
+.br
+
+.EX
+$ pigs wvtxm 1 3
+.br
+75
+.br
+
+.br
+$ pigs wvtxm 2 0
+.br
+-66
+.br
+ERROR: non existent wave id
+.br
+
+.EE
+
+.br
+
 .IP "\fBWVTXR wid\fP - Transmits waveform repeatedly"
 .IP "" 4
 
@@ -4078,6 +4123,21 @@ When a waveform is created it is given an id (0, 1, 2, ...).
 
 .br
 
+.IP "\fBwmde\fP - mode (0-3)" 0
+The command expects a wave transmission mode.
+
+.br
+0 = send once
+.br
+1 = send repeatedly
+.br
+2 = send once but first sync with previous wave
+.br
+3 = send repeatedly but first sync with previous wave
+.br
+
+.br
+
 .IP "\fBws\fP - wave stats sucommand (0-2)" 0
 The command expects a subcommand.
 
@@ -4350,6 +4410,8 @@ The WAIT command parameter is a bit-mask with 1 set for gpios of interest.
 The SYS script receives two unsigned parameters: the accumulator A and
 the current gpio levels.
 
+.br
+
 .SH SEE ALSO
 
 pigpiod(1), pig2vcd(1), pigpio(3), pigpiod_if(3), pigpiod_if2(3)
index 15d792eacf009e27f32e4d3fb890a2c7fc9d6d5a..7bb9ccc60ea87864ad1affe0ef8128a3dec80f67 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@
 from distutils.core import setup
 
 setup(name='pigpio',
-      version='1.26',
+      version='1.27',
       author='joan',
       author_email='joan@abyz.co.uk',
       maintainer='joan',
diff --git a/x_pigs b/x_pigs
index 8410f10d76c74c52ab49babf38b6b0c0dfb612ca..accaabb4c7d18f7586f80dfbb2c6080658afb44c 100755 (executable)
--- a/x_pigs
+++ b/x_pigs
@@ -49,7 +49,7 @@ s=$(pigs bs2 0)
 if [[ $s = "" ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi
 
 s=$(pigs h)
-if [[ ${#s} = 4502 ]]; then echo "HELP ok"; else echo "HELP fail (${#s})"; fi
+if [[ ${#s} = 4544 ]]; then echo "HELP ok"; else echo "HELP fail (${#s})"; fi
 
 s=$(pigs hwver)
 if [[ $s -ne 0 ]]; then echo "HWVER ok"; else echo "HWVER fail ($s)"; fi