For more information, please refer to <http://unlicense.org/>
*/
-/* pigpio version 40 */
+/* pigpio version 41 */
/* include ------------------------------------------------------- */
+#define _GNU_SOURCE
+
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <syslog.h>
#include <poll.h>
#include <unistd.h>
+#include <fcntl.h>
#include <termios.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
-#include <fcntl.h>
#include <sys/ioctl.h>
#include <limits.h>
#include <pthread.h>
int i2cWriteQuick(unsigned handle, unsigned bit)
{
- int err;
+ int status;
DBG(DBG_USER, "handle=%d bit=%d", handle, 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);
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);
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);
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;
}
{
union my_smbus_data data;
- int err;
+ int status;
DBG(DBG_USER, "handle=%d reg=%d bVal=%d", handle, reg, 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);
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;
}
{
union my_smbus_data data;
- int err;
+ int status;
DBG(DBG_USER, "handle=%d reg=%d wVal=%d", handle, reg, 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);
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;
}
{
union my_smbus_data data;
- int i;
+ int i, status;
DBG(DBG_USER, "handle=%d reg=%d buf=%08X", handle, reg, (unsigned)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)
{
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));
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;
}
{
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));
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)
{
union my_smbus_data data;
- int i;
+ int i, status;
uint32_t size;
DBG(DBG_USER, "handle=%d reg=%d count=%d buf=%08X",
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)
{
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));
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)
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)
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)
}
}
+
+
+
+
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;
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;
{
newSlot = dmaCurrentSlot(dmaNowAtICB());
+ newSlot = (newSlot / PULSE_PER_CYCLE) * PULSE_PER_CYCLE;
+
numSamples = 0;
changedBits = 0;
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<PULSE_PER_CYCLE; i++)
+ {
+ gpioSample[numSamples-PULSE_PER_CYCLE+i].tick =
+ ((i*ticks)/PULSE_PER_CYCLE) + ft;
+ }
+ }
+ }
+
diff += (TICKSLOTS/2);
if (diff < 0)
/* ----------------------------------------------------------------------- */
-int gpioNotifyOpen(void)
+int gpioNotifyOpenWithSize(int bufSize)
{
int i, slot, fd;
char name[32];
- DBG(DBG_USER, "");
+ DBG(DBG_USER, "bufSize=%d", bufSize);
CHECK_INITED;
SOFT_ERROR(PI_BAD_PATHNAME, "open %s failed (%m)", name);
}
+ if (bufSize != 0)
+ {
+ i = fcntl(fd, F_SETPIPE_SZ, bufSize);
+ if (i != bufSize)
+ {
+ gpioNotify[slot].state = PI_NOTIFY_CLOSED;
+ SOFT_ERROR(PI_BAD_PATHNAME,
+ "fcntl %s size %d failed (%m)", name, bufSize);
+ }
+ }
+
gpioNotify[slot].seqno = 0;
gpioNotify[slot].bits = 0;
gpioNotify[slot].fd = fd;
return slot;
}
+int gpioNotifyOpen(void)
+{
+ return gpioNotifyOpenWithSize(0);
+}
/* ----------------------------------------------------------------------- */