mirror of
https://github.com/Klipper3d/klipper.git
synced 2025-10-26 07:46:11 +01:00
steppersync: Add new steppersyncmgr_gen_steps() function
Generate and flush all the steppersync instances from a single steppersyncmgr_gen_steps() call. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
@@ -63,16 +63,13 @@ defs_stepcompress = """
|
||||
defs_steppersync = """
|
||||
void steppersync_set_time(struct steppersync *ss
|
||||
, double time_offset, double mcu_freq);
|
||||
void steppersync_history_expire(struct steppersync *ss, uint64_t end_clock);
|
||||
void steppersync_start_gen_steps(struct steppersync *ss
|
||||
, double gen_steps_time, uint64_t flush_clock);
|
||||
int32_t steppersync_finalize_gen_steps(struct steppersync *ss
|
||||
, uint64_t flush_clock);
|
||||
struct steppersyncmgr *steppersyncmgr_alloc(void);
|
||||
void steppersyncmgr_free(struct steppersyncmgr *ssm);
|
||||
struct steppersync *steppersyncmgr_alloc_steppersync(
|
||||
struct steppersyncmgr *ssm, struct serialqueue *sq
|
||||
, struct stepcompress **sc_list, int sc_num, int move_num);
|
||||
int32_t steppersyncmgr_gen_steps(struct steppersyncmgr *ssm
|
||||
, double flush_time, double gen_steps_time, double clear_history_time);
|
||||
"""
|
||||
|
||||
defs_itersolve = """
|
||||
|
||||
@@ -33,6 +33,8 @@ struct steppersync {
|
||||
// Storage for associated stepcompress objects
|
||||
struct stepcompress **sc_list;
|
||||
int sc_num;
|
||||
// Convert from time to clock
|
||||
struct clock_estimate ce;
|
||||
// Storage for list of pending move clocks
|
||||
uint64_t *move_clocks;
|
||||
int num_move_clocks;
|
||||
@@ -76,6 +78,7 @@ void __visible
|
||||
steppersync_set_time(struct steppersync *ss, double time_offset
|
||||
, double mcu_freq)
|
||||
{
|
||||
clock_fill(&ss->ce, mcu_freq, time_offset, 0, 0);
|
||||
int i;
|
||||
for (i=0; i<ss->sc_num; i++) {
|
||||
struct stepcompress *sc = ss->sc_list[i];
|
||||
@@ -83,17 +86,6 @@ steppersync_set_time(struct steppersync *ss, double time_offset
|
||||
}
|
||||
}
|
||||
|
||||
// Expire the stepcompress history before the given clock time
|
||||
void __visible
|
||||
steppersync_history_expire(struct steppersync *ss, uint64_t end_clock)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ss->sc_num; i++) {
|
||||
struct stepcompress *sc = ss->sc_list[i];
|
||||
stepcompress_history_expire(sc, end_clock);
|
||||
}
|
||||
}
|
||||
|
||||
// Implement a binary heap algorithm to track when the next available
|
||||
// 'struct move' in the mcu will be available
|
||||
static void
|
||||
@@ -165,36 +157,6 @@ steppersync_flush(struct steppersync *ss, uint64_t move_clock)
|
||||
serialqueue_send_batch(ss->sq, ss->cq, &msgs);
|
||||
}
|
||||
|
||||
// Start generating steps in stepcompress objects
|
||||
void __visible
|
||||
steppersync_start_gen_steps(struct steppersync *ss, double gen_steps_time
|
||||
, uint64_t flush_clock)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<ss->sc_num; i++) {
|
||||
struct stepcompress *sc = ss->sc_list[i];
|
||||
stepcompress_start_gen_steps(sc, gen_steps_time, flush_clock);
|
||||
}
|
||||
}
|
||||
|
||||
// Finalize step generation and flush
|
||||
int32_t __visible
|
||||
steppersync_finalize_gen_steps(struct steppersync *ss, uint64_t flush_clock)
|
||||
{
|
||||
int i;
|
||||
int32_t res = 0;
|
||||
for (i=0; i<ss->sc_num; i++) {
|
||||
struct stepcompress *sc = ss->sc_list[i];
|
||||
int32_t ret = stepcompress_finalize_gen_steps(sc);
|
||||
if (ret)
|
||||
res = ret;
|
||||
}
|
||||
if (res)
|
||||
return res;
|
||||
steppersync_flush(ss, flush_clock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* StepperSyncMgr - manage a list of steppersync
|
||||
@@ -239,3 +201,47 @@ steppersyncmgr_alloc_steppersync(
|
||||
list_add_tail(&ss->ssm_node, &ssm->ss_list);
|
||||
return ss;
|
||||
}
|
||||
|
||||
// Generate and flush steps
|
||||
int32_t __visible
|
||||
steppersyncmgr_gen_steps(struct steppersyncmgr *ssm, double flush_time
|
||||
, double gen_steps_time, double clear_history_time)
|
||||
{
|
||||
struct steppersync *ss;
|
||||
// Start step generation threads
|
||||
list_for_each_entry(ss, &ssm->ss_list, ssm_node) {
|
||||
uint64_t flush_clock = clock_from_time(&ss->ce, flush_time);
|
||||
int i;
|
||||
for (i=0; i<ss->sc_num; i++) {
|
||||
struct stepcompress *sc = ss->sc_list[i];
|
||||
stepcompress_start_gen_steps(sc, gen_steps_time, flush_clock);
|
||||
}
|
||||
}
|
||||
// Wait for step generation threads to complete
|
||||
int32_t res = 0;
|
||||
list_for_each_entry(ss, &ssm->ss_list, ssm_node) {
|
||||
int i;
|
||||
for (i=0; i<ss->sc_num; i++) {
|
||||
struct stepcompress *sc = ss->sc_list[i];
|
||||
int32_t ret = stepcompress_finalize_gen_steps(sc);
|
||||
if (ret)
|
||||
res = ret;
|
||||
}
|
||||
if (res)
|
||||
continue;
|
||||
uint64_t flush_clock = clock_from_time(&ss->ce, flush_time);
|
||||
steppersync_flush(ss, flush_clock);
|
||||
}
|
||||
if (res)
|
||||
return res;
|
||||
// Clear history
|
||||
list_for_each_entry(ss, &ssm->ss_list, ssm_node) {
|
||||
uint64_t end_clock = clock_from_time(&ss->ce, clear_history_time);
|
||||
int i;
|
||||
for (i = 0; i < ss->sc_num; i++) {
|
||||
struct stepcompress *sc = ss->sc_list[i];
|
||||
stepcompress_history_expire(sc, end_clock);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -6,11 +6,6 @@
|
||||
struct steppersync;
|
||||
void steppersync_set_time(struct steppersync *ss, double time_offset
|
||||
, double mcu_freq);
|
||||
void steppersync_history_expire(struct steppersync *ss, uint64_t end_clock);
|
||||
void steppersync_start_gen_steps(struct steppersync *ss, double gen_steps_time
|
||||
, uint64_t flush_clock);
|
||||
int32_t steppersync_finalize_gen_steps(struct steppersync *ss
|
||||
, uint64_t flush_clock);
|
||||
|
||||
struct steppersyncmgr *steppersyncmgr_alloc(void);
|
||||
void steppersyncmgr_free(struct steppersyncmgr *ssm);
|
||||
@@ -18,5 +13,8 @@ struct serialqueue;
|
||||
struct steppersync *steppersyncmgr_alloc_steppersync(
|
||||
struct steppersyncmgr *ssm, struct serialqueue *sq
|
||||
, struct stepcompress **sc_list, int sc_num, int move_num);
|
||||
int32_t steppersyncmgr_gen_steps(struct steppersyncmgr *ssm, double flush_time
|
||||
, double gen_steps_time
|
||||
, double clear_history_time);
|
||||
|
||||
#endif // steppersync.h
|
||||
|
||||
@@ -33,10 +33,7 @@ class PrinterMotionQueuing:
|
||||
ffi_lib.steppersyncmgr_free)
|
||||
self.stepcompress = []
|
||||
self.steppersyncs = []
|
||||
self.steppersync_start_gen_steps = ffi_lib.steppersync_start_gen_steps
|
||||
self.steppersync_finalize_gen_steps = \
|
||||
ffi_lib.steppersync_finalize_gen_steps
|
||||
self.steppersync_history_expire = ffi_lib.steppersync_history_expire
|
||||
self.steppersyncmgr_gen_steps = ffi_lib.steppersyncmgr_gen_steps
|
||||
# History expiration
|
||||
self.clear_history_time = 0.
|
||||
# Flush notification callbacks
|
||||
@@ -101,7 +98,7 @@ class PrinterMotionQueuing:
|
||||
ffi_lib.steppersync_set_time(ss, offset, freq)
|
||||
# Calculate history expiration
|
||||
est_print_time = self.mcu.estimated_print_time(eventtime)
|
||||
self.clear_history_time = est_print_time - MOVE_HISTORY_EXPIRE
|
||||
self.clear_history_time = max(0., est_print_time - MOVE_HISTORY_EXPIRE)
|
||||
return False, ""
|
||||
# Flush notification callbacks
|
||||
def register_flush_callback(self, callback, can_add_trapq=False):
|
||||
@@ -142,31 +139,22 @@ class PrinterMotionQueuing:
|
||||
# Invoke flush callbacks (if any)
|
||||
for cb in self.flush_callbacks:
|
||||
cb(flush_time, step_gen_time)
|
||||
# Generate stepper movement and transmit
|
||||
for mcu, ss in self.steppersyncs:
|
||||
clock = max(0, mcu.print_time_to_clock(flush_time))
|
||||
self.steppersync_start_gen_steps(ss, step_gen_time, clock)
|
||||
for mcu, ss in self.steppersyncs:
|
||||
clock = max(0, mcu.print_time_to_clock(flush_time))
|
||||
ret = self.steppersync_finalize_gen_steps(ss, clock)
|
||||
if ret:
|
||||
raise mcu.error("Internal error in MCU '%s' stepcompress"
|
||||
% (mcu.get_name(),))
|
||||
self.last_flush_time = flush_time
|
||||
self.last_step_gen_time = step_gen_time
|
||||
# Determine maximum history to keep
|
||||
trapq_free_time = step_gen_time - self.kin_flush_delay
|
||||
clear_history_time = self.clear_history_time
|
||||
if not self.can_pause:
|
||||
clear_history_time = trapq_free_time - MOVE_HISTORY_EXPIRE
|
||||
# Move processed trapq moves to history list, and expire old history
|
||||
clear_history_time = max(0., trapq_free_time - MOVE_HISTORY_EXPIRE)
|
||||
# Generate stepper movement and transmit
|
||||
ret = self.steppersyncmgr_gen_steps(self.steppersyncmgr, flush_time,
|
||||
step_gen_time, clear_history_time)
|
||||
if ret:
|
||||
raise self.mcu.error("Internal error in stepcompress")
|
||||
self.last_flush_time = flush_time
|
||||
self.last_step_gen_time = step_gen_time
|
||||
# Move processed trapq entries to history list, and expire old history
|
||||
for trapq in self.trapqs:
|
||||
self.trapq_finalize_moves(trapq, trapq_free_time,
|
||||
clear_history_time)
|
||||
# Clean up old history entries in stepcompress objects
|
||||
for mcu, ss in self.steppersyncs:
|
||||
clock = max(0, mcu.print_time_to_clock(clear_history_time))
|
||||
self.steppersync_history_expire(ss, clock)
|
||||
def _await_flush_time(self, want_flush_time):
|
||||
while 1:
|
||||
if self.last_flush_time >= want_flush_time or not self.can_pause:
|
||||
|
||||
Reference in New Issue
Block a user