mirror of
https://github.com/Klipper3d/klipper.git
synced 2026-02-07 16:50:54 -07:00
sensor_ldc1612: Convert homing code to use trigger_analog system
Remove the homing code from sensor_ldc1612.c and utilize the generic homing support found in trigger_analog.c . Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
147022dee2
commit
58cc059e31
4 changed files with 40 additions and 146 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue