aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--klippy/chelper/__init__.py36
-rw-r--r--klippy/chelper/kin_cartesian.c113
-rw-r--r--klippy/chelper/kin_delta.c133
-rw-r--r--klippy/chelper/stepcompress.c259
-rw-r--r--klippy/chelper/stepcompress.h40
5 files changed, 327 insertions, 254 deletions
diff --git a/klippy/chelper/__init__.py b/klippy/chelper/__init__.py
index ed5e156c..00fec80c 100644
--- a/klippy/chelper/__init__.py
+++ b/klippy/chelper/__init__.py
@@ -14,9 +14,12 @@ import cffi
COMPILE_CMD = ("gcc -Wall -g -O2 -shared -fPIC"
" -flto -fwhole-program -fno-use-linker-plugin"
" -o %s %s")
-SOURCE_FILES = ['stepcompress.c', 'serialqueue.c', 'pyhelper.c']
+SOURCE_FILES = [
+ 'stepcompress.c', 'kin_cartesian.c', 'kin_delta.c',
+ 'serialqueue.c', 'pyhelper.c'
+]
DEST_LIB = "c_helper.so"
-OTHER_FILES = ['list.h', 'serialqueue.h', 'pyhelper.h']
+OTHER_FILES = ['list.h', 'serialqueue.h', 'stepcompress.h', 'pyhelper.h']
defs_stepcompress = """
struct stepcompress *stepcompress_alloc(uint32_t max_error
@@ -27,20 +30,25 @@ defs_stepcompress = """
int stepcompress_set_homing(struct stepcompress *sc, uint64_t homing_clock);
int stepcompress_queue_msg(struct stepcompress *sc, uint32_t *data, int len);
+ struct steppersync *steppersync_alloc(struct serialqueue *sq
+ , struct stepcompress **sc_list, int sc_num, int move_num);
+ void steppersync_free(struct steppersync *ss);
+ void steppersync_set_time(struct steppersync *ss
+ , double time_offset, double mcu_freq);
+ int steppersync_flush(struct steppersync *ss, uint64_t move_clock);
+"""
+
+defs_kin_cartesian = """
int32_t stepcompress_push(struct stepcompress *sc, double step_clock
, int32_t sdir);
int32_t stepcompress_push_const(struct stepcompress *sc, double clock_offset
, double step_offset, double steps, double start_sv, double accel);
+"""
+
+defs_kin_delta = """
int32_t stepcompress_push_delta(struct stepcompress *sc
, double clock_offset, double move_sd, double start_sv, double accel
, double height, double startxy_sd, double arm_d, double movez_r);
-
- struct steppersync *steppersync_alloc(struct serialqueue *sq
- , struct stepcompress **sc_list, int sc_num, int move_num);
- void steppersync_free(struct steppersync *ss);
- void steppersync_set_time(struct steppersync *ss
- , double time_offset, double mcu_freq);
- int steppersync_flush(struct steppersync *ss, uint64_t move_clock);
"""
defs_serialqueue = """
@@ -75,6 +83,11 @@ defs_pyhelper = """
double get_monotonic(void);
"""
+defs_all = [
+ defs_stepcompress, defs_kin_cartesian, defs_kin_delta,
+ defs_serialqueue, defs_pyhelper
+]
+
# Return the list of file modification times
def get_mtimes(srcdir, filelist):
out = []
@@ -109,9 +122,8 @@ def get_ffi():
check_build_code(srcdir, DEST_LIB, SOURCE_FILES, COMPILE_CMD
, OTHER_FILES)
FFI_main = cffi.FFI()
- FFI_main.cdef(defs_stepcompress)
- FFI_main.cdef(defs_serialqueue)
- FFI_main.cdef(defs_pyhelper)
+ for d in defs_all:
+ FFI_main.cdef(d)
FFI_lib = FFI_main.dlopen(os.path.join(srcdir, DEST_LIB))
# Setup error logging
def logging_callback(msg):
diff --git a/klippy/chelper/kin_cartesian.c b/klippy/chelper/kin_cartesian.c
new file mode 100644
index 00000000..5cefb119
--- /dev/null
+++ b/klippy/chelper/kin_cartesian.c
@@ -0,0 +1,113 @@
+// Cartesian kinematics stepper pulse time generation
+//
+// Copyright (C) 2016-2018 Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU GPLv3 license.
+
+#include <math.h> // sqrt
+#include "compiler.h" // likely
+#include "pyhelper.h" // errorf
+#include "stepcompress.h" // queue_append
+
+// Common suffixes: _sd is step distance (a unit length the same
+// distance the stepper moves on each step), _sv is step velocity (in
+// units of step distance per time), _sd2 is step distance squared, _r
+// is ratio (scalar usually between 0.0 and 1.0). Times are in
+// seconds and acceleration is in units of step distance per second
+// squared.
+
+// Wrapper around sqrt() to handle small negative numbers
+static double
+_safe_sqrt(double v)
+{
+ // Due to floating point truncation, it's possible to get a small
+ // negative number - treat it as zero.
+ if (v < -0.001)
+ errorf("safe_sqrt of %.9f", v);
+ return 0.;
+}
+inline double safe_sqrt(double v) {
+ return likely(v >= 0.) ? sqrt(v) : _safe_sqrt(v);
+}
+
+// Schedule a step event at the specified step_clock time
+int32_t __visible
+stepcompress_push(struct stepcompress *sc, double print_time, int32_t sdir)
+{
+ int ret = set_next_step_dir(sc, !!sdir);
+ if (ret)
+ return ret;
+ struct queue_append qa = queue_append_start(sc, print_time, 0.5);
+ ret = queue_append(&qa, 0.);
+ if (ret)
+ return ret;
+ queue_append_finish(qa);
+ return sdir ? 1 : -1;
+}
+
+// Schedule 'steps' number of steps at constant acceleration. If
+// acceleration is zero (ie, constant velocity) it uses the formula:
+// step_time = print_time + step_num/start_sv
+// Otherwise it uses the formula:
+// step_time = (print_time + sqrt(2*step_num/accel + (start_sv/accel)**2)
+// - start_sv/accel)
+int32_t __visible
+stepcompress_push_const(
+ struct stepcompress *sc, double print_time
+ , double step_offset, double steps, double start_sv, double accel)
+{
+ // Calculate number of steps to take
+ int sdir = 1;
+ if (steps < 0) {
+ sdir = 0;
+ steps = -steps;
+ step_offset = -step_offset;
+ }
+ int count = steps + .5 - step_offset;
+ if (count <= 0 || count > 10000000) {
+ if (count && steps) {
+ errorf("push_const invalid count %d %f %f %f %f %f"
+ , stepcompress_get_oid(sc), print_time, step_offset, steps
+ , start_sv, accel);
+ return ERROR_RET;
+ }
+ return 0;
+ }
+ int ret = set_next_step_dir(sc, sdir);
+ if (ret)
+ return ret;
+ int res = sdir ? count : -count;
+
+ // Calculate each step time
+ if (!accel) {
+ // Move at constant velocity (zero acceleration)
+ struct queue_append qa = queue_append_start(sc, print_time, .5);
+ double inv_cruise_sv = stepcompress_get_mcu_freq(sc) / start_sv;
+ double pos = (step_offset + .5) * inv_cruise_sv;
+ while (count--) {
+ ret = queue_append(&qa, pos);
+ if (ret)
+ return ret;
+ pos += inv_cruise_sv;
+ }
+ queue_append_finish(qa);
+ } else {
+ // Move with constant acceleration
+ double inv_accel = 1. / accel;
+ double mcu_freq = stepcompress_get_mcu_freq(sc);
+ double accel_time = start_sv * inv_accel * mcu_freq;
+ struct queue_append qa = queue_append_start(
+ sc, print_time, 0.5 - accel_time);
+ double accel_multiplier = 2. * inv_accel * mcu_freq * mcu_freq;
+ double pos = (step_offset + .5)*accel_multiplier + accel_time*accel_time;
+ while (count--) {
+ double v = safe_sqrt(pos);
+ int ret = queue_append(&qa, accel_multiplier >= 0. ? v : -v);
+ if (ret)
+ return ret;
+ pos += accel_multiplier;
+ }
+ queue_append_finish(qa);
+ }
+ return res;
+}
diff --git a/klippy/chelper/kin_delta.c b/klippy/chelper/kin_delta.c
new file mode 100644
index 00000000..1925ae20
--- /dev/null
+++ b/klippy/chelper/kin_delta.c
@@ -0,0 +1,133 @@
+// Delta kinematics stepper pulse time generation
+//
+// Copyright (C) 2016-2018 Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU GPLv3 license.
+
+#include <math.h> // sqrt
+#include "compiler.h" // __visible
+#include "pyhelper.h" // errorf
+#include "stepcompress.h" // queue_append
+
+// Schedule steps using delta kinematics
+static int32_t
+_stepcompress_push_delta(
+ struct stepcompress *sc, int sdir
+ , double print_time, double move_sd, double start_sv, double accel
+ , double height, double startxy_sd, double arm_sd, double movez_r)
+{
+ // Calculate number of steps to take
+ double movexy_r = movez_r ? sqrt(1. - movez_r*movez_r) : 1.;
+ double arm_sd2 = arm_sd * arm_sd;
+ double endxy_sd = startxy_sd - movexy_r*move_sd;
+ double end_height = safe_sqrt(arm_sd2 - endxy_sd*endxy_sd);
+ int count = (end_height + movez_r*move_sd - height) * (sdir ? 1. : -1.) + .5;
+ if (count <= 0 || count > 10000000) {
+ if (count) {
+ errorf("push_delta invalid count %d %d %f %f %f %f %f %f %f %f"
+ , stepcompress_get_oid(sc), count, print_time, move_sd
+ , start_sv, accel, height, startxy_sd, arm_sd, movez_r);
+ return ERROR_RET;
+ }
+ return 0;
+ }
+ int ret = set_next_step_dir(sc, sdir);
+ if (ret)
+ return ret;
+ int res = sdir ? count : -count;
+
+ // Calculate each step time
+ height += (sdir ? .5 : -.5);
+ if (!accel) {
+ // Move at constant velocity (zero acceleration)
+ struct queue_append qa = queue_append_start(sc, print_time, .5);
+ double inv_cruise_sv = stepcompress_get_mcu_freq(sc) / start_sv;
+ if (!movez_r) {
+ // Optimized case for common XY only moves (no Z movement)
+ while (count--) {
+ double v = safe_sqrt(arm_sd2 - height*height);
+ double pos = startxy_sd + (sdir ? -v : v);
+ int ret = queue_append(&qa, pos * inv_cruise_sv);
+ if (ret)
+ return ret;
+ height += (sdir ? 1. : -1.);
+ }
+ } else if (!movexy_r) {
+ // Optimized case for Z only moves
+ double pos = ((sdir ? height-end_height : end_height-height)
+ * inv_cruise_sv);
+ while (count--) {
+ int ret = queue_append(&qa, pos);
+ if (ret)
+ return ret;
+ pos += inv_cruise_sv;
+ }
+ } else {
+ // General case (handles XY+Z moves)
+ double start_pos = movexy_r*startxy_sd, zoffset = movez_r*startxy_sd;
+ while (count--) {
+ double relheight = movexy_r*height - zoffset;
+ double v = safe_sqrt(arm_sd2 - relheight*relheight);
+ double pos = start_pos + movez_r*height + (sdir ? -v : v);
+ int ret = queue_append(&qa, pos * inv_cruise_sv);
+ if (ret)
+ return ret;
+ height += (sdir ? 1. : -1.);
+ }
+ }
+ queue_append_finish(qa);
+ } else {
+ // Move with constant acceleration
+ double start_pos = movexy_r*startxy_sd, zoffset = movez_r*startxy_sd;
+ double mcu_freq = stepcompress_get_mcu_freq(sc);
+ double inv_accel = 1. / accel;
+ start_pos += 0.5 * start_sv*start_sv * inv_accel;
+ struct queue_append qa = queue_append_start(
+ sc, print_time, 0.5 - start_sv * inv_accel * mcu_freq);
+ double accel_multiplier = 2. * inv_accel * mcu_freq * mcu_freq;
+ while (count--) {
+ double relheight = movexy_r*height - zoffset;
+ double v = safe_sqrt(arm_sd2 - relheight*relheight);
+ double pos = start_pos + movez_r*height + (sdir ? -v : v);
+ v = safe_sqrt(pos * accel_multiplier);
+ int ret = queue_append(&qa, accel_multiplier >= 0. ? v : -v);
+ if (ret)
+ return ret;
+ height += (sdir ? 1. : -1.);
+ }
+ queue_append_finish(qa);
+ }
+ return res;
+}
+
+int32_t __visible
+stepcompress_push_delta(
+ struct stepcompress *sc, double print_time, double move_sd
+ , double start_sv, double accel
+ , double height, double startxy_sd, double arm_sd, double movez_r)
+{
+ double reversexy_sd = startxy_sd + arm_sd*movez_r;
+ if (reversexy_sd <= 0.)
+ // All steps are in down direction
+ return _stepcompress_push_delta(
+ sc, 0, print_time, move_sd, start_sv, accel
+ , height, startxy_sd, arm_sd, movez_r);
+ double movexy_r = movez_r ? sqrt(1. - movez_r*movez_r) : 1.;
+ if (reversexy_sd >= move_sd * movexy_r)
+ // All steps are in up direction
+ return _stepcompress_push_delta(
+ sc, 1, print_time, move_sd, start_sv, accel
+ , height, startxy_sd, arm_sd, movez_r);
+ // Steps in both up and down direction
+ int res1 = _stepcompress_push_delta(
+ sc, 1, print_time, reversexy_sd / movexy_r, start_sv, accel
+ , height, startxy_sd, arm_sd, movez_r);
+ if (res1 == ERROR_RET)
+ return res1;
+ int res2 = _stepcompress_push_delta(
+ sc, 0, print_time, move_sd, start_sv, accel
+ , height + res1, startxy_sd, arm_sd, movez_r);
+ if (res2 == ERROR_RET)
+ return res2;
+ return res1 + res2;
+}
diff --git a/klippy/chelper/stepcompress.c b/klippy/chelper/stepcompress.c
index 6e7a80d4..e6b4da0b 100644
--- a/klippy/chelper/stepcompress.c
+++ b/klippy/chelper/stepcompress.c
@@ -14,7 +14,6 @@
// This code is written in C (instead of python) for processing
// efficiency - the repetitive integer math is vastly faster in C.
-#include <math.h> // sqrt
#include <stddef.h> // offsetof
#include <stdint.h> // uint32_t
#include <stdio.h> // fprintf
@@ -23,6 +22,7 @@
#include "compiler.h" // DIV_ROUND_UP
#include "pyhelper.h" // errorf
#include "serialqueue.h" // struct queue_message
+#include "stepcompress.h" // stepcompress_alloc
#define CHECK_LINES 1
#define QUEUE_START_SIZE 1024
@@ -186,8 +186,6 @@ compress_bisect_add(struct stepcompress *sc)
* Step compress checking
****************************************************************/
-#define ERROR_RET -989898989
-
// Verify that a given 'step_move' matches the actual step times
static int
check_line(struct stepcompress *sc, struct step_move move)
@@ -309,7 +307,7 @@ stepcompress_flush_far(struct stepcompress *sc, uint64_t abs_step_clock)
}
// Send the set_next_step_dir command
-static int
+int
set_next_step_dir(struct stepcompress *sc, int sdir)
{
if (sc->sdir == sdir)
@@ -373,22 +371,28 @@ stepcompress_set_time(struct stepcompress *sc
sc->mcu_freq = mcu_freq;
}
+double
+stepcompress_get_mcu_freq(struct stepcompress *sc)
+{
+ return sc->mcu_freq;
+}
+
+uint32_t
+stepcompress_get_oid(struct stepcompress *sc)
+{
+ return sc->oid;
+}
+
/****************************************************************
* Queue management
****************************************************************/
-struct queue_append {
- struct stepcompress *sc;
- uint32_t *qnext, *qend, last_step_clock_32;
- double clock_offset;
-};
-
// Maximium clock delta between messages in the queue
#define CLOCK_DIFF_MAX (3<<28)
// Create a cursor for inserting clock times into the queue
-static inline struct queue_append
+inline struct queue_append
queue_append_start(struct stepcompress *sc, double print_time, double adjust)
{
double print_clock = (print_time - sc->mcu_time_offset) * sc->mcu_freq;
@@ -399,7 +403,7 @@ queue_append_start(struct stepcompress *sc, double print_time, double adjust)
}
// Finalize a cursor created with queue_append_start()
-static inline void
+inline void
queue_append_finish(struct queue_append qa)
{
qa.sc->queue_next = qa.qnext;
@@ -453,7 +457,7 @@ queue_append_slow(struct stepcompress *sc, double rel_sc)
}
// Add a clock time to the queue (flushing the queue if needed)
-static inline int
+inline int
queue_append(struct queue_append *qa, double step_clock)
{
double rel_sc = step_clock + qa->clock_offset;
@@ -477,235 +481,6 @@ queue_append(struct queue_append *qa, double step_clock)
/****************************************************************
- * Motion to step conversions
- ****************************************************************/
-
-// Common suffixes: _sd is step distance (a unit length the same
-// distance the stepper moves on each step), _sv is step velocity (in
-// units of step distance per time), _sd2 is step distance squared, _r
-// is ratio (scalar usually between 0.0 and 1.0). Times are in
-// seconds and acceleration is in units of step distance per second
-// squared.
-
-// Wrapper around sqrt() to handle small negative numbers
-static double
-_safe_sqrt(double v)
-{
- // Due to floating point truncation, it's possible to get a small
- // negative number - treat it as zero.
- if (v < -0.001)
- errorf("safe_sqrt of %.9f", v);
- return 0.;
-}
-static inline double safe_sqrt(double v) {
- return likely(v >= 0.) ? sqrt(v) : _safe_sqrt(v);
-}
-
-// Schedule a step event at the specified step_clock time
-int32_t __visible
-stepcompress_push(struct stepcompress *sc, double print_time, int32_t sdir)
-{
- int ret = set_next_step_dir(sc, !!sdir);
- if (ret)
- return ret;
- struct queue_append qa = queue_append_start(sc, print_time, 0.5);
- ret = queue_append(&qa, 0.);
- if (ret)
- return ret;
- queue_append_finish(qa);
- return sdir ? 1 : -1;
-}
-
-// Schedule 'steps' number of steps at constant acceleration. If
-// acceleration is zero (ie, constant velocity) it uses the formula:
-// step_time = print_time + step_num/start_sv
-// Otherwise it uses the formula:
-// step_time = (print_time + sqrt(2*step_num/accel + (start_sv/accel)**2)
-// - start_sv/accel)
-int32_t __visible
-stepcompress_push_const(
- struct stepcompress *sc, double print_time
- , double step_offset, double steps, double start_sv, double accel)
-{
- // Calculate number of steps to take
- int sdir = 1;
- if (steps < 0) {
- sdir = 0;
- steps = -steps;
- step_offset = -step_offset;
- }
- int count = steps + .5 - step_offset;
- if (count <= 0 || count > 10000000) {
- if (count && steps) {
- errorf("push_const invalid count %d %f %f %f %f %f"
- , sc->oid, print_time, step_offset, steps
- , start_sv, accel);
- return ERROR_RET;
- }
- return 0;
- }
- int ret = set_next_step_dir(sc, sdir);
- if (ret)
- return ret;
- int res = sdir ? count : -count;
-
- // Calculate each step time
- if (!accel) {
- // Move at constant velocity (zero acceleration)
- struct queue_append qa = queue_append_start(sc, print_time, .5);
- double inv_cruise_sv = sc->mcu_freq / start_sv;
- double pos = (step_offset + .5) * inv_cruise_sv;
- while (count--) {
- ret = queue_append(&qa, pos);
- if (ret)
- return ret;
- pos += inv_cruise_sv;
- }
- queue_append_finish(qa);
- } else {
- // Move with constant acceleration
- double inv_accel = 1. / accel;
- double accel_time = start_sv * inv_accel * sc->mcu_freq;
- struct queue_append qa = queue_append_start(
- sc, print_time, 0.5 - accel_time);
- double accel_multiplier = 2. * inv_accel * sc->mcu_freq * sc->mcu_freq;
- double pos = (step_offset + .5)*accel_multiplier + accel_time*accel_time;
- while (count--) {
- double v = safe_sqrt(pos);
- int ret = queue_append(&qa, accel_multiplier >= 0. ? v : -v);
- if (ret)
- return ret;
- pos += accel_multiplier;
- }
- queue_append_finish(qa);
- }
- return res;
-}
-
-// Schedule steps using delta kinematics
-static int32_t
-_stepcompress_push_delta(
- struct stepcompress *sc, int sdir
- , double print_time, double move_sd, double start_sv, double accel
- , double height, double startxy_sd, double arm_sd, double movez_r)
-{
- // Calculate number of steps to take
- double movexy_r = movez_r ? sqrt(1. - movez_r*movez_r) : 1.;
- double arm_sd2 = arm_sd * arm_sd;
- double endxy_sd = startxy_sd - movexy_r*move_sd;
- double end_height = safe_sqrt(arm_sd2 - endxy_sd*endxy_sd);
- int count = (end_height + movez_r*move_sd - height) * (sdir ? 1. : -1.) + .5;
- if (count <= 0 || count > 10000000) {
- if (count) {
- errorf("push_delta invalid count %d %d %f %f %f %f %f %f %f %f"
- , sc->oid, count, print_time, move_sd, start_sv, accel
- , height, startxy_sd, arm_sd, movez_r);
- return ERROR_RET;
- }
- return 0;
- }
- int ret = set_next_step_dir(sc, sdir);
- if (ret)
- return ret;
- int res = sdir ? count : -count;
-
- // Calculate each step time
- height += (sdir ? .5 : -.5);
- if (!accel) {
- // Move at constant velocity (zero acceleration)
- struct queue_append qa = queue_append_start(sc, print_time, .5);
- double inv_cruise_sv = sc->mcu_freq / start_sv;
- if (!movez_r) {
- // Optimized case for common XY only moves (no Z movement)
- while (count--) {
- double v = safe_sqrt(arm_sd2 - height*height);
- double pos = startxy_sd + (sdir ? -v : v);
- int ret = queue_append(&qa, pos * inv_cruise_sv);
- if (ret)
- return ret;
- height += (sdir ? 1. : -1.);
- }
- } else if (!movexy_r) {
- // Optimized case for Z only moves
- double pos = ((sdir ? height-end_height : end_height-height)
- * inv_cruise_sv);
- while (count--) {
- int ret = queue_append(&qa, pos);
- if (ret)
- return ret;
- pos += inv_cruise_sv;
- }
- } else {
- // General case (handles XY+Z moves)
- double start_pos = movexy_r*startxy_sd, zoffset = movez_r*startxy_sd;
- while (count--) {
- double relheight = movexy_r*height - zoffset;
- double v = safe_sqrt(arm_sd2 - relheight*relheight);
- double pos = start_pos + movez_r*height + (sdir ? -v : v);
- int ret = queue_append(&qa, pos * inv_cruise_sv);
- if (ret)
- return ret;
- height += (sdir ? 1. : -1.);
- }
- }
- queue_append_finish(qa);
- } else {
- // Move with constant acceleration
- double start_pos = movexy_r*startxy_sd, zoffset = movez_r*startxy_sd;
- double inv_accel = 1. / accel;
- start_pos += 0.5 * start_sv*start_sv * inv_accel;
- struct queue_append qa = queue_append_start(
- sc, print_time, 0.5 - start_sv * inv_accel * sc->mcu_freq);
- double accel_multiplier = 2. * inv_accel * sc->mcu_freq * sc->mcu_freq;
- while (count--) {
- double relheight = movexy_r*height - zoffset;
- double v = safe_sqrt(arm_sd2 - relheight*relheight);
- double pos = start_pos + movez_r*height + (sdir ? -v : v);
- v = safe_sqrt(pos * accel_multiplier);
- int ret = queue_append(&qa, accel_multiplier >= 0. ? v : -v);
- if (ret)
- return ret;
- height += (sdir ? 1. : -1.);
- }
- queue_append_finish(qa);
- }
- return res;
-}
-
-int32_t __visible
-stepcompress_push_delta(
- struct stepcompress *sc, double print_time, double move_sd
- , double start_sv, double accel
- , double height, double startxy_sd, double arm_sd, double movez_r)
-{
- double reversexy_sd = startxy_sd + arm_sd*movez_r;
- if (reversexy_sd <= 0.)
- // All steps are in down direction
- return _stepcompress_push_delta(
- sc, 0, print_time, move_sd, start_sv, accel
- , height, startxy_sd, arm_sd, movez_r);
- double movexy_r = movez_r ? sqrt(1. - movez_r*movez_r) : 1.;
- if (reversexy_sd >= move_sd * movexy_r)
- // All steps are in up direction
- return _stepcompress_push_delta(
- sc, 1, print_time, move_sd, start_sv, accel
- , height, startxy_sd, arm_sd, movez_r);
- // Steps in both up and down direction
- int res1 = _stepcompress_push_delta(
- sc, 1, print_time, reversexy_sd / movexy_r, start_sv, accel
- , height, startxy_sd, arm_sd, movez_r);
- if (res1 == ERROR_RET)
- return res1;
- int res2 = _stepcompress_push_delta(
- sc, 0, print_time, move_sd, start_sv, accel
- , height + res1, startxy_sd, arm_sd, movez_r);
- if (res2 == ERROR_RET)
- return res2;
- return res1 + res2;
-}
-
-
-/****************************************************************
* Step compress synchronization
****************************************************************/
diff --git a/klippy/chelper/stepcompress.h b/klippy/chelper/stepcompress.h
new file mode 100644
index 00000000..2a2fe725
--- /dev/null
+++ b/klippy/chelper/stepcompress.h
@@ -0,0 +1,40 @@
+#ifndef STEPCOMPRESS_H
+#define STEPCOMPRESS_H
+
+#include <stdint.h> // uint32_t
+
+#define ERROR_RET -989898989
+
+struct stepcompress *stepcompress_alloc(
+ uint32_t max_error, uint32_t queue_step_msgid
+ , uint32_t set_next_step_dir_msgid, uint32_t invert_sdir, uint32_t oid);
+void stepcompress_free(struct stepcompress *sc);
+int set_next_step_dir(struct stepcompress *sc, int sdir);
+int stepcompress_reset(struct stepcompress *sc, uint64_t last_step_clock);
+int stepcompress_set_homing(struct stepcompress *sc, uint64_t homing_clock);
+int stepcompress_queue_msg(struct stepcompress *sc, uint32_t *data, int len);
+double stepcompress_get_mcu_freq(struct stepcompress *sc);
+uint32_t stepcompress_get_oid(struct stepcompress *sc);
+
+struct queue_append {
+ struct stepcompress *sc;
+ uint32_t *qnext, *qend, last_step_clock_32;
+ double clock_offset;
+};
+struct queue_append queue_append_start(
+ struct stepcompress *sc, double print_time, double adjust);
+void queue_append_finish(struct queue_append qa);
+int queue_append(struct queue_append *qa, double step_clock);
+
+struct serialqueue;
+struct steppersync *steppersync_alloc(
+ struct serialqueue *sq, struct stepcompress **sc_list, int sc_num
+ , int move_num);
+void steppersync_free(struct steppersync *ss);
+void steppersync_set_time(struct steppersync *ss, double time_offset
+ , double mcu_freq);
+int steppersync_flush(struct steppersync *ss, uint64_t move_clock);
+
+double safe_sqrt(double v);
+
+#endif // stepcompress.h