From 977792961c98ccb200e21e8ed39ff4c8d252e0e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=B0ni=20M=C3=A1r=20Gilbert?= Date: Mon, 9 Oct 2023 15:06:56 +0000 Subject: [PATCH 1/6] power panic: only send M23 for SD prints If the saved printing type was USB, then EEPROM_FILENAME does not contain anything. The firmware should also not be trying to open a file on a SD card which is maybe not even mounted. Change in memory: Flash: +12 bytes SRAM: 0 bytes --- Firmware/power_panic.cpp | 41 +++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/Firmware/power_panic.cpp b/Firmware/power_panic.cpp index f439c9c40..e4a7e8856 100644 --- a/Firmware/power_panic.cpp +++ b/Firmware/power_panic.cpp @@ -423,23 +423,12 @@ bool recover_machine_state_after_power_panic() { return mbl_was_active; } -void restore_print_from_eeprom(bool mbl_was_active) { - int feedrate_rec; - int feedmultiply_rec; - uint8_t fan_speed_rec; +/// @brief Read saved filename from EEPROM and send g-code command: M23 +void restore_file_from_sd() +{ char filename[FILENAME_LENGTH]; - uint8_t depth = 0; char dir_name[9]; - - fan_speed_rec = eeprom_read_byte((uint8_t*)EEPROM_UVLO_FAN_SPEED); - feedrate_rec = eeprom_read_word((uint16_t*)EEPROM_UVLO_FEEDRATE); - feedmultiply_rec = eeprom_read_word((uint16_t*)EEPROM_UVLO_FEEDMULTIPLY); - SERIAL_ECHOPGM("Feedrate:"); - MYSERIAL.print(feedrate_rec); - SERIAL_ECHOPGM(", feedmultiply:"); - MYSERIAL.println(feedmultiply_rec); - - depth = eeprom_read_byte((uint8_t*)EEPROM_DIR_DEPTH); + uint8_t depth = eeprom_read_byte((uint8_t*)EEPROM_DIR_DEPTH); MYSERIAL.println(int(depth)); for (uint8_t i = 0; i < depth; i++) { @@ -459,6 +448,28 @@ void restore_print_from_eeprom(bool mbl_was_active) { MYSERIAL.print(filename); strcat_P(filename, PSTR(".gco")); enquecommandf_P(MSG_M23, filename); +} + +void restore_print_from_eeprom(bool mbl_was_active) { + int feedrate_rec; + int feedmultiply_rec; + uint8_t fan_speed_rec; + + fan_speed_rec = eeprom_read_byte((uint8_t*)EEPROM_UVLO_FAN_SPEED); + feedrate_rec = eeprom_read_word((uint16_t*)EEPROM_UVLO_FEEDRATE); + feedmultiply_rec = eeprom_read_word((uint16_t*)EEPROM_UVLO_FEEDMULTIPLY); + SERIAL_ECHOPGM("Feedrate:"); + MYSERIAL.print(feedrate_rec); + SERIAL_ECHOPGM(", feedmultiply:"); + MYSERIAL.println(feedmultiply_rec); + + + if (eeprom_read_byte((uint8_t*)EEPROM_UVLO_PRINT_TYPE) == PowerPanic::PRINT_TYPE_SD) + { // M23 + restore_file_from_sd(); + } + + // SD: Position in file, USB: g-code line number uint32_t position = eeprom_read_dword((uint32_t*)(EEPROM_FILE_POSITION)); SERIAL_ECHOPGM("Position read from eeprom:"); MYSERIAL.println(position); From 82cece95aac533c7a489d2d1353dbbda866cae9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=B0ni=20M=C3=A1r=20Gilbert?= Date: Mon, 9 Oct 2023 18:23:25 +0000 Subject: [PATCH 2/6] power panic: read EEPROM_FILENAME until \0 is seen Also removed debug logs --- Firmware/power_panic.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Firmware/power_panic.cpp b/Firmware/power_panic.cpp index e4a7e8856..f03cbabe1 100644 --- a/Firmware/power_panic.cpp +++ b/Firmware/power_panic.cpp @@ -430,23 +430,26 @@ void restore_file_from_sd() char dir_name[9]; uint8_t depth = eeprom_read_byte((uint8_t*)EEPROM_DIR_DEPTH); - MYSERIAL.println(int(depth)); for (uint8_t i = 0; i < depth; i++) { for (uint8_t j = 0; j < 8; j++) { dir_name[j] = eeprom_read_byte((uint8_t*)EEPROM_DIRS + j + 8 * i); } dir_name[8] = '\0'; - MYSERIAL.println(dir_name); card.chdir(dir_name, false); } for (uint8_t i = 0; i < 8; i++) { - filename[i] = eeprom_read_byte((uint8_t*)EEPROM_FILENAME + i); + const char c = eeprom_read_byte((uint8_t*)EEPROM_FILENAME + i); + filename[i] = c; + if (c == '\0') break; // Filename is shorter than 8 characters } + + // Add null delimiter in case all 8 characters were not NULL filename[8] = '\0'; - MYSERIAL.print(filename); + // Add extension to complete the DOS 8.3 filename strcat_P(filename, PSTR(".gco")); + enquecommandf_P(MSG_M23, filename); } From dec5e2c1b4a6b34d113e1c7b815f1a703d54961d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=B0ni=20M=C3=A1r=20Gilbert?= Date: Mon, 9 Oct 2023 18:40:45 +0000 Subject: [PATCH 3/6] Refactor menu_action_sdfile --- Firmware/ultralcd.cpp | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 33f289785..fea7fb63d 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -6984,44 +6984,38 @@ static void menu_action_sdfile(const char* filename) { if(eFilamentAction != FilamentAction::None) return; - char cmd[30]; - char* c; - bool result = true; - sprintf_P(cmd, MSG_M23, filename); - for (c = &cmd[4]; *c; c++) - *c = tolower(*c); + // Create a copy of card.filename on the stack since card.filename pointer + // will be modified by the SD card library when searching for the file + char selected_filename[FILENAME_LENGTH]; + strcpy(selected_filename, filename); - const char end[5] = ".gco"; + bool result = true; //we are storing just first 8 characters of 8.3 filename assuming that extension is always ".gco" for (uint_least8_t i = 0; i < 8; i++) { - if (strcmp((cmd + i + 4), end) == 0) { + if (selected_filename[i] == '\0' || selected_filename[i] == '.') { //filename is shorter then 8.3, store '\0' character on position where ".gco" string was found to terminate stored string properly eeprom_write_byte((uint8_t*)EEPROM_FILENAME + i, '\0'); break; } else { - eeprom_write_byte((uint8_t*)EEPROM_FILENAME + i, cmd[i + 4]); + eeprom_write_byte((uint8_t*)EEPROM_FILENAME + i, selected_filename[i]); } } - uint8_t depth = card.getWorkDirDepth(); - eeprom_write_byte((uint8_t*)EEPROM_DIR_DEPTH, depth); + const uint8_t depth = card.getWorkDirDepth(); + eeprom_write_byte((uint8_t*)EEPROM_DIR_DEPTH, depth); - for (uint_least8_t i = 0; i < depth; i++) { - for (uint_least8_t j = 0; j < 8; j++) { - eeprom_write_byte((uint8_t*)EEPROM_DIRS + j + 8 * i, card.dir_names[i][j]); - } - } + for (uint_least8_t i = 0; i < depth; i++) { + eeprom_update_block(card.dir_names[i], (uint8_t*)EEPROM_DIRS + 8 * i, 8); + } - //filename is just a pointer to card.filename, which changes everytime you try to open a file by filename. So you can't use filename directly - //to open a file. Instead, the cached filename in cmd is used as that one is static for the whole lifetime of this function. - if (!check_file(cmd + 4)) { + if (!check_file(selected_filename)) { result = !lcd_show_fullscreen_message_yes_no_and_wait_P(_i("File incomplete. Continue anyway?"), false);////MSG_FILE_INCOMPLETE c=20 r=3 lcd_update_enable(true); } if (result) { - enquecommand(cmd); + enquecommandf_P(MSG_M23, selected_filename); enquecommand_P(MSG_M24); } From 21d0130626510230406067080d131d235ceded13 Mon Sep 17 00:00:00 2001 From: gudnimg Date: Sat, 14 Oct 2023 13:41:22 +0000 Subject: [PATCH 4/6] power panic: simplify recovering SD filename We can just read the whole EEPROM block since short filenames are always null terminated. strcat_P will then apply the file extension at the correct position. Change in memory: Flash: -24 bytes SRAM: 0 bytes --- Firmware/power_panic.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Firmware/power_panic.cpp b/Firmware/power_panic.cpp index f03cbabe1..fc6d77264 100644 --- a/Firmware/power_panic.cpp +++ b/Firmware/power_panic.cpp @@ -438,11 +438,9 @@ void restore_file_from_sd() card.chdir(dir_name, false); } - for (uint8_t i = 0; i < 8; i++) { - const char c = eeprom_read_byte((uint8_t*)EEPROM_FILENAME + i); - filename[i] = c; - if (c == '\0') break; // Filename is shorter than 8 characters - } + // Recover DOS 8.3 filename without extension. + // Short filenames are always null terminated. + eeprom_read_block(filename, (const char *)EEPROM_FILENAME, 8); // Add null delimiter in case all 8 characters were not NULL filename[8] = '\0'; From 4c52d92d164923df36b1a940ff881715f0c19b29 Mon Sep 17 00:00:00 2001 From: gudnimg Date: Sat, 14 Oct 2023 13:47:35 +0000 Subject: [PATCH 5/6] power panic: read whole directory name block from EEPROM There is no need to read one byte at a time. We can simply read the whole block in one go. This saves some flash memory. Change in memory: Flash: -18 bytes SRAM: 0 bytes --- Firmware/power_panic.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Firmware/power_panic.cpp b/Firmware/power_panic.cpp index fc6d77264..dffe5d7a2 100644 --- a/Firmware/power_panic.cpp +++ b/Firmware/power_panic.cpp @@ -431,9 +431,7 @@ void restore_file_from_sd() uint8_t depth = eeprom_read_byte((uint8_t*)EEPROM_DIR_DEPTH); for (uint8_t i = 0; i < depth; i++) { - for (uint8_t j = 0; j < 8; j++) { - dir_name[j] = eeprom_read_byte((uint8_t*)EEPROM_DIRS + j + 8 * i); - } + eeprom_read_block(dir_name, (const char *)EEPROM_DIRS + 8 * i, 8); dir_name[8] = '\0'; card.chdir(dir_name, false); } From dc280b0d9e8066cacf69dfa0a7e3ac7788c565bb Mon Sep 17 00:00:00 2001 From: gudnimg Date: Sun, 22 Oct 2023 17:37:40 +0000 Subject: [PATCH 6/6] power panic: support any valid DOS 8.3 extension When a SD file is selected to print save the DOS 8.3 extension into EEPROM. After a power outage, the correct file extension is then selected instead of always assuming it's ".gco" This allows users to recover ".g" files. Change in memory: Flash: +104 bytes SRAM: 0 bytes --- Firmware/eeprom.h | 5 ++++- Firmware/power_panic.cpp | 8 ++++++-- Firmware/ultralcd.cpp | 16 ++++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/Firmware/eeprom.h b/Firmware/eeprom.h index fddebdebd..346ac3a76 100644 --- a/Firmware/eeprom.h +++ b/Firmware/eeprom.h @@ -368,6 +368,7 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP | 0x0C97 3223 | uint8 | EEPROM_THERMAL_MODEL_VER | 0-255 | ffh | Thermal Model Version | Thermal Model| D3 Ax0c97 C1 | 0x0C95 3221 | PGM_P | EEPROM_KILL_MESSAGE | 0-65535 | ff ffh | Kill message PGM pointer | kill() | D3 Ax0c95 C2 | 0x0C94 3220 | uint8 | EEPROM_KILL_PENDING_FLAG | 42h, ffh | ffh | Kill pending flag (0x42 magic value) | kill() | D3 Ax0c94 C1 +| 0x0C91 3217 | char[3] | EEPROM_FILENAME_EXTENSION | ??? | ffffffffh | DOS 8.3 filename extension | ??? | D3 Ax0c91 C1 |Address begin|Bit/Type | Name | Valid values | Default/FactoryReset | Description |Gcode/Function| Debug code | :--: | :--: | :--: | :--: | :--: | :--: | :--: | :--: @@ -606,8 +607,10 @@ static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE); #define EEPROM_KILL_MESSAGE (EEPROM_THERMAL_MODEL_VER-2) //PGM_P #define EEPROM_KILL_PENDING_FLAG (EEPROM_KILL_MESSAGE-1) //uint8 +#define EEPROM_FILENAME_EXTENSION (EEPROM_KILL_PENDING_FLAG - 3) // 3 x char + //This is supposed to point to last item to allow EEPROM overrun check. Please update when adding new items. -#define EEPROM_LAST_ITEM EEPROM_KILL_PENDING_FLAG +#define EEPROM_LAST_ITEM EEPROM_FILENAME_EXTENSION // !!!!! // !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!! // !!!!! diff --git a/Firmware/power_panic.cpp b/Firmware/power_panic.cpp index dffe5d7a2..9c63936d4 100644 --- a/Firmware/power_panic.cpp +++ b/Firmware/power_panic.cpp @@ -428,6 +428,7 @@ void restore_file_from_sd() { char filename[FILENAME_LENGTH]; char dir_name[9]; + char extension_ptr[5]; uint8_t depth = eeprom_read_byte((uint8_t*)EEPROM_DIR_DEPTH); for (uint8_t i = 0; i < depth; i++) { @@ -443,8 +444,11 @@ void restore_file_from_sd() // Add null delimiter in case all 8 characters were not NULL filename[8] = '\0'; - // Add extension to complete the DOS 8.3 filename - strcat_P(filename, PSTR(".gco")); + // Add extension to complete the DOS 8.3 filename e.g. ".gco" or ".g" + extension_ptr[0] = '.'; + eeprom_read_block(&extension_ptr[1], (const char *)EEPROM_FILENAME_EXTENSION, 3); + extension_ptr[4] = '\0'; + strcat(filename, extension_ptr); enquecommandf_P(MSG_M23, filename); } diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index fea7fb63d..203ab22f8 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -7003,6 +7003,22 @@ static void menu_action_sdfile(const char* filename) } } + // Write the DOS 8.3 file extension into EEPROM + char * extension_ptr = strchr(selected_filename, '.'); + + if (extension_ptr) { + extension_ptr++; // skip the '.' + } + + for (uint_least8_t i = 0; i < 3; i++) + { + if (extension_ptr == NULL || extension_ptr[i] == '\0') { + eeprom_update_byte((uint8_t*)EEPROM_FILENAME_EXTENSION + i, '\0'); + } else { + eeprom_update_byte((uint8_t*)EEPROM_FILENAME_EXTENSION + i, extension_ptr[i]); + } + } + const uint8_t depth = card.getWorkDirDepth(); eeprom_write_byte((uint8_t*)EEPROM_DIR_DEPTH, depth);