From 21dcfb23f45b11bdb41c316d75d9bed1fd406cfa Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Thu, 31 Oct 2019 15:31:08 +0100 Subject: [PATCH 01/44] Follow RepRap Wiki G-codes documentation M120 is Enable endstops M121 is disable endstops I guess this was just a typo issue. --- Firmware/Marlin_main.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index a2cbece56..593194c60 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -6366,16 +6366,16 @@ Sigma_Exit: lcd_setstatus(strchr_pointer + 5); break;*/ - //! ### M120 - Disable endstops + //! ### M120 - Ensable endstops // ---------------------------------------- case 120: - enable_endstops(false) ; + enable_endstops(true) ; break; - //! ### M121 - Enable endstops + //! ### M121 - Disable endstops // ---------------------------------------- case 121: - enable_endstops(true) ; + enable_endstops(false) ; break; //! ### M119 - Get endstop states From ad5d068690fdc3e4a996bcb1d0fc8df5e3f98c6c Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Tue, 26 Jan 2021 12:09:35 +0100 Subject: [PATCH 02/44] Update char lengths part 1 Fix some too long translations --- Firmware/messages.c | 10 ++++----- Firmware/ultralcd.cpp | 48 +++++++++++++++++++++---------------------- lang/lang_en.txt | 10 ++++----- lang/lang_en_cz.txt | 10 ++++----- lang/lang_en_de.txt | 10 ++++----- lang/lang_en_es.txt | 12 +++++------ lang/lang_en_fr.txt | 10 ++++----- lang/lang_en_it.txt | 10 ++++----- lang/lang_en_pl.txt | 10 ++++----- 9 files changed, 65 insertions(+), 65 deletions(-) diff --git a/Firmware/messages.c b/Firmware/messages.c index 0b1d58e04..c5d781ad8 100644 --- a/Firmware/messages.c +++ b/Firmware/messages.c @@ -29,7 +29,7 @@ const char MSG_CRASHDETECT[] PROGMEM_I1 = ISTR("Crash det."); ////c=13 const char MSG_ERROR[] PROGMEM_I1 = ISTR("ERROR:"); //// const char MSG_EXTRUDER[] PROGMEM_I1 = ISTR("Extruder"); ////c=17 const char MSG_FANS_CHECK[] PROGMEM_I1 = ISTR("Fans check"); ////c=13 -const char MSG_FIL_RUNOUTS[] PROGMEM_I1 = ISTR("Fil. runouts"); ////c=14 +const char MSG_FIL_RUNOUTS[] PROGMEM_I1 = ISTR("Fil. runouts"); ////c=15 const char MSG_FILAMENT[] PROGMEM_I1 = ISTR("Filament"); ////c=17 r=1 const char MSG_FAN_SPEED[] PROGMEM_I1 = ISTR("Fan speed"); ////c=14 const char MSG_FILAMENT_CLEAN[] PROGMEM_I1 = ISTR("Filament extruding & with correct color?"); ////c=20 r=2 @@ -65,14 +65,14 @@ const char MSG_STEEL_SHEETS[] PROGMEM_I1 = ISTR("Steel sheets"); ////c=18 const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1[] PROGMEM_I1 = ISTR("Measuring reference height of calibration point"); ////c=60 const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2[] PROGMEM_I1 = ISTR(" of 9"); ////c=14 const char MSG_MENU_CALIBRATION[] PROGMEM_I1 = ISTR("Calibration"); //// -const char MSG_MMU_FAILS[] PROGMEM_I1 = ISTR("MMU fails"); ////c=14 -const char MSG_MMU_LOAD_FAILS[] PROGMEM_I1 = ISTR("MMU load fails"); ////c=14 +const char MSG_MMU_FAILS[] PROGMEM_I1 = ISTR("MMU fails"); ////c=15 +const char MSG_MMU_LOAD_FAILS[] PROGMEM_I1 = ISTR("MMU load fails"); ////c=15 const char MSG_NO[] PROGMEM_I1 = ISTR("No"); //// const char MSG_NOZZLE[] PROGMEM_I1 = ISTR("Nozzle"); //// const char MSG_PAPER[] PROGMEM_I1 = ISTR("Place a sheet of paper under the nozzle during the calibration of first 4 points. If the nozzle catches the paper, power off the printer immediately."); ////c=20 r=10 const char MSG_PLACE_STEEL_SHEET[] PROGMEM_I1 = ISTR("Please place steel sheet on heatbed."); ////c=20 r=4 const char MSG_PLEASE_WAIT[] PROGMEM_I1 = ISTR("Please wait"); ////c=20 -const char MSG_POWER_FAILURES[] PROGMEM_I1 = ISTR("Power failures"); ////c=14 +const char MSG_POWER_FAILURES[] PROGMEM_I1 = ISTR("Power failures"); ////c=15 const char MSG_PREHEAT_NOZZLE[] PROGMEM_I1 = ISTR("Preheat the nozzle!"); ////c=20 const char MSG_PRESS_TO_UNLOAD[] PROGMEM_I1 = ISTR("Please press the knob to unload filament"); ////c=20 r=4 const char MSG_PRINT_ABORTED[] PROGMEM_I1 = ISTR("Print aborted"); ////c=20 @@ -131,7 +131,7 @@ const char MSG_MODEL[] PROGMEM_I1 = ISTR("Model"); //// const char MSG_FIRMWARE[] PROGMEM_I1 = ISTR("Firmware"); //// const char MSG_GCODE[] PROGMEM_I1 = ISTR("Gcode"); //// const char MSG_GCODE_DIFF_PRINTER_CONTINUE[] PROGMEM_I1 = ISTR("G-code sliced for a different printer type. Continue?"); ////c=20 r=5 -const char MSG_GCODE_DIFF_PRINTER_CANCELLED[] PROGMEM_I1 =ISTR("G-code sliced for a different printer type. Please re-slice the model again. Print cancelled."); ////c=20 r=6 +const char MSG_GCODE_DIFF_PRINTER_CANCELLED[] PROGMEM_I1 =ISTR("G-code sliced for a different printer type. Please re-slice the model again. Print cancelled."); ////c=20 r=7 const char MSG_NOZZLE_DIAMETER[] PROGMEM_I1 = ISTR("Nozzle d."); //// const char MSG_MMU_MODE[] PROGMEM_I1 = ISTR("MMU Mode"); //// const char MSG_SD_CARD[] PROGMEM_I1 = ISTR("SD card"); //// diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 81bb0f3ca..cee7a45ab 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -1657,8 +1657,8 @@ static void lcd_menu_fails_stats_mmu() //! @code{.unparsed} //! |01234567890123456789| //! |Last print failures | MSG_LAST_PRINT_FAILURES c=20 -//! | MMU fails: 000| MSG_MMU_FAILS c=14 -//! | MMU load fails: 000| MSG_MMU_LOAD_FAILS c=14 +//! | MMU fails 000| MSG_MMU_FAILS c=15 +//! | MMU load fails 000| MSG_MMU_LOAD_FAILS c=15 //! | | //! ---------------------- //! @endcode @@ -1671,8 +1671,8 @@ static void lcd_menu_fails_stats_mmu_print() lcd_home(); lcd_printf_P(PSTR("%S\n" " %-16.16S%-3d\n" " %-16.16S%-3d"), _T(MSG_LAST_PRINT_FAILURES), ////c=20 - _T(MSG_MMU_FAILS), fails, ////c=14 - _T(MSG_MMU_LOAD_FAILS), load_fails); ////c=14 + _T(MSG_MMU_FAILS), fails, ////c=15 + _T(MSG_MMU_LOAD_FAILS), load_fails); ////c=15 menu_back_if_clicked_fb(); } @@ -1681,9 +1681,9 @@ static void lcd_menu_fails_stats_mmu_print() //! @code{.unparsed} //! |01234567890123456789| //! |Total failures | MSG_TOTAL_FAILURES c=20 -//! | MMU fails: 000| MSG_MMU_FAILS c=14 -//! | MMU load fails: 000| MSG_MMU_LOAD_FAILS c=14 -//! | MMU power fails:000| c=14 r=1 +//! | MMU fails 000| MSG_MMU_FAILS c=15 +//! | MMU load fails 000| MSG_MMU_LOAD_FAILS c=15 +//! | MMU power fails 000| c=15 //! ---------------------- //! @endcode //! @todo Positioning of the messages and values on LCD aren't fixed to their exact place. This causes issues with translations. @@ -1696,9 +1696,9 @@ static void lcd_menu_fails_stats_mmu_total() lcd_home(); lcd_printf_P(PSTR("%S\n" " %-16.16S%-3d\n" " %-16.16S%-3d\n" " %-16.16S%-3d"), _T(MSG_TOTAL_FAILURES), ////c=20 - _T(MSG_MMU_FAILS), fails, ////c=14 - _T(MSG_MMU_LOAD_FAILS), load_fails, ////c=14 - _i("MMU power fails"), mmu_power_failures); ////c=14 r=1 + _T(MSG_MMU_FAILS), fails, ////c=15 + _T(MSG_MMU_LOAD_FAILS), load_fails, ////c=15 + _i("MMU power fails"), mmu_power_failures); ////c=15 r=1 menu_back_if_clicked_fb(); } @@ -1710,8 +1710,8 @@ static const char failStatsFmt[] PROGMEM = "%S\n" " %-16.16S%-3d\n" " %-16.16S%- //! @code{.unparsed} //! |01234567890123456789| //! |Total failures | MSG_TOTAL_FAILURES c=20 -//! | Power failures: 000| MSG_POWER_FAILURES c=14 -//! | Fil. runouts : 000| MSG_FIL_RUNOUTS c=14 +//! | Power failures 000| MSG_POWER_FAILURES c=15 +//! | Fil. runouts 000| MSG_FIL_RUNOUTS c=15 //! | Crash X:000 Y:000| MSG_CRASH c=7 //! ---------------------- //! @endcode @@ -1726,8 +1726,8 @@ static void lcd_menu_fails_stats_total() lcd_home(); lcd_printf_P(failStatsFmt, _T(MSG_TOTAL_FAILURES), ////c=20 - _T(MSG_POWER_FAILURES), power, ////c=14 - _T(MSG_FIL_RUNOUTS), filam, ////c=14 + _T(MSG_POWER_FAILURES), power, ////c=15 + _T(MSG_FIL_RUNOUTS), filam, ////c=15 _T(MSG_CRASH), crashX, crashY); ////c=7 menu_back_if_clicked_fb(); } @@ -1737,9 +1737,9 @@ static void lcd_menu_fails_stats_total() //! @code{.unparsed} //! |01234567890123456789| //! |Last print failures | MSG_LAST_PRINT_FAILURES c=20 -//! | Power failures 000| MSG_POWER_FAILURES c=14 -//! | Fil. runouts 000| MSG_FIL_RUNOUTS c=14 -//! | Crash X:000 Y:000| MSG_CRASH c=7 +//! | Power failures 000| MSG_POWER_FAILURES c=15 +//! | Fil. runouts 000| MSG_FIL_RUNOUTS c=15 +//! | Crash X 000 Y 000| MSG_CRASH c=7 //! ---------------------- //! @endcode //! @todo Positioning of the messages and values on LCD aren't fixed to their exact place. This causes issues with translations. @@ -1754,8 +1754,8 @@ static void lcd_menu_fails_stats_print() #ifndef PAT9125 lcd_printf_P(failStatsFmt, _T(MSG_LAST_PRINT_FAILURES), ////c=20 - _T(MSG_POWER_FAILURES), power, ////c=14 - _T(MSG_FIL_RUNOUTS), filam, ////c=14 + _T(MSG_POWER_FAILURES), power, ////c=15 + _T(MSG_FIL_RUNOUTS), filam, ////c=15 _T(MSG_CRASH), crashX, crashY); ////c=7 #else // On the MK3 include detailed PAT9125 statistics about soft failures @@ -1764,7 +1764,7 @@ static void lcd_menu_fails_stats_print() " %-7.7S H %-3d S %-3d\n" " %-7.7S X %-3d Y %-3d"), _T(MSG_LAST_PRINT_FAILURES), ////c=20 - _T(MSG_POWER_FAILURES), power, ////c=14 + _T(MSG_POWER_FAILURES), power, ////c=15 _i("Runouts"), filam, fsensor_softfail, //c=7 _T(MSG_CRASH), crashX, crashY); ////c=7 #endif @@ -1807,9 +1807,9 @@ static const char failStatsFmt[] PROGMEM = "%S\n" " %-16.16S%-3d\n" "%S\n" " %-1 //! @code{.unparsed} //! |01234567890123456789| //! |Last print failures | MSG_LAST_PRINT_FAILURES c=20 -//! | Fil. runouts 000| MSG_FIL_RUNOUTS c=14 +//! | Fil. runouts 000| MSG_FIL_RUNOUTS c=15 //! |Total failures | MSG_TOTAL_FAILURES c=20 -//! | Fil. runouts 000| MSG_FIL_RUNOUTS c=14 +//! | Fil. runouts 000| MSG_FIL_RUNOUTS c=15 //! ---------------------- //! @endcode //! @todo Positioning of the messages and values on LCD aren't fixed to their exact place. This causes issues with translations. @@ -1821,9 +1821,9 @@ static void lcd_menu_fails_stats() lcd_home(); lcd_printf_P(failStatsFmt, _T(MSG_LAST_PRINT_FAILURES), ////c=20 - _T(MSG_FIL_RUNOUTS), filamentLast, ////c=14 + _T(MSG_FIL_RUNOUTS), filamentLast, ////c=15 _T(MSG_TOTAL_FAILURES), ////c=20 - _T(MSG_FIL_RUNOUTS), filamentTotal); ////c=14 + _T(MSG_FIL_RUNOUTS), filamentTotal); ////c=15 menu_back_if_clicked(); } diff --git a/lang/lang_en.txt b/lang/lang_en.txt index bcb0a4444..163746199 100644 --- a/lang/lang_en.txt +++ b/lang/lang_en.txt @@ -253,7 +253,7 @@ #MSG_FSENSOR "Fil. sensor" -#MSG_FIL_RUNOUTS c=14 +#MSG_FIL_RUNOUTS c=15 "Fil. runouts " #MSG_FILAMENT_CLEAN c=20 r=2 @@ -448,13 +448,13 @@ # "Measured skew" -#MSG_MMU_FAILS c=14 +#MSG_MMU_FAILS c=15 "MMU fails" # "MMU load failed " -#MSG_MMU_LOAD_FAILS c=14 +#MSG_MMU_LOAD_FAILS c=15 "MMU load fails" #MSG_MMU_OK_RESUMING c=20 r=4 @@ -625,7 +625,7 @@ #MSG_FS_PAUSE c=5 "Pause" -#MSG_POWER_FAILURES c=14 +#MSG_POWER_FAILURES c=15 "Power failures" #MSG_PRINT_ABORTED c=20 @@ -1048,7 +1048,7 @@ #MSG_GCODE_DIFF_PRINTER_CONTINUE c=20 r=5 "G-code sliced for a different printer type. Continue?" -#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=6 +#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=7 "G-code sliced for a different printer type. Please re-slice the model again. Print cancelled." # diff --git a/lang/lang_en_cz.txt b/lang/lang_en_cz.txt index 0b3d7b14f..7e8666e2d 100644 --- a/lang/lang_en_cz.txt +++ b/lang/lang_en_cz.txt @@ -338,7 +338,7 @@ "Fil. sensor" "Fil. senzor" -#MSG_FIL_RUNOUTS c=14 +#MSG_FIL_RUNOUTS c=15 "Fil. runouts " "Vypadky filam." @@ -598,7 +598,7 @@ "Measured skew" "Merene zkoseni" -#MSG_MMU_FAILS c=14 +#MSG_MMU_FAILS c=15 "MMU fails" "Selhani MMU" @@ -606,7 +606,7 @@ "MMU load failed " "Zavedeni MMU selhalo" -#MSG_MMU_LOAD_FAILS c=14 +#MSG_MMU_LOAD_FAILS c=15 "MMU load fails" "MMU selhani zavadeni" @@ -834,7 +834,7 @@ "Pause" "\x00" -#MSG_POWER_FAILURES c=14 +#MSG_POWER_FAILURES c=15 "Power failures" "Vypadky proudu" @@ -1398,7 +1398,7 @@ "G-code sliced for a different printer type. Continue?" "G-code je pripraven pro jiny typ tiskarny. Pokracovat?" -#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=6 +#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=7 "G-code sliced for a different printer type. Please re-slice the model again. Print cancelled." "G-code je pripraven pro jiny typ tiskarny. Prosim preslicujte model znovu. Tisk zrusen." diff --git a/lang/lang_en_de.txt b/lang/lang_en_de.txt index 0a436a9ee..063ad995c 100644 --- a/lang/lang_en_de.txt +++ b/lang/lang_en_de.txt @@ -338,7 +338,7 @@ "Fil. sensor" "Fil. Sensor" -#MSG_FIL_RUNOUTS c=14 +#MSG_FIL_RUNOUTS c=15 "Fil. runouts " "Fil. Maengel " @@ -598,7 +598,7 @@ "Measured skew" "Schraeglauf" -#MSG_MMU_FAILS c=14 +#MSG_MMU_FAILS c=15 "MMU fails" "MMU Fehler" @@ -606,7 +606,7 @@ "MMU load failed " "MMU Ladefehler" -#MSG_MMU_LOAD_FAILS c=14 +#MSG_MMU_LOAD_FAILS c=15 "MMU load fails" "MMU Ladefehler" @@ -834,7 +834,7 @@ "Pause" "\x00" -#MSG_POWER_FAILURES c=14 +#MSG_POWER_FAILURES c=15 "Power failures" "Netzfehler" @@ -1398,7 +1398,7 @@ "G-code sliced for a different printer type. Continue?" "G-Code ist fuer einen anderen Drucker geslict. Fortfahren?" -#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=6 +#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=7 "G-code sliced for a different printer type. Please re-slice the model again. Print cancelled." "G-Code ist fuer einen anderen Drucker geslict. Bitte slicen Sie das Modell erneut. Druck abgebrochen." diff --git a/lang/lang_en_es.txt b/lang/lang_en_es.txt index 2e29fa20a..e334ddacd 100644 --- a/lang/lang_en_es.txt +++ b/lang/lang_en_es.txt @@ -338,7 +338,7 @@ "Fil. sensor" "Sensor Fil." -#MSG_FIL_RUNOUTS c=14 +#MSG_FIL_RUNOUTS c=15 "Fil. runouts " "Fil. acabado " @@ -598,7 +598,7 @@ "Measured skew" "Desviacion med:" -#MSG_MMU_FAILS c=14 +#MSG_MMU_FAILS c=15 "MMU fails" "Fallos MMU" @@ -606,7 +606,7 @@ "MMU load failed " "Carga MMU fallida" -#MSG_MMU_LOAD_FAILS c=14 +#MSG_MMU_LOAD_FAILS c=15 "MMU load fails" "Carga MMU falla" @@ -834,9 +834,9 @@ "Pause" "Pausa" -#MSG_POWER_FAILURES c=14 +#MSG_POWER_FAILURES c=15 "Power failures" -"Cortes de energia" +"Fallas energia" #MSG_PRINT_ABORTED c=20 "Print aborted" @@ -1398,7 +1398,7 @@ "G-code sliced for a different printer type. Continue?" "Codigo G laminado para un tipo de impresora diferente. ?Continuar?" -#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=6 +#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=7 "G-code sliced for a different printer type. Please re-slice the model again. Print cancelled." "Codigo G laminado para una impresora diferente. Por favor relamina el modelo de nuevo. Impresion cancelada." diff --git a/lang/lang_en_fr.txt b/lang/lang_en_fr.txt index cc0cbb95b..a78c999e7 100644 --- a/lang/lang_en_fr.txt +++ b/lang/lang_en_fr.txt @@ -338,7 +338,7 @@ "Fil. sensor" "Capteur Fil." -#MSG_FIL_RUNOUTS c=14 +#MSG_FIL_RUNOUTS c=15 "Fil. runouts " "Fins filament " @@ -598,7 +598,7 @@ "Measured skew" "Deviat.mesuree" -#MSG_MMU_FAILS c=14 +#MSG_MMU_FAILS c=15 "MMU fails" "Echecs MMU" @@ -606,7 +606,7 @@ "MMU load failed " "Echec chargement MMU" -#MSG_MMU_LOAD_FAILS c=14 +#MSG_MMU_LOAD_FAILS c=15 "MMU load fails" "Echecs charg. MMU" @@ -834,7 +834,7 @@ "Pause" "\x00" -#MSG_POWER_FAILURES c=14 +#MSG_POWER_FAILURES c=15 "Power failures" "Coup.de courant" @@ -1398,7 +1398,7 @@ "G-code sliced for a different printer type. Continue?" "Le G-code a ete prepare pour une autre version de l'imprimante. Continuer?" -#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=6 +#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=7 "G-code sliced for a different printer type. Please re-slice the model again. Print cancelled." "Le G-code a ete prepare pour une autre version de l'imprimante. Veuillez decouper le modele a nouveau. L'impression a ete annulee." diff --git a/lang/lang_en_it.txt b/lang/lang_en_it.txt index 8cd939082..a442667a5 100644 --- a/lang/lang_en_it.txt +++ b/lang/lang_en_it.txt @@ -338,7 +338,7 @@ "Fil. sensor" "Sensore fil." -#MSG_FIL_RUNOUTS c=14 +#MSG_FIL_RUNOUTS c=15 "Fil. runouts " "Fil. esauriti " @@ -598,7 +598,7 @@ "Measured skew" "Deviazione mis" -#MSG_MMU_FAILS c=14 +#MSG_MMU_FAILS c=15 "MMU fails" "Fallimenti MMU" @@ -606,7 +606,7 @@ "MMU load failed " "Caricamento MMU fallito" -#MSG_MMU_LOAD_FAILS c=14 +#MSG_MMU_LOAD_FAILS c=15 "MMU load fails" "Caricamenti MMU falliti" @@ -834,7 +834,7 @@ "Pause" "Pausa" -#MSG_POWER_FAILURES c=14 +#MSG_POWER_FAILURES c=15 "Power failures" "Mancanza corrente" @@ -1398,7 +1398,7 @@ "G-code sliced for a different printer type. Continue?" "G-code processato per una stampante diversa. Continuare?" -#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=6 +#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=7 "G-code sliced for a different printer type. Please re-slice the model again. Print cancelled." "G-code processato per una stampante diversa. Per favore esegui nuovamente lo slice del modello. Stampa annullata." diff --git a/lang/lang_en_pl.txt b/lang/lang_en_pl.txt index 38d1421f7..104d61d2e 100644 --- a/lang/lang_en_pl.txt +++ b/lang/lang_en_pl.txt @@ -338,7 +338,7 @@ "Fil. sensor" "Czuj. filam." -#MSG_FIL_RUNOUTS c=14 +#MSG_FIL_RUNOUTS c=15 "Fil. runouts " "Konc.filamentu" @@ -598,7 +598,7 @@ "Measured skew" "Zmierzony skos" -#MSG_MMU_FAILS c=14 +#MSG_MMU_FAILS c=15 "MMU fails" "Bledy MMU" @@ -606,7 +606,7 @@ "MMU load failed " "Blad ladowania MMU" -#MSG_MMU_LOAD_FAILS c=14 +#MSG_MMU_LOAD_FAILS c=15 "MMU load fails" "Bledy ladow. MMU" @@ -834,7 +834,7 @@ "Pause" "Pauza" -#MSG_POWER_FAILURES c=14 +#MSG_POWER_FAILURES c=15 "Power failures" "Zaniki zasilania" @@ -1398,7 +1398,7 @@ "G-code sliced for a different printer type. Continue?" "G-code pociety dla innej drukarki. Kontynuowac?" -#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=6 +#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=7 "G-code sliced for a different printer type. Please re-slice the model again. Print cancelled." "G-code pociety dla drukarki innego typu. Potnij model ponownie. Druk anulowany." From f40c593d11f33cd88fee3e2899a2725e314b4a87 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Tue, 26 Jan 2021 14:15:34 +0100 Subject: [PATCH 03/44] Fix few translations not being used due to spaces or upper case --- Firmware/messages.c | 2 +- Firmware/ultralcd.cpp | 2 +- lang/lang_en.txt | 2 +- lang/lang_en_cz.txt | 2 +- lang/lang_en_de.txt | 4 ++-- lang/lang_en_es.txt | 4 ++-- lang/lang_en_fr.txt | 4 ++-- lang/lang_en_it.txt | 4 ++-- lang/lang_en_pl.txt | 2 +- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Firmware/messages.c b/Firmware/messages.c index c5d781ad8..7c397d7bb 100644 --- a/Firmware/messages.c +++ b/Firmware/messages.c @@ -16,7 +16,7 @@ const char MSG_BED_DONE[] PROGMEM_I1 = ISTR("Bed done"); //// const char MSG_BED_HEATING[] PROGMEM_I1 = ISTR("Bed Heating"); //// const char MSG_BED_LEVELING_FAILED_POINT_LOW[] PROGMEM_I1 = ISTR("Bed leveling failed. Sensor didnt trigger. Debris on nozzle? Waiting for reset."); ////c=20 r=5 const char MSG_BED_SKEW_OFFSET_DETECTION_FITTING_FAILED[] PROGMEM_I1 = ISTR("XYZ calibration failed. Please consult the manual."); ////c=20 r=8 -const char MSG_BELT_STATUS[] PROGMEM_I1 = ISTR("Belt Status");////c=18 +const char MSG_BELT_STATUS[] PROGMEM_I1 = ISTR("Belt status");////c=18 const char MSG_CALIBRATE_Z_AUTO[] PROGMEM_I1 = ISTR("Calibrating Z"); ////c=20 r=2 const char MSG_CARD_MENU[] PROGMEM_I1 = ISTR("Print from SD"); //// const char MSG_CHECKING_X[] PROGMEM_I1 = ISTR("Checking X axis"); ////c=20 diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index cee7a45ab..020d91934 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -8381,7 +8381,7 @@ static int lcd_selftest_screen(TestScreen screen, int _progress, int _progress_s if (screen == TestScreen::EndStops) lcd_puts_P(_i("Checking endstops"));////MSG_SELFTEST_CHECK_ENDSTOPS c=20 if (screen == TestScreen::AxisX) lcd_puts_P(_T(MSG_CHECKING_X)); if (screen == TestScreen::AxisY) lcd_puts_P(_T(MSG_CHECKING_Y)); - if (screen == TestScreen::AxisZ) lcd_puts_P(_i("Checking Z axis "));////MSG_SELFTEST_CHECK_Z c=20 + if (screen == TestScreen::AxisZ) lcd_puts_P(_i("Checking Z axis"));////MSG_SELFTEST_CHECK_Z c=20 if (screen == TestScreen::Bed) lcd_puts_P(_T(MSG_SELFTEST_CHECK_BED)); if (screen == TestScreen::Hotend || screen == TestScreen::HotendOk) lcd_puts_P(_i("Checking hotend "));////MSG_SELFTEST_CHECK_HOTEND c=20 diff --git a/lang/lang_en.txt b/lang/lang_en.txt index 163746199..3367e1497 100644 --- a/lang/lang_en.txt +++ b/lang/lang_en.txt @@ -254,7 +254,7 @@ "Fil. sensor" #MSG_FIL_RUNOUTS c=15 -"Fil. runouts " +"Fil. runouts" #MSG_FILAMENT_CLEAN c=20 r=2 "Filament extruding & with correct color?" diff --git a/lang/lang_en_cz.txt b/lang/lang_en_cz.txt index 7e8666e2d..cda08b0aa 100644 --- a/lang/lang_en_cz.txt +++ b/lang/lang_en_cz.txt @@ -339,7 +339,7 @@ "Fil. senzor" #MSG_FIL_RUNOUTS c=15 -"Fil. runouts " +"Fil. runouts" "Vypadky filam." #MSG_FILAMENT_CLEAN c=20 r=2 diff --git a/lang/lang_en_de.txt b/lang/lang_en_de.txt index 063ad995c..7215fea42 100644 --- a/lang/lang_en_de.txt +++ b/lang/lang_en_de.txt @@ -339,8 +339,8 @@ "Fil. Sensor" #MSG_FIL_RUNOUTS c=15 -"Fil. runouts " -"Fil. Maengel " +"Fil. runouts" +"Fil. Maengel" #MSG_FILAMENT_CLEAN c=20 r=2 "Filament extruding & with correct color?" diff --git a/lang/lang_en_es.txt b/lang/lang_en_es.txt index e334ddacd..1e7ae63d2 100644 --- a/lang/lang_en_es.txt +++ b/lang/lang_en_es.txt @@ -339,8 +339,8 @@ "Sensor Fil." #MSG_FIL_RUNOUTS c=15 -"Fil. runouts " -"Fil. acabado " +"Fil. runouts" +"Fil. acabado" #MSG_FILAMENT_CLEAN c=20 r=2 "Filament extruding & with correct color?" diff --git a/lang/lang_en_fr.txt b/lang/lang_en_fr.txt index a78c999e7..3910a2f69 100644 --- a/lang/lang_en_fr.txt +++ b/lang/lang_en_fr.txt @@ -339,8 +339,8 @@ "Capteur Fil." #MSG_FIL_RUNOUTS c=15 -"Fil. runouts " -"Fins filament " +"Fil. runouts" +"Fins filament" #MSG_FILAMENT_CLEAN c=20 r=2 "Filament extruding & with correct color?" diff --git a/lang/lang_en_it.txt b/lang/lang_en_it.txt index a442667a5..824442ffd 100644 --- a/lang/lang_en_it.txt +++ b/lang/lang_en_it.txt @@ -339,8 +339,8 @@ "Sensore fil." #MSG_FIL_RUNOUTS c=15 -"Fil. runouts " -"Fil. esauriti " +"Fil. runouts" +"Fil. esauriti" #MSG_FILAMENT_CLEAN c=20 r=2 "Filament extruding & with correct color?" diff --git a/lang/lang_en_pl.txt b/lang/lang_en_pl.txt index 104d61d2e..db420bf99 100644 --- a/lang/lang_en_pl.txt +++ b/lang/lang_en_pl.txt @@ -339,7 +339,7 @@ "Czuj. filam." #MSG_FIL_RUNOUTS c=15 -"Fil. runouts " +"Fil. runouts" "Konc.filamentu" #MSG_FILAMENT_CLEAN c=20 r=2 From dcc660580942fac4872e85ce80b143e086662d36 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Mon, 11 Jan 2021 11:13:40 +0100 Subject: [PATCH 04/44] Workaround for skipping large comment blocks If there are large blocks of comments in the G-code, the printer may get shot down by its own watchdog. Watchdog is generally set to 4s and updated only in manage_heaters (and some other spots in some specific cases). So far, the code reading the file and feeding it into Marlin cycles indefinitely until it finds valid G-code lines and fills up the command queue. If the block is large enough, the printer cannot read it completely within those 4s. A simple workaround - bail out after some consecutive empty/comment lines to enable other parts of code do their job (especially manage_heaters). Tested on MK404, previous FW fails with 600KB of comment lines at the beginning, this patch survives. The printer even draws some update on its status screen before starting a real print. --- Firmware/cmdqueue.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/Firmware/cmdqueue.cpp b/Firmware/cmdqueue.cpp index afdddfba2..f0ac1b395 100755 --- a/Firmware/cmdqueue.cpp +++ b/Firmware/cmdqueue.cpp @@ -573,6 +573,7 @@ void get_command() // this character _can_ occur in serial com, due to checksums. however, no checksums are used in SD printing static bool stop_buffering=false; + static uint8_t consecutiveEmptyLines = 0; if(buflen==0) stop_buffering=false; union { struct { @@ -586,11 +587,12 @@ void get_command() while( !card.eof() && !stop_buffering) { int16_t n=card.get(); char serial_char = (char)n; - if(serial_char == '\n' || - serial_char == '\r' || - ((serial_char == '#' || serial_char == ':') && comment_mode == false) || - serial_count >= (MAX_CMD_SIZE - 1) || n==-1) - { + if( serial_char == '\n' + || serial_char == '\r' + || ((serial_char == '#' || serial_char == ':') && comment_mode == false) + || serial_count >= (MAX_CMD_SIZE - 1) + || n==-1 + ){ if(serial_char=='#') stop_buffering=true; @@ -602,6 +604,10 @@ void get_command() // so that the lenght of the already read empty lines and comments will be added // to the following non-empty line. comment_mode = false; + if( ++consecutiveEmptyLines > 250 ){ + consecutiveEmptyLines = 0; + return; // prevent cycling indefinitely - let manage_heaters do their job + } continue; //if empty line } // The new command buffer could be updated non-atomically, because it is not yet considered @@ -638,9 +644,10 @@ void get_command() comment_mode = false; //for new command serial_count = 0; //clear buffer + consecutiveEmptyLines = 0; // reached a non-empty line which shall be enqueued if(card.eof()) break; - + // The following line will reserve buffer space if available. if (! cmdqueue_could_enqueue_back(MAX_CMD_SIZE-1, true)) return; From c3758d350efa9f677eb44e0ab5a98fabc190e5bf Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Thu, 14 Jan 2021 13:21:58 +0100 Subject: [PATCH 05/44] Fast skipping of large comment blocks This is an extension/optimization of PR #2956. It uses the cached 512B block buffer to avoid heavy-weight read() in SdBaseFile. Even though this principle allowed the AVR to skip ~600KB of data within ~5 seconds, the impact on code base is huge, especially into well proven and long-term stable parts like reading a file from the SD card. The sole purpose of this PR is to show/verify the possibility of the AVR CPU in relation to adding thumbnails into MK3 G-codes. Moreover, this PR shall not be merged unless the missing/commented features are restored - especially file seeking and M84 search. PFW-1175 --- Firmware/Marlin_main.cpp | 6 +- Firmware/SdBaseFile.cpp | 126 +++++++++++++++++++++++++++++++++++++-- Firmware/SdBaseFile.h | 29 ++++++++- Firmware/SdVolume.h | 5 +- Firmware/cardreader.cpp | 65 ++++++++++++++++++++ Firmware/cardreader.h | 6 +- Firmware/cmdqueue.cpp | 24 ++++---- Firmware/ultralcd.cpp | 4 +- 8 files changed, 243 insertions(+), 22 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 4739dc4a8..a5bd4e04a 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -3987,7 +3987,9 @@ void process_commands() #endif }else if (code_seen_P("fv")) { // PRUSA fv // get file version - #ifdef SDSUPPORT + #if 0 + //@@TODO + def SDSUPPORT card.openFile(strchr_pointer + 3,true); while (true) { uint16_t readByte = card.get(); @@ -5767,7 +5769,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) starpos = (strchr(strchr_pointer + 4,'*')); if(starpos!=NULL) *(starpos)='\0'; - card.openFile(strchr_pointer + 4,true); + card.openFileFilteredGcode(strchr_pointer + 4); break; /*! diff --git a/Firmware/SdBaseFile.cpp b/Firmware/SdBaseFile.cpp index b9e881ef2..4dead898c 100644 --- a/Firmware/SdBaseFile.cpp +++ b/Firmware/SdBaseFile.cpp @@ -530,9 +530,21 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) { * \return The value one, true, is returned for success and * the value zero, false, is returned for failure. */ - bool SdBaseFile::open(const char* path, uint8_t oflag) { - return open(cwd_, path, oflag); - } +bool SdBaseFile::open(const char* path, uint8_t oflag) { + return open(cwd_, path, oflag); +} + +bool SdBaseFile::openFilteredGcode(SdBaseFile* dirFile, const char* path){ + if( open(dirFile, path, O_READ) ){ + gf.reset(0,0); + // compute the block to start with + if( ! computeNextFileBlock(&gf.block, &gf.offset) ) + return false; + return true; + } else { + return false; + } +} //------------------------------------------------------------------------------ /** Open a file or directory by name. * @@ -1030,6 +1042,112 @@ int16_t SdBaseFile::read() { uint8_t b; return read(&b, 1) == 1 ? b : -1; } + +int16_t SdBaseFile::readFilteredGcode() { + // avoid calling the default heavy-weight read() for just one byte + return gf.read_byte(); +} + +void GCodeInputFilter::reset(uint32_t blk, uint16_t ofs){ + // @@TODO clean up + block = blk; + offset = ofs; + cachePBegin = sd->vol_->cache()->data; + // reset cache read ptr to its begin + cacheP = cachePBegin; +} + +int16_t GCodeInputFilter::read_byte(){ + EnsureBlock(); // this is unfortunate :( ... other calls are using the cache and we can loose the data block of our gcode file + + // assume, we have the 512B block cache filled and terminated with a '\n' +// SERIAL_PROTOCOLPGM("read_byte enter:"); +// for(uint8_t i = 0; i < 16; ++i){ +// SERIAL_PROTOCOL( cacheP[i] ); +// } + + const uint8_t *start = cacheP; + uint8_t consecutiveCommentLines = 0; + while( *cacheP == ';' ){ + for(;;){ + while( *(++cacheP) != '\n' ); // skip until a newline is found + // found a newline, prepare the next block if block cache end reached + if( cacheP - cachePBegin >= 512 ){ + // at the end of block cache, fill new data in + sd->curPosition_ += cacheP - start; + if( ! sd->computeNextFileBlock(&block, &offset) )goto fail; + EnsureBlock(); // fetch it into RAM + cacheP = start = cachePBegin; + } else { + if(++consecutiveCommentLines == 255){ + // SERIAL_PROTOCOLLN(sd->curPosition_); + goto forceExit; + } + // peek the next byte - we are inside the block at least at 511th index - still safe + if( *(cacheP+1) == ';' ){ + // consecutive comment + ++cacheP; + ++consecutiveCommentLines; + } + break; // found the real end of the line even across many blocks + } + } + } +forceExit: + sd->curPosition_ += cacheP - start + 1; + { + int16_t rv = *cacheP++; + + // prepare next block if needed + if( cacheP - cachePBegin >= 512 ){ +// SERIAL_PROTOCOLLN(sd->curPosition_); + if( ! sd->computeNextFileBlock(&block, &offset) )goto fail; + // don't need to force fetch the block here, it will get loaded on the next call + cacheP = cachePBegin; + } + return rv; + } +fail: +// SERIAL_PROTOCOLLNPGM("CacheFAIL"); + return -1; +} + +bool GCodeInputFilter::EnsureBlock(){ + if ( sd->vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)){ + // terminate with a '\n' + const uint16_t terminateOfs = (sd->fileSize_ - offset) < 512 ? (sd->fileSize_ - offset) : 512; + sd->vol_->cache()->data[ terminateOfs ] = '\n'; + return true; + } else { + return false; + } +} + +bool SdBaseFile::computeNextFileBlock(uint32_t *block, uint16_t *offset) { + // error if not open or write only + if (!isOpen() || !(flags_ & O_READ)) return false; + + *offset = curPosition_ & 0X1FF; // offset in block + if (type_ == FAT_FILE_TYPE_ROOT_FIXED) { + *block = vol_->rootDirStart() + (curPosition_ >> 9); + } else { + uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_); + if (*offset == 0 && blockOfCluster == 0) { + // start of new cluster + if (curPosition_ == 0) { + // use first cluster in file + curCluster_ = firstCluster_; + } else { + // get next cluster from FAT + if (!vol_->fatGet(curCluster_, &curCluster_)) return false; + } + } + *block = vol_->clusterStartBlock(curCluster_) + blockOfCluster; + } + return true; +} + + //------------------------------------------------------------------------------ /** Read data from a file starting at the current position. * @@ -1443,7 +1561,7 @@ bool SdBaseFile::rmRfStar() { * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive * OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t). */ -SdBaseFile::SdBaseFile(const char* path, uint8_t oflag) { +SdBaseFile::SdBaseFile(const char* path, uint8_t oflag):gf(this) { type_ = FAT_FILE_TYPE_CLOSED; writeError = false; open(path, oflag); diff --git a/Firmware/SdBaseFile.h b/Firmware/SdBaseFile.h index 923a391dd..4b3395875 100644 --- a/Firmware/SdBaseFile.h +++ b/Firmware/SdBaseFile.h @@ -174,15 +174,34 @@ static inline uint8_t FAT_SECOND(uint16_t fatTime) { uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1; /** Default time for file timestamp is 1 am */ uint16_t const FAT_DEFAULT_TIME = (1 << 11); + + +class SdBaseFile; +class GCodeInputFilter { + SdBaseFile *sd; //@@TODO subject to removal - merge with some derived SdFileXX + const uint8_t *cachePBegin; + const uint8_t *cacheP; + bool EnsureBlock(); +public: + uint32_t block; // remember the current file block to be kept in cache - due to reuse of the memory, the block may fall out a must be read back + uint16_t offset; + +public: + inline GCodeInputFilter(SdBaseFile *sd):sd(sd){} + void reset(uint32_t blk, uint16_t ofs); + int16_t read_byte(); +}; + //------------------------------------------------------------------------------ /** * \class SdBaseFile * \brief Base class for SdFile with Print and C++ streams. */ class SdBaseFile { + GCodeInputFilter gf; public: /** Create an instance. */ - SdBaseFile() : writeError(false), type_(FAT_FILE_TYPE_CLOSED) {} + SdBaseFile() : gf(this), writeError(false), type_(FAT_FILE_TYPE_CLOSED) {} SdBaseFile(const char* path, uint8_t oflag); ~SdBaseFile() {if(isOpen()) close();} /** @@ -275,14 +294,21 @@ class SdBaseFile { bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag); bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag); bool open(const char* path, uint8_t oflag = O_READ); + bool openFilteredGcode(SdBaseFile* dirFile, const char* path); bool openNext(SdBaseFile* dirFile, uint8_t oflag); bool openRoot(SdVolume* vol); int peek(); static void printFatDate(uint16_t fatDate); static void printFatTime( uint16_t fatTime); bool printName(); + + int16_t readFilteredGcode(); + bool computeNextFileBlock(uint32_t *block, uint16_t *offset); + +private: int16_t read(); int16_t read(void* buf, uint16_t nbyte); +public: int8_t readDir(dir_t* dir, char* longFilename); static bool remove(SdBaseFile* dirFile, const char* path); bool remove(); @@ -322,6 +348,7 @@ class SdBaseFile { int16_t write(const void* buf, uint16_t nbyte); //------------------------------------------------------------------------------ private: + friend class GCodeInputFilter; // allow SdFat to set cwd_ friend class SdFat; // global pointer to cwd dir diff --git a/Firmware/SdVolume.h b/Firmware/SdVolume.h index 2ff2b6eb9..7c4fce959 100644 --- a/Firmware/SdVolume.h +++ b/Firmware/SdVolume.h @@ -36,7 +36,7 @@ */ union cache_t { /** Used to access cached file data blocks. */ - uint8_t data[512]; + uint8_t data[512 + 1]; // abuse the last byte for saving '\n' - ugly optimization of read_filtered's inner skipping loop /** Used to access cached FAT16 entries. */ uint16_t fat16[256]; /** Used to access cached FAT32 entries. */ @@ -119,6 +119,7 @@ class SdVolume { bool dbgFat(uint32_t n, uint32_t* v) {return fatGet(n, v);} //------------------------------------------------------------------------------ private: + friend class GCodeInputFilter; // Allow SdBaseFile access to SdVolume private data. friend class SdBaseFile; @@ -211,4 +212,4 @@ class SdVolume { #endif // ALLOW_DEPRECATED_FUNCTIONS }; #endif // SdVolume -#endif \ No newline at end of file +#endif diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index e228c5236..abeec6a8d 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -375,6 +375,71 @@ void CardReader::diveSubfolder (const char *fileName, SdFile& dir) } } +// @@TODO merge with openFile, too much duplicated code and texts +void CardReader::openFileFilteredGcode(const char* name, bool replace_current/* = false*/){ + if(!cardOK) + return; + + if(file.isOpen()){ //replacing current file by new file, or subfile call + if(!replace_current){ + if((int)file_subcall_ctr>(int)SD_PROCEDURE_DEPTH-1){ + // SERIAL_ERROR_START; + // SERIAL_ERRORPGM("trying to call sub-gcode files with too many levels. MAX level is:"); + // SERIAL_ERRORLN(SD_PROCEDURE_DEPTH); + kill(_n("trying to call sub-gcode files with too many levels."), 1); + return; + } + + SERIAL_ECHO_START; + SERIAL_ECHOPGM("SUBROUTINE CALL target:\""); + SERIAL_ECHO(name); + SERIAL_ECHOPGM("\" parent:\""); + + //store current filename and position + getAbsFilename(filenames[file_subcall_ctr]); + + SERIAL_ECHO(filenames[file_subcall_ctr]); + SERIAL_ECHOPGM("\" pos"); + SERIAL_ECHOLN(sdpos); + filespos[file_subcall_ctr]=sdpos; + file_subcall_ctr++; + } else { + SERIAL_ECHO_START; + SERIAL_ECHOPGM("Now doing file: "); + SERIAL_ECHOLN(name); + } + file.close(); + } else { //opening fresh file + file_subcall_ctr=0; //resetting procedure depth in case user cancels print while in procedure + SERIAL_ECHO_START; + SERIAL_ECHOPGM("Now fresh file: "); + SERIAL_ECHOLN(name); + } + sdprinting = false; + + SdFile myDir; + const char *fname=name; + diveSubfolder(fname,myDir); + + if (file.openFilteredGcode(curDir, fname)) { + filesize = file.fileSize(); + SERIAL_PROTOCOLRPGM(_N("File opened: "));////MSG_SD_FILE_OPENED + SERIAL_PROTOCOL(fname); + SERIAL_PROTOCOLRPGM(_n(" Size: "));////MSG_SD_SIZE + SERIAL_PROTOCOLLN(filesize); + sdpos = 0; + + SERIAL_PROTOCOLLNRPGM(_N("File selected"));////MSG_SD_FILE_SELECTED + getfilename(0, fname); + lcd_setstatus(longFilename[0] ? longFilename : fname); + lcd_setstatus("SD-PRINTING "); + } else { + SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL); + SERIAL_PROTOCOL(fname); + SERIAL_PROTOCOLLN('.'); + } +} + void CardReader::openFile(const char* name,bool read, bool replace_current/*=true*/) { if(!cardOK) diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 25e97882e..1c630b667 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -20,6 +20,7 @@ public: void checkautostart(bool x); void openFile(const char* name,bool read,bool replace_current=true); + void openFileFilteredGcode(const char* name, bool replace_current = false); void openLogFile(const char* name); void removeFile(const char* name); void closefile(bool store_location=false); @@ -59,7 +60,10 @@ public: FORCE_INLINE bool isFileOpen() { return file.isOpen(); } FORCE_INLINE bool eof() { return sdpos>=filesize ;}; - FORCE_INLINE int16_t get() { sdpos = file.curPosition();return (int16_t)file.read();}; +// FORCE_INLINE int16_t getX() { sdpos = file.curPosition();return (int16_t)file.read();}; + //@@TODO potential performance problem - when the comment reading fails, sdpos points to the last correctly read character. + // However, repeated reading (e.g. after power panic) the comment will be read again - it should survive correctly, it will just take a few moments to skip + FORCE_INLINE int16_t getFilteredGcodeChar() { sdpos = file.curPosition();return (int16_t)file.readFilteredGcode();}; FORCE_INLINE void setIndex(long index) {sdpos = index;file.seekSet(index);}; FORCE_INLINE uint8_t percentDone(){if(!isFileOpen()) return 0; if(filesize) return sdpos/((filesize+99)/100); else return 0;}; FORCE_INLINE char* getWorkDirName(){workDir.getFilename(filename);return filename;}; diff --git a/Firmware/cmdqueue.cpp b/Firmware/cmdqueue.cpp index f0ac1b395..c89032750 100755 --- a/Firmware/cmdqueue.cpp +++ b/Firmware/cmdqueue.cpp @@ -573,7 +573,7 @@ void get_command() // this character _can_ occur in serial com, due to checksums. however, no checksums are used in SD printing static bool stop_buffering=false; - static uint8_t consecutiveEmptyLines = 0; +// static uint8_t consecutiveEmptyLines = 0; if(buflen==0) stop_buffering=false; union { struct { @@ -585,11 +585,11 @@ void get_command() sd_count.value = 0; // Reads whole lines from the SD card. Never leaves a half-filled line in the cmdbuffer. while( !card.eof() && !stop_buffering) { - int16_t n=card.get(); + int16_t n=card.getFilteredGcodeChar(); char serial_char = (char)n; if( serial_char == '\n' || serial_char == '\r' - || ((serial_char == '#' || serial_char == ':') && comment_mode == false) + || ((serial_char == '#' || serial_char == ':') /*&& comment_mode == false*/) || serial_count >= (MAX_CMD_SIZE - 1) || n==-1 ){ @@ -603,12 +603,12 @@ void get_command() // read from the sdcard into sd_count, // so that the lenght of the already read empty lines and comments will be added // to the following non-empty line. - comment_mode = false; - if( ++consecutiveEmptyLines > 250 ){ - consecutiveEmptyLines = 0; +// comment_mode = false; +// if( ++consecutiveEmptyLines > 10 ){ +// consecutiveEmptyLines = 0; return; // prevent cycling indefinitely - let manage_heaters do their job - } - continue; //if empty line +// } +// continue; //if empty line } // The new command buffer could be updated non-atomically, because it is not yet considered // to be inside the active queue. @@ -644,7 +644,7 @@ void get_command() comment_mode = false; //for new command serial_count = 0; //clear buffer - consecutiveEmptyLines = 0; // reached a non-empty line which shall be enqueued +// consecutiveEmptyLines = 0; // reached a non-empty line which shall be enqueued if(card.eof()) break; @@ -654,8 +654,10 @@ void get_command() } else { - if(serial_char == ';') comment_mode = true; - else if(!comment_mode) cmdbuffer[bufindw+CMDHDRSIZE+serial_count++] = serial_char; + /*if(serial_char == ';') comment_mode = true; + else if(!comment_mode)*/ + // there are no comments coming from the filtered file + cmdbuffer[bufindw+CMDHDRSIZE+serial_count++] = serial_char; } } if(card.eof()) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index d7976d277..3fc5f5a66 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -8473,8 +8473,10 @@ static void lcd_selftest_screen_step(int _row, int _col, int _state, const char /** Menu action functions **/ static bool check_file(const char* filename) { + return true; // @@TODO + if (farm_mode) return true; - card.openFile((char*)filename, true); + card.openFileFilteredGcode((char*)filename, true); //@@TODO bool result = false; const uint32_t filesize = card.getFileSize(); uint32_t startPos = 0; From d275fe0e83e7d29397413e4804069dc0ef139670 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Wed, 27 Jan 2021 09:33:28 +0100 Subject: [PATCH 06/44] Extract gcode filter from SdBaseFile into SdFile + optimization - Start saving instructions as the whole PR was >1KB long. - It turned out the compiler was unable to understand the core skipping cycle and an ASM version had to be used. - Add seekSet aware of the G-code filter --- Firmware/SdBaseFile.cpp | 118 +--------------------------- Firmware/SdBaseFile.h | 29 +------ Firmware/SdFile.cpp | 170 ++++++++++++++++++++++++++++++++++++++++ Firmware/SdFile.h | 16 +++- Firmware/SdVolume.h | 2 +- Firmware/cardreader.h | 4 +- Firmware/ultralcd.cpp | 4 +- 7 files changed, 193 insertions(+), 150 deletions(-) diff --git a/Firmware/SdBaseFile.cpp b/Firmware/SdBaseFile.cpp index 4dead898c..4b19ceae6 100644 --- a/Firmware/SdBaseFile.cpp +++ b/Firmware/SdBaseFile.cpp @@ -534,17 +534,6 @@ bool SdBaseFile::open(const char* path, uint8_t oflag) { return open(cwd_, path, oflag); } -bool SdBaseFile::openFilteredGcode(SdBaseFile* dirFile, const char* path){ - if( open(dirFile, path, O_READ) ){ - gf.reset(0,0); - // compute the block to start with - if( ! computeNextFileBlock(&gf.block, &gf.offset) ) - return false; - return true; - } else { - return false; - } -} //------------------------------------------------------------------------------ /** Open a file or directory by name. * @@ -1043,111 +1032,6 @@ int16_t SdBaseFile::read() { return read(&b, 1) == 1 ? b : -1; } -int16_t SdBaseFile::readFilteredGcode() { - // avoid calling the default heavy-weight read() for just one byte - return gf.read_byte(); -} - -void GCodeInputFilter::reset(uint32_t blk, uint16_t ofs){ - // @@TODO clean up - block = blk; - offset = ofs; - cachePBegin = sd->vol_->cache()->data; - // reset cache read ptr to its begin - cacheP = cachePBegin; -} - -int16_t GCodeInputFilter::read_byte(){ - EnsureBlock(); // this is unfortunate :( ... other calls are using the cache and we can loose the data block of our gcode file - - // assume, we have the 512B block cache filled and terminated with a '\n' -// SERIAL_PROTOCOLPGM("read_byte enter:"); -// for(uint8_t i = 0; i < 16; ++i){ -// SERIAL_PROTOCOL( cacheP[i] ); -// } - - const uint8_t *start = cacheP; - uint8_t consecutiveCommentLines = 0; - while( *cacheP == ';' ){ - for(;;){ - while( *(++cacheP) != '\n' ); // skip until a newline is found - // found a newline, prepare the next block if block cache end reached - if( cacheP - cachePBegin >= 512 ){ - // at the end of block cache, fill new data in - sd->curPosition_ += cacheP - start; - if( ! sd->computeNextFileBlock(&block, &offset) )goto fail; - EnsureBlock(); // fetch it into RAM - cacheP = start = cachePBegin; - } else { - if(++consecutiveCommentLines == 255){ - // SERIAL_PROTOCOLLN(sd->curPosition_); - goto forceExit; - } - // peek the next byte - we are inside the block at least at 511th index - still safe - if( *(cacheP+1) == ';' ){ - // consecutive comment - ++cacheP; - ++consecutiveCommentLines; - } - break; // found the real end of the line even across many blocks - } - } - } -forceExit: - sd->curPosition_ += cacheP - start + 1; - { - int16_t rv = *cacheP++; - - // prepare next block if needed - if( cacheP - cachePBegin >= 512 ){ -// SERIAL_PROTOCOLLN(sd->curPosition_); - if( ! sd->computeNextFileBlock(&block, &offset) )goto fail; - // don't need to force fetch the block here, it will get loaded on the next call - cacheP = cachePBegin; - } - return rv; - } -fail: -// SERIAL_PROTOCOLLNPGM("CacheFAIL"); - return -1; -} - -bool GCodeInputFilter::EnsureBlock(){ - if ( sd->vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)){ - // terminate with a '\n' - const uint16_t terminateOfs = (sd->fileSize_ - offset) < 512 ? (sd->fileSize_ - offset) : 512; - sd->vol_->cache()->data[ terminateOfs ] = '\n'; - return true; - } else { - return false; - } -} - -bool SdBaseFile::computeNextFileBlock(uint32_t *block, uint16_t *offset) { - // error if not open or write only - if (!isOpen() || !(flags_ & O_READ)) return false; - - *offset = curPosition_ & 0X1FF; // offset in block - if (type_ == FAT_FILE_TYPE_ROOT_FIXED) { - *block = vol_->rootDirStart() + (curPosition_ >> 9); - } else { - uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_); - if (*offset == 0 && blockOfCluster == 0) { - // start of new cluster - if (curPosition_ == 0) { - // use first cluster in file - curCluster_ = firstCluster_; - } else { - // get next cluster from FAT - if (!vol_->fatGet(curCluster_, &curCluster_)) return false; - } - } - *block = vol_->clusterStartBlock(curCluster_) + blockOfCluster; - } - return true; -} - - //------------------------------------------------------------------------------ /** Read data from a file starting at the current position. * @@ -1561,7 +1445,7 @@ bool SdBaseFile::rmRfStar() { * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive * OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t). */ -SdBaseFile::SdBaseFile(const char* path, uint8_t oflag):gf(this) { +SdBaseFile::SdBaseFile(const char* path, uint8_t oflag) { type_ = FAT_FILE_TYPE_CLOSED; writeError = false; open(path, oflag); diff --git a/Firmware/SdBaseFile.h b/Firmware/SdBaseFile.h index 4b3395875..ac39338da 100644 --- a/Firmware/SdBaseFile.h +++ b/Firmware/SdBaseFile.h @@ -176,32 +176,15 @@ uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1; uint16_t const FAT_DEFAULT_TIME = (1 << 11); -class SdBaseFile; -class GCodeInputFilter { - SdBaseFile *sd; //@@TODO subject to removal - merge with some derived SdFileXX - const uint8_t *cachePBegin; - const uint8_t *cacheP; - bool EnsureBlock(); -public: - uint32_t block; // remember the current file block to be kept in cache - due to reuse of the memory, the block may fall out a must be read back - uint16_t offset; - -public: - inline GCodeInputFilter(SdBaseFile *sd):sd(sd){} - void reset(uint32_t blk, uint16_t ofs); - int16_t read_byte(); -}; - //------------------------------------------------------------------------------ /** * \class SdBaseFile * \brief Base class for SdFile with Print and C++ streams. */ class SdBaseFile { - GCodeInputFilter gf; public: /** Create an instance. */ - SdBaseFile() : gf(this), writeError(false), type_(FAT_FILE_TYPE_CLOSED) {} + SdBaseFile() : writeError(false), type_(FAT_FILE_TYPE_CLOSED) {} SdBaseFile(const char* path, uint8_t oflag); ~SdBaseFile() {if(isOpen()) close();} /** @@ -294,18 +277,13 @@ class SdBaseFile { bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag); bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag); bool open(const char* path, uint8_t oflag = O_READ); - bool openFilteredGcode(SdBaseFile* dirFile, const char* path); bool openNext(SdBaseFile* dirFile, uint8_t oflag); bool openRoot(SdVolume* vol); int peek(); static void printFatDate(uint16_t fatDate); static void printFatTime( uint16_t fatTime); bool printName(); - - int16_t readFilteredGcode(); - bool computeNextFileBlock(uint32_t *block, uint16_t *offset); - -private: +protected: int16_t read(); int16_t read(void* buf, uint16_t nbyte); public: @@ -347,8 +325,7 @@ public: SdVolume* volume() const {return vol_;} int16_t write(const void* buf, uint16_t nbyte); //------------------------------------------------------------------------------ - private: - friend class GCodeInputFilter; + protected: // allow SdFat to set cwd_ friend class SdFat; // global pointer to cwd dir diff --git a/Firmware/SdFile.cpp b/Firmware/SdFile.cpp index 2fb4d5943..4787a0930 100644 --- a/Firmware/SdFile.cpp +++ b/Firmware/SdFile.cpp @@ -30,6 +30,176 @@ */ SdFile::SdFile(const char* path, uint8_t oflag) : SdBaseFile(path, oflag) { } + +//size=100B +bool SdFile::openFilteredGcode(SdBaseFile* dirFile, const char* path){ + if( open(dirFile, path, O_READ) ){ + gfReset(0,0); + // compute the block to start with + if( ! gfComputeNextFileBlock() ) + return false; + return true; + } else { + return false; + } +} + +//size=90B +bool SdFile::seekSetFilteredGcode(uint32_t pos){ + bool rv = seekSet(pos); + gfComputeNextFileBlock(); + return rv; +} + +//size=50B +void SdFile::gfReset(uint32_t blk, uint16_t ofs){ + // @@TODO clean up + gfBlock = blk; + gfOffset = ofs; + gfCachePBegin = vol_->cache()->data; + // reset cache read ptr to its begin + gfCacheP = gfCachePBegin; +} + +//FORCE_INLINE const uint8_t * find_endl(const uint8_t *p){ +// while( *(++p) != '\n' ); // skip until a newline is found +// return p; +//} + +// think twice before allowing this to inline - manipulating 4B longs is costly +// moreover - this function has its parameters in registers only, so no heavy stack usage besides the call/ret +void __attribute__((noinline)) SdFile::gfUpdateCurrentPosition(uint16_t inc){ + curPosition_ += inc; +} + +#define find_endl(resultP, startP) \ +__asm__ __volatile__ ( \ +"cycle: \n" \ +"ld r22, Z+ \n" \ +"cpi r22, 0x0A \n" \ +"brne cycle \n" \ +: "=z" (resultP) /* result of the ASM code - in our case the Z register (R30:R31) */ \ +: "z" (startP) /* input of the ASM code - in our case the Z register as well (R30:R31) */ \ +: "r22" /* modifying register R22 - so that the compiler knows */ \ +) + +//size=400B +// avoid calling the default heavy-weight read() for just one byte +int16_t SdFile::readFilteredGcode(){ + gfEnsureBlock(); // this is unfortunate :( ... other calls are using the cache and we can loose the data block of our gcode file + + // assume, we have the 512B block cache filled and terminated with a '\n' +// SERIAL_PROTOCOLPGM("read_byte enter:"); +// for(uint8_t i = 0; i < 16; ++i){ +// SERIAL_PROTOCOL( cacheP[i] ); +// } + + const uint8_t *start = gfCacheP; + uint8_t consecutiveCommentLines = 0; + while( *gfCacheP == ';' ){ + for(;;){ + + //while( *(++gfCacheP) != '\n' ); // skip until a newline is found - suboptimal code! + // Wondering, why this "nice while cycle" is done in such a weird way using a separate find_endl() function? + // Have a look at the ASM code GCC produced! + + // At first - a separate find_endl() makes the compiler understand, + // that I don't need to store gfCacheP every time, I'm only interested in the final address where the '\n' was found + // - the cycle can run on CPU registers only without touching memory besides reading the character being compared. + // Not only makes the code run considerably faster, but is also 40B shorter! + // This was the generated code: + //FORCE_INLINE const uint8_t * find_endl(const uint8_t *p){ + // while( *(++p) != '\n' ); // skip until a newline is found + // return p; } + // 11c5e: movw r30, r18 + // 11c60: subi r18, 0xFF ; 255 + // 11c62: sbci r19, 0xFF ; 255 + // 11c64: ld r22, Z + // 11c66: cpi r22, 0x0A ; 10 + // 11c68: brne .-12 ; 0x11c5e + + // Still, even that was suboptimal as the compiler seems not to understand the usage of ld r22, Z+ (the plus is important) + // aka automatic increment of the Z register (R30:R31 pair) + // There is no other way than pure ASM! + find_endl(gfCacheP, gfCacheP); + + // found a newline, prepare the next block if block cache end reached + if( gfCacheP - gfCachePBegin >= 512 ){ + // at the end of block cache, fill new data in + gfUpdateCurrentPosition( gfCacheP - start ); + if( ! gfComputeNextFileBlock() )goto fail; + gfEnsureBlock(); // fetch it into RAM + gfCacheP = start = gfCachePBegin; + } else { + if(++consecutiveCommentLines == 255){ + // SERIAL_PROTOCOLLN(sd->curPosition_); + goto forceExit; + } + // peek the next byte - we are inside the block at least at 511th index - still safe + if( *(gfCacheP+1) == ';' ){ + // consecutive comment + ++gfCacheP; + ++consecutiveCommentLines; + } + break; // found the real end of the line even across many blocks + } + } + } +forceExit: + { + gfUpdateCurrentPosition( gfCacheP - start + 1 ); + int16_t rv = *gfCacheP++; + + // prepare next block if needed + if( gfCacheP - gfCachePBegin >= 512 ){ + if( ! gfComputeNextFileBlock() )goto fail; + // don't need to force fetch the block here, it will get loaded on the next call + gfCacheP = gfCachePBegin; + } + return rv; + } +fail: +// SERIAL_PROTOCOLLNPGM("CacheFAIL"); + return -1; +} + +//size=100B +bool SdFile::gfEnsureBlock(){ + if ( vol_->cacheRawBlock(gfBlock, SdVolume::CACHE_FOR_READ)){ + // terminate with a '\n' + const uint16_t terminateOfs = (fileSize_ - gfOffset) < 512 ? (fileSize_ - gfOffset) : 512U; + vol_->cache()->data[ terminateOfs ] = '\n'; + return true; + } else { + return false; + } +} + +//size=350B +bool SdFile::gfComputeNextFileBlock() { + // error if not open or write only + if (!isOpen() || !(flags_ & O_READ)) return false; + + gfOffset = curPosition_ & 0X1FF; // offset in block + if (type_ == FAT_FILE_TYPE_ROOT_FIXED) { + gfBlock = vol_->rootDirStart() + (curPosition_ >> 9); + } else { + uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_); + if (gfOffset == 0 && blockOfCluster == 0) { + // start of new cluster + if (curPosition_ == 0) { + // use first cluster in file + curCluster_ = firstCluster_; + } else { + // get next cluster from FAT + if (!vol_->fatGet(curCluster_, &curCluster_)) return false; + } + } + gfBlock = vol_->clusterStartBlock(curCluster_) + blockOfCluster; + } + return true; +} + //------------------------------------------------------------------------------ /** Write data to an open file. * diff --git a/Firmware/SdFile.h b/Firmware/SdFile.h index 60e2f5deb..b4c91a7e8 100644 --- a/Firmware/SdFile.h +++ b/Firmware/SdFile.h @@ -34,7 +34,16 @@ * \brief SdBaseFile with Print. */ class SdFile : public SdBaseFile/*, public Print*/ { - public: + // GCode filtering vars and methods - due to optimization reasons not wrapped in a separate class + const uint8_t *gfCachePBegin; + const uint8_t *gfCacheP; + uint32_t gfBlock; // remember the current file block to be kept in cache - due to reuse of the memory, the block may fall out a must be read back + uint16_t gfOffset; + void gfReset(uint32_t blk, uint16_t ofs); + bool gfEnsureBlock(); + bool gfComputeNextFileBlock(); + void gfUpdateCurrentPosition(uint16_t inc); +public: SdFile() {} SdFile(const char* name, uint8_t oflag); #if ARDUINO >= 100 @@ -43,6 +52,9 @@ class SdFile : public SdBaseFile/*, public Print*/ { void write(uint8_t b); #endif + bool openFilteredGcode(SdBaseFile* dirFile, const char* path); + int16_t readFilteredGcode(); + bool seekSetFilteredGcode(uint32_t pos); int16_t write(const void* buf, uint16_t nbyte); void write(const char* str); void write_P(PGM_P str); @@ -51,4 +63,4 @@ class SdFile : public SdBaseFile/*, public Print*/ { #endif // SdFile_h -#endif \ No newline at end of file +#endif diff --git a/Firmware/SdVolume.h b/Firmware/SdVolume.h index 7c4fce959..17699190e 100644 --- a/Firmware/SdVolume.h +++ b/Firmware/SdVolume.h @@ -119,7 +119,7 @@ class SdVolume { bool dbgFat(uint32_t n, uint32_t* v) {return fatGet(n, v);} //------------------------------------------------------------------------------ private: - friend class GCodeInputFilter; + friend class SdFile; // Allow SdBaseFile access to SdVolume private data. friend class SdBaseFile; diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 1c630b667..8dfb68c98 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -1,6 +1,8 @@ #ifndef CARDREADER_H #define CARDREADER_H +#define SDSUPPORT + #ifdef SDSUPPORT #define MAX_DIR_DEPTH 10 @@ -64,7 +66,7 @@ public: //@@TODO potential performance problem - when the comment reading fails, sdpos points to the last correctly read character. // However, repeated reading (e.g. after power panic) the comment will be read again - it should survive correctly, it will just take a few moments to skip FORCE_INLINE int16_t getFilteredGcodeChar() { sdpos = file.curPosition();return (int16_t)file.readFilteredGcode();}; - FORCE_INLINE void setIndex(long index) {sdpos = index;file.seekSet(index);}; + /*FORCE_INLINE*/ void setIndex(long index) {sdpos = index;file.seekSetFilteredGcode(index);}; FORCE_INLINE uint8_t percentDone(){if(!isFileOpen()) return 0; if(filesize) return sdpos/((filesize+99)/100); else return 0;}; FORCE_INLINE char* getWorkDirName(){workDir.getFilename(filename);return filename;}; FORCE_INLINE uint32_t get_sdpos() { if (!isFileOpen()) return 0; else return(sdpos); }; diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 3fc5f5a66..78dddf2be 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -8473,10 +8473,8 @@ static void lcd_selftest_screen_step(int _row, int _col, int _state, const char /** Menu action functions **/ static bool check_file(const char* filename) { - return true; // @@TODO - if (farm_mode) return true; - card.openFileFilteredGcode((char*)filename, true); //@@TODO + card.openFileFilteredGcode((char*)filename, true); bool result = false; const uint32_t filesize = card.getFileSize(); uint32_t startPos = 0; From b6c59e08ac4ada0d78bf87b68a029d2e2c88a2f4 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Wed, 27 Jan 2021 09:52:20 +0100 Subject: [PATCH 07/44] Workaround ++gfCacheP into postincrement ld r22, Z+ TODO: ideally improve the automaton to work with postincrement only, at least in this case. --- Firmware/SdFile.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Firmware/SdFile.cpp b/Firmware/SdFile.cpp index 4787a0930..0d30618e2 100644 --- a/Firmware/SdFile.cpp +++ b/Firmware/SdFile.cpp @@ -74,10 +74,12 @@ void __attribute__((noinline)) SdFile::gfUpdateCurrentPosition(uint16_t inc){ #define find_endl(resultP, startP) \ __asm__ __volatile__ ( \ +"adiw r30, 1 \n" /* workaround the ++gfCacheP into post increment Z+ */ \ "cycle: \n" \ "ld r22, Z+ \n" \ "cpi r22, 0x0A \n" \ "brne cycle \n" \ +"sbiw r30, 1 \n" /* workaround the ++gfCacheP into post increment Z+ */ \ : "=z" (resultP) /* result of the ASM code - in our case the Z register (R30:R31) */ \ : "z" (startP) /* input of the ASM code - in our case the Z register as well (R30:R31) */ \ : "r22" /* modifying register R22 - so that the compiler knows */ \ From b2cf5b7b6c3818b783d63972d8507e24a84a6f24 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Wed, 27 Jan 2021 13:01:25 +0100 Subject: [PATCH 08/44] Fix seekSetFilteredGcode() +some more debug code which will vanish after all is done and verified --- Firmware/SdFile.cpp | 50 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/Firmware/SdFile.cpp b/Firmware/SdFile.cpp index 0d30618e2..b3dfefe9a 100644 --- a/Firmware/SdFile.cpp +++ b/Firmware/SdFile.cpp @@ -46,9 +46,14 @@ bool SdFile::openFilteredGcode(SdBaseFile* dirFile, const char* path){ //size=90B bool SdFile::seekSetFilteredGcode(uint32_t pos){ - bool rv = seekSet(pos); - gfComputeNextFileBlock(); - return rv; +// SERIAL_PROTOCOLPGM("Seek:"); +// SERIAL_PROTOCOLLN(pos); + if(! seekSet(pos) )return false; + if(! gfComputeNextFileBlock() )return false; + gfCachePBegin = vol_->cache()->data; + // reset cache read ptr to its begin + gfCacheP = gfCachePBegin + gfOffset; + return true; } //size=50B @@ -91,10 +96,13 @@ int16_t SdFile::readFilteredGcode(){ gfEnsureBlock(); // this is unfortunate :( ... other calls are using the cache and we can loose the data block of our gcode file // assume, we have the 512B block cache filled and terminated with a '\n' -// SERIAL_PROTOCOLPGM("read_byte enter:"); +// SERIAL_PROTOCOLPGM("Read:"); +// SERIAL_PROTOCOL(curPosition_); +// SERIAL_PROTOCOL(':'); // for(uint8_t i = 0; i < 16; ++i){ -// SERIAL_PROTOCOL( cacheP[i] ); +// SERIAL_PROTOCOL( gfCacheP[i] ); // } +// SERIAL_PROTOCOLLN(); const uint8_t *start = gfCacheP; uint8_t consecutiveCommentLines = 0; @@ -154,6 +162,10 @@ forceExit: // prepare next block if needed if( gfCacheP - gfCachePBegin >= 512 ){ +// speed checking - now at roughly 170KB/s which is much closer to raw read speed of SD card blocks at ~250KB/s +// SERIAL_PROTOCOL(millis2()); +// SERIAL_PROTOCOL(':'); +// SERIAL_PROTOCOLLN(curPosition_); if( ! gfComputeNextFileBlock() )goto fail; // don't need to force fetch the block here, it will get loaded on the next call gfCacheP = gfCachePBegin; @@ -165,18 +177,35 @@ fail: return -1; } -//size=100B +//size=70B bool SdFile::gfEnsureBlock(){ +// SERIAL_PROTOCOLPGM("EB:"); +// SERIAL_PROTOCOLLN(gfBlock); if ( vol_->cacheRawBlock(gfBlock, SdVolume::CACHE_FOR_READ)){ // terminate with a '\n' - const uint16_t terminateOfs = (fileSize_ - gfOffset) < 512 ? (fileSize_ - gfOffset) : 512U; - vol_->cache()->data[ terminateOfs ] = '\n'; + const uint16_t terminateOfs = fileSize_ - gfOffset; + vol_->cache()->data[ terminateOfs < 512 ? terminateOfs : 512 ] = '\n'; return true; } else { return false; } } + +//#define shr9(resultCurPos, curPos) \ +//__asm__ __volatile__ ( \ +//"asr r23 \n" \ +//"asr r22 \n" \ +//"asr r21 \n" \ +//"asr r20 \n" \ +//"ldi r20, r21 \n" \ +//"ldi r21, r22 \n" \ +//"ldi r22, r23 \n" \ +//"ldi r23, 0 \n" \ +//: "=a" (resultCurPos) \ +//: "a" (curPos) \ +//) + //size=350B bool SdFile::gfComputeNextFileBlock() { // error if not open or write only @@ -184,7 +213,10 @@ bool SdFile::gfComputeNextFileBlock() { gfOffset = curPosition_ & 0X1FF; // offset in block if (type_ == FAT_FILE_TYPE_ROOT_FIXED) { - gfBlock = vol_->rootDirStart() + (curPosition_ >> 9); + // SHR by 9 means skip the last byte and shift just 3 bytes by 1 + // -> should be 8 instructions... and not the horrible loop shifting 4 bytes at once + // still need to get some work on this + gfBlock = vol_->rootDirStart() + (curPosition_ >> 9); } else { uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_); if (gfOffset == 0 && blockOfCluster == 0) { From d1fd5a555f73889d3869761f826dfa4ce3c766c6 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Wed, 27 Jan 2021 14:12:11 +0100 Subject: [PATCH 09/44] Clean up gfReset() --- Firmware/SdFile.cpp | 13 ++++--------- Firmware/SdFile.h | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/Firmware/SdFile.cpp b/Firmware/SdFile.cpp index b3dfefe9a..5739f45ff 100644 --- a/Firmware/SdFile.cpp +++ b/Firmware/SdFile.cpp @@ -34,10 +34,10 @@ SdFile::SdFile(const char* path, uint8_t oflag) : SdBaseFile(path, oflag) { //size=100B bool SdFile::openFilteredGcode(SdBaseFile* dirFile, const char* path){ if( open(dirFile, path, O_READ) ){ - gfReset(0,0); // compute the block to start with if( ! gfComputeNextFileBlock() ) return false; + gfReset(); return true; } else { return false; @@ -50,20 +50,15 @@ bool SdFile::seekSetFilteredGcode(uint32_t pos){ // SERIAL_PROTOCOLLN(pos); if(! seekSet(pos) )return false; if(! gfComputeNextFileBlock() )return false; - gfCachePBegin = vol_->cache()->data; - // reset cache read ptr to its begin - gfCacheP = gfCachePBegin + gfOffset; + gfReset(); return true; } //size=50B -void SdFile::gfReset(uint32_t blk, uint16_t ofs){ - // @@TODO clean up - gfBlock = blk; - gfOffset = ofs; +void SdFile::gfReset(){ gfCachePBegin = vol_->cache()->data; // reset cache read ptr to its begin - gfCacheP = gfCachePBegin; + gfCacheP = gfCachePBegin + gfOffset; } //FORCE_INLINE const uint8_t * find_endl(const uint8_t *p){ diff --git a/Firmware/SdFile.h b/Firmware/SdFile.h index b4c91a7e8..a801a2282 100644 --- a/Firmware/SdFile.h +++ b/Firmware/SdFile.h @@ -39,7 +39,7 @@ class SdFile : public SdBaseFile/*, public Print*/ { const uint8_t *gfCacheP; uint32_t gfBlock; // remember the current file block to be kept in cache - due to reuse of the memory, the block may fall out a must be read back uint16_t gfOffset; - void gfReset(uint32_t blk, uint16_t ofs); + void gfReset(); bool gfEnsureBlock(); bool gfComputeNextFileBlock(); void gfUpdateCurrentPosition(uint16_t inc); From c05b625b1cfcda507c31e84367cefbb5a32abe9b Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Thu, 28 Jan 2021 08:13:16 +0100 Subject: [PATCH 10/44] Fix occasionally skipped valid G-code lines which also allowed for removal of the pre-increment -> post-increment workaround --- Firmware/SdFile.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Firmware/SdFile.cpp b/Firmware/SdFile.cpp index 5739f45ff..9d898fbcf 100644 --- a/Firmware/SdFile.cpp +++ b/Firmware/SdFile.cpp @@ -74,12 +74,10 @@ void __attribute__((noinline)) SdFile::gfUpdateCurrentPosition(uint16_t inc){ #define find_endl(resultP, startP) \ __asm__ __volatile__ ( \ -"adiw r30, 1 \n" /* workaround the ++gfCacheP into post increment Z+ */ \ "cycle: \n" \ "ld r22, Z+ \n" \ "cpi r22, 0x0A \n" \ "brne cycle \n" \ -"sbiw r30, 1 \n" /* workaround the ++gfCacheP into post increment Z+ */ \ : "=z" (resultP) /* result of the ASM code - in our case the Z register (R30:R31) */ \ : "z" (startP) /* input of the ASM code - in our case the Z register as well (R30:R31) */ \ : "r22" /* modifying register R22 - so that the compiler knows */ \ @@ -129,22 +127,25 @@ int16_t SdFile::readFilteredGcode(){ find_endl(gfCacheP, gfCacheP); // found a newline, prepare the next block if block cache end reached - if( gfCacheP - gfCachePBegin >= 512 ){ + if( gfCacheP - gfCachePBegin > 512 ){ // at the end of block cache, fill new data in - gfUpdateCurrentPosition( gfCacheP - start ); + gfUpdateCurrentPosition( gfCacheP - start - 1 ); if( ! gfComputeNextFileBlock() )goto fail; gfEnsureBlock(); // fetch it into RAM gfCacheP = start = gfCachePBegin; } else { if(++consecutiveCommentLines == 255){ // SERIAL_PROTOCOLLN(sd->curPosition_); + --gfCacheP; // unget the already consumed newline goto forceExit; } // peek the next byte - we are inside the block at least at 511th index - still safe - if( *(gfCacheP+1) == ';' ){ + if( *gfCacheP == ';' ){ // consecutive comment - ++gfCacheP; ++consecutiveCommentLines; + } else { + --gfCacheP; // unget the already consumed newline + goto forceExit; } break; // found the real end of the line even across many blocks } From 7279de740382a6f1bbbfa860978ec0706128e6a4 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Thu, 28 Jan 2021 09:37:58 +0100 Subject: [PATCH 11/44] Separate reading G-code files and writing to a file - extract common strings - cleanup openFileWrite and openFileReadFilteredGcode formatting a bit Alltogether - code size 400B down --- Firmware/Marlin_main.cpp | 8 +- Firmware/cardreader.cpp | 174 ++++++++++++++++----------------------- Firmware/cardreader.h | 4 +- Firmware/ultralcd.cpp | 2 +- 4 files changed, 80 insertions(+), 108 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index a5bd4e04a..73dd5df98 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -4005,7 +4005,7 @@ void process_commands() } else if (code_seen_P(PSTR("M28"))) { // PRUSA M28 trace(); prusa_sd_card_upload = true; - card.openFile(strchr_pointer+4,false); + card.openFileWrite(strchr_pointer+4); } else if (code_seen_P(PSTR("SN"))) { // PRUSA SN gcode_PRUSA_SN(); @@ -5769,7 +5769,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) starpos = (strchr(strchr_pointer + 4,'*')); if(starpos!=NULL) *(starpos)='\0'; - card.openFileFilteredGcode(strchr_pointer + 4); + card.openFileReadFilteredGcode(strchr_pointer + 4); break; /*! @@ -5833,7 +5833,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) strchr_pointer = strchr(npos,' ') + 1; *(starpos) = '\0'; } - card.openFile(strchr_pointer+4,false); + card.openFileWrite(strchr_pointer+4); break; /*! ### M29 - Stop SD write M29: Stop writing to SD card @@ -5894,7 +5894,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) if( card.cardOK ) { - card.openFile(namestartpos,true,!call_procedure); + card.openFileReadFilteredGcode(namestartpos,!call_procedure); if(code_seen('S')) if(strchr_pointer(int)SD_PROCEDURE_DEPTH-1) - { - // SERIAL_ERROR_START; - // SERIAL_ERRORPGM("trying to call sub-gcode files with too many levels. MAX level is:"); - // SERIAL_ERRORLN(SD_PROCEDURE_DEPTH); - kill(_n("trying to call sub-gcode files with too many levels."), 1); - return; - } - - SERIAL_ECHO_START; - SERIAL_ECHOPGM("SUBROUTINE CALL target:\""); - SERIAL_ECHO(name); - SERIAL_ECHOPGM("\" parent:\""); - - //store current filename and position - getAbsFilename(filenames[file_subcall_ctr]); - - SERIAL_ECHO(filenames[file_subcall_ctr]); - SERIAL_ECHOPGM("\" pos"); - SERIAL_ECHOLN(sdpos); - filespos[file_subcall_ctr]=sdpos; - file_subcall_ctr++; - } - else - { - SERIAL_ECHO_START; - SERIAL_ECHOPGM("Now doing file: "); - SERIAL_ECHOLN(name); - } - file.close(); - } - else //opening fresh file - { - file_subcall_ctr=0; //resetting procedure depth in case user cancels print while in procedure - SERIAL_ECHO_START; - SERIAL_ECHOPGM("Now fresh file: "); - SERIAL_ECHOLN(name); - } - sdprinting = false; + if(!cardOK) + return; + if(file.isOpen()){ //replacing current file by new file, or subfile call - SdFile myDir; - const char *fname=name; - diveSubfolder(fname,myDir); + // @@TODO I doubt this is necessary for file saving: - if(read) - { - if (file.open(curDir, fname, O_READ)) - { - filesize = file.fileSize(); - SERIAL_PROTOCOLRPGM(_N("File opened: "));////MSG_SD_FILE_OPENED - SERIAL_PROTOCOL(fname); - SERIAL_PROTOCOLRPGM(_n(" Size: "));////MSG_SD_SIZE - SERIAL_PROTOCOLLN(filesize); - sdpos = 0; - - SERIAL_PROTOCOLLNRPGM(_N("File selected"));////MSG_SD_FILE_SELECTED - getfilename(0, fname); - lcd_setstatus(longFilename[0] ? longFilename : fname); - lcd_setstatuspgm(PSTR("SD-PRINTING")); + if((int)file_subcall_ctr>(int)SD_PROCEDURE_DEPTH-1){ + // SERIAL_ERROR_START; + // SERIAL_ERRORPGM("trying to call sub-gcode files with too many levels. MAX level is:"); + // SERIAL_ERRORLN(SD_PROCEDURE_DEPTH); + kill(ofKill, 1); + return; + } + + SERIAL_ECHO_START; + SERIAL_ECHORPGM(ofSubroutineCallTgt); + SERIAL_ECHO(name); + SERIAL_ECHORPGM(ofParent); + + //store current filename and position + getAbsFilename(filenames[file_subcall_ctr]); + + SERIAL_ECHO(filenames[file_subcall_ctr]); + SERIAL_ECHORPGM(ofPos); + SERIAL_ECHOLN(sdpos); + filespos[file_subcall_ctr]=sdpos; + file_subcall_ctr++; + file.close(); + } else { //opening fresh file + file_subcall_ctr=0; //resetting procedure depth in case user cancels print while in procedure + SERIAL_ECHO_START; + SERIAL_ECHORPGM(ofNowFreshFile); + SERIAL_ECHOLN(name); } - else - { - SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL); - SERIAL_PROTOCOL(fname); - SERIAL_PROTOCOLLN('.'); + sdprinting = false; + + SdFile myDir; + const char *fname=name; + diveSubfolder(fname,myDir); + + //write + if (!file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)){ + SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL); + SERIAL_PROTOCOL(fname); + SERIAL_PROTOCOLLN('.'); + } else { + saving = true; + SERIAL_PROTOCOLRPGM(ofWritingToFile);////MSG_SD_WRITE_TO_FILE + SERIAL_PROTOCOLLN(name); + lcd_setstatus(fname); } - } - else - { //write - if (!file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) - { - SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL); - SERIAL_PROTOCOL(fname); - SERIAL_PROTOCOLLN('.'); - } - else - { - saving = true; - SERIAL_PROTOCOLRPGM(_N("Writing to file: "));////MSG_SD_WRITE_TO_FILE - SERIAL_PROTOCOLLN(name); - lcd_setstatus(fname); - } - } - } void CardReader::removeFile(const char* name) @@ -1069,7 +1041,7 @@ void CardReader::printingHasFinished() { file.close(); file_subcall_ctr--; - openFile(filenames[file_subcall_ctr],true,true); + openFileReadFilteredGcode(filenames[file_subcall_ctr],true); setIndex(filespos[file_subcall_ctr]); startFileprint(); } diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 8dfb68c98..241d5e8b8 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -21,8 +21,8 @@ public: //this is to delay autostart and hence the initialisaiton of the sd card to some seconds after the normal init, so the device is available quick after a reset void checkautostart(bool x); - void openFile(const char* name,bool read,bool replace_current=true); - void openFileFilteredGcode(const char* name, bool replace_current = false); + void openFileWrite(const char* name); + void openFileReadFilteredGcode(const char* name, bool replace_current = false); void openLogFile(const char* name); void removeFile(const char* name); void closefile(bool store_location=false); diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 78dddf2be..61f022c40 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -8474,7 +8474,7 @@ static void lcd_selftest_screen_step(int _row, int _col, int _state, const char static bool check_file(const char* filename) { if (farm_mode) return true; - card.openFileFilteredGcode((char*)filename, true); + card.openFileReadFilteredGcode(filename, true); bool result = false; const uint32_t filesize = card.getFileSize(); uint32_t startPos = 0; From 71d825d0f2957578e27bae701e34064b2ac749ba Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Thu, 28 Jan 2021 09:41:30 +0100 Subject: [PATCH 12/44] Return SdBaseFile into previous state no changes necessary afterall --- Firmware/SdBaseFile.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Firmware/SdBaseFile.cpp b/Firmware/SdBaseFile.cpp index 4b19ceae6..e3b1c18c8 100644 --- a/Firmware/SdBaseFile.cpp +++ b/Firmware/SdBaseFile.cpp @@ -533,7 +533,6 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) { bool SdBaseFile::open(const char* path, uint8_t oflag) { return open(cwd_, path, oflag); } - //------------------------------------------------------------------------------ /** Open a file or directory by name. * @@ -1031,7 +1030,6 @@ int16_t SdBaseFile::read() { uint8_t b; return read(&b, 1) == 1 ? b : -1; } - //------------------------------------------------------------------------------ /** Read data from a file starting at the current position. * From 6c9c1423c6ba173461bc42ab2acc1f594f140124 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Thu, 28 Jan 2021 09:42:50 +0100 Subject: [PATCH 13/44] Remove temporary changes from SdBaseFile.h --- Firmware/SdBaseFile.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/Firmware/SdBaseFile.h b/Firmware/SdBaseFile.h index ac39338da..a6bd311fe 100644 --- a/Firmware/SdBaseFile.h +++ b/Firmware/SdBaseFile.h @@ -174,8 +174,6 @@ static inline uint8_t FAT_SECOND(uint16_t fatTime) { uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1; /** Default time for file timestamp is 1 am */ uint16_t const FAT_DEFAULT_TIME = (1 << 11); - - //------------------------------------------------------------------------------ /** * \class SdBaseFile From caf58b16b6c78986cd1510e2730960e5d18fa924 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Fri, 29 Jan 2021 08:29:51 +0100 Subject: [PATCH 14/44] Fix handling EOF + save ~160B by using local variables + rename some of the vars to more descriptive names + remove consecutiveEmptyLines handling from cmdqueue --- Firmware/SdFile.cpp | 102 +++++++++++++++++++++++++++--------------- Firmware/SdFile.h | 12 ++++- Firmware/cmdqueue.cpp | 6 +-- 3 files changed, 78 insertions(+), 42 deletions(-) diff --git a/Firmware/SdFile.cpp b/Firmware/SdFile.cpp index 9d898fbcf..19e0fad50 100644 --- a/Firmware/SdFile.cpp +++ b/Firmware/SdFile.cpp @@ -54,11 +54,13 @@ bool SdFile::seekSetFilteredGcode(uint32_t pos){ return true; } -//size=50B +const uint8_t *SdFile::gfBlockBuffBegin() const { + return vol_->cache()->data; // this is constant for the whole time, so it should be fast and sleek +} + void SdFile::gfReset(){ - gfCachePBegin = vol_->cache()->data; // reset cache read ptr to its begin - gfCacheP = gfCachePBegin + gfOffset; + gfReadPtr = gfBlockBuffBegin() + gfOffset; } //FORCE_INLINE const uint8_t * find_endl(const uint8_t *p){ @@ -86,28 +88,43 @@ __asm__ __volatile__ ( \ //size=400B // avoid calling the default heavy-weight read() for just one byte int16_t SdFile::readFilteredGcode(){ - gfEnsureBlock(); // this is unfortunate :( ... other calls are using the cache and we can loose the data block of our gcode file - + if( ! gfEnsureBlock() ){ + goto eof_or_fail; // this is unfortunate :( ... other calls are using the cache and we can loose the data block of our gcode file + } // assume, we have the 512B block cache filled and terminated with a '\n' // SERIAL_PROTOCOLPGM("Read:"); // SERIAL_PROTOCOL(curPosition_); // SERIAL_PROTOCOL(':'); // for(uint8_t i = 0; i < 16; ++i){ -// SERIAL_PROTOCOL( gfCacheP[i] ); +// SERIAL_PROTOCOL( gfReadPtr[i] ); // } // SERIAL_PROTOCOLLN(); +// SERIAL_PROTOCOLLN(curPosition_); + { + const uint8_t *start = gfReadPtr; + + // It may seem unreasonable to copy the variable into a local one and copy it back at the end of this method, + // but there is an important point of view: the compiler is unsure whether it can optimize the reads/writes + // to gfReadPtr within this method, because it is a class member variable. + // The compiler cannot see, if omitting read/write won't have any incorrect side-effects to the rest of the whole FW. + // So this trick explicitly states, that rdPtr is a local variable limited to the scope of this method, + // therefore the compiler can omit read/write to it (keep it in registers!) as it sees fit. + // And it does! Codesize dropped by 68B! + const uint8_t *rdPtr = gfReadPtr; + + // the same applies to gfXBegin, codesize dropped another 100B! + const uint8_t *blockBuffBegin = gfBlockBuffBegin(); - const uint8_t *start = gfCacheP; uint8_t consecutiveCommentLines = 0; - while( *gfCacheP == ';' ){ + while( *rdPtr == ';' ){ for(;;){ - //while( *(++gfCacheP) != '\n' ); // skip until a newline is found - suboptimal code! + //while( *(++gfReadPtr) != '\n' ); // skip until a newline is found - suboptimal code! // Wondering, why this "nice while cycle" is done in such a weird way using a separate find_endl() function? // Have a look at the ASM code GCC produced! // At first - a separate find_endl() makes the compiler understand, - // that I don't need to store gfCacheP every time, I'm only interested in the final address where the '\n' was found + // that I don't need to store gfReadPtr every time, I'm only interested in the final address where the '\n' was found // - the cycle can run on CPU registers only without touching memory besides reading the character being compared. // Not only makes the code run considerably faster, but is also 40B shorter! // This was the generated code: @@ -124,52 +141,67 @@ int16_t SdFile::readFilteredGcode(){ // Still, even that was suboptimal as the compiler seems not to understand the usage of ld r22, Z+ (the plus is important) // aka automatic increment of the Z register (R30:R31 pair) // There is no other way than pure ASM! - find_endl(gfCacheP, gfCacheP); + find_endl(rdPtr, rdPtr); // found a newline, prepare the next block if block cache end reached - if( gfCacheP - gfCachePBegin > 512 ){ + if( rdPtr - blockBuffBegin > 512 ){ // at the end of block cache, fill new data in - gfUpdateCurrentPosition( gfCacheP - start - 1 ); - if( ! gfComputeNextFileBlock() )goto fail; - gfEnsureBlock(); // fetch it into RAM - gfCacheP = start = gfCachePBegin; + gfUpdateCurrentPosition( rdPtr - start - 1 ); + if( ! gfComputeNextFileBlock() )goto eof_or_fail; + if( ! gfEnsureBlock() )goto eof_or_fail; // fetch it into RAM + rdPtr = start = blockBuffBegin; } else { if(++consecutiveCommentLines == 255){ // SERIAL_PROTOCOLLN(sd->curPosition_); - --gfCacheP; // unget the already consumed newline - goto forceExit; + --rdPtr; // unget the already consumed newline + goto emit_char; } // peek the next byte - we are inside the block at least at 511th index - still safe - if( *gfCacheP == ';' ){ + if( *rdPtr == ';' ){ // consecutive comment ++consecutiveCommentLines; } else { - --gfCacheP; // unget the already consumed newline - goto forceExit; + --rdPtr; // unget the already consumed newline + goto emit_char; } break; // found the real end of the line even across many blocks } } } -forceExit: +emit_char: { - gfUpdateCurrentPosition( gfCacheP - start + 1 ); - int16_t rv = *gfCacheP++; + gfUpdateCurrentPosition( rdPtr - start + 1 ); + int16_t rv = *rdPtr++; - // prepare next block if needed - if( gfCacheP - gfCachePBegin >= 512 ){ -// speed checking - now at roughly 170KB/s which is much closer to raw read speed of SD card blocks at ~250KB/s -// SERIAL_PROTOCOL(millis2()); -// SERIAL_PROTOCOL(':'); -// SERIAL_PROTOCOLLN(curPosition_); - if( ! gfComputeNextFileBlock() )goto fail; + if( curPosition_ >= fileSize_ ){ + // past the end of file + goto eof_or_fail; + } else if( rdPtr - blockBuffBegin >= 512 ){ + // past the end of current bufferred block - prepare the next one... + if( ! gfComputeNextFileBlock() )goto eof_or_fail; // don't need to force fetch the block here, it will get loaded on the next call - gfCacheP = gfCachePBegin; - } + rdPtr = blockBuffBegin; + } + +// SERIAL_PROTOCOLPGM("c="); +// SERIAL_ECHO((char)rv); +// SERIAL_ECHO('|'); +// SERIAL_ECHO((int)rv); +// SERIAL_PROTOCOL('|'); +// SERIAL_PROTOCOLLN(curPosition_); + + // save the current read ptr for the next run + gfReadPtr = rdPtr; return rv; } -fail: -// SERIAL_PROTOCOLLNPGM("CacheFAIL"); + +} + +eof_or_fail: +// SERIAL_PROTOCOLPGM("CacheFAIL:"); + + // make the rdptr point to a safe location - end of file + gfReadPtr = gfBlockBuffBegin() + 512; return -1; } diff --git a/Firmware/SdFile.h b/Firmware/SdFile.h index a801a2282..30a4da5d3 100644 --- a/Firmware/SdFile.h +++ b/Firmware/SdFile.h @@ -35,11 +35,19 @@ */ class SdFile : public SdBaseFile/*, public Print*/ { // GCode filtering vars and methods - due to optimization reasons not wrapped in a separate class - const uint8_t *gfCachePBegin; - const uint8_t *gfCacheP; + + // beware - this read ptr is manipulated inside just 2 methods - readFilteredGcode and gfReset + // If you even want to call gfReset from readFilteredGcode, you must make sure + // to update gfCacheP inside readFilteredGcode from a local copy (see explanation of this trick in readFilteredGcode) + const uint8_t *gfReadPtr; + uint32_t gfBlock; // remember the current file block to be kept in cache - due to reuse of the memory, the block may fall out a must be read back uint16_t gfOffset; + + const uint8_t *gfBlockBuffBegin()const; + void gfReset(); + bool gfEnsureBlock(); bool gfComputeNextFileBlock(); void gfUpdateCurrentPosition(uint16_t inc); diff --git a/Firmware/cmdqueue.cpp b/Firmware/cmdqueue.cpp index c89032750..d7a760c77 100755 --- a/Firmware/cmdqueue.cpp +++ b/Firmware/cmdqueue.cpp @@ -573,7 +573,6 @@ void get_command() // this character _can_ occur in serial com, due to checksums. however, no checksums are used in SD printing static bool stop_buffering=false; -// static uint8_t consecutiveEmptyLines = 0; if(buflen==0) stop_buffering=false; union { struct { @@ -604,10 +603,7 @@ void get_command() // so that the lenght of the already read empty lines and comments will be added // to the following non-empty line. // comment_mode = false; -// if( ++consecutiveEmptyLines > 10 ){ -// consecutiveEmptyLines = 0; - return; // prevent cycling indefinitely - let manage_heaters do their job -// } + return; // prevent cycling indefinitely - let manage_heaters do their job // continue; //if empty line } // The new command buffer could be updated non-atomically, because it is not yet considered From 15d76a75018e4af0af04d5060d29c5e5fb79c28a Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Tue, 2 Feb 2021 07:57:06 +0100 Subject: [PATCH 15/44] Remove duplicit incrementation of consecutive comment lines It was left in the code in one of the refactoring/optimization passes. It really didn't do any harm, but was limiting the performance of the skipping algorithm. + some verification code added - will be removed after successful tests --- Firmware/SdFile.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Firmware/SdFile.cpp b/Firmware/SdFile.cpp index 19e0fad50..ee91bdfc9 100644 --- a/Firmware/SdFile.cpp +++ b/Firmware/SdFile.cpp @@ -151,7 +151,9 @@ int16_t SdFile::readFilteredGcode(){ if( ! gfEnsureBlock() )goto eof_or_fail; // fetch it into RAM rdPtr = start = blockBuffBegin; } else { - if(++consecutiveCommentLines == 255){ + if(consecutiveCommentLines >= 250){ +// SERIAL_ECHO("ccl="); +// SERIAL_ECHOLN((int)consecutiveCommentLines); // SERIAL_PROTOCOLLN(sd->curPosition_); --rdPtr; // unget the already consumed newline goto emit_char; From f343e6432ac33c7417d35d3f2faadcb9f94ae515 Mon Sep 17 00:00:00 2001 From: Voinea Dragos Date: Sun, 31 Jan 2021 16:42:01 +0200 Subject: [PATCH 16/44] Fix diveSubfolder string termination --- Firmware/cardreader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index a96268972..4b55e8161 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -340,9 +340,9 @@ void CardReader::diveSubfolder (const char *fileName, SdFile& dir) { const size_t maxLen = 12; char subdirname[maxLen+1]; - subdirname[maxLen] = 0; const size_t len = ((static_cast(dirname_end-dirname_start))>maxLen) ? maxLen : (dirname_end-dirname_start); strncpy(subdirname, dirname_start, len); + subdirname[len] = 0; SERIAL_ECHOLN(subdirname); if (!dir.open(curDir, subdirname, O_READ)) { From 52f7a71dce177cf7dc484988a6701f08e689d9e2 Mon Sep 17 00:00:00 2001 From: Voinea Dragos Date: Sat, 6 Feb 2021 14:59:11 +0200 Subject: [PATCH 17/44] More fixes that were extracted from #2405 --- Firmware/Marlin.h | 4 -- Firmware/Marlin_main.cpp | 8 +--- Firmware/cardreader.cpp | 81 +++++++++++++++++++++------------------- Firmware/cardreader.h | 10 +++-- Firmware/messages.c | 1 + Firmware/messages.h | 1 + Firmware/ultralcd.cpp | 12 ++---- 7 files changed, 57 insertions(+), 60 deletions(-) diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 1ed5e0bd3..cbe03c0f6 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -350,10 +350,6 @@ extern unsigned long t_fan_rising_edge; extern bool mesh_bed_leveling_flag; extern bool mesh_bed_run_from_menu; -extern bool sortAlpha; - -extern char dir_names[][9]; - extern int8_t lcd_change_fil_state; // save/restore printing extern bool saved_printing; diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 6db1d2770..e5daeee07 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -228,10 +228,6 @@ bool fan_state[2]; int fan_edge_counter[2]; int fan_speed[2]; -char dir_names[MAX_DIR_DEPTH][9]; - -bool sortAlpha = false; - float extruder_multiplier[EXTRUDERS] = {1.0 #if EXTRUDERS > 1 @@ -11281,8 +11277,8 @@ void restore_print_from_eeprom(bool mbl_was_active) { } dir_name[8] = '\0'; MYSERIAL.println(dir_name); - strcpy(dir_names[i], dir_name); - card.chdir(dir_name); + // strcpy(dir_names[i], dir_name); + card.chdir(dir_name, false); } for (int i = 0; i < 8; i++) { diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 4b55e8161..418dbb940 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -32,6 +32,7 @@ CardReader::CardReader() workDirDepth = 0; file_subcall_ctr=0; memset(workDirParents, 0, sizeof(workDirParents)); + presort_flag = false; autostart_stilltocheck=true; //the SD start is delayed, because otherwise the serial cannot answer fast enough to make contact with the host software. lastnr=0; @@ -69,12 +70,15 @@ char *createFilename(char *buffer,const dir_t &p) //buffer>12characters +*/ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/) { + static uint8_t recursionCnt = 0; dir_t p; uint8_t cnt = 0; // Read the next entry from a directory while (parent.readDir(p, longFilename) > 0) { - // If the entry is a directory and the action is LS_SerialPrint - if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { + if (recursionCnt >= MAX_DIR_DEPTH) + return; + else if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { // If the entry is a directory and the action is LS_SerialPrint + recursionCnt++; // Get the short name for the item, which we know is a folder char lfilename[FILENAME_LENGTH]; createFilename(lfilename, p); @@ -108,6 +112,7 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m if (lsAction == LS_SerialPrint_LFN) puts_P(PSTR("DIR_EXIT")); + recursionCnt--; } else { uint8_t pn0 = p.name[0]; @@ -241,18 +246,18 @@ void CardReader::initsd() } -void CardReader::setroot() +void CardReader::setroot(bool doPresort) { - /*if(!workDir.openRoot(&volume)) - { - SERIAL_ECHOLNPGM(MSG_SD_WORKDIR_FAIL); - }*/ workDir=root; + workDirDepth = 0; curDir=&workDir; - #ifdef SDCARD_SORT_ALPHA - presort(); - #endif +#ifdef SDCARD_SORT_ALPHA + if (doPresort) + presort(); + else + presort_flag = true; +#endif } void CardReader::release() { @@ -317,19 +322,17 @@ void CardReader::getAbsFilename(char *t) * @param[in,out] fileName * expects file name including path * in case of absolute path, file name without path is returned - * @param[in,out] dir SdFile object to operate with, - * in case of absolute path, curDir is modified to point to dir, - * so it is not possible to create on stack inside this function, - * as curDir would point to destroyed object. */ -void CardReader::diveSubfolder (const char *fileName, SdFile& dir) +bool CardReader::diveSubfolder (const char *&fileName) { curDir=&root; - if (!fileName) return; + if (!fileName) + return 1; const char *dirname_start, *dirname_end; if (fileName[0] == '/') // absolute path { + setroot(false); dirname_start = fileName + 1; while (*dirname_start) { @@ -344,19 +347,10 @@ void CardReader::diveSubfolder (const char *fileName, SdFile& dir) strncpy(subdirname, dirname_start, len); subdirname[len] = 0; SERIAL_ECHOLN(subdirname); - if (!dir.open(curDir, subdirname, O_READ)) - { - SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL); - SERIAL_PROTOCOL(subdirname); - SERIAL_PROTOCOLLN('.'); - return; - } - else - { - //SERIAL_ECHOLN("dive ok"); - } + if (!chdir(subdirname, false)) + return 0; - curDir = &dir; + curDir = &workDir; dirname_start = dirname_end + 1; } else // the reminder after all /fsa/fdsa/ is the filename @@ -373,6 +367,7 @@ void CardReader::diveSubfolder (const char *fileName, SdFile& dir) { curDir = &workDir; } + return 1; } void CardReader::openFile(const char* name,bool read, bool replace_current/*=true*/) @@ -423,9 +418,9 @@ void CardReader::openFile(const char* name,bool read, bool replace_current/*=tru } sdprinting = false; - SdFile myDir; const char *fname=name; - diveSubfolder(fname,myDir); + if (!diveSubfolder(fname)) + return; if(read) { @@ -438,10 +433,9 @@ void CardReader::openFile(const char* name,bool read, bool replace_current/*=tru SERIAL_PROTOCOLLN(filesize); sdpos = 0; - SERIAL_PROTOCOLLNRPGM(_N("File selected"));////MSG_SD_FILE_SELECTED + SERIAL_PROTOCOLLNRPGM(MSG_FILE_SELECTED); + lcd_setstatuspgm(MSG_FILE_SELECTED); getfilename(0, fname); - lcd_setstatus(longFilename[0] ? longFilename : fname); - lcd_setstatuspgm(PSTR("SD-PRINTING")); } else { @@ -475,9 +469,9 @@ void CardReader::removeFile(const char* name) file.close(); sdprinting = false; - SdFile myDir; const char *fname=name; - diveSubfolder(fname,myDir); + if (!diveSubfolder(fname)) + return; if (file.remove(curDir, fname)) { @@ -670,7 +664,7 @@ uint16_t CardReader::getnrfilenames() return nrFiles; } -void CardReader::chdir(const char * relpath) +bool CardReader::chdir(const char * relpath, bool doPresort) { SdFile newfile; SdFile *parent=&root; @@ -678,23 +672,32 @@ void CardReader::chdir(const char * relpath) if(workDir.isOpen()) parent=&workDir; - if(!newfile.open(*parent,relpath, O_READ)) + if(!newfile.open(*parent,relpath, O_READ) || ((workDirDepth + 1) >= MAX_DIR_DEPTH)) { SERIAL_ECHO_START; SERIAL_ECHORPGM(_n("Cannot enter subdir: "));////MSG_SD_CANT_ENTER_SUBDIR SERIAL_ECHOLN(relpath); + return 0; } else { + strcpy(dir_names[workDirDepth], relpath); + puts(relpath); + if (workDirDepth < MAX_DIR_DEPTH) { for (int d = ++workDirDepth; d--;) workDirParents[d+1] = workDirParents[d]; workDirParents[0]=*parent; } workDir=newfile; - #ifdef SDCARD_SORT_ALPHA + +#ifdef SDCARD_SORT_ALPHA + if (doPresort) presort(); - #endif + else + presort_flag = true; +#endif + return 1; } } diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 9bf9bd0a6..819e8bf27 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -39,9 +39,9 @@ public: void ls(bool printLFN); - void chdir(const char * relpath); + bool chdir(const char * relpath, bool doPresort); void updir(); - void setroot(); + void setroot(bool doPresort); #ifdef SDCARD_SORT_ALPHA void presort(); @@ -82,6 +82,10 @@ public: char longFilename[LONG_FILENAME_LENGTH]; bool filenameIsDir; int lastnr; //last number of the autostart; +#ifdef SDCARD_SORT_ALPHA + bool presort_flag; + char dir_names[MAX_DIR_DEPTH][9]; +#endif // SDCARD_SORT_ALPHA private: SdFile root,*curDir,workDir,workDirParents[MAX_DIR_DEPTH]; uint16_t workDirDepth; @@ -155,7 +159,7 @@ private: int16_t nrFiles; //counter for the files in the current directory and recycled as position counter for getting the nrFiles'th name in the directory. char* diveDirName; - void diveSubfolder (const char *fileName, SdFile& dir); + bool diveSubfolder (const char *&fileName); void lsDive(const char *prepend, SdFile parent, const char * const match=NULL); #ifdef SDCARD_SORT_ALPHA void flush_presort(); diff --git a/Firmware/messages.c b/Firmware/messages.c index 0b1d58e04..39f0cf336 100644 --- a/Firmware/messages.c +++ b/Firmware/messages.c @@ -197,3 +197,4 @@ const char MSG_M112_KILL[] PROGMEM_N1 = "M112 called. Emergency Stop."; ////c=20 const char MSG_ADVANCE_K[] PROGMEM_N1 = "Advance K:"; ////c=13 const char MSG_POWERPANIC_DETECTED[] PROGMEM_N1 = "POWER PANIC DETECTED"; ////c=20 const char MSG_LCD_STATUS_CHANGED[] PROGMEM_N1 = "LCD status changed"; +const char MSG_FILE_SELECTED[] PROGMEM_N1 = "File selected"; ////c=20 diff --git a/Firmware/messages.h b/Firmware/messages.h index 0a05c58f5..a5b672fa2 100644 --- a/Firmware/messages.h +++ b/Firmware/messages.h @@ -197,6 +197,7 @@ extern const char MSG_M112_KILL[]; extern const char MSG_ADVANCE_K[]; extern const char MSG_POWERPANIC_DETECTED[]; extern const char MSG_LCD_STATUS_CHANGED[]; +extern const char MSG_FILE_SELECTED[]; #if defined(__cplusplus) } diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 0f6bc1fa3..2d92596f0 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -4317,7 +4317,7 @@ static void lcd_sort_type_set() { default: sdSort = SD_SORT_TIME; } eeprom_update_byte((unsigned char *)EEPROM_SD_SORT, sdSort); - presort_flag = true; + card.presort_flag = true; } #endif //SDCARD_SORT_ALPHA @@ -8548,7 +8548,7 @@ static void menu_action_sdfile(const char* filename) 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, dir_names[i][j]); + eeprom_write_byte((uint8_t*)EEPROM_DIRS + j + 8 * i, card.dir_names[i][j]); } } @@ -8566,12 +8566,8 @@ static void menu_action_sdfile(const char* filename) void menu_action_sddirectory(const char* filename) { - uint8_t depth = (uint8_t)card.getWorkDirDepth(); - - strcpy(dir_names[depth], filename); - MYSERIAL.println(dir_names[depth]); - card.chdir(filename); - lcd_encoder = 0; + card.chdir(filename, true); + lcd_encoder = 0; } /** LCD API **/ From 77a5082b5664c7ccfe05ed08af16c89ad7c7b448 Mon Sep 17 00:00:00 2001 From: Voinea Dragos Date: Sat, 6 Feb 2021 17:25:17 +0200 Subject: [PATCH 18/44] Fix presort_flag duplicate declaration --- Firmware/ultralcd.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 2d92596f0..a736f8c2b 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -75,11 +75,6 @@ int8_t FSensorStateMenu = 1; bool bMenuFSDetect=false; #endif //IR_SENSOR_ANALOG - -#ifdef SDCARD_SORT_ALPHA -bool presort_flag = false; -#endif - LcdCommands lcd_commands_type = LcdCommands::Idle; static uint8_t lcd_commands_step = 0; @@ -7183,8 +7178,8 @@ void lcd_sdcard_menu() { uint8_t sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT); - if (presort_flag == true) { - presort_flag = false; + if (card.presort_flag == true) { + card.presort_flag = false; card.presort(); } if (lcd_draw_update == 0 && LCD_CLICKED == 0) From f5cde38a7c000eeacfc7dc08f46e820359ee8777 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Sat, 6 Feb 2021 21:06:37 +0200 Subject: [PATCH 19/44] Remove duplicit debug line --- Firmware/cardreader.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 418dbb940..8273e3d04 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -346,7 +346,6 @@ bool CardReader::diveSubfolder (const char *&fileName) const size_t len = ((static_cast(dirname_end-dirname_start))>maxLen) ? maxLen : (dirname_end-dirname_start); strncpy(subdirname, dirname_start, len); subdirname[len] = 0; - SERIAL_ECHOLN(subdirname); if (!chdir(subdirname, false)) return 0; From c739aa900303fddd86c62bc951f26ef18178a0a8 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Sun, 7 Feb 2021 21:51:44 +0200 Subject: [PATCH 20/44] M23 full path support. --- Firmware/cardreader.cpp | 22 ++++++++++++++++------ Firmware/cardreader.h | 1 + 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 8273e3d04..c414e2823 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -309,6 +309,18 @@ void CardReader::getAbsFilename(char *t) else t[0]=0; } + +void CardReader::printAbsFilenameFast() +{ + SERIAL_PROTOCOL('/'); + for (uint8_t i = 0; i < getWorkDirDepth(); i++) + { + SERIAL_PROTOCOL(dir_names[i]); + SERIAL_PROTOCOL('/'); + } + SERIAL_PROTOCOL(LONGEST_FILENAME); +} + /** * @brief Dive into subfolder * @@ -425,16 +437,16 @@ void CardReader::openFile(const char* name,bool read, bool replace_current/*=tru { if (file.open(curDir, fname, O_READ)) { + getfilename(0, fname); filesize = file.fileSize(); SERIAL_PROTOCOLRPGM(_N("File opened: "));////MSG_SD_FILE_OPENED - SERIAL_PROTOCOL(fname); + printAbsFilenameFast(); SERIAL_PROTOCOLRPGM(_n(" Size: "));////MSG_SD_SIZE SERIAL_PROTOCOLLN(filesize); sdpos = 0; SERIAL_PROTOCOLLNRPGM(MSG_FILE_SELECTED); lcd_setstatuspgm(MSG_FILE_SELECTED); - getfilename(0, fname); } else { @@ -508,10 +520,8 @@ void CardReader::getStatus(bool arg_P) { if (arg_P) { - SERIAL_PROTOCOL('/'); - for (uint8_t i = 0; i < getWorkDirDepth(); i++) - printf_P(PSTR("%s/"), dir_names[i]); - puts(filename); + printAbsFilenameFast(); + SERIAL_PROTOCOLLN(); } else SERIAL_PROTOCOLLN(LONGEST_FILENAME); diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 819e8bf27..0e94bd3c9 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -34,6 +34,7 @@ public: uint16_t getnrfilenames(); void getAbsFilename(char *t); + void printAbsFilenameFast(); void getDirName(char* name, uint8_t level); uint16_t getWorkDirDepth(); From fb39e7296b126c67a34937576389429d0ffc9de2 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Mon, 8 Feb 2021 10:58:41 +0100 Subject: [PATCH 21/44] Uniform message `Press the knob` --- Firmware/Marlin_main.cpp | 2 +- lang/lang_en.txt | 2 +- lang/lang_en_cz.txt | 2 +- lang/lang_en_de.txt | 2 +- lang/lang_en_es.txt | 2 +- lang/lang_en_fr.txt | 2 +- lang/lang_en_it.txt | 2 +- lang/lang_en_pl.txt | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 6db1d2770..bc90849eb 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -11786,7 +11786,7 @@ void M600_wait_for_user(float HotendTempBckp) { delay_keep_alive(4); if (_millis() > waiting_start_time + (unsigned long)M600_TIMEOUT * 1000) { - lcd_display_message_fullscreen_P(_i("Press knob to preheat nozzle and continue."));////MSG_PRESS_TO_PREHEAT c=20 r=4 + lcd_display_message_fullscreen_P(_i("Press the knob to preheat nozzle and continue."));////MSG_PRESS_TO_PREHEAT c=20 r=4 wait_for_user_state = 1; setAllTargetHotends(0); st_synchronize(); diff --git a/lang/lang_en.txt b/lang/lang_en.txt index bcb0a4444..41879c5a0 100644 --- a/lang/lang_en.txt +++ b/lang/lang_en.txt @@ -620,7 +620,7 @@ "Please upgrade." #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." #MSG_FS_PAUSE c=5 "Pause" diff --git a/lang/lang_en_cz.txt b/lang/lang_en_cz.txt index 0b3d7b14f..4c7efc5e8 100644 --- a/lang/lang_en_cz.txt +++ b/lang/lang_en_cz.txt @@ -827,7 +827,7 @@ "Prosim aktualizujte." #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." "Pro nahrati trysky a pokracovani stisknete tlacitko." #MSG_FS_PAUSE c=5 diff --git a/lang/lang_en_de.txt b/lang/lang_en_de.txt index 0a436a9ee..f38699318 100644 --- a/lang/lang_en_de.txt +++ b/lang/lang_en_de.txt @@ -827,7 +827,7 @@ "Bitte aktualisieren." #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." "Bitte druecken Sie den Knopf um die Duese vorzuheizen und fortzufahren." #MSG_FS_PAUSE c=5 diff --git a/lang/lang_en_es.txt b/lang/lang_en_es.txt index 2e29fa20a..f8b39e17d 100644 --- a/lang/lang_en_es.txt +++ b/lang/lang_en_es.txt @@ -827,7 +827,7 @@ "Actualize por favor" #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." "Pulsa el dial para precalentar la boquilla y continue." #MSG_FS_PAUSE c=5 diff --git a/lang/lang_en_fr.txt b/lang/lang_en_fr.txt index cc0cbb95b..f64f800df 100644 --- a/lang/lang_en_fr.txt +++ b/lang/lang_en_fr.txt @@ -827,7 +827,7 @@ "Mettez a jour le FW." #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." "Appuyez sur le bouton pour prechauffer la buse et continuer." #MSG_FS_PAUSE c=5 diff --git a/lang/lang_en_it.txt b/lang/lang_en_it.txt index 8cd939082..e33833364 100644 --- a/lang/lang_en_it.txt +++ b/lang/lang_en_it.txt @@ -827,7 +827,7 @@ "Prego aggiornare." #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." "Premete la manopola per preriscaldare l'ugello e continuare." #MSG_FS_PAUSE c=5 diff --git a/lang/lang_en_pl.txt b/lang/lang_en_pl.txt index 38d1421f7..b796c11ac 100644 --- a/lang/lang_en_pl.txt +++ b/lang/lang_en_pl.txt @@ -827,7 +827,7 @@ "Prosze zaktualizowac." #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." "Wcisnij pokretlo aby rozgrzac dysze i kontynuowac." #MSG_FS_PAUSE c=5 From 214695105c181796bc5c958aee9fafb65c53ff3f Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Mon, 8 Feb 2021 11:33:46 +0100 Subject: [PATCH 22/44] Fix issue #2958 --- Firmware/ultralcd.cpp | 8 ++++---- lang/lang_en.txt | 6 +++--- lang/lang_en_cz.txt | 6 +++--- lang/lang_en_de.txt | 6 +++--- lang/lang_en_es.txt | 6 +++--- lang/lang_en_fr.txt | 6 +++--- lang/lang_en_it.txt | 6 +++--- lang/lang_en_pl.txt | 6 +++--- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 0f6bc1fa3..0e654384e 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2235,18 +2235,18 @@ uint8_t nLevel; lcd_set_cursor(0,0); lcdui_print_temp(LCD_STR_THERMOMETER[0],(int)degHotend(0),(int)degTargetHotend(0)); -lcd_puts_at_P(0,2, _i("Press the knob")); ////MSG_ c=20 r=1 -lcd_set_cursor(0,3); +lcd_puts_at_P(0,1, _i("Press the knob")); ////MSG_ c=20 +lcd_set_cursor(0,2); switch(eFilamentAction) { case FilamentAction::Load: case FilamentAction::AutoLoad: case FilamentAction::MmuLoad: - lcd_puts_P(_i("to load filament")); ////MSG_ c=20 r=1 + lcd_puts_P(_i("to load filament")); ////MSG_ c=20 r=2 break; case FilamentAction::UnLoad: case FilamentAction::MmuUnLoad: - lcd_puts_P(_i("to unload filament")); ////MSG_ c=20 r=1 + lcd_puts_P(_i("to unload filament")); ////MSG_ c=20 r=2 break; case FilamentAction::MmuEject: case FilamentAction::MmuCut: diff --git a/lang/lang_en.txt b/lang/lang_en.txt index 41879c5a0..875aa370e 100644 --- a/lang/lang_en.txt +++ b/lang/lang_en.txt @@ -644,7 +644,7 @@ "Print from SD" # -"Press the knob" +"Press the knob" c=20 r=2 #MSG_PRINT_PAUSED c=20 r=1 "Print paused" @@ -875,10 +875,10 @@ "Total failures" # -"to load filament" +"to load filament" c=20 r=2 # -"to unload filament" +"to unload filament" c=20 r=2 #MSG_UNLOAD_FILAMENT c=17 "Unload filament" diff --git a/lang/lang_en_cz.txt b/lang/lang_en_cz.txt index 4c7efc5e8..3c8f0f06a 100644 --- a/lang/lang_en_cz.txt +++ b/lang/lang_en_cz.txt @@ -859,7 +859,7 @@ "Tisk z SD" # -"Press the knob" +"Press the knob" c=20 r=2 "Stisknete hl. tlacitko" #MSG_PRINT_PAUSED c=20 r=1 @@ -1167,11 +1167,11 @@ "Celkem selhani" # -"to load filament" +"to load filament" c=20 r=2 "k zavedeni filamentu" # -"to unload filament" +"to unload filament" c=20 r=2 "k vyjmuti filamentu" #MSG_UNLOAD_FILAMENT c=17 diff --git a/lang/lang_en_de.txt b/lang/lang_en_de.txt index f38699318..649994d93 100644 --- a/lang/lang_en_de.txt +++ b/lang/lang_en_de.txt @@ -859,7 +859,7 @@ "Drucken von SD" # -"Press the knob" +"Press the knob" c=20 r=2 "Knopf druecken zum" #MSG_PRINT_PAUSED c=20 r=1 @@ -1167,11 +1167,11 @@ "Gesamte Fehler" # -"to load filament" +"to load filament" c=20 r=2 "Filament laden" # -"to unload filament" +"to unload filament" c=20 r=2 "Filament entladen" #MSG_UNLOAD_FILAMENT c=17 diff --git a/lang/lang_en_es.txt b/lang/lang_en_es.txt index f8b39e17d..359130207 100644 --- a/lang/lang_en_es.txt +++ b/lang/lang_en_es.txt @@ -859,7 +859,7 @@ "Menu tarjeta SD" # -"Press the knob" +"Press the knob" c=20 r=2 "Pulsa el dial" #MSG_PRINT_PAUSED c=20 r=1 @@ -1167,11 +1167,11 @@ "Fallos totales" # -"to load filament" +"to load filament" c=20 r=2 "para cargar el filamento" # -"to unload filament" +"to unload filament" c=20 r=2 "para descargar el filamento" #MSG_UNLOAD_FILAMENT c=17 diff --git a/lang/lang_en_fr.txt b/lang/lang_en_fr.txt index f64f800df..54dc7a7cc 100644 --- a/lang/lang_en_fr.txt +++ b/lang/lang_en_fr.txt @@ -859,7 +859,7 @@ "Impr. depuis la SD" # -"Press the knob" +"Press the knob" c=20 r=2 "App. sur sur bouton" #MSG_PRINT_PAUSED c=20 r=1 @@ -1167,11 +1167,11 @@ "Total des echecs" # -"to load filament" +"to load filament" c=20 r=2 "pour charger le fil." # -"to unload filament" +"to unload filament" c=20 r=2 "pour decharger fil." #MSG_UNLOAD_FILAMENT c=17 diff --git a/lang/lang_en_it.txt b/lang/lang_en_it.txt index e33833364..d5846cba7 100644 --- a/lang/lang_en_it.txt +++ b/lang/lang_en_it.txt @@ -859,7 +859,7 @@ "Stampa da SD" # -"Press the knob" +"Press the knob" c=20 r=2 "Premere la manopola" #MSG_PRINT_PAUSED c=20 r=1 @@ -1167,11 +1167,11 @@ "Totale fallimenti" # -"to load filament" +"to load filament" c=20 r=2 "per caricare il filamento" # -"to unload filament" +"to unload filament" c=20 r=2 "per scaricare il filamento" #MSG_UNLOAD_FILAMENT c=17 diff --git a/lang/lang_en_pl.txt b/lang/lang_en_pl.txt index b796c11ac..eb4103eee 100644 --- a/lang/lang_en_pl.txt +++ b/lang/lang_en_pl.txt @@ -859,7 +859,7 @@ "Druk z karty SD" # -"Press the knob" +"Press the knob" c=20 r=2 "Wcisnij pokretlo" #MSG_PRINT_PAUSED c=20 r=1 @@ -1167,11 +1167,11 @@ "Suma bledow" # -"to load filament" +"to load filament" c=20 r=2 "aby zaladow. fil." # -"to unload filament" +"to unload filament" c=20 r=2 "aby rozlad. filament" #MSG_UNLOAD_FILAMENT c=17 From aecbd7ab49ec5fb0f7ca84b6bd40fd3f6823145f Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Mon, 8 Feb 2021 12:17:41 +0100 Subject: [PATCH 23/44] Fix `c=aa` location in lang files Fix too long translations in Spanish and Italian --- Firmware/ultralcd.cpp | 4 ++-- lang/lang_en.txt | 12 ++++++------ lang/lang_en_cz.txt | 12 ++++++------ lang/lang_en_de.txt | 12 ++++++------ lang/lang_en_es.txt | 16 ++++++++-------- lang/lang_en_fr.txt | 12 ++++++------ lang/lang_en_it.txt | 16 ++++++++-------- lang/lang_en_pl.txt | 12 ++++++------ 8 files changed, 48 insertions(+), 48 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 0e654384e..10fa2da38 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2242,11 +2242,11 @@ switch(eFilamentAction) case FilamentAction::Load: case FilamentAction::AutoLoad: case FilamentAction::MmuLoad: - lcd_puts_P(_i("to load filament")); ////MSG_ c=20 r=2 + lcd_puts_P(_i("to load filament")); ////MSG_ c=20 break; case FilamentAction::UnLoad: case FilamentAction::MmuUnLoad: - lcd_puts_P(_i("to unload filament")); ////MSG_ c=20 r=2 + lcd_puts_P(_i("to unload filament")); ////MSG_ c=20 break; case FilamentAction::MmuEject: case FilamentAction::MmuCut: diff --git a/lang/lang_en.txt b/lang/lang_en.txt index 875aa370e..8c0e6eb9d 100644 --- a/lang/lang_en.txt +++ b/lang/lang_en.txt @@ -643,8 +643,8 @@ #MSG_CARD_MENU "Print from SD" -# -"Press the knob" c=20 r=2 +# c=20 +"Press the knob" #MSG_PRINT_PAUSED c=20 r=1 "Print paused" @@ -874,11 +874,11 @@ #MSG_TOTAL_FAILURES c=20 "Total failures" -# -"to load filament" c=20 r=2 +# c=20 +"to load filament" -# -"to unload filament" c=20 r=2 +# c=20 +"to unload filament" #MSG_UNLOAD_FILAMENT c=17 "Unload filament" diff --git a/lang/lang_en_cz.txt b/lang/lang_en_cz.txt index 3c8f0f06a..2c0bc664b 100644 --- a/lang/lang_en_cz.txt +++ b/lang/lang_en_cz.txt @@ -858,8 +858,8 @@ "Print from SD" "Tisk z SD" -# -"Press the knob" c=20 r=2 +# c=20 +"Press the knob" "Stisknete hl. tlacitko" #MSG_PRINT_PAUSED c=20 r=1 @@ -1166,12 +1166,12 @@ "Total failures" "Celkem selhani" -# -"to load filament" c=20 r=2 +# c=20 +"to load filament" "k zavedeni filamentu" -# -"to unload filament" c=20 r=2 +# c=20 +"to unload filament" "k vyjmuti filamentu" #MSG_UNLOAD_FILAMENT c=17 diff --git a/lang/lang_en_de.txt b/lang/lang_en_de.txt index 649994d93..e6fd5bccc 100644 --- a/lang/lang_en_de.txt +++ b/lang/lang_en_de.txt @@ -858,8 +858,8 @@ "Print from SD" "Drucken von SD" -# -"Press the knob" c=20 r=2 +# c=20 +"Press the knob" "Knopf druecken zum" #MSG_PRINT_PAUSED c=20 r=1 @@ -1166,12 +1166,12 @@ "Total failures" "Gesamte Fehler" -# -"to load filament" c=20 r=2 +# c=20 +"to load filament" "Filament laden" -# -"to unload filament" c=20 r=2 +# c=20 +"to unload filament" "Filament entladen" #MSG_UNLOAD_FILAMENT c=17 diff --git a/lang/lang_en_es.txt b/lang/lang_en_es.txt index 359130207..4e622ebb9 100644 --- a/lang/lang_en_es.txt +++ b/lang/lang_en_es.txt @@ -858,8 +858,8 @@ "Print from SD" "Menu tarjeta SD" -# -"Press the knob" c=20 r=2 +# c=20 +"Press the knob" "Pulsa el dial" #MSG_PRINT_PAUSED c=20 r=1 @@ -1166,13 +1166,13 @@ "Total failures" "Fallos totales" -# -"to load filament" c=20 r=2 -"para cargar el filamento" +# c=20 +"to load filament" +"para cargar el fil." -# -"to unload filament" c=20 r=2 -"para descargar el filamento" +# c=20 +"to unload filament" +"para descargar fil." #MSG_UNLOAD_FILAMENT c=17 "Unload filament" diff --git a/lang/lang_en_fr.txt b/lang/lang_en_fr.txt index 54dc7a7cc..edf2bb8b4 100644 --- a/lang/lang_en_fr.txt +++ b/lang/lang_en_fr.txt @@ -858,8 +858,8 @@ "Print from SD" "Impr. depuis la SD" -# -"Press the knob" c=20 r=2 +# c=20 +"Press the knob" "App. sur sur bouton" #MSG_PRINT_PAUSED c=20 r=1 @@ -1166,12 +1166,12 @@ "Total failures" "Total des echecs" -# -"to load filament" c=20 r=2 +# c=20 +"to load filament" "pour charger le fil." -# -"to unload filament" c=20 r=2 +# c=20 +"to unload filament" "pour decharger fil." #MSG_UNLOAD_FILAMENT c=17 diff --git a/lang/lang_en_it.txt b/lang/lang_en_it.txt index d5846cba7..043d1141b 100644 --- a/lang/lang_en_it.txt +++ b/lang/lang_en_it.txt @@ -858,8 +858,8 @@ "Print from SD" "Stampa da SD" -# -"Press the knob" c=20 r=2 +# c=20 +"Press the knob" "Premere la manopola" #MSG_PRINT_PAUSED c=20 r=1 @@ -1166,13 +1166,13 @@ "Total failures" "Totale fallimenti" -# -"to load filament" c=20 r=2 -"per caricare il filamento" +# c=20 +"to load filament" +"per caricare il fil." -# -"to unload filament" c=20 r=2 -"per scaricare il filamento" +# c=20 +"to unload filament" +"per scaricare fil." #MSG_UNLOAD_FILAMENT c=17 "Unload filament" diff --git a/lang/lang_en_pl.txt b/lang/lang_en_pl.txt index eb4103eee..4e6be18e0 100644 --- a/lang/lang_en_pl.txt +++ b/lang/lang_en_pl.txt @@ -858,8 +858,8 @@ "Print from SD" "Druk z karty SD" -# -"Press the knob" c=20 r=2 +# c=20 +"Press the knob" "Wcisnij pokretlo" #MSG_PRINT_PAUSED c=20 r=1 @@ -1166,12 +1166,12 @@ "Total failures" "Suma bledow" -# -"to load filament" c=20 r=2 +# c=20 +"to load filament" "aby zaladow. fil." -# -"to unload filament" c=20 r=2 +# c=20 +"to unload filament" "aby rozlad. filament" #MSG_UNLOAD_FILAMENT c=17 From 5f49d65546a08d633ea452816718983f0a5a6acc Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Mon, 8 Feb 2021 09:49:11 +0100 Subject: [PATCH 24/44] Farmers' request - allow file sorting menu item --- Firmware/ultralcd.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 0f6bc1fa3..d3686509a 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -5291,16 +5291,13 @@ do\ else\ MENU_ITEM_TOGGLE_P(_T(MSG_SD_CARD), _T(MSG_NORMAL), lcd_toshiba_flash_air_compatibility_toggle);\ \ - if (!farm_mode)\ + uint8_t sdSort;\ + EEPROM_read(EEPROM_SD_SORT, (uint8_t*)&sdSort, sizeof(sdSort));\ + switch (sdSort)\ {\ - uint8_t sdSort;\ - EEPROM_read(EEPROM_SD_SORT, (uint8_t*)&sdSort, sizeof(sdSort));\ - switch (sdSort)\ - {\ - case SD_SORT_TIME: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_SORT_TIME), lcd_sort_type_set); break;\ - case SD_SORT_ALPHA: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_SORT_ALPHA), lcd_sort_type_set); break;\ - default: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_NONE), lcd_sort_type_set);\ - }\ + case SD_SORT_TIME: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_SORT_TIME), lcd_sort_type_set); break;\ + case SD_SORT_ALPHA: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_SORT_ALPHA), lcd_sort_type_set); break;\ + default: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_NONE), lcd_sort_type_set);\ }\ }\ while (0) From 4fcbf95db65e33d4fa7ee561a510c8f79f2bdfd1 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 9 Feb 2021 15:00:46 +0200 Subject: [PATCH 25/44] apply RAII principle on the lsDive recursion limiter --- Firmware/cardreader.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index c414e2823..3ca88f63c 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -71,14 +71,22 @@ char *createFilename(char *buffer,const dir_t &p) //buffer>12characters void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/) { static uint8_t recursionCnt = 0; + // RAII incrementer for the recursionCnt + class _incrementer + { + public: + _incrementer() {recursionCnt++;} + ~_incrementer() {recursionCnt--;} + } recursionCntIncrementer; + dir_t p; uint8_t cnt = 0; // Read the next entry from a directory while (parent.readDir(p, longFilename) > 0) { - if (recursionCnt >= MAX_DIR_DEPTH) + if (recursionCnt > MAX_DIR_DEPTH) return; else if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { // If the entry is a directory and the action is LS_SerialPrint - recursionCnt++; + // Get the short name for the item, which we know is a folder char lfilename[FILENAME_LENGTH]; createFilename(lfilename, p); @@ -112,7 +120,6 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m if (lsAction == LS_SerialPrint_LFN) puts_P(PSTR("DIR_EXIT")); - recursionCnt--; } else { uint8_t pn0 = p.name[0]; From c1ead75a733f2a05690c1919b7d95277efef2e60 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Wed, 10 Feb 2021 11:18:59 +0100 Subject: [PATCH 26/44] Remove commented debug code the whole PR is ready for review after successfull tests --- Firmware/Marlin_main.cpp | 8 +++---- Firmware/SdFile.cpp | 49 ---------------------------------------- Firmware/SdFile.h | 2 +- Firmware/cardreader.cpp | 8 +++++-- Firmware/cardreader.h | 7 +++--- Firmware/cmdqueue.cpp | 15 ++++-------- 6 files changed, 18 insertions(+), 71 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 73dd5df98..62734d420 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -3987,12 +3987,10 @@ void process_commands() #endif }else if (code_seen_P("fv")) { // PRUSA fv // get file version - #if 0 - //@@TODO - def SDSUPPORT - card.openFile(strchr_pointer + 3,true); + #ifdef SDSUPPORT + card.openFileReadFilteredGcode(strchr_pointer + 3,true); while (true) { - uint16_t readByte = card.get(); + uint16_t readByte = card.getFilteredGcodeChar(); MYSERIAL.write(readByte); if (readByte=='\n') { break; diff --git a/Firmware/SdFile.cpp b/Firmware/SdFile.cpp index ee91bdfc9..1bad4319f 100644 --- a/Firmware/SdFile.cpp +++ b/Firmware/SdFile.cpp @@ -31,7 +31,6 @@ SdFile::SdFile(const char* path, uint8_t oflag) : SdBaseFile(path, oflag) { } -//size=100B bool SdFile::openFilteredGcode(SdBaseFile* dirFile, const char* path){ if( open(dirFile, path, O_READ) ){ // compute the block to start with @@ -44,10 +43,7 @@ bool SdFile::openFilteredGcode(SdBaseFile* dirFile, const char* path){ } } -//size=90B bool SdFile::seekSetFilteredGcode(uint32_t pos){ -// SERIAL_PROTOCOLPGM("Seek:"); -// SERIAL_PROTOCOLLN(pos); if(! seekSet(pos) )return false; if(! gfComputeNextFileBlock() )return false; gfReset(); @@ -63,11 +59,6 @@ void SdFile::gfReset(){ gfReadPtr = gfBlockBuffBegin() + gfOffset; } -//FORCE_INLINE const uint8_t * find_endl(const uint8_t *p){ -// while( *(++p) != '\n' ); // skip until a newline is found -// return p; -//} - // think twice before allowing this to inline - manipulating 4B longs is costly // moreover - this function has its parameters in registers only, so no heavy stack usage besides the call/ret void __attribute__((noinline)) SdFile::gfUpdateCurrentPosition(uint16_t inc){ @@ -85,21 +76,12 @@ __asm__ __volatile__ ( \ : "r22" /* modifying register R22 - so that the compiler knows */ \ ) -//size=400B // avoid calling the default heavy-weight read() for just one byte int16_t SdFile::readFilteredGcode(){ if( ! gfEnsureBlock() ){ goto eof_or_fail; // this is unfortunate :( ... other calls are using the cache and we can loose the data block of our gcode file } // assume, we have the 512B block cache filled and terminated with a '\n' -// SERIAL_PROTOCOLPGM("Read:"); -// SERIAL_PROTOCOL(curPosition_); -// SERIAL_PROTOCOL(':'); -// for(uint8_t i = 0; i < 16; ++i){ -// SERIAL_PROTOCOL( gfReadPtr[i] ); -// } -// SERIAL_PROTOCOLLN(); -// SERIAL_PROTOCOLLN(curPosition_); { const uint8_t *start = gfReadPtr; @@ -152,9 +134,6 @@ int16_t SdFile::readFilteredGcode(){ rdPtr = start = blockBuffBegin; } else { if(consecutiveCommentLines >= 250){ -// SERIAL_ECHO("ccl="); -// SERIAL_ECHOLN((int)consecutiveCommentLines); - // SERIAL_PROTOCOLLN(sd->curPosition_); --rdPtr; // unget the already consumed newline goto emit_char; } @@ -185,13 +164,6 @@ emit_char: rdPtr = blockBuffBegin; } -// SERIAL_PROTOCOLPGM("c="); -// SERIAL_ECHO((char)rv); -// SERIAL_ECHO('|'); -// SERIAL_ECHO((int)rv); -// SERIAL_PROTOCOL('|'); -// SERIAL_PROTOCOLLN(curPosition_); - // save the current read ptr for the next run gfReadPtr = rdPtr; return rv; @@ -200,17 +172,12 @@ emit_char: } eof_or_fail: -// SERIAL_PROTOCOLPGM("CacheFAIL:"); - // make the rdptr point to a safe location - end of file gfReadPtr = gfBlockBuffBegin() + 512; return -1; } -//size=70B bool SdFile::gfEnsureBlock(){ -// SERIAL_PROTOCOLPGM("EB:"); -// SERIAL_PROTOCOLLN(gfBlock); if ( vol_->cacheRawBlock(gfBlock, SdVolume::CACHE_FOR_READ)){ // terminate with a '\n' const uint16_t terminateOfs = fileSize_ - gfOffset; @@ -221,22 +188,6 @@ bool SdFile::gfEnsureBlock(){ } } - -//#define shr9(resultCurPos, curPos) \ -//__asm__ __volatile__ ( \ -//"asr r23 \n" \ -//"asr r22 \n" \ -//"asr r21 \n" \ -//"asr r20 \n" \ -//"ldi r20, r21 \n" \ -//"ldi r21, r22 \n" \ -//"ldi r22, r23 \n" \ -//"ldi r23, 0 \n" \ -//: "=a" (resultCurPos) \ -//: "a" (curPos) \ -//) - -//size=350B bool SdFile::gfComputeNextFileBlock() { // error if not open or write only if (!isOpen() || !(flags_ & O_READ)) return false; diff --git a/Firmware/SdFile.h b/Firmware/SdFile.h index 30a4da5d3..465224623 100644 --- a/Firmware/SdFile.h +++ b/Firmware/SdFile.h @@ -38,7 +38,7 @@ class SdFile : public SdBaseFile/*, public Print*/ { // beware - this read ptr is manipulated inside just 2 methods - readFilteredGcode and gfReset // If you even want to call gfReset from readFilteredGcode, you must make sure - // to update gfCacheP inside readFilteredGcode from a local copy (see explanation of this trick in readFilteredGcode) + // to update gfReadPtr inside readFilteredGcode from a local copy (see explanation of this trick in readFilteredGcode) const uint8_t *gfReadPtr; uint32_t gfBlock; // remember the current file block to be kept in cache - due to reuse of the memory, the block may fall out a must be read back diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 7d709475e..54f3b593a 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -456,8 +456,9 @@ void CardReader::openFileWrite(const char* name) if(!cardOK) return; if(file.isOpen()){ //replacing current file by new file, or subfile call - - // @@TODO I doubt this is necessary for file saving: +#if 0 + // I doubt chained files support is necessary for file saving: + // Intentionally disabled because it takes a lot of code size while being not used if((int)file_subcall_ctr>(int)SD_PROCEDURE_DEPTH-1){ // SERIAL_ERROR_START; @@ -481,6 +482,9 @@ void CardReader::openFileWrite(const char* name) filespos[file_subcall_ctr]=sdpos; file_subcall_ctr++; file.close(); +#else + SERIAL_ECHOLNPGM("File already opened"); +#endif } else { //opening fresh file file_subcall_ctr=0; //resetting procedure depth in case user cancels print while in procedure SERIAL_ECHO_START; diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 241d5e8b8..f8d6e628e 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -61,12 +61,11 @@ public: #endif FORCE_INLINE bool isFileOpen() { return file.isOpen(); } - FORCE_INLINE bool eof() { return sdpos>=filesize ;}; -// FORCE_INLINE int16_t getX() { sdpos = file.curPosition();return (int16_t)file.read();}; - //@@TODO potential performance problem - when the comment reading fails, sdpos points to the last correctly read character. + bool eof() { return sdpos>=filesize; } + // There may be a potential performance problem - when the comment reading fails, sdpos points to the last correctly read character. // However, repeated reading (e.g. after power panic) the comment will be read again - it should survive correctly, it will just take a few moments to skip FORCE_INLINE int16_t getFilteredGcodeChar() { sdpos = file.curPosition();return (int16_t)file.readFilteredGcode();}; - /*FORCE_INLINE*/ void setIndex(long index) {sdpos = index;file.seekSetFilteredGcode(index);}; + void setIndex(long index) {sdpos = index;file.seekSetFilteredGcode(index);}; FORCE_INLINE uint8_t percentDone(){if(!isFileOpen()) return 0; if(filesize) return sdpos/((filesize+99)/100); else return 0;}; FORCE_INLINE char* getWorkDirName(){workDir.getFilename(filename);return filename;}; FORCE_INLINE uint32_t get_sdpos() { if (!isFileOpen()) return 0; else return(sdpos); }; diff --git a/Firmware/cmdqueue.cpp b/Firmware/cmdqueue.cpp index d7a760c77..9c822dab5 100755 --- a/Firmware/cmdqueue.cpp +++ b/Firmware/cmdqueue.cpp @@ -588,7 +588,7 @@ void get_command() char serial_char = (char)n; if( serial_char == '\n' || serial_char == '\r' - || ((serial_char == '#' || serial_char == ':') /*&& comment_mode == false*/) + || ((serial_char == '#' || serial_char == ':') ) || serial_count >= (MAX_CMD_SIZE - 1) || n==-1 ){ @@ -602,9 +602,7 @@ void get_command() // read from the sdcard into sd_count, // so that the lenght of the already read empty lines and comments will be added // to the following non-empty line. -// comment_mode = false; return; // prevent cycling indefinitely - let manage_heaters do their job -// continue; //if empty line } // The new command buffer could be updated non-atomically, because it is not yet considered // to be inside the active queue. @@ -620,10 +618,10 @@ void get_command() // MYSERIAL.print(sd_count.value, DEC); // SERIAL_ECHOPGM(") "); // SERIAL_ECHOLN(cmdbuffer+bufindw+CMDHDRSIZE); -// SERIAL_ECHOPGM("cmdbuffer:"); -// MYSERIAL.print(cmdbuffer); -// SERIAL_ECHOPGM("buflen:"); -// MYSERIAL.print(buflen+1); +// SERIAL_ECHOPGM("cmdbuffer:"); +// MYSERIAL.print(cmdbuffer); +// SERIAL_ECHOPGM("buflen:"); +// MYSERIAL.print(buflen+1); sd_count.value = 0; cli(); @@ -640,7 +638,6 @@ void get_command() comment_mode = false; //for new command serial_count = 0; //clear buffer -// consecutiveEmptyLines = 0; // reached a non-empty line which shall be enqueued if(card.eof()) break; @@ -650,8 +647,6 @@ void get_command() } else { - /*if(serial_char == ';') comment_mode = true; - else if(!comment_mode)*/ // there are no comments coming from the filtered file cmdbuffer[bufindw+CMDHDRSIZE+serial_count++] = serial_char; } From 8d39880abf860c630ddaa514f617478a4e5b03a3 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Wed, 10 Feb 2021 12:23:02 +0100 Subject: [PATCH 27/44] Fix compilation against latest MK3 branch --- Firmware/cardreader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 57113124a..afcbad736 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -506,9 +506,9 @@ void CardReader::openFileWrite(const char* name) } sdprinting = false; - SdFile myDir; const char *fname=name; - diveSubfolder(fname,myDir); + if (!diveSubfolder(fname)) + return; //write if (!file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)){ From 7ad922e87b39485132d33bb06aee9e4b52c32ab5 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Wed, 10 Feb 2021 12:38:04 +0100 Subject: [PATCH 28/44] Report fname instead of name looks like being omitted in MK3 upstream fixes --- Firmware/cardreader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index afcbad736..6fe890095 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -518,7 +518,7 @@ void CardReader::openFileWrite(const char* name) } else { saving = true; SERIAL_PROTOCOLRPGM(ofWritingToFile);////MSG_SD_WRITE_TO_FILE - SERIAL_PROTOCOLLN(name); + SERIAL_PROTOCOLLN(fname); lcd_setstatus(fname); } } From e010ca8ceb87e875d9353b55b8b69e97dca91cc5 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Thu, 4 Feb 2021 20:36:06 +0100 Subject: [PATCH 29/44] Fix conflicting extern/inline declarations The functions find_bed_induction_sensor_point_* have conflicting extern and inline declarations. These are used outside of the compilation unit only, and thus there's no point in defining them inline. This causes a compilation failure at O1 and above, which is strangely avoided at Os. --- Firmware/mesh_bed_calibration.cpp | 8 ++++---- Firmware/mesh_bed_calibration.h | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Firmware/mesh_bed_calibration.cpp b/Firmware/mesh_bed_calibration.cpp index a0efc3aae..fb79022ff 100644 --- a/Firmware/mesh_bed_calibration.cpp +++ b/Firmware/mesh_bed_calibration.cpp @@ -944,7 +944,7 @@ static inline void update_current_position_z() // At the current position, find the Z stop. -inline bool find_bed_induction_sensor_point_z(float minimum_z, uint8_t n_iter, int +bool find_bed_induction_sensor_point_z(float minimum_z, uint8_t n_iter, int #ifdef SUPPORT_VERBOSITY verbosity_level #endif //SUPPORT_VERBOSITY @@ -1065,7 +1065,7 @@ error: } #ifdef NEW_XYZCAL -extern bool xyzcal_find_bed_induction_sensor_point_xy(); +bool xyzcal_find_bed_induction_sensor_point_xy(); #endif //NEW_XYZCAL // Search around the current_position[X,Y], // look for the induction sensor response. @@ -1081,7 +1081,7 @@ extern bool xyzcal_find_bed_induction_sensor_point_xy(); #endif //HEATBED_V2 #ifdef HEATBED_V2 -inline bool find_bed_induction_sensor_point_xy(int +bool find_bed_induction_sensor_point_xy(int #if !defined (NEW_XYZCAL) && defined (SUPPORT_VERBOSITY) verbosity_level #endif @@ -1335,7 +1335,7 @@ inline bool find_bed_induction_sensor_point_xy(int #endif //NEW_XYZCAL } #else //HEATBED_V2 -inline bool find_bed_induction_sensor_point_xy(int verbosity_level) +bool find_bed_induction_sensor_point_xy(int verbosity_level) { #ifdef NEW_XYZCAL return xyzcal_find_bed_induction_sensor_point_xy(); diff --git a/Firmware/mesh_bed_calibration.h b/Firmware/mesh_bed_calibration.h index 8adc1c119..7ca93c953 100644 --- a/Firmware/mesh_bed_calibration.h +++ b/Firmware/mesh_bed_calibration.h @@ -146,9 +146,9 @@ inline bool world2machine_clamp(float &x, float &y) return clamped; } -extern bool find_bed_induction_sensor_point_z(float minimum_z = -10.f, uint8_t n_iter = 3, int verbosity_level = 0); -extern bool find_bed_induction_sensor_point_xy(int verbosity_level = 0); -extern void go_home_with_z_lift(); +bool find_bed_induction_sensor_point_z(float minimum_z = -10.f, uint8_t n_iter = 3, int verbosity_level = 0); +bool find_bed_induction_sensor_point_xy(int verbosity_level = 0); +void go_home_with_z_lift(); /** * @brief Bed skew and offest detection result From cb61436093238cd1a357dd248cd285e79e276542 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Sun, 7 Feb 2021 09:47:30 +0100 Subject: [PATCH 30/44] Add remaining time to change/pause/user interaction to LCD Info screen - Add parameter `C` to gcode `M73` - LCD Info screen switches to change time if last `M73` gcode contains `C` parameter - Examples: - `M73 P5 R120` will display on LCD ` SD 5% 02:00R ` if it is printing at 100% speed - `M73 P5 R120 C60` will display on LCD ` SD 5% 01:00C ` if it is printing at 100% speed Slicers can generate "Time to change/pause/user interaction" using `C` parameter to "overwrite" the remaining print time. To switch between time to change and remaining time just send in intervals `M73` with or without `C` parameter. --- Firmware/Marlin.h | 2 ++ Firmware/Marlin_main.cpp | 33 ++++++++++++++++++++++++++++----- Firmware/ultralcd.cpp | 32 ++++++++++++++++++++------------ 3 files changed, 50 insertions(+), 17 deletions(-) diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index cbe03c0f6..5ef7ca00e 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -366,6 +366,7 @@ extern uint8_t print_percent_done_normal; extern uint16_t print_time_remaining_normal; extern uint8_t print_percent_done_silent; extern uint16_t print_time_remaining_silent; +extern uint16_t print_time_to_change; #define PRINT_TIME_REMAINING_INIT 0xffff @@ -438,6 +439,7 @@ extern void cancel_saved_printing(); //estimated time to end of the print extern uint16_t print_time_remaining(); +extern uint16_t print_time_to_change_remaining(); extern uint8_t calc_percent_done(); diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 0c468189b..b36dd16a8 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -316,6 +316,7 @@ uint8_t print_percent_done_normal = PRINT_PERCENT_DONE_INIT; uint16_t print_time_remaining_normal = PRINT_TIME_REMAINING_INIT; //estimated remaining print time in minutes uint8_t print_percent_done_silent = PRINT_PERCENT_DONE_INIT; uint16_t print_time_remaining_silent = PRINT_TIME_REMAINING_INIT; //estimated remaining print time in minutes +uint16_t print_time_to_change = PRINT_TIME_REMAINING_INIT; //estimated remaining time to next change in minutes uint32_t IP_address = 0; @@ -6395,13 +6396,14 @@ Sigma_Exit: ### M73 - Set/get print progress M73: Set/Get build percentage #### Usage - M73 [ P | R | Q | S ] + M73 [ P | R | Q | S | C ] #### Parameters - `P` - Percent in normal mode - `R` - Time remaining in normal mode - `Q` - Percent in silent mode - `S` - Time in silent mode + - `C` - Time to change/pause/user interaction */ case 73: //M73 show percent done and time remaining if(code_seen('P')) print_percent_done_normal = code_value(); @@ -6414,6 +6416,14 @@ Sigma_Exit: printf_P(_msg_mode_done_remain, _N("NORMAL"), int(print_percent_done_normal), print_time_remaining_normal); printf_P(_msg_mode_done_remain, _N("SILENT"), int(print_percent_done_silent), print_time_remaining_silent); } + + print_time_to_change = PRINT_TIME_REMAINING_INIT; + if(code_seen('C')) + { + print_time_to_change = code_value(); + printf_P(_N("Time to next change in mins: %d\n"), print_time_to_change); + } + break; /*! @@ -11665,6 +11675,18 @@ uint16_t print_time_remaining() { return print_t; } +uint16_t print_time_to_change_remaining() { + uint16_t print_t = PRINT_TIME_REMAINING_INIT; +//#ifdef TMC2130 +// if (SilentModeMenu == SILENT_MODE_OFF) print_t = print_time_to_change; +// else print_t = print_time_to_change - (print_time_remaining_normal - print_time_remaining_silent); +//#else + print_t = print_time_to_change; +//#endif //TMC2130 + if ((print_t != PRINT_TIME_REMAINING_INIT) && (feedmultiply != 0)) print_t = 100ul * print_t / feedmultiply; + return print_t; +} + uint8_t calc_percent_done() { //in case that we have information from M73 gcode return percentage counted by slicer, else return percentage counted as byte_printed/filesize @@ -11689,10 +11711,11 @@ uint8_t calc_percent_done() static void print_time_remaining_init() { - print_time_remaining_normal = PRINT_TIME_REMAINING_INIT; - print_time_remaining_silent = PRINT_TIME_REMAINING_INIT; - print_percent_done_normal = PRINT_PERCENT_DONE_INIT; - print_percent_done_silent = PRINT_PERCENT_DONE_INIT; + print_time_remaining_normal = PRINT_TIME_REMAINING_INIT; + print_percent_done_normal = PRINT_PERCENT_DONE_INIT; + print_time_remaining_silent = PRINT_TIME_REMAINING_INIT; + print_percent_done_silent = PRINT_PERCENT_DONE_INIT; + print_time_to_change = PRINT_TIME_REMAINING_INIT; } void load_filament_final_feed() diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index f8b791b0b..1854d8465 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -673,22 +673,30 @@ void lcdui_print_time(void) { //if remaining print time estimation is available print it else print elapsed time uint16_t print_t = 0; - if (print_time_remaining_normal != PRINT_TIME_REMAINING_INIT) + int chars = 0; + char suff = ' '; + char suff_doubt = ' '; + + if(print_time_to_change != PRINT_TIME_REMAINING_INIT) + { + print_t = print_time_to_change_remaining(); + suff = 'C'; + if (feedmultiply != 100) + suff_doubt = '?'; + } + else if (print_time_remaining_normal != PRINT_TIME_REMAINING_INIT) + { print_t = print_time_remaining(); + suff = 'R'; + if (feedmultiply != 100) + suff_doubt = '?'; + } else if(starttime != 0) print_t = _millis() / 60000 - starttime / 60000; - int chars = 0; - if ((PRINTER_ACTIVE) && ((print_time_remaining_normal != PRINT_TIME_REMAINING_INIT) || (starttime != 0))) + + if ((PRINTER_ACTIVE) && ((print_time_remaining_normal != PRINT_TIME_REMAINING_INIT) || (print_time_to_change != PRINT_TIME_REMAINING_INIT) || (starttime != 0))) { - char suff = ' '; - char suff_doubt = ' '; - if (print_time_remaining_normal != PRINT_TIME_REMAINING_INIT) - { - suff = 'R'; - if (feedmultiply != 100) - suff_doubt = '?'; - } - if (print_t < 6000) //time<100h + if (print_t < 6000) //time<100h chars = lcd_printf_P(_N("%c%02u:%02u%c%c"), LCD_STR_CLOCK[0], print_t / 60, print_t % 60, suff, suff_doubt); else //time>=100h chars = lcd_printf_P(_N("%c%3uh %c%c"), LCD_STR_CLOCK[0], print_t / 60, suff, suff_doubt); From cca90da64bf40f671d401b5dd194a4352774b94e Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Sun, 7 Feb 2021 09:48:48 +0100 Subject: [PATCH 31/44] Include silent mode on time change - depends on difference between print time remaining NORMAL vs SILENT mode --- Firmware/Marlin_main.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index b36dd16a8..333e3a30d 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -11677,12 +11677,12 @@ uint16_t print_time_remaining() { uint16_t print_time_to_change_remaining() { uint16_t print_t = PRINT_TIME_REMAINING_INIT; -//#ifdef TMC2130 -// if (SilentModeMenu == SILENT_MODE_OFF) print_t = print_time_to_change; -// else print_t = print_time_to_change - (print_time_remaining_normal - print_time_remaining_silent); -//#else +/#ifdef TMC2130 + if (SilentModeMenu == SILENT_MODE_OFF) print_t = print_time_to_change; + else print_t = print_time_to_change - (print_time_remaining_normal - print_time_remaining_silent); +#else print_t = print_time_to_change; -//#endif //TMC2130 +#endif //TMC2130 if ((print_t != PRINT_TIME_REMAINING_INIT) && (feedmultiply != 0)) print_t = 100ul * print_t / feedmultiply; return print_t; } From f4ca6ee59d657ec7be06938f20294e12e0acd568 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Sun, 7 Feb 2021 09:52:25 +0100 Subject: [PATCH 32/44] Fix typo --- Firmware/Marlin_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 333e3a30d..2a67e3ad9 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -11677,7 +11677,7 @@ uint16_t print_time_remaining() { uint16_t print_time_to_change_remaining() { uint16_t print_t = PRINT_TIME_REMAINING_INIT; -/#ifdef TMC2130 +#ifdef TMC2130 if (SilentModeMenu == SILENT_MODE_OFF) print_t = print_time_to_change; else print_t = print_time_to_change - (print_time_remaining_normal - print_time_remaining_silent); #else From ae48e7c3ce5f0a1db13b22ada3e2fc6e9d7ed0f3 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Sun, 7 Feb 2021 10:37:41 +0100 Subject: [PATCH 33/44] indentation --- Firmware/Marlin_main.cpp | 101 +++++++++++++++++++++------------------ Firmware/ultralcd.cpp | 58 +++++++++++----------- 2 files changed, 83 insertions(+), 76 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 2a67e3ad9..c50ec0297 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -6392,40 +6392,41 @@ Sigma_Exit: #endif // Z_PROBE_REPEATABILITY_TEST #endif // ENABLE_AUTO_BED_LEVELING - /*! - ### M73 - Set/get print progress M73: Set/Get build percentage - #### Usage - - M73 [ P | R | Q | S | C ] - - #### Parameters + /*! + ### M73 - Set/get print progress M73: Set/Get build percentage + #### Usage + + M73 [ P | R | Q | S | C ] + + #### Parameters - `P` - Percent in normal mode - `R` - Time remaining in normal mode - `Q` - Percent in silent mode - `S` - Time in silent mode - `C` - Time to change/pause/user interaction - */ - case 73: //M73 show percent done and time remaining - if(code_seen('P')) print_percent_done_normal = code_value(); - if(code_seen('R')) print_time_remaining_normal = code_value(); - if(code_seen('Q')) print_percent_done_silent = code_value(); - if(code_seen('S')) print_time_remaining_silent = code_value(); + */ + //!@todo update RepRap Gcode wiki + case 73: //M73 show percent done and time remaining + { + if(code_seen('P')) print_percent_done_normal = code_value(); + if(code_seen('R')) print_time_remaining_normal = code_value(); + if(code_seen('Q')) print_percent_done_silent = code_value(); + if(code_seen('S')) print_time_remaining_silent = code_value(); - { - const char* _msg_mode_done_remain = _N("%S MODE: Percent done: %d; print time remaining in mins: %d\n"); - printf_P(_msg_mode_done_remain, _N("NORMAL"), int(print_percent_done_normal), print_time_remaining_normal); - printf_P(_msg_mode_done_remain, _N("SILENT"), int(print_percent_done_silent), print_time_remaining_silent); - } + { + const char* _msg_mode_done_remain = _N("%S MODE: Percent done: %d; print time remaining in mins: %d\n"); + printf_P(_msg_mode_done_remain, _N("NORMAL"), int(print_percent_done_normal), print_time_remaining_normal); + printf_P(_msg_mode_done_remain, _N("SILENT"), int(print_percent_done_silent), print_time_remaining_silent); + } print_time_to_change = PRINT_TIME_REMAINING_INIT; - if(code_seen('C')) + if(code_seen('C')) { print_time_to_change = code_value(); - printf_P(_N("Time to next change in mins: %d\n"), print_time_to_change); - } - - break; - + printf_P(_N("Time to next change in mins: %d\n"), print_time_to_change); + } + break; + } /*! ### M104 - Set hotend temperature M104: Set Extruder Temperature #### Usage @@ -11663,50 +11664,56 @@ void print_mesh_bed_leveling_table() SERIAL_ECHOLN(); } -uint16_t print_time_remaining() { - uint16_t print_t = PRINT_TIME_REMAINING_INIT; +uint16_t print_time_remaining() +{ + uint16_t print_t = PRINT_TIME_REMAINING_INIT; #ifdef TMC2130 - if (SilentModeMenu == SILENT_MODE_OFF) print_t = print_time_remaining_normal; - else print_t = print_time_remaining_silent; + if (SilentModeMenu == SILENT_MODE_OFF) print_t = print_time_remaining_normal; + else print_t = print_time_remaining_silent; #else - print_t = print_time_remaining_normal; + print_t = print_time_remaining_normal; #endif //TMC2130 - if ((print_t != PRINT_TIME_REMAINING_INIT) && (feedmultiply != 0)) print_t = 100ul * print_t / feedmultiply; - return print_t; + if ((print_t != PRINT_TIME_REMAINING_INIT) && (feedmultiply != 0)) print_t = 100ul * print_t / feedmultiply; + return print_t; } -uint16_t print_time_to_change_remaining() { - uint16_t print_t = PRINT_TIME_REMAINING_INIT; +uint16_t print_time_to_change_remaining() +{ + uint16_t print_t = PRINT_TIME_REMAINING_INIT; #ifdef TMC2130 - if (SilentModeMenu == SILENT_MODE_OFF) print_t = print_time_to_change; + if (SilentModeMenu == SILENT_MODE_OFF) print_t = print_time_to_change; else print_t = print_time_to_change - (print_time_remaining_normal - print_time_remaining_silent); #else print_t = print_time_to_change; #endif //TMC2130 - if ((print_t != PRINT_TIME_REMAINING_INIT) && (feedmultiply != 0)) print_t = 100ul * print_t / feedmultiply; - return print_t; + if ((print_t != PRINT_TIME_REMAINING_INIT) && (feedmultiply != 0)) print_t = 100ul * print_t / feedmultiply; + return print_t; } uint8_t calc_percent_done() { - //in case that we have information from M73 gcode return percentage counted by slicer, else return percentage counted as byte_printed/filesize - uint8_t percent_done = 0; + //in case that we have information from M73 gcode return percentage counted by slicer, else return percentage counted as byte_printed/filesize + uint8_t percent_done = 0; #ifdef TMC2130 - if (SilentModeMenu == SILENT_MODE_OFF && print_percent_done_normal <= 100) { - percent_done = print_percent_done_normal; - } - else if (print_percent_done_silent <= 100) { + if (SilentModeMenu == SILENT_MODE_OFF && print_percent_done_normal <= 100) + { + percent_done = print_percent_done_normal; + } + else if (print_percent_done_silent <= 100) + { percent_done = print_percent_done_silent; } #else - if (print_percent_done_normal <= 100) { + if (print_percent_done_normal <= 100) + { percent_done = print_percent_done_normal; } #endif //TMC2130 - else { - percent_done = card.percentDone(); - } - return percent_done; + else + { + percent_done = card.percentDone(); + } + return percent_done; } static void print_time_remaining_init() diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 1854d8465..cf4737cb8 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -671,39 +671,39 @@ void lcdui_print_cmd_diag(void) // Print time (8 chars total) void lcdui_print_time(void) { - //if remaining print time estimation is available print it else print elapsed time - uint16_t print_t = 0; - int chars = 0; + //if remaining print time estimation is available print it else print elapsed time + uint16_t print_t = 0; + int chars = 0; char suff = ' '; char suff_doubt = ' '; - if(print_time_to_change != PRINT_TIME_REMAINING_INIT) - { - print_t = print_time_to_change_remaining(); - suff = 'C'; - if (feedmultiply != 100) - suff_doubt = '?'; - } - else if (print_time_remaining_normal != PRINT_TIME_REMAINING_INIT) - { - print_t = print_time_remaining(); - suff = 'R'; - if (feedmultiply != 100) - suff_doubt = '?'; - } - else if(starttime != 0) - print_t = _millis() / 60000 - starttime / 60000; + if(print_time_to_change != PRINT_TIME_REMAINING_INIT) + { + print_t = print_time_to_change_remaining(); + suff = 'C'; + if (feedmultiply != 100) + suff_doubt = '?'; + } + else if (print_time_remaining_normal != PRINT_TIME_REMAINING_INIT) + { + print_t = print_time_remaining(); + suff = 'R'; + if (feedmultiply != 100) + suff_doubt = '?'; + } + else if(starttime != 0) + print_t = _millis() / 60000 - starttime / 60000; - if ((PRINTER_ACTIVE) && ((print_time_remaining_normal != PRINT_TIME_REMAINING_INIT) || (print_time_to_change != PRINT_TIME_REMAINING_INIT) || (starttime != 0))) - { - if (print_t < 6000) //time<100h - chars = lcd_printf_P(_N("%c%02u:%02u%c%c"), LCD_STR_CLOCK[0], print_t / 60, print_t % 60, suff, suff_doubt); - else //time>=100h - chars = lcd_printf_P(_N("%c%3uh %c%c"), LCD_STR_CLOCK[0], print_t / 60, suff, suff_doubt); - } - else - chars = lcd_printf_P(_N("%c--:-- "), LCD_STR_CLOCK[0]); - lcd_space(8 - chars); + if ((PRINTER_ACTIVE) && ((print_time_remaining_normal != PRINT_TIME_REMAINING_INIT) || (print_time_to_change != PRINT_TIME_REMAINING_INIT) || (starttime != 0))) + { + if (print_t < 6000) //time<100h + chars = lcd_printf_P(_N("%c%02u:%02u%c%c"), LCD_STR_CLOCK[0], print_t / 60, print_t % 60, suff, suff_doubt); + else //time>=100h + chars = lcd_printf_P(_N("%c%3uh %c%c"), LCD_STR_CLOCK[0], print_t / 60, suff, suff_doubt); + } + else + chars = lcd_printf_P(_N("%c--:-- "), LCD_STR_CLOCK[0]); + lcd_space(8 - chars); } //Print status line on status screen From 91c767b0f24d9d3877a88e8588c8711375512bfa Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Mon, 8 Feb 2021 03:34:01 +0100 Subject: [PATCH 34/44] Reduce code size --- Firmware/Configuration.h | 2 +- Firmware/Marlin.h | 2 -- Firmware/Marlin_main.cpp | 28 +----------------------- Firmware/ultralcd.cpp | 47 +++++++++++++++++++++++----------------- 4 files changed, 29 insertions(+), 50 deletions(-) diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index 62688ebe8..80d250bf2 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -17,7 +17,7 @@ extern PGM_P sPrinterName; // Firmware version #define FW_VERSION "3.9.3" -#define FW_COMMIT_NR 3556 +#define FW_COMMIT_NR 5002 // FW_VERSION_UNKNOWN means this is an unofficial build. // The firmware should only be checked into github with this symbol. #define FW_DEV_VERSION FW_VERSION_UNKNOWN diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 5ef7ca00e..49201c3a1 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -438,8 +438,6 @@ extern void cancel_saved_printing(); //estimated time to end of the print -extern uint16_t print_time_remaining(); -extern uint16_t print_time_to_change_remaining(); extern uint8_t calc_percent_done(); diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index c50ec0297..426a32170 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -6423,7 +6423,7 @@ Sigma_Exit: if(code_seen('C')) { print_time_to_change = code_value(); - printf_P(_N("Time to next change in mins: %d\n"), print_time_to_change); + printf_P(_N("Change in mins: %d\n"), print_time_to_change); } break; } @@ -11664,32 +11664,6 @@ void print_mesh_bed_leveling_table() SERIAL_ECHOLN(); } -uint16_t print_time_remaining() -{ - uint16_t print_t = PRINT_TIME_REMAINING_INIT; -#ifdef TMC2130 - if (SilentModeMenu == SILENT_MODE_OFF) print_t = print_time_remaining_normal; - else print_t = print_time_remaining_silent; -#else - print_t = print_time_remaining_normal; -#endif //TMC2130 - if ((print_t != PRINT_TIME_REMAINING_INIT) && (feedmultiply != 0)) print_t = 100ul * print_t / feedmultiply; - return print_t; -} - -uint16_t print_time_to_change_remaining() -{ - uint16_t print_t = PRINT_TIME_REMAINING_INIT; -#ifdef TMC2130 - if (SilentModeMenu == SILENT_MODE_OFF) print_t = print_time_to_change; - else print_t = print_time_to_change - (print_time_remaining_normal - print_time_remaining_silent); -#else - print_t = print_time_to_change; -#endif //TMC2130 - if ((print_t != PRINT_TIME_REMAINING_INIT) && (feedmultiply != 0)) print_t = 100ul * print_t / feedmultiply; - return print_t; -} - uint8_t calc_percent_done() { //in case that we have information from M73 gcode return percentage counted by slicer, else return percentage counted as byte_printed/filesize diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index cf4737cb8..43d80799e 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -672,30 +672,37 @@ void lcdui_print_cmd_diag(void) void lcdui_print_time(void) { //if remaining print time estimation is available print it else print elapsed time - uint16_t print_t = 0; int chars = 0; - char suff = ' '; - char suff_doubt = ' '; + if ((PRINTER_ACTIVE) && (starttime != 0)) + { + uint16_t print_t = 0; + char suff = ' '; + char suff_doubt = ' '; - if(print_time_to_change != PRINT_TIME_REMAINING_INIT) - { - print_t = print_time_to_change_remaining(); - suff = 'C'; + if (print_time_to_change != PRINT_TIME_REMAINING_INIT) + { + print_t = print_time_to_change; + suff = 'C'; + } + else + { + suff = 'R'; + #ifdef TMC2130 + if (print_time_remaining_silent != PRINT_TIME_REMAINING_INIT && (SilentModeMenu != SILENT_MODE_OFF)) + { + print_t = print_time_remaining_silent; + } + else + #endif //TMC2130 + print_t = print_time_remaining_normal; + } + if (feedmultiply != 100) + { suff_doubt = '?'; - } - else if (print_time_remaining_normal != PRINT_TIME_REMAINING_INIT) - { - print_t = print_time_remaining(); - suff = 'R'; - if (feedmultiply != 100) - suff_doubt = '?'; - } - else if(starttime != 0) - print_t = _millis() / 60000 - starttime / 60000; - - if ((PRINTER_ACTIVE) && ((print_time_remaining_normal != PRINT_TIME_REMAINING_INIT) || (print_time_to_change != PRINT_TIME_REMAINING_INIT) || (starttime != 0))) - { + print_t = 100ul * print_t / feedmultiply; + } + if (print_t < 6000) //time<100h chars = lcd_printf_P(_N("%c%02u:%02u%c%c"), LCD_STR_CLOCK[0], print_t / 60, print_t % 60, suff, suff_doubt); else //time>=100h From 83e791cbbe390730d56ad137b1b78064803cf43b Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Mon, 8 Feb 2021 04:05:01 +0100 Subject: [PATCH 35/44] Fix temp Build number --- Firmware/Configuration.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index 80d250bf2..62688ebe8 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -17,7 +17,7 @@ extern PGM_P sPrinterName; // Firmware version #define FW_VERSION "3.9.3" -#define FW_COMMIT_NR 5002 +#define FW_COMMIT_NR 3556 // FW_VERSION_UNKNOWN means this is an unofficial build. // The firmware should only be checked into github with this symbol. #define FW_DEV_VERSION FW_VERSION_UNKNOWN From d063ffb1413960004060c8b52229edec4bf67675 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Wed, 10 Feb 2021 08:13:40 +0100 Subject: [PATCH 36/44] Add parameter `D` to gcode `M73` for silent/stealth mode --- Firmware/Marlin.h | 3 ++- Firmware/Marlin_main.cpp | 16 +++++++++----- Firmware/ultralcd.cpp | 48 +++++++++++++++++++++++++++++----------- 3 files changed, 47 insertions(+), 20 deletions(-) diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 49201c3a1..a1b6fe4eb 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -366,7 +366,8 @@ extern uint8_t print_percent_done_normal; extern uint16_t print_time_remaining_normal; extern uint8_t print_percent_done_silent; extern uint16_t print_time_remaining_silent; -extern uint16_t print_time_to_change; +extern uint16_t print_time_to_change_normal; +extern uint16_t print_time_to_change_silent; #define PRINT_TIME_REMAINING_INIT 0xffff diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 426a32170..95acdf8fc 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -316,7 +316,8 @@ uint8_t print_percent_done_normal = PRINT_PERCENT_DONE_INIT; uint16_t print_time_remaining_normal = PRINT_TIME_REMAINING_INIT; //estimated remaining print time in minutes uint8_t print_percent_done_silent = PRINT_PERCENT_DONE_INIT; uint16_t print_time_remaining_silent = PRINT_TIME_REMAINING_INIT; //estimated remaining print time in minutes -uint16_t print_time_to_change = PRINT_TIME_REMAINING_INIT; //estimated remaining time to next change in minutes +uint16_t print_time_to_change_normal = PRINT_TIME_REMAINING_INIT; //estimated remaining time to next change in minutes +uint16_t print_time_to_change_silent = PRINT_TIME_REMAINING_INIT; //estimated remaining time to next change in minutes uint32_t IP_address = 0; @@ -6419,11 +6420,13 @@ Sigma_Exit: printf_P(_msg_mode_done_remain, _N("SILENT"), int(print_percent_done_silent), print_time_remaining_silent); } - print_time_to_change = PRINT_TIME_REMAINING_INIT; - if(code_seen('C')) + if(code_seen('C')) print_time_to_change_normal = code_value(); + if(code_seen('D')) print_time_to_change_silent = code_value(); + { - print_time_to_change = code_value(); - printf_P(_N("Change in mins: %d\n"), print_time_to_change); + const char* _msg_mode_done_remain = _N("%S MODE: Change in mins: %d\n"); + printf_P(_msg_mode_done_remain, _N("NORMAL"), print_time_to_change_normal); + printf_P(_msg_mode_done_remain, _N("SILENT"), print_time_to_change_silent); } break; } @@ -11696,7 +11699,8 @@ static void print_time_remaining_init() print_percent_done_normal = PRINT_PERCENT_DONE_INIT; print_time_remaining_silent = PRINT_TIME_REMAINING_INIT; print_percent_done_silent = PRINT_PERCENT_DONE_INIT; - print_time_to_change = PRINT_TIME_REMAINING_INIT; + print_time_to_change_normal = PRINT_TIME_REMAINING_INIT; + print_time_to_change_silent = PRINT_TIME_REMAINING_INIT; } void load_filament_final_feed() diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 43d80799e..5041f2036 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -676,33 +676,55 @@ void lcdui_print_time(void) if ((PRINTER_ACTIVE) && (starttime != 0)) { uint16_t print_t = 0; + uint16_t print_tr = 0; + uint16_t print_tc = 0; char suff = ' '; char suff_doubt = ' '; - if (print_time_to_change != PRINT_TIME_REMAINING_INIT) + #ifdef TMC2130 + if (SilentModeMenu != SILENT_MODE_OFF) { - print_t = print_time_to_change; + if (print_time_remaining_silent != PRINT_TIME_REMAINING_INIT) + { + print_tr = print_time_remaining_silent; + } + if (print_time_to_change_silent != PRINT_TIME_REMAINING_INIT) + { + print_tc = print_time_to_change_silent; + } + } + else + { + #endif //TMC2130 + if (print_time_remaining_normal != PRINT_TIME_REMAINING_INIT) + { + print_tr = print_time_remaining_normal; + } + if (print_time_to_change_normal != PRINT_TIME_REMAINING_INIT) + { + print_tc = print_time_to_change_normal; + } + #ifdef TMC2130 + } + #endif //TMC2130 + + if (print_tc != 0) + { + print_t = print_tc; suff = 'C'; } - else + else if (print_tr != 0) { + print_t = print_tr; suff = 'R'; - #ifdef TMC2130 - if (print_time_remaining_silent != PRINT_TIME_REMAINING_INIT && (SilentModeMenu != SILENT_MODE_OFF)) - { - print_t = print_time_remaining_silent; } - else - #endif //TMC2130 - print_t = print_time_remaining_normal; - } - + if (feedmultiply != 100) { suff_doubt = '?'; print_t = 100ul * print_t / feedmultiply; } - + if (print_t < 6000) //time<100h chars = lcd_printf_P(_N("%c%02u:%02u%c%c"), LCD_STR_CLOCK[0], print_t / 60, print_t % 60, suff, suff_doubt); else //time>=100h From 4998cfb70d4f8778f3f7f7c7fcb3d52a94f56d5d Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Wed, 10 Feb 2021 08:59:31 +0100 Subject: [PATCH 37/44] Fix printing time being shown without `M73` gcode Adjust estimated times only if speed is changed. Printing time has to stay printing time. --- Firmware/ultralcd.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 5041f2036..cd5705aae 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -718,8 +718,12 @@ void lcdui_print_time(void) print_t = print_tr; suff = 'R'; } + else + { + print_t = _millis() / 60000 - starttime / 60000; + } - if (feedmultiply != 100) + if (feedmultiply != 100 && (print_tc != 0 || print_tr !=0)) { suff_doubt = '?'; print_t = 100ul * print_t / feedmultiply; From b13d4b71d437962cf2b493d0f1805cfe44b8d613 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Wed, 10 Feb 2021 09:29:47 +0100 Subject: [PATCH 38/44] Add Change time behind existing message --- Firmware/Marlin_main.cpp | 62 ++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 95acdf8fc..2b89958cc 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -6393,43 +6393,37 @@ Sigma_Exit: #endif // Z_PROBE_REPEATABILITY_TEST #endif // ENABLE_AUTO_BED_LEVELING - /*! - ### M73 - Set/get print progress M73: Set/Get build percentage - #### Usage - - M73 [ P | R | Q | S | C ] - - #### Parameters - - `P` - Percent in normal mode - - `R` - Time remaining in normal mode - - `Q` - Percent in silent mode - - `S` - Time in silent mode - - `C` - Time to change/pause/user interaction - */ - //!@todo update RepRap Gcode wiki - case 73: //M73 show percent done and time remaining - { - if(code_seen('P')) print_percent_done_normal = code_value(); - if(code_seen('R')) print_time_remaining_normal = code_value(); - if(code_seen('Q')) print_percent_done_silent = code_value(); - if(code_seen('S')) print_time_remaining_silent = code_value(); - - { - const char* _msg_mode_done_remain = _N("%S MODE: Percent done: %d; print time remaining in mins: %d\n"); - printf_P(_msg_mode_done_remain, _N("NORMAL"), int(print_percent_done_normal), print_time_remaining_normal); - printf_P(_msg_mode_done_remain, _N("SILENT"), int(print_percent_done_silent), print_time_remaining_silent); - } - - if(code_seen('C')) print_time_to_change_normal = code_value(); - if(code_seen('D')) print_time_to_change_silent = code_value(); + /*! + ### M73 - Set/get print progress M73: Set/Get build percentage + #### Usage + M73 [ P | R | Q | S | C | D ] + + #### Parameters + - `P` - Percent in normal mode + - `R` - Time remaining in normal mode + - `Q` - Percent in silent mode + - `S` - Time in silent mode + - `C` - Time to change/pause/user interaction in normal mode + - `D` - Time to change/pause/user interaction in silent mode + */ + //!@todo update RepRap Gcode wiki + case 73: //M73 show percent done, time remaining and time to change/pause { - const char* _msg_mode_done_remain = _N("%S MODE: Change in mins: %d\n"); - printf_P(_msg_mode_done_remain, _N("NORMAL"), print_time_to_change_normal); - printf_P(_msg_mode_done_remain, _N("SILENT"), print_time_to_change_silent); + if(code_seen('P')) print_percent_done_normal = code_value(); + if(code_seen('R')) print_time_remaining_normal = code_value(); + if(code_seen('Q')) print_percent_done_silent = code_value(); + if(code_seen('S')) print_time_remaining_silent = code_value(); + if(code_seen('C')) print_time_to_change_normal = code_value(); + if(code_seen('D')) print_time_to_change_silent = code_value(); + + { + const char* _msg_mode_done_remain = _N("%S MODE: Percent done: %d; print time remaining in mins: %d; Change in mins: %d\n"); + printf_P(_msg_mode_done_remain, _N("NORMAL"), int(print_percent_done_normal), print_time_remaining_normal, print_time_to_change_normal); + printf_P(_msg_mode_done_remain, _N("SILENT"), int(print_percent_done_silent), print_time_remaining_silent, print_time_to_change_silent); + } + break; } - break; - } /*! ### M104 - Set hotend temperature M104: Set Extruder Temperature #### Usage From b9a3fa2ddd7f955ccfd0551b9980cd0d5052a4b2 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Wed, 10 Feb 2021 09:31:33 +0100 Subject: [PATCH 39/44] fix time at speed --- Firmware/ultralcd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index cd5705aae..057d7dea9 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -723,7 +723,7 @@ void lcdui_print_time(void) print_t = _millis() / 60000 - starttime / 60000; } - if (feedmultiply != 100 && (print_tc != 0 || print_tr !=0)) + if (feedmultiply != 100 && (print_t == print_tr || print_t == print_tc)) { suff_doubt = '?'; print_t = 100ul * print_t / feedmultiply; From 14b4bf5fa5dd8906ea89895470b1ad1f56f1248f Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Wed, 10 Feb 2021 16:18:47 +0100 Subject: [PATCH 40/44] Add CLOCK_INTERVAL_TIME and ShortTimer IntervalTimer --- Firmware/Configuration_adv.h | 6 ++++++ Firmware/ultralcd.cpp | 16 +++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Firmware/Configuration_adv.h b/Firmware/Configuration_adv.h index 7a9a4929a..8895eef68 100644 --- a/Firmware/Configuration_adv.h +++ b/Firmware/Configuration_adv.h @@ -338,6 +338,12 @@ const unsigned int dropsegments=5; //everything with less than this number of st // Control heater 0 and heater 1 in parallel. //#define HEATERS_PARALLEL +//LCD status clock interval timer to switch between +// print time +// remaining print time +// and time to change/pause/interaction +#define CLOCK_INTERVAL_TIME 5000 + //=========================================================================== //=============================Buffers ============================ //=========================================================================== diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 057d7dea9..98f4dccd4 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -673,6 +673,7 @@ void lcdui_print_time(void) { //if remaining print time estimation is available print it else print elapsed time int chars = 0; + ShortTimer IntervalTimer; if ((PRINTER_ACTIVE) && (starttime != 0)) { uint16_t print_t = 0; @@ -708,17 +709,18 @@ void lcdui_print_time(void) } #endif //TMC2130 - if (print_tc != 0) - { - print_t = print_tc; - suff = 'C'; - } - else if (print_tr != 0) + if (print_tr != 0) { print_t = print_tr; suff = 'R'; } - else + else if (print_tc != 0) + { + print_t = print_tc; + suff = 'C'; + } + + if (print_tr == 0) { print_t = _millis() / 60000 - starttime / 60000; } From cf982b0d4dee71cae62d0a673b8efc2f2c64ced5 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Thu, 11 Feb 2021 10:20:06 +0100 Subject: [PATCH 41/44] Fix timer issue The remaining time stays for ~5 seconds while the change time stays just for ~1 second --- Firmware/ultralcd.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 98f4dccd4..1653e61a2 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -673,7 +673,6 @@ void lcdui_print_time(void) { //if remaining print time estimation is available print it else print elapsed time int chars = 0; - ShortTimer IntervalTimer; if ((PRINTER_ACTIVE) && (starttime != 0)) { uint16_t print_t = 0; @@ -681,6 +680,8 @@ void lcdui_print_time(void) uint16_t print_tc = 0; char suff = ' '; char suff_doubt = ' '; + static ShortTimer IntervalTimer; + #ifdef TMC2130 if (SilentModeMenu != SILENT_MODE_OFF) @@ -714,10 +715,15 @@ void lcdui_print_time(void) print_t = print_tr; suff = 'R'; } - else if (print_tc != 0) + + if (print_tc != 0) { - print_t = print_tc; - suff = 'C'; + if (IntervalTimer.expired(5000)) + { + print_t = print_tc; + suff = 'C'; + IntervalTimer.start(); + } } if (print_tr == 0) From d2e60aee90fca67c01338ef4a49ad656a6164719 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Thu, 11 Feb 2021 10:45:26 +0100 Subject: [PATCH 42/44] Use `CLOCK_INTERVAL_TIME` --- Firmware/ultralcd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 1653e61a2..8a8f6b793 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -718,7 +718,7 @@ void lcdui_print_time(void) if (print_tc != 0) { - if (IntervalTimer.expired(5000)) + if (IntervalTimer.expired(CLOCK_INTERVAL_TIME)) { print_t = print_tc; suff = 'C'; From f810047a5c9cd4d9cbeea5947cc84183986f01fd Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Fri, 12 Feb 2021 11:29:47 +0100 Subject: [PATCH 43/44] Switch between Remaing and Change time every few seconds - If `M73` `R,S,C,D` values set the LCD Info screen clock switchs between Remaining and Change time - If Remaining time is 0 while Change time is >0 the clock switchs between Change time and actual printing time - If Change is 0 while Remaining time is >0 the clock shows the Remaining time - If both are 0 the clock shows the actual printing time - `M73 C` values are shown in "Normal" mode - `M73 D` values are shown in "Stealth" mode - Changing the speed will try to calculate the espected times and show `?` behind `R` or `C` --- Firmware/Configuration_adv.h | 3 +-- Firmware/ultralcd.cpp | 43 ++++++++++++++++++++---------------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/Firmware/Configuration_adv.h b/Firmware/Configuration_adv.h index 8895eef68..ee12716e6 100644 --- a/Firmware/Configuration_adv.h +++ b/Firmware/Configuration_adv.h @@ -339,10 +339,9 @@ const unsigned int dropsegments=5; //everything with less than this number of st //#define HEATERS_PARALLEL //LCD status clock interval timer to switch between -// print time // remaining print time // and time to change/pause/interaction -#define CLOCK_INTERVAL_TIME 5000 +#define CLOCK_INTERVAL_TIME 5 //=========================================================================== //=============================Buffers ============================ diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 8a8f6b793..422566f18 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -57,7 +57,7 @@ int scrollstuff = 0; char longFilenameOLD[LONG_FILENAME_LENGTH]; - +int clock_interval = 0; static void lcd_sd_updir(); static void lcd_mesh_bed_leveling_settings(); @@ -680,53 +680,58 @@ void lcdui_print_time(void) uint16_t print_tc = 0; char suff = ' '; char suff_doubt = ' '; - static ShortTimer IntervalTimer; - - #ifdef TMC2130 +#ifdef TMC2130 if (SilentModeMenu != SILENT_MODE_OFF) { if (print_time_remaining_silent != PRINT_TIME_REMAINING_INIT) { print_tr = print_time_remaining_silent; } +//#ifdef CLOCK_INTERVAL_TIME if (print_time_to_change_silent != PRINT_TIME_REMAINING_INIT) { print_tc = print_time_to_change_silent; } +//#endif //CLOCK_INTERVAL_TIME } else { - #endif //TMC2130 +#endif //TMC2130 if (print_time_remaining_normal != PRINT_TIME_REMAINING_INIT) { print_tr = print_time_remaining_normal; } +//#ifdef CLOCK_INTERVAL_TIME if (print_time_to_change_normal != PRINT_TIME_REMAINING_INIT) { print_tc = print_time_to_change_normal; } - #ifdef TMC2130 +//#endif //CLOCK_INTERVAL_TIME +#ifdef TMC2130 } - #endif //TMC2130 +#endif //TMC2130 +//#ifdef CLOCK_INTERVAL_TIME + if (clock_interval == CLOCK_INTERVAL_TIME*2) + { + clock_interval = 0; + } + clock_interval++; + + if (print_tc != 0 && clock_interval > CLOCK_INTERVAL_TIME) + { + print_t = print_tc; + suff = 'C'; + } + else +//#endif //CLOCK_INTERVAL_TIME if (print_tr != 0) { print_t = print_tr; suff = 'R'; } - - if (print_tc != 0) - { - if (IntervalTimer.expired(CLOCK_INTERVAL_TIME)) - { - print_t = print_tc; - suff = 'C'; - IntervalTimer.start(); - } - } - - if (print_tr == 0) + else { print_t = _millis() / 60000 - starttime / 60000; } From c95a8e13d76ddefe6b1c4a1bf32dcfec051e9987 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Fri, 12 Feb 2021 11:47:02 +0100 Subject: [PATCH 44/44] Fix indentations to 4 spaces per tab --- Firmware/Marlin_main.cpp | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 2b89958cc..c23a1c15a 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -11663,28 +11663,28 @@ void print_mesh_bed_leveling_table() uint8_t calc_percent_done() { - //in case that we have information from M73 gcode return percentage counted by slicer, else return percentage counted as byte_printed/filesize - uint8_t percent_done = 0; + //in case that we have information from M73 gcode return percentage counted by slicer, else return percentage counted as byte_printed/filesize + uint8_t percent_done = 0; #ifdef TMC2130 - if (SilentModeMenu == SILENT_MODE_OFF && print_percent_done_normal <= 100) - { - percent_done = print_percent_done_normal; - } - else if (print_percent_done_silent <= 100) - { - percent_done = print_percent_done_silent; - } + if (SilentModeMenu == SILENT_MODE_OFF && print_percent_done_normal <= 100) + { + percent_done = print_percent_done_normal; + } + else if (print_percent_done_silent <= 100) + { + percent_done = print_percent_done_silent; + } #else - if (print_percent_done_normal <= 100) - { - percent_done = print_percent_done_normal; - } + if (print_percent_done_normal <= 100) + { + percent_done = print_percent_done_normal; + } #endif //TMC2130 - else - { - percent_done = card.percentDone(); - } - return percent_done; + else + { + percent_done = card.percentDone(); + } + return percent_done; } static void print_time_remaining_init()