diff --git a/MakeRemote b/MakeRemote
index 1f96097..40ee70c 100644
--- a/MakeRemote
+++ b/MakeRemote
@@ -1,26 +1,34 @@
-CC = gcc
-AR = ar
-RANLIB = ranlib
-SIZE = size
+#
+CC = gcc
+SIZE = size
+SHLIB = gcc -shared
+STRIPLIB = strip --strip-unneeded
-CFLAGS = -O3 -Wall
+CFLAGS += -O3 -Wall
-ALL = libpigpiod_if.a pigs
+ALL = libpigpiod_if.so pigs
-all: $(ALL) pigpio.py setup.py
+all: $(ALL) pigpio.py setup.py
-pigs: command.o pigs.o
- $(CC) -o pigs pigs.c command.c
+pigpiod_if.o: pigpiod_if.c pigpio.h command.h pigpiod_if.h
+ $(CC) $(CFLAGS) -fpic -c -o pigpiod_if.o pigpiod_if.c
+
+command.o: command.c pigpio.h command.h
+ $(CC) $(CFLAGS) -fpic -c -o command.o command.c
+
+
+pigs: command.o pigs.o
+ $(CC) $(CFLAGS) -fpic -o pigs pigs.c command.c
clean:
rm -f *.o *.i *.s *~ $(ALL)
-install: $(LIB)
+install: $(LIB)
sudo install -m 0755 -d /usr/local/include
sudo install -m 0644 pigpio.h /usr/local/include
sudo install -m 0644 pigpiod_if.h /usr/local/include
sudo install -m 0755 -d /usr/local/lib
- sudo install -m 0644 libpigpiod_if.a /usr/local/lib
+ sudo install -m 0644 libpigpiod_if.so /usr/local/lib
sudo install -m 0755 -d /usr/local/bin
sudo install -m 0755 pigs /usr/local/bin
sudo python2 setup.py install
@@ -32,17 +40,17 @@ install: $(LIB)
uninstall:
sudo rm -f /usr/local/include/pigpio.h
- sudo rm -f /usr/local/lib/libpigpiod_if.a
+ sudo rm -f /usr/local/lib/libpigpiod_if.so
sudo rm -f /usr/local/bin/pigs
sudo rm -f /usr/local/man/man1/pig*.1
sudo rm -f /usr/local/man/man3/pig*.3
-LIB = libpigpiod_if.a
-OBJ = pigpiod_if.o command.o
+LIB = libpigpiod_if.so
+OBJ = pigpiod_if.o command.o
-$(LIB): $(OBJ)
- $(AR) rcs $(LIB) $(OBJ)
- $(RANLIB) $(LIB)
+$(LIB): $(OBJ)
+ $(SHLIB) -o $(LIB) $(OBJ)
+ $(STRIPLIB) $(LIB)
$(SIZE) $(LIB)
# generated using gcc -MM *.c
diff --git a/Makefile b/Makefile
index d5cf15c..ea7951f 100644
--- a/Makefile
+++ b/Makefile
@@ -9,14 +9,12 @@ STRIPLIB = strip --strip-unneeded
CFLAGS += -O3 -Wall
LIB1 = libpigpio.so
-LIB1_ST = libpigpio.a
OBJ1 = pigpio.o command.o
LIB2 = libpigpiod_if.so
-LIB2_ST = libpigpiod_if.a
OBJ2 = pigpiod_if.o command.o
-LIB = $(LIB1) $(LIB1_ST) $(LIB2) $(LIB2_ST)
+LIB = $(LIB1) $(LIB2)
ALL = $(LIB) x_pigpio x_pigpiod_if pig2vcd pigpiod pigs
@@ -59,9 +57,7 @@ install: $(ALL)
sudo install -m 0644 pigpio.h /usr/local/include
sudo install -m 0644 pigpiod_if.h /usr/local/include
sudo install -m 0755 -d /usr/local/lib
- sudo install -m 0644 libpigpio.a /usr/local/lib
sudo install -m 0755 libpigpio.so /usr/local/lib
- sudo install -m 0644 libpigpiod_if.a /usr/local/lib
sudo install -m 0755 libpigpiod_if.so /usr/local/lib
sudo install -m 0755 -d /usr/local/bin
sudo install -m 0755 -s pig2vcd /usr/local/bin
@@ -78,8 +74,6 @@ install: $(ALL)
uninstall:
sudo rm -f /usr/local/include/pigpio.h
sudo rm -f /usr/local/include/pigpiod_if.h
- sudo rm -f /usr/local/lib/libpigpio.a
- sudo rm -f /usr/local/lib/libpigpiod_if.a
sudo rm -f /usr/local/lib/libpigpio.so
sudo rm -f /usr/local/lib/libpigpiod_if.so
sudo rm -f /usr/local/bin/pig2vcd
@@ -100,23 +94,11 @@ $(LIB1): $(OBJ1)
$(STRIPLIB) $(LIB1)
$(SIZE) $(LIB1)
-$(LIB1_ST): $(OBJ1)
- $(AR) rcs $(LIB1_ST) $(OBJ1)
- $(RANLIB) $(LIB1_ST)
- $(STRIPLIB) $(LIB1_ST)
- $(SIZE) $(LIB1_ST)
-
$(LIB2): $(OBJ2)
$(SHLIB) -o $(LIB2) $(OBJ2)
$(STRIPLIB) $(LIB2)
$(SIZE) $(LIB2)
-$(LIB2_ST): $(OBJ2)
- $(AR) rcs $(LIB2_ST) $(OBJ2)
- $(RANLIB) $(LIB2_ST)
- $(STRIPLIB) $(LIB2_ST)
- $(SIZE) $(LIB2_ST)
-
# generated using gcc -MM *.c
pig2vcd.o: pig2vcd.c pigpio.h
diff --git a/README b/README
index 8b975e2..bb18a21 100644
--- a/README
+++ b/README
@@ -17,15 +17,15 @@ make install
This will install
-o the library (libpigpio.a) in /usr/local/lib
-o the library (libpigpiod_if.a) in /usr/local/lib
+o the library (libpigpio.so) in /usr/local/lib
+o the library (libpigpiod_if.so) in /usr/local/lib
o the header file (pigpio.h) in /usr/local/include
o the header file (pigpiod_if.h) in /usr/local/include
o the daemon (pigpiod) in /usr/local/bin
o the socket interface (pigs) in /usr/local/bin
o the utility pig2vcd in /usr/local/bin
o man pages in /usr/local/man/man1 and man3
-o the Python module pigpio.py
+o the Python module pigpio.py for Python 2 and 3
TEST (optional)
@@ -98,7 +98,8 @@ echo "help" >/dev/pigpio
PYTHON MODULE
-The Python pigpio module is installed to the default python location.
+The Python pigpio module is installed to the default Python location
+for Python 2 and Python 3.
You can install it for additional Python versions by
@@ -131,7 +132,7 @@ make -f MakeRemote install
This will install
-o the library (libpigpiod_if.a) in /usr/local/lib
+o the library (libpigpiod_if.so) in /usr/local/lib
o the header file (pigpio.h) in /usr/local/include
o the header file (pigpiod_if.h) in /usr/local/include
o the socket interface (pigs) in /usr/local/bin
diff --git a/command.c b/command.c
index c33f438..1bdb901 100644
--- a/command.c
+++ b/command.c
@@ -26,7 +26,7 @@ For more information, please refer to
*/
/*
-This version is for pigpio version 33+
+This version is for pigpio version 34+
*/
#include
@@ -166,6 +166,7 @@ cmdInfo_t cmdInfo[]=
{PI_CMD_WVAG, "WVAG", 192, 2}, // gpioWaveAddGeneric
{PI_CMD_WVAS, "WVAS", 196, 2}, // gpioWaveAddSerial
{PI_CMD_WVBSY, "WVBSY", 101, 2}, // gpioWaveTxBusy
+ {PI_CMD_WVCHA, "WVCHA", 197, 0}, // gpioWaveChain
{PI_CMD_WVCLR, "WVCLR", 101, 0}, // gpioWaveClear
{PI_CMD_WVCRE, "WVCRE", 101, 2}, // gpioWaveCreate
{PI_CMD_WVDEL, "WVDEL", 112, 0}, // gpioWaveDelete
@@ -318,6 +319,7 @@ WDOG g millis Set millisecond watchdog on gpio\n\
WVAG triplets Wave add generic pulses\n\
WVAS g baud bitlen stopbits offset ... | Wave add serial data\n\
WVBSY Check if wave busy\n\
+WVCHA Transmit a chain of waves\n\
WVCLR Wave clear\n\
WVCRE Create wave from added pulses\n\
WVDEL wid Delete waves w and higher\n\
@@ -456,6 +458,12 @@ static errInfo_t errInfo[]=
{PI_BAD_I2C_RLEN , "bad I2C read length"},
{PI_BAD_I2C_CMD , "bad I2C command"},
{PI_BAD_I2C_BAUD , "bad I2C baud rate, not 50-500k"},
+ {PI_BAD_REPEAT_CNT , "bad repeat count, not 2-max"},
+ {PI_BAD_REPEAT_WID , "bad repeat wave id"},
+ {PI_TOO_MANY_COUNTS , "too many chain counters"},
+ {PI_BAD_CHAIN_CMD , "malformed chain command string"},
+ {PI_REUSED_WID , "wave already used in chain"},
+
};
static char * fmtMdeStr="RW540123";
@@ -844,7 +852,7 @@ int cmdParse(
break;
- case 193: /* BI2CZ I2CWD I2CZ SERW SPIW SPIX
+ case 193: /* BI2CZ I2CWD I2CZ SERW SPIW SPIX
Two or more parameters, first >=0, rest 0-255.
*/
@@ -1005,6 +1013,32 @@ int cmdParse(
break;
+ case 197: /* WVCHA
+
+ One or more parameters, all 0-255.
+ */
+ pars = 0;
+ p8 = ext;
+
+ while (pars < CMD_MAX_PARAM)
+ {
+ ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
+ if ((to1 == CMD_NUMERIC) &&
+ ((int)tp1>=0) && ((int)tp1<=255))
+ {
+ pars++;
+ *p8++ = tp1;
+ }
+ else break;
+ }
+
+ p[3] = pars;
+
+ if (pars) valid = 1;
+
+ break;
+
+
}
if (valid) return idx; else return CMD_BAD_PARAMETER;
diff --git a/pigpio.3 b/pigpio.3
index bc5f550..8d948bb 100644
--- a/pigpio.3
+++ b/pigpio.3
@@ -1871,6 +1871,132 @@ wave_mode: 0 (PI_WAVE_MODE_ONE_SHOT), 1 (PI_WAVE_MODE_REPEAT)
Returns the number of DMA control blocks in the waveform if OK,
otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
+.IP "\fBint gpioWaveChain(char *buf, unsigned bufSize)\fP"
+.IP "" 4
+This function transmits a chain of waveforms.
+
+.br
+
+.br
+NOTE: Any hardware PWM started by \fBgpioHardwarePWM\fP will be cancelled.
+
+.br
+
+.br
+The waves to be transmitted are specified by the contents of buf
+which contains an ordered list of wave_ids and optional command
+codes and related data.
+
+.br
+
+.br
+
+.EX
+ buf: pointer to the wave_ids and optional command codes
+.br
+bufSize: the number of bytes in buf
+.br
+
+.EE
+
+.br
+
+.br
+Returns 0 if OK, otherwise PI_BAD_REPEAT_CNT, PI_BAD_REPEAT_WID,
+PI_BAD_CHAIN_CMD, PI_TOO_MANY_COUNTS, or PI_BAD_WAVE_ID.
+
+.br
+
+.br
+Each wave is transmitted in the order specified. A wave may only
+occur once per chain. Waves may be transmitted multiple times by
+using the repeat command. The repeat command specifies a wave id
+and a count. The wave id must occur earlier in the chain. All the
+waves between wave id and the repeat command are transmitted count
+times.
+
+.br
+
+.br
+Repeat commands may not be nested. The minimum repeat count is 2.
+A maximum of 5 repeat commands is supported per chain.
+
+.br
+
+.br
+The following command codes are supported:
+
+.br
+
+.br
+Name Cmd & Data Meaning
+
+.br
+Repeat 255 wid C0 C1 C2 Repeat from wid count times
+
+.br
+count = C0 + C1*256 + C2*65536
+
+.br
+
+.br
+\fBExample\fP
+.br
+
+.EX
+The following examples assume that waves with ids 0 to 12 exist.
+.br
+
+.br
+// 0 255 0 57 0 0 (repeat 0 57 times)
+.br
+status = gpioWaveChain((char []){0, 255, 0, 57, 0, 0}, 6);
+.br
+
+.br
+// 0 1 255 0 0 2 0 (repeat 0+1 512 times)
+.br
+status = gpioWaveChain((char []){0, 1, 255, 0, 0, 2, 0}, 7);
+.br
+
+.br
+// 0 1 255 1 0 0 1 (transmit 0, repeat 1 65536 times)
+.br
+status = gpioWaveChain((char []){0, 1, 255, 1, 0, 0, 1}, 7);
+.br
+
+.br
+// 0 1 2 3 255 2 13 0 0 (transmit 0+1, repeat 2+3 13 times)
+.br
+status = gpioWaveChain(
+.br
+ (char []){0, 1, 2, 3, 255, 2, 13, 0, 0}, 9);
+.br
+
+.br
+// The following repeats 5 65793 times, transmits 6,
+.br
+// repeats 7+8 514 times, transmits 12,
+.br
+// repeats 9+11+10 197121 times.
+.br
+// 5 255 5 1 1 1 6 7 8 255 7 2 2 0 12 9 11 10 255 9 1 2 3
+.br
+char chain[] = {
+.br
+ 5, 255, 5, 1, 1, 1,
+.br
+ 6, 7, 8, 255, 7, 2, 2, 0,
+.br
+ 12, 9, 11, 10, 255, 9, 1, 2, 3};
+.br
+
+.br
+status = gpioWaveChain(chain, sizeof(chain));
+.br
+
+.EE
+
.IP "\fBint gpioWaveTxBusy(void)\fP"
.IP "" 4
This function checks to see if a waveform is currently being
@@ -2358,7 +2484,7 @@ S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
.IP "\fBint i2cProcessCall(unsigned handle, unsigned i2cReg, unsigned wVal)\fP"
.IP "" 4
This writes 16 bits of data to the specified register of the device
-associated with handle and and reads 16 bits of data in return.
+associated with handle and reads 16 bits of data in return.
.br
@@ -4260,8 +4386,8 @@ Frequencies above 30MHz are unlikely to work.
.br
.br
-NOTE: Any waveform started by \fBgpioWaveTxSend\fP or \fBgpioWaveTxStart\fP
-will be cancelled.
+NOTE: Any waveform started by \fBgpioWaveTxSend\fP, \fBgpioWaveTxStart\fP,
+or \fBgpioWaveChain\fP will be cancelled.
.br
@@ -5414,7 +5540,7 @@ samples per second.
.br
.br
-The size of the sample buffer in milliseconds. Gnerally this should be
+The size of the sample buffer in milliseconds. Generally this should be
left at the default of 120ms. If you expect intense bursts of signals it
might be necessary to increase the buffer size.
@@ -6180,7 +6306,7 @@ The number of segments in a combined I2C transaction.
.IP "\fBoffset\fP" 0
The associated data starts this number of microseconds from the start of
-tghe waveform.
+the waveform.
.br
@@ -7144,6 +7270,10 @@ A 16-bit word value.
#define PI_CMD_I2CZ 92
.br
+.br
+#define PI_CMD_WVCHA 93
+.br
+
.br
#define PI_CMD_NOIB 99
.br
@@ -7384,6 +7514,16 @@ A 16-bit word value.
.br
#define PI_BAD_I2C_BAUD -112 // bad I2C baud rate, not 50-500k
.br
+#define PI_BAD_REPEAT_CNT -113 // bad repeat count, not 2-max
+.br
+#define PI_BAD_REPEAT_WID -114 // bad repeat wave id
+.br
+#define PI_TOO_MANY_COUNTS -115 // too many chain counters
+.br
+#define PI_BAD_CHAIN_CMD -116 // malformed chain command string
+.br
+#define PI_REUSED_WID -117 // wave already used in chain
+.br
.br
#define PI_PIGIF_ERR_0 -2000
diff --git a/pigpio.c b/pigpio.c
index 9725ecd..66aef15 100644
--- a/pigpio.c
+++ b/pigpio.c
@@ -1086,9 +1086,9 @@ static rawWaveInfo_t waveInfo[PI_MAX_WAVES];
static wfRx_t wfRx[PI_MAX_USER_GPIO+1];
-static int waveOutBotCB = 0;
+static int waveOutBotCB = PI_WAVE_COUNTERS*CBS_PER_OPAGE;
static int waveOutTopCB = NUM_WAVE_CBS;
-static int waveOutBotOOL = 0;
+static int waveOutBotOOL = PI_WAVE_COUNTERS*OOL_PER_OPAGE;
static int waveOutTopOOL = NUM_WAVE_OOL;
static int waveOutCount = 0;
@@ -2023,6 +2023,12 @@ static int myDoCommand(uint32_t *p, unsigned bufSize, char *buf)
case PI_CMD_WVBSY: res = gpioWaveTxBusy(); break;
+ case PI_CMD_WVCHA:
+ if (p[3] > bufSize) p[3] = bufSize;
+ res = gpioWaveChain(buf, p[3]);
+ break;
+
+
case PI_CMD_WVCLR: res = gpioWaveClear(); break;
case PI_CMD_WVCRE: res = gpioWaveCreate(); break;
@@ -2506,9 +2512,6 @@ static int errCBsOOL(int cb, int botOOL, int topOOL)
/* ----------------------------------------------------------------------- */
-#define PI_WAVE_COUNT_BLOCKS 3
-#define PI_WAVE_COUNT_LENGTH 10
-
static int wave2Cbs(unsigned wave_mode)
{
int botCB=waveOutBotCB, botOOL=waveOutBotOOL, topOOL=waveOutTopOOL;
@@ -2523,9 +2526,6 @@ static int wave2Cbs(unsigned wave_mode)
rawWave_t * waves;
- int b, baseCB;
- uint32_t def_next;
-
numWaves = wfc[wfcur];
waves = wf [wfcur];
@@ -2618,73 +2618,6 @@ static int wave2Cbs(unsigned wave_mode)
p->next = waveCbPOadr(botCB);
}
- if (waves[i].flags & WAVE_FLAG_COUNT)
- {
- if ((status = errCBsOOL(botCB+1, botOOL, topOOL-1))) return status;
-
- baseCB = botCB;
-
- def_next = waveCbPOadr(baseCB+(3*PI_WAVE_COUNT_BLOCKS));
-
- /* set up all the OOLs */
- for (b=0; b < (PI_WAVE_COUNT_BLOCKS*(PI_WAVE_COUNT_LENGTH+1)); b++)
- rawWaveSetIn(b, def_next);
-
- for (b=0; binfo = NORMAL_DMA;
-
- p->src = waveOOLPOadr
- (topOOL-((b+1)*(PI_WAVE_COUNT_LENGTH+1)));
- p->dst = (waveCbPOadr(botCB+1) + 20);
-
- p->length = 4;
- p->next = waveCbPOadr(botCB);
-
- /* copy BOTTOM to TOP */
-
- p = rawWaveCBAdr(botCB++);
-
- p->info = NORMAL_DMA;
-
- p->src = waveOOLPOadr
- (topOOL-((b+1)*(PI_WAVE_COUNT_LENGTH+1)));
- p->dst = waveOOLPOadr
- (topOOL-(1+(b*(PI_WAVE_COUNT_LENGTH+1))));
-
- p->length = 4;
- p->next = waveCbPOadr(botCB);
-
- /* shift all down one */
-
- p = rawWaveCBAdr(botCB++);
-
- p->info = NORMAL_DMA|DMA_SRC_INC|DMA_DEST_INC;
-
- p->src = waveOOLPOadr
- (topOOL-(((b+1)*(PI_WAVE_COUNT_LENGTH+1))-1));
- p->dst = waveOOLPOadr
- (topOOL-(((b+1)*(PI_WAVE_COUNT_LENGTH+1))-0));
-
- p->length = PI_WAVE_COUNT_LENGTH*4;
- p->next = waveCbPOadr
- (baseCB+(3*PI_WAVE_COUNT_BLOCKS));
- }
-
- topOOL -= PI_WAVE_COUNT_BLOCKS * (PI_WAVE_COUNT_LENGTH+1);
- }
-
if (waves[i].usDelay)
{
if ((status = errCBsOOL(botCB+1, botOOL, topOOL))) return status;
@@ -2732,6 +2665,103 @@ static int wave2Cbs(unsigned wave_mode)
return status;
}
+/* ----------------------------------------------------------------------- */
+
+static uint32_t waveGetIn(int page, int slot)
+{
+ return (dmaOVirt[page]->OOL[slot]);
+}
+
+static void waveSetIn(int page, int slot, uint32_t value)
+{
+ dmaOVirt[page]->OOL[slot] = value;
+}
+
+static uint32_t myWaveOOLPOadr(int page, int slot)
+{
+ return (uint32_t) &dmaOBus[page]->OOL[slot];
+}
+
+static void waveCount(
+ unsigned counter,
+ unsigned blklen,
+ unsigned blocks,
+ unsigned count,
+ uint32_t repeat,
+ uint32_t next)
+{
+ rawCbs_t *p=NULL;
+
+ int b, baseCB, dig;
+ uint32_t nxt;
+
+ int botCB;
+
+ botCB = counter * CBS_PER_OPAGE;
+
+ baseCB = botCB;
+
+ /* set up all the OOLs */
+ for (b=0; b < (blocks*(blklen+1)); b++) waveSetIn(counter, b, repeat);
+
+ for (b=0; binfo = NORMAL_DMA;
+
+ p->src = myWaveOOLPOadr(counter, b*(blklen+1));
+ p->dst = (waveCbPOadr(botCB+1) + 20);
+
+ p->length = 4;
+ p->next = waveCbPOadr(botCB);
+
+ /* copy BOTTOM to TOP */
+
+ p = rawWaveCBAdr(botCB++);
+
+ p->info = NORMAL_DMA;
+
+ p->src = myWaveOOLPOadr(counter, b*(blklen+1));
+ p->dst = myWaveOOLPOadr(counter, (b*(blklen+1))+blklen);
+
+ p->length = 4;
+ p->next = waveCbPOadr(botCB);
+
+ /* shift all down one */
+
+ p = rawWaveCBAdr(botCB++);
+
+ p->info = NORMAL_DMA|DMA_SRC_INC|DMA_DEST_INC;
+
+ p->src = myWaveOOLPOadr(counter, ((b*(blklen+1))+1));
+ p->dst = myWaveOOLPOadr(counter, ((b*(blklen+1))+0));
+
+ p->length = blklen*4;
+ p->next = repeat;
+ }
+
+ b = 0;
+
+ while (count && (b= numIn1) tNext1 = -1;
@@ -3751,7 +3775,7 @@ int i2cZip(
if ((bytes + inPos) < inLen)
{
segs[numSegs].addr = addr;
- segs[numSegs].flags = flags;
+ segs[numSegs].flags = (flags&0xfffe);
segs[numSegs].len = bytes;
segs[numSegs].buf = (uint8_t *)(inBuf + inPos);
inPos += bytes;
@@ -5540,15 +5564,15 @@ static int scrWait(gpioScript_t *s, uint32_t bits)
/* ----------------------------------------------------------------------- */
-static int scrSys(char *cmd, int param)
+static int scrSys(char *cmd, uint32_t p1, uint32_t p2)
{
char buf[256];
- char par[16];
+ char pars[40];
- sprintf(par, " %d", param);
+ sprintf(pars, " %u %u", p1, p2);
strcpy(buf, "/opt/pigpio/cgi/");
strncat(buf, cmd, 200);
- strcat(buf, par);
+ strcat(buf, pars);
DBG(DBG_USER, "sys %s", buf);
@@ -5740,7 +5764,7 @@ static void *pthScript(void *x)
case PI_CMD_SUB: A-=p1; F=A; PC++; break;
case PI_CMD_SYS:
- A=scrSys((char*)instr.p[4], A);
+ A=scrSys((char*)instr.p[4], A, *(gpioReg + GPLEV0));
F=A;
PC++;
break;
@@ -7929,9 +7953,9 @@ int gpioWaveClear(void)
wfStats.pulses = 0;
wfStats.cbs = 0;
- waveOutBotCB = 0;
+ waveOutBotCB = PI_WAVE_COUNTERS*CBS_PER_OPAGE;
waveOutTopCB = NUM_WAVE_CBS;
- waveOutBotOOL = 0;
+ waveOutBotOOL = PI_WAVE_COUNTERS*OOL_PER_OPAGE;
waveOutTopOOL = NUM_WAVE_OOL;
waveOutCount = 0;
@@ -8314,7 +8338,8 @@ int gpioWaveTxStart(unsigned wave_mode)
{
/* This function is deprecated and will be removed. */
- int cb, i;
+ int firstCB=PI_WAVE_COUNTERS*CBS_PER_OPAGE;
+ int numCBs, i;
DBG(DBG_USER, "wave_mode=%d", wave_mode);
@@ -8336,24 +8361,27 @@ int gpioWaveTxStart(unsigned wave_mode)
dmaOut[DMA_CONBLK_AD] = 0;
- waveOutBotCB = 0;
+ waveOutBotCB = firstCB;
waveOutTopCB = NUM_WAVE_CBS;
- waveOutBotOOL = 0;
+ waveOutBotOOL = PI_WAVE_COUNTERS*OOL_PER_OPAGE;
waveOutTopOOL = NUM_WAVE_OOL;
waveOutCount = 0;
- cb = wave2Cbs(wave_mode);
+ numCBs = wave2Cbs(wave_mode);
- if (gpioCfg.dbgLevel >= DBG_SLOW_TICK)
+ if (numCBs > 0)
{
- fprintf(stderr, "*** OUTPUT DMA CONTROL BLOCKS ***\n");
- for (i=0; i= DBG_SLOW_TICK)
+ {
+ fprintf(stderr, "*** OUTPUT DMA CONTROL BLOCKS ***\n");
+ for (i=0; inext = 0;
else p->next = waveCbPOadr(waveInfo[wave_id].botCB+1);
- dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
-
- dmaOut[DMA_CONBLK_AD] = 0;
-
initDMAgo((uint32_t *)dmaOut, waveCbPOadr(waveInfo[wave_id].botCB));
/* for compatability with the deprecated gpioWaveTxStart return the
@@ -8397,6 +8425,135 @@ int gpioWaveTxSend(unsigned wave_id, unsigned wave_mode)
return (waveInfo[wave_id].topCB - waveInfo[wave_id].botCB) + 1;
}
+/* ----------------------------------------------------------------------- */
+
+int gpioWaveChain(char *buf, unsigned bufSize)
+{
+ unsigned blklen=8, blocks=8;
+ int i, wid, rwid, nwid, firstCB, lastCB, counters, cycles;
+ uint32_t repeat, next;
+ char used[256];
+
+ rawCbs_t *p=NULL;
+
+ DBG(DBG_USER, "bufSize=%d [%s]", bufSize, myBuf2Str(bufSize, buf));
+
+ CHECK_INITED;
+
+ if (!waveClockInited)
+ {
+ stopHardwarePWM();
+ initClock(0); /* initialise secondary clock */
+ waveClockInited = 1;
+ }
+
+ dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
+
+ dmaOut[DMA_CONBLK_AD] = 0;
+
+ for (i=0; i<256; i++) used[i] = 255;
+
+ counters = 0;
+ wid = -1;
+ lastCB = -1;
+ firstCB = -1;
+
+ i = 0;
+
+ while (i 1) && (cycles < PI_MAX_WAVE_CYCLES))
+ {
+ --cycles;
+
+ waveCount(counters, blklen, blocks, cycles, repeat, next);
+
+ p = rawWaveCBAdr(lastCB);
+
+ lastCB = -1;
+
+ p->next = waveCbPOadr(counters * CBS_PER_OPAGE);
+
+ counters++;
+ }
+ else SOFT_ERROR(PI_BAD_REPEAT_CNT,
+ "bad chain repeat count (%d)", cycles);
+ }
+ else SOFT_ERROR(PI_BAD_REPEAT_WID,
+ "bad chain repeat wave (%d)", rwid);
+ }
+ else SOFT_ERROR(PI_BAD_CHAIN_CMD,
+ "bad chain command (at char %d)", i);
+ }
+ else SOFT_ERROR(PI_TOO_MANY_COUNTS,
+ "too many chain counters (at char %d)", i);
+ }
+ else if (wid >= waveOutCount)
+ SOFT_ERROR(PI_BAD_WAVE_ID, "undefined wave (%d)", wid);
+ else
+ {
+ if (used[wid] == 255)
+ {
+ used[wid] = counters;
+
+ if (firstCB < 0) firstCB = waveInfo[wid].botCB;
+
+ if (lastCB >= 0)
+ {
+ p = rawWaveCBAdr(lastCB);
+
+ p->next = waveCbPOadr(1+waveInfo[wid].botCB);
+ }
+ lastCB = waveInfo[wid].topCB;
+ }
+ else SOFT_ERROR(PI_REUSED_WID,
+ "wave already used in chain (%d)", wid);
+ }
+ i++;
+ }
+
+ if (firstCB >= 0)
+ {
+ if (lastCB >= 0)
+ {
+ p = rawWaveCBAdr(lastCB);
+
+ p->next = 0;
+ }
+
+ initDMAgo((uint32_t *)dmaOut, waveCbPOadr(firstCB));
+ }
+
+ return 0;
+}
+
/*-------------------------------------------------------------------------*/
int gpioWaveTxBusy(void)
diff --git a/pigpio.h b/pigpio.h
index 25fd758..f5f12a6 100644
--- a/pigpio.h
+++ b/pigpio.h
@@ -200,6 +200,9 @@ gpioWaveCreate Creates a waveform from added data
gpioWaveDelete Deletes one or more waveforms
gpioWaveTxSend Transmits a waveform
+
+gpioWaveChain Transmits a chain of waveforms
+
gpioWaveTxBusy Checks to see if the waveform has ended
gpioWaveTxStop Aborts the current waveform
@@ -371,7 +374,6 @@ typedef struct
#define WAVE_FLAG_READ 1
#define WAVE_FLAG_TICK 2
-#define WAVE_FLAG_COUNT 4
typedef struct
{
@@ -547,7 +549,10 @@ typedef void *(gpioThreadFunc_t) (void *);
#define PI_WAVE_MAX_MICROS (30 * 60 * 1000000) /* half an hour */
-#define PI_MAX_WAVES 512
+#define PI_MAX_WAVES 250
+//#define PI_MAX_WAVE_CYCLES 537824
+#define PI_MAX_WAVE_CYCLES 16777216
+#define PI_WAVE_COUNTERS 5
/* wave tx mode */
@@ -1610,6 +1615,71 @@ otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
D*/
+/*F*/
+int gpioWaveChain(char *buf, unsigned bufSize);
+/*D
+This function transmits a chain of waveforms.
+
+NOTE: Any hardware PWM started by [*gpioHardwarePWM*] will be cancelled.
+
+The waves to be transmitted are specified by the contents of buf
+which contains an ordered list of wave_ids and optional command
+codes and related data.
+
+. .
+ buf: pointer to the wave_ids and optional command codes
+bufSize: the number of bytes in buf
+. .
+
+Returns 0 if OK, otherwise PI_BAD_REPEAT_CNT, PI_BAD_REPEAT_WID,
+PI_BAD_CHAIN_CMD, PI_TOO_MANY_COUNTS, or PI_BAD_WAVE_ID.
+
+Each wave is transmitted in the order specified. A wave may only
+occur once per chain. Waves may be transmitted multiple times by
+using the repeat command. The repeat command specifies a wave id
+and a count. The wave id must occur earlier in the chain. All the
+waves between wave id and the repeat command are transmitted count
+times.
+
+Repeat commands may not be nested. The minimum repeat count is 2.
+A maximum of 5 repeat commands is supported per chain.
+
+The following command codes are supported:
+
+Name @ Cmd & Data @ Meaning
+Repeat @ 255 wid C0 C1 C2 @ Repeat from wid count times
+count = C0 + C1*256 + C2*65536
+
+...
+The following examples assume that waves with ids 0 to 12 exist.
+
+// 0 255 0 57 0 0 (repeat 0 57 times)
+status = gpioWaveChain((char []){0, 255, 0, 57, 0, 0}, 6);
+
+// 0 1 255 0 0 2 0 (repeat 0+1 512 times)
+status = gpioWaveChain((char []){0, 1, 255, 0, 0, 2, 0}, 7);
+
+// 0 1 255 1 0 0 1 (transmit 0, repeat 1 65536 times)
+status = gpioWaveChain((char []){0, 1, 255, 1, 0, 0, 1}, 7);
+
+// 0 1 2 3 255 2 13 0 0 (transmit 0+1, repeat 2+3 13 times)
+status = gpioWaveChain(
+ (char []){0, 1, 2, 3, 255, 2, 13, 0, 0}, 9);
+
+// The following repeats 5 65793 times, transmits 6,
+// repeats 7+8 514 times, transmits 12,
+// repeats 9+11+10 197121 times.
+// 5 255 5 1 1 1 6 7 8 255 7 2 2 0 12 9 11 10 255 9 1 2 3
+char chain[] = {
+ 5, 255, 5, 1, 1, 1,
+ 6, 7, 8, 255, 7, 2, 2, 0,
+ 12, 9, 11, 10, 255, 9, 1, 2, 3};
+
+status = gpioWaveChain(chain, sizeof(chain));
+...
+D*/
+
+
/*F*/
int gpioWaveTxBusy(void);
/*D
@@ -3065,8 +3135,8 @@ int gpioHardwarePWM(unsigned gpio, unsigned PWMfreq, unsigned 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 [*gpioWaveTxSend*] or [*gpioWaveTxStart*]
-will be cancelled.
+NOTE: Any waveform started by [*gpioWaveTxSend*], [*gpioWaveTxStart*],
+or [*gpioWaveChain*] 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 by a call to
@@ -4480,6 +4550,8 @@ PARAMS*/
#define PI_CMD_I2CZ 92
+#define PI_CMD_WVCHA 93
+
#define PI_CMD_NOIB 99
/*DEF_E*/
@@ -4657,6 +4729,11 @@ after this command is issued.
#define PI_BAD_I2C_RLEN -110 // bad I2C read length
#define PI_BAD_I2C_CMD -111 // bad I2C command
#define PI_BAD_I2C_BAUD -112 // bad I2C baud rate, not 50-500k
+#define PI_BAD_REPEAT_CNT -113 // bad repeat count, not 2-max
+#define PI_BAD_REPEAT_WID -114 // bad repeat wave id
+#define PI_TOO_MANY_COUNTS -115 // too many chain counters
+#define PI_BAD_CHAIN_CMD -116 // malformed chain command string
+#define PI_REUSED_WID -117 // wave already used in chain
#define PI_PIGIF_ERR_0 -2000
#define PI_PIGIF_ERR_99 -2099
diff --git a/pigpio.py b/pigpio.py
index 4492671..9a321f6 100644
--- a/pigpio.py
+++ b/pigpio.py
@@ -176,6 +176,9 @@ wave_delete Deletes one or more waveforms
wave_send_once Transmits a waveform once
wave_send_repeat Transmits a waveform repeatedly
+
+wave_chain Transmits a chain of waveforms
+
wave_tx_busy Checks to see if a waveform has ended
wave_tx_stop Aborts the current waveform
@@ -430,6 +433,8 @@ _PI_CMD_BI2CZ=91
_PI_CMD_I2CZ =92
+_PI_CMD_WVCHA=93
+
# pigpio error numbers
_PI_INIT_FAILED =-1
@@ -545,6 +550,11 @@ PI_BAD_I2C_WLEN =-109
PI_BAD_I2C_RLEN =-110
PI_BAD_I2C_CMD =-111
PI_BAD_I2C_BAUD =-112
+PI_BAD_REPEAT_CNT =-113
+PI_BAD_REPEAT_WID =-114
+PI_TOO_MANY_COUNTS =-115
+PI_BAD_CHAIN_CMD =-116
+PI_REUSED_WID =-117
# pigpio error text
@@ -659,6 +669,11 @@ _errors=[
[PI_BAD_I2C_RLEN , "bad I2C read length"],
[PI_BAD_I2C_CMD , "bad I2C command"],
[PI_BAD_I2C_BAUD , "bad I2C baud rate, not 50-500k"],
+ [PI_BAD_REPEAT_CNT , "bad repeat count, not 2-max"],
+ [PI_BAD_REPEAT_WID , "bad repeat wave id"],
+ [PI_TOO_MANY_COUNTS , "too many chain counters"],
+ [PI_BAD_CHAIN_CMD , "malformed chain command string"],
+ [PI_REUSED_WID , "wave already used in chain"],
]
@@ -1536,8 +1551,8 @@ class pi():
and dutycycle. Frequencies above 30MHz are unlikely to work.
NOTE: Any waveform started by [*wave_send_once*],
- [*wave_send_repeat*], [*wave_tx_start*], or
- [*wave_tx_repeat*] will be cancelled.
+ [*wave_send_repeat*], [*wave_tx_start*], [*wave_tx_repeat*],
+ 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
@@ -1956,6 +1971,74 @@ class pi():
"""
return _u2i(_pigpio_command(self.sl, _PI_CMD_WVHLT, 0, 0))
+ def wave_chain(self, data):
+ """
+ This function transmits a chain of waveforms.
+
+ NOTE: Any hardware PWM started by [*hardware_PWM*] will
+ be cancelled.
+
+ The waves to be transmitted are specified by the contents of
+ data which contains an ordered list of wave_ids and optional
+ command codes and related data.
+
+ data:= contains the wave_ids and optional command codes
+
+ Returns 0 if OK, otherwise PI_BAD_REPEAT_CNT, PI_BAD_REPEAT_WID,
+ PI_BAD_CHAIN_CMD, PI_TOO_MANY_COUNTS, or PI_BAD_WAVE_ID.
+
+ Each wave is transmitted in the order specified. A wave may
+ only occur once per chain. Waves may be transmitted multiple
+ times by using the repeat command. The repeat command
+ specifies a wave id and a count. The wave id must occur
+ earlier in the chain. All the waves between wave id and the
+ repeat command are transmitted count times.
+
+ Repeat commands may not be nested. The minimum repeat
+ count is 2. A maximum of 5 repeat commands is supported
+ per chain.
+
+ The following command codes are supported:
+
+ Name @ Cmd & Data @ Meaning
+ Repeat @ 255 wid C0 C1 C2 @ Repeat from wid count times
+ count = C0 + C1*256 + C2*65536
+
+ ...
+ The following examples assume that waves with ids 0 to 12 exist.
+
+ # 0 255 0 57 0 0 (repeat 0 57 times)
+ pi.wave_chain([0, 255, 0, 57, 0, 0])
+
+ # 0 1 255 0 0 2 0 (repeat 0+1 512 times)
+ pi.wave_chain([0, 1, 255, 0, 0, 2, 0])
+
+ # 0 1 255 1 0 0 1 (transmit 0, repeat 1 65536 times)
+ pi.wave_chain([0, 1, 255, 1, 0, 0, 1])
+
+ # 0 1 2 3 255 2 13 0 0 (transmit 0+1, repeat 2+3 13 times)
+ pi.wave_chain([0, 1, 2, 3, 255, 2, 13, 0, 0])
+
+ # The following repeats 5 65793 times, transmits 6,
+ # repeats 7+8 514 times, transmits 12,
+ # repeats 9+11+10 197121 times.
+ # 5 255 5 1 1 1 6 7 8 255 7 2 2 0 12 9 11 10 255 9 1 2 3
+ pi.wave_chain([
+ 5, 255, 5, 1, 1, 1,
+ 6, 7, 8, 255, 7, 2, 2, 0,
+ 12, 9, 11, 10, 255, 9, 1, 2, 3])
+ ...
+ """
+ # I p1 0
+ # I p2 0
+ # I p3 len
+ ## extension ##
+ # s len data bytes
+
+ return _u2i(_pigpio_command_ext(
+ self.sl, _PI_CMD_WVCHA, 0, 0, len(data), [data]))
+
+
def wave_get_micros(self):
"""
Returns the length in microseconds of the current waveform.
@@ -3512,87 +3595,95 @@ def xref():
errnum: <0
. .
- PI_BAD_DATABITS = -101
- PI_BAD_DUTYCYCLE = -8
- PI_BAD_DUTYRANGE = -21
- PI_BAD_FLAGS = -77
- PI_BAD_GPIO = -3
- PI_BAD_HANDLE = -25
- PI_BAD_HCLK_FREQ = -98
- PI_BAD_HCLK_PASS = -99
- PI_BAD_HPWM_DUTY = -97
- PI_BAD_HPWM_FREQ = -96
- PI_BAD_I2C_ADDR = -75
- PI_BAD_I2C_BUS = -74
- PI_BAD_LEVEL = -5
- PI_BAD_MICS_DELAY = -64
- PI_BAD_MILS_DELAY = -65
- PI_BAD_MODE = -4
- PI_BAD_PARAM = -81
- PI_BAD_PARAM_NUM = -52
- PI_BAD_PUD = -6
- PI_BAD_PULSELEN = -46
- PI_BAD_PULSEWIDTH = -7
- PI_BAD_SCRIPT = -47
- PI_BAD_SCRIPT_CMD = -55
- PI_BAD_SCRIPT_ID = -48
- PI_BAD_SERIAL_COUNT = -51
- PI_BAD_SER_DEVICE = -79
- PI_BAD_SER_OFFSET = -49
- PI_BAD_SER_SPEED = -80
- PI_BAD_SPI_CHANNEL = -76
- PI_BAD_SPI_COUNT = -84
- PI_BAD_SPI_SPEED = -78
- PI_BAD_STOPBITS = -102
- PI_BAD_TAG = -63
- PI_BAD_USER_GPIO = -2
- PI_BAD_VAR_NUM = -56
- PI_BAD_WAVE_BAUD = -35
- PI_BAD_WAVE_ID = -66
- PI_BAD_WDOG_TIMEOUT = -15
- PI_BAD_WVSC_COMMND = -43
- PI_BAD_WVSM_COMMND = -44
- PI_BAD_WVSP_COMMND = -45
- PI_DUP_TAG = -53
- PI_EMPTY_WAVEFORM = -69
- PI_GPIO_IN_USE = -50
- PI_HPWM_ILLEGAL = -100
- PI_I2C_OPEN_FAILED = -71
- PI_I2C_READ_FAILED = -83
- PI_I2C_WRITE_FAILED = -82
- PI_NOT_HALTED = -62
- PI_NOT_HCLK_GPIO = -94
- PI_NOT_HPWM_GPIO = -95
- PI_NOT_PERMITTED = -41
- PI_NOT_PWM_GPIO = -92
- PI_NOT_SERIAL_GPIO = -38
- PI_NOT_SERVO_GPIO = -93
- PI_NO_AUX_SPI = -91
- PI_NO_HANDLE = -24
- PI_NO_MEMORY = -58
- PI_NO_SCRIPT_ROOM = -57
- PI_NO_WAVEFORM_ID = -70
- PI_SCRIPT_FAILED = 4
- PI_SCRIPT_HALTED = 1
- PI_SCRIPT_INITING = 0
- PI_SCRIPT_RUNNING = 2
- PI_SCRIPT_WAITING = 3
- PI_SER_OPEN_FAILED = -72
- PI_SER_READ_FAILED = -86
- PI_SER_READ_NO_DATA = -87
- PI_SER_WRITE_FAILED = -85
- PI_SOCK_READ_FAILED = -59
- PI_SOCK_WRIT_FAILED = -60
- PI_SOME_PERMITTED = -42
- PI_SPI_OPEN_FAILED = -73
- PI_SPI_XFER_FAILED = -89
- PI_TOO_MANY_CBS = -67
- PI_TOO_MANY_CHARS = -37
- PI_TOO_MANY_OOL = -68
- PI_TOO_MANY_PARAM = -61
- PI_TOO_MANY_PULSES = -36
- PI_TOO_MANY_TAGS = -54
- PI_UNKNOWN_COMMAND = -88
+ PI_BAD_USER_GPIO =-2
+ PI_BAD_GPIO =-3
+ PI_BAD_MODE =-4
+ PI_BAD_LEVEL =-5
+ PI_BAD_PUD =-6
+ PI_BAD_PULSEWIDTH =-7
+ PI_BAD_DUTYCYCLE =-8
+ PI_BAD_WDOG_TIMEOUT =-15
+ PI_BAD_DUTYRANGE =-21
+ PI_NO_HANDLE =-24
+ PI_BAD_HANDLE =-25
+ PI_BAD_WAVE_BAUD =-35
+ PI_TOO_MANY_PULSES =-36
+ PI_TOO_MANY_CHARS =-37
+ PI_NOT_SERIAL_GPIO =-38
+ PI_NOT_PERMITTED =-41
+ PI_SOME_PERMITTED =-42
+ PI_BAD_WVSC_COMMND =-43
+ PI_BAD_WVSM_COMMND =-44
+ PI_BAD_WVSP_COMMND =-45
+ PI_BAD_PULSELEN =-46
+ PI_BAD_SCRIPT =-47
+ PI_BAD_SCRIPT_ID =-48
+ PI_BAD_SER_OFFSET =-49
+ PI_GPIO_IN_USE =-50
+ PI_BAD_SERIAL_COUNT =-51
+ PI_BAD_PARAM_NUM =-52
+ PI_DUP_TAG =-53
+ PI_TOO_MANY_TAGS =-54
+ PI_BAD_SCRIPT_CMD =-55
+ PI_BAD_VAR_NUM =-56
+ PI_NO_SCRIPT_ROOM =-57
+ PI_NO_MEMORY =-58
+ PI_SOCK_READ_FAILED =-59
+ PI_SOCK_WRIT_FAILED =-60
+ PI_TOO_MANY_PARAM =-61
+ PI_NOT_HALTED =-62
+ PI_BAD_TAG =-63
+ PI_BAD_MICS_DELAY =-64
+ PI_BAD_MILS_DELAY =-65
+ PI_BAD_WAVE_ID =-66
+ PI_TOO_MANY_CBS =-67
+ PI_TOO_MANY_OOL =-68
+ PI_EMPTY_WAVEFORM =-69
+ PI_NO_WAVEFORM_ID =-70
+ PI_I2C_OPEN_FAILED =-71
+ PI_SER_OPEN_FAILED =-72
+ PI_SPI_OPEN_FAILED =-73
+ PI_BAD_I2C_BUS =-74
+ PI_BAD_I2C_ADDR =-75
+ PI_BAD_SPI_CHANNEL =-76
+ PI_BAD_FLAGS =-77
+ PI_BAD_SPI_SPEED =-78
+ PI_BAD_SER_DEVICE =-79
+ PI_BAD_SER_SPEED =-80
+ PI_BAD_PARAM =-81
+ PI_I2C_WRITE_FAILED =-82
+ PI_I2C_READ_FAILED =-83
+ PI_BAD_SPI_COUNT =-84
+ PI_SER_WRITE_FAILED =-85
+ PI_SER_READ_FAILED =-86
+ PI_SER_READ_NO_DATA =-87
+ PI_UNKNOWN_COMMAND =-88
+ PI_SPI_XFER_FAILED =-89
+ PI_NO_AUX_SPI =-91
+ PI_NOT_PWM_GPIO =-92
+ PI_NOT_SERVO_GPIO =-93
+ PI_NOT_HCLK_GPIO =-94
+ PI_NOT_HPWM_GPIO =-95
+ PI_BAD_HPWM_FREQ =-96
+ PI_BAD_HPWM_DUTY =-97
+ PI_BAD_HCLK_FREQ =-98
+ PI_BAD_HCLK_PASS =-99
+ PI_HPWM_ILLEGAL =-100
+ PI_BAD_DATABITS =-101
+ PI_BAD_STOPBITS =-102
+ PI_MSG_TOOBIG =-103
+ PI_BAD_MALLOC_MODE =-104
+ PI_BAD_SMBUS_CMD =-107
+ PI_NOT_I2C_GPIO =-108
+ PI_BAD_I2C_WLEN =-109
+ PI_BAD_I2C_RLEN =-110
+ PI_BAD_I2C_CMD =-111
+ PI_BAD_I2C_BAUD =-112
+ PI_BAD_REPEAT_CNT =-113
+ PI_BAD_REPEAT_WID =-114
+ PI_TOO_MANY_COUNTS =-115
+ PI_BAD_CHAIN_CMD =-116
+ PI_REUSED_WID =-117
. .
frequency: 0-40000
diff --git a/pigpiod_if.3 b/pigpiod_if.3
index dfa99b3..0bcde27 100644
--- a/pigpiod_if.3
+++ b/pigpiod_if.3
@@ -1221,7 +1221,8 @@ Frequencies above 30MHz are unlikely to work.
.br
.br
-NOTE: Any waveform started by \fBwave_send_once\fP, \fBwave_send_repeat\fP, \fBwave_tx_start\fP, or \fBwave_tx_repeat\fP will be cancelled.
+NOTE: Any waveform started by \fBwave_send_once\fP, \fBwave_send_repeat\fP, \fBwave_tx_start\fP, \fBwave_tx_repeat\fP, or \fBwave_chain\fP
+will be cancelled.
.br
@@ -1702,6 +1703,132 @@ 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_chain(char *buf, unsigned bufSize)\fP"
+.IP "" 4
+This function transmits a chain of waveforms.
+
+.br
+
+.br
+NOTE: Any hardware PWM started by \fBhardware_PWM\fP will be cancelled.
+
+.br
+
+.br
+The waves to be transmitted are specified by the contents of buf
+which contains an ordered list of wave_ids and optional command
+codes and related data.
+
+.br
+
+.br
+
+.EX
+ buf: pointer to the wave_ids and optional command codes
+.br
+bufSize: the number of bytes in buf
+.br
+
+.EE
+
+.br
+
+.br
+Returns 0 if OK, otherwise PI_BAD_REPEAT_CNT, PI_BAD_REPEAT_WID,
+PI_BAD_CHAIN_CMD, PI_TOO_MANY_COUNTS, or PI_BAD_WAVE_ID.
+
+.br
+
+.br
+Each wave is transmitted in the order specified. A wave may only
+occur once per chain. Waves may be transmitted multiple times by
+using the repeat command. The repeat command specifies a wave id
+and a count. The wave id must occur earlier in the chain. All the
+waves between wave id and the repeat command are transmitted count
+times.
+
+.br
+
+.br
+Repeat commands may not be nested. The minimum repeat count is 2.
+A maximum of 5 repeat commands is supported per chain.
+
+.br
+
+.br
+The following command codes are supported:
+
+.br
+
+.br
+Name Cmd & Data Meaning
+
+.br
+Repeat 255 wid C0 C1 C2 Repeat from wid count times
+
+.br
+count = C0 + C1*256 + C2*65536
+
+.br
+
+.br
+\fBExample\fP
+.br
+
+.EX
+The following examples assume that waves with ids 0 to 12 exist.
+.br
+
+.br
+// 0 255 0 57 0 0 (repeat 0 57 times)
+.br
+status = wave_chain((char []){0, 255, 0, 57, 0, 0}, 6);
+.br
+
+.br
+// 0 1 255 0 0 2 0 (repeat 0+1 512 times)
+.br
+status = wave_chain((char []){0, 1, 255, 0, 0, 2, 0}, 7);
+.br
+
+.br
+// 0 1 255 1 0 0 1 (transmit 0, repeat 1 65536 times)
+.br
+status = wave_chain((char []){0, 1, 255, 1, 0, 0, 1}, 7);
+.br
+
+.br
+// 0 1 2 3 255 2 13 0 0 (transmit 0+1, repeat 2+3 13 times)
+.br
+status = wave_chain(
+.br
+ (char []){0, 1, 2, 3, 255, 2, 13, 0, 0}, 9);
+.br
+
+.br
+// The following repeats 5 65793 times, transmits 6,
+.br
+// repeats 7+8 514 times, transmits 12,
+.br
+// repeats 9+11+10 197121 times.
+.br
+// 5 255 5 1 1 1 6 7 8 255 7 2 2 0 12 9 11 10 255 9 1 2 3
+.br
+char chain[] = {
+.br
+ 5, 255, 5, 1, 1, 1,
+.br
+ 6, 7, 8, 255, 7, 2, 2, 0,
+.br
+ 12, 9, 11, 10, 255, 9, 1, 2, 3};
+.br
+
+.br
+status = wave_chain(chain, sizeof(chain));
+.br
+
+.EE
+
.IP "\fBint wave_tx_busy(void)\fP"
.IP "" 4
This function checks to see if a waveform is currently being
diff --git a/pigpiod_if.c b/pigpiod_if.c
index d5d2baf..6e0be8f 100644
--- a/pigpiod_if.c
+++ b/pigpiod_if.c
@@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to
*/
-/* PIGPIOD_IF_VERSION 15 */
+/* PIGPIOD_IF_VERSION 16 */
#include
#include
@@ -743,6 +743,25 @@ int wave_send_once(unsigned wave_id)
int wave_send_repeat(unsigned wave_id)
{return pigpio_command(gPigCommand, PI_CMD_WVTXR, 0, 0, 1);}
+int wave_chain(char *buf, unsigned bufSize)
+{
+ gpioExtent_t ext[1];
+
+ /*
+ p1=0
+ p2=0
+ p3=bufSize
+ ## extension ##
+ char buf[bufSize]
+ */
+
+ ext[0].size = bufSize;
+ ext[0].ptr = buf;
+
+ return pigpio_command_ext
+ (gPigCommand, PI_CMD_WVCHA, 0, 0, bufSize, 1, ext, 1);
+}
+
int wave_tx_busy(void)
{return pigpio_command(gPigCommand, PI_CMD_WVBSY, 0, 0, 1);}
diff --git a/pigpiod_if.h b/pigpiod_if.h
index 7a7ede0..5f32ffe 100644
--- a/pigpiod_if.h
+++ b/pigpiod_if.h
@@ -30,7 +30,7 @@ For more information, please refer to
#include "pigpio.h"
-#define PIGPIOD_IF_VERSION 15
+#define PIGPIOD_IF_VERSION 16
/*TEXT
@@ -186,6 +186,9 @@ wave_delete Deletes one or more waveforms
wave_send_once Transmits a waveform once
wave_send_repeat Transmits a waveform repeatedly
+
+wave_chain Transmits a chain of waveforms
+
wave_tx_busy Checks to see if the waveform has ended
wave_tx_stop Aborts the current waveform
@@ -911,7 +914,8 @@ int hardware_PWM(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*], [*wave_tx_start*], or [*wave_tx_repeat*] will be cancelled.
+NOTE: Any waveform started by [*wave_send_once*], [*wave_send_repeat*], [*wave_tx_start*], [*wave_tx_repeat*], 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
@@ -1195,6 +1199,70 @@ 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(char *buf, unsigned bufSize);
+/*D
+This function transmits a chain of waveforms.
+
+NOTE: Any hardware PWM started by [*hardware_PWM*] will be cancelled.
+
+The waves to be transmitted are specified by the contents of buf
+which contains an ordered list of wave_ids and optional command
+codes and related data.
+
+. .
+ buf: pointer to the wave_ids and optional command codes
+bufSize: the number of bytes in buf
+. .
+
+Returns 0 if OK, otherwise PI_BAD_REPEAT_CNT, PI_BAD_REPEAT_WID,
+PI_BAD_CHAIN_CMD, PI_TOO_MANY_COUNTS, or PI_BAD_WAVE_ID.
+
+Each wave is transmitted in the order specified. A wave may only
+occur once per chain. Waves may be transmitted multiple times by
+using the repeat command. The repeat command specifies a wave id
+and a count. The wave id must occur earlier in the chain. All the
+waves between wave id and the repeat command are transmitted count
+times.
+
+Repeat commands may not be nested. The minimum repeat count is 2.
+A maximum of 5 repeat commands is supported per chain.
+
+The following command codes are supported:
+
+Name @ Cmd & Data @ Meaning
+Repeat @ 255 wid C0 C1 C2 @ Repeat from wid count times
+count = C0 + C1*256 + C2*65536
+
+...
+The following examples assume that waves with ids 0 to 12 exist.
+
+// 0 255 0 57 0 0 (repeat 0 57 times)
+status = wave_chain((char []){0, 255, 0, 57, 0, 0}, 6);
+
+// 0 1 255 0 0 2 0 (repeat 0+1 512 times)
+status = wave_chain((char []){0, 1, 255, 0, 0, 2, 0}, 7);
+
+// 0 1 255 1 0 0 1 (transmit 0, repeat 1 65536 times)
+status = wave_chain((char []){0, 1, 255, 1, 0, 0, 1}, 7);
+
+// 0 1 2 3 255 2 13 0 0 (transmit 0+1, repeat 2+3 13 times)
+status = wave_chain(
+ (char []){0, 1, 2, 3, 255, 2, 13, 0, 0}, 9);
+
+// The following repeats 5 65793 times, transmits 6,
+// repeats 7+8 514 times, transmits 12,
+// repeats 9+11+10 197121 times.
+// 5 255 5 1 1 1 6 7 8 255 7 2 2 0 12 9 11 10 255 9 1 2 3
+char chain[] = {
+ 5, 255, 5, 1, 1, 1,
+ 6, 7, 8, 255, 7, 2, 2, 0,
+ 12, 9, 11, 10, 255, 9, 1, 2, 3};
+
+status = wave_chain(chain, sizeof(chain));
+...
+D*/
+
/*F*/
int wave_tx_busy(void);
diff --git a/pigs.1 b/pigs.1
index 08d9a17..88b8855 100644
--- a/pigs.1
+++ b/pigs.1
@@ -674,8 +674,8 @@ frequency \fBpf\fP with dutycycle \fBpdc\fP. Frequencies above 30MHz
are unlikely to work.
.br
-NOTE: Any waveform started by \fBWVGO\fP, \fBWVGOR\fP, \fBWVTX\fP or
-\fBWVTXR\fP will be cancelled.
+NOTE: Any waveform started by \fBWVGO\fP, \fBWVGOR\fP, \fBWVTX\fP,
+\fBWVTXR\fP, or \fBWVCHA\fP will be cancelled.
.br
This function is only valid if the pigpio main clock is PCM. The
@@ -3104,6 +3104,99 @@ $ pigs wvbsy
.br
+.IP "\fBWVCHA bvs\fP - Transmits a chain of waveforms"
+.IP "" 4
+
+.br
+This command transmits a chain of waveforms.
+
+.br
+NOTE: Any hardware PWM started by \fBHP\fP will
+be cancelled.
+
+.br
+The waves to be transmitted are specified by the contents of
+\fBbvs\fP which contains an ordered list of wave_ids and optional
+command codes and related data.
+
+.br
+Upon success 0 is returned. On error a negative status code
+will be returned.
+
+.br
+Each wave is transmitted in the order specified. A wave may
+only occur once per chain. Waves may be transmitted multiple
+times by using the repeat command. The repeat command
+specifies a wave id and a count. The wave id must occur
+earlier in the chain. All the waves between wave id and the
+repeat command are transmitted count times.
+
+.br
+Repeat commands may not be nested. The minimum repeat
+count is 2. A maximum of 5 repeat commands is supported
+per chain.
+
+.br
+The following command codes are supported:
+
+.br
+
+.EX
+Name Cmd & Data Meaning
+Repeat 255 wid C0 C1 C2 Repeat from wid count times
+
+.EE
+count = C0 + C1*256 + C2*65536
+
+.br
+
+\fBExample\fP
+.br
+
+.EX
+The following examples assume that waves with ids 0 to 12 exist.
+.br
+
+.br
+# 0 255 0 57 0 0 (repeat 0 57 times)
+.br
+$ pigs wvcha 0 255 0 57 0 0
+.br
+
+.br
+# 0 1 255 0 0 2 0 (repeat 0+1 512 times)
+.br
+$ pigs wvcha 0 1 255 0 0 2 0
+.br
+
+.br
+# 0 1 255 1 0 0 1 (transmit 0, repeat 1 65536 times)
+.br
+$ pigs wvcha 0 1 255 1 0 0 1
+.br
+
+.br
+# 0 1 2 3 255 2 13 0 0 (transmit 0+1, repeat 2+3 13 times)
+.br
+$ pigs wvcha 0 1 2 3 255 2 13 0 0
+.br
+
+.br
+# The following repeats 5 65793 times, transmits 6,
+.br
+# repeats 7+8 514 times, transmits 12,
+.br
+# repeats 9+11+10 197121 times.
+.br
+# 5 255 5 1 1 1 6 7 8 255 7 2 2 0 12 9 11 10 255 9 1 2 3
+.br
+$ pigs wvcha 5 255 5 1 1 1 6 7 8 255 7 2 2 0 12 9 11 10 255 9 1 2 3
+.br
+
+.EE
+
+.br
+
.IP "\fBWVCLR \fP - Clear all waveforms"
.IP "" 4
@@ -3444,7 +3537,7 @@ $ pigs wvsp 2
.br
-.IP "\fBWVTX wid\fP - Transmit waveform once"
+.IP "\fBWVTX wid\fP - Transmits waveform once"
.IP "" 4
.br
@@ -3480,7 +3573,7 @@ ERROR: non existent wave id
.br
-.IP "\fBWVTXR wid\fP - Transmit waveform repeatedly"
+.IP "\fBWVTXR wid\fP - Transmits waveform repeatedly"
.IP "" 4
.br
@@ -4109,6 +4202,8 @@ specified y is assumed to be a variable.
The WAIT command parameter is a bit-mask with 1 set for gpios of interest.
.br
+The SYS script receives two unsigned parameters: the accumulator A and
+the current gpio levels.
.SH SEE ALSO
diff --git a/pigs.c b/pigs.c
index b97418b..2ee99e3 100644
--- a/pigs.c
+++ b/pigs.c
@@ -26,7 +26,7 @@ For more information, please refer to
*/
/*
-This version is for pigpio version 33+
+This version is for pigpio version 34+
*/
#include
diff --git a/x_pigpiod_if.c b/x_pigpiod_if.c
index c1ff6c3..f782e09 100644
--- a/x_pigpiod_if.c
+++ b/x_pigpiod_if.c
@@ -359,7 +359,7 @@ To the lascivious pleasing of a lute.\n\
CHECK(5, 3, e, 9, 0, "wave tx repeat");
oc = t5_count;
- time_sleep(5);
+ time_sleep(5.05);
c = t5_count - oc;
CHECK(5, 4, c, 50, 1, "callback");
diff --git a/x_pigs b/x_pigs
index fc12cf9..c1d5d1c 100755
--- 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} = 4220 ]]; then echo "HELP ok"; else echo "HELP fail (${#s})"; fi
+if [[ ${#s} = 4263 ]]; 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