Merge branch 'master' of github.com:jamesbowman/i2cdriver
This commit is contained in:
commit
418473e362
|
@ -18,7 +18,9 @@
|
||||||
|
|
||||||
#if defined(WIN32) // {
|
#if defined(WIN32) // {
|
||||||
|
|
||||||
|
#ifndef NOMINMAX
|
||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
|
#endif
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
void ErrorExit(const char *func_name)
|
void ErrorExit(const char *func_name)
|
||||||
|
@ -323,7 +325,7 @@ uint8_t i2c_reset(I2CDriver *sd)
|
||||||
|
|
||||||
int i2c_start(I2CDriver *sd, uint8_t dev, uint8_t op)
|
int i2c_start(I2CDriver *sd, uint8_t dev, uint8_t op)
|
||||||
{
|
{
|
||||||
uint8_t start[2] = {'s', (dev << 1) | op};
|
uint8_t start[2] = {'s', (uint8_t)((dev << 1) | op)};
|
||||||
writeToSerialPort(sd->port, start, sizeof(start));
|
writeToSerialPort(sd->port, start, sizeof(start));
|
||||||
return i2c_ack(sd);
|
return i2c_ack(sd);
|
||||||
}
|
}
|
||||||
|
@ -367,6 +369,56 @@ void i2c_monitor(I2CDriver *sd, int enable)
|
||||||
charCommand(sd, enable ? 'm' : '@');
|
charCommand(sd, enable ? 'm' : '@');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void i2c_capture(I2CDriver *sd)
|
||||||
|
{
|
||||||
|
printf("Capture started\n");
|
||||||
|
charCommand(sd, 'c');
|
||||||
|
uint8_t bytes[1];
|
||||||
|
|
||||||
|
int starting = 0;
|
||||||
|
int nbits = 0, bits = 0;
|
||||||
|
while (1) {
|
||||||
|
int i;
|
||||||
|
readFromSerialPort(sd->port, bytes, 1);
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
int symbol = (i == 0) ? (bytes[0] >> 4) : (bytes[0] & 0xf);
|
||||||
|
switch (symbol) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
starting = 1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
printf("STOP\n");
|
||||||
|
starting = 1;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
case 12:
|
||||||
|
case 13:
|
||||||
|
case 14:
|
||||||
|
case 15:
|
||||||
|
bits = (bits << 3) | (symbol & 7);
|
||||||
|
nbits += 3;
|
||||||
|
if (nbits == 9) {
|
||||||
|
int b8 = (bits >> 1), ack = !(bits & 1);
|
||||||
|
if (starting) {
|
||||||
|
starting = 0;
|
||||||
|
printf("START %02x %s", b8 >> 1, (b8 & 1) ? "READ" : "WRITE");
|
||||||
|
} else {
|
||||||
|
printf("BYTE %02x", b8);
|
||||||
|
}
|
||||||
|
printf(" %s\n", ack ? "ACK" : "NAK");
|
||||||
|
nbits = 0;
|
||||||
|
bits = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int i2c_commands(I2CDriver *sd, int argc, char *argv[])
|
int i2c_commands(I2CDriver *sd, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -479,6 +531,12 @@ int i2c_commands(I2CDriver *sd, int argc, char *argv[])
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'c':
|
||||||
|
{
|
||||||
|
i2c_capture(sd);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
badcommand:
|
badcommand:
|
||||||
fprintf(stderr, "Bad command '%s'\n", token);
|
fprintf(stderr, "Bad command '%s'\n", token);
|
||||||
|
@ -492,6 +550,7 @@ int i2c_commands(I2CDriver *sd, int argc, char *argv[])
|
||||||
fprintf(stderr, " p send a STOP\n");
|
fprintf(stderr, " p send a STOP\n");
|
||||||
fprintf(stderr, " r dev N read N bytes from I2C device dev, then STOP\n");
|
fprintf(stderr, " r dev N read N bytes from I2C device dev, then STOP\n");
|
||||||
fprintf(stderr, " m enter I2C bus monitor mode\n");
|
fprintf(stderr, " m enter I2C bus monitor mode\n");
|
||||||
|
fprintf(stderr, " c enter I2C bus capture mode\n");
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -36,6 +36,7 @@ int i2c_start(I2CDriver *sd, uint8_t dev, uint8_t op);
|
||||||
void i2c_stop(I2CDriver *sd);
|
void i2c_stop(I2CDriver *sd);
|
||||||
|
|
||||||
void i2c_monitor(I2CDriver *sd, int enable);
|
void i2c_monitor(I2CDriver *sd, int enable);
|
||||||
|
void i2c_capture(I2CDriver *sd);
|
||||||
|
|
||||||
int i2c_commands(I2CDriver *sd, int argc, char *argv[]);
|
int i2c_commands(I2CDriver *sd, int argc, char *argv[]);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
CC=clang
|
||||||
|
CFLAGS += -I common -Wall -Wpointer-sign -xc++ -std=c++17 # -Werror
|
||||||
|
|
||||||
|
all: build/i2ccl
|
||||||
|
|
||||||
|
install: all
|
||||||
|
cp build/i2ccl /usr/local/bin
|
||||||
|
|
||||||
|
build/i2ccl: linux/i2c.c common/i2cdriver.c
|
||||||
|
mkdir -p build/
|
||||||
|
$(CC) -o $@ $(CPPFLAGS) $(CFLAGS) $^
|
|
@ -68,7 +68,15 @@ class I2CDriver:
|
||||||
"""
|
"""
|
||||||
A connected I2CDriver.
|
A connected I2CDriver.
|
||||||
|
|
||||||
:ivar product: product code e.g. 'i2cdriver1'
|
:param port: The USB port to connect to
|
||||||
|
:type port: str
|
||||||
|
:param reset: Issue an I2C bus reset on connection
|
||||||
|
:type reset: bool
|
||||||
|
|
||||||
|
After connection, the following object variables reflect the current values of the I2CDriver.
|
||||||
|
They are updated by calling :py:meth:`getstatus`.
|
||||||
|
|
||||||
|
:ivar product: product code e.g. 'i2cdriver1' or 'i2cdriverm'
|
||||||
:ivar serial: serial string of I2CDriver
|
:ivar serial: serial string of I2CDriver
|
||||||
:ivar uptime: time since I2CDriver boot, in seconds
|
:ivar uptime: time since I2CDriver boot, in seconds
|
||||||
:ivar voltage: USB voltage, in V
|
:ivar voltage: USB voltage, in V
|
||||||
|
@ -269,7 +277,7 @@ class I2CDriver:
|
||||||
:param reg: register address 0-255
|
:param reg: register address 0-255
|
||||||
:param fmt: :py:func:`struct.unpack` format string for the register contents, or an integer byte count
|
:param fmt: :py:func:`struct.unpack` format string for the register contents, or an integer byte count
|
||||||
|
|
||||||
If device 0x75 has a 16-bit register 102, it can be read with:
|
If device 0x75 has a 16-bit unsigned big-endian register 102, it can be read with:
|
||||||
|
|
||||||
>>> i2c.regrd(0x75, 102, ">H")
|
>>> i2c.regrd(0x75, 102, ">H")
|
||||||
4999
|
4999
|
||||||
|
@ -335,7 +343,6 @@ class I2CDriver:
|
||||||
self.__echo(0x40)
|
self.__echo(0x40)
|
||||||
|
|
||||||
def introspect(self):
|
def introspect(self):
|
||||||
""" Update all status variables """
|
|
||||||
self.ser.write(b'J')
|
self.ser.write(b'J')
|
||||||
r = self.ser.read(80)
|
r = self.ser.read(80)
|
||||||
assert len(r) == 80, r
|
assert len(r) == 80, r
|
||||||
|
@ -360,6 +367,11 @@ class I2CDriver:
|
||||||
self.sda)
|
self.sda)
|
||||||
|
|
||||||
def capture_start(self, idle=False, start = START, abyte = BYTE, stop = STOP):
|
def capture_start(self, idle=False, start = START, abyte = BYTE, stop = STOP):
|
||||||
|
"""Enter I2C capture mode, capturing I2C transactions.
|
||||||
|
:param idle: If ``True`` the generator returns ``None`` when the bus is idle. If ``False`` the generator does nothing during bus idle.
|
||||||
|
|
||||||
|
:return: a generator which returns an object for each I2C primitive captured.
|
||||||
|
"""
|
||||||
self.__ser_w([ord('c')])
|
self.__ser_w([ord('c')])
|
||||||
def nstream():
|
def nstream():
|
||||||
while True:
|
while True:
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
import sys
|
||||||
|
from i2cdriver import I2CDriver, EDS
|
||||||
|
|
||||||
|
# Using a TCA9548A Low-Voltage 8-Channel I2C Switch
|
||||||
|
# Three LM75B temperature sensors are connected to
|
||||||
|
# channels 0,1 and 2. All are at address 0x48.
|
||||||
|
|
||||||
|
class Mux:
|
||||||
|
def __init__(self, i2, a = 0x70):
|
||||||
|
self.i2 = i2
|
||||||
|
self.a = a
|
||||||
|
|
||||||
|
def select(self, n):
|
||||||
|
assert n in range(8)
|
||||||
|
self.i2.start(self.a, 0)
|
||||||
|
self.i2.write([1 << n])
|
||||||
|
self.i2.stop()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
i2 = I2CDriver(sys.argv[1])
|
||||||
|
|
||||||
|
mux = Mux(i2)
|
||||||
|
sensors = [
|
||||||
|
(0, EDS.Temp(i2)),
|
||||||
|
(1, EDS.Temp(i2)),
|
||||||
|
(2, EDS.Temp(i2))
|
||||||
|
]
|
||||||
|
|
||||||
|
# Reset all 8 channels
|
||||||
|
for chan in range(8):
|
||||||
|
mux.select(chan)
|
||||||
|
i2.reset()
|
||||||
|
|
||||||
|
def read(chan, dev):
|
||||||
|
mux.select(chan)
|
||||||
|
celsius = dev.read()
|
||||||
|
return celsius
|
||||||
|
|
||||||
|
while 1:
|
||||||
|
print(" ".join(["%.1f" % read(chan, dev) for chan,dev in sensors]))
|
Loading…
Reference in New Issue