diff --git a/Marlin/src/feature/spindle_laser.cpp b/Marlin/src/feature/spindle_laser.cpp index 3b28b61b4..3f6523478 100644 --- a/Marlin/src/feature/spindle_laser.cpp +++ b/Marlin/src/feature/spindle_laser.cpp @@ -118,7 +118,7 @@ void SpindleLaser::apply_power(const uint8_t opwr) { // Set the spindle direction and apply immediately // Stop on direction change if SPINDLE_STOP_ON_DIR_CHANGE is enabled // - void SpindleLaser::set_direction(const bool reverse) { + void SpindleLaser::set_reverse(const bool reverse) { const bool dir_state = (reverse == SPINDLE_INVERT_DIR); // Forward (M3) HIGH when not inverted if (TERN0(SPINDLE_STOP_ON_DIR_CHANGE, enabled()) && READ(SPINDLE_DIR_PIN) != dir_state) disable(); WRITE(SPINDLE_DIR_PIN, dir_state); diff --git a/Marlin/src/feature/spindle_laser.h b/Marlin/src/feature/spindle_laser.h index 74d06634a..4d3c80241 100644 --- a/Marlin/src/feature/spindle_laser.h +++ b/Marlin/src/feature/spindle_laser.h @@ -57,7 +57,7 @@ public: static const inline uint8_t cpwr_to_pct(const cutter_cpower_t cpwr) { constexpr cutter_cpower_t power_floor = TERN(CUTTER_POWER_RELATIVE, SPEED_POWER_MIN, 0), power_range = SPEED_POWER_MAX - power_floor; - return unitPower ? round(100.0f * (cpwr - power_floor) / power_range) : 0; + return cpwr ? round(100.0f * (cpwr - power_floor) / power_range) : 0; } // Convert a cpower (e.g., SPEED_POWER_STARTUP) to unit power (upwr, upower), @@ -191,9 +191,11 @@ public: } #if ENABLED(SPINDLE_CHANGE_DIR) - static void set_direction(const bool reverse); + static void set_reverse(const bool reverse); + static bool is_reverse() { return READ(SPINDLE_DIR_PIN) == SPINDLE_INVERT_DIR; } #else - static inline void set_direction(const bool) {} + static inline void set_reverse(const bool) {} + static bool is_reverse() { return false; } #endif static inline void disable() { isReady = false; set_enabled(false); } @@ -208,11 +210,12 @@ public: else menuPower = cpwr_to_upwr(SPEED_POWER_STARTUP); unitPower = menuPower; - set_direction(reverse); + set_reverse(reverse); set_enabled(true); } FORCE_INLINE static void enable_forward() { enable_with_dir(false); } FORCE_INLINE static void enable_reverse() { enable_with_dir(true); } + FORCE_INLINE static void enable_same_dir() { enable_with_dir(is_reverse()); } #if ENABLED(SPINDLE_LASER_PWM) static inline void update_from_mpower() { diff --git a/Marlin/src/gcode/control/M3-M5.cpp b/Marlin/src/gcode/control/M3-M5.cpp index 4ca103da5..711bb7e5e 100644 --- a/Marlin/src/gcode/control/M3-M5.cpp +++ b/Marlin/src/gcode/control/M3-M5.cpp @@ -103,7 +103,7 @@ void GcodeSuite::M3_M4(const bool is_M4) { #endif planner.synchronize(); // Wait for previous movement commands (G0/G0/G2/G3) to complete before changing power - cutter.set_direction(is_M4); + cutter.set_reverse(is_M4); #if ENABLED(SPINDLE_LASER_PWM) if (parser.seenval('O')) { diff --git a/Marlin/src/lcd/language/language_en.h b/Marlin/src/lcd/language/language_en.h index 0b96403b7..ed9ad954f 100644 --- a/Marlin/src/lcd/language/language_en.h +++ b/Marlin/src/lcd/language/language_en.h @@ -107,16 +107,17 @@ namespace Language_en { #endif PROGMEM Language_Str MSG_PREHEAT_CUSTOM = _UxGT("Preheat Custom"); PROGMEM Language_Str MSG_COOLDOWN = _UxGT("Cooldown"); + PROGMEM Language_Str MSG_CUTTER_FREQUENCY = _UxGT("Frequency"); PROGMEM Language_Str MSG_LASER_MENU = _UxGT("Laser Control"); - PROGMEM Language_Str MSG_LASER_OFF = _UxGT("Laser Off"); - PROGMEM Language_Str MSG_LASER_ON = _UxGT("Laser On"); - PROGMEM Language_Str MSG_LASER_POWER = _UxGT("Laser Power"); PROGMEM Language_Str MSG_SPINDLE_MENU = _UxGT("Spindle Control"); - PROGMEM Language_Str MSG_SPINDLE_OFF = _UxGT("Spindle Off"); - PROGMEM Language_Str MSG_SPINDLE_ON = _UxGT("Spindle On"); - PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("Spindle Power"); + PROGMEM Language_Str MSG_LASER_POWER = _UxGT("Laser Power"); + PROGMEM Language_Str MSG_SPINDLE_POWER = _UxGT("Spindle Pwr"); + PROGMEM Language_Str MSG_LASER_TOGGLE = _UxGT("Toggle Laser"); + PROGMEM Language_Str MSG_SPINDLE_TOGGLE = _UxGT("Toggle Spindle"); + PROGMEM Language_Str MSG_SPINDLE_FORWARD = _UxGT("Spindle Forward"); PROGMEM Language_Str MSG_SPINDLE_REVERSE = _UxGT("Spindle Reverse"); + PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Switch Power On"); PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Switch Power Off"); PROGMEM Language_Str MSG_EXTRUDE = _UxGT("Extrude"); diff --git a/Marlin/src/lcd/menu/menu.h b/Marlin/src/lcd/menu/menu.h index cf2f6b163..de11ee3a5 100644 --- a/Marlin/src/lcd/menu/menu.h +++ b/Marlin/src/lcd/menu/menu.h @@ -252,3 +252,5 @@ void _lcd_draw_homing(); extern uint8_t screen_history_depth; inline void clear_menu_history() { screen_history_depth = 0; } + +#define STICKY_SCREEN(S) []{ ui.defer_status_screen(); ui.goto_screen(S); } diff --git a/Marlin/src/lcd/menu/menu_main.cpp b/Marlin/src/lcd/menu/menu_main.cpp index 1b87e06cc..968de3d4b 100644 --- a/Marlin/src/lcd/menu/menu_main.cpp +++ b/Marlin/src/lcd/menu/menu_main.cpp @@ -170,7 +170,7 @@ void menu_main() { } #if HAS_CUTTER - SUBMENU(MSG_CUTTER(MENU), menu_spindle_laser); + SUBMENU(MSG_CUTTER(MENU), STICKY_SCREEN(menu_spindle_laser)); #endif #if HAS_TEMPERATURE diff --git a/Marlin/src/lcd/menu/menu_spindle_laser.cpp b/Marlin/src/lcd/menu/menu_spindle_laser.cpp index f1bf433c2..d5a291db7 100644 --- a/Marlin/src/lcd/menu/menu_spindle_laser.cpp +++ b/Marlin/src/lcd/menu/menu_spindle_laser.cpp @@ -33,8 +33,10 @@ #include "../../feature/spindle_laser.h" void menu_spindle_laser() { - - const bool is_enabled = cutter.enabled() && cutter.isReady; + bool is_enabled = cutter.enabled() && cutter.isReady; + #if ENABLED(SPINDLE_CHANGE_DIR) + bool is_rev = cutter.is_reverse(); + #endif START_MENU(); BACK_ITEM(MSG_MAIN); @@ -46,18 +48,20 @@ cutter.mpower_min(), cutter.mpower_max(), cutter.update_from_mpower); #endif - if (is_enabled) - ACTION_ITEM(MSG_CUTTER(OFF), cutter.disable); - else { - ACTION_ITEM(MSG_CUTTER(ON), cutter.enable_forward); - #if ENABLED(SPINDLE_CHANGE_DIR) - ACTION_ITEM(MSG_SPINDLE_REVERSE, cutter.enable_reverse); - #endif - } + editable.state = is_enabled; + EDIT_ITEM(bool, MSG_CUTTER(TOGGLE), &is_enabled, []{ if (editable.state) cutter.disable(); else cutter.enable_same_dir(); }); + + #if ENABLED(SPINDLE_CHANGE_DIR) + if (!is_enabled) { + editable.state = is_rev; + ACTION_ITEM_P(is_rev ? GET_TEXT(MSG_CUTTER(REVERSE)) : GET_TEXT(MSG_CUTTER(FORWARD)), []{ cutter.set_reverse(!editable.state); }); + } + #endif #if BOTH(MARLIN_DEV_MODE, HAL_CAN_SET_PWM_FREQ) && defined(SPINDLE_LASER_FREQUENCY) EDIT_ITEM_FAST(CUTTER_MENU_FREQUENCY_TYPE, MSG_CUTTER_FREQUENCY, &cutter.frequency, 2000, 50000, cutter.refresh_frequency); #endif + END_MENU(); }