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 <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2021-02-04 16:33:03 -05:00
parent efa497dfd8
commit 81da5379d4
8 changed files with 50 additions and 43 deletions

View File

@ -1,6 +1,6 @@
# Wrapper around C helper code
#
# Copyright (C) 2016-2020 Kevin O'Connor <kevin@koconnor.net>
# Copyright (C) 2016-2021 Kevin O'Connor <kevin@koconnor.net>
#
# 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

View File

@ -1,6 +1,6 @@
// Stepper pulse schedule compression
//
// Copyright (C) 2016-2020 Kevin O'Connor <kevin@koconnor.net>
// Copyright (C) 2016-2021 Kevin O'Connor <kevin@koconnor.net>
//
// 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;

View File

@ -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);

View File

@ -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))

View File

@ -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):

View File

@ -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:

View File

@ -1,6 +1,6 @@
# Printer stepper support
#
# Copyright (C) 2016-2019 Kevin O'Connor <kevin@koconnor.net>
# Copyright (C) 2016-2021 Kevin O'Connor <kevin@koconnor.net>
#
# 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():

View File

@ -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):