Skip to content

Commit 418473e

Browse files
committed
Merge branch 'master' of github.com:jamesbowman/i2cdriver
2 parents 7435273 + 2bdf441 commit 418473e

File tree

6 files changed

+128
-4
lines changed

6 files changed

+128
-4
lines changed

c/common/i2cdriver.c

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818

1919
#if defined(WIN32) // {
2020

21+
#ifndef NOMINMAX
2122
#define NOMINMAX
23+
#endif
2224
#include <windows.h>
2325

2426
void ErrorExit(const char *func_name)
@@ -323,7 +325,7 @@ uint8_t i2c_reset(I2CDriver *sd)
323325

324326
int i2c_start(I2CDriver *sd, uint8_t dev, uint8_t op)
325327
{
326-
uint8_t start[2] = {'s', (dev << 1) | op};
328+
uint8_t start[2] = {'s', (uint8_t)((dev << 1) | op)};
327329
writeToSerialPort(sd->port, start, sizeof(start));
328330
return i2c_ack(sd);
329331
}
@@ -367,6 +369,56 @@ void i2c_monitor(I2CDriver *sd, int enable)
367369
charCommand(sd, enable ? 'm' : '@');
368370
}
369371

372+
void i2c_capture(I2CDriver *sd)
373+
{
374+
printf("Capture started\n");
375+
charCommand(sd, 'c');
376+
uint8_t bytes[1];
377+
378+
int starting = 0;
379+
int nbits = 0, bits = 0;
380+
while (1) {
381+
int i;
382+
readFromSerialPort(sd->port, bytes, 1);
383+
for (i = 0; i < 2; i++) {
384+
int symbol = (i == 0) ? (bytes[0] >> 4) : (bytes[0] & 0xf);
385+
switch (symbol) {
386+
case 0:
387+
break;
388+
case 1:
389+
starting = 1;
390+
break;
391+
case 2:
392+
printf("STOP\n");
393+
starting = 1;
394+
break;
395+
case 8:
396+
case 9:
397+
case 10:
398+
case 11:
399+
case 12:
400+
case 13:
401+
case 14:
402+
case 15:
403+
bits = (bits << 3) | (symbol & 7);
404+
nbits += 3;
405+
if (nbits == 9) {
406+
int b8 = (bits >> 1), ack = !(bits & 1);
407+
if (starting) {
408+
starting = 0;
409+
printf("START %02x %s", b8 >> 1, (b8 & 1) ? "READ" : "WRITE");
410+
} else {
411+
printf("BYTE %02x", b8);
412+
}
413+
printf(" %s\n", ack ? "ACK" : "NAK");
414+
nbits = 0;
415+
bits = 0;
416+
}
417+
}
418+
}
419+
}
420+
}
421+
370422
int i2c_commands(I2CDriver *sd, int argc, char *argv[])
371423
{
372424
int i;
@@ -479,6 +531,12 @@ int i2c_commands(I2CDriver *sd, int argc, char *argv[])
479531
}
480532
break;
481533

534+
case 'c':
535+
{
536+
i2c_capture(sd);
537+
}
538+
break;
539+
482540
default:
483541
badcommand:
484542
fprintf(stderr, "Bad command '%s'\n", token);
@@ -492,6 +550,7 @@ int i2c_commands(I2CDriver *sd, int argc, char *argv[])
492550
fprintf(stderr, " p send a STOP\n");
493551
fprintf(stderr, " r dev N read N bytes from I2C device dev, then STOP\n");
494552
fprintf(stderr, " m enter I2C bus monitor mode\n");
553+
fprintf(stderr, " c enter I2C bus capture mode\n");
495554
fprintf(stderr, "\n");
496555

497556
return 1;

c/common/i2cdriver.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ int i2c_start(I2CDriver *sd, uint8_t dev, uint8_t op);
3636
void i2c_stop(I2CDriver *sd);
3737

3838
void i2c_monitor(I2CDriver *sd, int enable);
39+
void i2c_capture(I2CDriver *sd);
3940

4041
int i2c_commands(I2CDriver *sd, int argc, char *argv[]);
4142

c/linux/Makefile.clang

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CC=clang
2+
CFLAGS += -I common -Wall -Wpointer-sign -xc++ -std=c++17 # -Werror
3+
4+
all: build/i2ccl
5+
6+
install: all
7+
cp build/i2ccl /usr/local/bin
8+
9+
build/i2ccl: linux/i2c.c common/i2cdriver.c
10+
mkdir -p build/
11+
$(CC) -o $@ $(CPPFLAGS) $(CFLAGS) $^

python/i2cdriver.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,15 @@ class I2CDriver:
6868
"""
6969
A connected I2CDriver.
7070
71-
:ivar product: product code e.g. 'i2cdriver1'
71+
:param port: The USB port to connect to
72+
:type port: str
73+
:param reset: Issue an I2C bus reset on connection
74+
:type reset: bool
75+
76+
After connection, the following object variables reflect the current values of the I2CDriver.
77+
They are updated by calling :py:meth:`getstatus`.
78+
79+
:ivar product: product code e.g. 'i2cdriver1' or 'i2cdriverm'
7280
:ivar serial: serial string of I2CDriver
7381
:ivar uptime: time since I2CDriver boot, in seconds
7482
:ivar voltage: USB voltage, in V
@@ -269,7 +277,7 @@ def regrd(self, dev, reg, fmt = "B"):
269277
:param reg: register address 0-255
270278
:param fmt: :py:func:`struct.unpack` format string for the register contents, or an integer byte count
271279
272-
If device 0x75 has a 16-bit register 102, it can be read with:
280+
If device 0x75 has a 16-bit unsigned big-endian register 102, it can be read with:
273281
274282
>>> i2c.regrd(0x75, 102, ">H")
275283
4999
@@ -335,7 +343,6 @@ def monitor(self, s):
335343
self.__echo(0x40)
336344

337345
def introspect(self):
338-
""" Update all status variables """
339346
self.ser.write(b'J')
340347
r = self.ser.read(80)
341348
assert len(r) == 80, r
@@ -360,6 +367,11 @@ def __repr__(self):
360367
self.sda)
361368

362369
def capture_start(self, idle=False, start = START, abyte = BYTE, stop = STOP):
370+
"""Enter I2C capture mode, capturing I2C transactions.
371+
:param idle: If ``True`` the generator returns ``None`` when the bus is idle. If ``False`` the generator does nothing during bus idle.
372+
373+
:return: a generator which returns an object for each I2C primitive captured.
374+
"""
363375
self.__ser_w([ord('c')])
364376
def nstream():
365377
while True:

python/samples/mux.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import sys
2+
from i2cdriver import I2CDriver, EDS
3+
4+
# Using a TCA9548A Low-Voltage 8-Channel I2C Switch
5+
# Three LM75B temperature sensors are connected to
6+
# channels 0,1 and 2. All are at address 0x48.
7+
8+
class Mux:
9+
def __init__(self, i2, a = 0x70):
10+
self.i2 = i2
11+
self.a = a
12+
13+
def select(self, n):
14+
assert n in range(8)
15+
self.i2.start(self.a, 0)
16+
self.i2.write([1 << n])
17+
self.i2.stop()
18+
19+
if __name__ == '__main__':
20+
i2 = I2CDriver(sys.argv[1])
21+
22+
mux = Mux(i2)
23+
sensors = [
24+
(0, EDS.Temp(i2)),
25+
(1, EDS.Temp(i2)),
26+
(2, EDS.Temp(i2))
27+
]
28+
29+
# Reset all 8 channels
30+
for chan in range(8):
31+
mux.select(chan)
32+
i2.reset()
33+
34+
def read(chan, dev):
35+
mux.select(chan)
36+
celsius = dev.read()
37+
return celsius
38+
39+
while 1:
40+
print(" ".join(["%.1f" % read(chan, dev) for chan,dev in sensors]))

testall

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ python -c 'from i2cdriver import I2CDriver'
1414

1515
cd c
1616
make -f linux/Makefile
17+
make -f linux/Makefile.clang

0 commit comments

Comments
 (0)