This commit is contained in:
joan 2017-05-13 14:22:02 +01:00
parent c4c8ce50c6
commit f032029bf9
17 changed files with 802 additions and 221 deletions

View File

@ -2,7 +2,7 @@
." Process this file with ." Process this file with
." groff -man -Tascii pig2vcd.1 ." groff -man -Tascii pig2vcd.1
." ."
.TH pig2vcd 1 2012-2015 Linux "pigpio archive" .TH pig2vcd 1 2012-2017 Linux "pigpio archive"
.SH NAME .SH NAME
pig2vd - A utility to convert pigpio notifications to VCD. pig2vd - A utility to convert pigpio notifications to VCD.

163
pigpio.3
View File

@ -2,7 +2,7 @@
." Process this file with ." Process this file with
." groff -man -Tascii pigpio.3 ." groff -man -Tascii pigpio.3
." ."
.TH pigpio 3 2012-2015 Linux "pigpio archive" .TH pigpio 3 2012-2017 Linux "pigpio archive"
.SH NAME .SH NAME
pigpio - A C library to manipulate the Pi's GPIO. pigpio - A C library to manipulate the Pi's GPIO.
@ -1049,12 +1049,42 @@ Returns 0 if OK, otherwise PI_BAD_USER_GPIO.
.br .br
.br .br
One function may be registered per GPIO. One callback may be registered per GPIO.
.br .br
.br .br
The function is passed the GPIO, the new level, and the tick. The callback is passed the GPIO, the new level, and the tick.
.br
.br
.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
.EE
.br .br
@ -1175,26 +1205,60 @@ Returns 0 if OK, otherwise PI_BAD_USER_GPIO.
.br .br
.br .br
One function may be registered per GPIO. One callback may be registered per GPIO.
.br .br
.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. the userdata pointer.
.br .br
.br
.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.
.br
.br .br
Only one of \fBgpioSetAlertFunc\fP or \fBgpioSetAlertFuncEx\fP can be Only one of \fBgpioSetAlertFunc\fP or \fBgpioSetAlertFuncEx\fP can be
registered per GPIO. registered per GPIO.
.br .IP "\fBint gpioSetISRFunc(unsigned gpio, unsigned edge, int timeout, gpioISRFunc_t f)\fP"
.br
See \fBgpioSetAlertFunc\fP for further details.
.IP "\fBint gpioSetISRFunc(unsigned user_gpio, unsigned edge, int timeout, gpioISRFunc_t f)\fP"
.IP "" 4 .IP "" 4
Registers a function to be called (a callback) whenever the specified Registers a function to be called (a callback) whenever the specified
GPIO interrupt occurs. GPIO interrupt occurs.
@ -1204,7 +1268,7 @@ GPIO interrupt occurs.
.br .br
.EX .EX
user_gpio: 0-31 gpio: 0-53
.br .br
edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE
.br .br
@ -1218,7 +1282,7 @@ user_gpio: 0-31
.br .br
.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. or PI_BAD_ISR_INIT.
.br .br
@ -1277,7 +1341,7 @@ interrupts happening in rapid succession may be missed by the
kernel (i.e. this mechanism can not be used to capture several kernel (i.e. this mechanism can not be used to capture several
interrupts only a few microseconds apart). 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 .IP "" 4
Registers a function to be called (a callback) whenever the specified Registers a function to be called (a callback) whenever the specified
GPIO interrupt occurs. GPIO interrupt occurs.
@ -1287,7 +1351,7 @@ GPIO interrupt occurs.
.br .br
.EX .EX
user_gpio: 0-31 gpio: 0-53
.br .br
edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE
.br .br
@ -1303,7 +1367,7 @@ user_gpio: 0-31
.br .br
.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. or PI_BAD_ISR_INIT.
.br .br
@ -4136,20 +4200,31 @@ the word size in bits.
.br .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 .br
For bits 9-16 there will be two bytes per character. For bits 9-16 there will be two bytes per word.
.br .br
For bits 17-32 there will be four bytes per character. For bits 17-32 there will be four bytes per word.
.br .br
.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. and count should be 64.
.br .br
.br
E.g. to transfer the 14 bit value 0x1ABC send the bytes 0xBC followed
by 0x1A.
.br
.br .br
The other bits in flags should be set to zero. The other bits in flags should be set to zero.
@ -4492,16 +4567,24 @@ The watchdog may be cancelled by setting timeout to 0.
.br .br
.br .br
If no level change has been detected for the GPIO for timeout Until cancelled a timeout will be reported every timeout milliseconds
milliseconds:- after the last GPIO activity.
.br .br
.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. the level set to PI_TIMEOUT.
.br .br
2) any notification for the GPIO has a report written to the
.br
2) any notification for the GPIO will have a report written to the
fifo with the flags set to indicate a watchdog timeout. fifo with the flags set to indicate a watchdog timeout.
.br .br
@ -4568,7 +4651,21 @@ Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
.br .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 be reported. Your software must be designed to cope with
such reports. such reports.
@ -4604,7 +4701,21 @@ Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
.br .br
.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. after it was first detected.
.IP "\fBint gpioSetGetSamplesFunc(gpioGetSamplesFunc_t f, uint32_t bits)\fP" .IP "\fBint gpioSetGetSamplesFunc(gpioGetSamplesFunc_t f, uint32_t bits)\fP"

210
pigpio.c
View File

@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/> For more information, please refer to <http://unlicense.org/>
*/ */
/* pigpio version 62 */ /* pigpio version 63 */
/* include ------------------------------------------------------- */ /* include ------------------------------------------------------- */
@ -733,22 +733,27 @@ Assumes two counters per block. Each counter 4 * 16 (16^4=65536)
#define TICKSLOTS 50 #define TICKSLOTS 50
#define PI_I2C_CLOSED 0 #define PI_I2C_CLOSED 0
#define PI_I2C_OPENED 1 #define PI_I2C_RESERVED 1
#define PI_I2C_OPENED 2
#define PI_SPI_CLOSED 0 #define PI_SPI_CLOSED 0
#define PI_SPI_OPENED 1 #define PI_SPI_RESERVED 1
#define PI_SPI_OPENED 2
#define PI_SER_CLOSED 0 #define PI_SER_CLOSED 0
#define PI_SER_OPENED 1 #define PI_SER_RESERVED 1
#define PI_SER_OPENED 2
#define PI_FILE_CLOSED 0 #define PI_FILE_CLOSED 0
#define PI_FILE_OPENED 1 #define PI_FILE_RESERVED 1
#define PI_FILE_OPENED 2
#define PI_NOTIFY_CLOSED 0 #define PI_NOTIFY_CLOSED 0
#define PI_NOTIFY_CLOSING 1 #define PI_NOTIFY_RESERVED 1
#define PI_NOTIFY_OPENED 2 #define PI_NOTIFY_CLOSING 2
#define PI_NOTIFY_RUNNING 3 #define PI_NOTIFY_OPENED 3
#define PI_NOTIFY_PAUSED 4 #define PI_NOTIFY_RUNNING 4
#define PI_NOTIFY_PAUSED 5
#define PI_WFRX_NONE 0 #define PI_WFRX_NONE 0
#define PI_WFRX_SERIAL 1 #define PI_WFRX_SERIAL 1
@ -861,6 +866,10 @@ Assumes two counters per block. Each counter 4 * 16 (16^4=65536)
#define PI_RUNNING 1 #define PI_RUNNING 1
#define PI_ENDING 2 #define PI_ENDING 2
#define PI_THREAD_NONE 0
#define PI_THREAD_STARTED 1
#define PI_THREAD_RUNNING 2
#define PI_MAX_PATH 512 #define PI_MAX_PATH 512
/* typedef ------------------------------------------------------- */ /* typedef ------------------------------------------------------- */
@ -1251,15 +1260,15 @@ static volatile uint32_t scriptEventBits = 0;
static volatile int runState = PI_STARTING; static volatile int runState = PI_STARTING;
static int pthAlertRunning = 0; static int pthAlertRunning = PI_THREAD_NONE;
static int pthFifoRunning = 0; static int pthFifoRunning = PI_THREAD_NONE;
static int pthSocketRunning = 0; static int pthSocketRunning = PI_THREAD_NONE;
static gpioAlert_t gpioAlert [PI_MAX_USER_GPIO+1]; static gpioAlert_t gpioAlert [PI_MAX_USER_GPIO+1];
static eventAlert_t eventAlert [PI_MAX_EVENT+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 gpioGetSamples_t gpioGetSamples;
@ -1280,9 +1289,6 @@ static gpioTimer_t gpioTimer [PI_MAX_TIMER+1];
static int pwmFreq[PWM_FREQS]; 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 */ /* reset after gpioTerminated */
/* resources which must be released on gpioTerminate */ /* resources which must be released on gpioTerminate */
@ -3333,7 +3339,7 @@ int i2cWriteQuick(unsigned handle, unsigned bit)
if (handle >= PI_I2C_SLOTS) if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); 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); SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_QUICK) == 0) if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_QUICK) == 0)
@ -3366,7 +3372,7 @@ int i2cReadByte(unsigned handle)
if (handle >= PI_I2C_SLOTS) if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); 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); SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_BYTE) == 0) if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_BYTE) == 0)
@ -3396,7 +3402,7 @@ int i2cWriteByte(unsigned handle, unsigned bVal)
if (handle >= PI_I2C_SLOTS) if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); 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); SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_BYTE) == 0) if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_BYTE) == 0)
@ -3434,7 +3440,7 @@ int i2cReadByteData(unsigned handle, unsigned reg)
if (handle >= PI_I2C_SLOTS) if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); 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); SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_BYTE_DATA) == 0) if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_BYTE_DATA) == 0)
@ -3469,7 +3475,7 @@ int i2cWriteByteData(unsigned handle, unsigned reg, unsigned bVal)
if (handle >= PI_I2C_SLOTS) if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); 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); SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_BYTE_DATA) == 0) if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_BYTE_DATA) == 0)
@ -3512,7 +3518,7 @@ int i2cReadWordData(unsigned handle, unsigned reg)
if (handle >= PI_I2C_SLOTS) if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); 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); SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_WORD_DATA) == 0) if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_WORD_DATA) == 0)
@ -3551,7 +3557,7 @@ int i2cWriteWordData(unsigned handle, unsigned reg, unsigned wVal)
if (handle >= PI_I2C_SLOTS) if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); 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); SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_WORD_DATA) == 0) if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_WORD_DATA) == 0)
@ -3594,7 +3600,7 @@ int i2cProcessCall(unsigned handle, unsigned reg, unsigned wVal)
if (handle >= PI_I2C_SLOTS) if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); 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); SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_PROC_CALL) == 0) if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_PROC_CALL) == 0)
@ -3637,7 +3643,7 @@ int i2cReadBlockData(unsigned handle, unsigned reg, char *buf)
if (handle >= PI_I2C_SLOTS) if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); 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); SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_BLOCK_DATA) == 0) if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_BLOCK_DATA) == 0)
@ -3685,7 +3691,7 @@ int i2cWriteBlockData(
if (handle >= PI_I2C_SLOTS) if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); 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); SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) == 0) if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) == 0)
@ -3732,7 +3738,7 @@ int i2cBlockProcessCall(
if (handle >= PI_I2C_SLOTS) if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); 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); SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_PROC_CALL) == 0) if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_PROC_CALL) == 0)
@ -3784,7 +3790,7 @@ int i2cReadI2CBlockData(
if (handle >= PI_I2C_SLOTS) if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); 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); SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_I2C_BLOCK) == 0) if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_I2C_BLOCK) == 0)
@ -3838,7 +3844,7 @@ int i2cWriteI2CBlockData(
if (handle >= PI_I2C_SLOTS) if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); 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); SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) == 0) if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) == 0)
@ -3882,7 +3888,7 @@ int i2cWriteDevice(unsigned handle, char *buf, unsigned count)
if (handle >= PI_I2C_SLOTS) if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); 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); SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((count < 1) || (count > PI_MAX_I2C_DEVICE_COUNT)) if ((count < 1) || (count > PI_MAX_I2C_DEVICE_COUNT))
@ -3911,7 +3917,7 @@ int i2cReadDevice(unsigned handle, char *buf, unsigned count)
if (handle >= PI_I2C_SLOTS) if (handle >= PI_I2C_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); 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); SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if ((count < 1) || (count > PI_MAX_I2C_DEVICE_COUNT)) if ((count < 1) || (count > PI_MAX_I2C_DEVICE_COUNT))
@ -3930,6 +3936,7 @@ int i2cReadDevice(unsigned handle, char *buf, unsigned count)
int i2cOpen(unsigned i2cBus, unsigned i2cAddr, unsigned i2cFlags) int i2cOpen(unsigned i2cBus, unsigned i2cAddr, unsigned i2cFlags)
{ {
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
char dev[32]; char dev[32];
int i, slot, fd; int i, slot, fd;
uint32_t funcs; uint32_t funcs;
@ -3947,18 +3954,21 @@ int i2cOpen(unsigned i2cBus, unsigned i2cAddr, unsigned i2cFlags)
slot = -1; slot = -1;
pthread_mutex_lock(&mutex);
for (i=0; i<PI_I2C_SLOTS; i++) for (i=0; i<PI_I2C_SLOTS; i++)
{ {
if (i2cInfo[i].state == PI_I2C_CLOSED) if (i2cInfo[i].state == PI_I2C_CLOSED)
{ {
i2cInfo[i].state = PI_I2C_OPENED;
slot = i; slot = i;
i2cInfo[slot].state = PI_I2C_RESERVED;
break; break;
} }
} }
if (slot < 0) pthread_mutex_unlock(&mutex);
SOFT_ERROR(PI_NO_HANDLE, "no I2C handles");
if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no I2C handles");
sprintf(dev, "/dev/i2c-%d", i2cBus); sprintf(dev, "/dev/i2c-%d", i2cBus);
@ -3967,7 +3977,7 @@ int i2cOpen(unsigned i2cBus, unsigned i2cAddr, unsigned i2cFlags)
/* try a modprobe */ /* try a modprobe */
system("/sbin/modprobe i2c_dev"); system("/sbin/modprobe i2c_dev");
system("/sbin/modprobe i2c_bcm2708"); system("/sbin/modprobe i2c_bcm2835");
myGpioDelay(100000); myGpioDelay(100000);
@ -3994,6 +4004,7 @@ int i2cOpen(unsigned i2cBus, unsigned i2cAddr, unsigned i2cFlags)
i2cInfo[slot].addr = i2cAddr; i2cInfo[slot].addr = i2cAddr;
i2cInfo[slot].flags = i2cFlags; i2cInfo[slot].flags = i2cFlags;
i2cInfo[slot].funcs = funcs; i2cInfo[slot].funcs = funcs;
i2cInfo[i].state = PI_I2C_OPENED;
return slot; return slot;
} }
@ -4480,17 +4491,20 @@ static void spiGo(
char *rxBuf, char *rxBuf,
unsigned count) 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)) 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); spiGoA(speed, flags, txBuf, rxBuf, count);
pthread_mutex_unlock(&spi_aux_mutex); pthread_mutex_unlock(&aux_mutex);
} }
else else
{ {
pthread_mutex_lock(&spi_main_mutex); pthread_mutex_lock(&main_mutex);
spiGoS(speed, flags, txBuf, rxBuf, count); spiGoS(speed, flags, txBuf, rxBuf, count);
pthread_mutex_unlock(&spi_main_mutex); pthread_mutex_unlock(&main_mutex);
} }
} }
@ -4627,6 +4641,7 @@ static void spiTerm(uint32_t flags)
int spiOpen(unsigned spiChan, unsigned baud, unsigned spiFlags) int spiOpen(unsigned spiChan, unsigned baud, unsigned spiFlags)
{ {
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int i, slot; int i, slot;
DBG(DBG_USER, "spiChan=%d baud=%d spiFlags=0x%X", DBG(DBG_USER, "spiChan=%d baud=%d spiFlags=0x%X",
@ -4661,21 +4676,25 @@ int spiOpen(unsigned spiChan, unsigned baud, unsigned spiFlags)
slot = -1; slot = -1;
pthread_mutex_lock(&mutex);
for (i=0; i<PI_SPI_SLOTS; i++) for (i=0; i<PI_SPI_SLOTS; i++)
{ {
if (spiInfo[i].state == PI_SPI_CLOSED) if (spiInfo[i].state == PI_SPI_CLOSED)
{ {
spiInfo[i].state = PI_SPI_OPENED;
slot = i; slot = i;
spiInfo[slot].state = PI_SPI_RESERVED;
break; break;
} }
} }
if (slot < 0) pthread_mutex_unlock(&mutex);
SOFT_ERROR(PI_NO_HANDLE, "no SPI handles");
if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no SPI handles");
spiInfo[slot].speed = baud; spiInfo[slot].speed = baud;
spiInfo[slot].flags = spiFlags | PI_SPI_FLAGS_CHANNEL(spiChan); spiInfo[slot].flags = spiFlags | PI_SPI_FLAGS_CHANNEL(spiChan);
spiInfo[slot].state = PI_SPI_OPENED;
return slot; return slot;
} }
@ -4768,6 +4787,7 @@ int spiXfer(unsigned handle, char *txBuf, char *rxBuf, unsigned count)
int serOpen(char *tty, unsigned serBaud, unsigned serFlags) int serOpen(char *tty, unsigned serBaud, unsigned serFlags)
{ {
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
struct termios new; struct termios new;
int speed; int speed;
int fd; int fd;
@ -4810,18 +4830,21 @@ int serOpen(char *tty, unsigned serBaud, unsigned serFlags)
slot = -1; slot = -1;
pthread_mutex_lock(&mutex);
for (i=0; i<PI_SER_SLOTS; i++) for (i=0; i<PI_SER_SLOTS; i++)
{ {
if (serInfo[i].state == PI_SER_CLOSED) if (serInfo[i].state == PI_SER_CLOSED)
{ {
serInfo[i].state = PI_SER_OPENED;
slot = i; slot = i;
serInfo[slot].state = PI_SER_RESERVED;
break; break;
} }
} }
if (slot < 0) pthread_mutex_unlock(&mutex);
SOFT_ERROR(PI_NO_HANDLE, "no serial handles");
if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no serial handles");
if ((fd = open(tty, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1) if ((fd = open(tty, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)
{ {
@ -4846,6 +4869,7 @@ int serOpen(char *tty, unsigned serBaud, unsigned serFlags)
serInfo[slot].fd = fd; serInfo[slot].fd = fd;
serInfo[slot].flags = serFlags; serInfo[slot].flags = serFlags;
serInfo[slot].state = PI_SER_OPENED;
return slot; return slot;
} }
@ -5816,7 +5840,7 @@ static void alertEmit(
gpioNotify[n].state = PI_NOTIFY_CLOSED; 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; bits = gpioNotify[n].bits;
@ -5923,7 +5947,7 @@ static void alertEmit(
if (!emit) if (!emit)
{ {
if ((eTick - gpioNotify[n].lastReportTick) > 60000000) if ((int)(eTick - gpioNotify[n].lastReportTick) > 60000000)
{ {
if (numSamples) if (numSamples)
newLevel = sample[numSamples-1].level; newLevel = sample[numSamples-1].level;
@ -6268,6 +6292,7 @@ static void * pthAlertThread(void *x)
{ {
stickInited = 1; stickInited = 1;
numSamples = 0; numSamples = 0;
pthAlertRunning = PI_THREAD_RUNNING;
} }
} }
} }
@ -7745,9 +7770,9 @@ static void initClearGlobals(void)
nFilterBits = 0; nFilterBits = 0;
wdogBits = 0; wdogBits = 0;
pthAlertRunning = 0; pthAlertRunning = PI_THREAD_NONE;
pthFifoRunning = 0; pthFifoRunning = PI_THREAD_NONE;
pthSocketRunning = 0; pthSocketRunning = PI_THREAD_NONE;
wfc[0] = 0; wfc[0] = 0;
wfc[1] = 0; wfc[1] = 0;
@ -7856,7 +7881,7 @@ static void initReleaseResources(void)
/* shut down running threads */ /* 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 (gpioISR[i].pth)
{ {
@ -7878,25 +7903,25 @@ static void initReleaseResources(void)
} }
} }
if (pthAlertRunning) if (pthAlertRunning != PI_THREAD_NONE)
{ {
pthread_cancel(pthAlert); pthread_cancel(pthAlert);
pthread_join(pthAlert, NULL); pthread_join(pthAlert, NULL);
pthAlertRunning = 0; pthAlertRunning = PI_THREAD_NONE;
} }
if (pthFifoRunning) if (pthFifoRunning != PI_THREAD_NONE)
{ {
pthread_cancel(pthFifo); pthread_cancel(pthFifo);
pthread_join(pthFifo, NULL); pthread_join(pthFifo, NULL);
pthFifoRunning = 0; pthFifoRunning = PI_THREAD_NONE;
} }
if (pthSocketRunning) if (pthSocketRunning != PI_THREAD_NONE)
{ {
pthread_cancel(pthSocket); pthread_cancel(pthSocket);
pthread_join(pthSocket, NULL); pthread_join(pthSocket, NULL);
pthSocketRunning = 0; pthSocketRunning = PI_THREAD_NONE;
} }
/* release mmap'd memory */ /* release mmap'd memory */
@ -8118,14 +8143,14 @@ int initInitialise(void)
if (pthread_create(&pthAlert, &pthAttr, pthAlertThread, &i)) if (pthread_create(&pthAlert, &pthAttr, pthAlertThread, &i))
SOFT_ERROR(PI_INIT_FAILED, "pthread_create alert failed (%m)"); SOFT_ERROR(PI_INIT_FAILED, "pthread_create alert failed (%m)");
pthAlertRunning = 1; pthAlertRunning = PI_THREAD_STARTED;
if (!(gpioCfg.ifFlags & PI_DISABLE_FIFO_IF)) if (!(gpioCfg.ifFlags & PI_DISABLE_FIFO_IF))
{ {
if (pthread_create(&pthFifo, &pthAttr, pthFifoThread, &i)) if (pthread_create(&pthFifo, &pthAttr, pthFifoThread, &i))
SOFT_ERROR(PI_INIT_FAILED, "pthread_create fifo failed (%m)"); SOFT_ERROR(PI_INIT_FAILED, "pthread_create fifo failed (%m)");
pthFifoRunning = 1; pthFifoRunning = PI_THREAD_STARTED;
} }
if (!(gpioCfg.ifFlags & PI_DISABLE_SOCK_IF)) if (!(gpioCfg.ifFlags & PI_DISABLE_SOCK_IF))
@ -8182,10 +8207,10 @@ int initInitialise(void)
if (pthread_create(&pthSocket, &pthAttr, pthSocketThread, &i)) if (pthread_create(&pthSocket, &pthAttr, pthSocketThread, &i))
SOFT_ERROR(PI_INIT_FAILED, "pthread_create socket failed (%m)"); SOFT_ERROR(PI_INIT_FAILED, "pthread_create socket failed (%m)");
pthSocketRunning = 1; pthSocketRunning = PI_THREAD_STARTED;
} }
myGpioDelay(10000); myGpioDelay(1000);
dmaInitCbs(); dmaInitCbs();
@ -8193,8 +8218,6 @@ int initInitialise(void)
initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIBus[0]); initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIBus[0]);
myGpioDelay(20000);
return PIGPIO_VERSION; return PIGPIO_VERSION;
} }
@ -8445,7 +8468,10 @@ int gpioInitialise(void)
else else
{ {
libInitialised = 1; libInitialised = 1;
runState = PI_RUNNING; runState = PI_RUNNING;
while (pthAlertRunning != PI_THREAD_RUNNING) myGpioDelay(1000);
} }
return status; return status;
@ -11462,8 +11488,8 @@ int gpioSetISRFunc(
CHECK_INITED; CHECK_INITED;
if (gpio > PI_MAX_USER_GPIO) if (gpio > PI_MAX_GPIO)
SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio); SOFT_ERROR(PI_BAD_GPIO, "bad gpio (%d)", gpio);
if (edge > EITHER_EDGE) if (edge > EITHER_EDGE)
SOFT_ERROR(PI_BAD_EDGE, "bad ISR edge (%d)", edge); SOFT_ERROR(PI_BAD_EDGE, "bad ISR edge (%d)", edge);
@ -11486,8 +11512,8 @@ int gpioSetISRFuncEx(
CHECK_INITED; CHECK_INITED;
if (gpio > PI_MAX_USER_GPIO) if (gpio > PI_MAX_GPIO)
SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio); SOFT_ERROR(PI_BAD_GPIO, "bad gpio (%d)", gpio);
if (edge > EITHER_EDGE) if (edge > EITHER_EDGE)
SOFT_ERROR(PI_BAD_EDGE, "bad ISR edge (%d)", edge); SOFT_ERROR(PI_BAD_EDGE, "bad ISR edge (%d)", edge);
@ -11504,7 +11530,7 @@ static void closeOrphanedNotifications(int slot, int fd)
for (i=0; i<PI_NOTIFY_SLOTS; i++) for (i=0; i<PI_NOTIFY_SLOTS; i++)
{ {
if ((i != slot) && if ((i != slot) &&
(gpioNotify[i].state != PI_NOTIFY_CLOSED) && (gpioNotify[i].state >= PI_NOTIFY_OPENED) &&
(gpioNotify[i].fd == fd)) (gpioNotify[i].fd == fd))
{ {
DBG(DBG_USER, "closed orphaned fd=%d (handle=%d)", fd, i); DBG(DBG_USER, "closed orphaned fd=%d (handle=%d)", fd, i);
@ -11516,6 +11542,15 @@ static void closeOrphanedNotifications(int slot, int fd)
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
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 gpioNotifyOpenWithSize(int bufSize)
{ {
int i, slot, fd; int i, slot, fd;
@ -11527,18 +11562,21 @@ int gpioNotifyOpenWithSize(int bufSize)
slot = -1; slot = -1;
notifyMutex(1);
for (i=0; i<PI_NOTIFY_SLOTS; i++) for (i=0; i<PI_NOTIFY_SLOTS; i++)
{ {
if (gpioNotify[i].state == PI_NOTIFY_CLOSED) if (gpioNotify[i].state == PI_NOTIFY_CLOSED)
{ {
gpioNotify[i].state = PI_NOTIFY_OPENED;
slot = i; slot = i;
gpioNotify[slot].state = PI_NOTIFY_RESERVED;
break; break;
} }
} }
if (slot < 0) notifyMutex(0);
SOFT_ERROR(PI_NO_HANDLE, "no handle");
if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no handle");
sprintf(name, "/dev/pigpio%d", slot); sprintf(name, "/dev/pigpio%d", slot);
@ -11569,6 +11607,7 @@ int gpioNotifyOpenWithSize(int bufSize)
gpioNotify[slot].pipe = 1; gpioNotify[slot].pipe = 1;
gpioNotify[slot].max_emits = MAX_EMITS; gpioNotify[slot].max_emits = MAX_EMITS;
gpioNotify[slot].lastReportTick = gpioTick(); gpioNotify[slot].lastReportTick = gpioTick();
gpioNotify[i].state = PI_NOTIFY_OPENED;
closeOrphanedNotifications(slot, fd); closeOrphanedNotifications(slot, fd);
@ -11592,24 +11631,29 @@ static int gpioNotifyOpenInBand(int fd)
slot = -1; slot = -1;
notifyMutex(1);
for (i=0; i<PI_NOTIFY_SLOTS; i++) for (i=0; i<PI_NOTIFY_SLOTS; i++)
{ {
if (gpioNotify[i].state == PI_NOTIFY_CLOSED) if (gpioNotify[i].state == PI_NOTIFY_CLOSED)
{ {
slot = i; slot = i;
gpioNotify[slot].state = PI_NOTIFY_RESERVED;
break; break;
} }
} }
notifyMutex(0);
if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no handle"); if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no handle");
gpioNotify[slot].state = PI_NOTIFY_OPENED;
gpioNotify[slot].seqno = 0; gpioNotify[slot].seqno = 0;
gpioNotify[slot].bits = 0; gpioNotify[slot].bits = 0;
gpioNotify[slot].fd = fd; gpioNotify[slot].fd = fd;
gpioNotify[slot].pipe = 0; gpioNotify[slot].pipe = 0;
gpioNotify[slot].max_emits = MAX_EMITS; gpioNotify[slot].max_emits = MAX_EMITS;
gpioNotify[slot].lastReportTick = gpioTick(); gpioNotify[slot].lastReportTick = gpioTick();
gpioNotify[slot].state = PI_NOTIFY_OPENED;
closeOrphanedNotifications(slot, fd); closeOrphanedNotifications(slot, fd);
@ -12095,6 +12139,7 @@ void gpioStopThread(pthread_t *pth)
int gpioStoreScript(char *script) int gpioStoreScript(char *script)
{ {
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
gpioScript_t *s; gpioScript_t *s;
int status, slot, i; int status, slot, i;
@ -12104,18 +12149,21 @@ int gpioStoreScript(char *script)
slot = -1; slot = -1;
pthread_mutex_lock(&mutex);
for (i=0; i<PI_MAX_SCRIPTS; i++) for (i=0; i<PI_MAX_SCRIPTS; i++)
{ {
if (gpioScript[i].state == PI_SCRIPT_FREE) if (gpioScript[i].state == PI_SCRIPT_FREE)
{ {
gpioScript[i].state = PI_SCRIPT_RESERVED;
slot = i; slot = i;
gpioScript[slot].state = PI_SCRIPT_RESERVED;
break; break;
} }
} }
if (slot < 0) pthread_mutex_unlock(&mutex);
SOFT_ERROR(PI_NO_SCRIPT_ROOM, "no room for scripts");
if (slot < 0) SOFT_ERROR(PI_NO_SCRIPT_ROOM, "no room for scripts");
s = &gpioScript[slot]; s = &gpioScript[slot];
@ -12136,7 +12184,6 @@ int gpioStoreScript(char *script)
s->pthIdp = gpioStartThread(pthScript, s); s->pthIdp = gpioStartThread(pthScript, s);
status = slot; status = slot;
} }
else else
{ {
@ -12752,6 +12799,7 @@ int fileApprove(char *filename)
int fileOpen(char *file, unsigned mode) int fileOpen(char *file, unsigned mode)
{ {
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int fd=-1; int fd=-1;
int i, slot, oflag, omode; int i, slot, oflag, omode;
struct stat statbuf; struct stat statbuf;
@ -12770,18 +12818,21 @@ int fileOpen(char *file, unsigned mode)
slot = -1; slot = -1;
pthread_mutex_lock(&mutex);
for (i=0; i<PI_FILE_SLOTS; i++) for (i=0; i<PI_FILE_SLOTS; i++)
{ {
if (fileInfo[i].state == PI_FILE_CLOSED) if (fileInfo[i].state == PI_FILE_CLOSED)
{ {
fileInfo[i].state = PI_FILE_OPENED;
slot = i; slot = i;
fileInfo[slot].state = PI_FILE_RESERVED;
break; break;
} }
} }
if (slot < 0) pthread_mutex_unlock(&mutex);
SOFT_ERROR(PI_NO_HANDLE, "no file handles");
if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no file handles");
omode = 0; omode = 0;
oflag = 0; oflag = 0;
@ -12839,6 +12890,7 @@ int fileOpen(char *file, unsigned mode)
fileInfo[slot].fd = fd; fileInfo[slot].fd = fd;
fileInfo[slot].mode = mode; fileInfo[slot].mode = mode;
fileInfo[slot].state = PI_FILE_OPENED;
return slot; return slot;
} }

100
pigpio.h
View File

@ -31,7 +31,7 @@ For more information, please refer to <http://unlicense.org/>
#include <stdint.h> #include <stdint.h>
#include <pthread.h> #include <pthread.h>
#define PIGPIO_VERSION 62 #define PIGPIO_VERSION 63
/*TEXT /*TEXT
@ -1363,9 +1363,23 @@ user_gpio: 0-31
Returns 0 if OK, otherwise PI_BAD_USER_GPIO. 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, and the tick. The callback is passed the GPIO, the new 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
. .
The alert may be cancelled by passing NULL as the function. The alert may be cancelled by passing NULL as the function.
@ -1426,33 +1440,49 @@ user_gpio: 0-31
Returns 0 if OK, otherwise PI_BAD_USER_GPIO. 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. the userdata pointer.
. .
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 Only one of [*gpioSetAlertFunc*] or [*gpioSetAlertFuncEx*] can be
registered per GPIO. registered per GPIO.
See [*gpioSetAlertFunc*] for further details.
D*/ D*/
/*F*/ /*F*/
int gpioSetISRFunc( int gpioSetISRFunc(
unsigned user_gpio, unsigned edge, int timeout, gpioISRFunc_t f); unsigned gpio, unsigned edge, int timeout, gpioISRFunc_t f);
/*D /*D
Registers a function to be called (a callback) whenever the specified Registers a function to be called (a callback) whenever the specified
GPIO interrupt occurs. GPIO interrupt occurs.
. . . .
user_gpio: 0-31 gpio: 0-53
edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE
timeout: interrupt timeout in milliseconds (<=0 to cancel) timeout: interrupt timeout in milliseconds (<=0 to cancel)
f: the callback function 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. or PI_BAD_ISR_INIT.
One function may be registered per GPIO. One function may be registered per GPIO.
@ -1491,7 +1521,7 @@ D*/
/*F*/ /*F*/
int gpioSetISRFuncEx( int gpioSetISRFuncEx(
unsigned user_gpio, unsigned gpio,
unsigned edge, unsigned edge,
int timeout, int timeout,
gpioISRFuncEx_t f, gpioISRFuncEx_t f,
@ -1501,14 +1531,14 @@ Registers a function to be called (a callback) whenever the specified
GPIO interrupt occurs. GPIO interrupt occurs.
. . . .
user_gpio: 0-31 gpio: 0-53
edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE
timeout: interrupt timeout in milliseconds (<=0 to cancel) timeout: interrupt timeout in milliseconds (<=0 to cancel)
f: the callback function f: the callback function
userdata: pointer to arbitrary user data 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. or PI_BAD_ISR_INIT.
The function is passed the GPIO, the current level, the The function is passed the GPIO, the current level, the
@ -3137,13 +3167,18 @@ The [*spiRead*], [*spiWrite*], and [*spiXfer*] functions
transfer data packed into 1, 2, or 4 bytes according to transfer data packed into 1, 2, or 4 bytes according to
the word size in bits. the word size in bits.
For bits 1-8 there will be one byte per character. For bits 1-8 there will be one byte per word.
For bits 9-16 there will be two bytes per character. For bits 9-16 there will be two bytes per word.
For bits 17-32 there will be four bytes per character. 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. 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. The other bits in flags should be set to zero.
D*/ D*/
@ -3362,12 +3397,15 @@ One watchdog may be registered per GPIO.
The watchdog may be cancelled by setting timeout to 0. The watchdog may be cancelled by setting timeout to 0.
If no level change has been detected for the GPIO for timeout Until cancelled a timeout will be reported every timeout milliseconds
milliseconds:- after the last GPIO activity.
1) any registered alert function for the GPIO is called with In particular:
1) any registered alert function for the GPIO will be called with
the level set to PI_TIMEOUT. 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. fifo with the flags set to indicate a watchdog timeout.
... ...
@ -3403,7 +3441,15 @@ user_gpio: 0-31
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER. 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 be reported. Your software must be designed to cope with
such reports. such reports.
D*/ D*/
@ -3426,7 +3472,15 @@ user_gpio: 0-31
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER. 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. after it was first detected.
D*/ D*/

View File

@ -299,7 +299,7 @@ import threading
import os import os
import atexit import atexit
VERSION = "1.36" VERSION = "1.37"
exceptions = True exceptions = True
@ -390,6 +390,8 @@ SPI_RX_LSBFIRST = 1 << 15
EVENT_BSC = 31 EVENT_BSC = 31
_SOCK_CMD_LEN = 16
# pigpio command numbers # pigpio command numbers
_PI_CMD_MODES= 0 _PI_CMD_MODES= 0
@ -848,6 +850,10 @@ _except_2 = """
Do you have permission to access the pigpio daemon? Do you have permission to access the pigpio daemon?
Perhaps it was started with sudo pigpiod -nlocalhost""" Perhaps it was started with sudo pigpiod -nlocalhost"""
_except_3 = """
Can't create callback thread.
Perhaps too many simultaneous pigpio connections."""
class _socklock: class _socklock:
""" """
A class to store socket and lock. A class to store socket and lock.
@ -975,7 +981,7 @@ def _pigpio_command(sl, cmd, p1, p2, rl=True):
""" """
sl.l.acquire() sl.l.acquire()
sl.s.send(struct.pack('IIII', cmd, p1, p2, 0)) 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() if rl: sl.l.release()
return res return res
@ -998,7 +1004,7 @@ def _pigpio_command_ext(sl, cmd, p1, p2, p3, extents, rl=True):
ext.extend(x) ext.extend(x)
sl.l.acquire() sl.l.acquire()
sl.s.sendall(ext) 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() if rl: sl.l.release()
return res return res
@ -1048,7 +1054,8 @@ class _callback_thread(threading.Thread):
self.callbacks = [] self.callbacks = []
self.events = [] self.events = []
self.sl.s = socket.create_connection((host, port), None) 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.go = True
self.start() self.start()
@ -1101,7 +1108,7 @@ class _callback_thread(threading.Thread):
def run(self): def run(self):
"""Runs the notification thread.""" """Runs the notification thread."""
lastLevel = _pigpio_command(self.control, _PI_CMD_BR1, 0, 0) lastLevel = self.lastLevel
MSG_SIZ = 12 MSG_SIZ = 12
@ -1743,8 +1750,8 @@ class pi():
The watchdog may be cancelled by setting timeout to 0. The watchdog may be cancelled by setting timeout to 0.
Once a watchdog has been started callbacks for the GPIO Once a watchdog has been started callbacks for the GPIO
will be triggered whenever there has been no GPIO activity will be triggered every timeout interval after the last
for the timeout interval. GPIO activity.
The callback will receive the special level TIMEOUT. The callback will receive the special level TIMEOUT.
@ -3753,7 +3760,14 @@ class pi():
For bits 9-16 there will be two bytes 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 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. The other bits in flags should be set to zero.
@ -4064,7 +4078,13 @@ class pi():
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER. 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. microseconds after it was first detected.
... ...
@ -4088,7 +4108,13 @@ class pi():
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER. 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 be reported. Your software must be designed to cope with
such reports. such reports.
@ -4761,6 +4787,20 @@ class pi():
The user supplied callback receives three parameters, the GPIO, The user supplied callback receives three parameters, the GPIO,
the level, and the tick. 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 If a user callback is not specified a default tally callback is
provided which simply counts edges. The count may be retrieved provided which simply counts edges. The count may be retrieved
by calling the tally function. The count may be reset to zero by calling the tally function. The count may be reset to zero
@ -4946,6 +4986,9 @@ class pi():
except struct.error: except struct.error:
exception = 2 exception = 2
except error:
exception = 3
else: else:
exception = 0 exception = 0
atexit.register(self.stop) atexit.register(self.stop)
@ -4962,8 +5005,10 @@ class pi():
print(_except_a.format(s)) print(_except_a.format(s))
if exception == 1: if exception == 1:
print(_except_1) print(_except_1)
else: elif exception == 2:
print(_except_2) print(_except_2)
else:
print(_except_3)
print(_except_z) print(_except_z)
def stop(self): def stop(self):

View File

@ -2,7 +2,7 @@
." Process this file with ." Process this file with
." groff -man -Tascii pigpiod.1 ." groff -man -Tascii pigpiod.1
." ."
.TH pigpiod 1 2012-2015 Linux "pigpio archive" .TH pigpiod 1 2012-2017 Linux "pigpio archive"
.SH NAME .SH NAME
pigpiod - A utility to start the pigpio library as a daemon. pigpiod - A utility to start the pigpio library as a daemon.

View File

@ -2,7 +2,7 @@
." Process this file with ." Process this file with
." groff -man -Tascii pigpiod_if.3 ." 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 .SH NAME
pigpiod_if - A C library to interface to the pigpio daemon. pigpiod_if - A C library to interface to the pigpio daemon.
@ -1065,15 +1065,13 @@ The watchdog may be cancelled by setting timeout to 0.
.br .br
.br .br
If no level change has been detected for the GPIO for timeout Once a watchdog has been started callbacks for the GPIO will be
milliseconds any notification for the GPIO has a report written triggered every timeout interval after the last GPIO activity.
to the fifo with the flags set to indicate a watchdog timeout.
.br .br
.br .br
The \fBcallback\fP and \fBcallback_ex\fP functions interpret the flags The callback will receive the special level PI_TIMEOUT.
and will call registered callbacks for the GPIO with level TIMEOUT.
.IP "\fBint set_glitch_filter(unsigned user_gpio, unsigned steady)\fP" .IP "\fBint set_glitch_filter(unsigned user_gpio, unsigned steady)\fP"
.IP "" 4 .IP "" 4
@ -1107,7 +1105,15 @@ Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
.br .br
.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. after it was first detected.
.IP "\fBint set_noise_filter(unsigned user_gpio, unsigned steady, unsigned active)\fP" .IP "\fBint set_noise_filter(unsigned user_gpio, unsigned steady, unsigned active)\fP"
@ -1144,7 +1150,19 @@ Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
.br .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 \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 be reported. Your software must be designed to cope with
such reports. such reports.
@ -3415,6 +3433,39 @@ sets 8 bits per word. Auxiliary SPI device only.
.br .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 .br
The other bits in flags should be set to zero. The other bits in flags should be set to zero.
@ -3792,6 +3843,36 @@ pigif_duplicate_callback, or pigif_bad_callback.
The callback is called with the GPIO, edge, and tick, whenever the The callback is called with the GPIO, edge, and tick, whenever the
GPIO has the identified edge. 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 "\fBint callback_ex(unsigned user_gpio, unsigned edge, CBFuncEx_t f, void *userdata)\fP"
.IP "" 4 .IP "" 4
This function initialises a new callback. This function initialises a new callback.
@ -3828,6 +3909,36 @@ 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 "\fBint callback_cancel(unsigned callback_id)\fP"
.IP "" 4 .IP "" 4
This function cancels a callback identified by its id. This function cancels a callback identified by its id.

View File

@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/> For more information, please refer to <http://unlicense.org/>
*/ */
/* PIGPIOD_IF_VERSION 26 */ /* PIGPIOD_IF_VERSION 27 */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>

View File

@ -30,7 +30,7 @@ For more information, please refer to <http://unlicense.org/>
#include "pigpio.h" #include "pigpio.h"
#define PIGPIOD_IF_VERSION 26 #define PIGPIOD_IF_VERSION 27
/*TEXT /*TEXT
@ -805,12 +805,10 @@ Only one watchdog may be registered per GPIO.
The watchdog may be cancelled by setting timeout to 0. The watchdog may be cancelled by setting timeout to 0.
If no level change has been detected for the GPIO for timeout Once a watchdog has been started callbacks for the GPIO will be
milliseconds any notification for the GPIO has a report written triggered every timeout interval after the last GPIO activity.
to the fifo with the flags set to indicate a watchdog timeout.
The [*callback*] and [*callback_ex*] functions interpret the flags The callback will receive the special level PI_TIMEOUT.
and will call registered callbacks for the GPIO with level TIMEOUT.
D*/ D*/
/*F*/ /*F*/
@ -830,7 +828,12 @@ user_gpio: 0-31
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER. 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. after it was first detected.
D*/ D*/
@ -852,7 +855,13 @@ user_gpio: 0-31
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER. 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 be reported. Your software must be designed to cope with
such reports. such reports.
D*/ D*/
@ -2194,6 +2203,22 @@ device only.
bbbbbb defines the word size in bits (0-32). The default (0) bbbbbb defines the word size in bits (0-32). The default (0)
sets 8 bits per word. Auxiliary SPI device only. 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. The other bits in flags should be set to zero.
D*/ D*/
@ -2428,6 +2453,20 @@ pigif_duplicate_callback, or pigif_bad_callback.
The callback is called with the GPIO, edge, and tick, whenever the The callback is called with the GPIO, edge, and tick, whenever the
GPIO has the identified edge. 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*/ D*/
/*F*/ /*F*/
@ -2449,6 +2488,21 @@ pigif_duplicate_callback, or pigif_bad_callback.
The callback is called with the GPIO, edge, tick, and user, whenever The callback is called with the GPIO, edge, tick, and user, whenever
the GPIO has the identified edge. 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*/ D*/
/*F*/ /*F*/

View File

@ -2,7 +2,7 @@
." Process this file with ." Process this file with
." groff -man -Tascii pigpiod_if2.3 ." 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 .SH NAME
pigpiod_if2 - A C library to interface to the pigpio daemon. pigpiod_if2 - A C library to interface to the pigpio daemon.
@ -1133,15 +1133,13 @@ The watchdog may be cancelled by setting timeout to 0.
.br .br
.br .br
If no level change has been detected for the GPIO for timeout Once a watchdog has been started callbacks for the GPIO will be
milliseconds any notification for the GPIO has a report written triggered every timeout interval after the last GPIO activity.
to the fifo with the flags set to indicate a watchdog timeout.
.br .br
.br .br
The \fBcallback\fP and \fBcallback_ex\fP functions interpret the flags The callback will receive the special level PI_TIMEOUT.
and will call registered callbacks for the GPIO with level TIMEOUT.
.IP "\fBint set_glitch_filter(int pi, unsigned user_gpio, unsigned steady)\fP" .IP "\fBint set_glitch_filter(int pi, unsigned user_gpio, unsigned steady)\fP"
.IP "" 4 .IP "" 4
@ -1177,7 +1175,19 @@ Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
.br .br
.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. after it was first detected.
.IP "\fBint set_noise_filter(int pi, unsigned user_gpio, unsigned steady, unsigned active)\fP" .IP "\fBint set_noise_filter(int pi, unsigned user_gpio, unsigned steady, unsigned active)\fP"
@ -1216,7 +1226,19 @@ Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER.
.br .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 \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 be reported. Your software must be designed to cope with
such reports. such reports.
@ -4208,11 +4230,22 @@ For bits 17-32 there will be four bytes per character.
.br .br
.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. and count should be 64.
.br .br
.br
E.g. to transfer the 14 bit value 0x1ABC send the bytes 0xBC followed
by 0x1A.
.br
.br .br
The other bits in flags should be set to zero. The other bits in flags should be set to zero.
@ -5317,6 +5350,36 @@ pigif_duplicate_callback, or pigif_bad_callback.
The callback is called with the GPIO, edge, and tick, whenever the The callback is called with the GPIO, edge, and tick, whenever the
GPIO has the identified edge. 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 "\fBint callback_ex(int pi, unsigned user_gpio, unsigned edge, CBFuncEx_t f, void *userdata)\fP"
.IP "" 4 .IP "" 4
This function initialises a new callback. This function initialises a new callback.
@ -5351,6 +5414,40 @@ pigif_duplicate_callback, or pigif_bad_callback.
The callback is called with the GPIO, edge, tick, and the userdata The callback is called with the GPIO, edge, tick, and the userdata
pointer, whenever the GPIO has the identified edge. 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 "\fBint callback_cancel(unsigned callback_id)\fP"
.IP "" 4 .IP "" 4
This function cancels a callback identified by its id. This function cancels a callback identified by its id.

View File

@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/> For more information, please refer to <http://unlicense.org/>
*/ */
/* PIGPIOD_IF2_VERSION 10 */ /* PIGPIOD_IF2_VERSION 11 */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>

View File

@ -30,7 +30,7 @@ For more information, please refer to <http://unlicense.org/>
#include "pigpio.h" #include "pigpio.h"
#define PIGPIOD_IF2_VERSION 10 #define PIGPIOD_IF2_VERSION 11
/*TEXT /*TEXT
@ -879,12 +879,10 @@ Only one watchdog may be registered per GPIO.
The watchdog may be cancelled by setting timeout to 0. The watchdog may be cancelled by setting timeout to 0.
If no level change has been detected for the GPIO for timeout Once a watchdog has been started callbacks for the GPIO will be
milliseconds any notification for the GPIO has a report written triggered every timeout interval after the last GPIO activity.
to the fifo with the flags set to indicate a watchdog timeout.
The [*callback*] and [*callback_ex*] functions interpret the flags The callback will receive the special level PI_TIMEOUT.
and will call registered callbacks for the GPIO with level TIMEOUT.
D*/ D*/
/*F*/ /*F*/
@ -905,7 +903,13 @@ user_gpio: 0-31
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER. 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. after it was first detected.
D*/ D*/
@ -929,7 +933,13 @@ user_gpio: 0-31
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_BAD_FILTER. 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 be reported. Your software must be designed to cope with
such reports. such reports.
D*/ D*/
@ -2631,9 +2641,14 @@ For bits 1-8 there will be one byte per character.
For bits 9-16 there will be two bytes 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 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. 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. The other bits in flags should be set to zero.
D*/ D*/
@ -3247,6 +3262,20 @@ pigif_duplicate_callback, or pigif_bad_callback.
The callback is called with the GPIO, edge, and tick, whenever the The callback is called with the GPIO, edge, and tick, whenever the
GPIO has the identified edge. 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*/ D*/
/*F*/ /*F*/
@ -3268,6 +3297,22 @@ pigif_duplicate_callback, or pigif_bad_callback.
The callback is called with the GPIO, edge, tick, and the userdata The callback is called with the GPIO, edge, tick, and the userdata
pointer, whenever the GPIO has the identified edge. 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*/ D*/
/*F*/ /*F*/

32
pigs.1
View File

@ -2,7 +2,7 @@
." Process this file with ." Process this file with
." groff -man -Tascii foo.1 ." groff -man -Tascii foo.1
." ."
.TH pigs 1 2012-2015 Linux "pigpio archive" .TH pigs 1 2012-2017 Linux "pigpio archive"
.SH NAME .SH NAME
pigs - command line socket access to the pigpio daemon. pigs - command line socket access to the pigpio daemon.
@ -1079,6 +1079,12 @@ has been stable for at least \fBstdy\fP microseconds. The
level is then reported. Level changes of less than \fBstdy\fP level is then reported. Level changes of less than \fBstdy\fP
microseconds are ignored. 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 .br
Note, each (stable) edge will be timestamped \fBstdy\fP microseconds Note, each (stable) edge will be timestamped \fBstdy\fP microseconds
after it was first detected. after it was first detected.
@ -1160,6 +1166,12 @@ been stable for \fBstdy\fP microseconds is detected. Level
changes on the GPIO are then reported for \fBactv\fP microseconds changes on the GPIO are then reported for \fBactv\fP microseconds
after which the process repeats. 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 .br
Note, level changes before and after the active period may Note, level changes before and after the active period may
be reported. Your software must be designed to cope with be reported. Your software must be designed to cope with
@ -3957,7 +3969,14 @@ For bits 9-16 there will be two bytes per character.
For bits 17-32 there will be four bytes per character. For bits 17-32 there will be four bytes per character.
.br .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 .br
The other bits in flags should be set to zero. The other bits in flags should be set to zero.
@ -4183,11 +4202,10 @@ One watchdog may be registered per GPIO.
The watchdog may be cancelled by setting timeout to 0. The watchdog may be cancelled by setting timeout to 0.
.br .br
If no level change has been detected for the GPIO for timeout milliseconds:- Once a watchdog has been started monitors of the GPIO
will be triggered every timeout interval after the last
.br GPIO activity. The watchdog expiry will be indicated by
any notification for the GPIO has a report written to the fifo with a special TIMEOUT value.
the flags set to indicate a watchdog timeout.
.br .br

View File

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

View File

@ -282,15 +282,13 @@ void t4()
gpioSetPWMrange(GPIO, 100); gpioSetPWMrange(GPIO, 100);
h = gpioNotifyOpen(); 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); sprintf(p, "/dev/pigpio%d", h);
f = open(p, O_RDONLY); f = open(p, O_RDONLY);
e = gpioNotifyBegin(h, (1<<GPIO));
CHECK(4, 1, e, 0, 0, "notify open/begin");
gpioPWM(GPIO, 50); gpioPWM(GPIO, 50);
time_sleep(4); time_sleep(4);
gpioPWM(GPIO, 0); gpioPWM(GPIO, 0);

View File

@ -253,15 +253,13 @@ void t4()
set_PWM_range(GPIO, 100); set_PWM_range(GPIO, 100);
h = notify_open(); 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); sprintf(p, "/dev/pigpio%d", h);
f = open(p, O_RDONLY); 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); set_PWM_dutycycle(GPIO, 50);
time_sleep(4); time_sleep(4);
set_PWM_dutycycle(GPIO, 0); set_PWM_dutycycle(GPIO, 0);

View File

@ -257,15 +257,13 @@ void t4(int pi)
set_PWM_range(pi, GPIO, 100); set_PWM_range(pi, GPIO, 100);
h = notify_open(pi); 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); sprintf(p, "/dev/pigpio%d", h);
f = open(p, O_RDONLY); 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); set_PWM_dutycycle(pi, GPIO, 50);
time_sleep(4); time_sleep(4);
set_PWM_dutycycle(pi, GPIO, 0); set_PWM_dutycycle(pi, GPIO, 0);