." Process this file with
." groff -man -Tascii pig2vcd.1
."
-.TH pig2vcd 1 2012-2015 Linux "pigpio archive"
+.TH pig2vcd 1 2012-2017 Linux "pigpio archive"
.SH NAME
pig2vd - A utility to convert pigpio notifications to VCD.
." Process this file with
." groff -man -Tascii pigpio.3
."
-.TH pigpio 3 2012-2015 Linux "pigpio archive"
+.TH pigpio 3 2012-2017 Linux "pigpio archive"
.SH NAME
pigpio - A C library to manipulate the Pi's GPIO.
.br
.br
-One function may be registered per GPIO.
+One callback may be registered per GPIO.
+
+.br
+
+.br
+The callback is passed the GPIO, the new level, and the tick.
+
+.br
+
+.br
+.EX
+Parameter Value Meaning
.br
.br
-The function is passed the GPIO, the new level, and the tick.
+GPIO 0-31 The GPIO which has changed state
+.br
+
+.br
+level 0-2 0 = change to low (a falling edge)
+.br
+ 1 = change to high (a rising edge)
+.br
+ 2 = no level change (a watchdog timeout)
+.br
+
+.br
+tick 32 bit The number of microseconds since boot
+.br
+ WARNING: this wraps around from
+.br
+ 4294967295 to 0 roughly every 72 minutes
+.br
+
+.EE
.br
.br
.br
-One function may be registered per GPIO.
+One callback may be registered per GPIO.
.br
.br
-The function is passed the GPIO, the new level, the tick, and
+The callback is passed the GPIO, the new level, the tick, and
the userdata pointer.
.br
.br
-Only one of \fBgpioSetAlertFunc\fP or \fBgpioSetAlertFuncEx\fP can be
-registered per GPIO.
+
+.EX
+Parameter Value Meaning
+.br
+
+.br
+GPIO 0-31 The GPIO which has changed state
+.br
+
+.br
+level 0-2 0 = change to low (a falling edge)
+.br
+ 1 = change to high (a rising edge)
+.br
+ 2 = no level change (a watchdog timeout)
+.br
+
+.br
+tick 32 bit The number of microseconds since boot
+.br
+ WARNING: this wraps around from
+.br
+ 4294967295 to 0 roughly every 72 minutes
+.br
+
+.br
+userdata pointer Pointer to an arbitrary object
+.br
+
+.EE
.br
.br
See \fBgpioSetAlertFunc\fP for further details.
-.IP "\fBint gpioSetISRFunc(unsigned user_gpio, unsigned edge, int timeout, gpioISRFunc_t f)\fP"
+.br
+
+.br
+Only one of \fBgpioSetAlertFunc\fP or \fBgpioSetAlertFuncEx\fP can be
+registered per GPIO.
+
+.IP "\fBint gpioSetISRFunc(unsigned gpio, unsigned edge, int timeout, gpioISRFunc_t f)\fP"
.IP "" 4
Registers a function to be called (a callback) whenever the specified
GPIO interrupt occurs.
.br
.EX
-user_gpio: 0-31
+ gpio: 0-53
.br
- edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE
+ edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE
.br
- timeout: interrupt timeout in milliseconds (<=0 to cancel)
+timeout: interrupt timeout in milliseconds (<=0 to cancel)
.br
- f: the callback function
+ f: the callback function
.br
.EE
.br
.br
-Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_EDGE,
+Returns 0 if OK, otherwise PI_BAD_GPIO, PI_BAD_EDGE,
or PI_BAD_ISR_INIT.
.br
kernel (i.e. this mechanism can not be used to capture several
interrupts only a few microseconds apart).
-.IP "\fBint gpioSetISRFuncEx(unsigned user_gpio, unsigned edge, int timeout, gpioISRFuncEx_t f, void *userdata)\fP"
+.IP "\fBint gpioSetISRFuncEx(unsigned gpio, unsigned edge, int timeout, gpioISRFuncEx_t f, void *userdata)\fP"
.IP "" 4
Registers a function to be called (a callback) whenever the specified
GPIO interrupt occurs.
.br
.EX
-user_gpio: 0-31
+ gpio: 0-53
.br
- edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE
+ edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE
.br
- timeout: interrupt timeout in milliseconds (<=0 to cancel)
+ timeout: interrupt timeout in milliseconds (<=0 to cancel)
.br
- f: the callback function
+ f: the callback function
.br
- userdata: pointer to arbitrary user data
+userdata: pointer to arbitrary user data
.br
.EE
.br
.br
-Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_EDGE,
+Returns 0 if OK, otherwise PI_BAD_GPIO, PI_BAD_EDGE,
or PI_BAD_ISR_INIT.
.br
.br
.br
-For bits 1-8 there will be one byte per character.
+For bits 1-8 there will be one byte per word.
+.br
+For bits 9-16 there will be two bytes per word.
.br
-For bits 9-16 there will be two bytes per character.
+For bits 17-32 there will be four bytes per word.
+
+.br
+
.br
-For bits 17-32 there will be four bytes per character.
+Multi-byte transfers are made in least significant byte first order.
.br
.br
-E.g. to transfer 32 12-bit words buf should contain 64 bytes
+E.g. to transfer 32 11-bit words buf should contain 64 bytes
and count should be 64.
.br
+.br
+E.g. to transfer the 14 bit value 0x1ABC send the bytes 0xBC followed
+by 0x1A.
+
+.br
+
.br
The other bits in flags should be set to zero.
.br
.br
-If no level change has been detected for the GPIO for timeout
-milliseconds:-
+Until cancelled a timeout will be reported every timeout milliseconds
+after the last GPIO activity.
.br
.br
-1) any registered alert function for the GPIO is called with
+In particular:
+
+.br
+
+.br
+1) any registered alert function for the GPIO will be called with
the level set to PI_TIMEOUT.
+
+.br
+
.br
-2) any notification for the GPIO has a report written to the
+2) any notification for the GPIO will have a report written to the
fifo with the flags set to indicate a watchdog timeout.
.br
.br
.br
-Note, level changes before and after the active period may
+This filter affects the GPIO samples returned to callbacks set up
+with \fBgpioSetAlertFunc\fP, \fBgpioSetAlertFuncEx\fP, \fBgpioSetGetSamplesFunc\fP,
+and \fBgpioSetGetSamplesFuncEx\fP.
+
+.br
+
+.br
+It does not affect interrupts set up with \fBgpioSetISRFunc\fP,
+\fBgpioSetISRFuncEx\fP, or levels read by \fBgpioRead\fP,
+\fBgpioRead_Bits_0_31\fP, or \fBgpioRead_Bits_32_53\fP.
+
+.br
+
+.br
+Level changes before and after the active period may
be reported. Your software must be designed to cope with
such reports.
.br
.br
-Note, each (stable) edge will be timestamped \fBsteady\fP microseconds
+This filter affects the GPIO samples returned to callbacks set up
+with \fBgpioSetAlertFunc\fP, \fBgpioSetAlertFuncEx\fP, \fBgpioSetGetSamplesFunc\fP,
+and \fBgpioSetGetSamplesFuncEx\fP.
+
+.br
+
+.br
+It does not affect interrupts set up with \fBgpioSetISRFunc\fP,
+\fBgpioSetISRFuncEx\fP, or levels read by \fBgpioRead\fP,
+\fBgpioRead_Bits_0_31\fP, or \fBgpioRead_Bits_32_53\fP.
+
+.br
+
+.br
+Each (stable) edge will be timestamped \fBsteady\fP microseconds
after it was first detected.
.IP "\fBint gpioSetGetSamplesFunc(gpioGetSamplesFunc_t f, uint32_t bits)\fP"
For more information, please refer to <http://unlicense.org/>
*/
-/* pigpio version 62 */
+/* pigpio version 63 */
/* include ------------------------------------------------------- */
#define TICKSLOTS 50
-#define PI_I2C_CLOSED 0
-#define PI_I2C_OPENED 1
+#define PI_I2C_CLOSED 0
+#define PI_I2C_RESERVED 1
+#define PI_I2C_OPENED 2
-#define PI_SPI_CLOSED 0
-#define PI_SPI_OPENED 1
+#define PI_SPI_CLOSED 0
+#define PI_SPI_RESERVED 1
+#define PI_SPI_OPENED 2
-#define PI_SER_CLOSED 0
-#define PI_SER_OPENED 1
+#define PI_SER_CLOSED 0
+#define PI_SER_RESERVED 1
+#define PI_SER_OPENED 2
-#define PI_FILE_CLOSED 0
-#define PI_FILE_OPENED 1
+#define PI_FILE_CLOSED 0
+#define PI_FILE_RESERVED 1
+#define PI_FILE_OPENED 2
-#define PI_NOTIFY_CLOSED 0
-#define PI_NOTIFY_CLOSING 1
-#define PI_NOTIFY_OPENED 2
-#define PI_NOTIFY_RUNNING 3
-#define PI_NOTIFY_PAUSED 4
+#define PI_NOTIFY_CLOSED 0
+#define PI_NOTIFY_RESERVED 1
+#define PI_NOTIFY_CLOSING 2
+#define PI_NOTIFY_OPENED 3
+#define PI_NOTIFY_RUNNING 4
+#define PI_NOTIFY_PAUSED 5
#define PI_WFRX_NONE 0
#define PI_WFRX_SERIAL 1
#define PI_RUNNING 1
#define PI_ENDING 2
+#define PI_THREAD_NONE 0
+#define PI_THREAD_STARTED 1
+#define PI_THREAD_RUNNING 2
+
#define PI_MAX_PATH 512
/* typedef ------------------------------------------------------- */
static volatile int runState = PI_STARTING;
-static int pthAlertRunning = 0;
-static int pthFifoRunning = 0;
-static int pthSocketRunning = 0;
+static int pthAlertRunning = PI_THREAD_NONE;
+static int pthFifoRunning = PI_THREAD_NONE;
+static int pthSocketRunning = PI_THREAD_NONE;
static gpioAlert_t gpioAlert [PI_MAX_USER_GPIO+1];
static eventAlert_t eventAlert [PI_MAX_EVENT+1];
-static gpioISR_t gpioISR [PI_MAX_USER_GPIO+1];
+static gpioISR_t gpioISR [PI_MAX_GPIO+1];
static gpioGetSamples_t gpioGetSamples;
static int pwmFreq[PWM_FREQS];
-static pthread_mutex_t spi_main_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t spi_aux_mutex = PTHREAD_MUTEX_INITIALIZER;
-
/* reset after gpioTerminated */
/* resources which must be released on gpioTerminate */
if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
- if (i2cInfo[handle].state == PI_I2C_CLOSED)
+ if (i2cInfo[handle].state != PI_I2C_OPENED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_QUICK) == 0)
if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
- if (i2cInfo[handle].state == PI_I2C_CLOSED)
+ if (i2cInfo[handle].state != PI_I2C_OPENED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_BYTE) == 0)
if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
- if (i2cInfo[handle].state == PI_I2C_CLOSED)
+ if (i2cInfo[handle].state != PI_I2C_OPENED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_BYTE) == 0)
if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
- if (i2cInfo[handle].state == PI_I2C_CLOSED)
+ if (i2cInfo[handle].state != PI_I2C_OPENED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_BYTE_DATA) == 0)
if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
- if (i2cInfo[handle].state == PI_I2C_CLOSED)
+ if (i2cInfo[handle].state != PI_I2C_OPENED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_BYTE_DATA) == 0)
if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
- if (i2cInfo[handle].state == PI_I2C_CLOSED)
+ if (i2cInfo[handle].state != PI_I2C_OPENED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_WORD_DATA) == 0)
if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
- if (i2cInfo[handle].state == PI_I2C_CLOSED)
+ if (i2cInfo[handle].state != PI_I2C_OPENED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_WORD_DATA) == 0)
if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
- if (i2cInfo[handle].state == PI_I2C_CLOSED)
+ if (i2cInfo[handle].state != PI_I2C_OPENED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_PROC_CALL) == 0)
if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
- if (i2cInfo[handle].state == PI_I2C_CLOSED)
+ if (i2cInfo[handle].state != PI_I2C_OPENED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_BLOCK_DATA) == 0)
if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
- if (i2cInfo[handle].state == PI_I2C_CLOSED)
+ if (i2cInfo[handle].state != PI_I2C_OPENED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) == 0)
if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
- if (i2cInfo[handle].state == PI_I2C_CLOSED)
+ if (i2cInfo[handle].state != PI_I2C_OPENED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_PROC_CALL) == 0)
if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
- if (i2cInfo[handle].state == PI_I2C_CLOSED)
+ if (i2cInfo[handle].state != PI_I2C_OPENED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_I2C_BLOCK) == 0)
if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
- if (i2cInfo[handle].state == PI_I2C_CLOSED)
+ if (i2cInfo[handle].state != PI_I2C_OPENED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) == 0)
if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
- if (i2cInfo[handle].state == PI_I2C_CLOSED)
+ if (i2cInfo[handle].state != PI_I2C_OPENED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((count < 1) || (count > PI_MAX_I2C_DEVICE_COUNT))
if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
- if (i2cInfo[handle].state == PI_I2C_CLOSED)
+ if (i2cInfo[handle].state != PI_I2C_OPENED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((count < 1) || (count > PI_MAX_I2C_DEVICE_COUNT))
int i2cOpen(unsigned i2cBus, unsigned i2cAddr, unsigned i2cFlags)
{
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
char dev[32];
int i, slot, fd;
uint32_t funcs;
slot = -1;
+ pthread_mutex_lock(&mutex);
+
for (i=0; i<PI_I2C_SLOTS; i++)
{
if (i2cInfo[i].state == PI_I2C_CLOSED)
{
- i2cInfo[i].state = PI_I2C_OPENED;
slot = i;
+ i2cInfo[slot].state = PI_I2C_RESERVED;
break;
}
}
- if (slot < 0)
- SOFT_ERROR(PI_NO_HANDLE, "no I2C handles");
+ pthread_mutex_unlock(&mutex);
+
+ if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no I2C handles");
sprintf(dev, "/dev/i2c-%d", i2cBus);
/* try a modprobe */
system("/sbin/modprobe i2c_dev");
- system("/sbin/modprobe i2c_bcm2708");
+ system("/sbin/modprobe i2c_bcm2835");
myGpioDelay(100000);
i2cInfo[slot].addr = i2cAddr;
i2cInfo[slot].flags = i2cFlags;
i2cInfo[slot].funcs = funcs;
+ i2cInfo[i].state = PI_I2C_OPENED;
return slot;
}
char *rxBuf,
unsigned count)
{
+ static pthread_mutex_t main_mutex = PTHREAD_MUTEX_INITIALIZER;
+ static pthread_mutex_t aux_mutex = PTHREAD_MUTEX_INITIALIZER;
+
if (PI_SPI_FLAGS_GET_AUX_SPI(flags))
{
- pthread_mutex_lock(&spi_aux_mutex);
+ pthread_mutex_lock(&aux_mutex);
spiGoA(speed, flags, txBuf, rxBuf, count);
- pthread_mutex_unlock(&spi_aux_mutex);
+ pthread_mutex_unlock(&aux_mutex);
}
else
{
- pthread_mutex_lock(&spi_main_mutex);
+ pthread_mutex_lock(&main_mutex);
spiGoS(speed, flags, txBuf, rxBuf, count);
- pthread_mutex_unlock(&spi_main_mutex);
+ pthread_mutex_unlock(&main_mutex);
}
}
int spiOpen(unsigned spiChan, unsigned baud, unsigned spiFlags)
{
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int i, slot;
DBG(DBG_USER, "spiChan=%d baud=%d spiFlags=0x%X",
slot = -1;
+ pthread_mutex_lock(&mutex);
+
for (i=0; i<PI_SPI_SLOTS; i++)
{
if (spiInfo[i].state == PI_SPI_CLOSED)
{
- spiInfo[i].state = PI_SPI_OPENED;
slot = i;
+ spiInfo[slot].state = PI_SPI_RESERVED;
break;
}
}
- if (slot < 0)
- SOFT_ERROR(PI_NO_HANDLE, "no SPI handles");
+ pthread_mutex_unlock(&mutex);
+
+ if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no SPI handles");
spiInfo[slot].speed = baud;
spiInfo[slot].flags = spiFlags | PI_SPI_FLAGS_CHANNEL(spiChan);
+ spiInfo[slot].state = PI_SPI_OPENED;
return slot;
}
int serOpen(char *tty, unsigned serBaud, unsigned serFlags)
{
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
struct termios new;
int speed;
int fd;
slot = -1;
+ pthread_mutex_lock(&mutex);
+
for (i=0; i<PI_SER_SLOTS; i++)
{
if (serInfo[i].state == PI_SER_CLOSED)
{
- serInfo[i].state = PI_SER_OPENED;
slot = i;
+ serInfo[slot].state = PI_SER_RESERVED;
break;
}
}
- if (slot < 0)
- SOFT_ERROR(PI_NO_HANDLE, "no serial handles");
+ pthread_mutex_unlock(&mutex);
+
+ if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no serial handles");
if ((fd = open(tty, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)
{
serInfo[slot].fd = fd;
serInfo[slot].flags = serFlags;
+ serInfo[slot].state = PI_SER_OPENED;
return slot;
}
gpioNotify[n].state = PI_NOTIFY_CLOSED;
}
- else if (gpioNotify[n].state != PI_NOTIFY_CLOSED)
+ else if (gpioNotify[n].state >= PI_NOTIFY_OPENED)
{
bits = gpioNotify[n].bits;
if (!emit)
{
- if ((eTick - gpioNotify[n].lastReportTick) > 60000000)
+ if ((int)(eTick - gpioNotify[n].lastReportTick) > 60000000)
{
if (numSamples)
newLevel = sample[numSamples-1].level;
{
stickInited = 1;
numSamples = 0;
+ pthAlertRunning = PI_THREAD_RUNNING;
}
}
}
nFilterBits = 0;
wdogBits = 0;
- pthAlertRunning = 0;
- pthFifoRunning = 0;
- pthSocketRunning = 0;
+ pthAlertRunning = PI_THREAD_NONE;
+ pthFifoRunning = PI_THREAD_NONE;
+ pthSocketRunning = PI_THREAD_NONE;
wfc[0] = 0;
wfc[1] = 0;
/* shut down running threads */
- for (i=0; i<=PI_MAX_USER_GPIO; i++)
+ for (i=0; i<=PI_MAX_GPIO; i++)
{
if (gpioISR[i].pth)
{
}
}
- if (pthAlertRunning)
+ if (pthAlertRunning != PI_THREAD_NONE)
{
pthread_cancel(pthAlert);
pthread_join(pthAlert, NULL);
- pthAlertRunning = 0;
+ pthAlertRunning = PI_THREAD_NONE;
}
- if (pthFifoRunning)
+ if (pthFifoRunning != PI_THREAD_NONE)
{
pthread_cancel(pthFifo);
pthread_join(pthFifo, NULL);
- pthFifoRunning = 0;
+ pthFifoRunning = PI_THREAD_NONE;
}
- if (pthSocketRunning)
+ if (pthSocketRunning != PI_THREAD_NONE)
{
pthread_cancel(pthSocket);
pthread_join(pthSocket, NULL);
- pthSocketRunning = 0;
+ pthSocketRunning = PI_THREAD_NONE;
}
/* release mmap'd memory */
if (pthread_create(&pthAlert, &pthAttr, pthAlertThread, &i))
SOFT_ERROR(PI_INIT_FAILED, "pthread_create alert failed (%m)");
- pthAlertRunning = 1;
+ pthAlertRunning = PI_THREAD_STARTED;
if (!(gpioCfg.ifFlags & PI_DISABLE_FIFO_IF))
{
if (pthread_create(&pthFifo, &pthAttr, pthFifoThread, &i))
SOFT_ERROR(PI_INIT_FAILED, "pthread_create fifo failed (%m)");
- pthFifoRunning = 1;
+ pthFifoRunning = PI_THREAD_STARTED;
}
if (!(gpioCfg.ifFlags & PI_DISABLE_SOCK_IF))
if (pthread_create(&pthSocket, &pthAttr, pthSocketThread, &i))
SOFT_ERROR(PI_INIT_FAILED, "pthread_create socket failed (%m)");
- pthSocketRunning = 1;
+ pthSocketRunning = PI_THREAD_STARTED;
}
- myGpioDelay(10000);
+ myGpioDelay(1000);
dmaInitCbs();
initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIBus[0]);
- myGpioDelay(20000);
-
return PIGPIO_VERSION;
}
else
{
libInitialised = 1;
+
runState = PI_RUNNING;
+
+ while (pthAlertRunning != PI_THREAD_RUNNING) myGpioDelay(1000);
}
return status;
CHECK_INITED;
- if (gpio > PI_MAX_USER_GPIO)
- SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
+ if (gpio > PI_MAX_GPIO)
+ SOFT_ERROR(PI_BAD_GPIO, "bad gpio (%d)", gpio);
if (edge > EITHER_EDGE)
SOFT_ERROR(PI_BAD_EDGE, "bad ISR edge (%d)", edge);
CHECK_INITED;
- if (gpio > PI_MAX_USER_GPIO)
- SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
+ if (gpio > PI_MAX_GPIO)
+ SOFT_ERROR(PI_BAD_GPIO, "bad gpio (%d)", gpio);
if (edge > EITHER_EDGE)
SOFT_ERROR(PI_BAD_EDGE, "bad ISR edge (%d)", edge);
for (i=0; i<PI_NOTIFY_SLOTS; i++)
{
if ((i != slot) &&
- (gpioNotify[i].state != PI_NOTIFY_CLOSED) &&
+ (gpioNotify[i].state >= PI_NOTIFY_OPENED) &&
(gpioNotify[i].fd == fd))
{
DBG(DBG_USER, "closed orphaned fd=%d (handle=%d)", fd, i);
/* ----------------------------------------------------------------------- */
+static void notifyMutex(int lock)
+{
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+ if (lock) pthread_mutex_lock(&mutex);
+ else pthread_mutex_unlock(&mutex);
+}
+
+/* ----------------------------------------------------------------------- */
+
int gpioNotifyOpenWithSize(int bufSize)
{
int i, slot, fd;
slot = -1;
+ notifyMutex(1);
+
for (i=0; i<PI_NOTIFY_SLOTS; i++)
{
if (gpioNotify[i].state == PI_NOTIFY_CLOSED)
{
- gpioNotify[i].state = PI_NOTIFY_OPENED;
slot = i;
+ gpioNotify[slot].state = PI_NOTIFY_RESERVED;
break;
}
}
- if (slot < 0)
- SOFT_ERROR(PI_NO_HANDLE, "no handle");
+ notifyMutex(0);
+
+ if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no handle");
sprintf(name, "/dev/pigpio%d", slot);
gpioNotify[slot].pipe = 1;
gpioNotify[slot].max_emits = MAX_EMITS;
gpioNotify[slot].lastReportTick = gpioTick();
+ gpioNotify[i].state = PI_NOTIFY_OPENED;
closeOrphanedNotifications(slot, fd);
slot = -1;
+ notifyMutex(1);
+
for (i=0; i<PI_NOTIFY_SLOTS; i++)
{
if (gpioNotify[i].state == PI_NOTIFY_CLOSED)
{
slot = i;
+ gpioNotify[slot].state = PI_NOTIFY_RESERVED;
break;
}
}
+ notifyMutex(0);
+
if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no handle");
- gpioNotify[slot].state = PI_NOTIFY_OPENED;
gpioNotify[slot].seqno = 0;
gpioNotify[slot].bits = 0;
gpioNotify[slot].fd = fd;
gpioNotify[slot].pipe = 0;
gpioNotify[slot].max_emits = MAX_EMITS;
gpioNotify[slot].lastReportTick = gpioTick();
+ gpioNotify[slot].state = PI_NOTIFY_OPENED;
closeOrphanedNotifications(slot, fd);
int gpioStoreScript(char *script)
{
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
gpioScript_t *s;
int status, slot, i;
slot = -1;
+ pthread_mutex_lock(&mutex);
+
for (i=0; i<PI_MAX_SCRIPTS; i++)
{
if (gpioScript[i].state == PI_SCRIPT_FREE)
{
- gpioScript[i].state = PI_SCRIPT_RESERVED;
slot = i;
+ gpioScript[slot].state = PI_SCRIPT_RESERVED;
break;
}
}
- if (slot < 0)
- SOFT_ERROR(PI_NO_SCRIPT_ROOM, "no room for scripts");
+ pthread_mutex_unlock(&mutex);
+
+ if (slot < 0) SOFT_ERROR(PI_NO_SCRIPT_ROOM, "no room for scripts");
s = &gpioScript[slot];
s->pthIdp = gpioStartThread(pthScript, s);
status = slot;
-
}
else
{
int fileOpen(char *file, unsigned mode)
{
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int fd=-1;
int i, slot, oflag, omode;
struct stat statbuf;
slot = -1;
+ pthread_mutex_lock(&mutex);
+
for (i=0; i<PI_FILE_SLOTS; i++)
{
if (fileInfo[i].state == PI_FILE_CLOSED)
{
- fileInfo[i].state = PI_FILE_OPENED;
slot = i;
+ fileInfo[slot].state = PI_FILE_RESERVED;
break;
}
}
- if (slot < 0)
- SOFT_ERROR(PI_NO_HANDLE, "no file handles");
+ pthread_mutex_unlock(&mutex);
+
+ if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no file handles");
omode = 0;
oflag = 0;
fileInfo[slot].fd = fd;
fileInfo[slot].mode = mode;
+ fileInfo[slot].state = PI_FILE_OPENED;
return slot;
}
#include <stdint.h>
#include <pthread.h>
-#define PIGPIO_VERSION 62
+#define PIGPIO_VERSION 63
/*TEXT
Returns 0 if OK, otherwise PI_BAD_USER_GPIO.
-One function may be registered per GPIO.
+One callback may be registered per GPIO.
+
+The callback is passed the GPIO, the new level, and the tick.
+
+. .
+Parameter Value Meaning
+
+GPIO 0-31 The GPIO which has changed state
-The function is passed the GPIO, the new level, and the tick.
+level 0-2 0 = change to low (a falling edge)
+ 1 = change to high (a rising edge)
+ 2 = no level change (a watchdog timeout)
+
+tick 32 bit The number of microseconds since boot
+ WARNING: this wraps around from
+ 4294967295 to 0 roughly every 72 minutes
+. .
The alert may be cancelled by passing NULL as the function.
Returns 0 if OK, otherwise PI_BAD_USER_GPIO.
-One function may be registered per GPIO.
+One callback may be registered per GPIO.
-The function is passed the GPIO, the new level, the tick, and
+The callback is passed the GPIO, the new level, the tick, and
the userdata pointer.
-Only one of [*gpioSetAlertFunc*] or [*gpioSetAlertFuncEx*] can be
-registered per GPIO.
+. .
+Parameter Value Meaning
+
+GPIO 0-31 The GPIO which has changed state
+
+level 0-2 0 = change to low (a falling edge)
+ 1 = change to high (a rising edge)
+ 2 = no level change (a watchdog timeout)
+
+tick 32 bit The number of microseconds since boot
+ WARNING: this wraps around from
+ 4294967295 to 0 roughly every 72 minutes
+
+userdata pointer Pointer to an arbitrary object
+. .
See [*gpioSetAlertFunc*] for further details.
+
+Only one of [*gpioSetAlertFunc*] or [*gpioSetAlertFuncEx*] can be
+registered per GPIO.
D*/
/*F*/
int gpioSetISRFunc(
- unsigned user_gpio, unsigned edge, int timeout, gpioISRFunc_t f);
+ unsigned gpio, unsigned edge, int timeout, gpioISRFunc_t f);
/*D
Registers a function to be called (a callback) whenever the specified
GPIO interrupt occurs.
. .
-user_gpio: 0-31
- edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE
- timeout: interrupt timeout in milliseconds (<=0 to cancel)
- f: the callback function
+ gpio: 0-53
+ edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE
+timeout: interrupt timeout in milliseconds (<=0 to cancel)
+ f: the callback function
. .
-Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_EDGE,
+Returns 0 if OK, otherwise PI_BAD_GPIO, PI_BAD_EDGE,
or PI_BAD_ISR_INIT.
One function may be registered per GPIO.
/*F*/
int gpioSetISRFuncEx(
- unsigned user_gpio,
+ unsigned gpio,
unsigned edge,
int timeout,
gpioISRFuncEx_t f,
GPIO interrupt occurs.
. .
-user_gpio: 0-31
- edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE
- timeout: interrupt timeout in milliseconds (<=0 to cancel)
- f: the callback function
- userdata: pointer to arbitrary user data
+ gpio: 0-53
+ edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE
+ timeout: interrupt timeout in milliseconds (<=0 to cancel)
+ f: the callback function
+userdata: pointer to arbitrary user data
. .
-Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_EDGE,
+Returns 0 if OK, otherwise PI_BAD_GPIO, PI_BAD_EDGE,
or PI_BAD_ISR_INIT.
The function is passed the GPIO, the current level, the
transfer data packed into 1, 2, or 4 bytes according to
the word size in bits.
-For bits 1-8 there will be one byte per character.
-For bits 9-16 there will be two bytes per character.
-For bits 17-32 there will be four bytes per character.
+For bits 1-8 there will be one byte per word.
+For bits 9-16 there will be two bytes per word.
+For bits 17-32 there will be four bytes per word.
-E.g. to transfer 32 12-bit words buf should contain 64 bytes
+Multi-byte transfers are made in least significant byte first order.
+
+E.g. to transfer 32 11-bit words buf should contain 64 bytes
and count should be 64.
+E.g. to transfer the 14 bit value 0x1ABC send the bytes 0xBC followed
+by 0x1A.
+
The other bits in flags should be set to zero.
D*/
The watchdog may be cancelled by setting timeout to 0.
-If no level change has been detected for the GPIO for timeout
-milliseconds:-
+Until cancelled a timeout will be reported every timeout milliseconds
+after the last GPIO activity.
+
+In particular:
+
+1) any registered alert function for the GPIO will be called with
+ the level set to PI_TIMEOUT.
-1) any registered alert function for the GPIO is called with
- the level set to PI_TIMEOUT.
-2) any notification for the GPIO has a report written to the
+2) any notification for the GPIO will have a report written to the
fifo with the flags set to indicate a watchdog timeout.
...
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
-Note, level changes before and after the active period may
+This filter affects the GPIO samples returned to callbacks set up
+with [*gpioSetAlertFunc*], [*gpioSetAlertFuncEx*], [*gpioSetGetSamplesFunc*],
+and [*gpioSetGetSamplesFuncEx*].
+
+It does not affect interrupts set up with [*gpioSetISRFunc*],
+[*gpioSetISRFuncEx*], or levels read by [*gpioRead*],
+[*gpioRead_Bits_0_31*], or [*gpioRead_Bits_32_53*].
+
+Level changes before and after the active period may
be reported. Your software must be designed to cope with
such reports.
D*/
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
-Note, each (stable) edge will be timestamped [*steady*] microseconds
+This filter affects the GPIO samples returned to callbacks set up
+with [*gpioSetAlertFunc*], [*gpioSetAlertFuncEx*], [*gpioSetGetSamplesFunc*],
+and [*gpioSetGetSamplesFuncEx*].
+
+It does not affect interrupts set up with [*gpioSetISRFunc*],
+[*gpioSetISRFuncEx*], or levels read by [*gpioRead*],
+[*gpioRead_Bits_0_31*], or [*gpioRead_Bits_32_53*].
+
+Each (stable) edge will be timestamped [*steady*] microseconds
after it was first detected.
D*/
import os
import atexit
-VERSION = "1.36"
+VERSION = "1.37"
exceptions = True
EVENT_BSC = 31
+_SOCK_CMD_LEN = 16
+
# pigpio command numbers
_PI_CMD_MODES= 0
Do you have permission to access the pigpio daemon?
Perhaps it was started with sudo pigpiod -nlocalhost"""
+_except_3 = """
+Can't create callback thread.
+Perhaps too many simultaneous pigpio connections."""
+
class _socklock:
"""
A class to store socket and lock.
sl:= command socket and lock.
cmd:= the command to be executed.
p1:= command parameter 1 (if applicable).
- p2:= command parameter 2 (if applicable).
+ p2:= command parameter 2 (if applicable).
"""
sl.l.acquire()
sl.s.send(struct.pack('IIII', cmd, p1, p2, 0))
- dummy, res = struct.unpack('12sI', sl.s.recv(16))
+ dummy, res = struct.unpack('12sI', sl.s.recv(_SOCK_CMD_LEN))
if rl: sl.l.release()
return res
ext.extend(x)
sl.l.acquire()
sl.s.sendall(ext)
- dummy, res = struct.unpack('12sI', sl.s.recv(16))
+ dummy, res = struct.unpack('12sI', sl.s.recv(_SOCK_CMD_LEN))
if rl: sl.l.release()
return res
self.callbacks = []
self.events = []
self.sl.s = socket.create_connection((host, port), None)
- self.handle = _pigpio_command(self.sl, _PI_CMD_NOIB, 0, 0)
+ self.lastLevel = _u2i(_pigpio_command(self.sl, _PI_CMD_BR1, 0, 0))
+ self.handle = _u2i(_pigpio_command(self.sl, _PI_CMD_NOIB, 0, 0))
self.go = True
self.start()
def run(self):
"""Runs the notification thread."""
- lastLevel = _pigpio_command(self.control, _PI_CMD_BR1, 0, 0)
+ lastLevel = self.lastLevel
MSG_SIZ = 12
The watchdog may be cancelled by setting timeout to 0.
Once a watchdog has been started callbacks for the GPIO
- will be triggered whenever there has been no GPIO activity
- for the timeout interval.
+ will be triggered every timeout interval after the last
+ GPIO activity.
The callback will receive the special level TIMEOUT.
For bits 9-16 there will be two bytes per character.
For bits 17-32 there will be four bytes per character.
- E.g. 32 12-bit words will be transferred in 64 bytes.
+ Multi-byte transfers are made in least significant byte
+ first order.
+
+ E.g. to transfer 32 11-bit words data should
+ contain 64 bytes.
+
+ E.g. to transfer the 14 bit value 0x1ABC send the
+ bytes 0xBC followed by 0x1A.
The other bits in flags should be set to zero.
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
- Note, each (stable) edge will be timestamped [*steady*]
+ This filter affects the GPIO samples returned to callbacks set up
+ with [*callback*] and [*wait_for_edge*].
+
+ It does not affect levels read by [*read*],
+ [*read_bank_1*], or [*read_bank_2*].
+
+ Each (stable) edge will be timestamped [*steady*]
microseconds after it was first detected.
...
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
- Note, level changes before and after the active period may
+ This filter affects the GPIO samples returned to callbacks set up
+ with [*callback*] and [*wait_for_edge*].
+
+ It does not affect levels read by [*read*],
+ [*read_bank_1*], or [*read_bank_2*].
+
+ Level changes before and after the active period may
be reported. Your software must be designed to cope with
such reports.
The user supplied callback receives three parameters, the GPIO,
the level, and the tick.
+ . .
+ Parameter Value Meaning
+
+ GPIO 0-31 The GPIO which has changed state
+
+ level 0-2 0 = change to low (a falling edge)
+ 1 = change to high (a rising edge)
+ 2 = no level change (a watchdog timeout)
+
+ tick 32 bit The number of microseconds since boot
+ WARNING: this wraps around from
+ 4294967295 to 0 roughly every 72 minutes
+ . .
+
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. The count may be reset to zero
except struct.error:
exception = 2
+ except error:
+ exception = 3
+
else:
exception = 0
atexit.register(self.stop)
print(_except_a.format(s))
if exception == 1:
print(_except_1)
- else:
+ elif exception == 2:
print(_except_2)
+ else:
+ print(_except_3)
print(_except_z)
def stop(self):
." Process this file with
." groff -man -Tascii pigpiod.1
."
-.TH pigpiod 1 2012-2015 Linux "pigpio archive"
+.TH pigpiod 1 2012-2017 Linux "pigpio archive"
.SH NAME
pigpiod - A utility to start the pigpio library as a daemon.
." Process this file with
." groff -man -Tascii pigpiod_if.3
."
-.TH pigpiod_if 3 2012-2015 Linux "pigpio archive"
+.TH pigpiod_if 3 2012-2017 Linux "pigpio archive"
.SH NAME
pigpiod_if - A C library to interface to the pigpio daemon.
.br
.br
-If no level change has been detected for the GPIO for timeout
-milliseconds any notification for the GPIO has a report written
-to the fifo with the flags set to indicate a watchdog timeout.
+Once a watchdog has been started callbacks for the GPIO will be
+triggered every timeout interval after the last GPIO activity.
.br
.br
-The \fBcallback\fP and \fBcallback_ex\fP functions interpret the flags
-and will call registered callbacks for the GPIO with level TIMEOUT.
+The callback will receive the special level PI_TIMEOUT.
.IP "\fBint set_glitch_filter(unsigned user_gpio, unsigned steady)\fP"
.IP "" 4
.br
.br
-Note, each (stable) edge will be timestamped \fBsteady\fP microseconds
+This filter affects the GPIO samples returned to callbacks set up
+with \fBcallback\fP, \fBcallback_ex\fP and \fBwait_for_edge\fP.
+
+.br
+
+.br
+It does not affect levels read by \fBgpio_read\fP,
+\fBread_bank_1\fP, or \fBread_bank_2\fP.
+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"
.br
.br
-Note, level changes before and after the active period may
+This filter affects the GPIO samples returned to callbacks set up
+with \fBcallback\fP, \fBcallback_ex\fP and \fBwait_for_edge\fP.
+
+.br
+
+.br
+It does not affect levels read by \fBgpio_read\fP,
+\fBread_bank_1\fP, or \fBread_bank_2\fP.
+
+.br
+
+.br
+Level changes before and after the active period may
be reported. Your software must be designed to cope with
such reports.
.br
+.br
+The \fBspi_read\fP, \fBspi_write\fP, and \fBspi_xfer\fP functions
+transfer data packed into 1, 2, or 4 bytes according to
+the word size in bits.
+
+.br
+
+.br
+For bits 1-8 there will be one byte per word.
+.br
+For bits 9-16 there will be two bytes per word.
+.br
+For bits 17-32 there will be four bytes per word.
+
+.br
+
+.br
+Multi-byte transfers are made in least significant byte first order.
+
+.br
+
+.br
+E.g. to transfer 32 11-bit words buf should contain 64 bytes
+and count should be 64.
+
+.br
+
+.br
+E.g. to transfer the 14 bit value 0x1ABC send the bytes 0xBC followed
+by 0x1A.
+
+.br
+
.br
The other bits in flags should be set to zero.
The callback is called with the GPIO, edge, and tick, whenever the
GPIO has the identified edge.
+.br
+
+.br
+
+.EX
+Parameter Value Meaning
+.br
+
+.br
+GPIO 0-31 The GPIO which has changed state
+.br
+
+.br
+edge 0-2 0 = change to low (a falling edge)
+.br
+ 1 = change to high (a rising edge)
+.br
+ 2 = no level change (a watchdog timeout)
+.br
+
+.br
+tick 32 bit The number of microseconds since boot
+.br
+ WARNING: this wraps around from
+.br
+ 4294967295 to 0 roughly every 72 minutes
+.br
+
+.EE
+
.IP "\fBint callback_ex(unsigned user_gpio, unsigned edge, CBFuncEx_t f, void *userdata)\fP"
.IP "" 4
This function initialises a new callback.
.br
+.EX
+Parameter Value Meaning
+.br
+
+.br
+GPIO 0-31 The GPIO which has changed state
+.br
+
+.br
+edge 0-2 0 = change to low (a falling edge)
+.br
+ 1 = change to high (a rising edge)
+.br
+ 2 = no level change (a watchdog timeout)
+.br
+
+.br
+tick 32 bit The number of microseconds since boot
+.br
+ WARNING: this wraps around from
+.br
+ 4294967295 to 0 roughly every 72 minutes
+.br
+
+.br
+userdata pointer Pointer to an arbitrary object
+.br
+
+.EE
+
.IP "\fBint callback_cancel(unsigned callback_id)\fP"
.IP "" 4
This function cancels a callback identified by its id.
For more information, please refer to <http://unlicense.org/>
*/
-/* PIGPIOD_IF_VERSION 26 */
+/* PIGPIOD_IF_VERSION 27 */
#include <stdio.h>
#include <stdlib.h>
#include "pigpio.h"
-#define PIGPIOD_IF_VERSION 26
+#define PIGPIOD_IF_VERSION 27
/*TEXT
The watchdog may be cancelled by setting timeout to 0.
-If no level change has been detected for the GPIO for timeout
-milliseconds any notification for the GPIO has a report written
-to the fifo with the flags set to indicate a watchdog timeout.
+Once a watchdog has been started callbacks for the GPIO will be
+triggered every timeout interval after the last GPIO activity.
-The [*callback*] and [*callback_ex*] functions interpret the flags
-and will call registered callbacks for the GPIO with level TIMEOUT.
+The callback will receive the special level PI_TIMEOUT.
D*/
/*F*/
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
-Note, each (stable) edge will be timestamped [*steady*] microseconds
+This filter affects the GPIO samples returned to callbacks set up
+with [*callback*], [*callback_ex*] and [*wait_for_edge*].
+
+It does not affect levels read by [*gpio_read*],
+[*read_bank_1*], or [*read_bank_2*].
+Each (stable) edge will be timestamped [*steady*] microseconds
after it was first detected.
D*/
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
-Note, level changes before and after the active period may
+This filter affects the GPIO samples returned to callbacks set up
+with [*callback*], [*callback_ex*] and [*wait_for_edge*].
+
+It does not affect levels read by [*gpio_read*],
+[*read_bank_1*], or [*read_bank_2*].
+
+Level changes before and after the active period may
be reported. Your software must be designed to cope with
such reports.
D*/
bbbbbb defines the word size in bits (0-32). The default (0)
sets 8 bits per word. Auxiliary SPI device only.
+The [*spi_read*], [*spi_write*], and [*spi_xfer*] functions
+transfer data packed into 1, 2, or 4 bytes according to
+the word size in bits.
+
+For bits 1-8 there will be one byte per word.
+For bits 9-16 there will be two bytes per word.
+For bits 17-32 there will be four bytes per word.
+
+Multi-byte transfers are made in least significant byte first order.
+
+E.g. to transfer 32 11-bit words buf should contain 64 bytes
+and count should be 64.
+
+E.g. to transfer the 14 bit value 0x1ABC send the bytes 0xBC followed
+by 0x1A.
+
The other bits in flags should be set to zero.
D*/
The callback is called with the GPIO, edge, and tick, whenever the
GPIO has the identified edge.
+
+. .
+Parameter Value Meaning
+
+GPIO 0-31 The GPIO which has changed state
+
+edge 0-2 0 = change to low (a falling edge)
+ 1 = change to high (a rising edge)
+ 2 = no level change (a watchdog timeout)
+
+tick 32 bit The number of microseconds since boot
+ WARNING: this wraps around from
+ 4294967295 to 0 roughly every 72 minutes
+. .
D*/
/*F*/
The callback is called with the GPIO, edge, tick, and user, whenever
the GPIO has the identified edge.
+. .
+Parameter Value Meaning
+
+GPIO 0-31 The GPIO which has changed state
+
+edge 0-2 0 = change to low (a falling edge)
+ 1 = change to high (a rising edge)
+ 2 = no level change (a watchdog timeout)
+
+tick 32 bit The number of microseconds since boot
+ WARNING: this wraps around from
+ 4294967295 to 0 roughly every 72 minutes
+
+userdata pointer Pointer to an arbitrary object
+. .
D*/
/*F*/
." Process this file with
." groff -man -Tascii pigpiod_if2.3
."
-.TH pigpiod_if2 3 2012-2015 Linux "pigpio archive"
+.TH pigpiod_if2 3 2012-2017 Linux "pigpio archive"
.SH NAME
pigpiod_if2 - A C library to interface to the pigpio daemon.
.br
.br
-If no level change has been detected for the GPIO for timeout
-milliseconds any notification for the GPIO has a report written
-to the fifo with the flags set to indicate a watchdog timeout.
+Once a watchdog has been started callbacks for the GPIO will be
+triggered every timeout interval after the last GPIO activity.
.br
.br
-The \fBcallback\fP and \fBcallback_ex\fP functions interpret the flags
-and will call registered callbacks for the GPIO with level TIMEOUT.
+The callback will receive the special level PI_TIMEOUT.
.IP "\fBint set_glitch_filter(int pi, unsigned user_gpio, unsigned steady)\fP"
.IP "" 4
.br
.br
-Note, each (stable) edge will be timestamped \fBsteady\fP microseconds
+This filter affects the GPIO samples returned to callbacks set up
+with \fBcallback\fP, \fBcallback_ex\fP and \fBwait_for_edge\fP.
+
+.br
+
+.br
+It does not affect levels read by \fBgpio_read\fP,
+\fBread_bank_1\fP, or \fBread_bank_2\fP.
+
+.br
+
+.br
+Each (stable) edge will be timestamped \fBsteady\fP microseconds
after it was first detected.
.IP "\fBint set_noise_filter(int pi, unsigned user_gpio, unsigned steady, unsigned active)\fP"
.br
.br
-Note, level changes before and after the active period may
+This filter affects the GPIO samples returned to callbacks set up
+with \fBcallback\fP, \fBcallback_ex\fP and \fBwait_for_edge\fP.
+
+.br
+
+.br
+It does not affect levels read by \fBgpio_read\fP,
+\fBread_bank_1\fP, or \fBread_bank_2\fP.
+
+.br
+
+.br
+Level changes before and after the active period may
be reported. Your software must be designed to cope with
such reports.
.br
.br
-E.g. to transfer 32 12-bit words buf should contain 64 bytes
+Multi-byte transfers are made in least significant byte first order.
+
+.br
+
+.br
+E.g. to transfer 32 11-bit words buf should contain 64 bytes
and count should be 64.
.br
+.br
+E.g. to transfer the 14 bit value 0x1ABC send the bytes 0xBC followed
+by 0x1A.
+
+.br
+
.br
The other bits in flags should be set to zero.
The callback is called with the GPIO, edge, and tick, whenever the
GPIO has the identified edge.
+.br
+
+.br
+
+.EX
+Parameter Value Meaning
+.br
+
+.br
+GPIO 0-31 The GPIO which has changed state
+.br
+
+.br
+edge 0-2 0 = change to low (a falling edge)
+.br
+ 1 = change to high (a rising edge)
+.br
+ 2 = no level change (a watchdog timeout)
+.br
+
+.br
+tick 32 bit The number of microseconds since boot
+.br
+ WARNING: this wraps around from
+.br
+ 4294967295 to 0 roughly every 72 minutes
+.br
+
+.EE
+
.IP "\fBint callback_ex(int pi, unsigned user_gpio, unsigned edge, CBFuncEx_t f, void *userdata)\fP"
.IP "" 4
This function initialises a new callback.
The callback is called with the GPIO, edge, tick, and the userdata
pointer, whenever the GPIO has the identified edge.
+.br
+
+.br
+
+.EX
+Parameter Value Meaning
+.br
+
+.br
+GPIO 0-31 The GPIO which has changed state
+.br
+
+.br
+edge 0-2 0 = change to low (a falling edge)
+.br
+ 1 = change to high (a rising edge)
+.br
+ 2 = no level change (a watchdog timeout)
+.br
+
+.br
+tick 32 bit The number of microseconds since boot
+.br
+ WARNING: this wraps around from
+.br
+ 4294967295 to 0 roughly every 72 minutes
+.br
+
+.br
+userdata pointer Pointer to an arbitrary object
+.br
+
+.EE
+
.IP "\fBint callback_cancel(unsigned callback_id)\fP"
.IP "" 4
This function cancels a callback identified by its id.
For more information, please refer to <http://unlicense.org/>
*/
-/* PIGPIOD_IF2_VERSION 10 */
+/* PIGPIOD_IF2_VERSION 11 */
#include <stdio.h>
#include <stdlib.h>
#include "pigpio.h"
-#define PIGPIOD_IF2_VERSION 10
+#define PIGPIOD_IF2_VERSION 11
/*TEXT
The watchdog may be cancelled by setting timeout to 0.
-If no level change has been detected for the GPIO for timeout
-milliseconds any notification for the GPIO has a report written
-to the fifo with the flags set to indicate a watchdog timeout.
+Once a watchdog has been started callbacks for the GPIO will be
+triggered every timeout interval after the last GPIO activity.
-The [*callback*] and [*callback_ex*] functions interpret the flags
-and will call registered callbacks for the GPIO with level TIMEOUT.
+The callback will receive the special level PI_TIMEOUT.
D*/
/*F*/
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
-Note, each (stable) edge will be timestamped [*steady*] microseconds
+This filter affects the GPIO samples returned to callbacks set up
+with [*callback*], [*callback_ex*] and [*wait_for_edge*].
+
+It does not affect levels read by [*gpio_read*],
+[*read_bank_1*], or [*read_bank_2*].
+
+Each (stable) edge will be timestamped [*steady*] microseconds
after it was first detected.
D*/
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
-Note, level changes before and after the active period may
+This filter affects the GPIO samples returned to callbacks set up
+with [*callback*], [*callback_ex*] and [*wait_for_edge*].
+
+It does not affect levels read by [*gpio_read*],
+[*read_bank_1*], or [*read_bank_2*].
+
+Level changes before and after the active period may
be reported. Your software must be designed to cope with
such reports.
D*/
For bits 9-16 there will be two bytes per character.
For bits 17-32 there will be four bytes per character.
-E.g. to transfer 32 12-bit words buf should contain 64 bytes
+Multi-byte transfers are made in least significant byte first order.
+
+E.g. to transfer 32 11-bit words buf should contain 64 bytes
and count should be 64.
+E.g. to transfer the 14 bit value 0x1ABC send the bytes 0xBC followed
+by 0x1A.
+
The other bits in flags should be set to zero.
D*/
The callback is called with the GPIO, edge, and tick, whenever the
GPIO has the identified edge.
+
+. .
+Parameter Value Meaning
+
+GPIO 0-31 The GPIO which has changed state
+
+edge 0-2 0 = change to low (a falling edge)
+ 1 = change to high (a rising edge)
+ 2 = no level change (a watchdog timeout)
+
+tick 32 bit The number of microseconds since boot
+ WARNING: this wraps around from
+ 4294967295 to 0 roughly every 72 minutes
+. .
D*/
/*F*/
The callback is called with the GPIO, edge, tick, and the userdata
pointer, whenever the GPIO has the identified edge.
+
+. .
+Parameter Value Meaning
+
+GPIO 0-31 The GPIO which has changed state
+
+edge 0-2 0 = change to low (a falling edge)
+ 1 = change to high (a rising edge)
+ 2 = no level change (a watchdog timeout)
+
+tick 32 bit The number of microseconds since boot
+ WARNING: this wraps around from
+ 4294967295 to 0 roughly every 72 minutes
+
+userdata pointer Pointer to an arbitrary object
+. .
D*/
/*F*/
." Process this file with
." groff -man -Tascii foo.1
."
-.TH pigs 1 2012-2015 Linux "pigpio archive"
+.TH pigs 1 2012-2017 Linux "pigpio archive"
.SH NAME
pigs - command line socket access to the pigpio daemon.
level is then reported. Level changes of less than \fBstdy\fP
microseconds are ignored.
+.br
+The filter only affects callbacks (including pipe notifications).
+
+.br
+The \fBR/READ\fP, \fBBR1\fP, and \fBBR2\fP commands are not affected.
+
.br
Note, each (stable) edge will be timestamped \fBstdy\fP microseconds
after it was first detected.
changes on the GPIO are then reported for \fBactv\fP microseconds
after which the process repeats.
+.br
+The filter only affects callbacks (including pipe notifications).
+
+.br
+The \fBR/READ\fP, \fBBR1\fP, and \fBBR2\fP commands are not affected.
+
.br
Note, level changes before and after the active period may
be reported. Your software must be designed to cope with
For bits 17-32 there will be four bytes per character.
.br
-E.g. 32 12-bit words will be transferred in 64 bytes.
+Multi-byte transfers are made in least significant byte first order.
+
+.br
+E.g. to transfer 32 11-bit words 64 bytes need to be sent.
+
+.br
+E.g. to transfer the 14 bit value 0x1ABC send the bytes 0xBC followed
+by 0x1A.
.br
The other bits in flags should be set to zero.
The watchdog may be cancelled by setting timeout to 0.
.br
-If no level change has been detected for the GPIO for timeout milliseconds:-
-
-.br
-any notification for the GPIO has a report written to the fifo with
-the flags set to indicate a watchdog timeout.
+Once a watchdog has been started monitors of the GPIO
+will be triggered every timeout interval after the last
+GPIO activity. The watchdog expiry will be indicated by
+a special TIMEOUT value.
.br
from distutils.core import setup
setup(name='pigpio',
- version='1.35',
+ version='1.37',
author='joan',
author_email='joan@abyz.co.uk',
maintainer='joan',
gpioSetPWMrange(GPIO, 100);
h = gpioNotifyOpen();
- e = gpioNotifyBegin(h, (1<<GPIO));
- CHECK(4, 1, e, 0, 0, "notify open/begin");
-
- time_sleep(1);
sprintf(p, "/dev/pigpio%d", h);
-
f = open(p, O_RDONLY);
+ e = gpioNotifyBegin(h, (1<<GPIO));
+ CHECK(4, 1, e, 0, 0, "notify open/begin");
+
gpioPWM(GPIO, 50);
time_sleep(4);
gpioPWM(GPIO, 0);
set_PWM_range(GPIO, 100);
h = notify_open();
- e = notify_begin(h, (1<<GPIO));
- CHECK(4, 1, e, 0, 0, "notify open/begin");
-
- time_sleep(1);
sprintf(p, "/dev/pigpio%d", h);
-
f = open(p, O_RDONLY);
+ e = notify_begin(h, (1<<GPIO));
+ CHECK(4, 1, e, 0, 0, "notify open/begin");
+
set_PWM_dutycycle(GPIO, 50);
time_sleep(4);
set_PWM_dutycycle(GPIO, 0);
set_PWM_range(pi, GPIO, 100);
h = notify_open(pi);
- e = notify_begin(pi, h, (1<<GPIO));
- CHECK(4, 1, e, 0, 0, "notify open/begin");
-
- time_sleep(1);
sprintf(p, "/dev/pigpio%d", h);
-
f = open(p, O_RDONLY);
+ e = notify_begin(pi, h, (1<<GPIO));
+ CHECK(4, 1, e, 0, 0, "notify open/begin");
+
set_PWM_dutycycle(pi, GPIO, 50);
time_sleep(4);
set_PWM_dutycycle(pi, GPIO, 0);