aboutsummaryrefslogtreecommitdiffstats
path: root/klippy/extras/ldc1612.py
diff options
context:
space:
mode:
Diffstat (limited to 'klippy/extras/ldc1612.py')
-rw-r--r--klippy/extras/ldc1612.py163
1 files changed, 102 insertions, 61 deletions
diff --git a/klippy/extras/ldc1612.py b/klippy/extras/ldc1612.py
index dd41b43a..1bec5c35 100644
--- a/klippy/extras/ldc1612.py
+++ b/klippy/extras/ldc1612.py
@@ -10,53 +10,63 @@ MIN_MSG_TIME = 0.100
BATCH_UPDATES = 0.100
-LDC1612_ADDR = 0x2a
+LDC1612_ADDR = 0x2A
DEFAULT_LDC1612_FREQ = 12000000
SETTLETIME = 0.005
DRIVECUR = 15
-DEGLITCH = 0x05 # 10 Mhz
+DEGLITCH = 0x05 # 10 Mhz
LDC1612_MANUF_ID = 0x5449
LDC1612_DEV_ID = 0x3055
REG_RCOUNT0 = 0x08
-REG_OFFSET0 = 0x0c
+REG_OFFSET0 = 0x0C
REG_SETTLECOUNT0 = 0x10
REG_CLOCK_DIVIDERS0 = 0x14
REG_ERROR_CONFIG = 0x19
-REG_CONFIG = 0x1a
-REG_MUX_CONFIG = 0x1b
-REG_DRIVE_CURRENT0 = 0x1e
-REG_MANUFACTURER_ID = 0x7e
-REG_DEVICE_ID = 0x7f
+REG_CONFIG = 0x1A
+REG_MUX_CONFIG = 0x1B
+REG_DRIVE_CURRENT0 = 0x1E
+REG_MANUFACTURER_ID = 0x7E
+REG_DEVICE_ID = 0x7F
+
# Tool for determining appropriate DRIVE_CURRENT register
class DriveCurrentCalibrate:
def __init__(self, config, sensor):
self.printer = config.get_printer()
self.sensor = sensor
- self.drive_cur = config.getint("reg_drive_current", DRIVECUR,
- minval=0, maxval=31)
+ self.drive_cur = config.getint(
+ "reg_drive_current", DRIVECUR, minval=0, maxval=31
+ )
self.name = config.get_name()
- gcode = self.printer.lookup_object('gcode')
- gcode.register_mux_command("LDC_CALIBRATE_DRIVE_CURRENT",
- "CHIP", self.name.split()[-1],
- self.cmd_LDC_CALIBRATE,
- desc=self.cmd_LDC_CALIBRATE_help)
+ gcode = self.printer.lookup_object("gcode")
+ gcode.register_mux_command(
+ "LDC_CALIBRATE_DRIVE_CURRENT",
+ "CHIP",
+ self.name.split()[-1],
+ self.cmd_LDC_CALIBRATE,
+ desc=self.cmd_LDC_CALIBRATE_help,
+ )
+
def get_drive_current(self):
return self.drive_cur
+
cmd_LDC_CALIBRATE_help = "Calibrate LDC1612 DRIVE_CURRENT register"
+
def cmd_LDC_CALIBRATE(self, gcmd):
is_in_progress = True
+
def handle_batch(msg):
return is_in_progress
+
self.sensor.add_client(handle_batch)
toolhead = self.printer.lookup_object("toolhead")
toolhead.dwell(0.100)
toolhead.wait_moves()
old_config = self.sensor.read_reg(REG_CONFIG)
- self.sensor.set_reg(REG_CONFIG, 0x001 | (1<<9))
+ self.sensor.set_reg(REG_CONFIG, 0x001 | (1 << 9))
toolhead.wait_moves()
toolhead.dwell(0.100)
toolhead.wait_moves()
@@ -64,13 +74,15 @@ class DriveCurrentCalibrate:
self.sensor.set_reg(REG_CONFIG, old_config)
is_in_progress = False
# Report found value to user
- drive_cur = (reg_drive_current0 >> 6) & 0x1f
+ drive_cur = (reg_drive_current0 >> 6) & 0x1F
gcmd.respond_info(
"%s: reg_drive_current: %d\n"
"The SAVE_CONFIG command will update the printer config file\n"
- "with the above and restart the printer." % (self.name, drive_cur))
- configfile = self.printer.lookup_object('configfile')
- configfile.set(self.name, 'reg_drive_current', "%d" % (drive_cur,))
+ "with the above and restart the printer." % (self.name, drive_cur)
+ )
+ configfile = self.printer.lookup_object("configfile")
+ configfile.set(self.name, "reg_drive_current", "%d" % (drive_cur,))
+
# Interface class to LDC1612 mcu support
class LDC1612:
@@ -80,28 +92,32 @@ class LDC1612:
self.dccal = DriveCurrentCalibrate(config, self)
self.data_rate = 250
# Setup mcu sensor_ldc1612 bulk query code
- self.i2c = bus.MCU_I2C_from_config(config,
- default_addr=LDC1612_ADDR,
- default_speed=400000)
+ self.i2c = bus.MCU_I2C_from_config(
+ config, default_addr=LDC1612_ADDR, default_speed=400000
+ )
self.mcu = mcu = self.i2c.get_mcu()
self.oid = oid = mcu.create_oid()
self.query_ldc1612_cmd = None
self.ldc1612_setup_home_cmd = self.query_ldc1612_home_state_cmd = None
- self.frequency = config.getint("frequency", DEFAULT_LDC1612_FREQ,
- 2000000, 40000000)
- if config.get('intb_pin', None) is not None:
+ self.frequency = config.getint(
+ "frequency", DEFAULT_LDC1612_FREQ, 2000000, 40000000
+ )
+ if config.get("intb_pin", None) is not None:
ppins = config.get_printer().lookup_object("pins")
- pin_params = ppins.lookup_pin(config.get('intb_pin'))
- if pin_params['chip'] != mcu:
+ pin_params = ppins.lookup_pin(config.get("intb_pin"))
+ if pin_params["chip"] != mcu:
raise config.error("ldc1612 intb_pin must be on same mcu")
mcu.add_config_cmd(
"config_ldc1612_with_intb oid=%d i2c_oid=%d intb_pin=%s"
- % (oid, self.i2c.get_oid(), pin_params['pin']))
+ % (oid, self.i2c.get_oid(), pin_params["pin"])
+ )
else:
- mcu.add_config_cmd("config_ldc1612 oid=%d i2c_oid=%d"
- % (oid, self.i2c.get_oid()))
- mcu.add_config_cmd("query_ldc1612 oid=%d rest_ticks=0"
- % (oid,), on_restart=True)
+ mcu.add_config_cmd(
+ "config_ldc1612 oid=%d i2c_oid=%d" % (oid, self.i2c.get_oid())
+ )
+ mcu.add_config_cmd(
+ "query_ldc1612 oid=%d rest_ticks=0" % (oid,), on_restart=True
+ )
mcu.register_config_callback(self._build_config)
# Bulk sample message reading
chip_smooth = self.data_rate * BATCH_UPDATES * 2
@@ -109,60 +125,79 @@ class LDC1612:
self.last_error_count = 0
# Process messages in batches
self.batch_bulk = bulk_sensor.BatchBulkHelper(
- self.printer, self._process_batch,
- self._start_measurements, self._finish_measurements, BATCH_UPDATES)
+ self.printer,
+ self._process_batch,
+ self._start_measurements,
+ self._finish_measurements,
+ BATCH_UPDATES,
+ )
self.name = config.get_name().split()[-1]
- hdr = ('time', 'frequency', 'z')
- self.batch_bulk.add_mux_endpoint("ldc1612/dump_ldc1612", "sensor",
- self.name, {'header': hdr})
+ hdr = ("time", "frequency", "z")
+ self.batch_bulk.add_mux_endpoint(
+ "ldc1612/dump_ldc1612", "sensor", self.name, {"header": hdr}
+ )
+
def _build_config(self):
cmdqueue = self.i2c.get_command_queue()
self.query_ldc1612_cmd = self.mcu.lookup_command(
- "query_ldc1612 oid=%c rest_ticks=%u", cq=cmdqueue)
- self.ffreader.setup_query_command("query_status_ldc1612 oid=%c",
- oid=self.oid, cq=cmdqueue)
+ "query_ldc1612 oid=%c rest_ticks=%u", cq=cmdqueue
+ )
+ self.ffreader.setup_query_command(
+ "query_status_ldc1612 oid=%c", oid=self.oid, cq=cmdqueue
+ )
self.ldc1612_setup_home_cmd = self.mcu.lookup_command(
"ldc1612_setup_home oid=%c clock=%u threshold=%u"
- " trsync_oid=%c trigger_reason=%c error_reason=%c", cq=cmdqueue)
+ " trsync_oid=%c trigger_reason=%c error_reason=%c",
+ cq=cmdqueue,
+ )
self.query_ldc1612_home_state_cmd = self.mcu.lookup_query_command(
"query_ldc1612_home_state oid=%c",
"ldc1612_home_state oid=%c homing=%c trigger_clock=%u",
- oid=self.oid, cq=cmdqueue)
+ oid=self.oid,
+ cq=cmdqueue,
+ )
+
def get_mcu(self):
return self.i2c.get_mcu()
+
def read_reg(self, reg):
params = self.i2c.i2c_read([reg], 2)
- response = bytearray(params['response'])
+ response = bytearray(params["response"])
return (response[0] << 8) | response[1]
+
def set_reg(self, reg, val, minclock=0):
- self.i2c.i2c_write([reg, (val >> 8) & 0xff, val & 0xff],
- minclock=minclock)
+ self.i2c.i2c_write([reg, (val >> 8) & 0xFF, val & 0xFF], minclock=minclock)
+
def add_client(self, cb):
self.batch_bulk.add_client(cb)
+
# Homing
- def setup_home(self, print_time, trigger_freq,
- trsync_oid, hit_reason, err_reason):
+ def setup_home(self, print_time, trigger_freq, trsync_oid, hit_reason, err_reason):
clock = self.mcu.print_time_to_clock(print_time)
- tfreq = int(trigger_freq * (1<<28) / float(self.frequency) + 0.5)
+ tfreq = int(trigger_freq * (1 << 28) / float(self.frequency) + 0.5)
self.ldc1612_setup_home_cmd.send(
- [self.oid, clock, tfreq, trsync_oid, hit_reason, err_reason])
+ [self.oid, clock, tfreq, trsync_oid, hit_reason, err_reason]
+ )
+
def clear_home(self):
self.ldc1612_setup_home_cmd.send([self.oid, 0, 0, 0, 0, 0])
if self.mcu.is_fileoutput():
- return 0.
+ return 0.0
params = self.query_ldc1612_home_state_cmd.send([self.oid])
- tclock = self.mcu.clock32_to_clock64(params['trigger_clock'])
+ tclock = self.mcu.clock32_to_clock64(params["trigger_clock"])
return self.mcu.clock_to_print_time(tclock)
+
# Measurement decoding
def _convert_samples(self, samples):
- freq_conv = float(self.frequency) / (1<<28)
+ freq_conv = float(self.frequency) / (1 << 28)
count = 0
for ptime, val in samples:
- mv = val & 0x0fffffff
+ mv = val & 0x0FFFFFFF
if mv != val:
self.last_error_count += 1
samples[count] = (round(ptime, 6), round(freq_conv * mv, 3), 999.9)
count += 1
+
# Start, stop, and process message batches
def _start_measurements(self):
# In case of miswiring, testing LDC1612 device ID prevents treating
@@ -174,16 +209,17 @@ class LDC1612:
"Invalid ldc1612 id (got %x,%x vs %x,%x).\n"
"This is generally indicative of connection problems\n"
"(e.g. faulty wiring) or a faulty ldc1612 chip."
- % (manuf_id, dev_id, LDC1612_MANUF_ID, LDC1612_DEV_ID))
+ % (manuf_id, dev_id, LDC1612_MANUF_ID, LDC1612_DEV_ID)
+ )
# Setup chip in requested query rate
- rcount0 = self.frequency / (16. * (self.data_rate - 4))
+ rcount0 = self.frequency / (16.0 * (self.data_rate - 4))
self.set_reg(REG_RCOUNT0, int(rcount0 + 0.5))
self.set_reg(REG_OFFSET0, 0)
- self.set_reg(REG_SETTLECOUNT0, int(SETTLETIME*self.frequency/16. + .5))
+ self.set_reg(REG_SETTLECOUNT0, int(SETTLETIME * self.frequency / 16.0 + 0.5))
self.set_reg(REG_CLOCK_DIVIDERS0, (1 << 12) | 1)
- self.set_reg(REG_ERROR_CONFIG, (0x1f << 11) | 1)
+ self.set_reg(REG_ERROR_CONFIG, (0x1F << 11) | 1)
self.set_reg(REG_MUX_CONFIG, 0x0208 | DEGLITCH)
- self.set_reg(REG_CONFIG, 0x001 | (1<<12) | (1<<10) | (1<<9))
+ self.set_reg(REG_CONFIG, 0x001 | (1 << 12) | (1 << 10) | (1 << 9))
self.set_reg(REG_DRIVE_CURRENT0, self.dccal.get_drive_current() << 11)
# Start bulk reading
rest_ticks = self.mcu.seconds_to_clock(0.5 / self.data_rate)
@@ -192,11 +228,13 @@ class LDC1612:
# Initialize clock tracking
self.ffreader.note_start()
self.last_error_count = 0
+
def _finish_measurements(self):
# Halt bulk reading
self.query_ldc1612_cmd.send_wait_ack([self.oid, 0])
self.ffreader.note_end()
logging.info("LDC1612 finished '%s' measurements", self.name)
+
def _process_batch(self, eventtime):
samples = self.ffreader.pull_samples()
self._convert_samples(samples)
@@ -204,5 +242,8 @@ class LDC1612:
return {}
if self.calibration is not None:
self.calibration.apply_calibration(samples)
- return {'data': samples, 'errors': self.last_error_count,
- 'overflows': self.ffreader.get_last_overflows()}
+ return {
+ "data": samples,
+ "errors": self.last_error_count,
+ "overflows": self.ffreader.get_last_overflows(),
+ }