From 81da5379d406236b8284921d34f23e877464db63 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Thu, 4 Feb 2021 16:33:03 -0500 Subject: [PATCH] buildcommands: Extend number of available mcu messages from 96 to 128 Some internal code treats the message ids as encoded "variable length quantities", while other internal code assumes the message id is always one byte long. Continue using this scheme, but convert the VLQ users to use the name "msgtag" while the 1-byte users use "msgid". Increase the number of available msgids from 96 to 127 - the higher values get encoded as negative "msgtags". Signed-off-by: Kevin O'Connor --- klippy/chelper/__init__.py | 6 +++--- klippy/chelper/stepcompress.c | 19 ++++++++++--------- klippy/chelper/stepcompress.h | 4 ++-- klippy/console.py | 2 +- klippy/mcu.py | 4 ++-- klippy/msgproto.py | 13 ++++++++----- klippy/stepper.py | 18 +++++++++--------- scripts/buildcommands.py | 27 +++++++++++++++------------ 8 files changed, 50 insertions(+), 43 deletions(-) diff --git a/klippy/chelper/__init__.py b/klippy/chelper/__init__.py index d373d72e..851fda70 100644 --- a/klippy/chelper/__init__.py +++ b/klippy/chelper/__init__.py @@ -1,6 +1,6 @@ # Wrapper around C helper code # -# Copyright (C) 2016-2020 Kevin O'Connor +# Copyright (C) 2016-2021 Kevin O'Connor # # This file may be distributed under the terms of the GNU GPLv3 license. import os, logging @@ -31,8 +31,8 @@ OTHER_FILES = [ defs_stepcompress = """ struct stepcompress *stepcompress_alloc(uint32_t oid); void stepcompress_fill(struct stepcompress *sc, uint32_t max_error - , uint32_t invert_sdir, uint32_t queue_step_msgid - , uint32_t set_next_step_dir_msgid); + , uint32_t invert_sdir, int32_t queue_step_msgtag + , int32_t set_next_step_dir_msgtag); void stepcompress_free(struct stepcompress *sc); int stepcompress_reset(struct stepcompress *sc, uint64_t last_step_clock); int stepcompress_queue_msg(struct stepcompress *sc diff --git a/klippy/chelper/stepcompress.c b/klippy/chelper/stepcompress.c index 812a3b50..cd803ae7 100644 --- a/klippy/chelper/stepcompress.c +++ b/klippy/chelper/stepcompress.c @@ -1,6 +1,6 @@ // Stepper pulse schedule compression // -// Copyright (C) 2016-2020 Kevin O'Connor +// Copyright (C) 2016-2021 Kevin O'Connor // // This file may be distributed under the terms of the GNU GPLv3 license. @@ -36,7 +36,8 @@ struct stepcompress { // Message generation uint64_t last_step_clock; struct list_head msg_queue; - uint32_t queue_step_msgid, set_next_step_dir_msgid, oid; + uint32_t oid; + int32_t queue_step_msgtag, set_next_step_dir_msgtag; int sdir, invert_sdir; // Step+dir+step filter uint64_t next_step_clock; @@ -244,13 +245,13 @@ stepcompress_alloc(uint32_t oid) // Fill message id information void __visible stepcompress_fill(struct stepcompress *sc, uint32_t max_error - , uint32_t invert_sdir, uint32_t queue_step_msgid - , uint32_t set_next_step_dir_msgid) + , uint32_t invert_sdir, int32_t queue_step_msgtag + , int32_t set_next_step_dir_msgtag) { sc->max_error = max_error; sc->invert_sdir = !!invert_sdir; - sc->queue_step_msgid = queue_step_msgid; - sc->set_next_step_dir_msgid = set_next_step_dir_msgid; + sc->queue_step_msgtag = queue_step_msgtag; + sc->set_next_step_dir_msgtag = set_next_step_dir_msgtag; } // Free memory associated with a 'stepcompress' object @@ -307,7 +308,7 @@ queue_flush(struct stepcompress *sc, uint64_t move_clock) return ret; uint32_t msg[5] = { - sc->queue_step_msgid, sc->oid, move.interval, move.count, move.add + sc->queue_step_msgtag, sc->oid, move.interval, move.count, move.add }; struct queue_message *qm = message_alloc_and_encode(msg, 5); qm->min_clock = qm->req_clock = sc->last_step_clock; @@ -331,7 +332,7 @@ static int stepcompress_flush_far(struct stepcompress *sc, uint64_t abs_step_clock) { uint32_t msg[5] = { - sc->queue_step_msgid, sc->oid, abs_step_clock - sc->last_step_clock, + sc->queue_step_msgtag, sc->oid, abs_step_clock - sc->last_step_clock, 1, 0 }; struct queue_message *qm = message_alloc_and_encode(msg, 5); @@ -353,7 +354,7 @@ set_next_step_dir(struct stepcompress *sc, int sdir) if (ret) return ret; uint32_t msg[3] = { - sc->set_next_step_dir_msgid, sc->oid, sdir ^ sc->invert_sdir + sc->set_next_step_dir_msgtag, sc->oid, sdir ^ sc->invert_sdir }; struct queue_message *qm = message_alloc_and_encode(msg, 3); qm->req_clock = sc->last_step_clock; diff --git a/klippy/chelper/stepcompress.h b/klippy/chelper/stepcompress.h index 3462b3f8..2d1534c1 100644 --- a/klippy/chelper/stepcompress.h +++ b/klippy/chelper/stepcompress.h @@ -7,8 +7,8 @@ struct stepcompress *stepcompress_alloc(uint32_t oid); void stepcompress_fill(struct stepcompress *sc, uint32_t max_error - , uint32_t invert_sdir, uint32_t queue_step_msgid - , uint32_t set_next_step_dir_msgid); + , uint32_t invert_sdir, int32_t queue_step_msgtag + , int32_t set_next_step_dir_msgtag); void stepcompress_free(struct stepcompress *sc); uint32_t stepcompress_get_oid(struct stepcompress *sc); int stepcompress_get_step_dir(struct stepcompress *sc); diff --git a/klippy/console.py b/klippy/console.py index 69095345..b787111f 100755 --- a/klippy/console.py +++ b/klippy/console.py @@ -138,7 +138,7 @@ class KeyboardReader: def command_LIST(self, parts): self.update_evals(self.reactor.monotonic()) mp = self.ser.get_msgparser() - cmds = [msgformat for msgid, msgtype, msgformat in mp.get_messages() + cmds = [msgformat for msgtag, msgtype, msgformat in mp.get_messages() if msgtype == 'command'] out = "Available mcu commands:" out += "\n ".join([""] + sorted(cmds)) diff --git a/klippy/mcu.py b/klippy/mcu.py index 6f6c8002..5e31602c 100644 --- a/klippy/mcu.py +++ b/klippy/mcu.py @@ -694,9 +694,9 @@ class MCU: return self.lookup_command(msgformat) except self._serial.get_msgparser().error as e: return None - def lookup_command_id(self, msgformat): + def lookup_command_tag(self, msgformat): all_msgs = self._serial.get_msgparser().get_messages() - return {msgfmt: msgid for msgid, msgtype, msgfmt in all_msgs}[msgformat] + return {fmt: msgtag for msgtag, msgtype, fmt in all_msgs}[msgformat] def get_enumerations(self): return self._serial.get_msgparser().get_enumerations() def get_constants(self): diff --git a/klippy/msgproto.py b/klippy/msgproto.py index d1f461b8..c3c0cda9 100644 --- a/klippy/msgproto.py +++ b/klippy/msgproto.py @@ -357,14 +357,17 @@ class MessageParser: start_value, count = value for i in range(count): enums[enum_root + str(start_enum + i)] = start_value + i - def _init_messages(self, messages, command_ids=[], output_ids=[]): - for msgformat, msgid in messages.items(): + def _init_messages(self, messages, command_tags=[], output_tags=[]): + for msgformat, msgtag in messages.items(): msgtype = 'response' - if msgid in command_ids: + if msgtag in command_tags: msgtype = 'command' - elif msgid in output_ids: + elif msgtag in output_tags: msgtype = 'output' - self.messages.append((msgid, msgtype, msgformat)) + self.messages.append((msgtag, msgtype, msgformat)) + if msgtag < -32 or msgtag > 95: + raise error("Multi-byte msgtag not supported") + msgid = msgtag & 0x7f if msgtype == 'output': self.messages_by_id[msgid] = OutputFormat(msgid, msgformat) else: diff --git a/klippy/stepper.py b/klippy/stepper.py index 1b1ad7ad..8ba0b5f1 100644 --- a/klippy/stepper.py +++ b/klippy/stepper.py @@ -1,6 +1,6 @@ # Printer stepper support # -# Copyright (C) 2016-2019 Kevin O'Connor +# Copyright (C) 2016-2021 Kevin O'Connor # # This file may be distributed under the terms of the GNU GPLv3 license. import math, logging, collections @@ -33,7 +33,7 @@ class MCU_stepper: self._invert_dir = dir_pin_params['invert'] self._mcu_position_offset = self._tag_position = 0. self._min_stop_interval = 0. - self._reset_cmd_id = self._get_position_cmd = None + self._reset_cmd_tag = self._get_position_cmd = None self._active_callbacks = [] ffi_main, self._ffi_lib = chelper.get_ffi() self._stepqueue = ffi_main.gc(self._ffi_lib.stepcompress_alloc(oid), @@ -78,18 +78,18 @@ class MCU_stepper: self._invert_step)) self._mcu.add_config_cmd("reset_step_clock oid=%d clock=0" % (self._oid,), on_restart=True) - step_cmd_id = self._mcu.lookup_command_id( + step_cmd_tag = self._mcu.lookup_command_tag( "queue_step oid=%c interval=%u count=%hu add=%hi") - dir_cmd_id = self._mcu.lookup_command_id( + dir_cmd_tag = self._mcu.lookup_command_tag( "set_next_step_dir oid=%c dir=%c") - self._reset_cmd_id = self._mcu.lookup_command_id( + self._reset_cmd_tag = self._mcu.lookup_command_tag( "reset_step_clock oid=%c clock=%u") self._get_position_cmd = self._mcu.lookup_query_command( "stepper_get_position oid=%c", "stepper_position oid=%c pos=%i", oid=self._oid) self._ffi_lib.stepcompress_fill( self._stepqueue, self._mcu.seconds_to_clock(max_error), - self._invert_dir, step_cmd_id, dir_cmd_id) + self._invert_dir, step_cmd_tag, dir_cmd_tag) def get_oid(self): return self._oid def get_step_dist(self): @@ -132,9 +132,9 @@ class MCU_stepper: ret = self._ffi_lib.stepcompress_reset(self._stepqueue, 0) if ret: raise error("Internal error in stepcompress") - data = (self._reset_cmd_id, self._oid, 0) - ret = self._ffi_lib.stepcompress_queue_msg( - self._stepqueue, data, len(data)) + data = (self._reset_cmd_tag, self._oid, 0) + ret = self._ffi_lib.stepcompress_queue_msg(self._stepqueue, data, + len(data)) if ret: raise error("Internal error in stepcompress") if not did_trigger or self._mcu.is_fileoutput(): diff --git a/scripts/buildcommands.py b/scripts/buildcommands.py index 9e811485..d41cab0f 100644 --- a/scripts/buildcommands.py +++ b/scripts/buildcommands.py @@ -286,22 +286,25 @@ class HandleCommandGeneration: if msg not in self.msg_to_id: msgid += 1 self.msg_to_id[msg] = msgid - if msgid >= 96: + if msgid >= 128: # The mcu currently assumes all message ids encode to one byte error("Too many message ids") def update_data_dictionary(self, data): - command_ids = [self.msg_to_id[msg] - for msgname, msg in self.messages_by_name.items() - if msgname in self.commands] - response_ids = [self.msg_to_id[msg] + # Handle message ids over 96 (they are decoded as negative numbers) + msg_to_tag = {msg: msgid if msgid < 96 else msgid - 128 + for msg, msgid in self.msg_to_id.items()} + command_tags = [msg_to_tag[msg] for msgname, msg in self.messages_by_name.items() - if msgname not in self.commands] - data['commands'] = { msg: msgid for msg, msgid in self.msg_to_id.items() - if msgid in command_ids } - data['responses'] = {msg: msgid for msg, msgid in self.msg_to_id.items() - if msgid in response_ids } - output = { msg: msgid for msg, msgid in self.msg_to_id.items() - if msgid not in command_ids and msgid not in response_ids } + if msgname in self.commands] + response_tags = [msg_to_tag[msg] + for msgname, msg in self.messages_by_name.items() + if msgname not in self.commands] + data['commands'] = { msg: msgtag for msg, msgtag in msg_to_tag.items() + if msgtag in command_tags } + data['responses'] = { msg: msgtag for msg, msgtag in msg_to_tag.items() + if msgtag in response_tags } + output = {msg: msgtag for msg, msgtag in msg_to_tag.items() + if msgtag not in command_tags and msgtag not in response_tags} if output: data['output'] = output def build_parser(self, msgid, msgformat, msgtype):