aboutsummaryrefslogtreecommitdiffstats
path: root/klippy/extras/sx1509.py
diff options
context:
space:
mode:
Diffstat (limited to 'klippy/extras/sx1509.py')
-rw-r--r--klippy/extras/sx1509.py151
1 files changed, 103 insertions, 48 deletions
diff --git a/klippy/extras/sx1509.py b/klippy/extras/sx1509.py
index 070b9133..22a6c6a7 100644
--- a/klippy/extras/sx1509.py
+++ b/klippy/extras/sx1509.py
@@ -19,8 +19,26 @@ REG_ANALOG_DRIVER_ENABLE = 0x20
# Byte registers
-REG_I_ON = [0x2A, 0x2D, 0x30, 0x33, 0x36, 0x3B, 0x40, 0x45,
- 0x4A, 0x4D, 0x50, 0x53, 0x56, 0x5B, 0x5F, 0x65]
+REG_I_ON = [
+ 0x2A,
+ 0x2D,
+ 0x30,
+ 0x33,
+ 0x36,
+ 0x3B,
+ 0x40,
+ 0x45,
+ 0x4A,
+ 0x4D,
+ 0x50,
+ 0x53,
+ 0x56,
+ 0x5B,
+ 0x5F,
+ 0x65,
+]
+
+
class SX1509(object):
def __init__(self, config):
self._printer = config.get_printer()
@@ -33,58 +51,78 @@ class SX1509(object):
self._oid = self._i2c.get_oid()
self._last_clock = 0
# Set up registers default values
- self.reg_dict = {REG_DIR : 0xFFFF, REG_DATA : 0,
- REG_PULLUP : 0, REG_PULLDOWN : 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_dict = {
+ REG_DIR: 0xFFFF,
+ REG_DATA: 0,
+ REG_PULLUP: 0,
+ REG_PULLDOWN: 0,
+ REG_INPUT_DISABLE: 0,
+ REG_ANALOG_DRIVER_ENABLE: 0,
+ }
+ self.reg_i_on_dict = {reg: 0 for reg in REG_I_ON}
+
def _build_config(self):
# Reset the chip, Default RegClock/RegMisc 0x0
- self._mcu.add_config_cmd("i2c_write oid=%d data=%02x%02x" % (
- self._oid, REG_RESET, 0x12))
- self._mcu.add_config_cmd("i2c_write oid=%d data=%02x%02x" % (
- self._oid, REG_RESET, 0x34))
+ self._mcu.add_config_cmd(
+ "i2c_write oid=%d data=%02x%02x" % (self._oid, REG_RESET, 0x12)
+ )
+ self._mcu.add_config_cmd(
+ "i2c_write oid=%d data=%02x%02x" % (self._oid, REG_RESET, 0x34)
+ )
# Enable Oscillator
- self._mcu.add_config_cmd("i2c_write oid=%d data=%02x%02x" % (
- self._oid, REG_CLOCK, (1 << 6)))
+ self._mcu.add_config_cmd(
+ "i2c_write oid=%d data=%02x%02x" % (self._oid, REG_CLOCK, (1 << 6))
+ )
# Setup Clock Divider
- self._mcu.add_config_cmd("i2c_write oid=%d data=%02x%02x" % (
- self._oid, REG_MISC, (1 << 4)))
+ self._mcu.add_config_cmd(
+ "i2c_write oid=%d data=%02x%02x" % (self._oid, REG_MISC, (1 << 4))
+ )
# Transfer all regs with their initial cached state
for _reg, _data in self.reg_dict.items():
- self._mcu.add_config_cmd("i2c_write oid=%d data=%02x%04x" % (
- self._oid, _reg, _data), is_init=True)
+ self._mcu.add_config_cmd(
+ "i2c_write oid=%d data=%02x%04x" % (self._oid, _reg, _data),
+ is_init=True,
+ )
+
def setup_pin(self, pin_type, pin_params):
- if pin_type == 'digital_out' and pin_params['pin'][0:4] == "PIN_":
+ if pin_type == "digital_out" and pin_params["pin"][0:4] == "PIN_":
return SX1509_digital_out(self, pin_params)
- elif pin_type == 'pwm' and pin_params['pin'][0:4] == "PIN_":
+ elif pin_type == "pwm" and pin_params["pin"][0:4] == "PIN_":
return SX1509_pwm(self, pin_params)
- raise pins.error("Wrong pin or incompatible type: %s with type %s! " % (
- pin_params['pin'][0:4], pin_type))
+ raise pins.error(
+ "Wrong pin or incompatible type: %s with type %s! "
+ % (pin_params["pin"][0:4], pin_type)
+ )
+
def get_mcu(self):
return self._mcu
+
def get_oid(self):
return self._oid
+
def clear_bits_in_register(self, reg, bitmask):
if reg in self.reg_dict:
self.reg_dict[reg] &= ~(bitmask)
elif reg in self.reg_i_on_dict:
self.reg_i_on_dict[reg] &= ~(bitmask)
+
def set_bits_in_register(self, reg, bitmask):
if reg in self.reg_dict:
self.reg_dict[reg] |= bitmask
elif reg in self.reg_i_on_dict:
self.reg_i_on_dict[reg] |= bitmask
+
def set_register(self, reg, value):
if reg in self.reg_dict:
self.reg_dict[reg] = value
elif reg in self.reg_i_on_dict:
self.reg_i_on_dict[reg] = value
+
def send_register(self, reg, print_time):
data = [reg & 0xFF]
if reg in self.reg_dict:
# Word
- data += [(self.reg_dict[reg] >> 8) & 0xFF,
- self.reg_dict[reg] & 0xFF]
+ data += [(self.reg_dict[reg] >> 8) & 0xFF, self.reg_dict[reg] & 0xFF]
elif reg in self.reg_i_on_dict:
# Byte
data += [self.reg_i_on_dict[reg] & 0xFF]
@@ -92,27 +130,32 @@ class SX1509(object):
self._i2c.i2c_write(data, minclock=self._last_clock, reqclock=clock)
self._last_clock = clock
+
class SX1509_digital_out(object):
def __init__(self, sx1509, pin_params):
self._sx1509 = sx1509
self._mcu = sx1509.get_mcu()
- self._sxpin = int(pin_params['pin'].split('_')[1])
+ self._sxpin = int(pin_params["pin"].split("_")[1])
self._bitmask = 1 << self._sxpin
- self._pin = pin_params['pin']
- self._invert = pin_params['invert']
+ self._pin = pin_params["pin"]
+ self._invert = pin_params["invert"]
self._mcu.register_config_callback(self._build_config)
self._start_value = self._shutdown_value = self._invert
- self._max_duration = 2.
+ self._max_duration = 2.0
self._set_cmd = self._clear_cmd = None
# Set direction to output
self._sx1509.clear_bits_in_register(REG_DIR, self._bitmask)
+
def _build_config(self):
if self._max_duration:
raise pins.error("SX1509 pins are not suitable for heaters")
+
def get_mcu(self):
return self._mcu
+
def setup_max_duration(self, max_duration):
self._max_duration = max_duration
+
def setup_start_value(self, start_value, shutdown_value):
self._start_value = (not not start_value) ^ self._invert
self._shutdown_value = self._invert
@@ -122,70 +165,82 @@ class SX1509_digital_out(object):
self._sx1509.set_bits_in_register(REG_DATA, self._bitmask)
else:
self._sx1509.clear_bits_in_register(REG_DATA, self._bitmask)
+
def set_digital(self, print_time, value):
if int(value) ^ self._invert:
self._sx1509.set_bits_in_register(REG_DATA, self._bitmask)
else:
self._sx1509.clear_bits_in_register(REG_DATA, self._bitmask)
self._sx1509.send_register(REG_DATA, print_time)
+
def set_pwm(self, print_time, value, cycle_time=None):
self.set_digital(print_time, value >= 0.5)
+
class SX1509_pwm(object):
def __init__(self, sx1509, pin_params):
self._sx1509 = sx1509
self._mcu = sx1509.get_mcu()
- self._sxpin = int(pin_params['pin'].split('_')[1])
+ self._sxpin = int(pin_params["pin"].split("_")[1])
self._bitmask = 1 << self._sxpin
self._i_on_reg = REG_I_ON[self._sxpin]
- self._pin = pin_params['pin']
- self._invert = pin_params['invert']
+ self._pin = pin_params["pin"]
+ self._invert = pin_params["invert"]
self._mcu.register_config_callback(self._build_config)
self._start_value = self._shutdown_value = float(self._invert)
- self._max_duration = 2.
+ self._max_duration = 2.0
self._hardware_pwm = False
- self._pwm_max = 0.
+ self._pwm_max = 0.0
self._set_cmd = None
- self._cycle_time = 0.
+ self._cycle_time = 0.0
# Set required registers
self._sx1509.set_bits_in_register(REG_INPUT_DISABLE, self._bitmask)
self._sx1509.clear_bits_in_register(REG_PULLUP, self._bitmask)
self._sx1509.clear_bits_in_register(REG_DIR, self._bitmask)
- self._sx1509.set_bits_in_register(REG_ANALOG_DRIVER_ENABLE,
- self._bitmask)
+ self._sx1509.set_bits_in_register(REG_ANALOG_DRIVER_ENABLE, self._bitmask)
self._sx1509.clear_bits_in_register(REG_DATA, self._bitmask)
+
def _build_config(self):
if not self._hardware_pwm:
raise pins.error("SX1509_pwm must have hardware_pwm enabled")
if self._max_duration:
raise pins.error("SX1509 pins are not suitable for heaters")
# Send initial value
- self._sx1509.set_register(self._i_on_reg,
- ~int(255 * self._start_value) & 0xFF)
- self._mcu.add_config_cmd("i2c_write oid=%d data=%02x%02x" % (
- self._sx1509.get_oid(),
- self._i_on_reg,
- self._sx1509.reg_i_on_dict[self._i_on_reg]
+ self._sx1509.set_register(self._i_on_reg, ~int(255 * self._start_value) & 0xFF)
+ self._mcu.add_config_cmd(
+ "i2c_write oid=%d data=%02x%02x"
+ % (
+ self._sx1509.get_oid(),
+ self._i_on_reg,
+ self._sx1509.reg_i_on_dict[self._i_on_reg],
),
- is_init=True)
+ is_init=True,
+ )
+
def get_mcu(self):
return self._mcu
+
def setup_max_duration(self, max_duration):
self._max_duration = max_duration
+
def setup_cycle_time(self, cycle_time, hardware_pwm=False):
self._cycle_time = cycle_time
self._hardware_pwm = hardware_pwm
+
def setup_start_value(self, start_value, shutdown_value):
if self._invert:
- start_value = 1. - start_value
- shutdown_value = 1. - shutdown_value
- self._start_value = max(0., min(1., start_value))
- self._shutdown_value = max(0., min(1., shutdown_value))
+ start_value = 1.0 - start_value
+ shutdown_value = 1.0 - shutdown_value
+ self._start_value = max(0.0, min(1.0, start_value))
+ self._shutdown_value = max(0.0, min(1.0, shutdown_value))
+
def set_pwm(self, print_time, value):
- self._sx1509.set_register(self._i_on_reg, ~int(255 * value)
- if not self._invert
- else int(255 * value) & 0xFF)
+ self._sx1509.set_register(
+ self._i_on_reg,
+ ~int(255 * value) if not self._invert else int(255 * value) & 0xFF,
+ )
self._sx1509.send_register(self._i_on_reg, print_time)
+
def load_config_prefix(config):
return SX1509(config)