This commit is contained in:
joan 2016-02-18 21:51:10 +00:00
parent f99f64f781
commit 89fca37587
11 changed files with 423 additions and 107 deletions

View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/ */
/* /*
This version is for pigpio version 39+ This version is for pigpio version 46+
*/ */
#include <stdio.h> #include <stdio.h>
@ -185,6 +185,7 @@ cmdInfo_t cmdInfo[]=
{PI_CMD_WVSM, "WVSM", 112, 2}, // gpioWaveGet*Micros {PI_CMD_WVSM, "WVSM", 112, 2}, // gpioWaveGet*Micros
{PI_CMD_WVSP, "WVSP", 112, 2}, // gpioWaveGet*Pulses {PI_CMD_WVSP, "WVSP", 112, 2}, // gpioWaveGet*Pulses
{PI_CMD_WVTX, "WVTX", 112, 2}, // gpioWaveTxSend {PI_CMD_WVTX, "WVTX", 112, 2}, // gpioWaveTxSend
{PI_CMD_WVTXM, "WVTXM", 121, 2}, // gpioWaveTxSend
{PI_CMD_WVTXR, "WVTXR", 112, 2}, // gpioWaveTxSend {PI_CMD_WVTXR, "WVTXR", 112, 2}, // gpioWaveTxSend
{PI_CMD_ADD , "ADD" , 111, 0}, {PI_CMD_ADD , "ADD" , 111, 0},
@ -345,6 +346,7 @@ WVSC 0,1,2 Wave get DMA control block stats\n\
WVSM 0,1,2 Wave get micros stats\n\ WVSM 0,1,2 Wave get micros stats\n\
WVSP 0,1,2 Wave get pulses stats\n\ WVSP 0,1,2 Wave get pulses stats\n\
WVTX wid Transmit wave as one-shot\n\ WVTX wid Transmit wave as one-shot\n\
WVTXM wid wmde Transmit wave using mode\n\
WVTXR wid Transmit wave repeatedly\n\ WVTXR wid Transmit wave repeatedly\n\
\n\ \n\
\n\ \n\
@ -682,7 +684,7 @@ int cmdParse(
break; break;
case 121: /* HC I2CRD I2CRR I2CRW I2CWB I2CWQ P PFS PRS case 121: /* HC I2CRD I2CRR I2CRW I2CWB I2CWQ P PFS PRS
PWM S SERVO SLR SLRI W WDOG WRITE PWM S SERVO SLR SLRI W WDOG WRITE WVTXM
Two positive parameters. Two positive parameters.
*/ */

View File

@ -1968,6 +1968,14 @@ Returns 0 if OK, otherwise PI_BAD_WAVE_ID.
.IP "" 4 .IP "" 4
This function transmits the waveform with id wave_id. The mode This function transmits the waveform with id wave_id. The mode
determines whether the waveform is sent once or cycles endlessly. determines whether the waveform is sent once or cycles endlessly.
The SYNC variants wait for the current waveform to reach the
end of a cycle or finish before starting the new waveform.
.br
.br
WARNING: bad things may happen if you delete the previous
waveform before it has been synced to the new waveform.
.br .br
@ -1981,7 +1989,9 @@ NOTE: Any hardware PWM started by \fBgpioHardwarePWM\fP will be cancelled.
.EX .EX
wave_id: >=0, as returned by \fBgpioWaveCreate\fP wave_id: >=0, as returned by \fBgpioWaveCreate\fP
.br .br
wave_mode: 0 (PI_WAVE_MODE_ONE_SHOT), 1 (PI_WAVE_MODE_REPEAT) wave_mode: PI_WAVE_MODE_ONE_SHOT, PI_WAVE_MODE_REPEAT,
.br
PI_WAVE_MODE_ONE_SHOT_SYNC, PI_WAVE_MODE_REPEAT_SYNC
.br .br
.EE .EE
@ -7540,8 +7550,10 @@ A number identifying a waveform created by \fBgpioWaveCreate\fP.
.br .br
.br .br
The mode of waveform transmission, whether it is sent once or cycles The mode determines if the waveform is sent once or cycles
repeatedly. repeatedly. The SYNC variants wait for the current waveform
to reach the end of a cycle or finish before starting the new
waveform.
.br .br
@ -7552,6 +7564,10 @@ PI_WAVE_MODE_ONE_SHOT 0
.br .br
PI_WAVE_MODE_REPEAT 1 PI_WAVE_MODE_REPEAT 1
.br .br
PI_WAVE_MODE_ONE_SHOT_SYNC 2
.br
PI_WAVE_MODE_REPEAT_SYNC 3
.br
.EE .EE
@ -7801,6 +7817,10 @@ A 16-bit word value.
#define PI_CMD_NOIB 99 #define PI_CMD_NOIB 99
.br .br
.br
#define PI_CMD_WVTXM 100
.br
.br .br
.EE .EE
@ -7877,7 +7897,7 @@ A 16-bit word value.
.br .br
#define PI_INITIALISED -32 // function called after gpioInitialise #define PI_INITIALISED -32 // function called after gpioInitialise
.br .br
#define PI_BAD_WAVE_MODE -33 // waveform mode not 0-1 #define PI_BAD_WAVE_MODE -33 // waveform mode not 0-3
.br .br
#define PI_BAD_CFG_INTERNAL -34 // bad parameter in gpioCfgInternals call #define PI_BAD_CFG_INTERNAL -34 // bad parameter in gpioCfgInternals call
.br .br

149
pigpio.c
View File

@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/> For more information, please refer to <http://unlicense.org/>
*/ */
/* pigpio version 45 */ /* pigpio version 46 */
/* include ------------------------------------------------------- */ /* include ------------------------------------------------------- */
@ -1133,6 +1133,9 @@ static int libInitialised = 0;
/* initialise every gpioInitialise */ /* initialise every gpioInitialise */
static struct timespec libStarted; static struct timespec libStarted;
static uint32_t reportedLevel = 0;
static int waveClockInited = 0; static int waveClockInited = 0;
static volatile gpioStats_t gpioStats; static volatile gpioStats_t gpioStats;
@ -1165,6 +1168,8 @@ static int waveOutBotOOL = PI_WAVE_COUNT_PAGES*OOL_PER_OPAGE;
static int waveOutTopOOL = NUM_WAVE_OOL; static int waveOutTopOOL = NUM_WAVE_OOL;
static int waveOutCount = 0; static int waveOutCount = 0;
static uint32_t *waveEndPtr = NULL;
static volatile uint32_t alertBits = 0; static volatile uint32_t alertBits = 0;
static volatile uint32_t monitorBits = 0; static volatile uint32_t monitorBits = 0;
static volatile uint32_t notifyBits = 0; static volatile uint32_t notifyBits = 0;
@ -2179,6 +2184,9 @@ static int myDoCommand(uint32_t *p, unsigned bufSize, char *buf)
case PI_CMD_WVTX: case PI_CMD_WVTX:
res = gpioWaveTxSend(p[1], PI_WAVE_MODE_ONE_SHOT); break; res = gpioWaveTxSend(p[1], PI_WAVE_MODE_ONE_SHOT); break;
case PI_CMD_WVTXM:
res = gpioWaveTxSend(p[1], p[2]); break;
case PI_CMD_WVTXR: case PI_CMD_WVTXR:
res = gpioWaveTxSend(p[1], PI_WAVE_MODE_REPEAT); break; res = gpioWaveTxSend(p[1], PI_WAVE_MODE_REPEAT); break;
@ -5253,9 +5261,8 @@ static void alertNoiseFilter(gpioSample_t *sample, int numSamples)
} }
} }
uint32_t _reportedLevel, _changedBits; static void alertEmit(
gpioSample_t *sample, int numSamples, uint32_t changedBits, uint32_t eTick)
static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
{ {
uint32_t oldLevel, newLevel; uint32_t oldLevel, newLevel;
int32_t diff; int32_t diff;
@ -5268,7 +5275,7 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
char fifo[32]; char fifo[32];
gpioReport_t report[MAX_REPORT]; gpioReport_t report[MAX_REPORT];
if (_changedBits) if (changedBits)
{ {
if (gpioGetSamples.func) if (gpioGetSamples.func)
{ {
@ -5286,9 +5293,9 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
/* call alert callbacks for each bit transition */ /* call alert callbacks for each bit transition */
if (_changedBits & alertBits) if (changedBits & alertBits)
{ {
oldLevel = (_reportedLevel & alertBits); oldLevel = (reportedLevel & alertBits);
for (d=0; d<numSamples; d++) for (d=0; d<numSamples; d++)
{ {
@ -5328,6 +5335,8 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
timeoutBits = 0; timeoutBits = 0;
if (wdogBits)
{
for (b=0; b<=PI_MAX_USER_GPIO; b++) for (b=0; b<=PI_MAX_USER_GPIO; b++)
{ {
if (gpioAlert[b].wdSteadyUs) if (gpioAlert[b].wdSteadyUs)
@ -5344,8 +5353,8 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
{ {
if (gpioAlert[b].ex) if (gpioAlert[b].ex)
{ {
(gpioAlert[b].func) (gpioAlert[b].func)(b, PI_TIMEOUT, eTick,
(b, PI_TIMEOUT, eTick, gpioAlert[b].userdata); gpioAlert[b].userdata);
} }
else else
{ {
@ -5355,12 +5364,12 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
} }
} }
} }
}
for (n=0; n<PI_NOTIFY_SLOTS; n++) for (n=0; n<PI_NOTIFY_SLOTS; n++)
{ {
if (gpioNotify[n].state == PI_NOTIFY_CLOSING) if (gpioNotify[n].state == PI_NOTIFY_CLOSING)
{ {
if (gpioNotify[n].pipe) if (gpioNotify[n].pipe)
{ {
DBG(DBG_INTERNAL, "close notify pipe %d", gpioNotify[n].fd); DBG(DBG_INTERNAL, "close notify pipe %d", gpioNotify[n].fd);
@ -5372,7 +5381,6 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
} }
gpioNotify[n].state = PI_NOTIFY_CLOSED; gpioNotify[n].state = PI_NOTIFY_CLOSED;
} }
else if (gpioNotify[n].state == PI_NOTIFY_RUNNING) else if (gpioNotify[n].state == PI_NOTIFY_RUNNING)
{ {
@ -5386,12 +5394,12 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
notification. notification.
bits is the set of notification bits bits is the set of notification bits
_changedBits is the set of changed bits changedBits is the set of changed bits
*/ */
if (_changedBits & bits) if (changedBits & bits)
{ {
oldLevel = _reportedLevel & bits; oldLevel = reportedLevel & bits;
for (d=0; d<numSamples; d++) for (d=0; d<numSamples; d++)
{ {
@ -5434,7 +5442,7 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
if (numSamples) if (numSamples)
newLevel = sample[numSamples-1].level; newLevel = sample[numSamples-1].level;
else else
newLevel = _reportedLevel; newLevel = reportedLevel;
report[emit].seqno = seqno; report[emit].seqno = seqno;
report[emit].flags = PI_NTFY_FLAGS_WDOG | report[emit].flags = PI_NTFY_FLAGS_WDOG |
@ -5455,7 +5463,7 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
if (numSamples) if (numSamples)
newLevel = sample[numSamples-1].level; newLevel = sample[numSamples-1].level;
else else
newLevel = _reportedLevel; newLevel = reportedLevel;
report[emit].seqno = seqno; report[emit].seqno = seqno;
report[emit].flags = PI_NTFY_FLAGS_ALIVE; report[emit].flags = PI_NTFY_FLAGS_ALIVE;
@ -5516,7 +5524,10 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
err/sizeof(gpioReport_t), max_emits); err/sizeof(gpioReport_t), max_emits);
} }
} }
else gpioStats.goodPipeWrite++; else
{
gpioStats.goodPipeWrite++;
}
emitted += max_emits; emitted += max_emits;
emit -= max_emits; emit -= max_emits;
@ -5554,7 +5565,10 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
err/sizeof(gpioReport_t), emit); err/sizeof(gpioReport_t), emit);
} }
} }
else gpioStats.goodPipeWrite++; else
{
gpioStats.goodPipeWrite++;
}
emitted += emit; emitted += emit;
emit = 0; emit = 0;
@ -5566,20 +5580,20 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
} }
} }
if (_changedBits & scriptBits) if (changedBits & scriptBits)
{ {
for (n=0; n<PI_MAX_SCRIPTS; n++) for (n=0; n<PI_MAX_SCRIPTS; n++)
{ {
if ((gpioScript[n].state == PI_SCRIPT_IN_USE) && if ((gpioScript[n].state == PI_SCRIPT_IN_USE) &&
(gpioScript[n].run_state == PI_SCRIPT_WAITING) && (gpioScript[n].run_state == PI_SCRIPT_WAITING) &&
(gpioScript[n].waitBits & _changedBits)) (gpioScript[n].waitBits & changedBits))
{ {
pthread_mutex_lock(&gpioScript[n].pthMutex); pthread_mutex_lock(&gpioScript[n].pthMutex);
if (gpioScript[n].run_state == PI_SCRIPT_WAITING) if (gpioScript[n].run_state == PI_SCRIPT_WAITING)
{ {
gpioScript[n].changedBits = gpioScript[n].changedBits =
gpioScript[n].waitBits & _changedBits; gpioScript[n].waitBits & changedBits;
pthread_cond_signal(&gpioScript[n].pthCond); pthread_cond_signal(&gpioScript[n].pthCond);
} }
@ -5588,7 +5602,7 @@ static void alertEmit(gpioSample_t *sample, int numSamples, uint32_t eTick)
} }
} }
if (numSamples) _reportedLevel = sample[numSamples-1].level; if (numSamples) reportedLevel = sample[numSamples-1].level;
} }
static void alertWdogCheck(gpioSample_t *sample, int numSamples) static void alertWdogCheck(gpioSample_t *sample, int numSamples)
@ -5629,10 +5643,11 @@ static void * pthAlertThread(void *x)
uint32_t oldLevel, newLevel, level; uint32_t oldLevel, newLevel, level;
uint32_t oldSlot, newSlot; uint32_t oldSlot, newSlot;
uint32_t expected, ft, sTick; uint32_t expected, ft, sTick;
uint32_t changedBits;
int32_t diff, minDiff, stickInited; int32_t diff, minDiff, stickInited;
int cycle, pulse; int cycle, pulse;
int numSamples, ticks, i; int numSamples, ticks, i;
int rp, compactedSamples, totalSamples; int rp, reports, totalSamples;
int stopped; int stopped;
int moreToDo; int moreToDo;
gpioSample_t sample[MAX_SAMPLE]; gpioSample_t sample[MAX_SAMPLE];
@ -5643,7 +5658,9 @@ static void * pthAlertThread(void *x)
spinWhileStarting(); spinWhileStarting();
_reportedLevel = gpioReg[GPLEV0]; reportedLevel = gpioReg[GPLEV0];
oldLevel = reportedLevel;
oldSlot = dmaCurrentSlot(dmaNowAtICB()); oldSlot = dmaCurrentSlot(dmaNowAtICB());
@ -5782,53 +5799,52 @@ static void * pthAlertThread(void *x)
/* Compact samples */ /* Compact samples */
_changedBits = 0; changedBits = 0;
oldLevel = _reportedLevel & monitorBits; oldLevel &= monitorBits;
reports = 0;
compactedSamples = 0;
totalSamples = 0; totalSamples = 0;
for (rp=0; rp<numSamples; rp++) for (rp=0; rp<numSamples; rp++)
{ {
level = sample[rp].level; newLevel = (sample[rp].level & monitorBits);
newLevel = (level & monitorBits);
if (newLevel != oldLevel) if (newLevel != oldLevel)
{ {
sample[compactedSamples].tick = sample[rp].tick; sample[reports].tick = sample[rp].tick;
sample[compactedSamples].level = level; sample[reports].level = sample[rp].level;
_changedBits |= (newLevel ^ oldLevel); changedBits |= (newLevel ^ oldLevel);
oldLevel = newLevel; oldLevel = newLevel;
compactedSamples++; reports++;
if (compactedSamples >= MAX_REPORT)
if (reports >= MAX_REPORT)
{ {
totalSamples += compactedSamples; totalSamples += reports;
/* Rebase watchdog timeouts */ /* Rebase watchdog timeouts */
if (wdogBits) alertWdogCheck(sample, compactedSamples); if (wdogBits) alertWdogCheck(sample, reports);
gpioStats.numSamples += compactedSamples; gpioStats.numSamples += reports;
alertEmit(sample, compactedSamples, sample[rp].tick); alertEmit(sample, reports, changedBits, sample[rp].tick);
compactedSamples = 0; changedBits = 0;
reports = 0;
} }
} }
} }
if (compactedSamples) if (reports)
{ {
totalSamples += compactedSamples; totalSamples += reports;
/* Rebase watchdog timeouts */ /* Rebase watchdog timeouts */
if (wdogBits) alertWdogCheck(sample, compactedSamples); if (wdogBits) alertWdogCheck(sample, reports);
gpioStats.numSamples += compactedSamples; gpioStats.numSamples += reports;
} }
alertEmit(sample, compactedSamples, sTick); alertEmit(sample, reports, changedBits, sTick);
if (totalSamples > gpioStats.maxSamples) if (totalSamples > gpioStats.maxSamples)
gpioStats.maxSamples = numSamples; gpioStats.maxSamples = numSamples;
@ -8346,6 +8362,8 @@ int gpioWaveClear(void)
waveOutCount = 0; waveOutCount = 0;
waveEndPtr = NULL;
return 0; return 0;
} }
@ -8818,7 +8836,7 @@ int gpioWaveTxSend(unsigned wave_id, unsigned wave_mode)
if ((wave_id >= waveOutCount) || waveInfo[wave_id].deleted) if ((wave_id >= waveOutCount) || waveInfo[wave_id].deleted)
SOFT_ERROR(PI_BAD_WAVE_ID, "bad wave id (%d)", wave_id); SOFT_ERROR(PI_BAD_WAVE_ID, "bad wave id (%d)", wave_id);
if (wave_mode > PI_WAVE_MODE_REPEAT) if (wave_mode > PI_WAVE_MODE_REPEAT_SYNC)
SOFT_ERROR(PI_BAD_WAVE_MODE, "bad wave mode (%d)", wave_mode); SOFT_ERROR(PI_BAD_WAVE_MODE, "bad wave mode (%d)", wave_mode);
if (!waveClockInited) if (!waveClockInited)
@ -8828,16 +8846,28 @@ int gpioWaveTxSend(unsigned wave_id, unsigned wave_mode)
waveClockInited = 1; waveClockInited = 1;
} }
dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
dmaOut[DMA_CONBLK_AD] = 0;
p = rawWaveCBAdr(waveInfo[wave_id].topCB); p = rawWaveCBAdr(waveInfo[wave_id].topCB);
if (wave_mode == PI_WAVE_MODE_ONE_SHOT) p->next = 0; if ((wave_mode & 1) == PI_WAVE_MODE_ONE_SHOT)
else p->next = waveCbPOadr(waveInfo[wave_id].botCB+1); p->next = 0;
else
p->next = waveCbPOadr(waveInfo[wave_id].botCB+1);
if (waveEndPtr && (wave_mode > PI_WAVE_MODE_REPEAT))
{
*waveEndPtr = waveCbPOadr(waveInfo[wave_id].botCB+1);
if (!dmaOut[DMA_CONBLK_AD])
{
initDMAgo((uint32_t *)dmaOut, waveCbPOadr(waveInfo[wave_id].botCB)); initDMAgo((uint32_t *)dmaOut, waveCbPOadr(waveInfo[wave_id].botCB));
}
}
else
{
initDMAgo((uint32_t *)dmaOut, waveCbPOadr(waveInfo[wave_id].botCB));
}
waveEndPtr = &p->next;
/* for compatability with the deprecated gpioWaveTxStart return the /* for compatability with the deprecated gpioWaveTxStart return the
number of cbs number of cbs
@ -9035,7 +9065,7 @@ int gpioWaveChain(char *buf, unsigned bufSize)
rawCbs_t *p; rawCbs_t *p;
int i, wid, cmd, loop, counters; int i, wid, cmd, loop, counters;
unsigned cycles; unsigned cycles;
uint32_t repeat, next; uint32_t repeat, next, *endPtr;
int stk_pos[10], stk_lev=0; int stk_pos[10], stk_lev=0;
cb = 0; cb = 0;
@ -9053,8 +9083,9 @@ int gpioWaveChain(char *buf, unsigned bufSize)
} }
dmaOut[DMA_CS] = DMA_CHANNEL_RESET; dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
dmaOut[DMA_CONBLK_AD] = 0; dmaOut[DMA_CONBLK_AD] = 0;
waveEndPtr = NULL;
endPtr = NULL;
/* add delay cb at start of DMA */ /* add delay cb at start of DMA */
@ -9242,6 +9273,7 @@ int gpioWaveChain(char *buf, unsigned bufSize)
p->dst = (uint32_t) (&dmaOBus[0]->periphData); p->dst = (uint32_t) (&dmaOBus[0]->periphData);
p->length = 4; p->length = 4;
p->next = waveCbPOadr(chainGetCB(loop)); p->next = waveCbPOadr(chainGetCB(loop));
endPtr = &p->next;
} }
else else
SOFT_ERROR(PI_BAD_CHAIN_CMD, SOFT_ERROR(PI_BAD_CHAIN_CMD,
@ -9290,8 +9322,12 @@ int gpioWaveChain(char *buf, unsigned bufSize)
p->length = 4; p->length = 4;
p->next = 0; p->next = 0;
if (!endPtr) endPtr = &p->next;
initDMAgo((uint32_t *)dmaOut, waveCbPOadr(chainGetCB(0))); initDMAgo((uint32_t *)dmaOut, waveCbPOadr(chainGetCB(0)));
waveEndPtr = endPtr;
return 0; return 0;
} }
@ -9318,9 +9354,10 @@ int gpioWaveTxStop(void)
CHECK_INITED; CHECK_INITED;
dmaOut[DMA_CS] = DMA_CHANNEL_RESET; dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
dmaOut[DMA_CONBLK_AD] = 0; dmaOut[DMA_CONBLK_AD] = 0;
waveEndPtr = NULL;
return 0; return 0;
} }

View File

@ -31,7 +31,7 @@ For more information, please refer to <http://unlicense.org/>
#include <stdint.h> #include <stdint.h>
#include <pthread.h> #include <pthread.h>
#define PIGPIO_VERSION 45 #define PIGPIO_VERSION 46
/*TEXT /*TEXT
@ -601,6 +601,8 @@ typedef void *(gpioThreadFunc_t) (void *);
#define PI_WAVE_MODE_ONE_SHOT 0 #define PI_WAVE_MODE_ONE_SHOT 0
#define PI_WAVE_MODE_REPEAT 1 #define PI_WAVE_MODE_REPEAT 1
#define PI_WAVE_MODE_ONE_SHOT_SYNC 2
#define PI_WAVE_MODE_REPEAT_SYNC 3
/* I2C, SPI, SER */ /* I2C, SPI, SER */
@ -1748,12 +1750,18 @@ int gpioWaveTxSend(unsigned wave_id, unsigned wave_mode);
/*D /*D
This function transmits the waveform with id wave_id. The mode This function transmits the waveform with id wave_id. The mode
determines whether the waveform is sent once or cycles endlessly. determines whether the waveform is sent once or cycles endlessly.
The SYNC variants wait for the current waveform to reach the
end of a cycle or finish before starting the new waveform.
WARNING: bad things may happen if you delete the previous
waveform before it has been synced to the new waveform.
NOTE: Any hardware PWM started by [*gpioHardwarePWM*] will be cancelled. NOTE: Any hardware PWM started by [*gpioHardwarePWM*] will be cancelled.
. . . .
wave_id: >=0, as returned by [*gpioWaveCreate*] wave_id: >=0, as returned by [*gpioWaveCreate*]
wave_mode: 0 (PI_WAVE_MODE_ONE_SHOT), 1 (PI_WAVE_MODE_REPEAT) wave_mode: PI_WAVE_MODE_ONE_SHOT, PI_WAVE_MODE_REPEAT,
PI_WAVE_MODE_ONE_SHOT_SYNC, PI_WAVE_MODE_REPEAT_SYNC
. . . .
Returns the number of DMA control blocks in the waveform if OK, Returns the number of DMA control blocks in the waveform if OK,
@ -4780,12 +4788,16 @@ A number identifying a waveform created by [*gpioWaveCreate*].
wave_mode:: wave_mode::
The mode of waveform transmission, whether it is sent once or cycles The mode determines if the waveform is sent once or cycles
repeatedly. repeatedly. The SYNC variants wait for the current waveform
to reach the end of a cycle or finish before starting the new
waveform.
. . . .
PI_WAVE_MODE_ONE_SHOT 0 PI_WAVE_MODE_ONE_SHOT 0
PI_WAVE_MODE_REPEAT 1 PI_WAVE_MODE_REPEAT 1
PI_WAVE_MODE_ONE_SHOT_SYNC 2
PI_WAVE_MODE_REPEAT_SYNC 3
. . . .
wVal::0-65535 (Hex 0x0-0xFFFF, Octal 0-0177777) wVal::0-65535 (Hex 0x0-0xFFFF, Octal 0-0177777)
@ -4910,6 +4922,8 @@ PARAMS*/
#define PI_CMD_NOIB 99 #define PI_CMD_NOIB 99
#define PI_CMD_WVTXM 100
/*DEF_E*/ /*DEF_E*/
/* /*
@ -5005,7 +5019,7 @@ after this command is issued.
#define PI_BAD_SECO_CHANNEL -30 // DMA secondary channel not 0-6 #define PI_BAD_SECO_CHANNEL -30 // DMA secondary channel not 0-6
#define PI_NOT_INITIALISED -31 // function called before gpioInitialise #define PI_NOT_INITIALISED -31 // function called before gpioInitialise
#define PI_INITIALISED -32 // function called after gpioInitialise #define PI_INITIALISED -32 // function called after gpioInitialise
#define PI_BAD_WAVE_MODE -33 // waveform mode not 0-1 #define PI_BAD_WAVE_MODE -33 // waveform mode not 0-3
#define PI_BAD_CFG_INTERNAL -34 // bad parameter in gpioCfgInternals call #define PI_BAD_CFG_INTERNAL -34 // bad parameter in gpioCfgInternals call
#define PI_BAD_WAVE_BAUD -35 // baud rate not 50-250K(RX)/50-1M(TX) #define PI_BAD_WAVE_BAUD -35 // baud rate not 50-250K(RX)/50-1M(TX)
#define PI_TOO_MANY_PULSES -36 // waveform has too many pulses #define PI_TOO_MANY_PULSES -36 // waveform has too many pulses

View File

@ -180,6 +180,7 @@ wave_delete Deletes one or more waveforms
wave_send_once Transmits a waveform once wave_send_once Transmits a waveform once
wave_send_repeat Transmits a waveform repeatedly wave_send_repeat Transmits a waveform repeatedly
wave_send_using_mode Transmits a waveform in the chosen mode
wave_chain Transmits a chain of waveforms wave_chain Transmits a chain of waveforms
@ -268,7 +269,7 @@ import threading
import os import os
import atexit import atexit
VERSION = "1.26" VERSION = "1.27"
exceptions = True exceptions = True
@ -321,6 +322,13 @@ NTFY_FLAGS_ALIVE = (1 << 6)
NTFY_FLAGS_WDOG = (1 << 5) NTFY_FLAGS_WDOG = (1 << 5)
NTFY_FLAGS_GPIO = 31 NTFY_FLAGS_GPIO = 31
# wave modes
WAVE_MODE_ONE_SHOT =0
WAVE_MODE_REPEAT =1
WAVE_MODE_ONE_SHOT_SYNC=2
WAVE_MODE_REPEAT_SYNC =3
# pigpio command numbers # pigpio command numbers
_PI_CMD_MODES= 0 _PI_CMD_MODES= 0
@ -445,6 +453,8 @@ _PI_CMD_CSI =96
_PI_CMD_FG =97 _PI_CMD_FG =97
_PI_CMD_FN =98 _PI_CMD_FN =98
_PI_CMD_WVTXM=100
# pigpio error numbers # pigpio error numbers
_PI_INIT_FAILED =-1 _PI_INIT_FAILED =-1
@ -1995,6 +2005,40 @@ class pi():
""" """
return _u2i(_pigpio_command(self.sl, _PI_CMD_WVTXR, wave_id, 0)) return _u2i(_pigpio_command(self.sl, _PI_CMD_WVTXR, wave_id, 0))
def wave_send_using_mode(self, wave_id, mode):
"""
Transmits the waveform with id wave_id using mode mode.
wave_id:= >=0 (as returned by a prior call to [*wave_create*]).
mode:= WAVE_MODE_ONE_SHOT, WAVE_MODE_REPEAT,
WAVE_MODE_ONE_SHOT_SYNC, or WAVE_MODE_REPEAT_SYNC.
WAVE_MODE_ONE_SHOT: same as [*wave_send_once*].
WAVE_MODE_REPEAT same as [*wave_send_repeat*].
WAVE_MODE_ONE_SHOT_SYNC same as [*wave_send_once*] but tries
to sync with the previous waveform.
WAVE_MODE_REPEAT_SYNC same as [*wave_send_repeat*] but tries
to sync with the previous waveform.
WARNING: bad things may happen if you delete the previous
waveform before it has been synced to the new waveform.
NOTE: Any hardware PWM started by [*hardware_PWM*] will
be cancelled.
wave_id:= >=0 (as returned by a prior call to [*wave_create*]).
Returns the number of DMA control blocks used in the waveform.
...
cbs = pi.wave_send_using_mode(wid, WAVE_MODE_REPEAT_SYNC)
...
"""
return _u2i(_pigpio_command(self.sl, _PI_CMD_WVTXM, wave_id, mode))
def wave_tx_busy(self): def wave_tx_busy(self):
""" """
Returns 1 if a waveform is currently being transmitted, Returns 1 if a waveform is currently being transmitted,
@ -4025,7 +4069,10 @@ def xref():
SET = 1 SET = 1
TIMEOUT = 2 # only returned for a watchdog timeout TIMEOUT = 2 # only returned for a watchdog timeout
mode: 0-7 mode:
1.The operational mode of a gpio, normally INPUT or OUTPUT.
ALT0 = 4 ALT0 = 4
ALT1 = 5 ALT1 = 5
ALT2 = 6 ALT2 = 6
@ -4035,6 +4082,13 @@ def xref():
INPUT = 0 INPUT = 0
OUTPUT = 1 OUTPUT = 1
2. The mode of waveform transmission.
WAVE_MODE_ONE_SHOT = 0
WAVE_MODE_REPEAT = 1
WAVE_MODE_ONE_SHOT_SYNC = 2
WAVE_MODE_REPEAT_SYNC = 3
offset: 0- offset: 0-
The offset wave data starts from the beginning of the waveform The offset wave data starts from the beginning of the waveform
being currently defined. being currently defined.

View File

@ -1093,8 +1093,8 @@ Sets a glitch filter on a gpio.
.br .br
Level changes on the gpio are not reported unless the level Level changes on the gpio are not reported unless the level
has been stable for at least \fBsteady\fP microseconds. The has been stable for at least \fBsteady\fP microseconds. The
level is then reported. Level changes of less than \fBsteady\fP level is then reported. Level changes of less than
microseconds are ignored. \fBsteady\fP microseconds are ignored.
.br .br
@ -1398,8 +1398,8 @@ Frequencies above 30MHz are unlikely to work.
.br .br
.br .br
NOTE: Any waveform started by \fBwave_send_once\fP, \fBwave_send_repeat\fP, NOTE: Any waveform started by \fBwave_send_*\fP or \fBwave_chain\fP
or \fBwave_chain\fP will be cancelled. will be cancelled.
.br .br
@ -1943,6 +1943,65 @@ wave_id: >=0, as returned by \fBwave_create\fP.
Returns the number of DMA control blocks in the waveform if OK, Returns the number of DMA control blocks in the waveform if OK,
otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE. otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
.IP "\fBint wave_send_using_mode(int pi, unsigned wave_id, unsigned mode)\fP"
.IP "" 4
Transmits the waveform with id wave_id using mode mode.
.br
.br
.EX
pi: 0- (as returned by \fBpigpio_start\fP).
.br
wave_id: >=0, as returned by \fBwave_create\fP.
.br
mode: PI_WAVE_MODE_ONE_SHOT, PI_WAVE_MODE_REPEAT,
.br
PI_WAVE_MODE_ONE_SHOT_SYNC, or PI_WAVE_MODE_REPEAT_SYNC.
.br
.EE
.br
.br
PI_WAVE_MODE_ONE_SHOT: same as \fBwave_send_once\fP.
.br
.br
PI_WAVE_MODE_REPEAT same as \fBwave_send_repeat\fP.
.br
.br
PI_WAVE_MODE_ONE_SHOT_SYNC same as \fBwave_send_once\fP but tries
to sync with the previous waveform.
.br
.br
PI_WAVE_MODE_REPEAT_SYNC same as \fBwave_send_repeat\fP but tries
to sync with the previous waveform.
.br
.br
WARNING: bad things may happen if you delete the previous
waveform before it has been synced to the new waveform.
.br
.br
NOTE: Any hardware PWM started by \fBhardware_PWM\fP will be cancelled.
.br
.br
Returns the number of DMA control blocks in the waveform if OK,
otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
.IP "\fBint wave_chain(int pi, char *buf, unsigned bufSize)\fP" .IP "\fBint wave_chain(int pi, char *buf, unsigned bufSize)\fP"
.IP "" 4 .IP "" 4
This function transmits a chain of waveforms. This function transmits a chain of waveforms.
@ -4721,8 +4780,8 @@ PI_TIMEOUT 2
.br .br
.IP "\fBmode\fP: 0-7" 0 .IP "\fBmode\fP" 0
The operational mode of a gpio, normally INPUT or OUTPUT. 1. The operational mode of a gpio, normally INPUT or OUTPUT.
.br .br
@ -4750,6 +4809,27 @@ PI_ALT5 2
.br .br
.br
2. The mode of waveform transmission.
.br
.br
.EX
PI_WAVE_MODE_ONE_SHOT 0
.br
PI_WAVE_MODE_REPEAT 1
.br
PI_WAVE_MODE_ONE_SHOT_SYNC 2
.br
PI_WAVE_MODE_REPEAT_SYNC 3
.br
.EE
.br
.br .br
.IP "\fBnumBytes\fP" 0 .IP "\fBnumBytes\fP" 0

View File

@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/> For more information, please refer to <http://unlicense.org/>
*/ */
/* PIGPIOD_IF2_VERSION 2 */ /* PIGPIOD_IF2_VERSION 3 */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -852,6 +852,9 @@ int wave_send_once(int pi, unsigned wave_id)
int wave_send_repeat(int pi, unsigned wave_id) int wave_send_repeat(int pi, unsigned wave_id)
{return pigpio_command(pi, PI_CMD_WVTXR, wave_id, 0, 1);} {return pigpio_command(pi, PI_CMD_WVTXR, wave_id, 0, 1);}
int wave_send_using_mode(int pi, unsigned wave_id, unsigned mode)
{return pigpio_command(pi, PI_CMD_WVTXM, wave_id, mode, 1);}
int wave_chain(int pi, char *buf, unsigned bufSize) int wave_chain(int pi, char *buf, unsigned bufSize)
{ {
gpioExtent_t ext[1]; gpioExtent_t ext[1];

View File

@ -30,7 +30,7 @@ For more information, please refer to <http://unlicense.org/>
#include "pigpio.h" #include "pigpio.h"
#define PIGPIOD_IF2_VERSION 2 #define PIGPIOD_IF2_VERSION 3
/*TEXT /*TEXT
@ -190,6 +190,7 @@ wave_delete Deletes one or more waveforms
wave_send_once Transmits a waveform once wave_send_once Transmits a waveform once
wave_send_repeat Transmits a waveform repeatedly wave_send_repeat Transmits a waveform repeatedly
wave_send_using_mode Transmits a waveform in the chosen mode
wave_chain Transmits a chain of waveforms wave_chain Transmits a chain of waveforms
@ -825,8 +826,8 @@ Sets a glitch filter on a gpio.
Level changes on the gpio are not reported unless the level Level changes on the gpio are not reported unless the level
has been stable for at least [*steady*] microseconds. The has been stable for at least [*steady*] microseconds. The
level is then reported. Level changes of less than [*steady*] level is then reported. Level changes of less than
microseconds are ignored. [*steady*] microseconds are ignored.
. . . .
pi: 0- (as returned by [*pigpio_start*]). pi: 0- (as returned by [*pigpio_start*]).
@ -1006,8 +1007,8 @@ int hardware_PWM(int pi, unsigned gpio, unsigned PWMfreq, uint32_t PWMduty);
Starts hardware PWM on a gpio at the specified frequency and dutycycle. Starts hardware PWM on a gpio at the specified frequency and dutycycle.
Frequencies above 30MHz are unlikely to work. Frequencies above 30MHz are unlikely to work.
NOTE: Any waveform started by [*wave_send_once*], [*wave_send_repeat*], NOTE: Any waveform started by [*wave_send_**] or [*wave_chain*]
or [*wave_chain*] will be cancelled. will be cancelled.
This function is only valid if the pigpio main clock is PCM. The 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 main clock defaults to PCM but may be overridden when the pigpio
@ -1276,6 +1277,7 @@ Wave ids are allocated in order, 0, 1, 2, etc.
Returns 0 if OK, otherwise PI_BAD_WAVE_ID. Returns 0 if OK, otherwise PI_BAD_WAVE_ID.
D*/ D*/
/*F*/ /*F*/
int wave_send_once(int pi, unsigned wave_id); int wave_send_once(int pi, unsigned wave_id);
/*D /*D
@ -1293,6 +1295,7 @@ Returns the number of DMA control blocks in the waveform if OK,
otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE. otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
D*/ D*/
/*F*/ /*F*/
int wave_send_repeat(int pi, unsigned wave_id); int wave_send_repeat(int pi, unsigned wave_id);
/*D /*D
@ -1311,6 +1314,38 @@ Returns the number of DMA control blocks in the waveform if OK,
otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE. otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
D*/ D*/
/*F*/
int wave_send_using_mode(int pi, unsigned wave_id, unsigned mode);
/*D
Transmits the waveform with id wave_id using mode mode.
. .
pi: 0- (as returned by [*pigpio_start*]).
wave_id: >=0, as returned by [*wave_create*].
mode: PI_WAVE_MODE_ONE_SHOT, PI_WAVE_MODE_REPEAT,
PI_WAVE_MODE_ONE_SHOT_SYNC, or PI_WAVE_MODE_REPEAT_SYNC.
. .
PI_WAVE_MODE_ONE_SHOT: same as [*wave_send_once*].
PI_WAVE_MODE_REPEAT same as [*wave_send_repeat*].
PI_WAVE_MODE_ONE_SHOT_SYNC same as [*wave_send_once*] but tries
to sync with the previous waveform.
PI_WAVE_MODE_REPEAT_SYNC same as [*wave_send_repeat*] but tries
to sync with the previous waveform.
WARNING: bad things may happen if you delete the previous
waveform before it has been synced to the new waveform.
NOTE: Any hardware PWM started by [*hardware_PWM*] will be cancelled.
Returns the number of DMA control blocks in the waveform if OK,
otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
D*/
/*F*/ /*F*/
int wave_chain(int pi, char *buf, unsigned bufSize); int wave_chain(int pi, char *buf, unsigned bufSize);
/*D /*D
@ -2858,8 +2893,8 @@ reported as PI_TIMEOUT. See [*set_watchdog*].
PI_TIMEOUT 2 PI_TIMEOUT 2
. . . .
mode::0-7 mode::
The operational mode of a gpio, normally INPUT or OUTPUT. 1. The operational mode of a gpio, normally INPUT or OUTPUT.
. . . .
PI_INPUT 0 PI_INPUT 0
@ -2872,6 +2907,15 @@ PI_ALT4 3
PI_ALT5 2 PI_ALT5 2
. . . .
2. The mode of waveform transmission.
. .
PI_WAVE_MODE_ONE_SHOT 0
PI_WAVE_MODE_REPEAT 1
PI_WAVE_MODE_ONE_SHOT_SYNC 2
PI_WAVE_MODE_REPEAT_SYNC 3
. .
numBytes:: numBytes::
The number of bytes used to store characters in a string. Depending The number of bytes used to store characters in a string. Depending
on the number of bits per character there may be 1, 2, or 4 bytes on the number of bits per character there may be 1, 2, or 4 bytes
@ -2997,7 +3041,7 @@ A SPI channel, 0-2.
spi_flags:: spi_flags::
See [*spi_open*]. See [*spi_open*].
steady :: 0-300000 steady:: 0-300000
The number of microseconds level changes must be stable for The number of microseconds level changes must be stable for
before reporting the level changed ([*set_glitch_filter*]) or triggering before reporting the level changed ([*set_glitch_filter*]) or triggering

62
pigs.1
View File

@ -3700,6 +3700,51 @@ ERROR: non existent wave id
.br .br
.IP "\fBWVTXM wid wmde\fP - Transmits waveform using mode"
.IP "" 4
.br
This command transmits the waveform with id \fBwid\fP using mode \fBwmde\fP.
.br
The mode may be send once (0), send repeatedly (1), send once but
first sync with previous wave (2), or send repeatedly but first
sync with previous wave (3).
.br
WARNING: bad things may happen if you delete the previous
waveform before it has been synced to the new waveform.
.br
NOTE: Any hardware PWM started by \fBHP\fP will be cancelled.
.br
Upon success the number of DMA control blocks in the waveform is returned.
On error a negative status code will be returned.
.br
\fBExample\fP
.br
.EX
$ pigs wvtxm 1 3
.br
75
.br
.br
$ pigs wvtxm 2 0
.br
-66
.br
ERROR: non existent wave id
.br
.EE
.br
.IP "\fBWVTXR wid\fP - Transmits waveform repeatedly" .IP "\fBWVTXR wid\fP - Transmits waveform repeatedly"
.IP "" 4 .IP "" 4
@ -4078,6 +4123,21 @@ When a waveform is created it is given an id (0, 1, 2, ...).
.br .br
.IP "\fBwmde\fP - mode (0-3)" 0
The command expects a wave transmission mode.
.br
0 = send once
.br
1 = send repeatedly
.br
2 = send once but first sync with previous wave
.br
3 = send repeatedly but first sync with previous wave
.br
.br
.IP "\fBws\fP - wave stats sucommand (0-2)" 0 .IP "\fBws\fP - wave stats sucommand (0-2)" 0
The command expects a subcommand. The command expects a subcommand.
@ -4350,6 +4410,8 @@ The WAIT command parameter is a bit-mask with 1 set for gpios of interest.
The SYS script receives two unsigned parameters: the accumulator A and The SYS script receives two unsigned parameters: the accumulator A and
the current gpio levels. the current gpio levels.
.br
.SH SEE ALSO .SH SEE ALSO
pigpiod(1), pig2vcd(1), pigpio(3), pigpiod_if(3), pigpiod_if2(3) pigpiod(1), pig2vcd(1), pigpio(3), pigpiod_if(3), pigpiod_if2(3)

View File

@ -3,7 +3,7 @@
from distutils.core import setup from distutils.core import setup
setup(name='pigpio', setup(name='pigpio',
version='1.26', version='1.27',
author='joan', author='joan',
author_email='joan@abyz.co.uk', author_email='joan@abyz.co.uk',
maintainer='joan', maintainer='joan',

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 if [[ $s = "" ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi
s=$(pigs h) s=$(pigs h)
if [[ ${#s} = 4502 ]]; then echo "HELP ok"; else echo "HELP fail (${#s})"; fi if [[ ${#s} = 4544 ]]; then echo "HELP ok"; else echo "HELP fail (${#s})"; fi
s=$(pigs hwver) s=$(pigs hwver)
if [[ $s -ne 0 ]]; then echo "HWVER ok"; else echo "HWVER fail ($s)"; fi if [[ $s -ne 0 ]]; then echo "HWVER ok"; else echo "HWVER fail ($s)"; fi