0
0
Fork 0
mirror of https://github.com/MarlinFirmware/Marlin.git synced 2025-02-02 07:00:42 +00:00

🚸 Restore Object Cancel info on Power-Loss Recovery (#27501)

* 🎨 Shorten feature includes
* 🚸 Save Canceled Objects with Power Loss data
This commit is contained in:
Scott Lahteine 2024-10-28 11:17:40 -05:00 committed by GitHub
parent 9e8d561549
commit 3b7aadb359
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 73 additions and 49 deletions

View file

@ -30,23 +30,20 @@
CancelObject cancelable; CancelObject cancelable;
int8_t CancelObject::object_count, // = 0 cancel_state_t CancelObject::state;
CancelObject::active_object = -1;
uint32_t CancelObject::canceled; // = 0x0000
bool CancelObject::skipping; // = false
void CancelObject::set_active_object(const int8_t obj) { void CancelObject::set_active_object(const int8_t obj) {
active_object = obj; state.active_object = obj;
if (WITHIN(obj, 0, 31)) { if (WITHIN(obj, 0, 31)) {
if (obj >= object_count) object_count = obj + 1; if (obj >= state.object_count) state.object_count = obj + 1;
skipping = TEST(canceled, obj); state.skipping = TEST(state.canceled, obj);
} }
else else
skipping = false; state.skipping = false;
#if ALL(HAS_STATUS_MESSAGE, CANCEL_OBJECTS_REPORTING) #if ALL(HAS_STATUS_MESSAGE, CANCEL_OBJECTS_REPORTING)
if (active_object >= 0) if (state.active_object >= 0)
ui.set_status(MString<30>(GET_TEXT_F(MSG_PRINTING_OBJECT), ' ', active_object)); ui.set_status(MString<30>(GET_TEXT_F(MSG_PRINTING_OBJECT), ' ', state.active_object));
else else
ui.reset_status(); ui.reset_status();
#endif #endif
@ -54,29 +51,29 @@ void CancelObject::set_active_object(const int8_t obj) {
void CancelObject::cancel_object(const int8_t obj) { void CancelObject::cancel_object(const int8_t obj) {
if (WITHIN(obj, 0, 31)) { if (WITHIN(obj, 0, 31)) {
SBI(canceled, obj); SBI(state.canceled, obj);
if (obj == active_object) skipping = true; if (obj == state.active_object) state.skipping = true;
} }
} }
void CancelObject::uncancel_object(const int8_t obj) { void CancelObject::uncancel_object(const int8_t obj) {
if (WITHIN(obj, 0, 31)) { if (WITHIN(obj, 0, 31)) {
CBI(canceled, obj); CBI(state.canceled, obj);
if (obj == active_object) skipping = false; if (obj == state.active_object) state.skipping = false;
} }
} }
void CancelObject::report() { void CancelObject::report() {
if (active_object >= 0) if (state.active_object >= 0)
SERIAL_ECHO_MSG("Active Object: ", active_object); SERIAL_ECHO_MSG("Active Object: ", state.active_object);
if (canceled) { if (state.canceled == 0x0000) return;
SERIAL_ECHO_START();
SERIAL_ECHOPGM("Canceled:"); SERIAL_ECHO_START();
for (int i = 0; i < object_count; i++) SERIAL_ECHOPGM("Canceled:");
if (TEST(canceled, i)) { SERIAL_CHAR(' '); SERIAL_ECHO(i); } for (int i = 0; i < state.object_count; i++)
SERIAL_EOL(); if (TEST(state.canceled, i)) { SERIAL_CHAR(' '); SERIAL_ECHO(i); }
} SERIAL_EOL();
} }
#endif // CANCEL_OBJECTS #endif // CANCEL_OBJECTS

View file

@ -23,19 +23,23 @@
#include <stdint.h> #include <stdint.h>
typedef struct CancelState {
bool skipping = false;
int8_t object_count = 0, active_object = 0;
uint32_t canceled = 0x0000;
} cancel_state_t;
class CancelObject { class CancelObject {
public: public:
static bool skipping; static cancel_state_t state;
static int8_t object_count, active_object; static void set_active_object(const int8_t obj=state.active_object);
static uint32_t canceled;
static void set_active_object(const int8_t obj);
static void cancel_object(const int8_t obj); static void cancel_object(const int8_t obj);
static void uncancel_object(const int8_t obj); static void uncancel_object(const int8_t obj);
static void report(); static void report();
static bool is_canceled(const int8_t obj) { return TEST(canceled, obj); } static bool is_canceled(const int8_t obj) { return TEST(state.canceled, obj); }
static void clear_active_object() { set_active_object(-1); } static void clear_active_object() { set_active_object(-1); }
static void cancel_active_object() { cancel_object(active_object); } static void cancel_active_object() { cancel_object(state.active_object); }
static void reset() { canceled = 0x0000; object_count = 0; clear_active_object(); } static void reset() { state.canceled = 0x0000; state.object_count = 0; clear_active_object(); }
}; };
extern CancelObject cancelable; extern CancelObject cancelable;

View file

@ -36,7 +36,7 @@
#include "../module/stepper.h" #include "../module/stepper.h"
#include "../gcode/parser.h" #include "../gcode/parser.h"
#include "../feature/babystep.h" #include "babystep.h"
#include <Wire.h> #include <Wire.h>

View file

@ -31,7 +31,7 @@
#include "leds.h" #include "leds.h"
#if ANY(CASE_LIGHT_USE_RGB_LED, CASE_LIGHT_USE_NEOPIXEL) #if ANY(CASE_LIGHT_USE_RGB_LED, CASE_LIGHT_USE_NEOPIXEL)
#include "../../feature/caselight.h" #include "../caselight.h"
#endif #endif
#if ENABLED(LED_COLOR_PRESETS) #if ENABLED(LED_COLOR_PRESETS)

View file

@ -43,7 +43,7 @@ MMU2 mmu2;
#include "../../MarlinCore.h" #include "../../MarlinCore.h"
#if ENABLED(HOST_PROMPT_SUPPORT) #if ENABLED(HOST_PROMPT_SUPPORT)
#include "../../feature/host_actions.h" #include "../host_actions.h"
#endif #endif
#if ENABLED(EXTENSIBLE_UI) #if ENABLED(EXTENSIBLE_UI)

View file

@ -28,7 +28,7 @@
#if HAS_PRUSA_MMU3 #if HAS_PRUSA_MMU3
#include "../../feature/runout.h" #include "../runout.h"
#include "mmu3_fsensor.h" #include "mmu3_fsensor.h"
namespace MMU3 { namespace MMU3 {

View file

@ -34,7 +34,7 @@
#include "../../module/planner.h" #include "../../module/planner.h"
#include "../../module/temperature.h" #include "../../module/temperature.h"
#include "../../feature/pause.h" #include "../pause.h"
#include "../../libs/nozzle.h" #include "../../libs/nozzle.h"
#include "mmu3_marlin.h" #include "mmu3_marlin.h"

View file

@ -43,7 +43,7 @@
#include "../../core/language.h" #include "../../core/language.h"
#include "../../gcode/gcode.h" #include "../../gcode/gcode.h"
#include "../../feature/host_actions.h" #include "../host_actions.h"
#include "../../lcd/marlinui.h" #include "../../lcd/marlinui.h"
#include "../../lcd/menu/menu.h" #include "../../lcd/menu/menu.h"
#include "../../lcd/menu/menu_item.h" #include "../../lcd/menu/menu_item.h"

View file

@ -215,6 +215,7 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW
info.zraise = zraise; info.zraise = zraise;
info.flag.raised = raised; // Was Z raised before power-off? info.flag.raised = raised; // Was Z raised before power-off?
TERN_(CANCEL_OBJECTS, info.cancel_state = cancelable.state);
TERN_(GCODE_REPEAT_MARKERS, info.stored_repeat = repeat); TERN_(GCODE_REPEAT_MARKERS, info.stored_repeat = repeat);
TERN_(HAS_HOME_OFFSET, info.home_offset = home_offset); TERN_(HAS_HOME_OFFSET, info.home_offset = home_offset);
TERN_(HAS_WORKSPACE_OFFSET, info.workspace_offset = workspace_offset); TERN_(HAS_WORKSPACE_OFFSET, info.workspace_offset = workspace_offset);
@ -575,6 +576,11 @@ void PrintJobRecovery::resume() {
// Restore E position with G92.9 // Restore E position with G92.9
PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9E"), p_float_t(resume_pos.e, 3))); PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9E"), p_float_t(resume_pos.e, 3)));
#if ENABLED(CANCEL_OBJECTS)
cancelable.state = info.cancel_state;
cancelable.set_active_object(); // Sets the status message
#endif
TERN_(GCODE_REPEAT_MARKERS, repeat = info.stored_repeat); TERN_(GCODE_REPEAT_MARKERS, repeat = info.stored_repeat);
TERN_(HAS_HOME_OFFSET, home_offset = info.home_offset); TERN_(HAS_HOME_OFFSET, home_offset = info.home_offset);
TERN_(HAS_WORKSPACE_OFFSET, workspace_offset = info.workspace_offset); TERN_(HAS_WORKSPACE_OFFSET, workspace_offset = info.workspace_offset);
@ -613,6 +619,14 @@ void PrintJobRecovery::resume() {
DEBUG_ECHOLNPGM("zraise: ", info.zraise, " ", info.flag.raised ? "(before)" : ""); DEBUG_ECHOLNPGM("zraise: ", info.zraise, " ", info.flag.raised ? "(before)" : "");
#if ENABLED(CANCEL_OBJECTS)
const cancel_state_t cs = info.cancel_state;
DEBUG_ECHOPGM("Canceled:");
for (int i = 0; i < cs.object_count; i++)
if (TEST(cs.canceled, i)) { DEBUG_CHAR(' '); DEBUG_ECHO(i); }
DEBUG_EOL();
#endif
#if ENABLED(GCODE_REPEAT_MARKERS) #if ENABLED(GCODE_REPEAT_MARKERS)
const uint8_t ind = info.stored_repeat.count(); const uint8_t ind = info.stored_repeat.count();
DEBUG_ECHOLNPGM("repeat markers: ", ind); DEBUG_ECHOLNPGM("repeat markers: ", ind);

View file

@ -30,12 +30,16 @@
#include "../inc/MarlinConfig.h" #include "../inc/MarlinConfig.h"
#if ENABLED(CANCEL_OBJECTS)
#include "cancel_object.h"
#endif
#if ENABLED(GCODE_REPEAT_MARKERS) #if ENABLED(GCODE_REPEAT_MARKERS)
#include "../feature/repeat.h" #include "repeat.h"
#endif #endif
#if ENABLED(MIXING_EXTRUDER) #if ENABLED(MIXING_EXTRUDER)
#include "../feature/mixing.h" #include "mixing.h"
#endif #endif
#if !defined(POWER_LOSS_STATE) && PIN_EXISTS(POWER_LOSS) #if !defined(POWER_LOSS_STATE) && PIN_EXISTS(POWER_LOSS)
@ -64,6 +68,11 @@ typedef struct {
float zraise; float zraise;
// Canceled objects
#if ENABLED(CANCEL_OBJECTS)
cancel_state_t cancel_state;
#endif
// Repeat information // Repeat information
#if ENABLED(GCODE_REPEAT_MARKERS) #if ENABLED(GCODE_REPEAT_MARKERS)
Repeat stored_repeat; Repeat stored_repeat;

View file

@ -59,7 +59,7 @@ bool FilamentMonitorBase::enabled = true,
// Filament Runout event handler // Filament Runout event handler
// //
#include "../MarlinCore.h" #include "../MarlinCore.h"
#include "../feature/pause.h" #include "pause.h"
#include "../gcode/queue.h" #include "../gcode/queue.h"
#if ENABLED(HOST_ACTION_COMMANDS) #if ENABLED(HOST_ACTION_COMMANDS)

View file

@ -30,7 +30,7 @@
#include "../module/planner.h" #include "../module/planner.h"
#include "../module/stepper.h" // for block_t #include "../module/stepper.h" // for block_t
#include "../gcode/queue.h" #include "../gcode/queue.h"
#include "../feature/pause.h" // for did_pause_print #include "pause.h" // for did_pause_print
#include "../MarlinCore.h" // for printingIsActive() #include "../MarlinCore.h" // for printingIsActive()
#include "../inc/MarlinConfig.h" #include "../inc/MarlinConfig.h"

View file

@ -35,7 +35,7 @@
#endif #endif
#if ENABLED(I2C_AMMETER) #if ENABLED(I2C_AMMETER)
#include "../feature/ammeter.h" #include "ammeter.h"
#endif #endif
SpindleLaser cutter; SpindleLaser cutter;

View file

@ -102,7 +102,7 @@
#define G26_OK false #define G26_OK false
#define G26_ERR true #define G26_ERR true
#include "../../gcode/gcode.h" #include "../gcode.h"
#include "../../feature/bedlevel/bedlevel.h" #include "../../feature/bedlevel/bedlevel.h"
#include "../../MarlinCore.h" #include "../../MarlinCore.h"

View file

@ -41,7 +41,7 @@ void GcodeSuite::M486() {
if (parser.seen('T')) { if (parser.seen('T')) {
cancelable.reset(); cancelable.reset();
cancelable.object_count = parser.intval('T', 1); cancelable.state.object_count = parser.intval('T', 1);
} }
if (parser.seenval('S')) if (parser.seenval('S'))

View file

@ -165,7 +165,7 @@ void GcodeSuite::get_destination_from_command() {
xyze_bool_t seen{false}; xyze_bool_t seen{false};
#if ENABLED(CANCEL_OBJECTS) #if ENABLED(CANCEL_OBJECTS)
const bool &skip_move = cancelable.skipping; const bool &skip_move = cancelable.state.skipping;
#else #else
constexpr bool skip_move = false; constexpr bool skip_move = false;
#endif #endif

View file

@ -53,13 +53,13 @@ static void lcd_cancel_object_confirm() {
} }
void menu_cancelobject() { void menu_cancelobject() {
const int8_t ao = cancelable.active_object; const int8_t ao = cancelable.state.active_object;
START_MENU(); START_MENU();
BACK_ITEM(MSG_MAIN_MENU); BACK_ITEM(MSG_MAIN_MENU);
// Draw cancelable items in a loop // Draw cancelable items in a loop
for (int8_t i = -1; i < cancelable.object_count; i++) { for (int8_t i = -1; i < cancelable.state.object_count; i++) {
if (i == ao) continue; // Active is drawn on -1 index if (i == ao) continue; // Active is drawn on -1 index
const int8_t j = i < 0 ? ao : i; // Active or index item const int8_t j = i < 0 ? ao : i; // Active or index item
if (!cancelable.is_canceled(j)) { // Not canceled already? if (!cancelable.is_canceled(j)) { // Not canceled already?

View file

@ -2867,7 +2867,7 @@ bool Planner::buffer_segment(const abce_pos_t &abce
#if HAS_EXTRUDERS #if HAS_EXTRUDERS
// DRYRUN prevents E moves from taking place // DRYRUN prevents E moves from taking place
if (DEBUGGING(DRYRUN) || TERN0(CANCEL_OBJECTS, cancelable.skipping)) { if (DEBUGGING(DRYRUN) || TERN0(CANCEL_OBJECTS, cancelable.state.skipping)) {
position.e = target.e; position.e = target.e;
TERN_(HAS_POSITION_FLOAT, position_float.e = abce.e); TERN_(HAS_POSITION_FLOAT, position_float.e = abce.e);
} }

View file

@ -48,5 +48,5 @@ exec_test $1 $2 "RADDS with ABL (Bilinear), Triple Z Axis, Z_STEPPER_AUTO_ALIGN,
# #
restore_configs restore_configs
opt_set MOTHERBOARD BOARD_RAMPS4DUE_EEF LCD_LANGUAGE fi EXTRUDERS 2 TEMP_SENSOR_BED 0 NUM_SERVOS 1 opt_set MOTHERBOARD BOARD_RAMPS4DUE_EEF LCD_LANGUAGE fi EXTRUDERS 2 TEMP_SENSOR_BED 0 NUM_SERVOS 1
opt_enable SWITCHING_EXTRUDER ULTIMAKERCONTROLLER BEEP_ON_FEEDRATE_CHANGE POWER_LOSS_RECOVERY opt_enable SWITCHING_EXTRUDER ULTIMAKERCONTROLLER BEEP_ON_FEEDRATE_CHANGE CANCEL_OBJECTS POWER_LOSS_RECOVERY
exec_test $1 $2 "RAMPS4DUE_EEF with SWITCHING_EXTRUDER, POWER_LOSS_RECOVERY" "$3" exec_test $1 $2 "RAMPS4DUE_EEF with SWITCHING_EXTRUDER, CANCEL_OBJECTS, POWER_LOSS_RECOVERY" "$3"