Merge pull request #10479 from thinkyhead/bf2_creality_power_loss_resume
[2.0.x] Creality3D Power-Loss Recovery
This commit is contained in:
		| @@ -67,7 +67,7 @@ script: | ||||
|   - opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT EEPROM_SETTINGS | ||||
|   - opt_enable BLINKM PCA9632 RGB_LED NEOPIXEL_LED AUTO_POWER_CONTROL NOZZLE_PARK_FEATURE FILAMENT_RUNOUT_SENSOR | ||||
|   - opt_enable AUTO_BED_LEVELING_LINEAR Z_MIN_PROBE_REPEATABILITY_TEST DEBUG_LEVELING_FEATURE SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE | ||||
|   - opt_enable_adv ARC_P_CIRCLES ADVANCED_PAUSE_FEATURE CNC_WORKSPACE_PLANES CNC_COORDINATE_SYSTEMS | ||||
|   - opt_enable_adv ARC_P_CIRCLES ADVANCED_PAUSE_FEATURE CNC_WORKSPACE_PLANES CNC_COORDINATE_SYSTEMS POWER_LOSS_RECOVERY | ||||
|   - opt_enable_adv FWRETRACT MAX7219_DEBUG LED_CONTROL_MENU CASE_LIGHT_ENABLE CASE_LIGHT_USE_NEOPIXEL CODEPENDENT_XY_HOMING | ||||
|   - opt_set GRID_MAX_POINTS_X 16 | ||||
|   - opt_set_adv FANMUX0_PIN 53 | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -126,6 +126,10 @@ | ||||
|   #include "feature/pause.h" | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|   #include "feature/power_loss_recovery.h" | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(FILAMENT_RUNOUT_SENSOR) | ||||
|   #include "feature/runout.h" | ||||
| #endif | ||||
| @@ -876,6 +880,10 @@ void setup() { | ||||
|     pe_magnet_init(); | ||||
|   #endif | ||||
|  | ||||
|   #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|     do_print_job_recovery(); | ||||
|   #endif | ||||
|  | ||||
|   #if ENABLED(USE_WATCHDOG) // Reinit watchdog after HAL_get_reset_source call | ||||
|     watchdog_init(); | ||||
|   #endif | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -556,6 +556,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -568,6 +568,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -557,6 +557,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -557,6 +557,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -557,6 +557,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -557,6 +557,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -557,6 +557,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -557,6 +557,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -562,6 +562,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -557,6 +557,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -555,6 +555,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
| @@ -556,6 +556,16 @@ | ||||
|   // Add an option in the menu to run all auto#.g files | ||||
|   //#define MENU_ADDAUTOSTART | ||||
|  | ||||
|   /** | ||||
|    * Continue after Power-Loss (Creality3D) | ||||
|    * | ||||
|    * Store the current state to the SD Card at the start of each layer | ||||
|    * during SD printing. If the recovery file is found at boot time, present | ||||
|    * an option on the LCD screen to continue the print from the last-known | ||||
|    * point in the file. | ||||
|    */ | ||||
|   //#define POWER_LOSS_RECOVERY | ||||
|  | ||||
|   /** | ||||
|    * Sort SD file listings in alphabetical order. | ||||
|    * | ||||
|   | ||||
							
								
								
									
										235
									
								
								Marlin/src/feature/power_loss_recovery.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										235
									
								
								Marlin/src/feature/power_loss_recovery.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,235 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * | ||||
|  * Based on Sprinter and grbl. | ||||
|  * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * power_loss_recovery.cpp - Resume an SD print after power-loss | ||||
|  */ | ||||
|  | ||||
| #include "../inc/MarlinConfigPre.h" | ||||
|  | ||||
| #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|  | ||||
| #include "power_loss_recovery.h" | ||||
|  | ||||
| #include "../lcd/ultralcd.h" | ||||
| #include "../gcode/queue.h" | ||||
| #include "../module/planner.h" | ||||
| #include "../module/printcounter.h" | ||||
| #include "../module/temperature.h" | ||||
| #include "../sd/cardreader.h" | ||||
| #include "../core/serial.h" | ||||
|  | ||||
| // Recovery data | ||||
| job_recovery_info_t job_recovery_info; | ||||
| JobRecoveryPhase job_recovery_phase = JOB_RECOVERY_IDLE; | ||||
| uint8_t job_recovery_commands_count; //=0 | ||||
| char job_recovery_commands[BUFSIZE + APPEND_CMD_COUNT][MAX_CMD_SIZE]; | ||||
|  | ||||
| // Private | ||||
| static char sd_filename[MAXPATHNAMELENGTH]; | ||||
|  | ||||
| #if ENABLED(DEBUG_POWER_LOSS_RECOVERY) | ||||
|   void debug_print_job_recovery(const bool recovery) { | ||||
|     SERIAL_PROTOCOLPAIR("valid_head:", (int)job_recovery_info.valid_head); | ||||
|     SERIAL_PROTOCOLLNPAIR(" valid_foot:", (int)job_recovery_info.valid_foot); | ||||
|     if (job_recovery_info.valid_head) { | ||||
|       if (job_recovery_info.valid_head == job_recovery_info.valid_foot) { | ||||
|         SERIAL_PROTOCOLPGM("current_position"); | ||||
|         LOOP_XYZE(i) SERIAL_PROTOCOLPAIR(": ", job_recovery_info.current_position[i]); | ||||
|         SERIAL_EOL(); | ||||
|         SERIAL_PROTOCOLLNPAIR("feedrate: ", job_recovery_info.feedrate); | ||||
|         SERIAL_PROTOCOLPGM("target_temperature"); | ||||
|         HOTEND_LOOP() SERIAL_PROTOCOLPAIR(": ", job_recovery_info.target_temperature[e]); | ||||
|         SERIAL_EOL(); | ||||
|         SERIAL_PROTOCOLPGM("fanSpeeds"); | ||||
|         for(uint8_t i = 0; i < FAN_COUNT; i++) SERIAL_PROTOCOLPAIR(": ", job_recovery_info.fanSpeeds[i]); | ||||
|         SERIAL_EOL(); | ||||
|         #if HAS_LEVELING | ||||
|           SERIAL_PROTOCOLPAIR("leveling: ", int(job_recovery_info.leveling)); | ||||
|           SERIAL_PROTOCOLLNPAIR(" fade: ", int(job_recovery_info.fade)); | ||||
|         #endif | ||||
|         SERIAL_PROTOCOLLNPAIR("target_temperature_bed: ", job_recovery_info.target_temperature_bed); | ||||
|         SERIAL_PROTOCOLLNPAIR("cmd_queue_index_r: ", job_recovery_info.cmd_queue_index_r); | ||||
|         SERIAL_PROTOCOLLNPAIR("commands_in_queue: ", job_recovery_info.commands_in_queue); | ||||
|         if (recovery) | ||||
|           for (uint8_t i = 0; i < job_recovery_commands_count; i++) SERIAL_PROTOCOLLNPAIR("> ", job_recovery_commands[i]); | ||||
|         else | ||||
|           for (uint8_t i = 0; i < job_recovery_info.commands_in_queue; i++) SERIAL_PROTOCOLLNPAIR("> ", job_recovery_info.command_queue[i]); | ||||
|         SERIAL_PROTOCOLLNPAIR("sd_filename: ", sd_filename); | ||||
|         SERIAL_PROTOCOLLNPAIR("sdpos: ", job_recovery_info.sdpos); | ||||
|         SERIAL_PROTOCOLLNPAIR("print_job_elapsed: ", job_recovery_info.print_job_elapsed); | ||||
|       } | ||||
|       else | ||||
|         SERIAL_PROTOCOLLNPGM("INVALID DATA"); | ||||
|     } | ||||
|   } | ||||
| #endif // DEBUG_POWER_LOSS_RECOVERY | ||||
|  | ||||
| /** | ||||
|  * Check for Print Job Recovery | ||||
|  * If the file has a saved state, populate the job_recovery_commands queue | ||||
|  */ | ||||
| void do_print_job_recovery() { | ||||
|   //if (job_recovery_commands_count > 0) return; | ||||
|   memset(&job_recovery_info, 0, sizeof(job_recovery_info)); | ||||
|   ZERO(job_recovery_commands); | ||||
|  | ||||
|   if (!card.cardOK) card.initsd(); | ||||
|  | ||||
|   if (card.cardOK) { | ||||
|  | ||||
|     #if ENABLED(DEBUG_POWER_LOSS_RECOVERY) | ||||
|       SERIAL_PROTOCOLLNPAIR("Init job recovery info. Size: ", (int)sizeof(job_recovery_info)); | ||||
|     #endif | ||||
|  | ||||
|     if (card.jobRecoverFileExists()) { | ||||
|       card.openJobRecoveryFile(true); | ||||
|       card.loadJobRecoveryInfo(); | ||||
|       card.closeJobRecoveryFile(); | ||||
|       //card.removeJobRecoveryFile(); | ||||
|  | ||||
|       if (job_recovery_info.valid_head && job_recovery_info.valid_head == job_recovery_info.valid_foot) { | ||||
|  | ||||
|         uint8_t ind = 0; | ||||
|  | ||||
|         #if HAS_LEVELING | ||||
|           strcpy_P(job_recovery_commands[ind++], PSTR("M420 S0 Z0"));               // Leveling off before G92 or G28 | ||||
|         #endif | ||||
|  | ||||
|         strcpy_P(job_recovery_commands[ind++], PSTR("G92.0 Z0"));                   // Ensure Z is equal to 0 | ||||
|         strcpy_P(job_recovery_commands[ind++], PSTR("G1 Z2"));                      // Raise Z by 2mm (we hope!) | ||||
|         strcpy_P(job_recovery_commands[ind++], PSTR("G28 R0" | ||||
|           #if !IS_KINEMATIC | ||||
|             " X Y"                                                                  // Home X and Y for Cartesian | ||||
|           #endif | ||||
|         )); | ||||
|  | ||||
|         #if HAS_LEVELING | ||||
|           // Restore leveling state before G92 sets Z | ||||
|           // This ensures the steppers correspond to the native Z | ||||
|           sprintf_P(job_recovery_commands[ind++], PSTR("M420 S%i Z%s"), int(job_recovery_info.leveling), job_recovery_info.fade); | ||||
|         #endif | ||||
|  | ||||
|         char str_1[16], str_2[16]; | ||||
|         dtostrf(job_recovery_info.current_position[Z_AXIS] + 2, 1, 3, str_1); | ||||
|         dtostrf(job_recovery_info.current_position[E_AXIS] | ||||
|           #if ENABLED(SAVE_EACH_CMD_MODE) | ||||
|             - 5 | ||||
|           #endif | ||||
|           , 1, 3, str_2 | ||||
|         ); | ||||
|         sprintf_P(job_recovery_commands[ind++], PSTR("G92.0 Z%s E%s"), str_1, str_2); // Current Z + 2 and E | ||||
|  | ||||
|         strcpy_P(job_recovery_commands[ind++], PSTR("M117 Continuing...")); | ||||
|  | ||||
|         uint8_t r = job_recovery_info.cmd_queue_index_r; | ||||
|         while (job_recovery_info.commands_in_queue) { | ||||
|           strcpy(job_recovery_commands[ind++], job_recovery_info.command_queue[r]); | ||||
|           job_recovery_info.commands_in_queue--; | ||||
|           r = (r + 1) % BUFSIZE; | ||||
|         } | ||||
|  | ||||
|         job_recovery_commands_count = ind; | ||||
|  | ||||
|         #if ENABLED(DEBUG_POWER_LOSS_RECOVERY) | ||||
|           debug_print_job_recovery(true); | ||||
|         #endif | ||||
|  | ||||
|         card.openFile(sd_filename, true); | ||||
|         card.setIndex(job_recovery_info.sdpos); | ||||
|       } | ||||
|       else { | ||||
|         if (job_recovery_info.valid_head != job_recovery_info.valid_foot) | ||||
|           LCD_ALERTMESSAGEPGM("INVALID DATA"); | ||||
|         memset(&job_recovery_info, 0, sizeof(job_recovery_info)); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Save the current machine state to the "bin" file | ||||
|  */ | ||||
| void save_job_recovery_info() { | ||||
|   #if SAVE_INFO_INTERVAL_MS > 0 | ||||
|     static millis_t next_save_ms; // = 0;  // Init on reset | ||||
|     millis_t ms = millis(); | ||||
|   #endif | ||||
|   if ( | ||||
|     #if SAVE_INFO_INTERVAL_MS > 0 | ||||
|       ELAPSED(ms, next_save_ms) || | ||||
|     #endif | ||||
|     #if ENABLED(SAVE_EACH_CMD_MODE) | ||||
|       true | ||||
|     #else | ||||
|       (current_position[Z_AXIS] > 0 && current_position[Z_AXIS] > job_recovery_info.current_position[Z_AXIS]) | ||||
|     #endif | ||||
|   ) { | ||||
|     #if SAVE_INFO_INTERVAL_MS > 0 | ||||
|       next_save_ms = ms + SAVE_INFO_INTERVAL_MS; | ||||
|     #endif | ||||
|  | ||||
|     // Head and foot will match if valid data was saved | ||||
|     if (!++job_recovery_info.valid_head) ++job_recovery_info.valid_head; // non-zero in sequence | ||||
|     job_recovery_info.valid_foot = job_recovery_info.valid_head; | ||||
|  | ||||
|     // Machine state | ||||
|     COPY(job_recovery_info.current_position, current_position); | ||||
|     job_recovery_info.feedrate = feedrate_mm_s; | ||||
|     COPY(job_recovery_info.target_temperature, thermalManager.target_temperature); | ||||
|     job_recovery_info.target_temperature_bed = thermalManager.target_temperature_bed; | ||||
|     COPY(job_recovery_info.fanSpeeds, fanSpeeds); | ||||
|  | ||||
|     #if HAS_LEVELING | ||||
|       job_recovery_info.leveling = planner.leveling_active; | ||||
|       job_recovery_info.fade = ( | ||||
|         #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) | ||||
|           planner.z_fade_height | ||||
|         #else | ||||
|           0 | ||||
|         #endif | ||||
|       ); | ||||
|     #endif | ||||
|  | ||||
|     // Commands in the queue | ||||
|     job_recovery_info.cmd_queue_index_r = cmd_queue_index_r; | ||||
|     job_recovery_info.commands_in_queue = commands_in_queue; | ||||
|     COPY(job_recovery_info.command_queue, command_queue); | ||||
|  | ||||
|     // Elapsed print job time | ||||
|     job_recovery_info.print_job_elapsed = print_job_timer.duration() * 1000UL; | ||||
|  | ||||
|     // SD file position | ||||
|     card.getAbsFilename(sd_filename); | ||||
|     job_recovery_info.sdpos = card.getIndex(); | ||||
|  | ||||
|     #if ENABLED(DEBUG_POWER_LOSS_RECOVERY) | ||||
|       SERIAL_PROTOCOLLNPGM("Saving job_recovery_info"); | ||||
|       debug_print_job_recovery(false); | ||||
|     #endif | ||||
|  | ||||
|     card.openJobRecoveryFile(false); | ||||
|     (void)card.saveJobRecoveryInfo(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| #endif // POWER_LOSS_RECOVERY | ||||
							
								
								
									
										86
									
								
								Marlin/src/feature/power_loss_recovery.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								Marlin/src/feature/power_loss_recovery.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * | ||||
|  * Based on Sprinter and grbl. | ||||
|  * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * power_loss_recovery.h - Resume an SD print after power-loss | ||||
|  */ | ||||
|  | ||||
| #ifndef _POWER_LOSS_RECOVERY_H_ | ||||
| #define _POWER_LOSS_RECOVERY_H_ | ||||
|  | ||||
| #include "../sd/cardreader.h" | ||||
| #include "../core/types.h" | ||||
| #include "../inc/MarlinConfigPre.h" | ||||
|  | ||||
| #define SAVE_INFO_INTERVAL_MS 0 | ||||
| //#define SAVE_EACH_CMD_MODE | ||||
| //#define DEBUG_POWER_LOSS_RECOVERY | ||||
|  | ||||
| typedef struct { | ||||
|   uint8_t valid_head; | ||||
|  | ||||
|   // Machine state | ||||
|   float current_position[NUM_AXIS], feedrate; | ||||
|   int16_t target_temperature[HOTENDS], | ||||
|           target_temperature_bed, | ||||
|           fanSpeeds[FAN_COUNT]; | ||||
|  | ||||
|   #if HAS_LEVELING | ||||
|     bool leveling; | ||||
|     float fade; | ||||
|   #endif | ||||
|  | ||||
|   // Command queue | ||||
|   uint8_t cmd_queue_index_r, commands_in_queue; | ||||
|   char command_queue[BUFSIZE][MAX_CMD_SIZE]; | ||||
|  | ||||
|   // SD File position | ||||
|   uint32_t sdpos; | ||||
|  | ||||
|   // Job elapsed time | ||||
|   millis_t print_job_elapsed; | ||||
|  | ||||
|   uint8_t valid_foot; | ||||
| } job_recovery_info_t; | ||||
|  | ||||
| extern job_recovery_info_t job_recovery_info; | ||||
|  | ||||
| enum JobRecoveryPhase : unsigned char { | ||||
|   JOB_RECOVERY_IDLE, | ||||
|   JOB_RECOVERY_MAYBE, | ||||
|   JOB_RECOVERY_YES | ||||
| }; | ||||
| extern JobRecoveryPhase job_recovery_phase; | ||||
|  | ||||
| #if HAS_LEVELING | ||||
|   #define APPEND_CMD_COUNT 7 | ||||
| #else | ||||
|   #define APPEND_CMD_COUNT 5 | ||||
| #endif | ||||
|  | ||||
| extern char job_recovery_commands[BUFSIZE + APPEND_CMD_COUNT][MAX_CMD_SIZE]; | ||||
| extern uint8_t job_recovery_commands_count; | ||||
|  | ||||
| void do_print_job_recovery(); | ||||
| void save_job_recovery_info(); | ||||
|  | ||||
| #endif // _POWER_LOSS_RECOVERY_H_ | ||||
| @@ -152,7 +152,9 @@ | ||||
|  *  None  Home to all axes with no parameters. | ||||
|  *        With QUICK_HOME enabled XY will home together, then Z. | ||||
|  * | ||||
|  * Cartesian parameters | ||||
|  *  Rn  Raise by n mm/inches before homing | ||||
|  * | ||||
|  * Cartesian/SCARA parameters | ||||
|  * | ||||
|  *  X   Home to the X endstop | ||||
|  *  Y   Home to the Y endstop | ||||
| @@ -226,11 +228,12 @@ void GcodeSuite::G28(const bool always_home_all) { | ||||
|  | ||||
|     #endif | ||||
|  | ||||
|     const float z_homing_height = ( | ||||
|       #if ENABLED(UNKNOWN_Z_NO_RAISE) | ||||
|       const float z_homing_height = axis_known_position[Z_AXIS] ? Z_HOMING_HEIGHT : 0; | ||||
|     #else | ||||
|       constexpr float z_homing_height = Z_HOMING_HEIGHT; | ||||
|         !axis_known_position[Z_AXIS] ? 0 : | ||||
|       #endif | ||||
|           (parser.seenval('R') ? parser.value_linear_units() : Z_HOMING_HEIGHT) | ||||
|     ); | ||||
|   | ||||
|     if (z_homing_height && (home_all || homeX || homeY)) { | ||||
|       // Raise Z before homing any other axes and z is not already high enough (never lower z) | ||||
|   | ||||
| @@ -25,6 +25,7 @@ | ||||
| #if ENABLED(M100_FREE_MEMORY_WATCHER) | ||||
|  | ||||
| #include "../gcode.h" | ||||
| #include "../queue.h" | ||||
| #include "../../libs/hex_print_routines.h" | ||||
|  | ||||
| #include "../../Marlin.h" // for idle() | ||||
| @@ -59,8 +60,6 @@ | ||||
|  | ||||
| #define TEST_BYTE ((char) 0xE5) | ||||
|  | ||||
| extern char command_queue[BUFSIZE][MAX_CMD_SIZE]; | ||||
|  | ||||
| extern char* __brkval; | ||||
| extern size_t  __heap_start, __heap_end, __flp; | ||||
| extern char __bss_end; | ||||
|   | ||||
| @@ -37,6 +37,10 @@ | ||||
|   #include "../feature/leds/leds.h" | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|   #include "../feature/power_loss_recovery.h" | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * GCode line number handling. Hosts may opt to include line numbers when | ||||
|  * sending commands to Marlin, and lines will be checked for sequentiality. | ||||
| @@ -115,7 +119,7 @@ inline void _commit_command(bool say_ok | ||||
|  * Return true if the command was successfully added. | ||||
|  * Return false for a full buffer, or if the 'command' is a comment. | ||||
|  */ | ||||
| inline bool _enqueuecommand(const char* cmd, bool say_ok | ||||
| inline bool _enqueuecommand(const char* cmd, bool say_ok=false | ||||
|   #if NUM_SERIAL > 1 | ||||
|     , int16_t port = -1 | ||||
|   #endif | ||||
| @@ -133,8 +137,8 @@ inline bool _enqueuecommand(const char* cmd, bool say_ok | ||||
| /** | ||||
|  * Enqueue with Serial Echo | ||||
|  */ | ||||
| bool enqueue_and_echo_command(const char* cmd, bool say_ok/*=false*/) { | ||||
|   if (_enqueuecommand(cmd, say_ok)) { | ||||
| bool enqueue_and_echo_command(const char* cmd) { | ||||
|   if (_enqueuecommand(cmd)) { | ||||
|     SERIAL_ECHO_START(); | ||||
|     SERIAL_ECHOPAIR(MSG_ENQUEUEING, cmd); | ||||
|     SERIAL_CHAR('"'); | ||||
| @@ -486,6 +490,22 @@ inline void get_serial_commands() { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|  | ||||
|     inline bool drain_job_recovery_commands() { | ||||
|       static uint8_t job_recovery_commands_index = 0; // Resets on reboot | ||||
|       if (job_recovery_commands_count) { | ||||
|         if (_enqueuecommand(job_recovery_commands[job_recovery_commands_index])) { | ||||
|           ++job_recovery_commands_index; | ||||
|           if (!--job_recovery_commands_count) job_recovery_phase = JOB_RECOVERY_IDLE; | ||||
|         } | ||||
|         return true; | ||||
|       } | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|   #endif | ||||
|  | ||||
| #endif // SDSUPPORT | ||||
|  | ||||
| /** | ||||
| @@ -501,6 +521,11 @@ void get_available_commands() { | ||||
|  | ||||
|   get_serial_commands(); | ||||
|  | ||||
|   #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|     // Commands for power-loss recovery take precedence | ||||
|     if (job_recovery_phase == JOB_RECOVERY_YES && drain_job_recovery_commands()) return; | ||||
|   #endif | ||||
|  | ||||
|   #if ENABLED(SDSUPPORT) | ||||
|     get_sdcard_commands(); | ||||
|   #endif | ||||
| @@ -543,8 +568,12 @@ void advance_command_queue() { | ||||
|           ok_to_send(); | ||||
|       } | ||||
|     } | ||||
|     else | ||||
|     else { | ||||
|       gcode.process_next_command(); | ||||
|       #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|         if (card.cardOK && card.sdprinting) save_job_recovery_info(); | ||||
|       #endif | ||||
|     } | ||||
|  | ||||
|   #else | ||||
|  | ||||
|   | ||||
| @@ -95,7 +95,7 @@ void enqueue_and_echo_commands_P(const char * const pgcode); | ||||
| /** | ||||
|  * Enqueue with Serial Echo | ||||
|  */ | ||||
| bool enqueue_and_echo_command(const char* cmd, bool say_ok=false); | ||||
| bool enqueue_and_echo_command(const char* cmd); | ||||
|  | ||||
| #define HAS_LCD_QUEUE_NOW (ENABLED(MALYAN_LCD) || (ENABLED(ULTIPANEL) && (ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(PID_AUTOTUNE_MENU) || ENABLED(ADVANCED_PAUSE_FEATURE)))) | ||||
| #define HAS_QUEUE_NOW (ENABLED(SDSUPPORT) || HAS_LCD_QUEUE_NOW) | ||||
|   | ||||
| @@ -29,13 +29,16 @@ | ||||
| #include "../../module/printcounter.h" | ||||
| #include "../../module/stepper.h" | ||||
|  | ||||
| #if ENABLED(PARK_HEAD_ON_PAUSE) | ||||
|   #include "../../feature/pause.h" | ||||
|   #include "../queue.h" | ||||
| #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|   #include "../../feature/power_loss_recovery.h" | ||||
| #endif | ||||
|  | ||||
| #if NUM_SERIAL > 1 | ||||
|   #include "../../gcode/queue.h" | ||||
| #if ENABLED(PARK_HEAD_ON_PAUSE) | ||||
|   #include "../../feature/pause.h" | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(PARK_HEAD_ON_PAUSE) || NUM_SERIAL > 1 | ||||
|   #include "../queue.h" | ||||
| #endif | ||||
|  | ||||
| /** | ||||
| @@ -78,6 +81,10 @@ void GcodeSuite::M23() { | ||||
|  * M24: Start or Resume SD Print | ||||
|  */ | ||||
| void GcodeSuite::M24() { | ||||
|   #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|     card.removeJobRecoveryFile(); | ||||
|   #endif | ||||
|  | ||||
|   #if ENABLED(PARK_HEAD_ON_PAUSE) | ||||
|     resume_print(); | ||||
|   #endif | ||||
|   | ||||
| @@ -1334,7 +1334,7 @@ | ||||
| #define GRID_MAX_POINTS ((GRID_MAX_POINTS_X) * (GRID_MAX_POINTS_Y)) | ||||
|  | ||||
| // Add commands that need sub-codes to this list | ||||
| #define USE_GCODE_SUBCODES ENABLED(G38_PROBE_TARGET) || ENABLED(CNC_COORDINATE_SYSTEMS) | ||||
| #define USE_GCODE_SUBCODES ENABLED(G38_PROBE_TARGET) || ENABLED(CNC_COORDINATE_SYSTEMS) || ENABLED(POWER_LOSS_RECOVERY) | ||||
|  | ||||
| // Parking Extruder | ||||
| #if ENABLED(PARKING_EXTRUDER) | ||||
|   | ||||
| @@ -462,7 +462,7 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE, | ||||
|   #elif ENABLED(BABYSTEP_ZPROBE_OFFSET) && !HAS_BED_PROBE | ||||
|     #error "BABYSTEP_ZPROBE_OFFSET requires a probe." | ||||
|   #elif ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY) && !ENABLED(DOGLCD) | ||||
|     #error "BABYSTEP_ZPROBE_GFX_OVERLAY requires a DOGLCD." | ||||
|     #error "BABYSTEP_ZPROBE_GFX_OVERLAY requires a Graphical LCD." | ||||
|   #elif ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY) && !ENABLED(BABYSTEP_ZPROBE_OFFSET) | ||||
|     #error "BABYSTEP_ZPROBE_GFX_OVERLAY requires a BABYSTEP_ZPROBE_OFFSET." | ||||
|   #endif | ||||
| @@ -1708,4 +1708,8 @@ static_assert(COUNT(sanity_arr_3) <= XYZE_N, "DEFAULT_MAX_ACCELERATION has too m | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(POWER_LOSS_RECOVERY) && !ENABLED(ULTIPANEL) | ||||
|   #error "POWER_LOSS_RECOVERY currently requires an LCD Controller." | ||||
| #endif | ||||
|  | ||||
| #endif // _SANITYCHECK_H_ | ||||
|   | ||||
| @@ -302,7 +302,7 @@ void process_lcd_s_command(const char* command) { | ||||
|  | ||||
|     case 'H': | ||||
|       // Home all axis | ||||
|       enqueue_and_echo_command("G28", false); | ||||
|       enqueue_and_echo_commands_P(PSTR("G28")); | ||||
|       break; | ||||
|  | ||||
|     case 'L': { | ||||
|   | ||||
| @@ -43,6 +43,10 @@ | ||||
|   #include "../feature/pause.h" | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|   #include "../feature/power_loss_recovery.h" | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(PRINTCOUNTER) && ENABLED(LCD_INFO_MENU) | ||||
|   #include "../libs/duration_t.h" | ||||
| #endif | ||||
| @@ -862,10 +866,70 @@ void kill_screen(const char* lcd_msg) { | ||||
|       abort_sd_printing = true; | ||||
|       lcd_setstatusPGM(PSTR(MSG_PRINT_ABORTED), -1); | ||||
|       lcd_return_to_status(); | ||||
|  | ||||
|       #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|         card.openJobRecoveryFile(false); | ||||
|         job_recovery_info.valid_head = job_recovery_info.valid_foot = 0; | ||||
|         (void)card.saveJobRecoveryInfo(); | ||||
|         card.closeJobRecoveryFile(); | ||||
|         job_recovery_commands_count = 0; | ||||
|       #endif | ||||
|     } | ||||
|  | ||||
|   #endif // SDSUPPORT | ||||
|  | ||||
|   #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|  | ||||
|     static void lcd_sdcard_recover_job() { | ||||
|       char cmd[20]; | ||||
|  | ||||
|       // Return to status now | ||||
|       lcd_return_to_status(); | ||||
|  | ||||
|       // Turn leveling off and home | ||||
|       enqueue_and_echo_commands_P(PSTR("M420 S0\nG28" | ||||
|         #if !IS_KINEMATIC | ||||
|           " X Y" | ||||
|         #endif | ||||
|       )); | ||||
|  | ||||
|       // Restore the bed temperature | ||||
|       sprintf_P(cmd, PSTR("M190 S%i"), job_recovery_info.target_temperature_bed); | ||||
|       enqueue_and_echo_command(cmd); | ||||
|  | ||||
|       // Restore all hotend temperatures | ||||
|       HOTEND_LOOP() { | ||||
|         sprintf_P(cmd, PSTR("M109 S%i"), job_recovery_info.target_temperature[e]); | ||||
|         enqueue_and_echo_command(cmd); | ||||
|       } | ||||
|  | ||||
|       // Restore print cooling fan speeds | ||||
|       for (uint8_t i = 0; i < FAN_COUNT; i++) { | ||||
|         sprintf_P(cmd, PSTR("M106 P%i S%i"), i, job_recovery_info.fanSpeeds[i]); | ||||
|         enqueue_and_echo_command(cmd); | ||||
|       } | ||||
|  | ||||
|       // Start draining the job recovery command queue | ||||
|       job_recovery_phase = JOB_RECOVERY_YES; | ||||
|  | ||||
|       // Resume the print job timer | ||||
|       if (job_recovery_info.print_job_elapsed) | ||||
|         print_job_timer.resume(job_recovery_info.print_job_elapsed); | ||||
|  | ||||
|       // Start getting commands from SD | ||||
|       card.startFileprint(); | ||||
|     } | ||||
|  | ||||
|     static void lcd_job_recovery_menu() { | ||||
|       defer_return_to_status = true; | ||||
|       START_MENU(); | ||||
|       MENU_ITEM(function, MSG_RESUME_PRINT, lcd_sdcard_recover_job); | ||||
|       MENU_ITEM(function, MSG_STOP_PRINT, lcd_sdcard_stop); | ||||
|       END_MENU(); | ||||
|     } | ||||
|  | ||||
|   #endif // POWER_LOSS_RECOVERY | ||||
|  | ||||
|   #if ENABLED(MENU_ITEM_CASE_LIGHT) | ||||
|  | ||||
|     #include "../feature/caselight.h" | ||||
| @@ -5067,6 +5131,13 @@ void lcd_update() { | ||||
|  | ||||
|   #endif // SDSUPPORT && SD_DETECT_PIN | ||||
|  | ||||
|   #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|     if (job_recovery_commands_count && job_recovery_phase == JOB_RECOVERY_IDLE) { | ||||
|       lcd_goto_screen(lcd_job_recovery_menu); | ||||
|       job_recovery_phase = JOB_RECOVERY_MAYBE; // Waiting for a response | ||||
|     } | ||||
|   #endif | ||||
|  | ||||
|   const millis_t ms = millis(); | ||||
|   if (ELAPSED(ms, next_lcd_update_ms) | ||||
|     #if ENABLED(DOGLCD) | ||||
|   | ||||
| @@ -71,6 +71,15 @@ bool Stopwatch::start() { | ||||
|   else return false; | ||||
| } | ||||
|  | ||||
| void Stopwatch::resume(const millis_t duration) { | ||||
|   #if ENABLED(DEBUG_STOPWATCH) | ||||
|     Stopwatch::debug(PSTR("resume")); | ||||
|   #endif | ||||
|  | ||||
|   reset(); | ||||
|   if ((accumulator = duration)) state = RUNNING; | ||||
| } | ||||
|  | ||||
| void Stopwatch::reset() { | ||||
|   #if ENABLED(DEBUG_STOPWATCH) | ||||
|     Stopwatch::debug(PSTR("reset")); | ||||
| @@ -82,16 +91,8 @@ void Stopwatch::reset() { | ||||
|   accumulator = 0; | ||||
| } | ||||
|  | ||||
| bool Stopwatch::isRunning() { | ||||
|   return (state == RUNNING) ? true : false; | ||||
| } | ||||
|  | ||||
| bool Stopwatch::isPaused() { | ||||
|   return (state == PAUSED) ? true : false; | ||||
| } | ||||
|  | ||||
| millis_t Stopwatch::duration() { | ||||
|   return (((isRunning()) ? millis() : stopTimestamp) | ||||
|   return ((isRunning() ? millis() : stopTimestamp) | ||||
|           - startTimestamp) / 1000UL + accumulator; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -54,10 +54,10 @@ class Stopwatch { | ||||
|     FORCE_INLINE static void init() { reset(); } | ||||
|  | ||||
|     /** | ||||
|      * @brief Stops the stopwatch | ||||
|      * @details Stops the running timer, it will silently ignore the request if | ||||
|      * @brief Stop the stopwatch | ||||
|      * @details Stop the running timer, it will silently ignore the request if | ||||
|      *          no timer is currently running. | ||||
|      * @return true is method was successful | ||||
|      * @return true on success | ||||
|      */ | ||||
|     static bool stop(); | ||||
|  | ||||
| @@ -65,7 +65,7 @@ class Stopwatch { | ||||
|      * @brief Pause the stopwatch | ||||
|      * @details Pause the running timer, it will silently ignore the request if | ||||
|      *          no timer is currently running. | ||||
|      * @return true is method was successful | ||||
|      * @return true on success | ||||
|      */ | ||||
|     static bool pause(); | ||||
|  | ||||
| @@ -73,10 +73,16 @@ class Stopwatch { | ||||
|      * @brief Start the stopwatch | ||||
|      * @details Start the timer, it will silently ignore the request if the | ||||
|      *          timer is already running. | ||||
|      * @return true is method was successful | ||||
|      * @return true on success | ||||
|      */ | ||||
|     static bool start(); | ||||
|  | ||||
|     /** | ||||
|      * @brief Resume the stopwatch | ||||
|      * @details Resume a timer from a given duration | ||||
|      */ | ||||
|     static void resume(const millis_t duration); | ||||
|  | ||||
|     /** | ||||
|      * @brief Reset the stopwatch | ||||
|      * @details Reset all settings to their default values. | ||||
| @@ -88,14 +94,14 @@ class Stopwatch { | ||||
|      * @details Return true if the timer is currently running, false otherwise. | ||||
|      * @return true if stopwatch is running | ||||
|      */ | ||||
|     static bool isRunning(); | ||||
|     FORCE_INLINE static bool isRunning() { return state == RUNNING; } | ||||
|  | ||||
|     /** | ||||
|      * @brief Check if the timer is paused | ||||
|      * @details Return true if the timer is currently paused, false otherwise. | ||||
|      * @return true if stopwatch is paused | ||||
|      */ | ||||
|     static bool isPaused(); | ||||
|     FORCE_INLINE static bool isPaused() { return state == PAUSED; } | ||||
|  | ||||
|     /** | ||||
|      * @brief Get the running time | ||||
|   | ||||
| @@ -33,6 +33,10 @@ | ||||
| #include "../core/language.h" | ||||
| #include "../gcode/queue.h" | ||||
|  | ||||
| #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|   #include "../feature/power_loss_recovery.h" | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(ADVANCED_PAUSE_FEATURE) | ||||
|   #include "../feature/pause.h" | ||||
| #endif | ||||
| @@ -968,6 +972,15 @@ void CardReader::printingHasFinished() { | ||||
|   } | ||||
|   else { | ||||
|     sdprinting = false; | ||||
|  | ||||
|     #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|       openJobRecoveryFile(false); | ||||
|       job_recovery_info.valid_head = job_recovery_info.valid_foot = 0; | ||||
|       (void)saveJobRecoveryInfo(); | ||||
|       closeJobRecoveryFile(); | ||||
|       job_recovery_commands_count = 0; | ||||
|     #endif | ||||
|  | ||||
|     #if ENABLED(SD_FINISHED_STEPPERRELEASE) && defined(SD_FINISHED_RELEASECOMMAND) | ||||
|       stepper.cleaning_buffer_counter = 1; // The command will fire from the Stepper ISR | ||||
|     #endif | ||||
| @@ -1006,4 +1019,46 @@ void CardReader::printingHasFinished() { | ||||
|   } | ||||
| #endif // AUTO_REPORT_SD_STATUS | ||||
|  | ||||
| #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|  | ||||
|   char job_recovery_file_name[4] = "bin"; | ||||
|  | ||||
|   void CardReader::openJobRecoveryFile(const bool read) { | ||||
|     if (!cardOK) return; | ||||
|     if (jobRecoveryFile.isOpen()) return; | ||||
|     if (!jobRecoveryFile.open(&root, job_recovery_file_name, read ? O_READ : O_CREAT | O_WRITE | O_TRUNC | O_SYNC)) { | ||||
|       SERIAL_PROTOCOLPAIR(MSG_SD_OPEN_FILE_FAIL, job_recovery_file_name); | ||||
|       SERIAL_PROTOCOLCHAR('.'); | ||||
|       SERIAL_EOL(); | ||||
|     } | ||||
|     else | ||||
|       SERIAL_PROTOCOLLNPAIR(MSG_SD_WRITE_TO_FILE, job_recovery_file_name); | ||||
|   } | ||||
|  | ||||
|   void CardReader::closeJobRecoveryFile() { jobRecoveryFile.close(); } | ||||
|  | ||||
|   bool CardReader::jobRecoverFileExists() { | ||||
|     return jobRecoveryFile.open(&root, job_recovery_file_name, O_READ); | ||||
|   } | ||||
|  | ||||
|   int16_t CardReader::saveJobRecoveryInfo() { | ||||
|     jobRecoveryFile.seekSet(0); | ||||
|     const int16_t ret = jobRecoveryFile.write(&job_recovery_info, sizeof(job_recovery_info)); | ||||
|     if (ret == -1) SERIAL_PROTOCOLLNPGM("Power-loss file write failed."); | ||||
|     return ret; | ||||
|   } | ||||
|  | ||||
|   int16_t CardReader::loadJobRecoveryInfo() { | ||||
|     return jobRecoveryFile.read(&job_recovery_info, sizeof(job_recovery_info)); | ||||
|   } | ||||
|  | ||||
|   void CardReader::removeJobRecoveryFile() { | ||||
|     if (jobRecoveryFile.remove(&root, job_recovery_file_name)) | ||||
|       SERIAL_PROTOCOLLNPGM("Power-loss file deleted."); | ||||
|     else | ||||
|       SERIAL_PROTOCOLLNPGM("Power-loss file delete failed."); | ||||
|   } | ||||
|  | ||||
| #endif // POWER_LOSS_RECOVERY | ||||
|  | ||||
| #endif // SDSUPPORT | ||||
|   | ||||
| @@ -103,11 +103,21 @@ public: | ||||
|     #endif | ||||
|   #endif | ||||
|  | ||||
|   #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|     void openJobRecoveryFile(const bool read); | ||||
|     void closeJobRecoveryFile(); | ||||
|     bool jobRecoverFileExists(); | ||||
|     int16_t saveJobRecoveryInfo(); | ||||
|     int16_t loadJobRecoveryInfo(); | ||||
|     void removeJobRecoveryFile(); | ||||
|   #endif | ||||
|  | ||||
|   FORCE_INLINE void pauseSDPrint() { sdprinting = false; } | ||||
|   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 void setIndex(long index) { sdpos = index; file.seekSet(index); } | ||||
|   FORCE_INLINE void setIndex(const uint32_t index) { sdpos = index; file.seekSet(index); } | ||||
|   FORCE_INLINE uint32_t getIndex() { return sdpos; } | ||||
|   FORCE_INLINE uint8_t percentDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 99) / 100) : 0; } | ||||
|   FORCE_INLINE char* getWorkDirName() { workDir.getFilename(filename); return filename; } | ||||
|  | ||||
| @@ -191,6 +201,10 @@ private: | ||||
|   SdVolume volume; | ||||
|   SdFile file; | ||||
|  | ||||
|   #if ENABLED(POWER_LOSS_RECOVERY) | ||||
|     SdFile jobRecoveryFile; | ||||
|   #endif | ||||
|  | ||||
|   #define SD_PROCEDURE_DEPTH 1 | ||||
|   #define MAXPATHNAMELENGTH (FILENAME_LENGTH*MAX_DIR_DEPTH + MAX_DIR_DEPTH + 1) | ||||
|   uint8_t file_subcall_ctr; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user