diff --git a/klippy/extras/ldc1612.py b/klippy/extras/ldc1612.py index db539c650..085dc2a55 100644 --- a/klippy/extras/ldc1612.py +++ b/klippy/extras/ldc1612.py @@ -87,7 +87,6 @@ class LDC1612: self._sensor_errors = {} self.oid = oid = mcu.create_oid() self.query_ldc1612_cmd = None - self.ldc1612_setup_home_cmd = self.query_ldc1612_home_state_cmd = None self.clock_freq = config.getint("frequency", DEFAULT_LDC1612_FREQ, 2000000, 40000000) # Coil frequency divider, assume 12MHz is BTT Eddy @@ -120,23 +119,22 @@ class LDC1612: hdr = ('time', 'frequency', 'z') self.batch_bulk.add_mux_endpoint("ldc1612/dump_ldc1612", "sensor", self.name, {'header': hdr}) + def setup_trigger_analog(self, trigger_analog_oid): + self.mcu.add_config_cmd( + "ldc1612_attach_trigger_analog oid=%d trigger_analog_oid=%d" + % (self.oid, trigger_analog_oid), is_init=True) 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) - 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) - 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) errors = self.mcu.get_enumerations().get("ldc1612_error:", {}) self._sensor_errors = {v: k for k, v in errors.items()} def get_mcu(self): return self.i2c.get_mcu() + def get_samples_per_second(self): + return self.data_rate def read_reg(self, reg): if self.mcu.is_fileoutput(): return 0 @@ -148,20 +146,10 @@ class LDC1612: 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): - clock = self.mcu.print_time_to_clock(print_time) - tfreq = int(trigger_freq / self.freq_conv + 0.5) - self.ldc1612_setup_home_cmd.send( - [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]) - params = self.query_ldc1612_home_state_cmd.send([self.oid]) - tclock = self.mcu.clock32_to_clock64(params['trigger_clock']) - return self.mcu.clock_to_print_time(tclock) def lookup_sensor_error(self, error): return self._sensor_errors.get(error, "Unknown ldc1612 error") + def convert_frequency(self, freq): + return int(freq / self.freq_conv + 0.5) # Measurement decoding def _convert_samples(self, samples): freq_conv = self.freq_conv diff --git a/klippy/extras/probe_eddy_current.py b/klippy/extras/probe_eddy_current.py index 4d97d46d6..d30c7d404 100644 --- a/klippy/extras/probe_eddy_current.py +++ b/klippy/extras/probe_eddy_current.py @@ -5,7 +5,7 @@ # This file may be distributed under the terms of the GNU GPLv3 license. import logging, math, bisect import mcu -from . import ldc1612, probe, manual_probe +from . import ldc1612, trigger_analog, probe, manual_probe OUT_OF_RANGE = 99.9 @@ -388,9 +388,10 @@ class EddyGatherSamples: self._probe_times.append((start_time, end_time, pos_time, None)) self._check_samples() +MAX_VALID_RAW_VALUE=0x03ffffff + # Helper for implementing PROBE style commands (descend until trigger) class EddyDescend: - REASON_SENSOR_ERROR = mcu.MCU_trsync.REASON_COMMS_TIMEOUT + 1 def __init__(self, config, sensor_helper, calibration, probe_offsets, param_helper): self._printer = config.get_printer() @@ -399,43 +400,20 @@ class EddyDescend: self._calibration = calibration self._probe_offsets = probe_offsets self._param_helper = param_helper + self._trigger_analog = trigger_analog.MCU_trigger_analog(sensor_helper) self._z_min_position = probe.lookup_minimum_z(config) - self._dispatch = mcu.TriggerDispatch(self._mcu) - self._trigger_time = 0. self._gather = None - probe.LookupZSteppers(config, self._dispatch.add_stepper) - # Interface for phoming.probing_move() - def get_steppers(self): - return self._dispatch.get_steppers() - def home_start(self, print_time, sample_time, sample_count, rest_time, - triggered=True): - self._trigger_time = 0. + dispatch = self._trigger_analog.get_dispatch() + probe.LookupZSteppers(config, dispatch.add_stepper) + def _prep_trigger_analog(self): + self._trigger_analog.set_raw_range(0, MAX_VALID_RAW_VALUE) z_offset = self._probe_offsets.get_offsets()[2] trigger_freq = self._calibration.height_to_freq(z_offset) - trigger_completion = self._dispatch.start(print_time) - self._sensor_helper.setup_home( - print_time, trigger_freq, self._dispatch.get_oid(), - mcu.MCU_trsync.REASON_ENDSTOP_HIT, self.REASON_SENSOR_ERROR) - return trigger_completion - def home_wait(self, home_end_time): - self._dispatch.wait_end(home_end_time) - trigger_time = self._sensor_helper.clear_home() - res = self._dispatch.stop() - if res >= mcu.MCU_trsync.REASON_COMMS_TIMEOUT: - if res == mcu.MCU_trsync.REASON_COMMS_TIMEOUT: - raise self._printer.command_error( - "Communication timeout during homing") - error_code = res - self.REASON_SENSOR_ERROR - error_msg = self._sensor_helper.lookup_sensor_error(error_code) - raise self._printer.command_error(error_msg) - if res != mcu.MCU_trsync.REASON_ENDSTOP_HIT: - return 0. - if self._mcu.is_fileoutput(): - trigger_time = home_end_time - self._trigger_time = trigger_time - return trigger_time + conv_freq = self._sensor_helper.convert_frequency(trigger_freq) + self._trigger_analog.set_trigger('gt', conv_freq) # Probe session interface def start_probe_session(self, gcmd): + self._prep_trigger_analog() offsets = self._probe_offsets.get_offsets() self._gather = EddyGatherSamples(self._printer, self._sensor_helper, self._calibration, offsets) @@ -447,9 +425,9 @@ class EddyDescend: speed = self._param_helper.get_probe_params(gcmd)['probe_speed'] # Perform probing move phoming = self._printer.lookup_object('homing') - trig_pos = phoming.probing_move(self, pos, speed) + trig_pos = phoming.probing_move(self._trigger_analog, pos, speed) # Extract samples - start_time = self._trigger_time + 0.050 + start_time = self._trigger_analog.get_last_trigger_time() + 0.050 end_time = start_time + 0.100 toolhead_pos = toolhead.get_position() self._gather.note_probe(start_time, end_time, toolhead_pos) @@ -472,13 +450,13 @@ class EddyEndstopWrapper: def add_stepper(self, stepper): pass def get_steppers(self): - return self._eddy_descend.get_steppers() + return self._eddy_descend._trigger_analog.get_steppers() def home_start(self, print_time, sample_time, sample_count, rest_time, triggered=True): - return self._eddy_descend.home_start( + return self._eddy_descend._trigger_analog.home_start( print_time, sample_time, sample_count, rest_time, triggered) def home_wait(self, home_end_time): - return self._eddy_descend.home_wait(home_end_time) + return self._eddy_descend._trigger_analog.home_wait(home_end_time) def query_endstop(self, print_time): return False # XXX # Interface for HomingViaProbeHelper diff --git a/src/Kconfig b/src/Kconfig index 8013b40f0..bf5149380 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -179,7 +179,7 @@ config NEED_SENSOR_BULK default y config WANT_TRIGGER_ANALOG bool - depends on WANT_HX71X || WANT_ADS1220 + depends on WANT_HX71X || WANT_ADS1220 || WANT_LDC1612 default y config NEED_SOS_FILTER bool diff --git a/src/sensor_ldc1612.c b/src/sensor_ldc1612.c index 35c69a2bd..2c794fafe 100644 --- a/src/sensor_ldc1612.c +++ b/src/sensor_ldc1612.c @@ -13,11 +13,10 @@ #include "i2ccmds.h" // i2cdev_oid_lookup #include "sched.h" // DECL_TASK #include "sensor_bulk.h" // sensor_bulk_report -#include "trsync.h" // trsync_do_trigger +#include "trigger_analog.h" // trigger_analog_update enum { LDC_PENDING = 1<<0, LDC_HAVE_INTB = 1<<1, - LH_AWAIT_HOMING = 1<<1, LH_CAN_TRIGGER = 1<<2 }; struct ldc1612 { @@ -27,12 +26,7 @@ struct ldc1612 { uint8_t flags; struct sensor_bulk sb; struct gpio_in intb_pin; - // homing - struct trsync *ts; - uint8_t homing_flags; - uint8_t trigger_reason, error_reason; - uint32_t trigger_threshold; - uint32_t homing_clock; + struct trigger_analog *ta; }; static struct task_wake ldc1612_wake; @@ -91,83 +85,15 @@ DECL_COMMAND(command_config_ldc1612_with_intb, "config_ldc1612_with_intb oid=%c i2c_oid=%c intb_pin=%c"); void -command_ldc1612_setup_home(uint32_t *args) -{ +ldc1612_attach_trigger_analog(uint32_t *args) { struct ldc1612 *ld = oid_lookup(args[0], command_config_ldc1612); - - ld->trigger_threshold = args[2]; - if (!ld->trigger_threshold) { - ld->ts = NULL; - ld->homing_flags = 0; - return; - } - ld->homing_clock = args[1]; - ld->ts = trsync_oid_lookup(args[3]); - ld->trigger_reason = args[4]; - ld->error_reason = args[5]; - ld->homing_flags = LH_AWAIT_HOMING | LH_CAN_TRIGGER; + ld->ta = trigger_analog_oid_lookup(args[1]); } -DECL_COMMAND(command_ldc1612_setup_home, - "ldc1612_setup_home oid=%c clock=%u threshold=%u" - " trsync_oid=%c trigger_reason=%c error_reason=%c"); +DECL_COMMAND(ldc1612_attach_trigger_analog, + "ldc1612_attach_trigger_analog oid=%c trigger_analog_oid=%c"); -void -command_query_ldc1612_home_state(uint32_t *args) -{ - struct ldc1612 *ld = oid_lookup(args[0], command_config_ldc1612); - sendf("ldc1612_home_state oid=%c homing=%c trigger_clock=%u" - , args[0], !!(ld->homing_flags & LH_CAN_TRIGGER), ld->homing_clock); -} -DECL_COMMAND(command_query_ldc1612_home_state, - "query_ldc1612_home_state oid=%c"); - -// Cancel homing due to an error -static void -cancel_homing(struct ldc1612 *ld, int error_code) -{ - if (!(ld->homing_flags & LH_CAN_TRIGGER)) - return; - ld->homing_flags = 0; - trsync_do_trigger(ld->ts, ld->error_reason + error_code); -} - -#define MAX_VALID_RAW_VALUE 0x03ffffff #define DATA_ERROR_AMPLITUDE (1L << 28) -static int -check_data_bits(struct ldc1612 *ld, uint32_t raw_data) { - // Ignore amplitude errors - raw_data &= ~DATA_ERROR_AMPLITUDE; - // Datasheet define valid frequency input as < F_ref / 4 - if (raw_data < MAX_VALID_RAW_VALUE) - return 0; - cancel_homing(ld, SE_SENSOR_ERROR); - return -1; -} - -// Check if a sample should trigger a homing event -static void -check_home(struct ldc1612 *ld, uint32_t raw_data) -{ - uint8_t homing_flags = ld->homing_flags; - if (!(homing_flags & LH_CAN_TRIGGER)) - return; - if (check_data_bits(ld, raw_data)) - return; - uint32_t data = raw_data & 0x0fffffff; - uint32_t time = timer_read_time(); - if ((homing_flags & LH_AWAIT_HOMING) - && timer_is_before(time, ld->homing_clock)) - return; - homing_flags &= ~LH_AWAIT_HOMING; - if (data > ld->trigger_threshold) { - homing_flags = 0; - ld->homing_clock = time; - trsync_do_trigger(ld->ts, ld->trigger_reason); - } - ld->homing_flags = homing_flags; -} - // Chip registers #define REG_DATA0_MSB 0x00 #define REG_DATA0_LSB 0x01 @@ -196,7 +122,7 @@ read_reg_status(struct ldc1612 *ld, uint16_t *status) static void report_sample_error(struct ldc1612 *ld, int error_code) { - cancel_homing(ld, error_code); + trigger_analog_note_error(ld->ta, error_code); uint8_t *d = &ld->sb.data[ld->sb.data_count]; d[0] = 0xff; @@ -238,12 +164,14 @@ ldc1612_query(struct ldc1612 *ld, uint8_t oid) goto out; } - // Check for endstop trigger - uint32_t data = ((uint32_t)d[0] << 24) - | ((uint32_t)d[1] << 16) - | ((uint32_t)d[2] << 8) - | ((uint32_t)d[3]); - check_home(ld, data); + // Check for homing trigger + uint32_t raw_data = (((uint32_t)d[0] << 24) | ((uint32_t)d[1] << 16) + | ((uint32_t)d[2] << 8) | ((uint32_t)d[3])); + if (raw_data & 0xe0000000) + trigger_analog_note_error(ld->ta, SE_SENSOR_ERROR); + else + trigger_analog_update(ld->ta, raw_data & 0x0fffffff); + out: ld->sb.data_count += BYTES_PER_SAMPLE; // Flush local buffer if needed