mirror of
				https://github.com/Klipper3d/klipper.git
				synced 2025-10-31 02:15:52 +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