Parse the motor current the firmware echoes back in DUMP

This commit is contained in:
pgdalmeida 2026-09-17 17:58:46 +02:00
parent ffaa41ac2f
commit 9a61167aa6
Signed by: pedro.almeida
GPG Key ID: D4A6C394DF13F1D7
3 changed files with 42 additions and 0 deletions

View File

@ -21,6 +21,16 @@ struct DumpAxis {
long center_count = 0; // count the firmware anchored the homed midpoint to
long hold_target = 0;
long speed = 0;
// Motor current, as the firmware believes it applied it. GLOBALSCALER and
// IHOLD_IRUN are write-only on the TMC5160, so this echo is the only way the
// host can confirm a CURRENT command landed.
//
// -1 means the field was absent, i.e. the firmware predates the command -
// which is a different thing from "applied a current of zero" and has to stay
// distinguishable, because one is a version skew and the other is a fault.
long global_scaler = -1;
long run_irun = -1;
long homing_irun = -1;
// Encoder-tracking health accumulated by the firmware hold corrector.
long hold_corrections = 0; // # of hold resyncs since firmware boot/RESET
long hold_peak_dev = 0; // largest deviation seen while holding (counts)

View File

@ -162,6 +162,9 @@ DumpData parseDump(const std::string& block) {
ax.center_count = asInt(get(m, "center", "0"));
ax.hold_target = asInt(get(m, "hold_target", "0"));
ax.speed = asInt(get(m, "speed", "0"));
ax.global_scaler = asInt(get(m, "gs", "-1"));
ax.run_irun = asInt(get(m, "irun", "-1"));
ax.homing_irun = asInt(get(m, "irun_home", "-1"));
ax.hold_corrections = asInt(get(m, "hold_corr", "0"));
ax.hold_peak_dev = asInt(get(m, "hold_peak", "0"));
ax.hold_cumulative_dev = asInt(get(m, "hold_cumul", "0"));

View File

@ -136,3 +136,32 @@ TEST_CASE("formatDump renders valid and invalid dumps") {
CHECK(joined.find("[P]") != std::string::npos);
CHECK(joined.find("RAMP_STAT") != std::string::npos);
}
TEST_CASE("a DUMP axis line carries the motor current the firmware applied") {
auto d = parseDump(
"DUMP BEGIN build=abc uptime=1 mcusr=0x3 free_ram=100\n"
"DUMP Y state=3 hsub=0 enabled=1 lim_neg=-105389 lim_pos=1105389 hold_target=0 "
"speed=3000 center=500000 soft_margin=5000 gs=80 irun=31 irun_home=7 "
"hold_corr=0 hold_peak=0 hold_cumul=0 has_encoder=1\n"
"DUMP END\n");
REQUIRE(d.valid);
REQUIRE(d.axes.size() == 1);
CHECK(d.axes[0].global_scaler == 80);
CHECK(d.axes[0].run_irun == 31);
CHECK(d.axes[0].homing_irun == 7);
}
TEST_CASE("a DUMP from firmware without the current fields reports -1, not zero") {
// Zero is a legitimate IRUN; absent is a version skew. Conflating them would
// let an old firmware look like one configured to zero current.
auto d = parseDump(
"DUMP BEGIN build=abc uptime=1 mcusr=0x3 free_ram=100\n"
"DUMP Y state=3 hsub=0 enabled=1 lim_neg=0 lim_pos=0 hold_target=0 speed=3000 "
"center=500000 soft_margin=5000 hold_corr=0 hold_peak=0 hold_cumul=0 has_encoder=1\n"
"DUMP END\n");
REQUIRE(d.valid);
REQUIRE(d.axes.size() == 1);
CHECK(d.axes[0].global_scaler == -1);
CHECK(d.axes[0].run_irun == -1);
CHECK(d.axes[0].homing_irun == -1);
}