mirror of
https://github.com/Klipper3d/klipper.git
synced 2025-10-26 15:56:10 +01:00
steppersync: Support sending messages directly from syncemitter
Move msg_queue allocation from stepcompress to syncemitter. With this change the pwm_tool module does not need to allocate a stepcompress object. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
@@ -48,8 +48,6 @@ defs_stepcompress = """
|
|||||||
, uint64_t clock);
|
, uint64_t clock);
|
||||||
int stepcompress_queue_msg(struct stepcompress *sc
|
int stepcompress_queue_msg(struct stepcompress *sc
|
||||||
, uint32_t *data, int len);
|
, uint32_t *data, int len);
|
||||||
int stepcompress_queue_mq_msg(struct stepcompress *sc, uint64_t req_clock
|
|
||||||
, uint32_t *data, int len);
|
|
||||||
int stepcompress_extract_old(struct stepcompress *sc
|
int stepcompress_extract_old(struct stepcompress *sc
|
||||||
, struct pull_history_steps *p, int max
|
, struct pull_history_steps *p, int max
|
||||||
, uint64_t start_clock, uint64_t end_clock);
|
, uint64_t start_clock, uint64_t end_clock);
|
||||||
@@ -61,6 +59,8 @@ defs_stepcompress = """
|
|||||||
|
|
||||||
defs_steppersync = """
|
defs_steppersync = """
|
||||||
struct stepcompress *syncemitter_get_stepcompress(struct syncemitter *se);
|
struct stepcompress *syncemitter_get_stepcompress(struct syncemitter *se);
|
||||||
|
void syncemitter_queue_msg(struct syncemitter *se, uint64_t req_clock
|
||||||
|
, uint32_t *data, int len);
|
||||||
struct syncemitter *steppersync_alloc_syncemitter(struct steppersync *ss
|
struct syncemitter *steppersync_alloc_syncemitter(struct steppersync *ss
|
||||||
, char name[16], int alloc_stepcompress);
|
, char name[16], int alloc_stepcompress);
|
||||||
void steppersync_setup_movequeue(struct steppersync *ss
|
void steppersync_setup_movequeue(struct steppersync *ss
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ struct stepcompress {
|
|||||||
double mcu_time_offset, mcu_freq, last_step_print_time;
|
double mcu_time_offset, mcu_freq, last_step_print_time;
|
||||||
// Message generation
|
// Message generation
|
||||||
uint64_t last_step_clock;
|
uint64_t last_step_clock;
|
||||||
struct list_head msg_queue;
|
struct list_head *msg_queue;
|
||||||
uint32_t oid;
|
uint32_t oid;
|
||||||
int32_t queue_step_msgtag, set_next_step_dir_msgtag;
|
int32_t queue_step_msgtag, set_next_step_dir_msgtag;
|
||||||
int sdir, invert_sdir;
|
int sdir, invert_sdir;
|
||||||
@@ -258,13 +258,13 @@ static void sc_thread_free(struct stepcompress *sc);
|
|||||||
|
|
||||||
// Allocate a new 'stepcompress' object
|
// Allocate a new 'stepcompress' object
|
||||||
struct stepcompress *
|
struct stepcompress *
|
||||||
stepcompress_alloc(char name[16])
|
stepcompress_alloc(char name[16], struct list_head *msg_queue)
|
||||||
{
|
{
|
||||||
struct stepcompress *sc = malloc(sizeof(*sc));
|
struct stepcompress *sc = malloc(sizeof(*sc));
|
||||||
memset(sc, 0, sizeof(*sc));
|
memset(sc, 0, sizeof(*sc));
|
||||||
list_init(&sc->msg_queue);
|
|
||||||
list_init(&sc->history_list);
|
list_init(&sc->history_list);
|
||||||
sc->sdir = -1;
|
sc->sdir = -1;
|
||||||
|
sc->msg_queue = msg_queue;
|
||||||
|
|
||||||
int ret = sc_thread_alloc(sc, name);
|
int ret = sc_thread_alloc(sc, name);
|
||||||
if (ret)
|
if (ret)
|
||||||
@@ -317,7 +317,6 @@ stepcompress_free(struct stepcompress *sc)
|
|||||||
return;
|
return;
|
||||||
sc_thread_free(sc);
|
sc_thread_free(sc);
|
||||||
free(sc->queue);
|
free(sc->queue);
|
||||||
message_queue_free(&sc->msg_queue);
|
|
||||||
stepcompress_history_expire(sc, UINT64_MAX);
|
stepcompress_history_expire(sc, UINT64_MAX);
|
||||||
free(sc);
|
free(sc);
|
||||||
}
|
}
|
||||||
@@ -334,12 +333,6 @@ stepcompress_get_step_dir(struct stepcompress *sc)
|
|||||||
return sc->next_step_dir;
|
return sc->next_step_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct list_head *
|
|
||||||
stepcompress_get_msg_queue(struct stepcompress *sc)
|
|
||||||
{
|
|
||||||
return &sc->msg_queue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine the "print time" of the last_step_clock
|
// Determine the "print time" of the last_step_clock
|
||||||
static void
|
static void
|
||||||
calc_last_step_print_time(struct stepcompress *sc)
|
calc_last_step_print_time(struct stepcompress *sc)
|
||||||
@@ -377,7 +370,7 @@ add_move(struct stepcompress *sc, uint64_t first_clock, struct step_move *move)
|
|||||||
qm->min_clock = qm->req_clock = sc->last_step_clock;
|
qm->min_clock = qm->req_clock = sc->last_step_clock;
|
||||||
if (move->count == 1 && first_clock >= sc->last_step_clock + CLOCK_DIFF_MAX)
|
if (move->count == 1 && first_clock >= sc->last_step_clock + CLOCK_DIFF_MAX)
|
||||||
qm->req_clock = first_clock;
|
qm->req_clock = first_clock;
|
||||||
list_add_tail(&qm->node, &sc->msg_queue);
|
list_add_tail(&qm->node, sc->msg_queue);
|
||||||
sc->last_step_clock = last_clock;
|
sc->last_step_clock = last_clock;
|
||||||
|
|
||||||
// Create and store move in history tracking
|
// Create and store move in history tracking
|
||||||
@@ -441,7 +434,7 @@ set_next_step_dir(struct stepcompress *sc, int sdir)
|
|||||||
};
|
};
|
||||||
struct queue_message *qm = message_alloc_and_encode(msg, 3);
|
struct queue_message *qm = message_alloc_and_encode(msg, 3);
|
||||||
qm->req_clock = sc->last_step_clock;
|
qm->req_clock = sc->last_step_clock;
|
||||||
list_add_tail(&qm->node, &sc->msg_queue);
|
list_add_tail(&qm->node, sc->msg_queue);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -640,22 +633,7 @@ stepcompress_queue_msg(struct stepcompress *sc, uint32_t *data, int len)
|
|||||||
|
|
||||||
struct queue_message *qm = message_alloc_and_encode(data, len);
|
struct queue_message *qm = message_alloc_and_encode(data, len);
|
||||||
qm->req_clock = sc->last_step_clock;
|
qm->req_clock = sc->last_step_clock;
|
||||||
list_add_tail(&qm->node, &sc->msg_queue);
|
list_add_tail(&qm->node, sc->msg_queue);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Queue an mcu command that will consume space in the mcu move queue
|
|
||||||
int __visible
|
|
||||||
stepcompress_queue_mq_msg(struct stepcompress *sc, uint64_t req_clock
|
|
||||||
, uint32_t *data, int len)
|
|
||||||
{
|
|
||||||
int ret = stepcompress_flush(sc, UINT64_MAX);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
struct queue_message *qm = message_alloc_and_encode(data, len);
|
|
||||||
qm->min_clock = qm->req_clock = req_clock;
|
|
||||||
list_add_tail(&qm->node, &sc->msg_queue);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ struct pull_history_steps {
|
|||||||
int step_count, interval, add;
|
int step_count, interval, add;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stepcompress *stepcompress_alloc(char name[16]);
|
struct list_head;
|
||||||
|
struct stepcompress *stepcompress_alloc(char name[16]
|
||||||
|
, struct list_head *msg_queue);
|
||||||
void stepcompress_fill(struct stepcompress *sc, uint32_t oid, uint32_t max_error
|
void stepcompress_fill(struct stepcompress *sc, uint32_t oid, uint32_t max_error
|
||||||
, int32_t queue_step_msgtag
|
, int32_t queue_step_msgtag
|
||||||
, int32_t set_next_step_dir_msgtag);
|
, int32_t set_next_step_dir_msgtag);
|
||||||
@@ -21,7 +23,6 @@ void stepcompress_history_expire(struct stepcompress *sc, uint64_t end_clock);
|
|||||||
void stepcompress_free(struct stepcompress *sc);
|
void stepcompress_free(struct stepcompress *sc);
|
||||||
uint32_t stepcompress_get_oid(struct stepcompress *sc);
|
uint32_t stepcompress_get_oid(struct stepcompress *sc);
|
||||||
int stepcompress_get_step_dir(struct stepcompress *sc);
|
int stepcompress_get_step_dir(struct stepcompress *sc);
|
||||||
struct list_head *stepcompress_get_msg_queue(struct stepcompress *sc);
|
|
||||||
void stepcompress_set_time(struct stepcompress *sc
|
void stepcompress_set_time(struct stepcompress *sc
|
||||||
, double time_offset, double mcu_freq);
|
, double time_offset, double mcu_freq);
|
||||||
int stepcompress_append(struct stepcompress *sc, int sdir
|
int stepcompress_append(struct stepcompress *sc, int sdir
|
||||||
@@ -33,8 +34,6 @@ int stepcompress_set_last_position(struct stepcompress *sc, uint64_t clock
|
|||||||
int64_t stepcompress_find_past_position(struct stepcompress *sc
|
int64_t stepcompress_find_past_position(struct stepcompress *sc
|
||||||
, uint64_t clock);
|
, uint64_t clock);
|
||||||
int stepcompress_queue_msg(struct stepcompress *sc, uint32_t *data, int len);
|
int stepcompress_queue_msg(struct stepcompress *sc, uint32_t *data, int len);
|
||||||
int stepcompress_queue_mq_msg(struct stepcompress *sc, uint64_t req_clock
|
|
||||||
, uint32_t *data, int len);
|
|
||||||
int stepcompress_extract_old(struct stepcompress *sc
|
int stepcompress_extract_old(struct stepcompress *sc
|
||||||
, struct pull_history_steps *p, int max
|
, struct pull_history_steps *p, int max
|
||||||
, uint64_t start_clock, uint64_t end_clock);
|
, uint64_t start_clock, uint64_t end_clock);
|
||||||
|
|||||||
@@ -27,16 +27,29 @@
|
|||||||
struct syncemitter {
|
struct syncemitter {
|
||||||
// List node for storage in steppersync list
|
// List node for storage in steppersync list
|
||||||
struct list_node ss_node;
|
struct list_node ss_node;
|
||||||
|
// Transmit message queue
|
||||||
|
struct list_head msg_queue;
|
||||||
// Step compression and generation
|
// Step compression and generation
|
||||||
struct stepcompress *sc;
|
struct stepcompress *sc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Return this emitters 'struct stepcompress' (or NULL if not allocated)
|
||||||
struct stepcompress * __visible
|
struct stepcompress * __visible
|
||||||
syncemitter_get_stepcompress(struct syncemitter *se)
|
syncemitter_get_stepcompress(struct syncemitter *se)
|
||||||
{
|
{
|
||||||
return se->sc;
|
return se->sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Queue an mcu command that will consume space in the mcu move queue
|
||||||
|
void __visible
|
||||||
|
syncemitter_queue_msg(struct syncemitter *se, uint64_t req_clock
|
||||||
|
, uint32_t *data, int len)
|
||||||
|
{
|
||||||
|
struct queue_message *qm = message_alloc_and_encode(data, len);
|
||||||
|
qm->min_clock = qm->req_clock = req_clock;
|
||||||
|
list_add_tail(&qm->node, &se->msg_queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
* StepperSync - sort move queue for a micro-controller
|
* StepperSync - sort move queue for a micro-controller
|
||||||
@@ -65,8 +78,9 @@ steppersync_alloc_syncemitter(struct steppersync *ss, char name[16]
|
|||||||
struct syncemitter *se = malloc(sizeof(*se));
|
struct syncemitter *se = malloc(sizeof(*se));
|
||||||
memset(se, 0, sizeof(*se));
|
memset(se, 0, sizeof(*se));
|
||||||
list_add_tail(&se->ss_node, &ss->se_list);
|
list_add_tail(&se->ss_node, &ss->se_list);
|
||||||
|
list_init(&se->msg_queue);
|
||||||
if (alloc_stepcompress)
|
if (alloc_stepcompress)
|
||||||
se->sc = stepcompress_alloc(name);
|
se->sc = stepcompress_alloc(name, &se->msg_queue);
|
||||||
return se;
|
return se;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,10 +151,9 @@ steppersync_flush(struct steppersync *ss, uint64_t move_clock)
|
|||||||
struct queue_message *qm = NULL;
|
struct queue_message *qm = NULL;
|
||||||
struct syncemitter *se;
|
struct syncemitter *se;
|
||||||
list_for_each_entry(se, &ss->se_list, ss_node) {
|
list_for_each_entry(se, &ss->se_list, ss_node) {
|
||||||
struct list_head *sc_mq = stepcompress_get_msg_queue(se->sc);
|
if (!list_empty(&se->msg_queue)) {
|
||||||
if (!list_empty(sc_mq)) {
|
|
||||||
struct queue_message *m = list_first_entry(
|
struct queue_message *m = list_first_entry(
|
||||||
sc_mq, struct queue_message, node);
|
&se->msg_queue, struct queue_message, node);
|
||||||
if (m->req_clock < req_clock) {
|
if (m->req_clock < req_clock) {
|
||||||
qm = m;
|
qm = m;
|
||||||
req_clock = m->req_clock;
|
req_clock = m->req_clock;
|
||||||
@@ -205,6 +218,7 @@ steppersyncmgr_free(struct steppersyncmgr *ssm)
|
|||||||
&ss->se_list, struct syncemitter, ss_node);
|
&ss->se_list, struct syncemitter, ss_node);
|
||||||
list_del(&se->ss_node);
|
list_del(&se->ss_node);
|
||||||
stepcompress_free(se->sc);
|
stepcompress_free(se->sc);
|
||||||
|
message_queue_free(&se->msg_queue);
|
||||||
free(se);
|
free(se);
|
||||||
}
|
}
|
||||||
free(ss);
|
free(ss);
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
struct syncemitter;
|
struct syncemitter;
|
||||||
struct stepcompress *syncemitter_get_stepcompress(struct syncemitter *se);
|
struct stepcompress *syncemitter_get_stepcompress(struct syncemitter *se);
|
||||||
|
void syncemitter_queue_msg(struct syncemitter *se, uint64_t req_clock
|
||||||
|
, uint32_t *data, int len);
|
||||||
|
|
||||||
struct steppersync;
|
struct steppersync;
|
||||||
struct syncemitter *steppersync_alloc_syncemitter(
|
struct syncemitter *steppersync_alloc_syncemitter(
|
||||||
|
|||||||
@@ -77,13 +77,13 @@ class PrinterMotionQueuing:
|
|||||||
ss = ffi_lib.steppersyncmgr_alloc_steppersync(self.steppersyncmgr)
|
ss = ffi_lib.steppersyncmgr_alloc_steppersync(self.steppersyncmgr)
|
||||||
self.steppersyncs.append((mcu, ss))
|
self.steppersyncs.append((mcu, ss))
|
||||||
return ss
|
return ss
|
||||||
def allocate_stepcompress(self, mcu, name):
|
def allocate_syncemitter(self, mcu, name, alloc_stepcompress=True):
|
||||||
name = name.encode("utf-8")[:15]
|
name = name.encode("utf-8")[:15]
|
||||||
ss = self._lookup_steppersync(mcu)
|
ss = self._lookup_steppersync(mcu)
|
||||||
ffi_main, ffi_lib = chelper.get_ffi()
|
ffi_main, ffi_lib = chelper.get_ffi()
|
||||||
se = ffi_lib.steppersync_alloc_syncemitter(ss, name, True)
|
se = ffi_lib.steppersync_alloc_syncemitter(ss, name, alloc_stepcompress)
|
||||||
self.syncemitters.append(se)
|
self.syncemitters.append(se)
|
||||||
return ffi_lib.syncemitter_get_stepcompress(se)
|
return se
|
||||||
def setup_mcu_movequeue(self, mcu, serialqueue, move_count):
|
def setup_mcu_movequeue(self, mcu, serialqueue, move_count):
|
||||||
# Setup steppersync object for the mcu's main movequeue
|
# Setup steppersync object for the mcu's main movequeue
|
||||||
ffi_main, ffi_lib = chelper.get_ffi()
|
ffi_main, ffi_lib = chelper.get_ffi()
|
||||||
|
|||||||
@@ -18,9 +18,10 @@ class MCU_queued_pwm:
|
|||||||
printer = mcu.get_printer()
|
printer = mcu.get_printer()
|
||||||
sname = config.get_name().split()[-1]
|
sname = config.get_name().split()[-1]
|
||||||
self._motion_queuing = printer.load_object(config, 'motion_queuing')
|
self._motion_queuing = printer.load_object(config, 'motion_queuing')
|
||||||
self._stepqueue = self._motion_queuing.allocate_stepcompress(mcu, sname)
|
self._syncemitter = self._motion_queuing.allocate_syncemitter(
|
||||||
|
mcu, sname, alloc_stepcompress=False)
|
||||||
ffi_main, ffi_lib = chelper.get_ffi()
|
ffi_main, ffi_lib = chelper.get_ffi()
|
||||||
self._stepcompress_queue_mq_msg = ffi_lib.stepcompress_queue_mq_msg
|
self._syncemitter_queue_msg = ffi_lib.syncemitter_queue_msg
|
||||||
mcu.register_config_callback(self._build_config)
|
mcu.register_config_callback(self._build_config)
|
||||||
self._pin = pin_params['pin']
|
self._pin = pin_params['pin']
|
||||||
self._invert = pin_params['invert']
|
self._invert = pin_params['invert']
|
||||||
@@ -107,10 +108,7 @@ class MCU_queued_pwm:
|
|||||||
self._last_clock = clock = max(self._last_clock, clock)
|
self._last_clock = clock = max(self._last_clock, clock)
|
||||||
self._last_value = val
|
self._last_value = val
|
||||||
data = (self._set_cmd_tag, self._oid, clock & 0xffffffff, val)
|
data = (self._set_cmd_tag, self._oid, clock & 0xffffffff, val)
|
||||||
ret = self._stepcompress_queue_mq_msg(self._stepqueue, clock,
|
self._syncemitter_queue_msg(self._syncemitter, clock, data, len(data))
|
||||||
data, len(data))
|
|
||||||
if ret:
|
|
||||||
raise error("Internal error in stepcompress")
|
|
||||||
# Notify toolhead so that it will flush this update
|
# Notify toolhead so that it will flush this update
|
||||||
wakeclock = clock
|
wakeclock = clock
|
||||||
if self._last_value != self._default_value:
|
if self._last_value != self._default_value:
|
||||||
|
|||||||
@@ -45,8 +45,9 @@ class MCU_stepper:
|
|||||||
self._active_callbacks = []
|
self._active_callbacks = []
|
||||||
motion_queuing = printer.load_object(config, 'motion_queuing')
|
motion_queuing = printer.load_object(config, 'motion_queuing')
|
||||||
sname = self._name.split()[-1]
|
sname = self._name.split()[-1]
|
||||||
self._stepqueue = motion_queuing.allocate_stepcompress(mcu, sname)
|
syncemitter = motion_queuing.allocate_syncemitter(mcu, sname)
|
||||||
ffi_main, ffi_lib = chelper.get_ffi()
|
ffi_main, ffi_lib = chelper.get_ffi()
|
||||||
|
self._stepqueue = ffi_lib.syncemitter_get_stepcompress(syncemitter)
|
||||||
ffi_lib.stepcompress_set_invert_sdir(self._stepqueue, self._invert_dir)
|
ffi_lib.stepcompress_set_invert_sdir(self._stepqueue, self._invert_dir)
|
||||||
self._stepper_kinematics = None
|
self._stepper_kinematics = None
|
||||||
self._itersolve_check_active = ffi_lib.itersolve_check_active
|
self._itersolve_check_active = ffi_lib.itersolve_check_active
|
||||||
|
|||||||
Reference in New Issue
Block a user