mirror of
https://github.com/Klipper3d/klipper.git
synced 2026-02-08 01:01:06 -07:00
trigger_analog: Update to support generic trigger types
Rework the trigger_analog code to support different "trigger" conditions. This merges in features of ldc1612.c into trigger_analog.c, such as error code reporting in the MCU. This is in preparation for using trigger_analog with ldc1612. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
73a6184407
commit
147022dee2
6 changed files with 202 additions and 159 deletions
|
|
@ -122,6 +122,9 @@ class ADS1220:
|
|||
def get_samples_per_second(self):
|
||||
return self.sps
|
||||
|
||||
def lookup_sensor_error(self, error_code):
|
||||
return "Unknown ads1220 error" % (error_code,)
|
||||
|
||||
# returns a tuple of the minimum and maximum value of the sensor, used to
|
||||
# detect if a data value is saturated
|
||||
def get_range(self):
|
||||
|
|
|
|||
|
|
@ -80,6 +80,9 @@ class HX71xBase:
|
|||
def get_samples_per_second(self):
|
||||
return self.sps
|
||||
|
||||
def lookup_sensor_error(self, error_code):
|
||||
return "Unknown hx71x error %d" % (error_code,)
|
||||
|
||||
# returns a tuple of the minimum and maximum value of the sensor, used to
|
||||
# detect if a data value is saturated
|
||||
def get_range(self):
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ class LoadCellProbingMove:
|
|||
safety_min, safety_max = self._config_helper.get_safety_range(gcmd)
|
||||
self._mcu_trigger_analog.set_raw_range(safety_min, safety_max)
|
||||
trigger_val = self._config_helper.get_trigger_force_grams(gcmd)
|
||||
self._mcu_trigger_analog.set_trigger_value(trigger_val)
|
||||
self._mcu_trigger_analog.set_trigger("abs_ge", trigger_val)
|
||||
# update internal tare value
|
||||
gpc = self._config_helper.get_grams_per_count()
|
||||
sos_filter = self._mcu_trigger_analog.get_sos_filter()
|
||||
|
|
|
|||
|
|
@ -213,30 +213,28 @@ class MCU_SosFilter:
|
|||
# MCU_trigger_analog is the interface to `trigger_analog` on the MCU
|
||||
class MCU_trigger_analog:
|
||||
MONITOR_MAX = 3
|
||||
ERROR_SAFETY_RANGE = mcu.MCU_trsync.REASON_COMMS_TIMEOUT + 1
|
||||
ERROR_OVERFLOW = mcu.MCU_trsync.REASON_COMMS_TIMEOUT + 2
|
||||
ERROR_WATCHDOG = mcu.MCU_trsync.REASON_COMMS_TIMEOUT + 3
|
||||
ERROR_MAP = {
|
||||
mcu.MCU_trsync.REASON_COMMS_TIMEOUT: "Communication timeout during "
|
||||
"homing",
|
||||
ERROR_SAFETY_RANGE: "sensor exceeds safety limit",
|
||||
ERROR_OVERFLOW: "fixed point math overflow",
|
||||
ERROR_WATCHDOG: "timed out waiting for sensor data"
|
||||
}
|
||||
|
||||
REASON_TRIGGER_ANALOG = mcu.MCU_trsync.REASON_COMMS_TIMEOUT + 1
|
||||
def __init__(self, sensor_inst):
|
||||
self._printer = sensor_inst.get_mcu().get_printer()
|
||||
self._sensor = sensor_inst
|
||||
self._mcu = self._sensor.get_mcu()
|
||||
self._sos_filter = None
|
||||
# configure MCU objects
|
||||
self._dispatch = mcu.TriggerDispatch(self._mcu)
|
||||
self._oid = self._mcu.create_oid()
|
||||
self._last_trigger_time = 0.
|
||||
# Raw range checking
|
||||
self._raw_min = self._raw_max = 0
|
||||
self._last_range_args = None
|
||||
# Trigger type
|
||||
self._trigger_type = "unspecified"
|
||||
self._trigger_value = 0.
|
||||
self._last_trigger_time = 0.
|
||||
self._home_cmd = self._query_cmd = self._set_range_cmd = None
|
||||
self._last_trigger_args = None
|
||||
# Error codes from MCU
|
||||
self._error_map = {}
|
||||
self._sensor_specific_error = 0
|
||||
# Configure MCU objects
|
||||
self._oid = self._mcu.create_oid()
|
||||
self._home_cmd = self._query_state_cmd = None
|
||||
self._set_raw_range_cmd = self._set_trigger_cmd = None
|
||||
self._mcu.register_config_callback(self._build_config)
|
||||
|
||||
def setup_sos_filter(self, sos_filter):
|
||||
|
|
@ -251,17 +249,24 @@ class MCU_trigger_analog:
|
|||
"config_trigger_analog oid=%d sos_filter_oid=%d" % (
|
||||
self._oid, self._sos_filter.get_oid()))
|
||||
# Lookup commands
|
||||
self._query_cmd = self._mcu.lookup_query_command(
|
||||
self._query_state_cmd = self._mcu.lookup_query_command(
|
||||
"trigger_analog_query_state oid=%c",
|
||||
"trigger_analog_state oid=%c is_homing_trigger=%c "
|
||||
"trigger_ticks=%u", oid=self._oid, cq=cmd_queue)
|
||||
self._set_range_cmd = self._mcu.lookup_command(
|
||||
"trigger_analog_set_range oid=%c safety_counts_min=%i"
|
||||
" safety_counts_max=%i trigger_value=%i", cq=cmd_queue)
|
||||
"trigger_analog_state oid=%c homing=%c trigger_clock=%u",
|
||||
oid=self._oid, cq=cmd_queue)
|
||||
self._set_raw_range_cmd = self._mcu.lookup_command(
|
||||
"trigger_analog_set_raw_range oid=%c raw_min=%i raw_max=%i",
|
||||
cq=cmd_queue)
|
||||
self._set_trigger_cmd = self._mcu.lookup_command(
|
||||
"trigger_analog_set_trigger oid=%c trigger_analog_type=%c"
|
||||
" trigger_value=%i", cq=cmd_queue)
|
||||
self._home_cmd = self._mcu.lookup_command(
|
||||
"trigger_analog_home oid=%c trsync_oid=%c trigger_reason=%c"
|
||||
" error_reason=%c clock=%u rest_ticks=%u timeout=%u",
|
||||
" error_reason=%c clock=%u monitor_ticks=%u monitor_max=%u",
|
||||
cq=cmd_queue)
|
||||
# Load errors from mcu
|
||||
errors = self._mcu.get_enumerations().get("trigger_analog_error:", {})
|
||||
self._error_map = {v: k for k, v in errors.items()}
|
||||
self._sensor_specific_error = errors.get("SENSOR_SPECIFIC", 0)
|
||||
|
||||
def get_oid(self):
|
||||
return self._oid
|
||||
|
|
@ -278,7 +283,8 @@ class MCU_trigger_analog:
|
|||
def get_last_trigger_time(self):
|
||||
return self._last_trigger_time
|
||||
|
||||
def set_trigger_value(self, trigger_value):
|
||||
def set_trigger(self, trigger_type, trigger_value):
|
||||
self._trigger_type = trigger_type
|
||||
self._trigger_value = trigger_value
|
||||
|
||||
def set_raw_range(self, raw_min, raw_max):
|
||||
|
|
@ -286,21 +292,24 @@ class MCU_trigger_analog:
|
|||
self._raw_max = raw_max
|
||||
|
||||
def _reset_filter(self):
|
||||
# Update parameters in mcu (if they have changed)
|
||||
tval32 = self._sos_filter.convert_value(self._trigger_value)
|
||||
args = [self._oid, self._raw_min, self._raw_max, tval32]
|
||||
# Update raw range parameters in mcu (if they have changed)
|
||||
args = [self._oid, self._raw_min, self._raw_max]
|
||||
if args != self._last_range_args:
|
||||
self._set_range_cmd.send(args)
|
||||
self._set_raw_range_cmd.send(args)
|
||||
self._last_range_args = args
|
||||
# Update trigger in mcu (if it has changed)
|
||||
tval32 = self._sos_filter.convert_value(self._trigger_value)
|
||||
args = [self._oid, self._trigger_type, tval32]
|
||||
if args != self._last_trigger_args:
|
||||
self._set_trigger_cmd.send(args)
|
||||
self._last_trigger_args = args
|
||||
# Update sos filter in mcu
|
||||
self._sos_filter.reset_filter()
|
||||
|
||||
def _clear_home(self):
|
||||
params = self._query_cmd.send([self._oid])
|
||||
# The time of the first sample that triggered is in "trigger_ticks"
|
||||
trigger_ticks = self._mcu.clock32_to_clock64(params['trigger_ticks'])
|
||||
# clear trsync from load_cell_endstop
|
||||
self._home_cmd.send([self._oid, 0, 0, 0, 0, 0, 0, 0])
|
||||
params = self._query_state_cmd.send([self._oid])
|
||||
trigger_ticks = self._mcu.clock32_to_clock64(params['trigger_clock'])
|
||||
return self._mcu.clock_to_print_time(trigger_ticks)
|
||||
|
||||
def get_steppers(self):
|
||||
|
|
@ -315,8 +324,8 @@ class MCU_trigger_analog:
|
|||
sensor_update = 1. / self._sensor.get_samples_per_second()
|
||||
sm_ticks = self._mcu.seconds_to_clock(sensor_update)
|
||||
self._home_cmd.send([self._oid, self._dispatch.get_oid(),
|
||||
mcu.MCU_trsync.REASON_ENDSTOP_HIT, self.ERROR_SAFETY_RANGE, clock,
|
||||
sm_ticks, self.MONITOR_MAX], reqclock=clock)
|
||||
mcu.MCU_trsync.REASON_ENDSTOP_HIT, self.REASON_TRIGGER_ANALOG,
|
||||
clock, sm_ticks, self.MONITOR_MAX], reqclock=clock)
|
||||
return trigger_completion
|
||||
|
||||
def home_wait(self, home_end_time):
|
||||
|
|
@ -326,8 +335,16 @@ class MCU_trigger_analog:
|
|||
# clear the homing state so it stops processing samples
|
||||
trigger_time = self._clear_home()
|
||||
if res >= mcu.MCU_trsync.REASON_COMMS_TIMEOUT:
|
||||
defmsg = "unknown reason code %i" % (res,)
|
||||
error_msg = self.ERROR_MAP.get(res, defmsg)
|
||||
if res == mcu.MCU_trsync.REASON_COMMS_TIMEOUT:
|
||||
raise self._printer.command_error(
|
||||
"Communication timeout during homing")
|
||||
error_code = res - self.REASON_TRIGGER_ANALOG
|
||||
if error_code >= self._sensor_specific_error:
|
||||
sensor_err = error_code - self._sensor_specific_error
|
||||
error_msg = self._sensor.lookup_sensor_error(sensor_err)
|
||||
else:
|
||||
defmsg = "Unknown code %i" % (error_code,)
|
||||
error_msg = self._error_map.get(error_code, defmsg)
|
||||
raise self._printer.command_error("Trigger analog error: %s"
|
||||
% (error_msg,))
|
||||
if res != mcu.MCU_trsync.REASON_ENDSTOP_HIT:
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
// Support homing/probing "trigger" notification from analog sensors
|
||||
//
|
||||
// Copyright (C) 2025 Gareth Farrington <gareth@waves.ky>
|
||||
// Copyright (C) 2024-2026 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
#include <stdlib.h> // abs
|
||||
#include "basecmd.h" // oid_alloc
|
||||
#include "board/io.h" // writeb
|
||||
#include "board/misc.h" // timer_read_time
|
||||
#include "command.h" // DECL_COMMAND
|
||||
#include "sched.h" // shutdown
|
||||
|
|
@ -13,133 +15,149 @@
|
|||
#include "trigger_analog.h" // trigger_analog_update
|
||||
#include "trsync.h" // trsync_do_trigger
|
||||
|
||||
#define ERROR_SAFETY_RANGE 0
|
||||
#define ERROR_OVERFLOW 1
|
||||
#define ERROR_WATCHDOG 2
|
||||
|
||||
// Flags
|
||||
enum {FLAG_IS_HOMING = 1 << 0
|
||||
, FLAG_IS_HOMING_TRIGGER = 1 << 1
|
||||
, FLAG_AWAIT_HOMING = 1 << 2
|
||||
};
|
||||
|
||||
// Endstop Structure
|
||||
// Main trigger_analog storage
|
||||
struct trigger_analog {
|
||||
struct timer time;
|
||||
uint32_t trigger_ticks, last_sample_ticks, rest_ticks;
|
||||
uint32_t homing_start_time;
|
||||
struct trsync *ts;
|
||||
int32_t safety_counts_min, safety_counts_max;
|
||||
uint8_t flags, trigger_reason, error_reason, watchdog_max, watchdog_count;
|
||||
int32_t trigger_value;
|
||||
// Raw value range check
|
||||
int32_t raw_min, raw_max;
|
||||
// Filtering
|
||||
struct sos_filter *sf;
|
||||
// Trigger value checking
|
||||
int32_t trigger_value;
|
||||
uint8_t trigger_type;
|
||||
// Trsync triggering
|
||||
uint8_t flags, trigger_reason, error_reason;
|
||||
struct trsync *ts;
|
||||
uint32_t homing_clock, trigger_clock;
|
||||
// Sensor activity monitoring
|
||||
uint8_t monitor_max, monitor_count;
|
||||
struct timer time;
|
||||
uint32_t monitor_ticks;
|
||||
};
|
||||
|
||||
static inline uint8_t
|
||||
is_flag_set(const uint8_t mask, struct trigger_analog *ta)
|
||||
{
|
||||
return !!(mask & ta->flags);
|
||||
}
|
||||
// Homing flags
|
||||
enum {
|
||||
TA_AWAIT_HOMING = 1<<1, TA_CAN_TRIGGER = 1<<2
|
||||
};
|
||||
|
||||
static inline void
|
||||
set_flag(uint8_t mask, struct trigger_analog *ta)
|
||||
{
|
||||
ta->flags |= mask;
|
||||
}
|
||||
// Trigger types
|
||||
enum {
|
||||
TT_ABS_GE, TT_GT
|
||||
};
|
||||
DECL_ENUMERATION("trigger_analog_type", "abs_ge", TT_ABS_GE);
|
||||
DECL_ENUMERATION("trigger_analog_type", "gt", TT_GT);
|
||||
|
||||
static inline void
|
||||
clear_flag(uint8_t mask, struct trigger_analog *ta)
|
||||
{
|
||||
ta->flags &= ~mask;
|
||||
}
|
||||
// Sample errors sent via trsync error code
|
||||
enum {
|
||||
TE_RAW_RANGE, TE_OVERFLOW, TE_MONITOR, TE_SENSOR_SPECIFIC
|
||||
};
|
||||
DECL_ENUMERATION("trigger_analog_error:", "RAW_RANGE", TE_RAW_RANGE);
|
||||
DECL_ENUMERATION("trigger_analog_error:", "OVERFLOW", TE_OVERFLOW);
|
||||
DECL_ENUMERATION("trigger_analog_error:", "MONITOR", TE_MONITOR);
|
||||
DECL_ENUMERATION("trigger_analog_error:", "SENSOR_SPECIFIC"
|
||||
, TE_SENSOR_SPECIFIC);
|
||||
|
||||
void
|
||||
try_trigger(struct trigger_analog *ta, uint32_t ticks)
|
||||
// Timer callback that monitors for sensor timeouts
|
||||
static uint_fast8_t
|
||||
monitor_event(struct timer *t)
|
||||
{
|
||||
uint8_t is_homing_triggered = is_flag_set(FLAG_IS_HOMING_TRIGGER, ta);
|
||||
if (!is_homing_triggered) {
|
||||
// the first triggering sample when homing sets the trigger time
|
||||
ta->trigger_ticks = ticks;
|
||||
// this flag latches until a reset, disabling further triggering
|
||||
set_flag(FLAG_IS_HOMING_TRIGGER, ta);
|
||||
trsync_do_trigger(ta->ts, ta->trigger_reason);
|
||||
struct trigger_analog *ta = container_of(t, struct trigger_analog, time);
|
||||
|
||||
if (!(ta->flags & TA_CAN_TRIGGER))
|
||||
return SF_DONE;
|
||||
|
||||
if (ta->monitor_count > ta->monitor_max) {
|
||||
trsync_do_trigger(ta->ts, ta->error_reason + TE_MONITOR);
|
||||
return SF_DONE;
|
||||
}
|
||||
|
||||
// A sample was recently delivered, continue monitoring
|
||||
ta->monitor_count++;
|
||||
ta->time.waketime += ta->monitor_ticks;
|
||||
return SF_RESCHEDULE;
|
||||
}
|
||||
|
||||
void
|
||||
trigger_error(struct trigger_analog *ta, uint8_t error_code)
|
||||
// Note recent activity
|
||||
static void
|
||||
monitor_note_activity(struct trigger_analog *ta)
|
||||
{
|
||||
writeb(&ta->monitor_count, 0);
|
||||
}
|
||||
|
||||
// Check if a value should signal a "trigger" event
|
||||
static int
|
||||
check_trigger(struct trigger_analog *ta, int32_t value)
|
||||
{
|
||||
switch (ta->trigger_type) {
|
||||
case TT_ABS_GE:
|
||||
return abs(value) >= ta->trigger_value;
|
||||
case TT_GT:
|
||||
return value > ta->trigger_value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Stop homing due to an error
|
||||
static void
|
||||
cancel_homing(struct trigger_analog *ta, uint8_t error_code)
|
||||
{
|
||||
if (!(ta->flags & TA_CAN_TRIGGER))
|
||||
return;
|
||||
ta->flags = 0;
|
||||
trsync_do_trigger(ta->ts, ta->error_reason + error_code);
|
||||
}
|
||||
|
||||
// Handle an error reported by the sensor
|
||||
void
|
||||
trigger_analog_note_error(struct trigger_analog *ta, uint8_t sensor_code)
|
||||
{
|
||||
if (!ta)
|
||||
return;
|
||||
cancel_homing(ta, sensor_code + TE_SENSOR_SPECIFIC);
|
||||
}
|
||||
|
||||
// Used by Sensors to report new raw ADC sample
|
||||
void
|
||||
trigger_analog_update(struct trigger_analog *ta, const int32_t sample)
|
||||
trigger_analog_update(struct trigger_analog *ta, int32_t sample)
|
||||
{
|
||||
// Check homing is active
|
||||
if (!ta)
|
||||
return;
|
||||
uint8_t flags = ta->flags;
|
||||
if (!(flags & TA_CAN_TRIGGER))
|
||||
return;
|
||||
|
||||
// only process samples when homing
|
||||
uint8_t is_homing = is_flag_set(FLAG_IS_HOMING, ta);
|
||||
if (!is_homing) {
|
||||
// Check if homing has started
|
||||
uint32_t time = timer_read_time();
|
||||
if ((flags & TA_AWAIT_HOMING) && timer_is_before(time, ta->homing_clock))
|
||||
return;
|
||||
flags &= ~TA_AWAIT_HOMING;
|
||||
|
||||
// Reset the sensor timeout checking
|
||||
monitor_note_activity(ta);
|
||||
|
||||
// Check that raw value is in range
|
||||
if (sample < ta->raw_min || sample > ta->raw_max) {
|
||||
cancel_homing(ta, TE_RAW_RANGE);
|
||||
return;
|
||||
}
|
||||
|
||||
// save new sample
|
||||
uint32_t ticks = timer_read_time();
|
||||
ta->last_sample_ticks = ticks;
|
||||
ta->watchdog_count = 0;
|
||||
|
||||
// do not trigger before homing start time
|
||||
uint8_t await_homing = is_flag_set(FLAG_AWAIT_HOMING, ta);
|
||||
if (await_homing && timer_is_before(ticks, ta->homing_start_time)) {
|
||||
return;
|
||||
}
|
||||
clear_flag(FLAG_AWAIT_HOMING, ta);
|
||||
|
||||
// check for safety limit violations
|
||||
const uint8_t is_safety_trigger = sample <= ta->safety_counts_min
|
||||
|| sample >= ta->safety_counts_max;
|
||||
// too much force, this is an error while homing
|
||||
if (is_safety_trigger) {
|
||||
trigger_error(ta, ERROR_SAFETY_RANGE);
|
||||
return;
|
||||
}
|
||||
|
||||
// perform filtering
|
||||
// Perform filtering
|
||||
int32_t filtered_value = sample;
|
||||
int ret = sos_filter_apply(ta->sf, &filtered_value);
|
||||
if (ret) {
|
||||
trigger_error(ta, ERROR_OVERFLOW);
|
||||
cancel_homing(ta, TE_OVERFLOW);
|
||||
return;
|
||||
}
|
||||
|
||||
// update trigger state
|
||||
if (abs(filtered_value) >= ta->trigger_value) {
|
||||
try_trigger(ta, ta->last_sample_ticks);
|
||||
}
|
||||
}
|
||||
|
||||
// Timer callback that monitors for timeouts
|
||||
static uint_fast8_t
|
||||
watchdog_event(struct timer *t)
|
||||
{
|
||||
struct trigger_analog *ta = container_of(t, struct trigger_analog, time);
|
||||
uint8_t is_homing = is_flag_set(FLAG_IS_HOMING, ta);
|
||||
uint8_t is_homing_trigger = is_flag_set(FLAG_IS_HOMING_TRIGGER, ta);
|
||||
// the watchdog stops when not homing or when trsync becomes triggered
|
||||
if (!is_homing || is_homing_trigger) {
|
||||
return SF_DONE;
|
||||
// Check if this is a "trigger"
|
||||
ret = check_trigger(ta, filtered_value);
|
||||
if (ret) {
|
||||
trsync_do_trigger(ta->ts, ta->trigger_reason);
|
||||
ta->trigger_clock = time;
|
||||
flags = 0;
|
||||
}
|
||||
|
||||
if (ta->watchdog_count > ta->watchdog_max) {
|
||||
trigger_error(ta, ERROR_WATCHDOG);
|
||||
}
|
||||
ta->watchdog_count += 1;
|
||||
|
||||
// A sample was recently delivered, continue monitoring
|
||||
ta->time.waketime += ta->rest_ticks;
|
||||
return SF_RESCHEDULE;
|
||||
ta->flags = flags;
|
||||
}
|
||||
|
||||
// Create a trigger_analog
|
||||
|
|
@ -160,17 +178,27 @@ trigger_analog_oid_lookup(uint8_t oid)
|
|||
return oid_lookup(oid, command_config_trigger_analog);
|
||||
}
|
||||
|
||||
// Set the triggering range and tare value
|
||||
// Set valid raw range
|
||||
void
|
||||
command_trigger_analog_set_range(uint32_t *args)
|
||||
command_trigger_analog_set_raw_range(uint32_t *args)
|
||||
{
|
||||
struct trigger_analog *ta = trigger_analog_oid_lookup(args[0]);
|
||||
ta->safety_counts_min = args[1];
|
||||
ta->safety_counts_max = args[2];
|
||||
ta->trigger_value = args[3];
|
||||
ta->raw_min = args[1];
|
||||
ta->raw_max = args[2];
|
||||
}
|
||||
DECL_COMMAND(command_trigger_analog_set_range, "trigger_analog_set_range"
|
||||
" oid=%c safety_counts_min=%i safety_counts_max=%i trigger_value=%i");
|
||||
DECL_COMMAND(command_trigger_analog_set_raw_range,
|
||||
"trigger_analog_set_raw_range oid=%c raw_min=%i raw_max=%i");
|
||||
|
||||
// Set the triggering type and value
|
||||
void
|
||||
command_trigger_analog_set_trigger(uint32_t *args)
|
||||
{
|
||||
struct trigger_analog *ta = trigger_analog_oid_lookup(args[0]);
|
||||
ta->trigger_type = args[1];
|
||||
ta->trigger_value = args[2];
|
||||
}
|
||||
DECL_COMMAND(command_trigger_analog_set_trigger, "trigger_analog_set_trigger"
|
||||
" oid=%c trigger_analog_type=%c trigger_value=%i");
|
||||
|
||||
// Home an axis
|
||||
void
|
||||
|
|
@ -178,42 +206,33 @@ command_trigger_analog_home(uint32_t *args)
|
|||
{
|
||||
struct trigger_analog *ta = trigger_analog_oid_lookup(args[0]);
|
||||
sched_del_timer(&ta->time);
|
||||
// clear the homing trigger flag
|
||||
clear_flag(FLAG_IS_HOMING_TRIGGER, ta);
|
||||
clear_flag(FLAG_IS_HOMING, ta);
|
||||
ta->trigger_ticks = 0;
|
||||
ta->ts = NULL;
|
||||
// 0 samples indicates homing is finished
|
||||
if (args[3] == 0) {
|
||||
// Disable end stop checking
|
||||
ta->monitor_ticks = args[5];
|
||||
if (!ta->monitor_ticks) {
|
||||
ta->flags = 0;
|
||||
ta->ts = NULL;
|
||||
return;
|
||||
}
|
||||
ta->ts = trsync_oid_lookup(args[1]);
|
||||
ta->trigger_reason = args[2];
|
||||
ta->error_reason = args[3];
|
||||
ta->time.waketime = args[4];
|
||||
ta->homing_start_time = args[4];
|
||||
ta->rest_ticks = args[5];
|
||||
ta->watchdog_max = args[6];
|
||||
ta->watchdog_count = 0;
|
||||
ta->time.func = watchdog_event;
|
||||
set_flag(FLAG_IS_HOMING, ta);
|
||||
set_flag(FLAG_AWAIT_HOMING, ta);
|
||||
ta->time.waketime = ta->homing_clock = args[4];
|
||||
ta->monitor_max = args[6];
|
||||
ta->monitor_count = 0;
|
||||
ta->time.func = monitor_event;
|
||||
ta->flags = TA_AWAIT_HOMING | TA_CAN_TRIGGER;
|
||||
sched_add_timer(&ta->time);
|
||||
}
|
||||
DECL_COMMAND(command_trigger_analog_home,
|
||||
"trigger_analog_home oid=%c trsync_oid=%c trigger_reason=%c"
|
||||
" error_reason=%c clock=%u rest_ticks=%u timeout=%u");
|
||||
" error_reason=%c clock=%u monitor_ticks=%u monitor_max=%u");
|
||||
|
||||
void
|
||||
command_trigger_analog_query_state(uint32_t *args)
|
||||
{
|
||||
uint8_t oid = args[0];
|
||||
struct trigger_analog *ta = trigger_analog_oid_lookup(args[0]);
|
||||
sendf("trigger_analog_state oid=%c is_homing_trigger=%c trigger_ticks=%u"
|
||||
, oid
|
||||
, is_flag_set(FLAG_IS_HOMING_TRIGGER, ta)
|
||||
, ta->trigger_ticks);
|
||||
sendf("trigger_analog_state oid=%c homing=%c trigger_clock=%u"
|
||||
, oid, !!(ta->flags & TA_CAN_TRIGGER), ta->trigger_clock);
|
||||
}
|
||||
DECL_COMMAND(command_trigger_analog_query_state
|
||||
, "trigger_analog_query_state oid=%c");
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <stdint.h> // uint8_t
|
||||
|
||||
struct trigger_analog *trigger_analog_oid_lookup(uint8_t oid);
|
||||
void trigger_analog_note_error(struct trigger_analog *ta, uint8_t sensor_code);
|
||||
void trigger_analog_update(struct trigger_analog *ta, int32_t sample);
|
||||
|
||||
#endif // trigger_analog.h
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue