*/
/*
-This version is for pigpio version 38+
+This version is for pigpio version 39+
*/
#include <stdio.h>
{PI_CMD_CGI, "CGI", 101, 4}, // gpioCfgGetInternals
{PI_CMD_CSI, "CSI", 111, 1}, // gpioCfgSetInternals
+ {PI_CMD_FG, "FG", 121, 0}, // gpioGlitchFilter
+ {PI_CMD_FN, "FN", 131, 0}, // gpioNoiseFilter
+
{PI_CMD_GDC, "GDC", 112, 2}, // gpioGetPWMdutycycle
{PI_CMD_GPW, "GPW", 112, 2}, // gpioGetServoPulsewidth
CGI Configuration get internals\n\
CSI v Configuration set internals\n\
\n\
+FG g steady Set glitch filter on gpio\n\
+FN g steady active | Set noise filter on gpio\n\
+\n\
GDC g Get PWM dutycycle for gpio\n\
GPW g Get servo pulsewidth for gpio\n\
\n\
{PI_BAD_EDGE , "bad ISR edge, not 1, 1, or 2"},
{PI_BAD_ISR_INIT , "bad ISR initialisation"},
{PI_BAD_FOREVER , "loop forever must be last chain command"},
+ {PI_BAD_FILTER , "bad filter parameter"},
};
.EE
+.IP "\fBint gpioNoiseFilter(unsigned user_gpio, unsigned steady, unsigned active)\fP"
+.IP "" 4
+Sets a noise filter on a gpio.
+
+.br
+
+.br
+Level changes on the gpio are ignored until a level which has
+been stable for \fBsteady\fP microseconds is detected. Level changes
+on the gpio are then reported for \fBactive\fP microseconds after
+which the process repeats.
+
+.br
+
+.br
+
+.EX
+user_gpio: 0-31
+.br
+ steady: 0-300000
+.br
+ active: 0-1000000
+.br
+
+.EE
+
+.br
+
+.br
+Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
+
+.br
+
+.br
+Note, level changes before and after the active period may
+be reported. Your software must be designed to cope with
+such reports.
+
+.IP "\fBint gpioGlitchFilter(unsigned user_gpio, unsigned steady)\fP"
+.IP "" 4
+Sets a glitch filter on a gpio.
+
+.br
+
+.br
+Level changes on the gpio are not reported unless the level
+has been stable for at least \fBsteady\fP microseconds. The
+level is then reported. Level changes of less than \fBsteady\fP
+microseconds are ignored.
+
+.br
+
+.br
+
+.EX
+user_gpio: 0-31
+.br
+ steady: 0-300000
+.br
+
+.EE
+
+.br
+
+.br
+Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
+
+.br
+
+.br
+Note, each (stable) edge will be timestamped \fBsteady\fP microseconds
+after it was first detected.
+
.IP "\fBint gpioSetGetSamplesFunc(gpioGetSamplesFunc_t f, uint32_t bits)\fP"
.IP "" 4
Registers a function to be called (a callback) every millisecond
.br
+.IP "\fBactive\fP: 0-1000000" 0
+
+.br
+
+.br
+The number of microseconds level changes are reported for once
+a noise filter has been triggered (by \fBsteady\fP microseconds of
+a stable level).
+
+.br
+
+.br
+
.IP "\fB*arg\fP" 0
.br
.br
+.IP "\fBsteady\fP: 0-300000" 0
+
+.br
+
+.br
+The number of microseconds level changes must be stable for
+before reporting the level changed (\fBgpioGlitchFilter\fP) or triggering
+the active part of a noise filter (\fBgpioNoiseFilter\fP).
+
+.br
+
+.br
+
.IP "\fBstop_bits\fP: 2-8" 0
The number of (half) stop bits to be used when adding serial data
to a waveform.
#define PI_CMD_CSI 96
.br
+.br
+#define PI_CMD_FG 97
+.br
+#define PI_CMD_FN 98
+.br
+
.br
#define PI_CMD_NOIB 99
.br
.br
#define PI_BAD_FOREVER -124 // loop forever must be last chain command
.br
+#define PI_BAD_FILTER -125 // bad filter parameter
+.br
.br
#define PI_PIGIF_ERR_0 -2000
For more information, please refer to <http://unlicense.org/>
*/
-/* pigpio version 38 */
+/* pigpio version 39 */
/* include ------------------------------------------------------- */
#define PI_WF_MICROS 1
-#define DATUMS 2000
+#define DATUMS 4000
#define DEFAULT_PWM_IDX 5
callbk_t func;
unsigned ex;
void *userdata;
- int timeout;
- uint32_t tick;
+ uint32_t wdTick;
+ uint32_t fnTick;
+ uint32_t fnTick2;
+ uint32_t fnLBitV;
+ int wdSteadyUs;
+ int fnSteadyUs;
+ int fnActiveUs;
+ uint32_t fgTick;
+ uint32_t fgDebounceUs;
+ uint32_t fgRBitV;
+ uint32_t fgLBitV;
} gpioAlert_t;
typedef struct
static volatile uint32_t monitorBits = 0;
static volatile uint32_t notifyBits = 0;
static volatile uint32_t scriptBits = 0;
+static volatile uint32_t filterBits = 0;
static volatile int runState = PI_STARTING;
case PI_CMD_CSI: res = gpioCfgSetInternals(p[1]); break;
+ case PI_CMD_FG:
+ res = gpioGlitchFilter(p[1], p[2]);
+ break;
+
+ case PI_CMD_FN:
+ memcpy(&p[4], buf, 4);
+ res = gpioNoiseFilter(p[1], p[2], p[4]);
+ break;
+
case PI_CMD_GDC: res = gpioGetPWMdutycycle(p[1]); break;
case PI_CMD_GPW: res = gpioGetServoPulsewidth(p[1]); break;
}
}
-unsigned alert_delays[]={
- 1000, 1068, 1145, 1235,
- 1339, 1463, 1613, 1796,
- 2027, 2326, 2727, 3297,
- 4167, 5660, 8823, 20000};
+unsigned alert_delays[]=
+{
+ 1000, 1034, 1071, 1111, 1154, 1200, 1250, 1304,
+ 1364, 1429, 1500, 1579, 1667, 1765, 1875, 2000
+};
/* ======================================================================= */
+static void alertGlitchFilter(int numSamples)
+{
+ int i, j, diff;
+ uint32_t DebounceUs, Tick, RBitV, LBitV;
+ uint32_t bit, bitV;
+
+ if (!numSamples) return;
+
+ for (i=0; i<=PI_MAX_USER_GPIO; i++)
+ {
+ bit = (1<<i);
+
+ if (monitorBits & bit)
+ {
+ DebounceUs = gpioAlert[i].fgDebounceUs;
+
+ if (DebounceUs)
+ {
+ RBitV = gpioAlert[i].fgRBitV;
+ LBitV = gpioAlert[i].fgLBitV;
+ Tick = gpioAlert[i].fgTick;
+
+ for (j=0; j<numSamples; j++)
+ {
+ bitV = gpioSample[j].level & bit;
+
+ if (bitV ^ LBitV)
+ {
+ /* Difference between level and last level.
+ Restart debounce timer. */
+
+ Tick = gpioSample[j].tick;
+ LBitV = bitV;
+ }
+
+ if (bitV ^ RBitV)
+ {
+ /* Difference between level and reported level. */
+
+ diff = gpioSample[j].tick - Tick;
+ if (diff >= DebounceUs)
+ {
+ /* Level steady for debounce period. */
+
+ RBitV = bitV;
+ }
+ else
+ {
+ /* Keep reporting old level. */
+
+ gpioSample[j].level ^= bit;
+ }
+ }
+ }
+
+ gpioAlert[i].fgRBitV = RBitV;
+ gpioAlert[i].fgLBitV = LBitV;
+ gpioAlert[i].fgTick = Tick;
+ }
+ }
+ }
+}
+
+static void alertActivityFilter(int numSamples)
+{
+ int i, j, diff;
+ uint32_t LBitV;
+ uint32_t bit;
+ uint32_t firstTick, nowTick, lastTick;
+
+ if (!numSamples) return;
+
+ firstTick = gpioSample[0].tick;
+ lastTick = gpioSample[numSamples-1].tick;
+
+ for (i=0; i<=PI_MAX_USER_GPIO; i++)
+ {
+ bit = (1<<i);
+
+ if ((monitorBits & bit) &&
+ (gpioAlert[i].wdSteadyUs || gpioAlert[i].fnSteadyUs))
+ {
+ if (gpioAlert[i].fnSteadyUs)
+ {
+ diff = firstTick - gpioAlert[i].fnTick2;
+
+ if (diff >= 0)
+ {
+ /* Stop reporting gpio changes */
+ filterBits |= bit;
+ }
+ }
+
+ LBitV = gpioAlert[i].fnLBitV;
+
+ for (j=0; j<numSamples; j++)
+ {
+ if ((gpioSample[j].level & bit) != LBitV)
+ {
+ nowTick = gpioSample[j].tick;
+
+ if (gpioAlert[i].fnSteadyUs)
+ {
+ diff = nowTick - gpioAlert[i].fnTick;
+
+ if (diff >= gpioAlert[i].fnSteadyUs)
+ {
+ /* Start reporting gpio changes */
+ filterBits &= (~bit);
+ gpioAlert[i].fnTick2 =
+ nowTick + gpioAlert[i].fnActiveUs;
+ }
+ }
+
+ LBitV = gpioSample[j].level & bit;
+
+ gpioAlert[i].fnTick = nowTick;
+ gpioAlert[i].wdTick = nowTick;
+ }
+ }
+
+ gpioAlert[i].fnLBitV = LBitV;
+
+ if (gpioAlert[i].fnSteadyUs)
+ {
+ diff = lastTick - gpioAlert[i].fnTick;
+
+ if (diff >= gpioAlert[i].fnSteadyUs)
+ {
+ /* Start reporting gpio changes */
+ filterBits &= (~bit);
+ gpioAlert[i].fnTick2 = lastTick + gpioAlert[i].fnActiveUs;
+ }
+ }
+ }
+ }
+}
+
static void * pthAlertThread(void *x)
{
struct timespec req, rem;
uint32_t oldLevel, newLevel, level, reportedLevel;
uint32_t oldSlot, newSlot;
- uint32_t tick, expected, nowTick;
+ uint32_t stick, expected, nowTick;
int32_t diff;
int cycle, pulse;
int emit, seqno, emitted;
uint32_t changes, bits, changedBits, timeoutBits;
int numSamples, d;
int b, n, v;
+ int rp, wp;
int err;
int stopped;
int delayTicks;
moreToDo = 0;
- tick = systReg[SYST_CLO];
+ stick = systReg[SYST_CLO];
nextWakeTick =
- tick + alert_delays[(gpioCfg.internals>>PI_CFG_ALERT_FREQ)&15];
+ stick + alert_delays[(gpioCfg.internals>>PI_CFG_ALERT_FREQ)&15];
while (1)
{
oldLevel = reportedLevel & monitorBits;
+ /* Work through latest samples saving any level
+ changes of gpios of interest.
+ */
+
while ((oldSlot != newSlot) && (numSamples < DATUMS))
{
level = myGetLevel(oldSlot++);
newLevel = (level & monitorBits);
- if (newLevel != oldLevel)
- {
- gpioSample[numSamples].tick = tick;
- gpioSample[numSamples].level = level;
-
- changedBits |= (newLevel ^ oldLevel);
-
- oldLevel = newLevel;
+ gpioSample[numSamples].tick = stick;
+ gpioSample[numSamples].level = level;
- numSamples++;
- }
+ numSamples++;
- tick += gpioCfg.clockMicros;
+ stick += gpioCfg.clockMicros;
if (++pulse >= PULSE_PER_CYCLE)
{
oldSlot = 0;
}
- expected = tick;
+ expected = stick;
- tick = myGetTick(cycle);
+ stick = myGetTick(cycle);
- diff = tick - expected;
+ diff = stick - expected;
diff += (TICKSLOTS/2);
if (oldSlot == newSlot) moreToDo = 0; else moreToDo = 1;
- /* should gpioGetSamples be called */
+ /* Apply glitch filter */
+
+ alertGlitchFilter(numSamples);
+
+ /* Compact samples */
+
+ wp = 0;
+
+ for (rp=0; rp<numSamples; rp++)
+ {
+ level = gpioSample[rp].level;
+
+ newLevel = (level & monitorBits);
+
+ if (newLevel != oldLevel)
+ {
+ gpioSample[wp].tick = gpioSample[rp].tick;
+ gpioSample[wp].level = level;
+ wp++;
+
+ changedBits |= (newLevel ^ oldLevel);
+
+ oldLevel = newLevel;
+ }
+ }
+
+ numSamples = wp;
+
+ /* Write compacted samples. */
if (changedBits)
{
}
}
- /* reset timeouts for any changed bits */
+ /* Apply activity filter */
- if (changedBits)
- {
- for (b=0; b<=PI_MAX_USER_GPIO; b++)
- {
- if (changedBits & (1<<b)) gpioAlert[b].tick = tick;
- }
- }
+ alertActivityFilter(numSamples);
/* call alert callbacks for each bit transition */
- if (changedBits & alertBits)
+ if ((changedBits & alertBits) & (~filterBits))
{
- oldLevel = reportedLevel & alertBits;
+ oldLevel = (reportedLevel & alertBits) & (~filterBits);
for (d=0; d<numSamples; d++)
{
- newLevel = gpioSample[d].level & alertBits;
+ newLevel = (gpioSample[d].level & alertBits) & (~filterBits);
if (newLevel != oldLevel)
{
- changes = newLevel ^ oldLevel;
+ changes = (newLevel ^ oldLevel) & (~filterBits);
for (b=0; b<=PI_MAX_USER_GPIO; b++)
{
}
}
- /* check for timeout watchdogs */
+ /* check for watchdog timeouts */
timeoutBits = 0;
for (b=0; b<=PI_MAX_USER_GPIO; b++)
{
- if (gpioAlert[b].timeout)
+ if (gpioAlert[b].wdSteadyUs)
{
- diff = tick - gpioAlert[b].tick;
+ diff = stick - gpioAlert[b].wdTick;
- if (diff > (gpioAlert[b].timeout*1000))
+ if (diff >= gpioAlert[b].wdSteadyUs)
{
timeoutBits |= (1<<b);
- gpioAlert[b].tick += (gpioAlert[b].timeout*1000);
+ gpioAlert[b].wdTick += gpioAlert[b].wdSteadyUs;
if (gpioAlert[b].func)
{
if (gpioAlert[b].ex)
{
(gpioAlert[b].func)
- (b, PI_TIMEOUT, tick, gpioAlert[b].userdata);
+ (b, PI_TIMEOUT, stick, gpioAlert[b].userdata);
}
else
{
(gpioAlert[b].func)
- (b, PI_TIMEOUT, tick);
+ (b, PI_TIMEOUT, stick);
}
}
}
}
else if (gpioNotify[n].state == PI_NOTIFY_RUNNING)
{
- bits = gpioNotify[n].bits;
+ bits = gpioNotify[n].bits & (~filterBits);
emit = 0;
gpioReport[emit].seqno = seqno;
gpioReport[emit].flags = 0;
gpioReport[emit].tick = gpioSample[d].tick;
- gpioReport[emit].level = gpioSample[d].level;
+ gpioReport[emit].level =
+ gpioSample[d].level & (~filterBits);
oldLevel = newLevel;
timeoutBits is the set of timed out bits
*/
+ bits = gpioNotify[n].bits;
+
if (timeoutBits & bits)
{
/* at least one watchdog has fired for this
gpioReport[emit].seqno = seqno;
gpioReport[emit].flags = PI_NTFY_FLAGS_WDOG |
PI_NTFY_FLAGS_BIT(b);
- gpioReport[emit].tick = tick;
+ gpioReport[emit].tick = stick;
gpioReport[emit].level = newLevel;
emit++;
if (!emit)
{
- if ((tick - gpioNotify[n].lastReportTick) > 60000000)
+ if ((stick - gpioNotify[n].lastReportTick) > 60000000)
{
if (numSamples)
newLevel = gpioSample[numSamples-1].level;
gpioReport[emit].seqno = seqno;
gpioReport[emit].flags = PI_NTFY_FLAGS_ALIVE;
- gpioReport[emit].tick = tick;
+ gpioReport[emit].tick = stick;
gpioReport[emit].level = newLevel;
emit++;
if (emit)
{
- gpioNotify[n].lastReportTick = tick;
+ gpioNotify[n].lastReportTick = stick;
max_emits = gpioNotify[n].max_emits;
if (emit > gpioStats.maxEmit) gpioStats.maxEmit = emit;
gpioISR[gpio].pth = NULL;
}
- if (gpioISR[gpio].inited) /* unexport any gpio */
+ if (gpioISR[gpio].inited) /* unexport the gpio */
{
fd = open("/sys/class/gpio/unexport", O_WRONLY);
if (fd < 0) return PI_BAD_ISR_INIT;
sprintf(buf, "%d\n", gpio);
err = write(fd, buf, strlen(buf));
close(fd);
- if (err != sizeof(buf)) return PI_BAD_ISR_INIT;
+ if (err != strlen(buf)) return PI_BAD_ISR_INIT;
gpioISR[gpio].inited = 0;
}
}
SOFT_ERROR(PI_BAD_WDOG_TIMEOUT,
"gpio %d, bad timeout (%d)", gpio, timeout);
- gpioAlert[gpio].timeout = timeout;
- gpioAlert[gpio].tick = systReg[SYST_CLO];
+ gpioAlert[gpio].wdTick = systReg[SYST_CLO];
+ gpioAlert[gpio].wdSteadyUs = timeout*1000;
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+int gpioNoiseFilter(unsigned gpio, unsigned steady, unsigned active)
+{
+ DBG(DBG_USER, "gpio=%d steady=%d active=%d", gpio, steady, active);
+
+ CHECK_INITED;
+
+ if (gpio > PI_MAX_USER_GPIO)
+ SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
+
+ if (steady > PI_MAX_STEADY)
+ SOFT_ERROR(PI_BAD_FILTER, "bad steady (%d)", steady);
+
+ if (active > PI_MAX_ACTIVE)
+ SOFT_ERROR(PI_BAD_FILTER, "bad active (%d)", active);
+
+ gpioAlert[gpio].fnTick = systReg[SYST_CLO];
+ gpioAlert[gpio].fnTick2 = gpioAlert[gpio].fnTick;
+ gpioAlert[gpio].fnSteadyUs = steady;
+ gpioAlert[gpio].fnActiveUs = active;
+
+ if (steady) filterBits |= (1<<gpio);
+ else filterBits &= (~(1<<gpio));
+
+ return 0;
+}
+
+
+/* ----------------------------------------------------------------------- */
+
+int gpioGlitchFilter(unsigned gpio, unsigned steady)
+{
+ DBG(DBG_USER, "gpio=%d steady=%d", gpio, steady);
+
+ CHECK_INITED;
+
+ if (gpio > PI_MAX_USER_GPIO)
+ SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
+
+ if (steady > PI_MAX_STEADY)
+ SOFT_ERROR(PI_BAD_FILTER, "bad steady (%d)", steady);
+
+ if (steady)
+ {
+ gpioAlert[gpio].fgTick = systReg[SYST_CLO];
+
+ if (gpioRead_Bits_0_31() & (1<<gpio))
+ {
+ gpioAlert[gpio].fgLBitV = (1<<gpio);
+ gpioAlert[gpio].fgRBitV = 0 ;
+ }
+ else
+ {
+ gpioAlert[gpio].fgLBitV = 0 ;
+ gpioAlert[gpio].fgRBitV = (1<<gpio);
+ }
+ }
+
+ gpioAlert[gpio].fgDebounceUs = steady;
return 0;
}
#include <stdint.h>
#include <pthread.h>
-#define PIGPIO_VERSION 38
+#define PIGPIO_VERSION 39
/*TEXT
gpioHardwareClock Start hardware clock on supported gpios
gpioHardwarePWM Start hardware PWM on supported gpios
+gpioGlitchFilter Set a glitch filter on a gpio
+gpioNoiseFilter Set a noise filter on a gpio
+
SCRIPTS
gpioStoreScript Store a script
#define PI_MEM_ALLOC_PAGEMAP 1
#define PI_MEM_ALLOC_MAILBOX 2
+/* filters */
+
+#define PI_MAX_STEADY 300000
+#define PI_MAX_ACTIVE 1000000
+
/* gpioCfgInternals */
#define PI_CFG_DBG_LEVEL 0 /* bits 0-3 */
D*/
+/*F*/
+int gpioNoiseFilter(unsigned user_gpio, unsigned steady, unsigned active);
+/*D
+Sets a noise filter on a gpio.
+
+Level changes on the gpio are ignored until a level which has
+been stable for [*steady*] microseconds is detected. Level changes
+on the gpio are then reported for [*active*] microseconds after
+which the process repeats.
+
+. .
+user_gpio: 0-31
+ steady: 0-300000
+ active: 0-1000000
+. .
+
+Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
+
+Note, level changes before and after the active period may
+be reported. Your software must be designed to cope with
+such reports.
+D*/
+
+
+/*F*/
+int gpioGlitchFilter(unsigned user_gpio, unsigned steady);
+/*D
+Sets a glitch filter on a gpio.
+
+Level changes on the gpio are not reported unless the level
+has been stable for at least [*steady*] microseconds. The
+level is then reported. Level changes of less than [*steady*]
+microseconds are ignored.
+
+. .
+user_gpio: 0-31
+ steady: 0-300000
+. .
+
+Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
+
+Note, each (stable) edge will be timestamped [*steady*] microseconds
+after it was first detected.
+D*/
+
+
/*F*/
int gpioSetGetSamplesFunc(gpioGetSamplesFunc_t f, uint32_t bits);
/*D
/*PARAMS
+active :: 0-1000000
+
+The number of microseconds level changes are reported for once
+a noise filter has been triggered (by [*steady*] microseconds of
+a stable level).
+
*arg::
A pointer to a void object passed to a thread started by gpioStartThread.
spiTxBits::
The number of bits to transfer dring a raw SPI transaction
+steady :: 0-300000
+
+The number of microseconds level changes must be stable for
+before reporting the level changed ([*gpioGlitchFilter*]) or triggering
+the active part of a noise filter ([*gpioNoiseFilter*]).
+
stop_bits::2-8
The number of (half) stop bits to be used when adding serial data
to a waveform.
#define PI_CMD_CGI 95
#define PI_CMD_CSI 96
+#define PI_CMD_FG 97
+#define PI_CMD_FN 98
+
#define PI_CMD_NOIB 99
/*DEF_E*/
#define PI_BAD_EDGE -122 // bad ISR edge value, not 0-2
#define PI_BAD_ISR_INIT -123 // bad ISR initialisation
#define PI_BAD_FOREVER -124 // loop forever must be last chain command
+#define PI_BAD_FILTER -125 // bad filter parameter
#define PI_PIGIF_ERR_0 -2000
#define PI_PIGIF_ERR_99 -2099
gpio_trigger Send a trigger pulse to a gpio
set_watchdog Set a watchdog on a gpio
+set_filter Set an activity filter on a gpio
set_PWM_range Configure PWM range of a gpio
get_PWM_range Get configured PWM range of a gpio
hardware_clock Start hardware clock on supported gpios
hardware_PWM Start hardware PWM on supported gpios
+set_glitch_filter Set a glitch filter on a gpio
+set_noise_filter Set a noise filter on a gpio
+
Scripts
store_script Store a script
pigpio.error_text Gets error text from error number
pigpio.tickDiff Returns difference between two ticks
"""
+
import sys
import socket
import struct
import os
import atexit
-VERSION = "1.22"
+VERSION = "1.23"
exceptions = True
_PI_CMD_SLRI =94
+_PI_CMD_CGI =95
+_PI_CMD_CSI =96
+
+_PI_CMD_FG =97
+_PI_CMD_FN =98
+
# pigpio error numbers
_PI_INIT_FAILED =-1
PI_CHAIN_TOO_BIG =-119
PI_DEPRECATED =-120
PI_BAD_SER_INVERT =-121
+_PI_BAD_EDGE =-122
+_PI_BAD_ISR_INIT =-123
+PI_BAD_FOREVER =-124
+PI_BAD_FILTER =-125
+
# pigpio error text
[PI_CHAIN_TOO_BIG , "chain is too long"],
[PI_DEPRECATED , "deprecated function removed"],
[PI_BAD_SER_INVERT , "bit bang serial invert not 0 or 1"],
+ [_PI_BAD_EDGE , "bad ISR edge value, not 0-2"],
+ [_PI_BAD_ISR_INIT , "bad ISR initialisation"],
+ [PI_BAD_FOREVER , "loop forever must be last chain command"],
+ [PI_BAD_FILTER , "bad filter parameter"],
]
self.monitor = 0
self.callbacks = []
self.sl.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.sl.s.settimeout(None)
self.sl.s.connect((host, port))
self.handle = _pigpio_command(self.sl, _PI_CMD_NOIB, 0, 0)
self.go = True
return _u2i(_pigpio_command_ext(
self.sl, _PI_CMD_TRIG, user_gpio, pulse_len, 4, extents))
+ def set_glitch_filter(self, user_gpio, steady):
+ """
+ Sets a glitch filter on a gpio.
+
+ Level changes on the gpio are not reported unless the level
+ has been stable for at least [*steady*] microseconds. The
+ level is then reported. Level changes of less than [*steady*]
+ microseconds are ignored.
+
+ user_gpio:= 0-31
+ steady:= 0-300000
+
+ Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
+
+ Note, each (stable) edge will be timestamped [*steady*]
+ microseconds after it was first detected.
+
+ ...
+ pi.set_glitch_filter(23, 100)
+ ...
+ """
+ return _u2i(_pigpio_command(self.sl, _PI_CMD_FG, user_gpio, steady))
+
+ def set_noise_filter(self, user_gpio, steady, active):
+ """
+ Sets a noise filter on a gpio.
+
+ Level changes on the gpio are ignored until a level which has
+ been stable for [*steady*] microseconds is detected. Level
+ changes on the gpio are then reported for [*active*]
+ microseconds after which the process repeats.
+
+ user_gpio:= 0-31
+ steady:= 0-300000
+ active:= 0-1000000
+
+ Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
+
+ Note, level changes before and after the active period may
+ be reported. Your software must be designed to cope with
+ such reports.
+
+ ...
+ pi.set_noise_filter(23, 1000, 5000)
+ ...
+ """
+ # pigpio message format
+
+ # I p1 user_gpio
+ # I p2 steady
+ # I p3 4
+ ## extension ##
+ # I active
+ extents = [struct.pack("I", active)]
+ return _u2i(_pigpio_command_ext(
+ self.sl, _PI_CMD_FN, user_gpio, steady, 4, extents))
+
def store_script(self, script):
"""
Store a script for later execution.
self._port = int(port)
self.sl.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.sl.s.settimeout(None)
# Disable the Nagle algorithm.
self.sl.s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
def xref():
"""
+ active: 0-1000000
+ The number of microseconds level changes are reported for once
+ a noise filter has been triggered (by [*steady*] microseconds of
+ a stable level).
+
+
arg1:
An unsigned argument passed to a user customised function. Its
meaning is defined by the customiser.
spi_flags: 32 bit
See [*spi_open*].
+ steady: 0-300000
+
+ The number of microseconds level changes must be stable for
+ before reporting the level changed ([*set_glitch_filter*])
+ or triggering the active part of a noise filter
+ ([*set_noise_filter*]).
+
t1:
A tick (earlier).
The \fBcallback\fP and \fBcallback_ex\fP functions interpret the flags
and will call registered callbacks for the gpio with level TIMEOUT.
+.IP "\fBint set_glitch_filter(unsigned user_gpio, unsigned steady)\fP"
+.IP "" 4
+Sets a glitch filter on a gpio.
+
+.br
+
+.br
+Level changes on the gpio are not reported unless the level
+has been stable for at least \fBsteady\fP microseconds. The
+level is then reported. Level changes of less than \fBsteady\fP
+microseconds are ignored.
+
+.br
+
+.br
+
+.EX
+user_gpio: 0-31
+.br
+ steady: 0-300000
+.br
+
+.EE
+
+.br
+
+.br
+Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
+
+.br
+
+.br
+Note, each (stable) edge will be timestamped \fBsteady\fP microseconds
+after it was first detected.
+
+.IP "\fBint set_noise_filter(unsigned user_gpio, unsigned steady, unsigned active)\fP"
+.IP "" 4
+Sets a noise filter on a gpio.
+
+.br
+
+.br
+Level changes on the gpio are ignored until a level which has
+been stable for \fBsteady\fP microseconds is detected. Level changes
+on the gpio are then reported for \fBactive\fP microseconds after
+which the process repeats.
+
+.br
+
+.br
+
+.EX
+user_gpio: 0-31
+.br
+ steady: 0-300000
+.br
+ active: 0-1000000
+.br
+
+.EE
+
+.br
+
+.br
+Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
+
+.br
+
+.br
+Note, level changes before and after the active period may
+be reported. Your software must be designed to cope with
+such reports.
+
.IP "\fBuint32_t read_bank_1(void)\fP"
.IP "" 4
Read the levels of the bank 1 gpios (gpios 0-31).
.IP "\fBint callback_cancel(unsigned callback_id)\fP"
.IP "" 4
-This function fim
-cancels a callback identified by its id.
+This function cancels a callback identified by its id.
.br
.br
+.IP "\fBactive\fP: 0-1000000" 0
+
+.br
+
+.br
+The number of microseconds level changes are reported for once
+a noise filter has been triggered (by \fBsteady\fP microseconds of
+a stable level).
+
+.br
+
+.br
+
.IP "\fB*addrStr\fP" 0
A string specifying the host or IP address of the Pi running
the pigpio daemon. It may be NULL in which case localhost
.br
+.IP "\fBsteady\fP: 0-300000" 0
+
+.br
+
+.br
+The number of microseconds level changes must be stable for
+before reporting the level changed (\fBset_glitch_filter\fP) or triggering
+the active part of a noise filter (\fBset_noise_filter\fP).
+
+.br
+
+.br
+
.IP "\fBstop_bits\fP: 2-8" 0
The number of (half) stop bits to be used when adding serial data
to a waveform.
For more information, please refer to <http://unlicense.org/>
*/
-/* PIGPIOD_IF_VERSION 19 */
+/* PIGPIOD_IF_VERSION 21 */
#include <stdio.h>
#include <stdlib.h>
{return pigpio_command(gPigCommand, PI_CMD_WVGOR, 0, 0, 1);}
int wave_send_once(unsigned wave_id)
- {return pigpio_command(gPigCommand, PI_CMD_WVTX, 0, 0, 1);}
+ {return pigpio_command(gPigCommand, PI_CMD_WVTX, wave_id, 0, 1);}
int wave_send_repeat(unsigned wave_id)
- {return pigpio_command(gPigCommand, PI_CMD_WVTXR, 0, 0, 1);}
+ {return pigpio_command(gPigCommand, PI_CMD_WVTXR, wave_id, 0, 1);}
int wave_chain(char *buf, unsigned bufSize)
{
gPigCommand, PI_CMD_TRIG, user_gpio, pulseLen, 4, 1, ext, 1);
}
+int set_glitch_filter(unsigned user_gpio, unsigned steady)
+ {return pigpio_command(gPigCommand, PI_CMD_FG, user_gpio, steady, 1);}
+
+int set_noise_filter(unsigned user_gpio, unsigned steady, unsigned active)
+{
+ gpioExtent_t ext[1];
+
+ /*
+ p1=user_gpio
+ p2=steady
+ p3=4
+ ## extension ##
+ unsigned active
+ */
+
+ ext[0].size = sizeof(uint32_t);
+ ext[0].ptr = &active;
+
+ return pigpio_command_ext(
+ gPigCommand, PI_CMD_FN, user_gpio, steady, 4, 1, ext, 1);
+}
+
int store_script(char *script)
{
unsigned len;
#include "pigpio.h"
-#define PIGPIOD_IF_VERSION 20
+#define PIGPIOD_IF_VERSION 21
/*TEXT
hardware_clock Start hardware clock on supported gpios
hardware_PWM Start hardware PWM on supported gpios
+set_glitch_filter Set a glitch filter on a gpio
+set_noise_filter Set a noise filter on a gpio
+
SCRIPTS
store_script Store a script
OVERVIEW*/
+#ifdef __cplusplus
+extern "C" {
+#endif
typedef void (*CBFunc_t) (unsigned user_gpio, unsigned level, uint32_t tick);
and will call registered callbacks for the gpio with level TIMEOUT.
D*/
+/*F*/
+int set_glitch_filter(unsigned user_gpio, unsigned steady);
+/*D
+Sets a glitch filter on a gpio.
+
+Level changes on the gpio are not reported unless the level
+has been stable for at least [*steady*] microseconds. The
+level is then reported. Level changes of less than [*steady*]
+microseconds are ignored.
+
+. .
+user_gpio: 0-31
+ steady: 0-300000
+. .
+
+Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
+
+Note, each (stable) edge will be timestamped [*steady*] microseconds
+after it was first detected.
+D*/
+
+/*F*/
+int set_noise_filter(unsigned user_gpio, unsigned steady, unsigned active);
+/*D
+Sets a noise filter on a gpio.
+
+Level changes on the gpio are ignored until a level which has
+been stable for [*steady*] microseconds is detected. Level changes
+on the gpio are then reported for [*active*] microseconds after
+which the process repeats.
+
+. .
+user_gpio: 0-31
+ steady: 0-300000
+ active: 0-1000000
+. .
+
+Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
+
+Note, level changes before and after the active period may
+be reported. Your software must be designed to cope with
+such reports.
+D*/
+
/*F*/
uint32_t read_bank_1(void);
/*D
/*F*/
int callback_cancel(unsigned callback_id);
/*D
-This function fim
-cancels a callback identified by its id.
+This function cancels a callback identified by its id.
. .
callback_id: >=0, as returned by a call to [*callback*] or [*callback_ex*].
/*PARAMS
+active :: 0-1000000
+
+The number of microseconds level changes are reported for once
+a noise filter has been triggered (by [*steady*] microseconds of
+a stable level).
+
*addrStr::
A string specifying the host or IP address of the Pi running
the pigpio daemon. It may be NULL in which case localhost
spi_flags::
See [*spi_open*].
+steady :: 0-300000
+
+The number of microseconds level changes must be stable for
+before reporting the level changed ([*set_glitch_filter*]) or triggering
+the active part of a noise filter ([*set_noise_filter*]).
+
stop_bits::2-8
The number of (half) stop bits to be used when adding serial data
to a waveform.
/*DEF_E*/
+#ifdef __cplusplus
+}
+#endif
+
#endif
.br
+.IP "\fBFG u stdy\fP - Set a glitch filter on a gpio"
+.IP "" 4
+
+.br
+Level changes on the gpio are not reported unless the level
+has been stable for at least \fBstdy\fP microseconds. The
+level is then reported. Level changes of less than \fBstdy\fP
+microseconds are ignored.
+
+.br
+Note, each (stable) edge will be timestamped \fBstdy\fP microseconds
+after it was first detected.
+
+.br
+
+.IP "\fBFN u stdy actv\fP - Set a noise filter on a gpio"
+.IP "" 4
+
+.br
+Level changes on the gpio are ignored until a level which has
+been stable for \fBstdy\fP microseconds is detected. Level
+changes on the gpio are then reported for \fBactv\fP microseconds
+after which the process repeats.
+
+.br
+Note, level changes before and after the active period may
+be reported. Your software must be designed to cope with
+such reports.
+
+.br
+
.IP "\fBGDC u\fP - Get gpio PWM dutycycle"
.IP "" 4
.br
+.IP "\fBactv\fP - 0-1000000" 0
+
+.br
+The number of microseconds level changes are reported for once
+a noise filter has been triggered (by \fBstdy\fP microseconds of
+a stable level).
+
+.br
+
.IP "\fBb\fP - baud" 0
The command expects the baud rate in bits per second for
the transmission of serial data (I2C/SPI/serial link, waves).
.br
+.IP "\fBstdy\fP - 0-300000" 0
+
+.br
+The number of microseconds level changes must be stable for
+before reporting the level changed (\fBFG\fP) or triggering
+the active part of a noise filter (\fBFN\fP).
+
+.br
+
.IP "\fBt\fP - text (a string of text)" 0
The command expects a text string.
from distutils.core import setup
setup(name='pigpio',
- version='1.22',
+ version='1.23',
author='joan',
author_email='joan@abyz.co.uk',
maintainer='joan',
if [[ $s = "" ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi
s=$(pigs h)
-if [[ ${#s} = 4412 ]]; then echo "HELP ok"; else echo "HELP fail (${#s})"; fi
+if [[ ${#s} = 4502 ]]; 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