-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
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
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
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
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
$(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
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)
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
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
*/
/*
-This version is for pigpio version 33+
+This version is for pigpio version 34+
*/
#include <stdio.h>
{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
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\
{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";
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.
*/
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;
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
.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
.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
.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.
.IP "\fBoffset\fP" 0
The associated data starts this number of microseconds from the start of
-tghe waveform.
+the waveform.
.br
#define PI_CMD_I2CZ 92
.br
+.br
+#define PI_CMD_WVCHA 93
+.br
+
.br
#define PI_CMD_NOIB 99
.br
.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
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;
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;
/* ----------------------------------------------------------------------- */
-#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;
rawWave_t * waves;
- int b, baseCB;
- uint32_t def_next;
-
numWaves = wfc[wfcur];
waves = wf [wfcur];
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; b<PI_WAVE_COUNT_BLOCKS; b++)
- rawWaveSetIn( (b*(PI_WAVE_COUNT_LENGTH+1))+1,
- waveCbPOadr (baseCB+((b*PI_WAVE_COUNT_BLOCKS)+3)));
-
- rawWaveSetIn
- (((PI_WAVE_COUNT_BLOCKS-1)*(PI_WAVE_COUNT_LENGTH+1))+7, 0);
-
- for (b=0; b<PI_WAVE_COUNT_BLOCKS; b++)
- {
- /* copy BOTTOM to NEXT */
-
- p = rawWaveCBAdr(botCB++);
-
- p->info = 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;
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; b<blocks; b++)
+ waveSetIn(counter, ((b*(blklen+1))+blklen), waveCbPOadr(baseCB+((b*3)+3)));
+
+ for (b=0; b<blocks; b++)
+ {
+ /* copy BOTTOM to NEXT */
+
+ p = rawWaveCBAdr(botCB++);
+
+ p->info = 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<blocks))
+ {
+ dig = count % blklen;
+ count /= blklen;
+
+ if (count) nxt = waveGetIn(counter, (b*(blklen+1))+blklen);
+ else nxt = next;
+
+ waveSetIn(counter, b*(blklen+1)+dig, nxt);
+
+ b++;
+ }
+}
+
/* ----------------------------------------------------------------------- */
--level;
}
- if (out[outPos].flags & WAVE_FLAG_COUNT)
- {
- cbs += (3*PI_WAVE_COUNT_BLOCKS);
- level -= (PI_WAVE_COUNT_BLOCKS*(PI_WAVE_COUNT_LENGTH+1));
- }
-
outPos++;
if (inPos1 >= numIn1) tNext1 = -1;
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;
/* ----------------------------------------------------------------------- */
-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);
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;
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;
{
/* 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);
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<cb; i++) waveCbOPrint(i);
- }
+ if (gpioCfg.dbgLevel >= DBG_SLOW_TICK)
+ {
+ fprintf(stderr, "*** OUTPUT DMA CONTROL BLOCKS ***\n");
+ for (i=0; i<numCBs; i++) waveCbOPrint(firstCB+i);
+ }
- initDMAgo((uint32_t *)dmaOut, (uint32_t)dmaOBus[0]);
+ initDMAgo((uint32_t *)dmaOut, waveCbPOadr(firstCB));
+ }
- return cb;
+ return numCBs;
}
waveClockInited = 1;
}
+ dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
+
+ dmaOut[DMA_CONBLK_AD] = 0;
+
p = rawWaveCBAdr(waveInfo[wave_id].topCB);
if (wave_mode == PI_WAVE_MODE_ONE_SHOT) p->next = 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
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<bufSize)
+ {
+ wid = (unsigned)buf[i];
+
+ if (wid == 255) /* repeat wave command */
+ {
+ if (counters < PI_WAVE_COUNTERS)
+ {
+ if ((i+4) < bufSize)
+ {
+ rwid = buf[i+1];
+ if ((i+5) < bufSize)
+ {
+ nwid = buf[i+5];
+ if (nwid < waveOutCount)
+ next = waveCbPOadr(1+waveInfo[nwid].botCB);
+ else next = 0; /* error, will be picked up later */
+ }
+ else next = 0;
+ if (used[rwid] == counters)
+ {
+ repeat = waveCbPOadr(1+waveInfo[rwid].botCB);
+
+ cycles = (unsigned)buf[i+2] +
+ ((unsigned)buf[i+3]<<8) +
+ ((unsigned)buf[i+4]<<16);
+
+ i+=4;
+
+ if ((cycles > 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)
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
#define WAVE_FLAG_READ 1
#define WAVE_FLAG_TICK 2
-#define WAVE_FLAG_COUNT 4
typedef struct
{
#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 */
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
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
#define PI_CMD_I2CZ 92
+#define PI_CMD_WVCHA 93
+
#define PI_CMD_NOIB 99
/*DEF_E*/
#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
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
_PI_CMD_I2CZ =92
+_PI_CMD_WVCHA=93
+
# pigpio error numbers
_PI_INIT_FAILED =-1
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
[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"],
]
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
"""
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.
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
.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
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
For more information, please refer to <http://unlicense.org/>
*/
-/* PIGPIOD_IF_VERSION 15 */
+/* PIGPIOD_IF_VERSION 16 */
#include <stdio.h>
#include <stdlib.h>
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);}
#include "pigpio.h"
-#define PIGPIOD_IF_VERSION 15
+#define PIGPIOD_IF_VERSION 16
/*TEXT
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
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
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);
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
.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
.br
-.IP "\fBWVTX wid\fP - Transmit waveform once"
+.IP "\fBWVTX wid\fP - Transmits waveform once"
.IP "" 4
.br
.br
-.IP "\fBWVTXR wid\fP - Transmit waveform repeatedly"
+.IP "\fBWVTXR wid\fP - Transmits waveform repeatedly"
.IP "" 4
.br
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
*/
/*
-This version is for pigpio version 33+
+This version is for pigpio version 34+
*/
#include <stdio.h>
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");
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