i2ccmds: Pass the i2c address as a 7-bit number (0-127)

The sam3 i2c code and the linux code use a 7-bit i2c address, while
the avr, lpc176x, and samd21 i2c code uses an 8-bit address with the
least significant bit always zero.  A similar issue occurred in the
host code (sx1509.py and replicape.py use 7-bit addresses while
uc1701.py and mcp4451.py use 8-bit addresses).

Consistently use 7-bit addresses in all the code.  This breaks
compatibility between host and mcu software, so make a change to the
config_i2c command to force users to synchronize software updates.
This also breaks common Smoothieboard configs, so update the mcp4451
code to validate the i2c_address.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2018-12-27 19:11:46 -05:00 committed by KevinOConnor
parent f2f54290e8
commit e26d1a3567
10 changed files with 28 additions and 17 deletions

View File

@ -90,7 +90,7 @@ max_z_accel: 100
pins: P1.18, P1.19, P1.20, P1.21, P4.28 pins: P1.18, P1.19, P1.20, P1.21, P4.28
[mcp4451 stepper_digipot1] [mcp4451 stepper_digipot1]
i2c_address: 88 i2c_address: 44
# Scale the config so that wiper values can be specified in amps. # Scale the config so that wiper values can be specified in amps.
scale: 2.25 scale: 2.25
# wiper 0 is X (aka alpha), 1 is Y, 2 is Z, 3 is E0 # wiper 0 is X (aka alpha), 1 is Y, 2 is Z, 3 is E0
@ -100,7 +100,7 @@ wiper_2: 1.0
wiper_3: 1.0 wiper_3: 1.0
[mcp4451 stepper_digipot2] [mcp4451 stepper_digipot2]
i2c_address: 90 i2c_address: 45
scale: 2.25 scale: 2.25
# wiper 0 is E1 # wiper 0 is E1
wiper_0: 1.0 wiper_0: 1.0

View File

@ -6,4 +6,9 @@ All dates in this document are approximate.
# Changes # Changes
20190107: The i2c_address parameter in the mcp4451 config section
changed. This is a common setting on Smoothieboards. The new value is
half the old value (88 should be changed to 44, and 90 should be
changed to 45).
20181220: Klipper v0.7.0 released 20181220: Klipper v0.7.0 released

View File

@ -83,9 +83,11 @@ def MCU_SPI_from_config(config, mode, pin_option="cs_pin",
class MCU_I2C: class MCU_I2C:
def __init__(self, mcu, bus, addr, speed): def __init__(self, mcu, bus, addr, speed):
self.mcu = mcu self.mcu = mcu
self.i2c_address = addr
self.oid = self.mcu.create_oid() self.oid = self.mcu.create_oid()
self.mcu.add_config_cmd("config_i2c oid=%d bus=%d rate=%d addr=%d" % ( self.mcu.add_config_cmd(
self.oid, bus, speed, addr)) "config_i2c oid=%d bus=%d rate=%d address=%d" % (
self.oid, bus, speed, addr))
self.cmd_queue = self.mcu.alloc_command_queue() self.cmd_queue = self.mcu.alloc_command_queue()
self.mcu.register_config_callback(self.build_config) self.mcu.register_config_callback(self.build_config)
self.i2c_write_cmd = self.i2c_read_cmd = self.i2c_modify_bits_cmd = None self.i2c_write_cmd = self.i2c_read_cmd = self.i2c_modify_bits_cmd = None
@ -93,6 +95,8 @@ class MCU_I2C:
return self.oid return self.oid
def get_mcu(self): def get_mcu(self):
return self.mcu return self.mcu
def get_i2c_address(self):
return self.i2c_address
def get_command_queue(self): def get_command_queue(self):
return self.cmd_queue return self.cmd_queue
def build_config(self): def build_config(self):
@ -136,8 +140,8 @@ def MCU_I2C_from_config(config, default_addr=None, default_speed=100000):
speed = config.getint('i2c_speed', default_speed, minval=100000) speed = config.getint('i2c_speed', default_speed, minval=100000)
bus = config.getint('i2c_bus', 0, minval=0) bus = config.getint('i2c_bus', 0, minval=0)
if default_addr is None: if default_addr is None:
addr = config.getint('i2c_address') addr = config.getint('i2c_address', minval=0, maxval=127)
else: else:
addr = config.getint('i2c_address', default_addr) addr = config.getint('i2c_address', default_addr, minval=0, maxval=127)
# Create MCU_I2C object # Create MCU_I2C object
return MCU_I2C(i2c_mcu, bus, addr, speed) return MCU_I2C(i2c_mcu, bus, addr, speed)

View File

@ -177,11 +177,11 @@ class UC1701(DisplayBase):
logging.info("uc1701 initialized") logging.info("uc1701 initialized")
# The SSD1306 supports both i2c and "4-wire" spi # The SSD1306 supports both i2c and "4-wire" spi
class SSD1306(UC1701): class SSD1306(DisplayBase):
def __init__(self, config): def __init__(self, config):
cs_pin = config.get("cs_pin", None) cs_pin = config.get("cs_pin", None)
if cs_pin is None: if cs_pin is None:
io = I2C(config, 120) io = I2C(config, 60)
else: else:
io = SPI4wire(config, "dc_pin") io = SPI4wire(config, "dc_pin")
DisplayBase.__init__(self, io) DisplayBase.__init__(self, io)

View File

@ -10,6 +10,9 @@ WiperRegisters = [0x00, 0x01, 0x06, 0x07]
class mcp4451: class mcp4451:
def __init__(self, config): def __init__(self, config):
self.i2c = bus.MCU_I2C_from_config(config) self.i2c = bus.MCU_I2C_from_config(config)
i2c_addr = self.i2c.get_i2c_address()
if i2c_addr < 44 or i2c_addr > 47:
raise config.error("mcp4451 address must be between 44 and 47")
scale = config.getfloat('scale', 1., above=0.) scale = config.getfloat('scale', 1., above=0.)
# Configure registers # Configure registers
self.set_register(0x04, 0xff) self.set_register(0x04, 0xff)

View File

@ -41,8 +41,9 @@ class SX1509(object):
REG_INPUT_DISABLE : 0, REG_ANALOG_DRIVER_ENABLE : 0} REG_INPUT_DISABLE : 0, REG_ANALOG_DRIVER_ENABLE : 0}
self.reg_i_on_dict = {reg : 0 for reg in REG_I_ON} self.reg_i_on_dict = {reg : 0 for reg in REG_I_ON}
def _build_config(self): def _build_config(self):
self._mcu.add_config_cmd("config_i2c oid=%d bus=%d rate=%d addr=%d" % ( self._mcu.add_config_cmd(
self._oid, self._bus, self._freq, self._chip_address)) "config_i2c oid=%d bus=%d rate=%d address=%d" % (
self._oid, self._bus, self._freq, self._chip_address))
# Reset the chip # Reset the chip
self._mcu.add_config_cmd("i2c_write oid=%d data=%02x%02x" % ( self._mcu.add_config_cmd("i2c_write oid=%d data=%02x%02x" % (
self._oid, REG_RESET, 0x12)) self._oid, REG_RESET, 0x12))

View File

@ -45,7 +45,7 @@ i2c_setup(uint32_t bus, uint32_t rate, uint8_t addr)
if (bus) if (bus)
shutdown("Unsupported i2c bus"); shutdown("Unsupported i2c bus");
i2c_init(); i2c_init();
return (struct i2c_config){ .addr=addr }; return (struct i2c_config){ .addr=addr<<1 };
} }
static void static void

View File

@ -16,15 +16,13 @@ struct i2cdev_s {
void void
command_config_i2c(uint32_t *args) command_config_i2c(uint32_t *args)
{ {
uint8_t addr = args[3]; uint8_t addr = args[3] & 0x7f;
if (addr & 1)
shutdown("Invalid I2C address");
struct i2cdev_s *i2c = oid_alloc(args[0], command_config_i2c struct i2cdev_s *i2c = oid_alloc(args[0], command_config_i2c
, sizeof(*i2c)); , sizeof(*i2c));
i2c->i2c_config = i2c_setup(args[1], args[2], addr); i2c->i2c_config = i2c_setup(args[1], args[2], addr);
} }
DECL_COMMAND(command_config_i2c, DECL_COMMAND(command_config_i2c,
"config_i2c oid=%c bus=%u rate=%u addr=%u"); "config_i2c oid=%c bus=%u rate=%u address=%u");
void void
command_i2c_write(uint32_t *args) command_i2c_write(uint32_t *args)

View File

@ -45,7 +45,7 @@ i2c_setup(uint32_t bus, uint32_t rate, uint8_t addr)
if (bus) if (bus)
shutdown("Unsupported i2c bus"); shutdown("Unsupported i2c bus");
i2c_init(); i2c_init();
return (struct i2c_config){ .addr=addr }; return (struct i2c_config){ .addr=addr<<1 };
} }
static void static void

View File

@ -57,7 +57,7 @@ i2c_setup(uint32_t bus, uint32_t rate, uint8_t addr)
if (bus) if (bus)
shutdown("Unsupported i2c bus"); shutdown("Unsupported i2c bus");
i2c_init(); i2c_init();
return (struct i2c_config){ .addr=addr }; return (struct i2c_config){ .addr=addr<<1 };
} }
static void static void