diff --git a/Makefile b/Makefile
index 08856bd..2cfc4b8 100644
--- a/Makefile
+++ b/Makefile
@@ -52,7 +52,8 @@ install: $(LIB)
sudo install -m 0755 pig2vcd /usr/local/bin
sudo install -m 0755 pigpiod /usr/local/bin
sudo install -m 0755 pigs /usr/local/bin
- sudo python setup.py install
+ sudo python2 setup.py install
+ sudo python3 setup.py install
sudo install -m 0755 -d /usr/local/man/man1
sudo install -m 0644 *.1 /usr/local/man/man1
sudo install -m 0755 -d /usr/local/man/man3
@@ -66,6 +67,12 @@ uninstall:
sudo rm -f /usr/local/bin/pig2vcd
sudo rm -f /usr/local/bin/pigpiod
sudo rm -f /usr/local/bin/pigs
+ echo removing python2 files
+ sudo python2 setup.py install --record /tmp/pigpio >/dev/null
+ sudo xargs rm -f < /tmp/pigpio >/dev/null
+ echo removing python3 files
+ sudo python3 setup.py install --record /tmp/pigpio >/dev/null
+ sudo xargs rm -f < /tmp/pigpio >/dev/null
sudo rm -f /usr/local/man/man1/pig*.1
sudo rm -f /usr/local/man/man3/pig*.3
diff --git a/command.c b/command.c
index 06fc914..baa41eb 100644
--- a/command.c
+++ b/command.c
@@ -26,7 +26,7 @@ For more information, please refer to
*/
/*
-This version is for pigpio version 31+
+This version is for pigpio version 32+
*/
#include
@@ -45,6 +45,10 @@ cmdInfo_t cmdInfo[]=
{PI_CMD_BC1, "BC1", 111, 1}, // gpioWrite_Bits_0_31_Clear
{PI_CMD_BC2, "BC2", 111, 1}, // gpioWrite_Bits_32_53_Clear
+ {PI_CMD_BI2CC, "BI2CC", 112, 0}, // bbI2CClose
+ {PI_CMD_BI2CO, "BI2CO", 131, 0}, // bbI2COpen
+ {PI_CMD_BI2CX, "BI2CX", 193, 6}, // bbI2CXfer
+
{PI_CMD_BR1, "BR1", 101, 3}, // gpioRead_Bits_0_31
{PI_CMD_BR2, "BR2", 101, 3}, // gpioRead_Bits_32_53
@@ -86,6 +90,8 @@ cmdInfo_t cmdInfo[]=
{PI_CMD_I2CWS, "I2CWS", 121, 0}, // i2cWriteByte
{PI_CMD_I2CWW, "I2CWW", 131, 0}, // i2cWriteWordData
+ {PI_CMD_I2CX, "I2CX", 131, 0}, // i2cXfer
+
{PI_CMD_MICS, "MICS", 112, 0}, // gpioDelay
{PI_CMD_MILS, "MILS", 112, 0}, // gpioDelay
@@ -243,23 +249,23 @@ HWVER Get hardware version\n\
I2CC h Close I2C handle\n\
I2CO ib id if Open I2C bus and device with flags\n\
\n\
-I2CPC h r wv smb Process Call: exchange register with word\n\
-I2CPK h r bvs smb Block Process Call: exchange data bytes with register\n\
+I2CPC h r wv SMBus Process Call: exchange register with word\n\
+I2CPK h r bvs SMBus Block Process Call: exchange data bytes with register\n\
\n\
-I2CRB h r smb Read Byte Data: read byte from register\n\
+I2CRB h r SMBus Read Byte Data: read byte from register\n\
I2CRD h num i2c Read bytes\n\
-I2CRI h r num smb Read I2C Block Data: read bytes from register\n\
-I2CRK h r smb Read Block Data: read data from register\n\
-I2CRS h smb Read Byte: read byte\n\
-I2CRW h r smb Read Word Data: read word from register\n\
+I2CRI h r num SMBus Read I2C Block Data: read bytes from register\n\
+I2CRK h r SMBus Read Block Data: read data from register\n\
+I2CRS h SMBus Read Byte: read byte\n\
+I2CRW h r SMBus Read Word Data: read word from register\n\
\n\
-I2CWB h r bv smb Write Byte Data: write byte to register\n\
+I2CWB h r bv SMBus Write Byte Data: write byte to register\n\
I2CWD h bvs i2c Write data\n\
-I2CWI h r bvs smb Write I2C Block Data\n\
-I2CWK h r bvs smb Write Block Data: write data to register\n\
-I2CWQ h bit smb Write Quick: write bit\n\
-I2CWS h bv smb Write Byte: write byte\n\
-I2CWW h r wv smb Write Word Data: write word to register\n\
+I2CWI h r bvs SMBus Write I2C Block Data\n\
+I2CWK h r bvs SMBus Write Block Data: write data to register\n\
+I2CWQ h bit SMBus Write Quick: write bit\n\
+I2CWS h bv SMBus Write Byte: write byte\n\
+I2CWW h r wv SMBus Write Word Data: write word to register\n\
\n\
M/MODES g m Set gpio mode\n\
MG/MODEG g Get gpio mode\n\
@@ -428,7 +434,7 @@ static errInfo_t errInfo[]=
{PI_BAD_WAVE_BAUD , "baud rate not 50-250K(RX)/50-1M(TX)"},
{PI_TOO_MANY_PULSES , "waveform has too many pulses"},
{PI_TOO_MANY_CHARS , "waveform has too many chars"},
- {PI_NOT_SERIAL_GPIO , "no serial read in progress on gpio"},
+ {PI_NOT_SERIAL_GPIO , "no bit bang serial read in progress on gpio"},
{PI_BAD_SERIAL_STRUC , "bad (null) serial structure parameter"},
{PI_BAD_SERIAL_BUF , "bad (null) serial buf parameter"},
{PI_NOT_PERMITTED , "no permission to update gpio"},
@@ -496,6 +502,8 @@ static errInfo_t errInfo[]=
{PI_BAD_MALLOC_MODE , "bad memory allocation mode"},
{PI_TOO_MANY_PARTS , "too many I2C transaction parts"},
{PI_BAD_I2C_PART , "a combined I2C transaction failed"},
+ {PI_BAD_SMBUS_CMD , "SMBus command not supported by driver"},
+ {PI_NOT_I2C_GPIO , "no bit bang I2C in progress on gpio"},
};
@@ -616,7 +624,7 @@ int cmdParse(
break;
- case 112: /* GDC GPW I2CC
+ case 112: /* BI2CC GDC GPW I2CC
I2CRB MG MICS MILS MODEG NC NP PFG PRG
PROCD PROCP PROCS PRRG R READ SLRC SPIC
WVDEL WVSC WVSM WVSP WVTX WVTXR
@@ -787,7 +795,8 @@ int cmdParse(
break;
- case 131: /* HP I2CO I2CPC I2CRI I2CWB I2CWW SLRO SPIO TRIG
+ case 131: /* BI2CO HP I2CO I2CPC I2CRI I2CWB I2CWW SLRO
+ SPIO TRIG
Three positive parameters.
*/
@@ -884,7 +893,7 @@ int cmdParse(
break;
- case 193: /* I2CWD SERW
+ case 193: /* BI2CX I2CWD SERW SPIW SPIX
Two or more parameters, first >=0, rest 0-255.
*/
diff --git a/pigpio.3 b/pigpio.3
index 08c5dd9..38180c5 100644
--- a/pigpio.3
+++ b/pigpio.3
@@ -2065,7 +2065,7 @@ PI_BAD_FLAGS, PI_NO_HANDLE, or PI_I2C_OPEN_FAILED.
.br
.br
-For the smbus commands the low level transactions are shown at the end
+For the SMBus commands the low level transactions are shown at the end
of the function description. The following abbreviations are used.
.br
@@ -2191,7 +2191,7 @@ PI_I2C_WRITE_FAILED.
.br
.br
-Quick command. smbus 2.0 5.5.1
+Quick command. SMBus 2.0 5.5.1
.EX
S Addr Rd/Wr [A] P
@@ -2224,7 +2224,7 @@ PI_I2C_WRITE_FAILED.
.br
.br
-Send byte. smbus 2.0 5.5.2
+Send byte. SMBus 2.0 5.5.2
.EX
S Addr Wr [A] Data [A] P
@@ -2255,7 +2255,7 @@ or PI_I2C_READ_FAILED.
.br
.br
-Receive byte. smbus 2.0 5.5.3
+Receive byte. SMBus 2.0 5.5.3
.EX
S Addr Rd [A] [Data] NA P
@@ -2291,7 +2291,7 @@ PI_I2C_WRITE_FAILED.
.br
.br
-Write byte. smbus 2.0 5.5.4
+Write byte. SMBus 2.0 5.5.4
.EX
S Addr Wr [A] Comm [A] Data [A] P
@@ -2327,7 +2327,7 @@ PI_I2C_WRITE_FAILED.
.br
.br
-Write word. smbus 2.0 5.5.4
+Write word. SMBus 2.0 5.5.4
.EX
S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P
@@ -2361,7 +2361,7 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED.
.br
.br
-Read byte. smbus 2.0 5.5.5
+Read byte. SMBus 2.0 5.5.5
.EX
S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P
@@ -2395,7 +2395,7 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED.
.br
.br
-Read word. smbus 2.0 5.5.5
+Read word. SMBus 2.0 5.5.5
.EX
S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
@@ -2431,7 +2431,7 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED.
.br
.br
-Process call. smbus 2.0 5.5.6
+Process call. SMBus 2.0 5.5.6
.EX
S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A]
@@ -2471,7 +2471,7 @@ PI_I2C_WRITE_FAILED.
.br
.br
-Block write. smbus 2.0 5.5.7
+Block write. SMBus 2.0 5.5.7
.EX
S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P
@@ -2512,7 +2512,7 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED.
.br
.br
-Block read. smbus 2.0 5.5.7
+Block read. SMBus 2.0 5.5.7
.EX
S Addr Wr [A] Comm [A]
@@ -2553,14 +2553,14 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED.
.br
.br
-The smbus 2.0 documentation states that a minimum of 1 byte may be
+The SMBus 2.0 documentation states that a minimum of 1 byte may be
sent and a minimum of 1 byte may be received. The total number of
bytes sent/received must be 32 or less.
.br
.br
-Block write-block read. smbus 2.0 5.5.8
+Block write-block read. SMBus 2.0 5.5.8
.EX
S Addr Wr [A] Comm [A] Count [A] Data [A] ...
@@ -6815,6 +6815,18 @@ A 16-bit word value.
#define PI_CMD_CF2 88
.br
+.br
+#define PI_CMD_BI2CC 89
+.br
+#define PI_CMD_BI2CO 90
+.br
+#define PI_CMD_BI2CX 91
+.br
+
+.br
+#define PI_CMD_I2CX 92
+.br
+
.br
#define PI_CMD_NOIB 99
.br
@@ -6905,7 +6917,7 @@ A 16-bit word value.
.br
#define PI_TOO_MANY_CHARS -37 // waveform has too many chars
.br
-#define PI_NOT_SERIAL_GPIO -38 // no serial read in progress on gpio
+#define PI_NOT_SERIAL_GPIO -38 // no bit bang serial read in progress on gpio
.br
#define PI_BAD_SERIAL_STRUC -39 // bad (null) serial structure parameter
.br
@@ -7043,7 +7055,15 @@ A 16-bit word value.
.br
#define PI_BAD_I2C_PART -106 // a combined I2C transaction failed
.br
-
+#define PI_BAD_SMBUS_CMD -107 // SMBus command not supported by driver
+.br
+#define PI_NOT_I2C_GPIO -108 // no bit bang I2C in progress on gpio
+.br
+#define PI_BAD_BB_WLEN -109 // bad BB write length
+.br
+#define PI_BAD_BB_RLEN -110 // bad BB read length
+.br
+#define PI_BAD_BB_CMD -111 // bad BB command
.br
.br
@@ -7092,7 +7112,7 @@ A 16-bit word value.
.br
#define PI_DEFAULT_UPDATE_MASK_R2 0xFBC7CF9C
.br
-#define PI_DEFAULT_UPDATE_MASK_R3 0x0080400FFFFFFCLL
+#define PI_DEFAULT_UPDATE_MASK_R3 0x0080480FFFFFFCLL
.br
#define PI_DEFAULT_UPDATE_MASK_COMPUTE 0x00FFFFFFFFFFFFLL
.br
diff --git a/pigpio.c b/pigpio.c
index 920cb2f..b0fcaae 100644
--- a/pigpio.c
+++ b/pigpio.c
@@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to
*/
-/* pigpio version 31 */
+/* pigpio version 32 */
/* include ------------------------------------------------------- */
@@ -204,6 +204,7 @@ bit 0 READ_LAST_NOT_SET_ERROR
}
#define CHECK_INITED \
+ do \
{ \
if (!libInitialised) \
{ \
@@ -212,8 +213,10 @@ bit 0 READ_LAST_NOT_SET_ERROR
return PI_NOT_INITIALISED; \
} \
} \
+ while (0)
#define CHECK_INITED_RET_NULL_PTR \
+ do \
{ \
if (!libInitialised) \
{ \
@@ -222,8 +225,10 @@ bit 0 READ_LAST_NOT_SET_ERROR
return (NULL); \
} \
} \
+ while (0)
#define CHECK_INITED_RET_NIL \
+ do \
{ \
if (!libInitialised) \
{ \
@@ -231,8 +236,10 @@ bit 0 READ_LAST_NOT_SET_ERROR
"pigpio uninitialised, call gpioInitialise()"); \
} \
} \
+ while (0)
#define CHECK_NOT_INITED \
+ do \
{ \
if (libInitialised) \
{ \
@@ -241,14 +248,18 @@ bit 0 READ_LAST_NOT_SET_ERROR
return PI_INITIALISED; \
} \
} \
+ while (0)
#define SOFT_ERROR(x, format, arg...) \
+ do \
{ \
DBG(DBG_ALWAYS, format, ## arg); \
return x; \
} \
+ while (0)
#define TIMER_ADD(a, b, result) \
+ do \
{ \
(result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
(result)->tv_nsec = (a)->tv_nsec + (b)->tv_nsec; \
@@ -258,8 +269,10 @@ bit 0 READ_LAST_NOT_SET_ERROR
(result)->tv_nsec -= BILLION; \
} \
} \
+ while (0)
#define TIMER_SUB(a, b, result) \
+ do \
{ \
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
(result)->tv_nsec = (a)->tv_nsec - (b)->tv_nsec; \
@@ -269,6 +282,7 @@ bit 0 READ_LAST_NOT_SET_ERROR
(result)->tv_nsec += BILLION; \
} \
} \
+ while (0)
#define PI_PERI_BUS 0x7E000000
@@ -688,8 +702,11 @@ bit 0 READ_LAST_NOT_SET_ERROR
#define PI_NOTIFY_RUNNING 3
#define PI_NOTIFY_PAUSED 4
-#define PI_WFRX_NONE 0
-#define PI_WFRX_SERIAL 1
+#define PI_WFRX_NONE 0
+#define PI_WFRX_SERIAL 1
+#define PI_WFRX_I2C 2
+#define PI_WFRX_I2C_CLK 3
+
#define PI_WF_MICROS 1
#define DATUMS 2000
@@ -700,9 +717,12 @@ bit 0 READ_LAST_NOT_SET_ERROR
#define SRX_BUF_SIZE 8192
-#define PI_I2C_SLAVE 0x0703
-#define PI_I2C_RDWR 0x0707
-#define PI_I2C_SMBUS 0x0720
+#define PI_I2C_RETRIES 0x0701
+#define PI_I2C_TIMEOUT 0x0702
+#define PI_I2C_SLAVE 0x0703
+#define PI_I2C_FUNCS 0x0705
+#define PI_I2C_RDWR 0x0707
+#define PI_I2C_SMBUS 0x0720
#define PI_I2C_SMBUS_READ 1
#define PI_I2C_SMBUS_WRITE 0
@@ -720,6 +740,19 @@ bit 0 READ_LAST_NOT_SET_ERROR
#define PI_I2C_SMBUS_BLOCK_MAX 32
#define PI_I2C_SMBUS_I2C_BLOCK_MAX 32
+#define PI_I2C_FUNC_SMBUS_QUICK 0x00010000
+#define PI_I2C_FUNC_SMBUS_READ_BYTE 0x00020000
+#define PI_I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000
+#define PI_I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000
+#define PI_I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000
+#define PI_I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000
+#define PI_I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000
+#define PI_I2C_FUNC_SMBUS_PROC_CALL 0x00800000
+#define PI_I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000
+#define PI_I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
+#define PI_I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000
+#define PI_I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000
+
#define PI_MASH_MAX_FREQ 23800000
#define FLUSH_PAGES 1024
@@ -764,6 +797,10 @@ bit 0 READ_LAST_NOT_SET_ERROR
#define PI_SPI_FLAGS_GET_CSPOLS(x) (((x)>>2)&7)
#define PI_SPI_FLAGS_GET_MODE(x) ((x)&3)
+#define PI_STARTING 0
+#define PI_RUNNING 1
+#define PI_ENDING 2
+
/* typedef ------------------------------------------------------- */
typedef void (*callbk_t) ();
@@ -862,6 +899,7 @@ typedef struct
uint16_t seqno;
uint16_t state;
uint32_t bits;
+ uint32_t lastReportTick;
int fd;
int pipe;
} gpioNotify_t;
@@ -871,6 +909,7 @@ typedef struct
uint16_t state;
int16_t fd;
uint32_t flags;
+ uint32_t funcs;
} i2cInfo_t;
typedef struct
@@ -931,12 +970,10 @@ typedef struct
typedef struct
{
- int gpio;
char *buf;
uint32_t bufSize;
int readPos;
int writePos;
- uint32_t baud; /* 50-250000 */
uint32_t fullBit; /* nanoseconds */
uint32_t halfBit; /* nanoseconds */
int timeout; /* millisconds */
@@ -946,8 +983,29 @@ typedef struct
uint32_t data;
int bytes; /* 1, 2, 4 */
int level;
- int mode;
int dataBits; /* 1-32 */
+} wfRxSerial_t;
+
+typedef struct
+{
+ int SDA;
+ int SCL;
+ int delay;
+ int SDAMode;
+ int SCLMode;
+ int started;
+} wfRxI2C_t;
+
+typedef struct
+{
+ int mode;
+ int gpio;
+ uint32_t baud; /* 50-250000 */
+ union
+ {
+ wfRxSerial_t s;
+ wfRxI2C_t I;
+ };
} wfRx_t;
union my_smbus_data
@@ -1038,8 +1096,7 @@ static volatile uint32_t monitorBits = 0;
static volatile uint32_t notifyBits = 0;
static volatile uint32_t scriptBits = 0;
-static volatile int DMAstarted = 0;
-static volatile int terminating = 0;
+static volatile int runState = PI_STARTING;
static int pthAlertRunning = 0;
static int pthFifoRunning = 0;
@@ -1278,11 +1335,33 @@ static char * myTimeStamp()
/* ----------------------------------------------------------------------- */
+static char *myBuf2Str(unsigned count, char *buf)
+{
+ static char str[128];
+ int i, c;
+
+ if (count && buf)
+ {
+ if (count > 40) c = 40; else c = count;
+
+ for (i=0; ibyte+1, (char*)data));
+
args.read_write = rw;
args.command = cmd;
args.size = size;
@@ -1293,23 +1372,18 @@ static int my_smbus_access(
/* ----------------------------------------------------------------------- */
-static char *myBuf2Str(unsigned count, char *buf)
+static void myGpioSetMode(unsigned gpio, unsigned mode)
{
- static char str[64];
- int i, c;
+ int reg, shift;
- if (count)
- {
- if (count > 10) c = 10; else c = count;
+ reg = gpio/10;
+ shift = (gpio%10) * 3;
- for (i=0; i (bufSize/2)) p[3] = bufSize/2;
+ res = bbI2CXfer(p[1], buf, p[3], buf+(bufSize/2), bufSize/2);
+ if (res > 0)
+ {
+ memcpy(buf, buf+(bufSize/2), res);
+ }
+ break;
+
case PI_CMD_BR1: res = gpioRead_Bits_0_31(); break;
case PI_CMD_BR2: res = gpioRead_Bits_32_53(); break;
@@ -2164,7 +2255,7 @@ static unsigned mbAllocateMemory(
p[i++] = align;
p[i++] = flags;
p[i++] = MB_END_TAG;
- p[0] = i*sizeof *p;
+ p[0] = i*sizeof(*p);
mbProperty(fd, p);
@@ -2182,7 +2273,7 @@ static unsigned mbLockMemory(int fd, unsigned handle)
p[i++] = 4;
p[i++] = handle;
p[i++] = MB_END_TAG;
- p[0] = i*sizeof *p;
+ p[0] = i*sizeof(*p);
mbProperty(fd, p);
@@ -2200,7 +2291,7 @@ static unsigned mbUnlockMemory(int fd, unsigned handle)
p[i++] = 4;
p[i++] = handle;
p[i++] = MB_END_TAG;
- p[0] = i*sizeof *p;
+ p[0] = i*sizeof(*p);
mbProperty(fd, p);
@@ -2218,7 +2309,7 @@ static unsigned mbReleaseMemory(int fd, unsigned handle)
p[i++] = 4;
p[i++] = handle;
p[i++] = MB_END_TAG;
- p[0] = i*sizeof *p;
+ p[0] = i*sizeof(*p);
mbProperty(fd, p);
@@ -2608,56 +2699,57 @@ static int wave2Cbs(unsigned wave_mode)
/* ----------------------------------------------------------------------- */
-static void waveRxSerial(wfRx_t *s, int level, uint32_t tick)
+static void waveRxSerial(wfRx_t *w, int level, uint32_t tick)
{
int diffTicks, lastLevel;
int newWritePos;
- if (s->bit >= 0)
+ if (w->s.bit >= 0)
{
- diffTicks = tick - s->startBitTick;
+ diffTicks = tick - w->s.startBitTick;
if (level != PI_TIMEOUT)
{
- s->level = level;
+ w->s.level = level;
lastLevel = !level;
}
- else lastLevel = s->level;
+ else lastLevel = w->s.level;
- while ((s->bit <= s->dataBits) && (diffTicks > (s->nextBitDiff/1000)))
+ while ((w->s.bit <= w->s.dataBits) &&
+ (diffTicks > (w->s.nextBitDiff/1000)))
{
- if (s->bit)
+ if (w->s.bit)
{
- if (lastLevel) s->data |= (1<<(s->bit-1));
+ if (lastLevel) w->s.data |= (1<<(w->s.bit-1));
}
- else s->data = 0;
+ else w->s.data = 0;
- ++(s->bit);
+ ++(w->s.bit);
- s->nextBitDiff += s->fullBit;
+ w->s.nextBitDiff += w->s.fullBit;
}
- if (s->bit > s->dataBits)
+ if (w->s.bit > w->s.dataBits)
{
- memcpy(s->buf + s->writePos, &s->data, s->bytes);
+ memcpy(w->s.buf + w->s.writePos, &w->s.data, w->s.bytes);
/* don't let writePos catch readPos */
- newWritePos = (s->writePos + s->bytes) % (s->bufSize);
+ newWritePos = (w->s.writePos + w->s.bytes) % (w->s.bufSize);
- if (newWritePos != s->readPos) s->writePos = newWritePos;
+ if (newWritePos != w->s.readPos) w->s.writePos = newWritePos;
if (level == 0)
{
- gpioSetWatchdog(s->gpio, s->timeout);
- s->bit = 0;
- s->startBitTick = tick;
- s->nextBitDiff = s->halfBit;
+ gpioSetWatchdog(w->gpio, w->s.timeout);
+ w->s.bit = 0;
+ w->s.startBitTick = tick;
+ w->s.nextBitDiff = w->s.halfBit;
}
else
{
- s->bit = -1;
- gpioSetWatchdog(s->gpio, 0);
+ w->s.bit = -1;
+ gpioSetWatchdog(w->gpio, 0);
}
}
}
@@ -2667,11 +2759,11 @@ static void waveRxSerial(wfRx_t *s, int level, uint32_t tick)
if (level == 0)
{
- gpioSetWatchdog(s->gpio, s->timeout);
- s->level = 0;
- s->bit = 0;
- s->startBitTick = tick;
- s->nextBitDiff = s->halfBit;
+ gpioSetWatchdog(w->gpio, w->s.timeout);
+ w->s.level = 0;
+ w->s.bit = 0;
+ w->s.startBitTick = tick;
+ w->s.nextBitDiff = w->s.halfBit;
}
}
}
@@ -2683,9 +2775,6 @@ static void waveRxBit(int gpio, int level, uint32_t tick)
{
switch (wfRx[gpio].mode)
{
- case PI_WFRX_NONE:
- break;
-
case PI_WFRX_SERIAL:
waveRxSerial(&wfRx[gpio], level, tick);
}
@@ -2846,6 +2935,9 @@ int i2cWriteQuick(unsigned handle, unsigned bit)
if (i2cInfo[handle].state == PI_I2C_CLOSED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
+ if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_QUICK) == 0)
+ SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
+
if (bit > 1)
SOFT_ERROR(PI_BAD_PARAM, "bad bit (%d)", bit);
@@ -2871,6 +2963,9 @@ int i2cReadByte(unsigned handle)
if (i2cInfo[handle].state == PI_I2C_CLOSED)
SOFT_ERROR(PI_BAD_HANDLE, "bad 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))
return PI_I2C_READ_FAILED;
@@ -2893,6 +2988,9 @@ int i2cWriteByte(unsigned handle, unsigned bVal)
if (i2cInfo[handle].state == PI_I2C_CLOSED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
+ if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_BYTE) == 0)
+ SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
+
if (bVal > 0xFF)
SOFT_ERROR(PI_BAD_PARAM, "bad bVal (%d)", bVal);
@@ -2923,6 +3021,9 @@ int i2cReadByteData(unsigned handle, unsigned reg)
if (i2cInfo[handle].state == PI_I2C_CLOSED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
+ if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_BYTE_DATA) == 0)
+ SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
+
if (reg > 0xFF)
SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg);
@@ -2950,6 +3051,9 @@ int i2cWriteByteData(unsigned handle, unsigned reg, unsigned bVal)
if (i2cInfo[handle].state == PI_I2C_CLOSED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
+ if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_BYTE_DATA) == 0)
+ SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
+
if (reg > 0xFF)
SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg);
@@ -2985,11 +3089,18 @@ int i2cReadWordData(unsigned handle, unsigned reg)
if (i2cInfo[handle].state == PI_I2C_CLOSED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
+ if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_WORD_DATA) == 0)
+ SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
+
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_WORD_DATA, &data))
+ i2cInfo[handle].fd,
+ PI_I2C_SMBUS_READ,
+ reg,
+ PI_I2C_SMBUS_WORD_DATA,
+ &data))
return PI_I2C_READ_FAILED;
else
return 0xFFFF & data.word;
@@ -3012,6 +3123,9 @@ int i2cWriteWordData(unsigned handle, unsigned reg, unsigned wVal)
if (i2cInfo[handle].state == PI_I2C_CLOSED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
+ if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_WORD_DATA) == 0)
+ SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
+
if (reg > 0xFF)
SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg);
@@ -3047,6 +3161,9 @@ int i2cProcessCall(unsigned handle, unsigned reg, unsigned wVal)
if (i2cInfo[handle].state == PI_I2C_CLOSED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
+ if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_PROC_CALL) == 0)
+ SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
+
if (reg > 0xFF)
SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg);
@@ -3056,7 +3173,10 @@ int i2cProcessCall(unsigned handle, unsigned reg, unsigned wVal)
data.word = wVal;
if (my_smbus_access(
- i2cInfo[handle].fd, PI_I2C_SMBUS_WRITE, reg, PI_I2C_SMBUS_PROC_CALL, &data))
+ i2cInfo[handle].fd,
+ PI_I2C_SMBUS_WRITE,
+ reg, PI_I2C_SMBUS_PROC_CALL,
+ &data))
return PI_I2C_READ_FAILED;
else
return 0xFFFF & data.word;
@@ -3079,11 +3199,18 @@ int i2cReadBlockData(unsigned handle, unsigned reg, char *buf)
if (i2cInfo[handle].state == PI_I2C_CLOSED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
+ if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_BLOCK_DATA) == 0)
+ SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
+
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_BLOCK_DATA, &data))
+ i2cInfo[handle].fd,
+ PI_I2C_SMBUS_READ,
+ reg,
+ PI_I2C_SMBUS_BLOCK_DATA,
+ &data))
return PI_I2C_READ_FAILED;
else
{
@@ -3115,6 +3242,9 @@ int i2cWriteBlockData(
if (i2cInfo[handle].state == PI_I2C_CLOSED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
+ if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) == 0)
+ SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
+
if (reg > 0xFF)
SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg);
@@ -3155,6 +3285,9 @@ int i2cBlockProcessCall(
if (i2cInfo[handle].state == PI_I2C_CLOSED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
+ if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_PROC_CALL) == 0)
+ SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
+
if (reg > 0xFF)
SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg);
@@ -3198,6 +3331,9 @@ int i2cReadI2CBlockData(
if (i2cInfo[handle].state == PI_I2C_CLOSED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
+ if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_I2C_BLOCK) == 0)
+ SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
+
if (reg > 0xFF)
SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg);
@@ -3243,6 +3379,9 @@ int i2cWriteI2CBlockData(
if (i2cInfo[handle].state == PI_I2C_CLOSED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
+ if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) == 0)
+ SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
+
if (reg > 0xFF)
SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg);
@@ -3321,6 +3460,7 @@ int i2cOpen(unsigned i2cBus, unsigned i2cAddr, unsigned i2cFlags)
{
char dev[32];
int i, slot, fd;
+ uint32_t funcs;
DBG(DBG_USER, "i2cBus=%d i2cAddr=%d flags=0x%X",
i2cBus, i2cAddr, i2cFlags);
@@ -3330,8 +3470,8 @@ int i2cOpen(unsigned i2cBus, unsigned i2cAddr, unsigned i2cFlags)
if (i2cBus >= PI_NUM_I2C_BUS)
SOFT_ERROR(PI_BAD_I2C_BUS, "bad I2C bus (%d)", i2cBus);
- if ((i2cAddr < 0x08) || (i2cAddr > 0x77))
- SOFT_ERROR(PI_BAD_I2C_ADDR, "bad I2C address (0x%X)", i2cAddr);
+// if ((i2cAddr < 0x08) || (i2cAddr > 0x77))
+// SOFT_ERROR(PI_BAD_I2C_ADDR, "bad I2C address (0x%X)", i2cAddr);
if (i2cFlags)
SOFT_ERROR(PI_BAD_FLAGS, "bad flags (0x%X)", i2cFlags);
@@ -3376,8 +3516,14 @@ int i2cOpen(unsigned i2cBus, unsigned i2cAddr, unsigned i2cFlags)
return PI_I2C_OPEN_FAILED;
}
+ if (ioctl(fd, PI_I2C_FUNCS, &funcs) < 0)
+ {
+ funcs = -1; /* assume all smbus commands allowed */
+ }
+
i2cInfo[slot].fd = fd;
i2cInfo[slot].flags = i2cFlags;
+ i2cInfo[slot].funcs = funcs;
return slot;
}
@@ -3404,7 +3550,7 @@ int i2cClose(unsigned handle)
int i2cTransaction(unsigned handle, pi_i2c_msg_t *parts, unsigned numParts)
{
- int retval, fd;
+ int retval;
my_i2c_rdwr_ioctl_data_t rdwr;
DBG(DBG_USER, "handle=%d", handle);
@@ -3423,14 +3569,6 @@ int i2cTransaction(unsigned handle, pi_i2c_msg_t *parts, unsigned numParts)
if (numParts > PI_I2C_RDRW_IOCTL_MAX_MSGS)
SOFT_ERROR(PI_TOO_MANY_PARTS, "too many parts (%d)", numParts);
- fd = open(PI_I2C_COMBINED, O_RDWR);
-
- if (fd >= 0)
- {
- write(fd, "1", 1);
- close(fd);
- }
-
rdwr.msgs = parts;
rdwr.nmsgs = numParts;
@@ -3442,6 +3580,129 @@ int i2cTransaction(unsigned handle, pi_i2c_msg_t *parts, unsigned numParts)
else return PI_BAD_I2C_PART;
}
+#ifdef ZZZZ
+
+int i2cXfer(
+ unsigned handle,
+ char *inBuf, unsigned inLen, char *outBuf, unsigned outLen)
+{
+ int i, parts, inPos, outPos, status, bytes, len_bytes,flags, addr;
+ pi_i2c_msg_t part[PI_I2C_RDRW_IOCTL_MAX_MSGS];
+
+ DBG(DBG_USER, "handle=%d inBuf=%s outBuf=%08X len=%d",
+ handle, myBuf2Str(inLen, (char *)inBuf), (int)outBuf, outLen);
+
+ CHECK_INITED;
+
+ if (handle >= PI_I2C_SLOTS)
+ SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
+
+ if (i2cInfo[handle].state != PI_I2C_OPENED)
+ SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
+
+ if (!inBuf || !inLen)
+ SOFT_ERROR(PI_BAD_POINTER, "input buffer can't be NULL");
+
+ if (!outBuf && outLen)
+ SOFT_ERROR(PI_BAD_POINTER, "output buffer can't be NULL");
+
+ parts = 0;
+ inPos = 0;
+ outPos = 0;
+ status = 0;
+ flags = 0;
+ addr = 0;
+
+ while (!status && (inPos < inLen) && (parts < PI_I2C_RDRW_IOCTL_MAX_MSGS))
+ {
+ DBG(DBG_INTERNAL, "status=%d inpos=%d inlen=%d cmd=%d",
+ status, inPos, inLen, inBuf[inPos]);
+
+ len_bytes = 1;
+
+ switch (inBuf[inPos++])
+ {
+ case PI_I2C_END:
+ status = 1;
+ break;
+
+ case PI_I2C_READ16:
+ len_bytes = 2;
+ /* fall through */
+
+ case PI_I2C_READ:
+ if (inPos <= (inLen - len_bytes))
+ {
+ if (len_bytes != 1)
+ {
+ bytes=inBuf[inPos] + (inBuf[inPos+1]<<8);
+ inPos += 2;
+ }
+ else
+ {
+ bytes=inBuf[inPos++];
+ }
+
+ if (bytes && ((bytes + outPos) < outLen))
+ {
+ part[parts].addr = addr;
+ part[parts].flags = flags;
+ part[parts].len =
+ part[parts].buf =
+
+ for (i=0; i<(bytes-1); i++)
+ {
+ outBuf[outPos++] = I2CGetByte(w, 0);
+ }
+ outBuf[outPos++] = I2CGetByte(w, 1);
+ }
+ else status = PI_BAD_BB_WLEN;
+ }
+ else status = PI_BAD_BB_WLEN;
+ break;
+
+ case PI_I2C_WRITE16:
+ len_bytes = 2;
+ /* fall through */
+
+ case PI_I2C_WRITE:
+ if (inPos <= (inLen - len_bytes))
+ {
+ if (len_bytes != 1)
+ {
+ bytes=inBuf[inPos] + (inBuf[inPos+1]<<8);
+ inPos += 2;
+ }
+ else
+ {
+ bytes=inBuf[inPos++];
+ }
+
+ if (bytes && ((bytes + inPos) < inLen))
+ {
+ for (i=0; i<(bytes-1); i++)
+ {
+ ack = I2CPutByte(w, inBuf[inPos++]);
+ if (ack) status = PI_I2C_WRITE_FAILED;
+ }
+ ack = I2CPutByte(w, inBuf[inPos++]);
+ //if (ack) status = PI_I2C_WRITE_FAILED;
+ }
+ else status = PI_BAD_BB_RLEN;
+ }
+ else status = PI_BAD_BB_RLEN;
+ break;
+
+ default:
+ status = PI_BAD_BB_CMD;
+ }
+ }
+
+ if (status >= 0) status = outPos;
+
+ return status;
+}
+#endif
/* ======================================================================= */
@@ -4682,7 +4943,7 @@ static void * pthAlertThread(void *x)
/* don't start until DMA started */
- waitForDMAstarted();
+ spinWhileStarting();
reportedLevel = gpioReg[GPLEV0];
@@ -4714,7 +4975,7 @@ static void * pthAlertThread(void *x)
myGpioDelay(5000);
- if (DMAstarted)
+ if (runState == PI_RUNNING)
{
/* should never be executed, leave code just in case */
@@ -4897,11 +5158,13 @@ static void * pthAlertThread(void *x)
{
if (gpioAlert[b].ex)
{
- (gpioAlert[b].func)(b, 2, tick, gpioAlert[b].userdata);
+ (gpioAlert[b].func)
+ (b, PI_TIMEOUT, tick, gpioAlert[b].userdata);
}
else
{
- (gpioAlert[b].func)(b, 2, tick);
+ (gpioAlert[b].func)
+ (b, PI_TIMEOUT, tick);
}
}
}
@@ -4985,7 +5248,7 @@ static void * pthAlertThread(void *x)
gpioReport[emit].seqno = seqno;
gpioReport[emit].flags = PI_NTFY_FLAGS_WDOG |
- PI_NTFY_FLAGS_BIT(b);
+ PI_NTFY_FLAGS_BIT(b);
gpioReport[emit].tick = tick;
gpioReport[emit].level = newLevel;
@@ -4995,8 +5258,29 @@ static void * pthAlertThread(void *x)
}
}
+ if (!emit)
+ {
+ if ((tick - gpioNotify[n].lastReportTick) > 60000000)
+ {
+ if (numSamples)
+ newLevel = gpioSample[numSamples-1].level;
+ else
+ newLevel = reportedLevel;
+
+ gpioReport[emit].seqno = seqno;
+ gpioReport[emit].flags = PI_NTFY_FLAGS_ALIVE;
+ gpioReport[emit].tick = tick;
+ gpioReport[emit].level = newLevel;
+
+ emit++;
+ seqno++;
+ }
+ }
+
if (emit)
{
+ gpioNotify[n].lastReportTick = tick;
+
if (emit > gpioStats.maxEmit) gpioStats.maxEmit = emit;
emitted = 0;
@@ -5496,7 +5780,7 @@ static void * pthFifoThread(void *x)
/* don't start until DMA started */
- waitForDMAstarted();
+ spinWhileStarting();
while (1)
{
@@ -5665,6 +5949,7 @@ static void *pthSocketThreadHandler(void *fdC)
{
/* extensions */
+ case PI_CMD_BI2CX:
case PI_CMD_CF2:
case PI_CMD_I2CPK:
case PI_CMD_I2CRD:
@@ -5721,7 +6006,7 @@ static void * pthSocketThread(void *x)
/* don't start until DMA started */
- waitForDMAstarted();
+ spinWhileStarting();
while ((fdC =
accept(fdSock, (struct sockaddr *)&client, (socklen_t*)&c)))
@@ -5794,7 +6079,7 @@ static int initCheckPermitted(void)
if ((fdMem = open("/dev/mem", O_RDWR | O_SYNC) ) < 0)
{
- DBG(DBG_STARTUP,
+ DBG(DBG_ALWAYS,
"\n" \
"+---------------------------------------------------------+\n" \
"|Sorry, you don't have permission to run this program. |\n" \
@@ -6375,10 +6660,6 @@ static void initClearGlobals(void)
notifyBits = 0;
scriptBits = 0;
- libInitialised = 0;
- DMAstarted = 0;
- terminating = 0;
-
pthAlertRunning = 0;
pthFifoRunning = 0;
pthSocketRunning = 0;
@@ -6642,8 +6923,6 @@ int initInitialise(void)
DBG(DBG_STARTUP, "");
- if (libInitialised) return PIGPIO_VERSION;
-
waveClockInited = 0;
clock_gettime(CLOCK_REALTIME, &libStarted);
@@ -6692,8 +6971,6 @@ int initInitialise(void)
initClock(1); /* initialise main clock */
- libInitialised = 1;
-
atexit(gpioTerminate);
if (pthread_attr_init(&pthAttr))
@@ -6749,8 +7026,6 @@ int initInitialise(void)
myGpioDelay(20000);
- DMAstarted = 1;
-
return PIGPIO_VERSION;
}
@@ -6956,12 +7231,22 @@ int gpioInitialise(void)
{
int status;
+ if (libInitialised) return PIGPIO_VERSION;
+
+ runState = PI_STARTING;
+
status = initInitialise();
if (status < 0)
{
+ runState = PI_ENDING;
initReleaseResources();
}
+ else
+ {
+ libInitialised = 1;
+ runState = PI_RUNNING;
+ }
return status;
}
@@ -6975,58 +7260,54 @@ void gpioTerminate(void)
DBG(DBG_USER, "");
- terminating = 1;
+ if (!libInitialised) return;
- if (libInitialised)
- {
- libInitialised = 0;
+ runState = PI_ENDING;
- gpioMaskSet = 0;
+ gpioMaskSet = 0;
- /* reset DMA */
+ /* reset DMA */
- DMAstarted = 0;
-
- dmaIn[DMA_CS] = DMA_CHANNEL_RESET;
- dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
+ if (dmaReg != MAP_FAILED) dmaIn[DMA_CS] = DMA_CHANNEL_RESET;
+ if (dmaReg != MAP_FAILED) dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
#ifndef EMBEDDED_IN_VM
- if (gpioCfg.showStats)
- {
- fprintf(stderr,
- "If you didn't request stats please cut & paste the\n"
- "following and e-mail to pigpio@abyz.co.uk\n");
+ if (gpioCfg.showStats)
+ {
+ fprintf(stderr,
+ "If you didn't request stats please cut & paste the\n"
+ "following and e-mail to pigpio@abyz.co.uk\n");
- fprintf(stderr,
- "#####################################################\n");
+ fprintf(stderr,
+ "micros=%d allocMode=%d dmaInitCbs=%d DMARestarts=%d\n",
+ gpioCfg.clockMicros, gpioCfg.memAllocMode,
+ gpioStats.dmaInitCbsCount, gpioStats.DMARestarts);
- fprintf(stderr,
- "micros=%d allocMode=%d dmaInitCbs=%d DMARestarts=%d\n",
- gpioCfg.clockMicros, gpioCfg.memAllocMode,
- gpioStats.dmaInitCbsCount, gpioStats.DMARestarts);
+ fprintf(stderr,
+ "samples %u maxSamples %u maxEmit %u emitFrags %u\n",
+ gpioStats.numSamples, gpioStats.maxSamples,
+ gpioStats.maxEmit, gpioStats.emitFrags);
- fprintf(stderr,
- "samples %u maxSamples %u maxEmit %u emitFrags %u\n",
- gpioStats.numSamples, gpioStats.maxSamples,
- gpioStats.maxEmit, gpioStats.emitFrags);
+ fprintf(stderr, "cbTicks %d, cbCalls %u alertTicks %u\n",
+ gpioStats.cbTicks, gpioStats.cbCalls, gpioStats.alertTicks);
- fprintf(stderr, "cbTicks %d, cbCalls %u alertTicks %u\n",
- gpioStats.cbTicks, gpioStats.cbCalls, gpioStats.alertTicks);
+ for (i=0; i< TICKSLOTS; i++)
+ fprintf(stderr, "%9u ", gpioStats.diffTick[i]);
- for (i=0; i< TICKSLOTS; i++)
- fprintf(stderr, "%9u ", gpioStats.diffTick[i]);
+ fprintf(stderr, "\n");
- fprintf(stderr, "\n");
+ fprintf(stderr, "\n");
- fprintf(stderr,
- "#####################################################\n");
- }
-#endif
+ fprintf(stderr,
+ "#####################################################\n");
}
+#endif
initReleaseResources();
fflush(NULL);
+
+ libInitialised = 0;
}
static void switchFunctionOff(unsigned gpio)
@@ -8117,6 +8398,332 @@ int gpioWaveGetMaxCbs(void)
return wfStats.maxCbs;
}
+static int read_SDA(wfRx_t *w)
+{
+ myGpioSetMode(w->I.SDA, PI_INPUT);
+ return gpioRead(w->I.SDA);
+}
+
+static void set_SDA(wfRx_t *w)
+{
+ myGpioSetMode(w->I.SDA, PI_INPUT);
+}
+
+static void clear_SDA(wfRx_t *w)
+{
+ myGpioSetMode(w->I.SDA, PI_OUTPUT);
+ myGpioWrite(w->I.SDA, 0);
+}
+
+static void clear_SCL(wfRx_t *w)
+{
+ myGpioSetMode(w->I.SCL, PI_OUTPUT);
+ myGpioWrite(w->I.SCL, 0);
+}
+
+static void I2C_delay(wfRx_t *w)
+{
+ myGpioDelay(w->I.delay);
+}
+
+static void I2C_clock_stretch(wfRx_t *w)
+{
+ uint32_t now, max_stretch=10000;
+
+ myGpioSetMode(w->I.SCL, PI_INPUT);
+ now = gpioTick();
+ while ((gpioRead(w->I.SCL) == 0) && ((gpioTick()-now) < max_stretch));
+}
+
+static void I2CStart(wfRx_t *w)
+{
+ if (w->I.started)
+ {
+ set_SDA(w);
+ I2C_delay(w);
+ I2C_clock_stretch(w);
+ I2C_delay(w);
+ }
+
+ clear_SDA(w);
+ I2C_delay(w);
+ clear_SCL(w);
+ I2C_delay(w);
+
+ w->I.started = 1;
+}
+
+static void I2CStop(wfRx_t *w)
+{
+ clear_SDA(w);
+ I2C_delay(w);
+ I2C_clock_stretch(w);
+ I2C_delay(w);
+ set_SDA(w);
+ I2C_delay(w);
+
+ w->I.started = 0;
+}
+
+static void I2CPutBit(wfRx_t *w, int bit)
+{
+ if (bit) set_SDA(w);
+ else clear_SDA(w);
+
+ I2C_delay(w);
+ I2C_clock_stretch(w);
+ I2C_delay(w);
+ clear_SCL(w);
+}
+
+static int I2CGetBit(wfRx_t *w)
+{
+ int bit;
+
+ set_SDA(w); /* let SDA float */
+ I2C_delay(w);
+ I2C_clock_stretch(w);
+ bit = read_SDA(w);
+ I2C_delay(w);
+ clear_SCL(w);
+
+ return bit;
+}
+
+static int I2CPutByte(wfRx_t *w, int byte)
+{
+ int bit, nack;
+
+ for(bit=0; bit<8; bit++)
+ {
+ I2CPutBit(w, byte & 0x80);
+ byte <<= 1;
+ }
+
+ nack = I2CGetBit(w);
+
+ return nack;
+}
+
+static uint8_t I2CGetByte(wfRx_t *w, int nack)
+{
+ int bit, byte=0;
+
+ for (bit=0; bit<8; bit++)
+ {
+ byte = (byte << 1) | I2CGetBit(w);
+ }
+
+ I2CPutBit(w, nack);
+
+ return byte;
+}
+
+int bbI2COpen(unsigned SDA, unsigned SCL, unsigned bbBaud)
+{
+ DBG(DBG_USER, "SDA=%d SCL=%d bbBaud=%d", SDA, SCL, bbBaud);
+
+ CHECK_INITED;
+
+ if (SDA > PI_MAX_USER_GPIO)
+ SOFT_ERROR(PI_BAD_USER_GPIO, "bad SDA (%d)", SDA);
+
+ if (SCL > PI_MAX_USER_GPIO)
+ SOFT_ERROR(PI_BAD_USER_GPIO, "bad SCL (%d)", SCL);
+
+ if ((bbBaud < PI_BB_MIN_BAUD) || (bbBaud > PI_BB_RX_MAX_BAUD))
+ SOFT_ERROR(PI_BAD_WAVE_BAUD,
+ "SDA %d, bad baud rate (%d)", SDA, bbBaud);
+
+ if (wfRx[SDA].mode != PI_WFRX_NONE)
+ SOFT_ERROR(PI_GPIO_IN_USE, "gpio %d is already being used", SDA);
+
+ if (wfRx[SCL].mode != PI_WFRX_NONE)
+ SOFT_ERROR(PI_GPIO_IN_USE, "gpio %d is already being used", SCL);
+
+ wfRx[SDA].gpio = SDA;
+ wfRx[SDA].mode = PI_WFRX_I2C;
+ wfRx[SDA].baud = bbBaud;
+
+ wfRx[SDA].I.started = 0;
+ wfRx[SDA].I.SDA = SDA;
+ wfRx[SDA].I.SCL = SCL;
+ wfRx[SDA].I.delay = 500000 / bbBaud;
+ wfRx[SDA].I.SDAMode = gpioGetMode(SDA);
+ wfRx[SDA].I.SCLMode = gpioGetMode(SCL);
+
+ wfRx[SCL].gpio = SCL;
+ wfRx[SCL].mode = PI_WFRX_I2C_CLK;
+
+ myGpioSetMode(SDA, PI_INPUT);
+ myGpioSetMode(SCL, PI_INPUT);
+
+ return 0;
+}
+
+
+/* ----------------------------------------------------------------------- */
+
+
+int bbI2CClose(unsigned SDA)
+{
+ DBG(DBG_USER, "SDA=%d", SDA);
+
+ CHECK_INITED;
+
+ if (SDA > PI_MAX_USER_GPIO)
+ SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", SDA);
+
+ switch(wfRx[SDA].mode)
+ {
+ case PI_WFRX_I2C:
+
+ gpioSetMode(wfRx[SDA].I.SDA, wfRx[SDA].I.SDAMode);
+ gpioSetMode(wfRx[SDA].I.SCL, wfRx[SDA].I.SCLMode);
+
+ wfRx[wfRx[SDA].I.SDA].mode = PI_WFRX_NONE;
+ wfRx[wfRx[SDA].I.SCL].mode = PI_WFRX_NONE;
+
+ break;
+
+ default:
+
+ SOFT_ERROR(PI_NOT_I2C_GPIO, "no I2C on gpio (%d)", SDA);
+
+ break;
+
+ }
+
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+int bbI2CXfer(
+ unsigned SDA,
+ char *inBuf, unsigned inLen, char *outBuf, unsigned outLen)
+{
+ int i, ack, inPos, outPos, status, bytes, len_bytes;
+ wfRx_t *w;
+
+ DBG(DBG_USER, "gpio=%d inBuf=%s outBuf=%08X len=%d",
+ SDA, myBuf2Str(inLen, (char *)inBuf), (int)outBuf, outLen);
+
+ CHECK_INITED;
+
+ if (SDA > PI_MAX_USER_GPIO)
+ SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", SDA);
+
+ if (wfRx[SDA].mode != PI_WFRX_I2C)
+ SOFT_ERROR(PI_NOT_I2C_GPIO, "no I2C on gpio (%d)", SDA);
+
+ if (!inBuf || !inLen)
+ SOFT_ERROR(PI_BAD_POINTER, "input buffer can't be NULL");
+
+ if (!outBuf && outLen)
+ SOFT_ERROR(PI_BAD_POINTER, "output buffer can't be NULL");
+
+ w = &wfRx[SDA];
+
+ inPos = 0;
+ outPos = 0;
+ status = 0;
+
+ while (!status && (inPos < inLen))
+ {
+ DBG(DBG_INTERNAL, "status=%d inpos=%d inlen=%d cmd=%d",
+ status, inPos, inLen, inBuf[inPos]);
+
+ len_bytes = 1;
+
+ switch (inBuf[inPos++])
+ {
+ case PI_I2C_END:
+ status = 1;
+ break;
+
+ case PI_I2C_START:
+ I2CStart(w);
+ break;
+
+ case PI_I2C_STOP:
+ I2CStop(w);
+ break;
+
+ case PI_I2C_READ16:
+ len_bytes = 2;
+ /* fall through */
+
+ case PI_I2C_READ:
+ if (inPos <= (inLen - len_bytes))
+ {
+ if (len_bytes != 1)
+ {
+ bytes=inBuf[inPos] + (inBuf[inPos+1]<<8);
+ inPos += 2;
+ }
+ else
+ {
+ bytes=inBuf[inPos++];
+ }
+
+ if (bytes && ((bytes + outPos) < outLen))
+ {
+ for (i=0; i<(bytes-1); i++)
+ {
+ outBuf[outPos++] = I2CGetByte(w, 0);
+ }
+ outBuf[outPos++] = I2CGetByte(w, 1);
+ }
+ else status = PI_BAD_BB_WLEN;
+ }
+ else status = PI_BAD_BB_WLEN;
+ break;
+
+ case PI_I2C_WRITE16:
+ len_bytes = 2;
+ /* fall through */
+
+ case PI_I2C_WRITE:
+ if (inPos <= (inLen - len_bytes))
+ {
+ if (len_bytes != 1)
+ {
+ bytes=inBuf[inPos] + (inBuf[inPos+1]<<8);
+ inPos += 2;
+ }
+ else
+ {
+ bytes=inBuf[inPos++];
+ }
+
+ if (bytes && ((bytes + inPos) < inLen))
+ {
+ for (i=0; i<(bytes-1); i++)
+ {
+ ack = I2CPutByte(w, inBuf[inPos++]);
+ if (ack) status = PI_I2C_WRITE_FAILED;
+ }
+ ack = I2CPutByte(w, inBuf[inPos++]);
+ //if (ack) status = PI_I2C_WRITE_FAILED;
+ }
+ else status = PI_BAD_BB_RLEN;
+ }
+ else status = PI_BAD_BB_RLEN;
+ break;
+
+ default:
+ status = PI_BAD_BB_CMD;
+ }
+ }
+
+ if (status >= 0) status = outPos;
+
+ return status;
+}
+
+
/*-------------------------------------------------------------------------*/
int gpioSerialReadOpen(unsigned gpio, unsigned bbBaud, unsigned bbBits)
@@ -8141,28 +8748,29 @@ int gpioSerialReadOpen(unsigned gpio, unsigned bbBaud, unsigned bbBits)
if (wfRx[gpio].mode != PI_WFRX_NONE)
SOFT_ERROR(PI_GPIO_IN_USE, "gpio %d is already being used", gpio);
- bitTime = (1000 * MILLION) / bbBaud; /* nanoseconds */
+ bitTime = (1000 * MILLION) / bbBaud; /* nanos */
- timeout = ((bbBits+2) * bitTime)/MILLION; /* milliseconds */
+ timeout = ((bbBits+2) * bitTime)/MILLION; /* millis */
if (timeout < 1) timeout = 1;
- wfRx[gpio].gpio = gpio;
- wfRx[gpio].buf = malloc(SRX_BUF_SIZE);
- wfRx[gpio].bufSize = SRX_BUF_SIZE;
- wfRx[gpio].mode = PI_WFRX_SERIAL;
- wfRx[gpio].baud = bbBaud;
- wfRx[gpio].timeout = timeout;
- wfRx[gpio].fullBit = bitTime; /* nanoseconds */
- wfRx[gpio].halfBit = (bitTime/2)+500; /* nanoseconds (500 for rounding) */
- wfRx[gpio].readPos = 0;
- wfRx[gpio].writePos = 0;
- wfRx[gpio].bit = -1;
- wfRx[gpio].dataBits = bbBits;
+ wfRx[gpio].gpio = gpio;
+ wfRx[gpio].mode = PI_WFRX_SERIAL;
+ wfRx[gpio].baud = bbBaud;
- if (bbBits < 9) wfRx[gpio].bytes = 1;
- else if (bbBits < 17) wfRx[gpio].bytes = 2;
- else wfRx[gpio].bytes = 4;
+ wfRx[gpio].s.buf = malloc(SRX_BUF_SIZE);
+ wfRx[gpio].s.bufSize = SRX_BUF_SIZE;
+ wfRx[gpio].s.timeout = timeout;
+ wfRx[gpio].s.fullBit = bitTime; /* nanos */
+ wfRx[gpio].s.halfBit = (bitTime/2)+500; /* nanos (500 for rounding) */
+ wfRx[gpio].s.readPos = 0;
+ wfRx[gpio].s.writePos = 0;
+ wfRx[gpio].s.bit = -1;
+ wfRx[gpio].s.dataBits = bbBits;
+
+ if (bbBits < 9) wfRx[gpio].s.bytes = 1;
+ else if (bbBits < 17) wfRx[gpio].s.bytes = 2;
+ else wfRx[gpio].s.bytes = 4;
gpioSetAlertFunc(gpio, waveRxBit);
@@ -8174,7 +8782,7 @@ int gpioSerialReadOpen(unsigned gpio, unsigned bbBaud, unsigned bbBits)
int gpioSerialRead(unsigned gpio, void *buf, size_t bufSize)
{
unsigned bytes=0, wpos;
- volatile wfRx_t *p;
+ volatile wfRx_t *w;
DBG(DBG_USER, "gpio=%d buf=%08X bufSize=%d", gpio, (int)buf, bufSize);
@@ -8189,26 +8797,26 @@ int gpioSerialRead(unsigned gpio, void *buf, size_t bufSize)
if (wfRx[gpio].mode != PI_WFRX_SERIAL)
SOFT_ERROR(PI_NOT_SERIAL_GPIO, "no serial read on gpio (%d)", gpio);
- p = &wfRx[gpio];
+ w = &wfRx[gpio];
- if (p->readPos != p->writePos)
+ if (w->s.readPos != w->s.writePos)
{
- wpos = p->writePos;
+ wpos = w->s.writePos;
- if (wpos > p->readPos) bytes = wpos - p->readPos;
- else bytes = p->bufSize - p->readPos;
+ if (wpos > w->s.readPos) bytes = wpos - w->s.readPos;
+ else bytes = w->s.bufSize - w->s.readPos;
if (bytes > bufSize) bytes = bufSize;
/* copy in multiples of the data size in bytes */
- bytes = (bytes / p->bytes) * p->bytes;
+ bytes = (bytes / w->s.bytes) * w->s.bytes;
- if (buf) memcpy(buf, p->buf+p->readPos, bytes);
+ if (buf) memcpy(buf, w->s.buf+w->s.readPos, bytes);
- p->readPos += bytes;
+ w->s.readPos += bytes;
- if (p->readPos >= p->bufSize) p->readPos = 0;
+ if (w->s.readPos >= w->s.bufSize) w->s.readPos = 0;
}
return bytes;
}
@@ -8235,7 +8843,7 @@ int gpioSerialReadClose(unsigned gpio)
case PI_WFRX_SERIAL:
- free(wfRx[gpio].buf);
+ free(wfRx[gpio].s.buf);
gpioSetWatchdog(gpio, 0); /* switch off timeouts */
@@ -8357,6 +8965,7 @@ int gpioNotifyOpen(void)
gpioNotify[slot].bits = 0;
gpioNotify[slot].fd = fd;
gpioNotify[slot].pipe = 1;
+ gpioNotify[slot].lastReportTick = gpioTick();
return slot;
}
@@ -8390,6 +8999,7 @@ static int gpioNotifyOpenInBand(int fd)
gpioNotify[slot].bits = 0;
gpioNotify[slot].fd = fd;
gpioNotify[slot].pipe = 0;
+ gpioNotify[slot].lastReportTick = gpioTick();
return slot;
}
@@ -9368,9 +9978,10 @@ uint32_t gpioDelay(uint32_t micros)
start = systReg[SYST_CLO];
- if (micros <= PI_MAX_BUSY_DELAY) while ((systReg[SYST_CLO] - start) <= micros);
-
- else gpioSleep(PI_TIME_RELATIVE, (micros/MILLION), (micros%MILLION));
+ if (micros <= PI_MAX_BUSY_DELAY)
+ while ((systReg[SYST_CLO] - start) <= micros);
+ else
+ gpioSleep(PI_TIME_RELATIVE, (micros/MILLION), (micros%MILLION));
return (systReg[SYST_CLO] - start);
}
@@ -9663,3 +10274,4 @@ int gpioCfgInternals(unsigned cfgWhat, int cfgVal)
/* include any user customisations */
#include "custom.cext"
+
diff --git a/pigpio.h b/pigpio.h
index 69afbc8..d5c302d 100644
--- a/pigpio.h
+++ b/pigpio.h
@@ -31,7 +31,7 @@ For more information, please refer to
#include
#include
-#define PIGPIO_VERSION 31
+#define PIGPIO_VERSION 3202
/*TEXT
@@ -225,20 +225,20 @@ i2cClose Closes an I2C device
i2cReadDevice Reads the raw I2C device
i2cWriteDevice Writes the raw I2C device
-i2cWriteQuick smbus write quick
-i2cWriteByte smbus write byte
-i2cReadByte smbus read byte
-i2cWriteByteData smbus write byte data
-i2cWriteWordData smbus write word data
-i2cReadByteData smbus read byte data
-i2cReadWordData smbus read word data
-i2cProcessCall smbus process call
-i2cWriteBlockData smbus write block data
-i2cReadBlockData smbus read block data
-i2cBlockProcessCall smbus block process call
+i2cWriteQuick SMBus write quick
+i2cWriteByte SMBus write byte
+i2cReadByte SMBus read byte
+i2cWriteByteData SMBus write byte data
+i2cWriteWordData SMBus write word data
+i2cReadByteData SMBus read byte data
+i2cReadWordData SMBus read word data
+i2cProcessCall SMBus process call
+i2cWriteBlockData SMBus write block data
+i2cReadBlockData SMBus read block data
+i2cBlockProcessCall SMBus block process call
-i2cWriteI2CBlockData smbus write I2C block data
-i2cReadI2CBlockData smbus read I2C block data
+i2cWriteI2CBlockData SMBus write I2C block data
+i2cReadI2CBlockData SMBus read I2C block data
SPI
@@ -327,36 +327,36 @@ extern "C" {
typedef struct
{
-uint16_t func;
-uint16_t size;
+ uint16_t func;
+ uint16_t size;
} gpioHeader_t;
typedef struct
{
-size_t size;
-void *ptr;
-uint32_t data;
+ size_t size;
+ void *ptr;
+ uint32_t data;
} gpioExtent_t;
typedef struct
{
-uint32_t tick;
-uint32_t level;
+ uint32_t tick;
+ uint32_t level;
} gpioSample_t;
typedef struct
{
-uint16_t seqno;
-uint16_t flags;
-uint32_t tick;
-uint32_t level;
+ uint16_t seqno;
+ uint16_t flags;
+ uint32_t tick;
+ uint32_t level;
} gpioReport_t;
typedef struct
{
-uint32_t gpioOn;
-uint32_t gpioOff;
-uint32_t usDelay;
+ uint32_t gpioOn;
+ uint32_t gpioOff;
+ uint32_t usDelay;
} gpioPulse_t;
#define WAVE_FLAG_READ 1
@@ -365,10 +365,10 @@ uint32_t usDelay;
typedef struct
{
-uint32_t gpioOn;
-uint32_t gpioOff;
-uint32_t usDelay;
-uint32_t flags;
+ uint32_t gpioOn;
+ uint32_t gpioOff;
+ uint32_t usDelay;
+ uint32_t flags;
} rawWave_t;
typedef struct
@@ -381,41 +381,26 @@ typedef struct
typedef struct
{
-int clk; /* gpio for clock */
-int mosi; /* gpio for MOSI */
-int miso; /* gpio for MISO */
-int ss_pol; /* slave select off state */
-int ss_us; /* delay after slave select */
-int clk_pol; /* clock off state */
-int clk_pha; /* clock phase */
-int clk_us; /* clock micros */
+ int clk; /* gpio for clock */
+ int mosi; /* gpio for MOSI */
+ int miso; /* gpio for MISO */
+ int ss_pol; /* slave select off state */
+ int ss_us; /* delay after slave select */
+ int clk_pol; /* clock off state */
+ int clk_pha; /* clock phase */
+ int clk_us; /* clock micros */
} rawSPI_t;
typedef struct { /* linux/arch/arm/mach-bcm2708/include/mach/dma.h */
-uint32_t info;
-uint32_t src;
-uint32_t dst;
-uint32_t length;
-uint32_t stride;
-uint32_t next;
-uint32_t pad[2];
+ uint32_t info;
+ uint32_t src;
+ uint32_t dst;
+ uint32_t length;
+ uint32_t stride;
+ uint32_t next;
+ uint32_t pad[2];
} rawCbs_t;
-/* max pi_i2c_msg_t per transaction */
-
-#define PI_I2C_RDRW_IOCTL_MAX_MSGS 42
-
-/* flags for pi_i2c_msg_t */
-
-#define PI_I2C_M_WR 0x0000 /* write data */
-#define PI_I2C_M_RD 0x0001 /* read data */
-#define PI_I2C_M_TEN 0x0010 /* ten bit chip address */
-#define PI_I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
-#define PI_I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
-#define PI_I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
-#define PI_I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
-#define PI_I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */
-
typedef struct
{
uint16_t addr; /* slave address */
@@ -521,6 +506,7 @@ typedef void *(gpioThreadFunc_t) (void *);
#define PI_NOTIFY_SLOTS 32
+#define PI_NTFY_FLAGS_ALIVE (1 <<6)
#define PI_NTFY_FLAGS_WDOG (1 <<5)
#define PI_NTFY_FLAGS_BIT(x) (((x)<<0)&31)
@@ -564,6 +550,43 @@ typedef void *(gpioThreadFunc_t) (void *);
#define PI_MAX_I2C_DEVICE_COUNT (1<<16)
#define PI_MAX_SPI_DEVICE_COUNT (1<<16)
+/* max pi_i2c_msg_t per transaction */
+
+#define PI_I2C_RDRW_IOCTL_MAX_MSGS 42
+
+/* flags for pi_i2c_msg_t */
+
+#define PI_I2C_M_WR 0x0000 /* write data */
+#define PI_I2C_M_RD 0x0001 /* read data */
+#define PI_I2C_M_TEN 0x0010 /* ten bit chip address */
+#define PI_I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
+#define PI_I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
+#define PI_I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
+#define PI_I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
+#define PI_I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */
+
+/* bit bang I2C commands */
+
+#define PI_I2C_END 0
+#define PI_I2C_START 1
+#define PI_I2C_STOP 2
+#define PI_I2C_READ 3
+#define PI_I2C_WRITE 4
+#define PI_I2C_READ16 5
+#define PI_I2C_WRITE16 6
+
+/* combined transaction I2C flag commands */
+
+#define PI_I2C_F_CLEAR 40 /* clear flags */
+#define PI_I2C_F_TEN 41 /* ten bit chip address */
+#define PI_I2C_F_RECV_LEN 42 /* length will be first received byte */
+#define PI_I2C_F_NO_RD_ACK 43 /* if I2C_FUNC_PROTOCOL_MANGLING */
+#define PI_I2C_F_IGNORE_NAK 44 /* if I2C_FUNC_PROTOCOL_MANGLING */
+#define PI_I2C_F_REV_DIR_ADDR 45 /* if I2C_FUNC_PROTOCOL_MANGLING */
+#define PI_I2C_F_NOSTART 46 /* if I2C_FUNC_PROTOCOL_MANGLING */
+
+/* SPI */
+
#define PI_SPI_FLAGS_BITLEN(x) ((x&63)<<16)
#define PI_SPI_FLAGS_RX_LSB(x) ((x&1)<<15)
#define PI_SPI_FLAGS_TX_LSB(x) ((x&1)<<14)
@@ -1740,7 +1763,7 @@ No flags are currently defined. This parameter should be set to zero.
Returns a handle (>=0) if OK, otherwise PI_BAD_I2C_BUS, PI_BAD_I2C_ADDR,
PI_BAD_FLAGS, PI_NO_HANDLE, or PI_I2C_OPEN_FAILED.
-For the smbus commands the low level transactions are shown at the end
+For the SMBus commands the low level transactions are shown at the end
of the function description. The following abbreviations are used.
. .
@@ -1821,7 +1844,7 @@ handle: >=0, as returned by a call to [*i2cOpen*]
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or
PI_I2C_WRITE_FAILED.
-Quick command. smbus 2.0 5.5.1
+Quick command. SMBus 2.0 5.5.1
. .
S Addr Rd/Wr [A] P
. .
@@ -1841,7 +1864,7 @@ handle: >=0, as returned by a call to [*i2cOpen*]
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or
PI_I2C_WRITE_FAILED.
-Send byte. smbus 2.0 5.5.2
+Send byte. SMBus 2.0 5.5.2
. .
S Addr Wr [A] Data [A] P
. .
@@ -1860,7 +1883,7 @@ handle: >=0, as returned by a call to [*i2cOpen*]
Returns the byte read (>=0) if OK, otherwise PI_BAD_HANDLE,
or PI_I2C_READ_FAILED.
-Receive byte. smbus 2.0 5.5.3
+Receive byte. SMBus 2.0 5.5.3
. .
S Addr Rd [A] [Data] NA P
. .
@@ -1882,7 +1905,7 @@ i2cReg: 0-255, the register to write
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or
PI_I2C_WRITE_FAILED.
-Write byte. smbus 2.0 5.5.4
+Write byte. SMBus 2.0 5.5.4
. .
S Addr Wr [A] Comm [A] Data [A] P
. .
@@ -1904,7 +1927,7 @@ i2cReg: 0-255, the register to write
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or
PI_I2C_WRITE_FAILED.
-Write word. smbus 2.0 5.5.4
+Write word. SMBus 2.0 5.5.4
. .
S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P
. .
@@ -1925,7 +1948,7 @@ i2cReg: 0-255, the register to read
Returns the byte read (>=0) if OK, otherwise PI_BAD_HANDLE,
PI_BAD_PARAM, or PI_I2C_READ_FAILED.
-Read byte. smbus 2.0 5.5.5
+Read byte. SMBus 2.0 5.5.5
. .
S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P
. .
@@ -1946,7 +1969,7 @@ i2cReg: 0-255, the register to read
Returns the word read (>=0) if OK, otherwise PI_BAD_HANDLE,
PI_BAD_PARAM, or PI_I2C_READ_FAILED.
-Read word. smbus 2.0 5.5.5
+Read word. SMBus 2.0 5.5.5
. .
S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
. .
@@ -1968,7 +1991,7 @@ i2cReg: 0-255, the register to write/read
Returns the word read (>=0) if OK, otherwise PI_BAD_HANDLE,
PI_BAD_PARAM, or PI_I2C_READ_FAILED.
-Process call. smbus 2.0 5.5.6
+Process call. SMBus 2.0 5.5.6
. .
S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A]
S Addr Rd [A] [DataLow] A [DataHigh] NA P
@@ -1993,7 +2016,7 @@ i2cReg: 0-255, the register to write
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or
PI_I2C_WRITE_FAILED.
-Block write. smbus 2.0 5.5.7
+Block write. SMBus 2.0 5.5.7
. .
S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P
. .
@@ -2017,7 +2040,7 @@ The amount of returned data is set by the device.
Returns the number of bytes read (>=0) if OK, otherwise PI_BAD_HANDLE,
PI_BAD_PARAM, or PI_I2C_READ_FAILED.
-Block read. smbus 2.0 5.5.7
+Block read. SMBus 2.0 5.5.7
. .
S Addr Wr [A] Comm [A]
S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P
@@ -2043,11 +2066,11 @@ i2cReg: 0-255, the register to write/read
Returns the number of bytes read (>=0) if OK, otherwise PI_BAD_HANDLE,
PI_BAD_PARAM, or PI_I2C_READ_FAILED.
-The smbus 2.0 documentation states that a minimum of 1 byte may be
+The SMBus 2.0 documentation states that a minimum of 1 byte may be
sent and a minimum of 1 byte may be received. The total number of
bytes sent/received must be 32 or less.
-Block write-block read. smbus 2.0 5.5.8
+Block write-block read. SMBus 2.0 5.5.8
. .
S Addr Wr [A] Comm [A] Count [A] Data [A] ...
S Addr Rd [A] [Count] A [Data] ... A P
@@ -2101,6 +2124,14 @@ S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P
. .
D*/
+int bbI2COpen(unsigned SDA, unsigned SCL, unsigned bbBaud);
+
+int bbI2CClose(unsigned SDA);
+
+int bbI2CXfer(
+ unsigned SDA,
+ char *inBuf, unsigned inLen, char *outBuf, unsigned outLen);
+
/*F*/
int spiOpen(unsigned spiChan, unsigned spiBaud, unsigned spiFlags);
@@ -4252,6 +4283,12 @@ PARAMS*/
#define PI_CMD_CF1 87
#define PI_CMD_CF2 88
+#define PI_CMD_BI2CC 89
+#define PI_CMD_BI2CO 90
+#define PI_CMD_BI2CX 91
+
+#define PI_CMD_I2CX 92
+
#define PI_CMD_NOIB 99
/*DEF_E*/
@@ -4354,7 +4391,7 @@ after this command is issued.
#define PI_BAD_WAVE_BAUD -35 // baud rate not 50-250K(RX)/50-1M(TX)
#define PI_TOO_MANY_PULSES -36 // waveform has too many pulses
#define PI_TOO_MANY_CHARS -37 // waveform has too many chars
-#define PI_NOT_SERIAL_GPIO -38 // no serial read in progress on gpio
+#define PI_NOT_SERIAL_GPIO -38 // no bit bang serial read in progress on gpio
#define PI_BAD_SERIAL_STRUC -39 // bad (null) serial structure parameter
#define PI_BAD_SERIAL_BUF -40 // bad (null) serial buf parameter
#define PI_NOT_PERMITTED -41 // gpio operation not permitted
@@ -4423,7 +4460,11 @@ after this command is issued.
#define PI_BAD_MALLOC_MODE -104 // bad memory allocation mode
#define PI_TOO_MANY_PARTS -105 // too many I2C transaction parts
#define PI_BAD_I2C_PART -106 // a combined I2C transaction failed
-
+#define PI_BAD_SMBUS_CMD -107 // SMBus command not supported by driver
+#define PI_NOT_I2C_GPIO -108 // no bit bang I2C in progress on gpio
+#define PI_BAD_BB_WLEN -109 // bad BB write length
+#define PI_BAD_BB_RLEN -110 // bad BB read length
+#define PI_BAD_BB_CMD -111 // bad BB command
#define PI_PIGIF_ERR_0 -2000
#define PI_PIGIF_ERR_99 -2099
@@ -4448,7 +4489,7 @@ after this command is issued.
#define PI_DEFAULT_UPDATE_MASK_R0 0xFFFFFFFF
#define PI_DEFAULT_UPDATE_MASK_R1 0x03E7CF93
#define PI_DEFAULT_UPDATE_MASK_R2 0xFBC7CF9C
-#define PI_DEFAULT_UPDATE_MASK_R3 0x0080400FFFFFFCLL
+#define PI_DEFAULT_UPDATE_MASK_R3 0x0080480FFFFFFCLL
#define PI_DEFAULT_UPDATE_MASK_COMPUTE 0x00FFFFFFFFFFFFLL
#define PI_DEFAULT_MEM_ALLOC_MODE PI_MEM_ALLOC_AUTO
diff --git a/pigpio.py b/pigpio.py
index 42518fc..cc43e58 100644
--- a/pigpio.py
+++ b/pigpio.py
@@ -197,20 +197,20 @@ i2c_close Closes an I2C device
i2c_read_device Reads the raw I2C device
i2c_write_device Writes the raw I2C device
-i2c_write_quick smbus write quick
-i2c_write_byte smbus write byte
-i2c_read_byte smbus read byte
-i2c_write_byte_data smbus write byte data
-i2c_write_word_data smbus write word data
-i2c_read_byte_data smbus read byte data
-i2c_read_word_data smbus read word data
-i2c_process_call smbus process call
-i2c_write_block_data smbus write block data
-i2c_read_block_data smbus read block data
-i2c_block_process_call smbus block process call
+i2c_write_quick SMBus write quick
+i2c_write_byte SMBus write byte
+i2c_read_byte SMBus read byte
+i2c_write_byte_data SMBus write byte data
+i2c_write_word_data SMBus write word data
+i2c_read_byte_data SMBus read byte data
+i2c_read_word_data SMBus read word data
+i2c_process_call SMBus process call
+i2c_write_block_data SMBus write block data
+i2c_read_block_data SMBus read block data
+i2c_block_process_call SMBus block process call
-i2c_read_i2c_block_data smbus read I2C block data
-i2c_write_i2c_block_data smbus write I2C block data
+i2c_read_i2c_block_data SMBus read I2C block data
+i2c_write_i2c_block_data SMBus write I2C block data
SPI
@@ -257,7 +257,7 @@ import threading
import os
import atexit
-VERSION = "1.16"
+VERSION = "1.17"
exceptions = True
@@ -304,6 +304,12 @@ PI_SCRIPT_RUNNING=2
PI_SCRIPT_WAITING=3
PI_SCRIPT_FAILED =4
+# notification flags
+
+NTFY_FLAGS_ALIVE = (1 << 6)
+NTFY_FLAGS_WDOG = (1 << 5)
+NTFY_FLAGS_GPIO = 31
+
# pigpio command numbers
_PI_CMD_MODES= 0
@@ -519,6 +525,10 @@ PI_BAD_DATABITS =-101
PI_BAD_STOPBITS =-102
PI_MSG_TOOBIG =-103
PI_BAD_MALLOC_MODE =-104
+_PI_TOO_MANY_PARTS =-105
+_PI_BAD_I2C_PART =-106
+PI_BAD_SMBUS_CMD =-107
+PI_NOT_I2C_GPIO =-108
# pigpio error text
@@ -560,7 +570,7 @@ _errors=[
[PI_BAD_WAVE_BAUD , "baud rate not 50-250000(RX)/1000000(TX)"],
[PI_TOO_MANY_PULSES , "waveform has too many pulses"],
[PI_TOO_MANY_CHARS , "waveform has too many chars"],
- [PI_NOT_SERIAL_GPIO , "no serial read in progress on gpio"],
+ [PI_NOT_SERIAL_GPIO , "no bit bang serial read in progress on gpio"],
[PI_NOT_PERMITTED , "no permission to update gpio"],
[PI_SOME_PERMITTED , "no permission to update one or more gpios"],
[PI_BAD_WVSC_COMMND , "bad WVSC subcommand"],
@@ -625,6 +635,10 @@ _errors=[
[PI_BAD_STOPBITS , "serial (half) stop bits not 2-8"],
[PI_MSG_TOOBIG , "socket/pipe message too big"],
[PI_BAD_MALLOC_MODE , "bad memory allocation mode"],
+ [_PI_TOO_MANY_PARTS , "too many I2C transaction parts"],
+ [_PI_BAD_I2C_PART , "a combined I2C transaction failed"],
+ [PI_BAD_SMBUS_CMD , "SMBus command not supported"],
+ [PI_NOT_I2C_GPIO , "no bit bang I2C in progress on gpio"],
]
@@ -867,10 +881,11 @@ class _callback_thread(threading.Thread):
if (cb.edge ^ newLevel):
cb.func(cb.gpio, newLevel, tick)
else:
- gpio = flags & 31
- for cb in self.callbacks:
- if cb.gpio == gpio:
- cb.func(cb.gpio, TIMEOUT, tick)
+ if flags & NTFY_FLAGS_WDOG:
+ gpio = flags & NTFY_FLAGS_GPIO
+ for cb in self.callbacks:
+ if cb.gpio == gpio:
+ cb.func(cb.gpio, TIMEOUT, tick)
self.sl.s.close()
@@ -1993,7 +2008,7 @@ class pi():
Normally you would only use the [*i2c_**] functions if
you are or will be connecting to the Pi over a network. If
- you will always run on the local Pi use the standard smbus
+ you will always run on the local Pi use the standard SMBus
module instead.
...
@@ -2080,7 +2095,7 @@ class pi():
"""
Sends a single bit to the device associated with handle.
- smbus 2.0 5.5.1 - Quick command.
+ SMBus 2.0 5.5.1 - Quick command.
handle:= >=0 (as returned by a prior call to [*i2c_open*]).
bit:= 0 or 1, the value to write.
@@ -2096,7 +2111,7 @@ class pi():
"""
Sends a single byte to the device associated with handle.
- smbus 2.0 5.5.2 - Send byte.
+ SMBus 2.0 5.5.2 - Send byte.
handle:= >=0 (as returned by a prior call to [*i2c_open*]).
byte_val:= 0-255, the value to write.
@@ -2113,7 +2128,7 @@ class pi():
"""
Reads a single byte from the device associated with handle.
- smbus 2.0 5.5.3 - Receive byte.
+ SMBus 2.0 5.5.3 - Receive byte.
handle:= >=0 (as returned by a prior call to [*i2c_open*]).
@@ -2128,7 +2143,7 @@ class pi():
Writes a single byte to the specified register of the device
associated with handle.
- smbus 2.0 5.5.4 - Write byte.
+ SMBus 2.0 5.5.4 - Write byte.
handle:= >=0 (as returned by a prior call to [*i2c_open*]).
reg:= >=0, the device register.
@@ -2156,7 +2171,7 @@ class pi():
Writes a single 16 bit word to the specified register of the
device associated with handle.
- smbus 2.0 5.5.4 - Write word.
+ SMBus 2.0 5.5.4 - Write word.
handle:= >=0 (as returned by a prior call to [*i2c_open*]).
reg:= >=0, the device register.
@@ -2184,7 +2199,7 @@ class pi():
Reads a single byte from the specified register of the device
associated with handle.
- smbus 2.0 5.5.5 - Read byte.
+ SMBus 2.0 5.5.5 - Read byte.
handle:= >=0 (as returned by a prior call to [*i2c_open*]).
reg:= >=0, the device register.
@@ -2204,7 +2219,7 @@ class pi():
Reads a single 16 bit word from the specified register of the
device associated with handle.
- smbus 2.0 5.5.5 - Read word.
+ SMBus 2.0 5.5.5 - Read word.
handle:= >=0 (as returned by a prior call to [*i2c_open*]).
reg:= >=0, the device register.
@@ -2224,7 +2239,7 @@ class pi():
Writes 16 bits of data to the specified register of the device
associated with handle and reads 16 bits of data in return.
- smbus 2.0 5.5.6 - Process call.
+ SMBus 2.0 5.5.6 - Process call.
handle:= >=0 (as returned by a prior call to [*i2c_open*]).
reg:= >=0, the device register.
@@ -2249,7 +2264,7 @@ class pi():
Writes up to 32 bytes to the specified register of the device
associated with handle.
- smbus 2.0 5.5.7 - Block write.
+ SMBus 2.0 5.5.7 - Block write.
handle:= >=0 (as returned by a prior call to [*i2c_open*]).
reg:= >=0, the device register.
@@ -2281,7 +2296,7 @@ class pi():
Reads a block of up to 32 bytes from the specified register of
the device associated with handle.
- smbus 2.0 5.5.7 - Block read.
+ SMBus 2.0 5.5.7 - Block read.
handle:= >=0 (as returned by a prior call to [*i2c_open*]).
reg:= >=0, the device register.
@@ -2316,13 +2331,13 @@ class pi():
associated with handle and reads a device specified number
of bytes of data in return.
- smbus 2.0 5.5.8 - Block write-block read.
+ SMBus 2.0 5.5.8 - Block write-block read.
handle:= >=0 (as returned by a prior call to [*i2c_open*]).
reg:= >=0, the device register.
data:= the bytes to write.
- The smbus 2.0 documentation states that a minimum of 1 byte may
+ The SMBus 2.0 documentation states that a minimum of 1 byte may
be sent and a minimum of 1 byte may be received. The total
number of bytes sent/received must be 32 or less.
diff --git a/pigs.c b/pigs.c
index e4e2421..1869164 100644
--- a/pigs.c
+++ b/pigs.c
@@ -26,7 +26,7 @@ For more information, please refer to
*/
/*
-This version is for pigpio version 26+
+This version is for pigpio version 32+
*/
#include
@@ -141,7 +141,7 @@ void print_result(int sock, int rv, cmdCmd_t cmd)
printf(cmdUsage);
break;
- case 6: /* CF2 I2CPK I2CRD I2CRI I2CRK SERR SLR SPIX SPIR */
+ case 6: /* BI2CX CF2 I2CPK I2CRD I2CRI I2CRK SERR SLR SPIX SPIR */
printf("%d", r);
if (r < 0) fatal("ERROR: %s", cmdErrStr(r));
if (r > 0)
@@ -178,6 +178,7 @@ void get_extensions(int sock, int command, int res)
{
switch (command)
{
+ case PI_CMD_BI2CX:
case PI_CMD_CF2:
case PI_CMD_I2CPK:
case PI_CMD_I2CRD:
diff --git a/setup.py b/setup.py
index 8fec0ac..b027567 100644
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@
from distutils.core import setup
setup(name='pigpio',
- version='1.16',
+ version='1.17',
author='joan',
author_email='joan@abyz.co.uk',
maintainer='joan',