aboutsummaryrefslogtreecommitdiff
path: root/Marlin/src/feature/powerloss.h
diff options
context:
space:
mode:
Diffstat (limited to 'Marlin/src/feature/powerloss.h')
-rw-r--r--Marlin/src/feature/powerloss.h191
1 files changed, 191 insertions, 0 deletions
diff --git a/Marlin/src/feature/powerloss.h b/Marlin/src/feature/powerloss.h
new file mode 100644
index 0000000..25581e1
--- /dev/null
+++ b/Marlin/src/feature/powerloss.h
@@ -0,0 +1,191 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 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 <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+/**
+ * feature/powerloss.h - Resume an SD print after power-loss
+ */
+
+#include "../sd/cardreader.h"
+#include "../gcode/gcode.h"
+
+#include "../inc/MarlinConfig.h"
+
+#if ENABLED(GCODE_REPEAT_MARKERS)
+ #include "../feature/repeat.h"
+#endif
+
+#if ENABLED(MIXING_EXTRUDER)
+ #include "../feature/mixing.h"
+#endif
+
+#if !defined(POWER_LOSS_STATE) && PIN_EXISTS(POWER_LOSS)
+ #define POWER_LOSS_STATE HIGH
+#endif
+
+//#define DEBUG_POWER_LOSS_RECOVERY
+//#define SAVE_EACH_CMD_MODE
+//#define SAVE_INFO_INTERVAL_MS 0
+
+typedef struct {
+ uint8_t valid_head;
+
+ // Machine state
+ xyze_pos_t current_position;
+ uint16_t feedrate;
+ float zraise;
+
+ // Repeat information
+ TERN_(GCODE_REPEAT_MARKERS, Repeat stored_repeat);
+
+ TERN_(HAS_HOME_OFFSET, xyz_pos_t home_offset);
+ TERN_(HAS_POSITION_SHIFT, xyz_pos_t position_shift);
+ TERN_(HAS_MULTI_EXTRUDER, uint8_t active_extruder);
+
+ #if DISABLED(NO_VOLUMETRICS)
+ bool volumetric_enabled;
+ float filament_size[EXTRUDERS];
+ #endif
+
+ TERN_(HAS_HOTEND, int16_t target_temperature[HOTENDS]);
+ TERN_(HAS_HEATED_BED, int16_t target_temperature_bed);
+ TERN_(HAS_FAN, uint8_t fan_speed[FAN_COUNT]);
+
+ TERN_(HAS_LEVELING, float fade);
+
+ #if ENABLED(FWRETRACT)
+ float retract[EXTRUDERS], retract_hop;
+ #endif
+
+ // Mixing extruder and gradient
+ #if ENABLED(MIXING_EXTRUDER)
+ //uint_fast8_t selected_vtool;
+ //mixer_comp_t color[NR_MIXING_VIRTUAL_TOOLS][MIXING_STEPPERS];
+ TERN_(GRADIENT_MIX, gradient_t gradient);
+ #endif
+
+ // SD Filename and position
+ char sd_filename[MAXPATHNAMELENGTH];
+ volatile uint32_t sdpos;
+
+ // Job elapsed time
+ millis_t print_job_elapsed;
+
+ // Relative axis modes
+ uint8_t axis_relative;
+
+ // Misc. Marlin flags
+ struct {
+ bool dryrun:1; // M111 S8
+ bool allow_cold_extrusion:1; // M302 P1
+ TERN_(HAS_LEVELING, bool leveling:1);
+ } flag;
+
+ uint8_t valid_foot;
+
+ bool valid() { return valid_head && valid_head == valid_foot; }
+
+} job_recovery_info_t;
+
+class PrintJobRecovery {
+ public:
+ static const char filename[5];
+
+ static SdFile file;
+ static job_recovery_info_t info;
+
+ static uint8_t queue_index_r; //!< Queue index of the active command
+ static uint32_t cmd_sdpos, //!< SD position of the next command
+ sdpos[BUFSIZE]; //!< SD positions of queued commands
+
+ #if ENABLED(DWIN_CREALITY_LCD)
+ static bool dwin_flag;
+ #endif
+
+ static void init();
+ static void prepare();
+
+ static inline void setup() {
+ #if PIN_EXISTS(POWER_LOSS)
+ #if ENABLED(POWER_LOSS_PULLUP)
+ SET_INPUT_PULLUP(POWER_LOSS_PIN);
+ #elif ENABLED(POWER_LOSS_PULLDOWN)
+ SET_INPUT_PULLDOWN(POWER_LOSS_PIN);
+ #else
+ SET_INPUT(POWER_LOSS_PIN);
+ #endif
+ #endif
+ }
+
+ // Track each command's file offsets
+ static inline uint32_t command_sdpos() { return sdpos[queue_index_r]; }
+ static inline void commit_sdpos(const uint8_t index_w) { sdpos[index_w] = cmd_sdpos; }
+
+ static bool enabled;
+ static void enable(const bool onoff);
+ static void changed();
+
+ static inline bool exists() { return card.jobRecoverFileExists(); }
+ static inline void open(const bool read) { card.openJobRecoveryFile(read); }
+ static inline void close() { file.close(); }
+
+ static void check();
+ static void resume();
+ static void purge();
+
+ static inline void cancel() { purge(); IF_DISABLED(NO_SD_AUTOSTART, card.autofile_begin()); }
+
+ static void load();
+ static void save(const bool force=ENABLED(SAVE_EACH_CMD_MODE), const float zraise=0);
+
+ #if PIN_EXISTS(POWER_LOSS)
+ static inline void outage() {
+ if (enabled && READ(POWER_LOSS_PIN) == POWER_LOSS_STATE)
+ _outage();
+ }
+ #endif
+
+ // The referenced file exists
+ static inline bool interrupted_file_exists() { return card.fileExists(info.sd_filename); }
+
+ static inline bool valid() { return info.valid() && interrupted_file_exists(); }
+
+ #if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
+ static void debug(PGM_P const prefix);
+ #else
+ static inline void debug(PGM_P const) {}
+ #endif
+
+ private:
+ static void write();
+
+ #if ENABLED(BACKUP_POWER_SUPPLY)
+ static void retract_and_lift(const float &zraise);
+ #endif
+
+ #if PIN_EXISTS(POWER_LOSS)
+ friend class GcodeSuite;
+ static void _outage();
+ #endif
+};
+
+extern PrintJobRecovery recovery;