diff --git a/pigpio.3 b/pigpio.3 index 52ff01e..43406d5 100644 --- a/pigpio.3 +++ b/pigpio.3 @@ -1369,6 +1369,21 @@ else .EE +.IP "\fBint gpioNotifyOpenWithSize(int bufSize)\fP" +.IP "" 4 +This function requests a free notification handle. + +.br + +.br +It differs from \fBgpioNotifyOpen\fP in that the pipe size may be +specified, whereas \fBgpioNotifyOpen\fP uses the default pipe size. + +.br + +.br +See \fBgpioNotifyOpen\fP for further details. + .IP "\fBint gpioNotifyBegin(unsigned handle, uint32_t bits)\fP" .IP "" 4 This function starts notifications on a previously opened handle. diff --git a/pigpio.c b/pigpio.c index cf10699..f781551 100644 --- a/pigpio.c +++ b/pigpio.c @@ -25,10 +25,12 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to */ -/* pigpio version 40 */ +/* pigpio version 41 */ /* include ------------------------------------------------------- */ +#define _GNU_SOURCE + #include #include #include @@ -39,11 +41,11 @@ For more information, please refer to #include #include #include +#include #include #include #include #include -#include #include #include #include @@ -2966,7 +2968,7 @@ int rawWaveAddGeneric(unsigned numIn1, rawWave_t *in1) int i2cWriteQuick(unsigned handle, unsigned bit) { - int err; + int status; DBG(DBG_USER, "handle=%d bit=%d", handle, bit); @@ -2984,17 +2986,22 @@ int i2cWriteQuick(unsigned handle, unsigned bit) if (bit > 1) SOFT_ERROR(PI_BAD_PARAM, "bad bit (%d)", bit); - err = my_smbus_access( + status = my_smbus_access( i2cInfo[handle].fd, bit, 0, PI_I2C_SMBUS_QUICK, NULL); - if (err < 0) return PI_I2C_WRITE_FAILED; + if (status < 0) + { + DBG(DBG_USER, "error=%d (%m)", status); + return PI_I2C_WRITE_FAILED; + } - return err; + return status; } int i2cReadByte(unsigned handle) { union my_smbus_data data; + int status; DBG(DBG_USER, "handle=%d", handle); @@ -3009,17 +3016,22 @@ int i2cReadByte(unsigned handle) if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_BYTE) == 0) SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver"); - if (my_smbus_access( - i2cInfo[handle].fd, PI_I2C_SMBUS_READ, 0, PI_I2C_SMBUS_BYTE, &data)) + status = my_smbus_access( + i2cInfo[handle].fd, PI_I2C_SMBUS_READ, 0, PI_I2C_SMBUS_BYTE, &data); + + if (status < 0) + { + DBG(DBG_USER, "error=%d (%m)", status); return PI_I2C_READ_FAILED; - else - return 0xFF & data.byte; + } + + return 0xFF & data.byte; } int i2cWriteByte(unsigned handle, unsigned bVal) { - int err; + int status; DBG(DBG_USER, "handle=%d bVal=%d", handle, bVal); @@ -3037,22 +3049,27 @@ int i2cWriteByte(unsigned handle, unsigned bVal) if (bVal > 0xFF) SOFT_ERROR(PI_BAD_PARAM, "bad bVal (%d)", bVal); - err = my_smbus_access( + status = my_smbus_access( i2cInfo[handle].fd, PI_I2C_SMBUS_WRITE, bVal, PI_I2C_SMBUS_BYTE, NULL); - if (err < 0) return PI_I2C_WRITE_FAILED; + if (status < 0) + { + DBG(DBG_USER, "error=%d (%m)", status); + return PI_I2C_WRITE_FAILED; + } - return err; + return status; } int i2cReadByteData(unsigned handle, unsigned reg) { union my_smbus_data data; + int status; DBG(DBG_USER, "handle=%d reg=%d", handle, reg); @@ -3070,11 +3087,16 @@ int i2cReadByteData(unsigned handle, unsigned reg) if (reg > 0xFF) SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg); - if (my_smbus_access( - i2cInfo[handle].fd, PI_I2C_SMBUS_READ, reg, PI_I2C_SMBUS_BYTE_DATA, &data)) + status = my_smbus_access(i2cInfo[handle].fd, + PI_I2C_SMBUS_READ, reg, PI_I2C_SMBUS_BYTE_DATA, &data); + + if (status < 0) + { + DBG(DBG_USER, "error=%d (%m)", status); return PI_I2C_READ_FAILED; - else - return 0xFF & data.byte; + } + + return 0xFF & data.byte; } @@ -3082,7 +3104,7 @@ int i2cWriteByteData(unsigned handle, unsigned reg, unsigned bVal) { union my_smbus_data data; - int err; + int status; DBG(DBG_USER, "handle=%d reg=%d bVal=%d", handle, reg, bVal); @@ -3105,22 +3127,27 @@ int i2cWriteByteData(unsigned handle, unsigned reg, unsigned bVal) data.byte = bVal; - err = my_smbus_access( + status = my_smbus_access( i2cInfo[handle].fd, PI_I2C_SMBUS_WRITE, reg, PI_I2C_SMBUS_BYTE_DATA, &data); - if (err < 0) return PI_I2C_WRITE_FAILED; + if (status < 0) + { + DBG(DBG_USER, "error=%d (%m)", status); + return PI_I2C_WRITE_FAILED; + } - return err; + return status; } int i2cReadWordData(unsigned handle, unsigned reg) { union my_smbus_data data; + int status; DBG(DBG_USER, "handle=%d reg=%d", handle, reg); @@ -3138,15 +3165,20 @@ int i2cReadWordData(unsigned handle, unsigned reg) if (reg > 0xFF) SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg); - if (my_smbus_access( + status = (my_smbus_access( i2cInfo[handle].fd, PI_I2C_SMBUS_READ, reg, PI_I2C_SMBUS_WORD_DATA, - &data)) + &data)); + + if (status < 0) + { + DBG(DBG_USER, "error=%d (%m)", status); return PI_I2C_READ_FAILED; - else - return 0xFFFF & data.word; + } + + return 0xFFFF & data.word; } @@ -3154,7 +3186,7 @@ int i2cWriteWordData(unsigned handle, unsigned reg, unsigned wVal) { union my_smbus_data data; - int err; + int status; DBG(DBG_USER, "handle=%d reg=%d wVal=%d", handle, reg, wVal); @@ -3177,22 +3209,27 @@ int i2cWriteWordData(unsigned handle, unsigned reg, unsigned wVal) data.word = wVal; - err = my_smbus_access( + status = my_smbus_access( i2cInfo[handle].fd, PI_I2C_SMBUS_WRITE, reg, PI_I2C_SMBUS_WORD_DATA, &data); - if (err < 0) return PI_I2C_WRITE_FAILED; + if (status < 0) + { + DBG(DBG_USER, "error=%d (%m)", status); + return PI_I2C_WRITE_FAILED; + } - return err; + return status; } int i2cProcessCall(unsigned handle, unsigned reg, unsigned wVal) { union my_smbus_data data; + int status; DBG(DBG_USER, "handle=%d reg=%d wVal=%d", handle, reg, wVal); @@ -3215,14 +3252,19 @@ int i2cProcessCall(unsigned handle, unsigned reg, unsigned wVal) data.word = wVal; - if (my_smbus_access( + status = (my_smbus_access( i2cInfo[handle].fd, PI_I2C_SMBUS_WRITE, reg, PI_I2C_SMBUS_PROC_CALL, - &data)) + &data)); + + if (status < 0) + { + DBG(DBG_USER, "error=%d (%m)", status); return PI_I2C_READ_FAILED; - else - return 0xFFFF & data.word; + } + + return 0xFFFF & data.word; } @@ -3230,7 +3272,7 @@ int i2cReadBlockData(unsigned handle, unsigned reg, char *buf) { union my_smbus_data data; - int i; + int i, status; DBG(DBG_USER, "handle=%d reg=%d buf=%08X", handle, reg, (unsigned)buf); @@ -3248,13 +3290,18 @@ int i2cReadBlockData(unsigned handle, unsigned reg, char *buf) if (reg > 0xFF) SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg); - if (my_smbus_access( + status = (my_smbus_access( i2cInfo[handle].fd, PI_I2C_SMBUS_READ, reg, PI_I2C_SMBUS_BLOCK_DATA, - &data)) + &data)); + + if (status < 0) + { + DBG(DBG_USER, "error=%d (%m)", status); return PI_I2C_READ_FAILED; + } else { if (data.block[0] <= PI_I2C_SMBUS_BLOCK_MAX) @@ -3272,7 +3319,7 @@ int i2cWriteBlockData( { union my_smbus_data data; - int i, err; + int i, status; DBG(DBG_USER, "handle=%d reg=%d count=%d [%s]", handle, reg, count, myBuf2Str(count, buf)); @@ -3297,16 +3344,20 @@ int i2cWriteBlockData( for (i=1; i<=count; i++) data.block[i] = buf[i-1]; data.block[0] = count; - err = my_smbus_access( + status = my_smbus_access( i2cInfo[handle].fd, PI_I2C_SMBUS_WRITE, reg, PI_I2C_SMBUS_BLOCK_DATA, &data); - if (err < 0) return PI_I2C_WRITE_FAILED; + if (status < 0) + { + DBG(DBG_USER, "error=%d (%m)", status); + return PI_I2C_WRITE_FAILED; + } - return err; + return status; } @@ -3315,7 +3366,7 @@ int i2cBlockProcessCall( { union my_smbus_data data; - int i; + int i, status; DBG(DBG_USER, "handle=%d reg=%d count=%d [%s]", handle, reg, count, myBuf2Str(count, buf)); @@ -3339,10 +3390,16 @@ int i2cBlockProcessCall( for (i=1; i<=count; i++) data.block[i] = buf[i-1]; data.block[0] = count; - if (my_smbus_access( + + status = (my_smbus_access( i2cInfo[handle].fd, PI_I2C_SMBUS_WRITE, reg, - PI_I2C_SMBUS_BLOCK_PROC_CALL, &data)) + PI_I2C_SMBUS_BLOCK_PROC_CALL, &data)); + + if (status < 0) + { + DBG(DBG_USER, "error=%d (%m)", status); return PI_I2C_READ_FAILED; + } else { if (data.block[0] <= PI_I2C_SMBUS_BLOCK_MAX) @@ -3360,7 +3417,7 @@ int i2cReadI2CBlockData( { union my_smbus_data data; - int i; + int i, status; uint32_t size; DBG(DBG_USER, "handle=%d reg=%d count=%d buf=%08X", @@ -3389,9 +3446,15 @@ int i2cReadI2CBlockData( size = PI_I2C_SMBUS_I2C_BLOCK_DATA; data.block[0] = count; - if (my_smbus_access( - i2cInfo[handle].fd, PI_I2C_SMBUS_READ, reg, size, &data)) + + status = (my_smbus_access( + i2cInfo[handle].fd, PI_I2C_SMBUS_READ, reg, size, &data)); + + if (status < 0) + { + DBG(DBG_USER, "error=%d (%m)", status); return PI_I2C_READ_FAILED; + } else { if (data.block[0] <= PI_I2C_SMBUS_I2C_BLOCK_MAX) @@ -3409,7 +3472,7 @@ int i2cWriteI2CBlockData( { union my_smbus_data data; - int i, err; + int i, status; DBG(DBG_USER, "handle=%d reg=%d count=%d [%s]", handle, reg, count, myBuf2Str(count, buf)); @@ -3435,16 +3498,20 @@ int i2cWriteI2CBlockData( data.block[0] = count; - err = my_smbus_access( + status = my_smbus_access( i2cInfo[handle].fd, PI_I2C_SMBUS_WRITE, reg, PI_I2C_SMBUS_I2C_BLOCK_BROKEN, &data); - if (err < 0) return PI_I2C_WRITE_FAILED; + if (status < 0) + { + DBG(DBG_USER, "error=%d (%m)", status); + return PI_I2C_WRITE_FAILED; + } - return err; + return status; } int i2cWriteDevice(unsigned handle, char *buf, unsigned count) @@ -3468,9 +3535,12 @@ int i2cWriteDevice(unsigned handle, char *buf, unsigned count) bytes = write(i2cInfo[handle].fd, buf, count); if (bytes != count) + { + DBG(DBG_USER, "error=%d (%m)", bytes); return PI_I2C_WRITE_FAILED; - else - return 0; + } + + return 0; } int i2cReadDevice(unsigned handle, char *buf, unsigned count) @@ -3494,9 +3564,12 @@ int i2cReadDevice(unsigned handle, char *buf, unsigned count) bytes = read(i2cInfo[handle].fd, buf, count); if (bytes != count) + { + DBG(DBG_USER, "error=%d (%m)", bytes); return PI_I2C_READ_FAILED; - else - return bytes; + } + + return bytes; } int i2cOpen(unsigned i2cBus, unsigned i2cAddr, unsigned i2cFlags) @@ -5161,17 +5234,21 @@ static void alertActivityFilter(int numSamples) } } + + + + static void * pthAlertThread(void *x) { struct timespec req, rem; uint32_t oldLevel, newLevel, level, reportedLevel; uint32_t oldSlot, newSlot; - uint32_t stick, expected, nowTick; + uint32_t stick, expected, nowTick, ft; int32_t diff; int cycle, pulse; int emit, seqno, emitted; uint32_t changes, bits, changedBits, timeoutBits; - int numSamples, d; + int numSamples, d, ticks, i; int b, n, v; int rp, wp; int err; @@ -5192,8 +5269,11 @@ static void * pthAlertThread(void *x) oldSlot = dmaCurrentSlot(dmaNowAtICB()); + oldSlot = (oldSlot / PULSE_PER_CYCLE) * PULSE_PER_CYCLE; + cycle = (oldSlot/PULSE_PER_CYCLE); - pulse = (oldSlot%PULSE_PER_CYCLE); + + pulse = 0; stopped = 0; @@ -5208,6 +5288,8 @@ static void * pthAlertThread(void *x) { newSlot = dmaCurrentSlot(dmaNowAtICB()); + newSlot = (newSlot / PULSE_PER_CYCLE) * PULSE_PER_CYCLE; + numSamples = 0; changedBits = 0; @@ -5247,6 +5329,22 @@ static void * pthAlertThread(void *x) diff = stick - expected; + if ((diff < -1) || (diff > 1)) + { + if (gpioCfg.clockMicros > 1) + { + ft = gpioSample[numSamples-PULSE_PER_CYCLE].tick; + + ticks = stick - ft; + + for (i=1; i #include #include -#define PIGPIO_VERSION 40 +#define PIGPIO_VERSION 41 /*TEXT @@ -172,6 +172,7 @@ gpioSetGetSamplesFuncEx Requests a gpio samples callback, extended gpioSetTimerFuncEx Request a regular timed callback, extended gpioNotifyOpen Request a notification handle +gpioNotifyOpenWithSize Request a notification handle with sized pipe gpioNotifyBegin Start notifications for selected gpios gpioNotifyPause Pause notifications gpioNotifyClose Close a notification @@ -1412,6 +1413,18 @@ else D*/ +/*F*/ +int gpioNotifyOpenWithSize(int bufSize); +/*D +This function requests a free notification handle. + +It differs from [*gpioNotifyOpen*] in that the pipe size may be +specified, whereas [*gpioNotifyOpen*] uses the default pipe size. + +See [*gpioNotifyOpen*] for further details. +D*/ + + /*F*/ int gpioNotifyBegin(unsigned handle, uint32_t bits); /*D