diff --git a/pigpio.3 b/pigpio.3 index 1853e72..a534ab0 100644 --- a/pigpio.3 +++ b/pigpio.3 @@ -3658,7 +3658,7 @@ PI_SER_OPEN_FAILED. .br The baud rate must be one of 50, 75, 110, 134, 150, -200, 300, 600, 1200, 1800, 2400, 4800, 9500, 19200, +200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, or 230400. .br diff --git a/pigpio.c b/pigpio.c index 56cf82f..05bde0d 100644 --- a/pigpio.c +++ b/pigpio.c @@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to */ -/* pigpio version 43 */ +/* pigpio version 44 */ /* include ------------------------------------------------------- */ @@ -742,7 +742,7 @@ Assumes two counters per block. Each counter 4 * 16 (16^4=65536) #define PI_WF_MICROS 1 -#define DATUMS 4000 +#define DATUMS 125 #define DEFAULT_PWM_IDX 5 @@ -876,17 +876,24 @@ typedef struct callbk_t func; unsigned ex; void *userdata; + + int wdSteadyUs; 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; + uint32_t wdLBitV; + + int nfSteadyUs; + int nfActiveUs; + int nfActive; + uint32_t nfTick1; + uint32_t nfTick2; + uint32_t nfLBitV; + uint32_t nfRBitV; + + uint32_t gfSteadyUs; + uint32_t gfTick; + uint32_t gfLBitV; + uint32_t gfRBitV; + } gpioAlert_t; typedef struct @@ -1161,11 +1168,16 @@ 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 uint32_t gFilterBits = 0; +static volatile uint32_t nFilterBits = 0; +static volatile uint32_t wdogBits = 0; static volatile int runState = PI_STARTING; -static int pthAlertRunning = 0; +static int triggerAlert2 = 0; + +static int pthAlert1Running = 0; +static int pthAlert2Running = 0; static int pthFifoRunning = 0; static int pthSocketRunning = 0; @@ -1198,11 +1210,13 @@ static int pwmFreq[PWM_FREQS]; static FILE * inpFifo = NULL; static FILE * outFifo = NULL; -static int fdLock = -1; -static int fdMem = -1; -static int fdSock = -1; -static int fdPmap = -1; -static int fdMbox = -1; +static int fdLock = -1; +static int fdMem = -1; +static int fdSock = -1; +static int fdPmap = -1; +static int fdMbox = -1; +static int fdAlertRead = -1; +static int fdAlertWrite = -1; static DMAMem_t *dmaMboxBlk = MAP_FAILED; static uintptr_t * * dmaPMapBlk = MAP_FAILED; @@ -1252,11 +1266,11 @@ static volatile gpioCfg_t gpioCfg = static unsigned bufferBlocks; /* number of blocks in buffer */ static unsigned bufferCycles; /* number of cycles */ -static pthread_t pthAlert; +static pthread_t pthAlert1; +static pthread_t pthAlert2; static pthread_t pthFifo; static pthread_t pthSocket; -static gpioSample_t gpioSample[DATUMS]; static gpioReport_t gpioReport[DATUMS]; static uint32_t spi_dummy; @@ -5096,174 +5110,199 @@ static void sigSetHandler(void) unsigned alert_delays[]= { - 1000, 1034, 1071, 1111, 1154, 1200, 1250, 1304, - 1364, 1429, 1500, 1579, 1667, 1765, 1875, 2000 + 1000000, 1034000, 1071000, 1111000, 1154000, 1200000, 1250000, 1304000, + 1364000, 1429000, 1500000, 1579000, 1667000, 1765000, 1875000, 2000000 }; /* ======================================================================= */ -static void alertGlitchFilter(int numSamples) +static void alertGlitchFilter(gpioSample_t *sample, int numSamples) { int i, j, diff; - uint32_t DebounceUs, Tick, RBitV, LBitV; + uint32_t steadyUs, nowTick, 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; + steadyUs = gpioAlert[i].gfSteadyUs; + RBitV = gpioAlert[i].gfRBitV; + LBitV = gpioAlert[i].gfLBitV; + nowTick = gpioAlert[i].gfTick; for (j=0; j= steadyUs) { - diff = nowTick - gpioAlert[i].fnTick; - - if (diff >= gpioAlert[i].fnSteadyUs) - { - /* Start reporting gpio changes */ - filterBits &= (~bit); - gpioAlert[i].fnTick2 = - nowTick + gpioAlert[i].fnActiveUs; - } + /* Level stable for steady period. */ + RBitV = bitV; } + else + { + /* Keep reporting old level. */ - LBitV = gpioSample[j].level & bit; - - gpioAlert[i].fnTick = nowTick; - gpioAlert[i].wdTick = nowTick; + sample[j].level ^= bit; + } } - } - gpioAlert[i].fnLBitV = LBitV; - - if (gpioAlert[i].fnSteadyUs) - { - diff = lastTick - gpioAlert[i].fnTick; - - if (diff >= gpioAlert[i].fnSteadyUs) + if (bitV != LBitV) { - /* Start reporting gpio changes */ - filterBits &= (~bit); - gpioAlert[i].fnTick2 = lastTick + gpioAlert[i].fnActiveUs; + /* Difference between level and last level. + Restart steady timer. */ + + nowTick = sample[j].tick; + LBitV = bitV; } } + + gpioAlert[i].gfRBitV = RBitV; + gpioAlert[i].gfLBitV = LBitV; + gpioAlert[i].gfTick = nowTick; } } } +static void alertNoiseFilter(gpioSample_t *sample, int numSamples) +{ + int i, j, diff; + uint32_t LBitV; + uint32_t bit, bitV; + uint32_t nowTick; + for (i=0; i<=PI_MAX_USER_GPIO; i++) + { + bit = (1<= 0) + { + /* Stop reporting gpio changes */ + + gpioAlert[i].nfActive = 0; + gpioAlert[i].nfTick1 = nowTick; + } + } + else /* waiting for steady us */ + { + if (bitV != LBitV) + { + diff = nowTick - gpioAlert[i].nfTick1; + gpioAlert[i].nfTick1 = nowTick; + + if (diff >= gpioAlert[i].nfSteadyUs) + { + /* Start reporting gpio changes */ + + gpioAlert[i].nfRBitV = LBitV; + gpioAlert[i].nfActive = 1; + gpioAlert[i].nfTick2 = + nowTick + gpioAlert[i].nfActiveUs; + } + } + } + + if (!gpioAlert[i].nfActive) + { + if (bitV != gpioAlert[i].nfRBitV) + sample[j].level ^= bit; + } + + LBitV = bitV; + } + + gpioAlert[i].nfLBitV = LBitV; + + } + } +} + +static void alertWdogCheck(gpioSample_t *sample, int numSamples, uint32_t tick) +{ + /* + Go through and set the last time each GPIO with a watchdog changed state. + + If the watchdog has expired make sure the alert 2 thread is called to + emit the watchdog report. + */ + + int i, j, diff; + uint32_t LBitV; + uint32_t bit; + + for (i=0; i<=PI_MAX_USER_GPIO; i++) + { + bit = (1<= gpioAlert[i].wdSteadyUs) triggerAlert2 = 1; + } + } +} + +#define PIPE_MAX 500 + +static void * pthAlert1Thread(void *x) { struct timespec req, rem; uint32_t oldLevel, newLevel, level, reportedLevel; uint32_t oldSlot, newSlot; - uint32_t stick, expected, nowTick, ft; + uint32_t stick, expected, ft; int32_t diff, minDiff, stickInited; int cycle, pulse; - int emit, seqno, emitted; - uint32_t changes, bits, changedBits, timeoutBits; - int numSamples, d, ticks, i; - int b, n, v; - int rp, wp; - int err; + uint32_t changedBits; + int numSamples, ticks, i; + int rp, compactedSamples; int stopped; - int delayTicks; - uint32_t nextWakeTick; int moreToDo; - int max_emits; - char fifo[32]; + int skippedAlert2Count; + gpioSample_t sample[PIPE_MAX]; + int pipefd[2]; + + pipe(pipefd); + + fdAlertRead = pipefd[0]; + fdAlertWrite = pipefd[1]; + + i = fcntl(fdAlertRead, F_SETPIPE_SZ, 32*4096); req.tv_sec = 0; @@ -5286,13 +5325,13 @@ static void * pthAlertThread(void *x) moreToDo = 0; stickInited = 0; + stick = 0; - nextWakeTick = - stick + alert_delays[(gpioCfg.internals>>PI_CFG_ALERT_FREQ)&15]; - minDiff = gpioCfg.clockMicros / 2; + skippedAlert2Count = 0; + while (1) { newSlot = dmaCurrentSlot(dmaNowAtICB()); @@ -5305,16 +5344,17 @@ static void * pthAlertThread(void *x) oldLevel = reportedLevel & monitorBits; - /* Work through latest samples saving any level - changes of gpios of interest. + /* + Work through latest samples saving any level + changes of gpios of interest. */ - while ((oldSlot != newSlot) && (numSamples < DATUMS)) + while ((oldSlot != newSlot) && (numSamples < PIPE_MAX)) { level = myGetLevel(oldSlot++); - gpioSample[numSamples].tick = stick; - gpioSample[numSamples].level = level; + sample[numSamples].tick = stick; + sample[numSamples].level = level; numSamples++; @@ -5340,13 +5380,13 @@ static void * pthAlertThread(void *x) if (abs(diff) > minDiff) { - ft = gpioSample[numSamples-PULSE_PER_CYCLE].tick; + ft = sample[numSamples-PULSE_PER_CYCLE].tick; ticks = stick - ft; for (i=1; i 10000) + { + /* call alert 2 thread at least every 10 seconds */ - /* Write compacted samples. */ + triggerAlert2 = 1; + } + + if (compactedSamples) + { + numSamples = compactedSamples; + if (wdogBits) + alertWdogCheck(sample, numSamples, sample[numSamples-1].tick); + } + else + { + if (wdogBits) alertWdogCheck(sample, 0, sample[numSamples-1].tick); + + if (triggerAlert2) + { + /* emit a null report to trigger alert 2 thread */ + + sample[0].tick = sample[numSamples-1].tick; + sample[0].level = sample[numSamples-1].level; + numSamples = 1; + } + else numSamples = 0; + } + + if (numSamples) + { + write(fdAlertWrite, sample, numSamples * sizeof(gpioSample_t)); + + skippedAlert2Count = 0; + + /* once all outputs have been emitted set reported level */ + + reportedLevel = sample[numSamples-1].level; + + if (compactedSamples > gpioStats.maxSamples) + gpioStats.maxSamples = compactedSamples; + + gpioStats.numSamples += compactedSamples; + } + + /* Check that DMA is running okay */ + + if (dmaIn[DMA_CONBLK_AD]) + { + if (stopped) + { + DBG(DBG_STARTUP, "****** GOING ******"); + stopped = 0; + } + } + else + { + stopped = 1; + + myGpioDelay(5000); + + if (runState == PI_RUNNING) + { + /* should never be executed, leave code just in case */ + + gpioCfg.internals |= PI_CFG_STATS; + + dmaInitCbs(); + flushMemory(); + initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIBus[0]); + myGpioDelay(5000); /* let DMA run for a while */ + oldSlot = dmaCurrentSlot(dmaNowAtICB()); + gpioStats.DMARestarts++; + } + } + + req.tv_sec = 0; + req.tv_nsec = alert_delays[(gpioCfg.internals>>PI_CFG_ALERT_FREQ)&15]; + + if (moreToDo) + { + req.tv_nsec /= 2; + + gpioStats.moreToDo++; + } + else + { + gpioStats.alertTicks++; + } + + while (nanosleep(&req, &rem)) + { + req.tv_sec = rem.tv_sec; + req.tv_nsec = rem.tv_nsec; + } + } + + return 0; +} + +static void * pthAlert2Thread(void *x) +{ + uint32_t oldLevel, newLevel, reportedLevel; + uint32_t stick; + int32_t diff; + int emit, seqno, emitted; + uint32_t changes, bits, changedBits, timeoutBits; + int numSamples, d, i; + int b, n, v; + int err; + int max_emits; + int bytes; + char fifo[32]; + gpioSample_t sample[DATUMS]; + + while (fdAlertRead < 0) time_sleep(0.01) ; + + reportedLevel = gpioReg[GPLEV0]; + + oldLevel = reportedLevel & monitorBits; + + while (1) + { + bytes = read(fdAlertRead, sample, DATUMS * sizeof(gpioSample_t)); + + triggerAlert2 = 0; + + numSamples = bytes / sizeof(gpioSample_t); + + changedBits = 0; + + stick = sample[numSamples-1].tick; + + for (i=0; i 60000000) { if (numSamples) - newLevel = gpioSample[numSamples-1].level; + newLevel = sample[numSamples-1].level; else newLevel = reportedLevel; @@ -5646,6 +5826,7 @@ static void * pthAlertThread(void *x) gpioNotify[n].bits = 0; gpioNotify[n].state = PI_NOTIFY_CLOSING; + triggerAlert2 = 1; intNotifyBits(); break; } @@ -5684,6 +5865,7 @@ static void * pthAlertThread(void *x) /* serious error, no point continuing */ gpioNotify[n].bits = 0; gpioNotify[n].state = PI_NOTIFY_CLOSING; + triggerAlert2 = 1; intNotifyBits(); break; } @@ -5731,99 +5913,7 @@ static void * pthAlertThread(void *x) } } - /* once all outputs have been emitted set reported level */ - - if (numSamples) reportedLevel = gpioSample[numSamples-1].level; - - if (numSamples > gpioStats.maxSamples) - gpioStats.maxSamples = numSamples; - - gpioStats.numSamples += numSamples; - - /* Check that DMA is running okay */ - - if (dmaIn[DMA_CONBLK_AD]) - { - if (stopped) - { - DBG(DBG_STARTUP, "****** GOING ******"); - stopped = 0; - } - } - else - { - stopped = 1; - - myGpioDelay(5000); - - if (runState == PI_RUNNING) - { - /* should never be executed, leave code just in case */ - - gpioCfg.internals |= PI_CFG_STATS; - - dmaInitCbs(); - flushMemory(); - initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIBus[0]); - myGpioDelay(5000); /* let DMA run for a while */ - oldSlot = dmaCurrentSlot(dmaNowAtICB()); - gpioStats.DMARestarts++; - } - } - - nowTick = systReg[SYST_CLO]; - - if (moreToDo) - { - gpioStats.moreToDo++; - - /* rebase wake up time */ - - nextWakeTick = nowTick + - alert_delays[(gpioCfg.internals>>PI_CFG_ALERT_FREQ)&15]; - - req.tv_nsec = 0; - } - else - { - delayTicks = nextWakeTick - nowTick; - - if (delayTicks < 0) - { - gpioStats.lateTicks++; - - /* rebase wake up time */ - - nextWakeTick = nowTick + - alert_delays[(gpioCfg.internals>>PI_CFG_ALERT_FREQ)&15]; - - req.tv_nsec = 0; - } - else - { - gpioStats.alertTicks++; - - nextWakeTick += - alert_delays[(gpioCfg.internals>>PI_CFG_ALERT_FREQ)&15]; - - req.tv_nsec = (delayTicks * 1000); - } - } - - if (req.tv_nsec) - { - req.tv_sec = 0; - - while (nanosleep(&req, &rem)) - { - req.tv_sec = rem.tv_sec; - req.tv_nsec = rem.tv_nsec; - } - } - - nextWakeTick += - alert_delays[(gpioCfg.internals>>PI_CFG_ALERT_FREQ)&15]; - + if (numSamples) reportedLevel = sample[numSamples-1].level; } return 0; @@ -7143,8 +7233,14 @@ static void initClearGlobals(void) monitorBits = 0; notifyBits = 0; scriptBits = 0; + gFilterBits = 0; + nFilterBits = 0; + wdogBits = 0; - pthAlertRunning = 0; + triggerAlert2 = 0; + + pthAlert1Running = 0; + pthAlert2Running = 0; pthFifoRunning = 0; pthSocketRunning = 0; @@ -7219,9 +7315,11 @@ static void initClearGlobals(void) inpFifo = NULL; outFifo = NULL; - fdLock = -1; - fdMem = -1; - fdSock = -1; + fdLock = -1; + fdMem = -1; + fdSock = -1; + fdAlertRead = -1; + fdAlertWrite = -1; dmaMboxBlk = MAP_FAILED; dmaPMapBlk = MAP_FAILED; @@ -7270,11 +7368,18 @@ static void initReleaseResources(void) } } - if (pthAlertRunning) + if (pthAlert1Running) { - pthread_cancel(pthAlert); - pthread_join(pthAlert, NULL); - pthAlertRunning = 0; + pthread_cancel(pthAlert1); + pthread_join(pthAlert1, NULL); + pthAlert1Running = 0; + } + + if (pthAlert2Running) + { + pthread_cancel(pthAlert2); + pthread_join(pthAlert2, NULL); + pthAlert2Running = 0; } if (pthFifoRunning) @@ -7405,6 +7510,18 @@ static void initReleaseResources(void) fdMbox = -1; } + if (fdAlertRead != -1) + { + close(fdAlertRead); + fdAlertRead = -1; + } + + if (fdAlertWrite != -1) + { + close(fdAlertWrite); + fdAlertWrite = -1; + } + gpioStats.DMARestarts = 0; gpioStats.dmaInitCbsCount = 0; } @@ -7477,10 +7594,15 @@ int initInitialise(void) if (pthread_attr_setstacksize(&pthAttr, STACK_SIZE)) SOFT_ERROR(PI_INIT_FAILED, "pthread_attr_setstacksize failed (%m)"); - if (pthread_create(&pthAlert, &pthAttr, pthAlertThread, &i)) - SOFT_ERROR(PI_INIT_FAILED, "pthread_create alert failed (%m)"); + if (pthread_create(&pthAlert1, &pthAttr, pthAlert1Thread, &i)) + SOFT_ERROR(PI_INIT_FAILED, "pthread_create alert 1 failed (%m)"); - pthAlertRunning = 1; + pthAlert1Running = 1; + + if (pthread_create(&pthAlert2, &pthAttr, pthAlert2Thread, &i)) + SOFT_ERROR(PI_INIT_FAILED, "pthread_create alert 2 failed (%m)"); + + pthAlert2Running = 1; if (!(gpioCfg.ifFlags & PI_DISABLE_FIFO_IF)) { @@ -10396,9 +10518,11 @@ int gpioNotifyClose(unsigned handle) gpioNotify[handle].state = PI_NOTIFY_CLOSING; + triggerAlert2 = 1; + intNotifyBits(); - /* actual close done in alert thread */ + /* actual close done in alert2 thread */ return 0; } @@ -10451,6 +10575,9 @@ int gpioSetWatchdog(unsigned gpio, unsigned timeout) gpioAlert[gpio].wdTick = systReg[SYST_CLO]; gpioAlert[gpio].wdSteadyUs = timeout*1000; + if (timeout) wdogBits |= (1< 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; + gpioAlert[gpio].nfTick1 = systReg[SYST_CLO]; + gpioAlert[gpio].nfTick2 = gpioAlert[gpio].nfTick1; + gpioAlert[gpio].nfSteadyUs = steady; + gpioAlert[gpio].nfActiveUs = active; + gpioAlert[gpio].nfActive = 0; - if (steady) filterBits |= (1< #include #include -#define PIGPIO_VERSION 43 +#define PIGPIO_VERSION 44 /*TEXT @@ -2761,7 +2761,7 @@ Returns a handle (>=0) if OK, otherwise PI_NO_HANDLE, or PI_SER_OPEN_FAILED. The baud rate must be one of 50, 75, 110, 134, 150, -200, 300, 600, 1200, 1800, 2400, 4800, 9500, 19200, +200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, or 230400. No flags are currently defined. This parameter should be set to zero. diff --git a/pigpio.py b/pigpio.py index c46b9d2..4aa486f 100644 --- a/pigpio.py +++ b/pigpio.py @@ -123,7 +123,6 @@ 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 @@ -269,7 +268,7 @@ import threading import os import atexit -VERSION = "1.25" +VERSION = "1.26" exceptions = True @@ -962,6 +961,7 @@ class _callback: """ self._notify = notify self.count=0 + self._reset = False if func is None: func=self._tally self.callb = _callback_ADT(user_gpio, edge, func) @@ -973,6 +973,9 @@ class _callback: def _tally(self, user_gpio, level, tick): """Increment the callback called count.""" + if self._reset: + self._reset = False + self.count = 0 self.count += 1 def tally(self): @@ -985,6 +988,13 @@ class _callback: """ return self.count + def reset_tally(self): + """ + Resets the tally count to zero. + """ + self._reset = True + self.count = 0 + class _wait_for_edge: """Encapsulates waiting for gpio edges.""" @@ -3103,7 +3113,7 @@ class pi(): module instead. The baud rate must be one of 50, 75, 110, 134, 150, - 200, 300, 600, 1200, 1800, 2400, 4800, 9500, 19200, + 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, or 230400. ... @@ -3608,7 +3618,8 @@ class pi(): If a user callback is not specified a default tally callback is provided which simply counts edges. The count may be retrieved - by calling the tally function. + by calling the tally function. The count may be reset to zero + by calling the reset_tally function. The callback may be cancelled by calling the cancel function. @@ -3627,6 +3638,8 @@ class pi(): print(cb3.tally()) + cb3.reset_tally() + cb1.cancel() # To cancel callback cb1. ... """ @@ -3696,8 +3709,10 @@ class pi(): self.sl = _socklock() self._notify = None + port = int(port) + self._host = host - self._port = int(port) + self._port = port self.sl.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sl.s.settimeout(None) @@ -3706,23 +3721,22 @@ class pi(): self.sl.s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) try: - self.sl.s.connect((self._host, self._port)) - self._notify = _callback_thread(self.sl, self._host, self._port) + self.sl.s.connect((host, port)) + self._notify = _callback_thread(self.sl, host, port) except socket.error: self.connected = False if self.sl.s is not None: self.sl.s = None - if self._host == '': + if host == '': h = "localhost" else: - h = self._host + h = host - errStr = "Can't connect to pigpio on {}({})".format( - str(h), str(self._port)) + s = "Can't connect to pigpio at {}({})".format(str(h), str(port)) print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") - print(errStr) + print(s) print("") print("Did you start the pigpio daemon? E.g. sudo pigpiod") print("") @@ -3744,6 +3758,8 @@ class pi(): ... """ + self.connected = False + if self._notify is not None: self._notify.stop() self._notify = None @@ -4121,7 +4137,7 @@ def xref(): See [*gpio*]. wait_timeout: 0.0 - - The number of seconds to wait in wait_for_edge before timing out. + The number of seconds to wait in [*wait_for_edge*] before timing out. wave_add_*: One of [*wave_add_new*] , [*wave_add_generic*], [*wave_add_serial*]. diff --git a/pigpiod.1 b/pigpiod.1 index ef04989..fc5c0fa 100644 --- a/pigpiod.1 +++ b/pigpiod.1 @@ -60,7 +60,12 @@ disable fifo interface default enabled .IP "\fB-k\fP" -disable socket interface +disable local and remote socket interface + +default enabled + +.IP "\fB-l\fP" +disable remote socket interface default enabled @@ -79,6 +84,11 @@ clock peripheral 0=PWM 1=PCM default PCM +.IP "\fB-v -V\fP" +display pigpio version and exit + + + .IP "\fB-x mask\fP" gpios which may be updated A 54 bit mask with (1<=0) if OK, otherwise PI_NO_HANDLE, or PI_SER_OPEN_FAILED. The baud rate must be one of 50, 75, 110, 134, 150, -200, 300, 600, 1200, 1800, 2400, 4800, 9500, 19200, +200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, or 230400. No flags are currently defined. This parameter should be set to zero. diff --git a/pigpiod_if2.3 b/pigpiod_if2.3 index 9e3c251..533519c 100644 --- a/pigpiod_if2.3 +++ b/pigpiod_if2.3 @@ -3902,7 +3902,7 @@ PI_SER_OPEN_FAILED. .br The baud rate must be one of 50, 75, 110, 134, 150, -200, 300, 600, 1200, 1800, 2400, 4800, 9500, 19200, +200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, or 230400. .br diff --git a/pigpiod_if2.h b/pigpiod_if2.h index fda029a..60d4101 100644 --- a/pigpiod_if2.h +++ b/pigpiod_if2.h @@ -2429,7 +2429,7 @@ Returns a handle (>=0) if OK, otherwise PI_NO_HANDLE, or PI_SER_OPEN_FAILED. The baud rate must be one of 50, 75, 110, 134, 150, -200, 300, 600, 1200, 1800, 2400, 4800, 9500, 19200, +200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, or 230400. No flags are currently defined. This parameter should be set to zero. diff --git a/pigs.1 b/pigs.1 index afef3df..d46ec02 100644 --- a/pigs.1 +++ b/pigs.1 @@ -2421,7 +2421,7 @@ devices are /dev/ttyUSBx. .br The baud rate must be one of 50, 75, 110, 134, 150, -200, 300, 600, 1200, 1800, 2400, 4800, 9500, 19200, +200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, or 230400. .br diff --git a/pigs.c b/pigs.c index 2ee99e3..1e87d3c 100644 --- a/pigs.c +++ b/pigs.c @@ -168,7 +168,7 @@ void print_result(int sock, int rv, cmdCmd_t cmd) break; case 5: - printf(cmdUsage); + printf("%s", cmdUsage); break; case 6: /* BI2CZ CF2 I2CPK I2CRD I2CRI I2CRK I2CZ SERR SLR SPIX SPIR */ @@ -283,7 +283,7 @@ int main(int argc , char *argv[]) { if (command == PI_CMD_HELP) { - printf(cmdUsage); + printf("%s", cmdUsage); } else if (command == PI_CMD_PARSE) { diff --git a/setup.py b/setup.py index c58a792..15d792e 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from distutils.core import setup setup(name='pigpio', - version='1.25', + version='1.26', author='joan', author_email='joan@abyz.co.uk', maintainer='joan', diff --git a/x_pigpio.c b/x_pigpio.c index 9725094..4554950 100644 --- a/x_pigpio.c +++ b/x_pigpio.c @@ -82,7 +82,7 @@ void t1() CHECK(1, 6, v, 1, 0, "write, read"); } -int t2_count=0; +int t2_count; void t2cb(int gpio, int level, uint32_t tick) { @@ -100,6 +100,8 @@ void t2() f = gpioGetPWMfrequency(GPIO); CHECK(2, 1, f, 10, 0, "set PWM range, set/get PWM frequency"); + t2_count=0; + gpioSetAlertFunc(GPIO, t2cb); gpioPWM(GPIO, 0); @@ -155,12 +157,12 @@ void t2() gpioPWM(GPIO, 0); } -int t3_val = USERDATA; -int t3_reset=1; -int t3_count=0; -uint32_t t3_tick=0; -float t3_on=0.0; -float t3_off=0.0; +int t3_val; +int t3_reset; +int t3_count; +uint32_t t3_tick; +float t3_on; +float t3_off; void t3cbf(int gpio, int level, uint32_t tick, void *userdata) { @@ -217,6 +219,13 @@ void t3() printf("PWM/Servo pulse accuracy tests.\n"); + t3_val = USERDATA; + t3_reset=1; + t3_count=0; + t3_tick=0; + t3_on=0.0; + t3_off=0.0; + gpioSetAlertFuncEx(GPIO, t3cbf, &t3_val); /* test extended alert */ for (t=0; t<3; t++) @@ -327,7 +336,7 @@ void t4() CHECK(4, 6, n, 80, 10, "number of notifications"); } -int t5_count = 0; +int t5_count; void t5cbf(int gpio, int level, uint32_t tick) { @@ -369,6 +378,8 @@ To the lascivious pleasing of a lute.\n\ printf("Waveforms & serial read/write tests.\n"); + t5_count = 0; + gpioSetAlertFunc(GPIO, t5cbf); gpioSetMode(GPIO, PI_OUTPUT); @@ -445,9 +456,9 @@ To the lascivious pleasing of a lute.\n\ CHECK(5, 21, c, 25016, 0, "wave get max cbs"); } -int t6_count=0; -int t6_on=0; -uint32_t t6_on_tick=0; +int t6_count; +int t6_on; +uint32_t t6_on_tick; void t6cbf(int gpio, int level, uint32_t tick) { @@ -472,6 +483,10 @@ void t6() tp = 0; + t6_count=0; + t6_on=0; + t6_on_tick=0; + gpioSetAlertFunc(GPIO, t6cbf); for (t=0; t<5; t++) @@ -489,7 +504,7 @@ void t6() CHECK(6, 2, t6_on, tp, 25, "gpio trigger pulse length"); } -int t7_count=0; +int t7_count; void t7cbf(int gpio, int level, uint32_t tick) { @@ -502,6 +517,8 @@ void t7() printf("Watchdog tests.\n"); + t7_count=0; + /* type of edge shouldn't matter for watchdogs */ gpioSetAlertFunc(GPIO, t7cbf); @@ -559,7 +576,7 @@ void t8() CHECK(8, 9, 0, 0, 0, "NOT APPLICABLE"); } -int t9_count = 0; +int t9_count; void t9cbf(int gpio, int level, uint32_t tick) { @@ -590,6 +607,8 @@ void t9() gpioWrite(GPIO, 0); /* need known state */ + t9_count = 0; + gpioSetAlertFunc(GPIO, t9cbf); s = gpioStoreScript(script); diff --git a/x_pigpio.py b/x_pigpio.py index 2764d0b..261a71a 100755 --- a/x_pigpio.py +++ b/x_pigpio.py @@ -574,6 +574,13 @@ def t8(): pigpio.exceptions = True CHECK(8, 9, v, pigpio.PI_SOME_PERMITTED, 0, "set bank 2") +def t9waitNotHalted(s): + for check in range(10): + time.sleep(0.1) + e, p = pi.script_status(s) + if e != pigpio.PI_SCRIPT_HALTED: + return + def t9(): print("Script store/run/status/stop/delete tests.") @@ -609,28 +616,37 @@ def t9(): oc = t9cb.tally() pi.run_script(s, [99, GPIO]) + + t9waitNotHalted(s) + while True: e, p = pi.script_status(s) if e != pigpio.PI_SCRIPT_RUNNING: break time.sleep(0.1) - time.sleep(0.3) + time.sleep(0.2) c = t9cb.tally() - oc CHECK(9, 1, c, 100, 0, "store/run script") oc = t9cb.tally() pi.run_script(s, [200, GPIO]) + + t9waitNotHalted(s) + while True: e, p = pi.script_status(s) if e != pigpio.PI_SCRIPT_RUNNING: break time.sleep(0.1) - time.sleep(0.3) + time.sleep(0.2) c = t9cb.tally() - oc CHECK(9, 2, c, 201, 0, "run script/script status") oc = t9cb.tally() pi.run_script(s, [2000, GPIO]) + + t9waitNotHalted(s) + while True: e, p = pi.script_status(s) if e != pigpio.PI_SCRIPT_RUNNING: @@ -638,7 +654,7 @@ def t9(): if p[9] < 1900: pi.stop_script(s) time.sleep(0.1) - time.sleep(0.3) + time.sleep(0.2) c = t9cb.tally() - oc CHECK(9, 3, c, 110, 20, "run/stop script/script status") diff --git a/x_pigpiod_if.c b/x_pigpiod_if.c index a55f580..17fd8a8 100644 --- a/x_pigpiod_if.c +++ b/x_pigpiod_if.c @@ -113,6 +113,7 @@ void t2() dc = get_PWM_dutycycle(GPIO); CHECK(2, 4, dc, 128, 0, "get PWM dutycycle"); + time_sleep(0.2); oc = t2_count; time_sleep(2); f = t2_count - oc; @@ -122,6 +123,7 @@ void t2() f = get_PWM_frequency(GPIO); CHECK(2, 6, f, 100, 0, "set/get PWM frequency"); + time_sleep(0.2); oc = t2_count; time_sleep(2); f = t2_count - oc; @@ -131,6 +133,7 @@ void t2() f = get_PWM_frequency(GPIO); CHECK(2, 8, f, 1000, 0, "set/get PWM frequency"); + time_sleep(0.2); oc = t2_count; time_sleep(2); f = t2_count - oc; diff --git a/x_pigpiod_if2.c b/x_pigpiod_if2.c index 9af1a4a..ec2da1e 100644 --- a/x_pigpiod_if2.c +++ b/x_pigpiod_if2.c @@ -113,6 +113,7 @@ void t2(int pi) dc = get_PWM_dutycycle(pi, GPIO); CHECK(2, 4, dc, 128, 0, "get PWM dutycycle"); + time_sleep(0.2); oc = t2_count; time_sleep(2); f = t2_count - oc; @@ -122,6 +123,7 @@ void t2(int pi) f = get_PWM_frequency(pi, GPIO); CHECK(2, 6, f, 100, 0, "set/get PWM frequency"); + time_sleep(0.2); oc = t2_count; time_sleep(2); f = t2_count - oc; @@ -131,6 +133,7 @@ void t2(int pi) f = get_PWM_frequency(pi, GPIO); CHECK(2, 8, f, 1000, 0, "set/get PWM frequency"); + time_sleep(0.2); oc = t2_count; time_sleep(2); f = t2_count - oc; diff --git a/x_pigs b/x_pigs index 895ee70..8410f10 100755 --- a/x_pigs +++ b/x_pigs @@ -189,9 +189,9 @@ if [[ $s = "" ]]; then echo "SERVO-d ok"; else echo "SERVO-d fail ($s)"; fi s=$(pigs wvclr) if [[ $s = "" ]]; then echo "SLR-a ok"; else echo "SLR-a fail ($s)"; fi -s=$(pigs slro $GPIO 1200 8) +s=$(pigs slro $GPIO 4800 8) if [[ $s = "" ]]; then echo "SLR-b ok"; else echo "SLR-b fail ($s)"; fi -s=$(pigs wvas $GPIO 1200 8 2 0 0x6d 0x79 0x20 0x6e 0x61 0x6d 0x65 0x20 0x69 0x73 0x20 0x6a 0x6f 0x61 0x6e) +s=$(pigs wvas $GPIO 4800 8 2 0 0x6d 0x79 0x20 0x6e 0x61 0x6d 0x65 0x20 0x69 0x73 0x20 0x6a 0x6f 0x61 0x6e) if [[ $s = 95 ]]; then echo "SLR-c ok"; else echo "SLR-c fail ($s)"; fi s=$(pigs m $GPIO w) if [[ $s = "" ]]; then echo "SLR-d ok"; else echo "SLR-d fail ($s)"; fi @@ -199,7 +199,7 @@ w=$(pigs wvcre) if [[ $w -ge 0 ]]; then echo "WVCRE ok"; else echo "WVCRE fail ($s)"; fi s=$(pigs wvtx $w) if [[ $s = 191 ]]; then echo "SLR-e ok"; else echo "SLR-e fail ($s)"; fi -sleep 0.2 +sleep 0.4 s=$(pigs slr $GPIO 100) e="15 109 121 32 110 97 109 101 32 105 115 32 106 111 97 110" if [[ $s = $e ]] diff --git a/x_pipe b/x_pipe index 646b561..4b66a5f 100755 --- a/x_pipe +++ b/x_pipe @@ -261,10 +261,10 @@ if [[ $s = 0 ]]; then echo "SERVO-d ok"; else echo "SERVO-d fail ($s)"; fi echo "wvclr" >/dev/pigpio read -t 1 s /dev/pigpio +echo "slro $GPIO 4800 8" >/dev/pigpio read -t 1 s /dev/pigpio +echo "wvas $GPIO 4800 8 2 0 0x6d 0x79 0x20 0x6e 0x61 0x6d 0x65 0x20 0x69 0x73 0x20 0x6a 0x6f 0x61 0x6e" >/dev/pigpio read -t 1 s /dev/pigpio @@ -276,7 +276,7 @@ if [[ $w -ge 0 ]]; then echo "WVCRE ok"; else echo "WVCRE fail ($w)"; fi echo "wvtx $w" >/dev/pigpio read -t 1 s /dev/pigpio read -t 1 s