mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2024-11-27 13:56:24 +00:00
🚸 Improve EEPROM validation (#25860)
This commit is contained in:
parent
62a7bba225
commit
09247e7ea9
@ -192,6 +192,7 @@
|
||||
#define STR_ERR_LONG_EXTRUDE_STOP " too long extrusion prevented"
|
||||
#define STR_ERR_HOTEND_TOO_COLD "Hotend too cold"
|
||||
#define STR_ERR_EEPROM_WRITE "Error writing to EEPROM!"
|
||||
#define STR_ERR_EEPROM_CORRUPT "EEPROM Corrupt"
|
||||
|
||||
#define STR_FILAMENT_CHANGE_HEAT_LCD "Press button to heat nozzle"
|
||||
#define STR_FILAMENT_CHANGE_INSERT_LCD "Insert filament and press button"
|
||||
|
@ -414,7 +414,7 @@ namespace Language_de {
|
||||
LSTR MSG_RESTORE_DEFAULTS = _UxGT("Standardwerte laden");
|
||||
LSTR MSG_INIT_EEPROM = _UxGT("Werkseinstellungen");
|
||||
LSTR MSG_ERR_EEPROM_CRC = _UxGT("EEPROM CRC Fehler");
|
||||
LSTR MSG_ERR_EEPROM_INDEX = _UxGT("EEPROM Index Fehler");
|
||||
LSTR MSG_ERR_EEPROM_SIZE = _UxGT("EEPROM Größe Fehler");
|
||||
LSTR MSG_ERR_EEPROM_VERSION = _UxGT("EEPROM Version Fehler");
|
||||
LSTR MSG_SETTINGS_STORED = _UxGT("Einstell. gespei.");
|
||||
LSTR MSG_MEDIA_UPDATE = _UxGT("FW Update vom Medium");
|
||||
|
@ -445,9 +445,10 @@ namespace Language_en {
|
||||
LSTR MSG_LOAD_EEPROM = _UxGT("Load Settings");
|
||||
LSTR MSG_RESTORE_DEFAULTS = _UxGT("Restore Defaults");
|
||||
LSTR MSG_INIT_EEPROM = _UxGT("Initialize EEPROM");
|
||||
LSTR MSG_ERR_EEPROM_CRC = _UxGT("EEPROM CRC Error");
|
||||
LSTR MSG_ERR_EEPROM_INDEX = _UxGT("EEPROM Index Error");
|
||||
LSTR MSG_ERR_EEPROM_VERSION = _UxGT("EEPROM Version Error");
|
||||
LSTR MSG_ERR_EEPROM_CRC = _UxGT("Err: EEPROM CRC");
|
||||
LSTR MSG_ERR_EEPROM_SIZE = _UxGT("Err: EEPROM Size");
|
||||
LSTR MSG_ERR_EEPROM_VERSION = _UxGT("Err: EEPROM Version");
|
||||
LSTR MSG_ERR_EEPROM_CORRUPT = _UxGT("Err: EEPROM Corrupt");
|
||||
LSTR MSG_SETTINGS_STORED = _UxGT("Settings Stored");
|
||||
LSTR MSG_MEDIA_UPDATE = MEDIA_TYPE_EN _UxGT(" Update");
|
||||
LSTR MSG_RESET_PRINTER = _UxGT("Reset Printer");
|
||||
|
@ -315,7 +315,7 @@ namespace Language_es {
|
||||
LSTR MSG_RESTORE_DEFAULTS = _UxGT("Rest. fábrica");
|
||||
LSTR MSG_INIT_EEPROM = _UxGT("Inicializar EEPROM");
|
||||
LSTR MSG_ERR_EEPROM_CRC = _UxGT("Err: EEPROM CRC");
|
||||
LSTR MSG_ERR_EEPROM_INDEX = _UxGT("Err: Índice EEPROM");
|
||||
LSTR MSG_ERR_EEPROM_SIZE = _UxGT("Err: EEPROM Tamaño");
|
||||
LSTR MSG_ERR_EEPROM_VERSION = _UxGT("Err: Versión EEPROM");
|
||||
LSTR MSG_MEDIA_UPDATE = _UxGT("Actualizar SD/FD");
|
||||
LSTR MSG_RESET_PRINTER = _UxGT("Resetear Impresora");
|
||||
|
@ -317,7 +317,7 @@ namespace Language_gl {
|
||||
LSTR MSG_RESTORE_DEFAULTS = _UxGT("Rest. Defecto");
|
||||
LSTR MSG_INIT_EEPROM = _UxGT("Inicializar EEPROM");
|
||||
LSTR MSG_ERR_EEPROM_CRC = _UxGT("Erro: CRC EEPROM");
|
||||
LSTR MSG_ERR_EEPROM_INDEX = _UxGT("Erro: Índice EEPROM");
|
||||
LSTR MSG_ERR_EEPROM_SIZE = _UxGT("Erro: Tamaño EEPROM");
|
||||
LSTR MSG_ERR_EEPROM_VERSION = _UxGT("Erro: Versión EEPROM");
|
||||
LSTR MSG_SETTINGS_STORED = _UxGT("Config Gardada");
|
||||
LSTR MSG_MEDIA_UPDATE = _UxGT("Actualizar SD/FD");
|
||||
|
@ -363,7 +363,7 @@ namespace Language_hu {
|
||||
LSTR MSG_RESTORE_DEFAULTS = _UxGT("Alapértelmezett");
|
||||
LSTR MSG_INIT_EEPROM = _UxGT("EEPROM inicializálás");
|
||||
LSTR MSG_ERR_EEPROM_CRC = _UxGT("Hiba: EEPROM CRC");
|
||||
LSTR MSG_ERR_EEPROM_INDEX = _UxGT("Hiba: EEPROM index");
|
||||
LSTR MSG_ERR_EEPROM_SIZE = _UxGT("Hiba: EEPROM mérete");
|
||||
LSTR MSG_ERR_EEPROM_VERSION = _UxGT("Hiba: EEPROM verzió");
|
||||
LSTR MSG_SETTINGS_STORED = _UxGT("Beállítások mentve");
|
||||
LSTR MSG_MEDIA_UPDATE = _UxGT("Tároló frissítés");
|
||||
|
@ -451,7 +451,7 @@ namespace Language_it {
|
||||
LSTR MSG_RESTORE_DEFAULTS = _UxGT("Ripristina imp.");
|
||||
LSTR MSG_INIT_EEPROM = _UxGT("Inizializza EEPROM");
|
||||
LSTR MSG_ERR_EEPROM_CRC = _UxGT("Err: CRC EEPROM");
|
||||
LSTR MSG_ERR_EEPROM_INDEX = _UxGT("Err: Indice EEPROM");
|
||||
LSTR MSG_ERR_EEPROM_SIZE = _UxGT("Err: Taglia EEPROM");
|
||||
LSTR MSG_ERR_EEPROM_VERSION = _UxGT("Err: Versione EEPROM");
|
||||
LSTR MSG_SETTINGS_STORED = _UxGT("Impostazioni mem.");
|
||||
LSTR MSG_MEDIA_UPDATE = _UxGT("Aggiorna media");
|
||||
|
@ -317,9 +317,9 @@ namespace Language_ro {
|
||||
LSTR MSG_LOAD_EEPROM = _UxGT("Load Settings");
|
||||
LSTR MSG_RESTORE_DEFAULTS = _UxGT("Restore Defaults");
|
||||
LSTR MSG_INIT_EEPROM = _UxGT("Initialize EEPROM");
|
||||
LSTR MSG_ERR_EEPROM_CRC = _UxGT("EEPROM CRC Error");
|
||||
LSTR MSG_ERR_EEPROM_INDEX = _UxGT("EEPROM Index Error");
|
||||
LSTR MSG_ERR_EEPROM_VERSION = _UxGT("EEPROM Version Error");
|
||||
LSTR MSG_ERR_EEPROM_CRC = _UxGT("Err: EEPROM CRC");
|
||||
LSTR MSG_ERR_EEPROM_SIZE = _UxGT("Err: Mărimea EEPROM");
|
||||
LSTR MSG_ERR_EEPROM_VERSION = _UxGT("Err: Versiunea EEPROM");
|
||||
LSTR MSG_SETTINGS_STORED = _UxGT("Settings Stored");
|
||||
LSTR MSG_MEDIA_UPDATE = _UxGT("Media Update");
|
||||
LSTR MSG_RESET_PRINTER = _UxGT("Reset Imprimanta");
|
||||
|
@ -454,7 +454,7 @@ namespace Language_ru {
|
||||
LSTR MSG_INIT_EEPROM = _UxGT("Инициализ. EEPROM");
|
||||
#endif
|
||||
LSTR MSG_ERR_EEPROM_CRC = _UxGT("Сбой EEPROM: CRC");
|
||||
LSTR MSG_ERR_EEPROM_INDEX = _UxGT("Сбой EEPROM: индекс");
|
||||
LSTR MSG_ERR_EEPROM_SIZE = _UxGT("Сбой EEPROM: размер");
|
||||
LSTR MSG_ERR_EEPROM_VERSION = _UxGT("Сбой EEPROM: версия");
|
||||
LSTR MSG_SETTINGS_STORED = _UxGT("Параметры сохранены");
|
||||
LSTR MSG_MEDIA_UPDATE = _UxGT("Обновление прошивки");
|
||||
|
@ -452,7 +452,7 @@ namespace Language_sk {
|
||||
LSTR MSG_RESTORE_DEFAULTS = _UxGT("Obnoviť nastavenie");
|
||||
LSTR MSG_INIT_EEPROM = _UxGT("Inicializ. EEPROM");
|
||||
LSTR MSG_ERR_EEPROM_CRC = _UxGT("Chyba: EEPROM CRC");
|
||||
LSTR MSG_ERR_EEPROM_INDEX = _UxGT("Chyba: EEPROM Index");
|
||||
LSTR MSG_ERR_EEPROM_SIZE = _UxGT("Chyba: Veľkosť EEPROM");
|
||||
LSTR MSG_ERR_EEPROM_VERSION = _UxGT("Chyba: Verzia EEPROM");
|
||||
LSTR MSG_SETTINGS_STORED = _UxGT("Nastavenie uložené");
|
||||
LSTR MSG_MEDIA_UPDATE = _UxGT("Aktualiz. z karty");
|
||||
|
@ -348,7 +348,7 @@ namespace Language_sv {
|
||||
LSTR MSG_RESTORE_DEFAULTS = _UxGT("Återställ Standard");
|
||||
LSTR MSG_INIT_EEPROM = _UxGT("Initiera EEPROM");
|
||||
LSTR MSG_ERR_EEPROM_CRC = _UxGT("EEPROM CRC Fel");
|
||||
LSTR MSG_ERR_EEPROM_INDEX = _UxGT("EEPROM Index Fel");
|
||||
LSTR MSG_ERR_EEPROM_SIZE = _UxGT("EEPROM Storlek Fel");
|
||||
LSTR MSG_ERR_EEPROM_VERSION = _UxGT("EEPROM Version Fel");
|
||||
LSTR MSG_SETTINGS_STORED = _UxGT("Inställningar Lagrad");
|
||||
LSTR MSG_MEDIA_UPDATE = _UxGT("Media Uppdatera");
|
||||
|
@ -431,7 +431,7 @@ namespace Language_tr {
|
||||
LSTR MSG_RESTORE_DEFAULTS = _UxGT("Fabrika Ayarları");
|
||||
LSTR MSG_INIT_EEPROM = _UxGT("EEPROM'u başlat");
|
||||
LSTR MSG_ERR_EEPROM_CRC = _UxGT("Hata: EEPROM CRC");
|
||||
LSTR MSG_ERR_EEPROM_INDEX = _UxGT("Hata: EEPROM Indeks");
|
||||
LSTR MSG_ERR_EEPROM_SIZE = _UxGT("Hata: EEPROM Boyutu");
|
||||
LSTR MSG_ERR_EEPROM_VERSION = _UxGT("Hata: EEPROM Sürümü");
|
||||
LSTR MSG_SETTINGS_STORED = _UxGT("Ayarlar Kaydedildi");
|
||||
LSTR MSG_MEDIA_UPDATE = _UxGT("SD Güncellemesi");
|
||||
|
@ -465,7 +465,7 @@ namespace Language_uk {
|
||||
LSTR MSG_INIT_EEPROM = _UxGT("Ініціаліз. EEPROM");
|
||||
#endif
|
||||
LSTR MSG_ERR_EEPROM_CRC = _UxGT("Збій EEPROM: CRC");
|
||||
LSTR MSG_ERR_EEPROM_INDEX = _UxGT("Збій EEPROM: індекс");
|
||||
LSTR MSG_ERR_EEPROM_SIZE = _UxGT("Збій EEPROM: розмір");
|
||||
LSTR MSG_ERR_EEPROM_VERSION = _UxGT("Збій EEPROM: версія");
|
||||
LSTR MSG_SETTINGS_STORED = _UxGT("Параметри збережені");
|
||||
LSTR MSG_MEDIA_UPDATE = _UxGT("Оновити SD-картку");
|
||||
|
@ -317,9 +317,9 @@ namespace Language_zh_CN {
|
||||
LSTR MSG_LOAD_EEPROM = _UxGT("装载设置"); // "Load memory"
|
||||
LSTR MSG_RESTORE_DEFAULTS = _UxGT("恢复安全值"); // "Restore Defaults"
|
||||
LSTR MSG_INIT_EEPROM = _UxGT("初始化设置"); // "Initialize EEPROM"
|
||||
LSTR MSG_ERR_EEPROM_CRC = _UxGT("EEPROM CRC 错误");
|
||||
LSTR MSG_ERR_EEPROM_INDEX = _UxGT("EEPROM Index 错误");
|
||||
LSTR MSG_ERR_EEPROM_VERSION = _UxGT("EEPROM Version 错误");
|
||||
LSTR MSG_ERR_EEPROM_CRC = _UxGT("EEPROM 校验和 错误");
|
||||
LSTR MSG_ERR_EEPROM_SIZE = _UxGT("EEPROM 尺寸 错误");
|
||||
LSTR MSG_ERR_EEPROM_VERSION = _UxGT("EEPROM 版本 错误");
|
||||
LSTR MSG_SETTINGS_STORED = _UxGT("设置已保存");
|
||||
LSTR MSG_MEDIA_UPDATE = _UxGT("存储器更新");
|
||||
LSTR MSG_RESET_PRINTER = _UxGT("复位打印机");
|
||||
|
@ -299,8 +299,8 @@ namespace Language_zh_TW {
|
||||
LSTR MSG_RESTORE_DEFAULTS = _UxGT("恢復安全值"); // "Restore failsafe"
|
||||
LSTR MSG_INIT_EEPROM = _UxGT("初始化設置"); // "Initialize EEPROM"
|
||||
LSTR MSG_ERR_EEPROM_CRC = _UxGT("錯誤: EEPROM CRC"); // "Err: EEPROM CRC"
|
||||
LSTR MSG_ERR_EEPROM_INDEX = _UxGT("錯誤: EEPROM Index"); // "Err: EEPROM Index"
|
||||
LSTR MSG_ERR_EEPROM_VERSION = _UxGT("錯誤: EEPROM Version"); // "EEPROM Version"
|
||||
LSTR MSG_ERR_EEPROM_SIZE = _UxGT("錯誤: EEPROM 尺寸"); // "Err: EEPROM Index"
|
||||
LSTR MSG_ERR_EEPROM_VERSION = _UxGT("錯誤: EEPROM 版本"); // "EEPROM Version"
|
||||
LSTR MSG_MEDIA_UPDATE = _UxGT("媒體更新"); // "Media Update"
|
||||
LSTR MSG_RESET_PRINTER = _UxGT("重置打印機"); // "Reset Printer
|
||||
LSTR MSG_REFRESH = _UxGT("刷新"); // "Refresh"
|
||||
|
@ -1899,18 +1899,22 @@ void MarlinUI::init() {
|
||||
|
||||
#if DISABLED(EEPROM_AUTO_INIT)
|
||||
|
||||
static inline FSTR_P eeprom_err(const uint8_t msgid) {
|
||||
switch (msgid) {
|
||||
default:
|
||||
case 0: return GET_TEXT_F(MSG_ERR_EEPROM_CRC);
|
||||
case 1: return GET_TEXT_F(MSG_ERR_EEPROM_INDEX);
|
||||
case 2: return GET_TEXT_F(MSG_ERR_EEPROM_VERSION);
|
||||
static inline FSTR_P eeprom_err(const EEPROM_Error err) {
|
||||
switch (err) {
|
||||
case ERR_EEPROM_VERSION: return GET_TEXT_F(MSG_ERR_EEPROM_VERSION);
|
||||
case ERR_EEPROM_SIZE: return GET_TEXT_F(MSG_ERR_EEPROM_SIZE);
|
||||
case ERR_EEPROM_CRC: return GET_TEXT_F(MSG_ERR_EEPROM_CRC);
|
||||
case ERR_EEPROM_CORRUPT: return GET_TEXT_F(MSG_ERR_EEPROM_CORRUPT);
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void MarlinUI::eeprom_alert(const uint8_t msgid) {
|
||||
void MarlinUI::eeprom_alert(const EEPROM_Error err) {
|
||||
FSTR_P const err_msg = eeprom_err(err);
|
||||
set_status(err_msg);
|
||||
TERN_(HOST_PROMPT_SUPPORT, hostui.notify(err_msg));
|
||||
#if HAS_MARLINUI_MENU
|
||||
editable.uint8 = msgid;
|
||||
editable.uint8 = err;
|
||||
goto_screen([]{
|
||||
FSTR_P const restore_msg = GET_TEXT_F(MSG_INIT_EEPROM);
|
||||
char msg[utf8_strlen(restore_msg) + 1];
|
||||
@ -1918,11 +1922,9 @@ void MarlinUI::init() {
|
||||
MenuItem_confirm::select_screen(
|
||||
GET_TEXT_F(MSG_BUTTON_RESET), GET_TEXT_F(MSG_BUTTON_IGNORE),
|
||||
init_eeprom, return_to_status,
|
||||
eeprom_err(editable.uint8), msg, F("?")
|
||||
eeprom_err((EEPROM_Error)editable.uint8), msg, F("?")
|
||||
);
|
||||
});
|
||||
#else
|
||||
set_status(eeprom_err(msgid));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,10 @@
|
||||
#include "../libs/buzzer.h"
|
||||
#include "buttons.h"
|
||||
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
#include "../module/settings.h"
|
||||
#endif
|
||||
|
||||
#if ENABLED(TOUCH_SCREEN_CALIBRATION)
|
||||
#include "tft_io/touch_calibration.h"
|
||||
#endif
|
||||
@ -672,12 +676,7 @@ public:
|
||||
static void load_settings();
|
||||
static void store_settings();
|
||||
#endif
|
||||
#if DISABLED(EEPROM_AUTO_INIT)
|
||||
static void eeprom_alert(const uint8_t msgid);
|
||||
static void eeprom_alert_crc() { eeprom_alert(0); }
|
||||
static void eeprom_alert_index() { eeprom_alert(1); }
|
||||
static void eeprom_alert_version() { eeprom_alert(2); }
|
||||
#endif
|
||||
static void eeprom_alert(const EEPROM_Error) TERN_(EEPROM_AUTO_INIT, {});
|
||||
#endif
|
||||
|
||||
//
|
||||
|
@ -36,12 +36,13 @@
|
||||
*/
|
||||
|
||||
// Change EEPROM version if the structure changes
|
||||
#define EEPROM_VERSION "V87"
|
||||
#define EEPROM_VERSION "V88"
|
||||
#define EEPROM_OFFSET 100
|
||||
|
||||
// Check the integrity of data offsets.
|
||||
// Can be disabled for production build.
|
||||
//#define DEBUG_EEPROM_READWRITE
|
||||
//#define DEBUG_EEPROM_OBSERVE
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
@ -207,7 +208,8 @@ typedef struct SettingsDataStruct {
|
||||
#if ENABLED(EEPROM_INIT_NOW)
|
||||
uint32_t build_hash; // Unique build hash
|
||||
#endif
|
||||
uint16_t crc; // Data Checksum
|
||||
uint16_t crc; // Data Checksum for validation
|
||||
uint16_t data_size; // Data Size for validation
|
||||
|
||||
//
|
||||
// DISTINCT_E_FACTORS
|
||||
@ -250,6 +252,7 @@ typedef struct SettingsDataStruct {
|
||||
//
|
||||
float mbl_z_offset; // bedlevel.z_offset
|
||||
uint8_t mesh_num_x, mesh_num_y; // GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y
|
||||
uint16_t mesh_check; // Hash to check against X/Y
|
||||
float mbl_z_values[TERN(MESH_BED_LEVELING, GRID_MAX_POINTS_X, 3)] // bedlevel.z_values
|
||||
[TERN(MESH_BED_LEVELING, GRID_MAX_POINTS_Y, 3)];
|
||||
|
||||
@ -268,6 +271,7 @@ typedef struct SettingsDataStruct {
|
||||
// AUTO_BED_LEVELING_BILINEAR
|
||||
//
|
||||
uint8_t grid_max_x, grid_max_y; // GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y
|
||||
uint16_t grid_check; // Hash to check against X/Y
|
||||
xy_pos_t bilinear_grid_spacing, bilinear_start; // G29 L F
|
||||
#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
|
||||
bed_mesh_t z_values; // G29
|
||||
@ -716,10 +720,13 @@ void MarlinSettings::postprocess() {
|
||||
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
|
||||
#define EEPROM_ASSERT(TST,ERR) do{ if (!(TST)) { SERIAL_ERROR_MSG(ERR); eeprom_error = true; } }while(0)
|
||||
#define EEPROM_ASSERT(TST,ERR) do{ if (!(TST)) { SERIAL_ERROR_MSG(ERR); eeprom_error = ERR_EEPROM_SIZE; } }while(0)
|
||||
|
||||
#define TWO_BYTE_HASH(A,B) uint16_t((uint16_t(A ^ 0xC3) << 4) ^ (uint16_t(B ^ 0xC3) << 12))
|
||||
|
||||
#if ENABLED(DEBUG_EEPROM_READWRITE)
|
||||
#define _FIELD_TEST(FIELD) \
|
||||
SERIAL_ECHOLNPGM("Field: " STRINGIFY(FIELD)); \
|
||||
EEPROM_ASSERT( \
|
||||
eeprom_error || eeprom_index == offsetof(SettingsData, FIELD) + EEPROM_OFFSET, \
|
||||
"Field " STRINGIFY(FIELD) " mismatch." \
|
||||
@ -728,6 +735,14 @@ void MarlinSettings::postprocess() {
|
||||
#define _FIELD_TEST(FIELD) NOOP
|
||||
#endif
|
||||
|
||||
#if ENABLED(DEBUG_EEPROM_OBSERVE)
|
||||
#define EEPROM_READ(V...) do{ SERIAL_ECHOLNPGM("READ: ", F(STRINGIFY(FIRST(V)))); EEPROM_READ_(V); }while(0)
|
||||
#define EEPROM_READ_ALWAYS(V...) do{ SERIAL_ECHOLNPGM("READ: ", F(STRINGIFY(FIRST(V)))); EEPROM_READ_ALWAYS_(V); }while(0)
|
||||
#else
|
||||
#define EEPROM_READ(V...) EEPROM_READ_(V)
|
||||
#define EEPROM_READ_ALWAYS(V...) EEPROM_READ_ALWAYS_(V)
|
||||
#endif
|
||||
|
||||
const char version[4] = EEPROM_VERSION;
|
||||
|
||||
#if ENABLED(EEPROM_INIT_NOW)
|
||||
@ -737,20 +752,20 @@ void MarlinSettings::postprocess() {
|
||||
constexpr uint32_t build_hash = strhash32(__DATE__ __TIME__);
|
||||
#endif
|
||||
|
||||
bool MarlinSettings::eeprom_error, MarlinSettings::validating;
|
||||
bool MarlinSettings::validating;
|
||||
int MarlinSettings::eeprom_index;
|
||||
uint16_t MarlinSettings::working_crc;
|
||||
|
||||
bool MarlinSettings::size_error(const uint16_t size) {
|
||||
EEPROM_Error MarlinSettings::size_error(const uint16_t size) {
|
||||
if (size != datasize()) {
|
||||
DEBUG_ERROR_MSG("EEPROM datasize error."
|
||||
#if ENABLED(MARLIN_DEV_MODE)
|
||||
" (Actual:", size, " Expected:", datasize(), ")"
|
||||
#endif
|
||||
);
|
||||
return true;
|
||||
return ERR_EEPROM_SIZE;
|
||||
}
|
||||
return false;
|
||||
return ERR_EEPROM_NOERR;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -762,18 +777,25 @@ void MarlinSettings::postprocess() {
|
||||
|
||||
if (!EEPROM_START(EEPROM_OFFSET)) return false;
|
||||
|
||||
eeprom_error = false;
|
||||
EEPROM_Error eeprom_error = ERR_EEPROM_NOERR;
|
||||
|
||||
// Write or Skip version. (Flash doesn't allow rewrite without erase.)
|
||||
TERN(FLASH_EEPROM_EMULATION, EEPROM_SKIP, EEPROM_WRITE)(ver);
|
||||
|
||||
#if ENABLED(EEPROM_INIT_NOW)
|
||||
EEPROM_SKIP(build_hash); // Skip the hash slot
|
||||
EEPROM_SKIP(build_hash); // Skip the hash slot which will be written later
|
||||
#endif
|
||||
|
||||
EEPROM_SKIP(working_crc); // Skip the checksum slot
|
||||
|
||||
working_crc = 0; // clear before first "real data"
|
||||
//
|
||||
// Clear after skipping CRC and before writing the CRC'ed data
|
||||
//
|
||||
working_crc = 0;
|
||||
|
||||
// Write the size of the data structure for use in validation
|
||||
const uint16_t data_size = datasize();
|
||||
EEPROM_WRITE(data_size);
|
||||
|
||||
const uint8_t e_factors = DISTINCT_AXES - (NUM_AXES);
|
||||
_FIELD_TEST(e_factors);
|
||||
@ -875,6 +897,10 @@ void MarlinSettings::postprocess() {
|
||||
EEPROM_WRITE(mesh_num_x);
|
||||
EEPROM_WRITE(mesh_num_y);
|
||||
|
||||
// Check value for the X/Y values
|
||||
const uint16_t mesh_check = TWO_BYTE_HASH(mesh_num_x, mesh_num_y);
|
||||
EEPROM_WRITE(mesh_check);
|
||||
|
||||
#if ENABLED(MESH_BED_LEVELING)
|
||||
EEPROM_WRITE(bedlevel.z_values);
|
||||
#else
|
||||
@ -922,6 +948,11 @@ void MarlinSettings::postprocess() {
|
||||
grid_max_y = TERN(AUTO_BED_LEVELING_BILINEAR, GRID_MAX_POINTS_Y, 3);
|
||||
EEPROM_WRITE(grid_max_x);
|
||||
EEPROM_WRITE(grid_max_y);
|
||||
|
||||
// Check value for the X/Y values
|
||||
const uint16_t grid_check = TWO_BYTE_HASH(grid_max_x, grid_max_y);
|
||||
EEPROM_WRITE(grid_check);
|
||||
|
||||
#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
|
||||
EEPROM_WRITE(bedlevel.grid_spacing);
|
||||
EEPROM_WRITE(bedlevel.grid_start);
|
||||
@ -1631,7 +1662,7 @@ void MarlinSettings::postprocess() {
|
||||
//
|
||||
// Report final CRC and Data Size
|
||||
//
|
||||
if (!eeprom_error) {
|
||||
if (eeprom_error == ERR_EEPROM_NOERR) {
|
||||
const uint16_t eeprom_size = eeprom_index - (EEPROM_OFFSET),
|
||||
final_crc = working_crc;
|
||||
|
||||
@ -1647,7 +1678,7 @@ void MarlinSettings::postprocess() {
|
||||
// Report storage size
|
||||
DEBUG_ECHO_MSG("Settings Stored (", eeprom_size, " bytes; crc ", (uint32_t)final_crc, ")");
|
||||
|
||||
eeprom_error |= size_error(eeprom_size);
|
||||
eeprom_error = size_error(eeprom_size);
|
||||
}
|
||||
EEPROM_FINISH();
|
||||
|
||||
@ -1659,25 +1690,32 @@ void MarlinSettings::postprocess() {
|
||||
store_mesh(bedlevel.storage_slot);
|
||||
#endif
|
||||
|
||||
if (!eeprom_error) {
|
||||
const bool success = (eeprom_error == ERR_EEPROM_NOERR);
|
||||
if (success) {
|
||||
LCD_MESSAGE(MSG_SETTINGS_STORED);
|
||||
TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_SETTINGS_STORED)));
|
||||
}
|
||||
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onSettingsStored(!eeprom_error));
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onSettingsStored(success));
|
||||
|
||||
return !eeprom_error;
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* M501 - Retrieve Configuration
|
||||
*/
|
||||
bool MarlinSettings::_load() {
|
||||
if (!EEPROM_START(EEPROM_OFFSET)) return false;
|
||||
EEPROM_Error MarlinSettings::_load() {
|
||||
EEPROM_Error eeprom_error = ERR_EEPROM_NOERR;
|
||||
|
||||
if (!EEPROM_START(EEPROM_OFFSET)) return eeprom_error;
|
||||
|
||||
char stored_ver[4];
|
||||
EEPROM_READ_ALWAYS(stored_ver);
|
||||
|
||||
uint16_t stored_crc;
|
||||
|
||||
do { // A block to break out of on error
|
||||
|
||||
// Version has to match or defaults are used
|
||||
if (strncmp(version, stored_ver, 3) != 0) {
|
||||
if (stored_ver[3] != '\0') {
|
||||
@ -1685,30 +1723,49 @@ void MarlinSettings::postprocess() {
|
||||
stored_ver[1] = '\0';
|
||||
}
|
||||
DEBUG_ECHO_MSG("EEPROM version mismatch (EEPROM=", stored_ver, " Marlin=" EEPROM_VERSION ")");
|
||||
LCD_MESSAGE(MSG_ERR_EEPROM_VERSION);
|
||||
TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_ERR_EEPROM_VERSION)));
|
||||
|
||||
IF_DISABLED(EEPROM_AUTO_INIT, ui.eeprom_alert_version());
|
||||
eeprom_error = true;
|
||||
eeprom_error = ERR_EEPROM_VERSION;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
|
||||
// Optionally reset on the first boot after flashing
|
||||
//
|
||||
// Optionally reset on first boot after flashing
|
||||
//
|
||||
#if ENABLED(EEPROM_INIT_NOW)
|
||||
uint32_t stored_hash;
|
||||
EEPROM_READ_ALWAYS(stored_hash);
|
||||
if (stored_hash != build_hash) { EEPROM_FINISH(); return false; }
|
||||
if (stored_hash != build_hash) {
|
||||
eeprom_error = ERR_EEPROM_CORRUPT;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16_t stored_crc;
|
||||
//
|
||||
// Get the stored CRC to compare at the end
|
||||
//
|
||||
EEPROM_READ_ALWAYS(stored_crc);
|
||||
|
||||
//
|
||||
// A temporary float for safe storage
|
||||
//
|
||||
float dummyf = 0;
|
||||
working_crc = 0; // Init to 0. Accumulated by EEPROM_READ
|
||||
|
||||
_FIELD_TEST(e_factors);
|
||||
//
|
||||
// Init to 0. Accumulated by EEPROM_READ
|
||||
//
|
||||
working_crc = 0;
|
||||
|
||||
//
|
||||
// Validate the stored size against the current data structure size
|
||||
//
|
||||
uint16_t stored_size;
|
||||
EEPROM_READ_ALWAYS(stored_size);
|
||||
if ((eeprom_error = size_error(stored_size))) break;
|
||||
|
||||
//
|
||||
// Extruder Parameter Count
|
||||
// Number of e_factors may change
|
||||
//
|
||||
_FIELD_TEST(e_factors);
|
||||
uint8_t e_factors;
|
||||
EEPROM_READ_ALWAYS(e_factors);
|
||||
|
||||
@ -1808,16 +1865,28 @@ void MarlinSettings::postprocess() {
|
||||
//
|
||||
{
|
||||
uint8_t mesh_num_x, mesh_num_y;
|
||||
uint16_t mesh_check;
|
||||
EEPROM_READ(dummyf);
|
||||
EEPROM_READ_ALWAYS(mesh_num_x);
|
||||
EEPROM_READ_ALWAYS(mesh_num_y);
|
||||
|
||||
// Check value must correspond to the X/Y values
|
||||
EEPROM_READ_ALWAYS(mesh_check);
|
||||
if (mesh_check != TWO_BYTE_HASH(mesh_num_x, mesh_num_y)) {
|
||||
eeprom_error = ERR_EEPROM_CORRUPT;
|
||||
break;
|
||||
}
|
||||
|
||||
#if ENABLED(MESH_BED_LEVELING)
|
||||
if (!validating) bedlevel.z_offset = dummyf;
|
||||
if (mesh_num_x == (GRID_MAX_POINTS_X) && mesh_num_y == (GRID_MAX_POINTS_Y)) {
|
||||
// EEPROM data fits the current mesh
|
||||
EEPROM_READ(bedlevel.z_values);
|
||||
}
|
||||
else if (mesh_num_x > (GRID_MAX_POINTS_X) || mesh_num_y > (GRID_MAX_POINTS_Y)) {
|
||||
eeprom_error = ERR_EEPROM_CORRUPT;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// EEPROM data is stale
|
||||
if (!validating) bedlevel.reset();
|
||||
@ -1860,6 +1929,15 @@ void MarlinSettings::postprocess() {
|
||||
uint8_t grid_max_x, grid_max_y;
|
||||
EEPROM_READ_ALWAYS(grid_max_x); // 1 byte
|
||||
EEPROM_READ_ALWAYS(grid_max_y); // 1 byte
|
||||
|
||||
// Check value must correspond to the X/Y values
|
||||
uint16_t grid_check;
|
||||
EEPROM_READ_ALWAYS(grid_check);
|
||||
if (grid_check != TWO_BYTE_HASH(grid_max_x, grid_max_y)) {
|
||||
eeprom_error = ERR_EEPROM_CORRUPT;
|
||||
break;
|
||||
}
|
||||
|
||||
xy_pos_t spacing, start;
|
||||
EEPROM_READ(spacing); // 2 ints
|
||||
EEPROM_READ(start); // 2 ints
|
||||
@ -1869,6 +1947,10 @@ void MarlinSettings::postprocess() {
|
||||
bedlevel.set_grid(spacing, start);
|
||||
EEPROM_READ(bedlevel.z_values); // 9 to 256 floats
|
||||
}
|
||||
else if (grid_max_x > (GRID_MAX_POINTS_X) || grid_max_y > (GRID_MAX_POINTS_Y)) {
|
||||
eeprom_error = ERR_EEPROM_CORRUPT;
|
||||
break;
|
||||
}
|
||||
else // EEPROM data is stale
|
||||
#endif // AUTO_BED_LEVELING_BILINEAR
|
||||
{
|
||||
@ -2623,27 +2705,22 @@ void MarlinSettings::postprocess() {
|
||||
//
|
||||
// Validate Final Size and CRC
|
||||
//
|
||||
eeprom_error = size_error(eeprom_index - (EEPROM_OFFSET));
|
||||
if (eeprom_error) {
|
||||
DEBUG_ECHO_MSG("Index: ", eeprom_index - (EEPROM_OFFSET), " Size: ", datasize());
|
||||
IF_DISABLED(EEPROM_AUTO_INIT, ui.eeprom_alert_index());
|
||||
const uint16_t eeprom_total = eeprom_index - (EEPROM_OFFSET);
|
||||
if ((eeprom_error = size_error(eeprom_total))) {
|
||||
// Handle below and on return
|
||||
break;
|
||||
}
|
||||
else if (working_crc != stored_crc) {
|
||||
eeprom_error = true;
|
||||
DEBUG_ERROR_MSG("EEPROM CRC mismatch - (stored) ", stored_crc, " != ", working_crc, " (calculated)!");
|
||||
LCD_MESSAGE(MSG_ERR_EEPROM_CRC);
|
||||
TERN_(HOST_EEPROM_CHITCHAT, hostui.notify(GET_TEXT_F(MSG_ERR_EEPROM_CRC)));
|
||||
IF_DISABLED(EEPROM_AUTO_INIT, ui.eeprom_alert_crc());
|
||||
eeprom_error = ERR_EEPROM_CRC;
|
||||
break;
|
||||
}
|
||||
else if (!validating) {
|
||||
DEBUG_ECHO_START();
|
||||
DEBUG_ECHO(version);
|
||||
DEBUG_ECHOLNPGM(" stored settings retrieved (", eeprom_index - (EEPROM_OFFSET), " bytes; crc ", (uint32_t)working_crc, ")");
|
||||
DEBUG_ECHOLNPGM(" stored settings retrieved (", eeprom_total, " bytes; crc ", working_crc, ")");
|
||||
TERN_(HOST_EEPROM_CHITCHAT, hostui.notify(F("Stored settings retrieved")));
|
||||
}
|
||||
|
||||
if (!validating && !eeprom_error) postprocess();
|
||||
|
||||
#if ENABLED(AUTO_BED_LEVELING_UBL)
|
||||
if (!validating) {
|
||||
bedlevel.report_state();
|
||||
@ -2655,7 +2732,7 @@ void MarlinSettings::postprocess() {
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
eeprom_error = true;
|
||||
eeprom_error = ERR_EEPROM_CORRUPT;
|
||||
#if BOTH(EEPROM_CHITCHAT, DEBUG_LEVELING_FEATURE)
|
||||
DEBUG_ECHOPGM("?Can't enable ");
|
||||
bedlevel.echo_name();
|
||||
@ -2674,6 +2751,26 @@ void MarlinSettings::postprocess() {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} while(0);
|
||||
|
||||
EEPROM_FINISH();
|
||||
|
||||
switch (eeprom_error) {
|
||||
case ERR_EEPROM_NOERR:
|
||||
if (!validating) postprocess();
|
||||
break;
|
||||
case ERR_EEPROM_SIZE:
|
||||
DEBUG_ECHO_MSG("Index: ", eeprom_index - (EEPROM_OFFSET), " Size: ", datasize());
|
||||
break;
|
||||
case ERR_EEPROM_CORRUPT:
|
||||
DEBUG_ERROR_MSG(STR_ERR_EEPROM_CORRUPT);
|
||||
break;
|
||||
case ERR_EEPROM_CRC:
|
||||
DEBUG_ERROR_MSG("EEPROM CRC mismatch - (stored) ", stored_crc, " != ", working_crc, " (calculated)!");
|
||||
TERN_(HOST_EEPROM_CHITCHAT, hostui.notify(GET_TEXT_F(MSG_ERR_EEPROM_CRC)));
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
#if ENABLED(EEPROM_CHITCHAT) && DISABLED(DISABLE_M503)
|
||||
@ -2681,9 +2778,7 @@ void MarlinSettings::postprocess() {
|
||||
if (!validating && TERN1(EEPROM_BOOT_SILENT, IsRunning())) report();
|
||||
#endif
|
||||
|
||||
EEPROM_FINISH();
|
||||
|
||||
return !eeprom_error;
|
||||
return eeprom_error;
|
||||
}
|
||||
|
||||
#ifdef ARCHIM2_SPI_FLASH_EEPROM_BACKUP_SIZE
|
||||
@ -2693,21 +2788,25 @@ void MarlinSettings::postprocess() {
|
||||
bool MarlinSettings::validate() {
|
||||
validating = true;
|
||||
#ifdef ARCHIM2_SPI_FLASH_EEPROM_BACKUP_SIZE
|
||||
bool success = _load();
|
||||
if (!success && restoreEEPROM()) {
|
||||
EEPROM_Error err = _load();
|
||||
if (err != ERR_EEPROM_NOERR && restoreEEPROM()) {
|
||||
SERIAL_ECHOLNPGM("Recovered backup EEPROM settings from SPI Flash");
|
||||
success = _load();
|
||||
err = _load();
|
||||
}
|
||||
#else
|
||||
const bool success = _load();
|
||||
const EEPROM_Error err = _load();
|
||||
#endif
|
||||
validating = false;
|
||||
return success;
|
||||
|
||||
if (err) ui.eeprom_alert(err);
|
||||
|
||||
return (err == ERR_EEPROM_NOERR);
|
||||
}
|
||||
|
||||
bool MarlinSettings::load() {
|
||||
if (validate()) {
|
||||
const bool success = _load();
|
||||
const EEPROM_Error err = _load();
|
||||
const bool success = (err == ERR_EEPROM_NOERR);
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onSettingsLoaded(success));
|
||||
return success;
|
||||
}
|
||||
|
@ -29,6 +29,13 @@
|
||||
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
#include "../HAL/shared/eeprom_api.h"
|
||||
enum EEPROM_Error : uint8_t {
|
||||
ERR_EEPROM_NOERR,
|
||||
ERR_EEPROM_VERSION,
|
||||
ERR_EEPROM_SIZE,
|
||||
ERR_EEPROM_CRC,
|
||||
ERR_EEPROM_CORRUPT
|
||||
};
|
||||
#endif
|
||||
|
||||
class MarlinSettings {
|
||||
@ -98,7 +105,7 @@ class MarlinSettings {
|
||||
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
|
||||
static bool eeprom_error, validating;
|
||||
static bool validating;
|
||||
|
||||
#if ENABLED(AUTO_BED_LEVELING_UBL) // Eventually make these available if any leveling system
|
||||
// That can store is enabled
|
||||
@ -106,8 +113,8 @@ class MarlinSettings {
|
||||
// live at the very end of the eeprom
|
||||
#endif
|
||||
|
||||
static bool _load();
|
||||
static bool size_error(const uint16_t size);
|
||||
static EEPROM_Error _load();
|
||||
static EEPROM_Error size_error(const uint16_t size);
|
||||
|
||||
static int eeprom_index;
|
||||
static uint16_t working_crc;
|
||||
@ -130,16 +137,16 @@ class MarlinSettings {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void EEPROM_READ(T &VAR) {
|
||||
static void EEPROM_READ_(T &VAR) {
|
||||
persistentStore.read_data(eeprom_index, (uint8_t *) &VAR, sizeof(VAR), &working_crc, !validating);
|
||||
}
|
||||
|
||||
static void EEPROM_READ(uint8_t *VAR, size_t sizeof_VAR) {
|
||||
static void EEPROM_READ_(uint8_t *VAR, size_t sizeof_VAR) {
|
||||
persistentStore.read_data(eeprom_index, VAR, sizeof_VAR, &working_crc, !validating);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void EEPROM_READ_ALWAYS(T &VAR) {
|
||||
static void EEPROM_READ_ALWAYS_(T &VAR) {
|
||||
persistentStore.read_data(eeprom_index, (uint8_t *) &VAR, sizeof(VAR), &working_crc);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user