diff --git a/command.c b/command.c index 4a81543..49ac7c6 100644 --- a/command.c +++ b/command.c @@ -26,7 +26,7 @@ For more information, please refer to */ /* -This version is for pigpio version 38+ +This version is for pigpio version 39+ */ #include @@ -61,6 +61,9 @@ cmdInfo_t cmdInfo[]= {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 @@ -247,6 +250,9 @@ CF2 ... Custom function 2\n\ 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\ @@ -479,6 +485,7 @@ static errInfo_t errInfo[]= {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"}, }; diff --git a/pigpio.3 b/pigpio.3 index 1cb5d71..c06b3de 100644 --- a/pigpio.3 +++ b/pigpio.3 @@ -3862,6 +3862,79 @@ gpioSetWatchdog(4, 5); .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 @@ -5620,6 +5693,19 @@ Not intended for general use. .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 @@ -7138,6 +7224,19 @@ The number of bits to transfer dring a raw SPI transaction .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. @@ -7591,6 +7690,12 @@ A 16-bit word value. #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 @@ -7855,6 +7960,8 @@ A 16-bit word value. .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 diff --git a/pigpio.c b/pigpio.c index 191226a..3205f2c 100644 --- a/pigpio.c +++ b/pigpio.c @@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to */ -/* pigpio version 38 */ +/* pigpio version 39 */ /* include ------------------------------------------------------- */ @@ -734,7 +734,7 @@ Assumes two counters per block. Each counter 4 * 16 (16^4=65536) #define PI_WF_MICROS 1 -#define DATUMS 2000 +#define DATUMS 4000 #define DEFAULT_PWM_IDX 5 @@ -868,8 +868,17 @@ typedef struct 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 @@ -1144,6 +1153,7 @@ static volatile uint32_t alertBits = 0; 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; @@ -1734,6 +1744,15 @@ static int myDoCommand(uint32_t *p, unsigned bufSize, char *buf) 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; @@ -4994,26 +5013,165 @@ static void sigSetHandler(void) } } -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<= 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<= 0) + { + /* Stop reporting gpio changes */ + filterBits |= bit; + } + } + + LBitV = gpioAlert[i].fnLBitV; + + for (j=0; j= 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; @@ -5039,10 +5197,10 @@ static void * pthAlertThread(void *x) 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) { @@ -5054,25 +5212,22 @@ static void * pthAlertThread(void *x) 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; + gpioSample[numSamples].tick = stick; + gpioSample[numSamples].level = level; - changedBits |= (newLevel ^ oldLevel); + numSamples++; - oldLevel = newLevel; - - numSamples++; - } - - tick += gpioCfg.clockMicros; + stick += gpioCfg.clockMicros; if (++pulse >= PULSE_PER_CYCLE) { @@ -5084,11 +5239,11 @@ static void * pthAlertThread(void *x) oldSlot = 0; } - expected = tick; + expected = stick; - tick = myGetTick(cycle); + stick = myGetTick(cycle); - diff = tick - expected; + diff = stick - expected; diff += (TICKSLOTS/2); @@ -5108,7 +5263,35 @@ static void * pthAlertThread(void *x) 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 (gpioAlert[b].timeout*1000)) + if (diff >= gpioAlert[b].wdSteadyUs) { timeoutBits |= (1< 60000000) + if ((stick - gpioNotify[n].lastReportTick) > 60000000) { if (numSamples) newLevel = gpioSample[numSamples-1].level; @@ -5309,7 +5489,7 @@ static void * pthAlertThread(void *x) gpioReport[emit].seqno = seqno; gpioReport[emit].flags = PI_NTFY_FLAGS_ALIVE; - gpioReport[emit].tick = tick; + gpioReport[emit].tick = stick; gpioReport[emit].level = newLevel; emit++; @@ -5319,7 +5499,7 @@ static void * pthAlertThread(void *x) if (emit) { - gpioNotify[n].lastReportTick = tick; + gpioNotify[n].lastReportTick = stick; max_emits = gpioNotify[n].max_emits; if (emit > gpioStats.maxEmit) gpioStats.maxEmit = emit; @@ -9785,14 +9965,14 @@ static int intGpioSetISRFunc( 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; } } @@ -10093,8 +10273,72 @@ int gpioSetWatchdog(unsigned gpio, unsigned timeout) 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< 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< #include #include -#define PIGPIO_VERSION 38 +#define PIGPIO_VERSION 39 /*TEXT @@ -184,6 +184,9 @@ gpioSerialReadClose Closes a gpio for bit bang serial reads 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 @@ -736,6 +739,11 @@ typedef void *(gpioThreadFunc_t) (void *); #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 */ @@ -2882,6 +2890,52 @@ gpioSetWatchdog(4, 5); 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 @@ -3945,6 +3999,12 @@ 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. @@ -4580,6 +4640,12 @@ The SPI slave select gpio in a raw SPI transaction. 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. @@ -4786,6 +4852,9 @@ PARAMS*/ #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*/ @@ -4975,6 +5044,7 @@ after this command is issued. #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 diff --git a/pigpio.py b/pigpio.py index 2771dfb..965d9b7 100644 --- a/pigpio.py +++ b/pigpio.py @@ -123,6 +123,7 @@ Intermediate 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 @@ -156,6 +157,9 @@ bb_serial_invert Invert serial logic (1 invert, 0 normal) 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 @@ -256,6 +260,7 @@ get_pigpio_version Get the pigpio version pigpio.error_text Gets error text from error number pigpio.tickDiff Returns difference between two ticks """ + import sys import socket import struct @@ -264,7 +269,7 @@ import threading import os import atexit -VERSION = "1.22" +VERSION = "1.23" exceptions = True @@ -435,6 +440,12 @@ _PI_CMD_WVCHA=93 _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 @@ -559,6 +570,11 @@ PI_CHAIN_NESTING =-118 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 @@ -682,6 +698,10 @@ _errors=[ [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"], ] @@ -867,6 +887,7 @@ class _callback_thread(threading.Thread): 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 @@ -3215,6 +3236,63 @@ class pi(): 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. @@ -3600,6 +3678,7 @@ class pi(): 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) @@ -3653,6 +3732,12 @@ class pi(): 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. @@ -3982,6 +4067,13 @@ def xref(): 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). diff --git a/pigpiod_if.3 b/pigpiod_if.3 index 3e29b50..fac7b70 100644 --- a/pigpiod_if.3 +++ b/pigpiod_if.3 @@ -1014,6 +1014,79 @@ to the fifo with the flags set to indicate a watchdog timeout. 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). @@ -3697,8 +3770,7 @@ the gpio has the identified edge. .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 @@ -3749,6 +3821,19 @@ The function returns when the edge occurs or after the timeout. .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 @@ -4508,6 +4593,19 @@ See \fBspi_open\fP. .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. diff --git a/pigpiod_if.c b/pigpiod_if.c index e36a0fd..4078e12 100644 --- a/pigpiod_if.c +++ b/pigpiod_if.c @@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to */ -/* PIGPIOD_IF_VERSION 19 */ +/* PIGPIOD_IF_VERSION 21 */ #include #include @@ -740,10 +740,10 @@ int wave_tx_repeat(void) /* DEPRECATED */ {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) { @@ -816,6 +816,28 @@ int gpio_trigger(unsigned user_gpio, unsigned pulseLen, uint32_t level) 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; diff --git a/pigpiod_if.h b/pigpiod_if.h index 7d6a630..b819464 100644 --- a/pigpiod_if.h +++ b/pigpiod_if.h @@ -30,7 +30,7 @@ For more information, please refer to #include "pigpio.h" -#define PIGPIOD_IF_VERSION 20 +#define PIGPIOD_IF_VERSION 21 /*TEXT @@ -166,6 +166,9 @@ bb_serial_invert Invert serial logic (1 invert, 0 normal) 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 @@ -275,6 +278,9 @@ time_time Float number of seconds since the epoch OVERVIEW*/ +#ifdef __cplusplus +extern "C" { +#endif typedef void (*CBFunc_t) (unsigned user_gpio, unsigned level, uint32_t tick); @@ -780,6 +786,50 @@ The [*callback*] and [*callback_ex*] functions interpret the flags 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 @@ -2367,8 +2417,7 @@ 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*]. @@ -2396,6 +2445,12 @@ 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). + *addrStr:: A string specifying the host or IP address of the Pi running the pigpio daemon. It may be NULL in which case localhost @@ -2737,6 +2792,12 @@ A SPI channel, 0-2. 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. @@ -2813,5 +2874,9 @@ typedef enum /*DEF_E*/ +#ifdef __cplusplus +} +#endif + #endif diff --git a/pigs.1 b/pigs.1 index 061255a..a3706e6 100644 --- a/pigs.1 +++ b/pigs.1 @@ -514,6 +514,37 @@ configuration settings to \fBv\fP. .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 @@ -3696,6 +3727,15 @@ ERROR: non existent wave id .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). @@ -3958,6 +3998,15 @@ See \fBSPIO\fP. .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. diff --git a/setup.py b/setup.py index 958444e..a7df3a0 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from distutils.core import setup setup(name='pigpio', - version='1.22', + version='1.23', author='joan', author_email='joan@abyz.co.uk', maintainer='joan', diff --git a/x_pigs b/x_pigs index a8b8d21..14b22e8 100755 --- a/x_pigs +++ b/x_pigs @@ -49,7 +49,7 @@ s=$(pigs bs2 0) if [[ $s = "" ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi s=$(pigs h) -if [[ ${#s} = 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