This commit is contained in:
joan 2015-06-18 11:46:46 +01:00
parent 4ffd02b8fc
commit 927f3544f1
15 changed files with 1048 additions and 249 deletions

View File

@ -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

View File

@ -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

11
README
View File

@ -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

View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 33+
This version is for pigpio version 34+
*/
#include <stdio.h>
@ -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;

150
pigpio.3
View File

@ -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

363
pigpio.c
View File

@ -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; 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;
@ -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; 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++;
}
}
/* ----------------------------------------------------------------------- */
@ -2920,12 +2950,6 @@ int rawWaveAddGeneric(unsigned numIn1, rawWave_t *in1)
--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;
@ -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<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, waveCbPOadr(firstCB));
}
initDMAgo((uint32_t *)dmaOut, (uint32_t)dmaOBus[0]);
return cb;
return numCBs;
}
@ -8380,15 +8408,15 @@ int gpioWaveTxSend(unsigned wave_id, unsigned wave_mode)
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
@ -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<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)

View File

@ -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

257
pigpio.py
View File

@ -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

View File

@ -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

View File

@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
*/
/* PIGPIOD_IF_VERSION 15 */
/* PIGPIOD_IF_VERSION 16 */
#include <stdio.h>
#include <stdlib.h>
@ -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);}

View File

@ -30,7 +30,7 @@ For more information, please refer to <http://unlicense.org/>
#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);

103
pigs.1
View File

@ -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

2
pigs.c
View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 33+
This version is for pigpio version 34+
*/
#include <stdio.h>

View File

@ -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");

2
x_pigs
View File

@ -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