Skip to content

fix(gcode): M500 tells the user when persistence is disabled - #5305

Open
packerlschupfer wants to merge 1 commit into
prusa3d:masterfrom
packerlschupfer:pr/m500-explicit-noop
Open

fix(gcode): M500 tells the user when persistence is disabled#5305
packerlschupfer wants to merge 1 commit into
prusa3d:masterfrom
packerlschupfer:pr/m500-explicit-noop

Conversation

@packerlschupfer

Copy link
Copy Markdown

Summary

When a user runs M500 over USB serial (or via PrusaLink g-code passthrough), it currently replies ok and silently does nothing. This PR makes M500 emit an explicit user-visible message in that case so the user isn't fooled into thinking their settings were saved.

The current silent failure

MarlinSettings::save() in configuration_store.cpp is stubbed:

bool MarlinSettings::save() {
  DEBUG_ERROR_MSG("EEPROM disabled");
  return false;
}

DEBUG_ERROR_MSG is NOOP unless EEPROM_CHITCHAT is defined. Checking the configs:

$ grep -r 'EEPROM_CHITCHAT' include/marlin/
include/marlin/Configuration_*.h:  //#define EEPROM_CHITCHAT

It's commented out in every printer's Configuration header (MK3.5, MK4, MINI, XL, iX, COREONE, COREONEL, …). So DEBUG_ERROR_MSG expands to nothing, save() returns false, and the M500 G-code wrapper ignores the return value:

void GcodeSuite::M500() {
  (void)settings.save();
}

The user sees ok and assumes the save worked.

Why this matters

This is confusing during real workflows where users genuinely expect persistence:

  • After M303 PID autotune — Marlin's docs (and many tutorials) tell users to run M500 to save. They follow the steps, see ok, and don't realize nothing happened.
  • After M92 / M203 / M204 / M205 tuning — same issue.
  • After M301 PID set — actually persists via config_store, but only because M301's handler writes to the store directly, not via settings.save().

The machine-readable signal exists (Cap:EEPROM:0 in M115), but no normal user runs M115 to check before every M500.

The fix

void GcodeSuite::M500() {
  if (!settings.save()) {
    SERIAL_ECHO_MSG(\"Persistent EEPROM disabled; settings are runtime-only.\");
    SERIAL_ECHO_MSG(\"Use specific M-codes (M301/M304/M92/M203/etc.) — they persist via config_store.\");
  }
}

SERIAL_ECHO_MSG is unconditional and prefixes with echo:, which is the standard Marlin pattern for user-facing info.

No behavior change when EEPROM actually works (save() returns true). The existing Cap:EEPROM:0 in M115 is unchanged.

Test plan

  • Compiled against Core One (coreone_release_emptyboot).
  • On a printer where save() works (Marlin without the stub): no output change — save() returns true, message skipped.
  • On Buddy: M500 now emits the two echo: lines before the final ok.

Notes / scope

  • I considered also fixing M501 (which has a similar issue: load() is defined as reset(); report(); return true; — it reports success while actually just resetting to defaults). Decided to keep this PR focused on M500 since the M501 case has subtler semantics (load → reset is at least somewhat defensible at boot). Happy to add it here or in a follow-up.
  • An alternative would be to make MarlinSettings::save() itself emit a SERIAL_ECHO_MSG (not gated by EEPROM_CHITCHAT) so all callers benefit. Currently M500 is the only caller, so a wrapper-level fix has the same effect with less surface.

`MarlinSettings::save()` is stubbed on Buddy (returns `false` with a
debug-only `DEBUG_ERROR_MSG("EEPROM disabled")`). `DEBUG_ERROR_MSG` is
gated by `EEPROM_CHITCHAT` which is commented out in every Configuration
header in the tree, so the message is `NOOP`. M500 silently does nothing
and replies "ok" — users running it manually (during PID autotune,
calibration tweaks, etc.) think their settings were saved.

Persistence on Buddy actually goes through `config_store`, called by
specific M-codes (M301, M304, M92, M203, etc.). M500 has no equivalent
for these in the EEPROM-less codepath.

Make M500 explicitly tell the user when the underlying save did nothing:

  echo:Persistent EEPROM disabled; settings are runtime-only.
  echo:Use specific M-codes (M301/M304/M92/M203/etc.) — they persist via config_store.

No behavior change when EEPROM actually works (save() returns true).
M115's `Cap:EEPROM:0` still indicates the machine-readable state.
@packerlschupfer
packerlschupfer force-pushed the pr/m500-explicit-noop branch from 8c24b25 to aaec1a1 Compare July 26, 2026 19:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant