diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 2969b57eef..ff986b6783 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -1770,6 +1770,11 @@ //#define PROBE_TOOLCHANGE_NO_MOVE // Suppress motion on probe tool-change #endif +#if ENABLED(TREX3) + #define NOZZLE_TO_PROBE_OFFSET { -3, 31, 0 } +#else + #define NOZZLE_TO_PROBE_OFFSET { -7, 29, 0 } +#endif // Most probes should stay away from the edges of the bed, but // with NOZZLE_AS_PROBE this can be negative for a wider probing area. #define PROBING_MARGIN 10 @@ -2223,6 +2228,34 @@ #endif #endif #endif + + #define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins. + //#define FIL_RUNOUT_PULLDOWN // Use internal pulldown for filament runout pins. + + // Override individually if the runout sensors vary + //#define FIL_RUNOUT1_PULLUP + //#define FIL_RUNOUT1_PULLDOWN + + //#define FIL_RUNOUT2_PULLUP + //#define FIL_RUNOUT2_PULLDOWN + + //#define FIL_RUNOUT3_PULLUP + //#define FIL_RUNOUT3_PULLDOWN + + //#define FIL_RUNOUT4_PULLUP + //#define FIL_RUNOUT4_PULLDOWN + + //#define FIL_RUNOUT5_PULLUP + //#define FIL_RUNOUT5_PULLDOWN + + //#define FIL_RUNOUT6_PULLUP + //#define FIL_RUNOUT6_PULLDOWN + + //#define FIL_RUNOUT7_PULLUP + //#define FIL_RUNOUT7_PULLDOWN + + //#define FIL_RUNOUT8_PULLUP + //#define FIL_RUNOUT8_PULLDOWN #endif //=========================================================================== diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 96edba9509..eb57073cbe 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -2321,7 +2321,7 @@ #define BABYSTEP_ZPROBE_OFFSET // Combine M851 Z and Babystepping #if ENABLED(BABYSTEP_ZPROBE_OFFSET) #define BABYSTEP_HOTEND_Z_OFFSET // For multiple hotends, babystep relative Z offsets - #define BABYSTEP_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + #define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor #endif #endif diff --git a/Marlin/Version.h b/Marlin/Version.h index 4bdfcdaebb..c7f370a028 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -28,13 +28,13 @@ /** * Marlin release version identifier */ -//#define SHORT_BUILD_VERSION "bugfix-2.1.x" +#define SHORT_BUILD_VERSION "2.1.x-TR1" /** * Verbose version identifier which should contain a reference to the location * from where the binary was downloaded or the source code was compiled. */ -//#define DETAILED_BUILD_VERSION SHORT_BUILD_VERSION +#define DETAILED_BUILD_VERSION SHORT_BUILD_VERSION " TM3D" /** * The STRING_DISTRIBUTION_DATE represents when the binary file was built, @@ -46,7 +46,7 @@ /** * Defines a generic printer name to be output to the LCD after booting Marlin. */ -//#define MACHINE_NAME "3D Printer" +#define MACHINE_NAME "TM3D Trex" /** * The SOURCE_CODE_URL is the location where users will find the Marlin Source @@ -54,7 +54,7 @@ * has a distinct Github fork— the Source Code URL should just be the main * Marlin repository. */ -//#define SOURCE_CODE_URL "github.com/MarlinFirmware/Marlin" +#define SOURCE_CODE_URL "https://github.com/InsanityAutomation/Marlin/tree/TM_Trex2+_2.0.x" /** * Default generic printer UUID. @@ -65,7 +65,7 @@ * The WEBSITE_URL is the location where users can get more information such as * documentation about a specific Marlin release. */ -//#define WEBSITE_URL "marlinfw.org" +#define WEBSITE_URL "tinymachines3d.com" /** * Set the vendor info the serial USB interface, if changable diff --git a/Marlin/src/core/utility.cpp b/Marlin/src/core/utility.cpp index b555d9f2a6..597c536d8c 100644 --- a/Marlin/src/core/utility.cpp +++ b/Marlin/src/core/utility.cpp @@ -25,10 +25,6 @@ #include "../MarlinCore.h" #include "../module/temperature.h" -#if ENABLED(MARLIN_DEV_MODE) - MarlinError marlin_error_number; // Error Number - Marlin can beep X times periodically, display, and emit... -#endif - void safe_delay(millis_t ms) { while (ms > 50) { ms -= 50; @@ -80,8 +76,6 @@ void safe_delay(millis_t ms) { TERN_(Z_PROBE_ALLEN_KEY, "Z_PROBE_ALLEN_KEY") TERN_(SOLENOID_PROBE, "SOLENOID_PROBE") TERN_(MAGLEV4, "MAGLEV4") - TERN_(BIQU_MICROPROBE_V1, "BIQU_MICROPROBE_V1") - TERN_(BIQU_MICROPROBE_V2, "BIQU_MICROPROBE_V2") IF_DISABLED(PROBE_SELECTED, "NONE") ); @@ -101,9 +95,9 @@ void safe_delay(millis_t ms) { SERIAL_ECHOPGM(" (Aligned With"); if (probe.offset_xy.y > 0) - SERIAL_ECHO(F(TERN(IS_SCARA, "-Distal", "-Back"))); + SERIAL_ECHOPGM(TERN(IS_SCARA, "-Distal", "-Back")); else if (probe.offset_xy.y < 0) - SERIAL_ECHO(F(TERN(IS_SCARA, "-Proximal", "-Front"))); + SERIAL_ECHOPGM(TERN(IS_SCARA, "-Proximal", "-Front")); else if (probe.offset_xy.x != 0) SERIAL_ECHOPGM("-Center"); @@ -111,7 +105,7 @@ void safe_delay(millis_t ms) { #endif - SERIAL_ECHO(probe.offset.z < 0 ? F("Below") : probe.offset.z > 0 ? F("Above") : F("Same Z as")); + SERIAL_ECHOF(probe.offset.z < 0 ? F("Below") : probe.offset.z > 0 ? F("Above") : F("Same Z as")); SERIAL_ECHOLNPGM(" Nozzle)"); #endif diff --git a/Marlin/src/feature/host_actions.cpp b/Marlin/src/feature/host_actions.cpp index 538aa92e91..898ae2f85c 100644 --- a/Marlin/src/feature/host_actions.cpp +++ b/Marlin/src/feature/host_actions.cpp @@ -197,7 +197,7 @@ void HostUI::action(FSTR_P const fstr, const bool eol) { #endif #if HAS_FILAMENT_SENSOR if (runout.filament_ran_out) { // Disable a triggered sensor - runout.enabled = false; + runout.enabled[active_extruder] = false; runout.reset(); } #endif diff --git a/Marlin/src/feature/mmu/mmu2.cpp b/Marlin/src/feature/mmu/mmu2.cpp index 5ef56c7eac..75cb17cbf1 100644 --- a/Marlin/src/feature/mmu/mmu2.cpp +++ b/Marlin/src/feature/mmu/mmu2.cpp @@ -76,7 +76,7 @@ MMU2 mmu2; #define MMU2_NO_TOOL 99 #define MMU_BAUD 115200 -bool MMU2::_enabled, MMU2::ready; +bool MMU2::_enabled, MMU2::ready, MMU2::mmu_print_saved; #if HAS_PRUSA_MMU2S bool MMU2::mmu2s_triggered; #endif @@ -84,6 +84,7 @@ uint8_t MMU2::cmd, MMU2::cmd_arg, MMU2::last_cmd, MMU2::extruder; int8_t MMU2::state = 0; volatile int8_t MMU2::finda = 1; volatile bool MMU2::finda_runout_valid; +int16_t MMU2::version = -1, MMU2::buildnr = -1; millis_t MMU2::prev_request, MMU2::prev_P0_request; char MMU2::rx_buffer[MMU_RX_SIZE], MMU2::tx_buffer[MMU_TX_SIZE]; @@ -92,11 +93,14 @@ struct E_Step { feedRate_t feedRate; //!< feed rate in mm/s }; -inline void unscaled_mmu2_e_move(const float &dist, const feedRate_t fr_mm_s, const bool sync=true) { - current_position.e += dist / planner.e_factor[active_extruder]; - line_to_current_position(fr_mm_s); - if (sync) planner.synchronize(); -} +static constexpr E_Step + ramming_sequence[] PROGMEM = { MMU2_RAMMING_SEQUENCE } + , load_to_nozzle_sequence[] PROGMEM = { MMU2_LOAD_TO_NOZZLE_SEQUENCE } + #if HAS_PRUSA_MMU2S + , can_load_sequence[] PROGMEM = { MMU2_CAN_LOAD_SEQUENCE } + , can_load_increment_sequence[] PROGMEM = { MMU2_CAN_LOAD_INCREMENT_SEQUENCE } + #endif +; MMU2::MMU2() { rx_buffer[0] = '\0'; @@ -132,12 +136,12 @@ void MMU2::reset() { #endif } -int8_t MMU2::get_current_tool() { return extruder == MMU2_NO_TOOL ? -1 : extruder; } +uint8_t MMU2::get_current_tool() { + return extruder == MMU2_NO_TOOL ? -1 : extruder; +} -#if ANY(HAS_PRUSA_MMU2S, MMU_EXTRUDER_SENSOR) - #define FILAMENT_PRESENT() (READ(FIL_RUNOUT1_PIN) != FIL_RUNOUT1_STATE) -#else - #define FILAMENT_PRESENT() true +#if EITHER(HAS_PRUSA_MMU2S, MMU_EXTRUDER_SENSOR) + #define FILAMENT_PRESENT() (READ(FIL_RUNOUT1_PIN) != runout.out_state()) #endif void mmu2_attn_buzz(const bool two=false) { @@ -145,7 +149,6 @@ void mmu2_attn_buzz(const bool two=false) { if (two) { BUZZ(10, 0); BUZZ(200, 404); } } -// Avoiding sscanf significantly reduces build size void MMU2::mmu_loop() { switch (state) { @@ -160,7 +163,7 @@ void MMU2::mmu_loop() { MMU2_SEND("S1"); // Read Version state = -2; } - else if (ELAPSED(millis(), prev_request + 30000)) { // 30sec after reset disable MMU + else if (millis() > 30000) { // 30sec after reset disable MMU SERIAL_ECHOLNPGM("MMU not responding - DISABLED"); state = 0; } @@ -168,7 +171,7 @@ void MMU2::mmu_loop() { case -2: if (rx_ok()) { - const uint16_t version = uint16_t(strtoul(rx_buffer, nullptr, 10)); + sscanf(rx_buffer, "%huok\n", &version); DEBUG_ECHOLNPGM("MMU => ", version, "\nMMU <= 'S2'"); MMU2_SEND("S2"); // Read Build Number state = -3; @@ -177,15 +180,17 @@ void MMU2::mmu_loop() { case -3: if (rx_ok()) { - const uint16_t buildnr = uint16_t(strtoul(rx_buffer, nullptr, 10)); + sscanf(rx_buffer, "%huok\n", &buildnr); + DEBUG_ECHOLNPGM("MMU => ", buildnr); - check_version(buildnr); + check_version(); #if ENABLED(MMU2_MODE_12V) DEBUG_ECHOLNPGM("MMU <= 'M1'"); MMU2_SEND("M1"); // Stealth Mode state = -5; + #else DEBUG_ECHOLNPGM("MMU <= 'P0'"); MMU2_SEND("P0"); // Read FINDA @@ -195,21 +200,20 @@ void MMU2::mmu_loop() { break; #if ENABLED(MMU2_MODE_12V) - case -5: - // response to M1 - if (rx_ok()) { - DEBUG_ECHOLNPGM("MMU => ok"); - DEBUG_ECHOLNPGM("MMU <= 'P0'"); - MMU2_SEND("P0"); // Read FINDA - state = -4; - } - break; + case -5: + // response to M1 + if (rx_ok()) { + DEBUG_ECHOLNPGM("MMU => ok"); + DEBUG_ECHOLNPGM("MMU <= 'P0'"); + MMU2_SEND("P0"); // Read FINDA + state = -4; + } + break; #endif case -4: if (rx_ok()) { - const uint8_t findex = uint8_t(rx_buffer[0] - '0'); - if (findex <= 1) finda = findex; + sscanf(rx_buffer, "%hhuok\n", &finda); DEBUG_ECHOLNPGM("MMU => ", finda, "\nMMU - ENABLED"); @@ -282,11 +286,10 @@ void MMU2::mmu_loop() { case 2: // response to command P0 if (rx_ok()) { - const uint8_t findex = uint8_t(rx_buffer[0] - '0'); - if (findex <= 1) finda = findex; + sscanf(rx_buffer, "%hhuok\n", &finda); // This is super annoying. Only activate if necessary - //if (finda_runout_valid) DEBUG_ECHOLNPGM("MMU <= 'P0'\nMMU => ", p_float_t(finda, 6)); + // if (finda_runout_valid) DEBUG_ECHOLNPAIR_F("MMU <= 'P0'\nMMU => ", finda, 6); if (!finda && finda_runout_valid) filament_runout(); if (cmd == MMU_CMD_NONE) ready = true; @@ -403,7 +406,7 @@ void MMU2::tx_str(FSTR_P fstr) { void MMU2::tx_printf(FSTR_P format, int argument = -1) { clear_rx_buffer(); const uint8_t len = sprintf_P(tx_buffer, FTOP(format), argument); - for (uint8_t i = 0; i < len; ++i) MMU2_SERIAL.write(tx_buffer[i]); + LOOP_L_N(i, len) MMU2_SERIAL.write(tx_buffer[i]); prev_request = millis(); } @@ -413,7 +416,7 @@ void MMU2::tx_printf(FSTR_P format, int argument = -1) { void MMU2::tx_printf(FSTR_P format, int argument1, int argument2) { clear_rx_buffer(); const uint8_t len = sprintf_P(tx_buffer, FTOP(format), argument1, argument2); - for (uint8_t i = 0; i < len; ++i) MMU2_SERIAL.write(tx_buffer[i]); + LOOP_L_N(i, len) MMU2_SERIAL.write(tx_buffer[i]); prev_request = millis(); } @@ -439,7 +442,7 @@ bool MMU2::rx_ok() { /** * Check if MMU has compatible firmware */ -void MMU2::check_version(const uint16_t buildnr) { +void MMU2::check_version() { if (buildnr < MMU_REQUIRED_FW_BUILDNR) { SERIAL_ERROR_MSG("Invalid MMU2 firmware. Version >= " STRINGIFY(MMU_REQUIRED_FW_BUILDNR) " required."); kill(GET_TEXT_F(MSG_KILL_MMU2_FIRMWARE)); @@ -455,19 +458,12 @@ static void mmu2_not_responding() { BUZZ(100, 659); } -inline void beep_bad_cmd() { BUZZ(400, 40); } - #if HAS_PRUSA_MMU2S - /** - * Load filament until the sensor at the gears is triggered - * and give up after a number of attempts set with MMU2_C0_RETRY. - * Each try has a timeout before returning a fail state. - */ bool MMU2::load_to_gears() { command(MMU_CMD_C0); manage_response(true, true); - for (uint8_t i = 0; i < MMU2_C0_RETRY; ++i) { // Keep loading until filament reaches gears + LOOP_L_N(i, MMU2_C0_RETRY) { // Keep loading until filament reaches gears if (mmu2s_triggered) break; command(MMU_CMD_C0); manage_response(true, true); @@ -488,11 +484,6 @@ inline void beep_bad_cmd() { BUZZ(400, 40); } set_runout_valid(false); if (index != extruder) { - if (ENABLED(MMU_IR_UNLOAD_MOVE) && FILAMENT_PRESENT()) { - DEBUG_ECHOLNPGM("Unloading\n"); - while (FILAMENT_PRESENT()) // Filament present? Keep unloading. - unscaled_mmu2_e_move(-0.25, MMM_TO_MMS(120)); // 0.25mm is a guessed value. Adjust to preference. - } stepper.disable_extruder(); ui.status_printf(0, GET_TEXT_F(MSG_MMU2_LOADING_FILAMENT), int(index + 1)); @@ -529,9 +520,9 @@ inline void beep_bad_cmd() { BUZZ(400, 40); } #if ENABLED(MMU2_MENUS) const uint8_t index = mmu2_choose_filament(); while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100); - load_to_nozzle(index); + load_filament_to_nozzle(index); #else - beep_bad_cmd(); + ERR_BUZZ(); #endif } break; @@ -550,13 +541,13 @@ inline void beep_bad_cmd() { BUZZ(400, 40); } active_extruder = 0; } #else - beep_bad_cmd(); + ERR_BUZZ(); #endif } break; case 'c': { while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100); - load_to_nozzle_sequence(); + load_to_nozzle(); } break; } @@ -617,9 +608,9 @@ inline void beep_bad_cmd() { BUZZ(400, 40); } #if ENABLED(MMU2_MENUS) uint8_t index = mmu2_choose_filament(); while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100); - load_to_nozzle(index); + load_filament_to_nozzle(index); #else - beep_bad_cmd(); + ERR_BUZZ(); #endif } break; @@ -639,14 +630,14 @@ inline void beep_bad_cmd() { BUZZ(400, 40); } extruder = index; active_extruder = 0; #else - beep_bad_cmd(); + ERR_BUZZ(); #endif } break; case 'c': { DEBUG_ECHOLNPGM("case c\n"); while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100); - load_to_nozzle_sequence(); + execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence)); } break; } @@ -732,9 +723,9 @@ inline void beep_bad_cmd() { BUZZ(400, 40); } #if ENABLED(MMU2_MENUS) uint8_t index = mmu2_choose_filament(); while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100); - load_to_nozzle(index); + load_filament_to_nozzle(index); #else - beep_bad_cmd(); + ERR_BUZZ(); #endif } break; @@ -753,14 +744,14 @@ inline void beep_bad_cmd() { BUZZ(400, 40); } extruder = index; active_extruder = 0; #else - beep_bad_cmd(); + ERR_BUZZ(); #endif } break; case 'c': { DEBUG_ECHOLNPGM("case c\n"); while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100); - load_to_nozzle_sequence(); + execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence)); } break; } @@ -801,7 +792,8 @@ bool MMU2::get_response() { void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) { constexpr xyz_pos_t park_point = NOZZLE_PARK_POINT; - bool response = false, mmu_print_saved = false; + bool response = false; + mmu_print_saved = false; xyz_pos_t resume_position; celsius_t resume_hotend_temp = thermalManager.degTargetHotend(active_extruder); @@ -823,7 +815,8 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) { resume_hotend_temp = thermalManager.degTargetHotend(active_extruder); resume_position = current_position; - if (move_axes && all_axes_homed()) nozzle.park(0, park_point); + if (move_axes && all_axes_homed()) + nozzle.park(0, park_point /*= NOZZLE_PARK_POINT*/); if (turn_off_nozzle) thermalManager.setTargetHotend(0, active_extruder); @@ -831,12 +824,13 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) { } } else if (mmu_print_saved) { - SERIAL_ECHOLNPGM("\nMMU starts responding"); + SERIAL_ECHOLNPGM("MMU starts responding\n"); if (turn_off_nozzle && resume_hotend_temp) { thermalManager.setTargetHotend(resume_hotend_temp, active_extruder); LCD_MESSAGE(MSG_HEATING); ERR_BUZZ(); + while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(1000); } @@ -849,6 +843,7 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) { if (move_axes && all_axes_homed()) { // Move XY to starting position, then Z do_blocking_move_to_xy(resume_position, feedRate_t(NOZZLE_PARK_XY_FEEDRATE)); + // Move Z_AXIS to saved position do_blocking_move_to_z(resume_position.z, feedRate_t(NOZZLE_PARK_Z_FEEDRATE)); } @@ -883,24 +878,23 @@ void MMU2::filament_runout() { } // Slowly spin the extruder during C0 else { - while (planner.movesplanned() < 3) - unscaled_mmu2_e_move(0.25, MMM_TO_MMS(120), false); + while (planner.movesplanned() < 3) { + current_position.e += 0.25; + line_to_current_position(MMM_TO_MMS(120)); + } } } mmu2s_triggered = present; } bool MMU2::can_load() { - static const E_Step can_load_sequence[] PROGMEM = { MMU2_CAN_LOAD_SEQUENCE }, - can_load_increment_sequence[] PROGMEM = { MMU2_CAN_LOAD_INCREMENT_SEQUENCE }; - - execute_extruder_sequence(can_load_sequence, COUNT(can_load_sequence)); + execute_extruder_sequence((const E_Step *)can_load_sequence, COUNT(can_load_sequence)); int filament_detected_count = 0; const int steps = (MMU2_CAN_LOAD_RETRACT) / (MMU2_CAN_LOAD_INCREMENT); DEBUG_ECHOLNPGM("MMU can_load:"); - for (uint8_t i = 0; i < steps; ++i) { - execute_extruder_sequence(can_load_increment_sequence, COUNT(can_load_increment_sequence)); + LOOP_L_N(i, steps) { + execute_extruder_sequence((const E_Step *)can_load_increment_sequence, COUNT(can_load_increment_sequence)); check_filament(); // Don't trust the idle function DEBUG_CHAR(mmu2s_triggered ? 'O' : 'o'); if (mmu2s_triggered) ++filament_detected_count; @@ -918,7 +912,7 @@ void MMU2::filament_runout() { #endif // Load filament into MMU2 -void MMU2::load_to_feeder(const uint8_t index) { +void MMU2::load_filament(const uint8_t index) { if (!_enabled) return; command(MMU_CMD_L0 + index); @@ -929,7 +923,8 @@ void MMU2::load_to_feeder(const uint8_t index) { /** * Switch material and load to nozzle */ -bool MMU2::load_to_nozzle(const uint8_t index) { +bool MMU2::load_filament_to_nozzle(const uint8_t index) { + if (!_enabled) return false; if (thermalManager.tooColdToExtrude(active_extruder)) { @@ -938,13 +933,6 @@ bool MMU2::load_to_nozzle(const uint8_t index) { return false; } - if (TERN0(MMU_IR_UNLOAD_MOVE, index != extruder) && FILAMENT_PRESENT()) { - DEBUG_ECHOLNPGM("Unloading\n"); - ramming_sequence(); // Unloading instructions from printer side when operating LCD - while (FILAMENT_PRESENT()) // Filament present? Keep unloading. - unscaled_mmu2_e_move(-0.25, MMM_TO_MMS(120)); // 0.25mm is a guessed value. Adjust to preference. - } - stepper.disable_extruder(); command(MMU_CMD_T0 + index); manage_response(true, true); @@ -954,12 +942,23 @@ bool MMU2::load_to_nozzle(const uint8_t index) { mmu_loop(); extruder = index; active_extruder = 0; - load_to_nozzle_sequence(); + load_to_nozzle(); mmu2_attn_buzz(); } return success; } +/** + * Load filament to nozzle of multimaterial printer + * + * This function is used only after T? (user select filament) and M600 (change filament). + * It is not used after T0 .. T4 command (select filament), in such case, G-code is responsible for loading + * filament to nozzle. + */ +void MMU2::load_to_nozzle() { + execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence)); +} + bool MMU2::eject_filament(const uint8_t index, const bool recover) { if (!_enabled) return false; @@ -972,17 +971,20 @@ bool MMU2::eject_filament(const uint8_t index, const bool recover) { LCD_MESSAGE(MSG_MMU2_EJECTING_FILAMENT); - unscaled_mmu2_e_move(-(MMU2_FILAMENTCHANGE_EJECT_FEED), MMM_TO_MMS(2500)); + stepper.enable_extruder(); + current_position.e -= MMU2_FILAMENTCHANGE_EJECT_FEED; + line_to_current_position(MMM_TO_MMS(2500)); + planner.synchronize(); command(MMU_CMD_E0 + index); manage_response(false, false); if (recover) { - LCD_MESSAGE(MSG_MMU2_REMOVE_AND_CLICK); + LCD_MESSAGE(MSG_MMU2_EJECT_RECOVER); mmu2_attn_buzz(); - TERN_(HOST_PROMPT_SUPPORT, hostui.continue_prompt(GET_TEXT_F(MSG_MMU2_EJECT_RECOVER))); - TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_MMU2_EJECT_RECOVER))); + TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, F("MMU2 Eject Recover"), FPSTR(CONTINUE_STR))); + TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(F("MMU2 Eject Recover"))); TERN_(HAS_RESUME_CONTINUE, wait_for_user_response()); - mmu2_attn_buzz(); + mmu2_attn_buzz(true); command(MMU_CMD_R0); manage_response(false, false); @@ -1016,7 +1018,7 @@ bool MMU2::unload() { } // Unload sequence to optimize shape of the tip of the unloaded filament - ramming_sequence(); + execute_extruder_sequence((const E_Step *)ramming_sequence, sizeof(ramming_sequence) / sizeof(E_Step)); command(MMU_CMD_U0); manage_response(false, true); @@ -1031,26 +1033,23 @@ bool MMU2::unload() { return true; } -void MMU2::ramming_sequence() { - static const E_Step sequence[] PROGMEM = { MMU2_RAMMING_SEQUENCE }; - execute_extruder_sequence(sequence, COUNT(sequence)); -} - -void MMU2::load_to_nozzle_sequence() { - static const E_Step sequence[] PROGMEM = { MMU2_LOAD_TO_NOZZLE_SEQUENCE }; - execute_extruder_sequence(sequence, COUNT(sequence)); -} - void MMU2::execute_extruder_sequence(const E_Step * sequence, int steps) { + planner.synchronize(); + stepper.enable_extruder(); - const E_Step *step = sequence; + const E_Step* step = sequence; - for (uint8_t i = 0; i < steps; ++i) { + LOOP_L_N(i, steps) { const float es = pgm_read_float(&(step->extrude)); const feedRate_t fr_mm_m = pgm_read_float(&(step->feedRate)); + DEBUG_ECHO_MSG("E step ", es, "/", fr_mm_m); - unscaled_mmu2_e_move(es, MMM_TO_MMS(fr_mm_m)); + + current_position.e += es; + line_to_current_position(MMM_TO_MMS(fr_mm_m)); + planner.synchronize(); + step++; } diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp index 74a4f236c0..15238aee5d 100644 --- a/Marlin/src/feature/pause.cpp +++ b/Marlin/src/feature/pause.cpp @@ -23,8 +23,6 @@ /** * feature/pause.cpp - Pause feature support functions * This may be combined with related G-codes if features are consolidated. - * - * Note: Calls to ui.pause_show_message are passed to either ExtUI or MarlinUI. */ #include "../inc/MarlinConfigPre.h" @@ -62,6 +60,8 @@ #if ENABLED(EXTENSIBLE_UI) #include "../lcd/extui/ui_api.h" +#elif ENABLED(DWIN_LCD_PROUI) + #include "../lcd/e3v2/proui/dwin.h" #endif #include "../lcd/marlinui.h" @@ -89,11 +89,9 @@ static xyze_pos_t resume_position; PauseMode pause_mode = PAUSE_MODE_PAUSE_PRINT; #endif -#if ENABLED(CONFIGURE_FILAMENT_CHANGE) - fil_change_settings_t fc_settings[EXTRUDERS]; -#endif +fil_change_settings_t fc_settings[EXTRUDERS]; -#if HAS_MEDIA +#if ENABLED(SDSUPPORT) #include "../sd/cardreader.h" #endif @@ -148,7 +146,7 @@ static bool ensure_safe_temperature(const bool wait=true, const PauseMode mode=P thermalManager.setTargetHotend(thermalManager.extrude_min_temp, active_extruder); #endif - ui.pause_show_message(PAUSE_MESSAGE_HEATING, mode); + ui.pause_show_message(PAUSE_MESSAGE_HEATING, mode); UNUSED(mode); if (wait) return thermalManager.wait_for_hotend(active_extruder); @@ -203,7 +201,7 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load KEEPALIVE_STATE(PAUSED_FOR_USER); wait_for_user = true; // LCD click or M108 will clear this - TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_FILAMENTLOAD))); + TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(F("Load Filament"))); #if ENABLED(HOST_PROMPT_SUPPORT) const char tool = '0' + TERN0(MULTI_FILAMENT_SENSOR, active_extruder); @@ -212,14 +210,23 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load while (wait_for_user) { impatient_beep(max_beep_count); - #if ALL(FILAMENT_CHANGE_RESUME_ON_INSERT, FILAMENT_RUNOUT_SENSOR) + #if BOTH(FILAMENT_CHANGE_RESUME_ON_INSERT, FILAMENT_RUNOUT_SENSOR) #if MULTI_FILAMENT_SENSOR - #define _CASE_INSERTED(N) case N-1: if (READ(FIL_RUNOUT##N##_PIN) != FIL_RUNOUT##N##_STATE) wait_for_user = false; break; - switch (active_extruder) { - REPEAT_1(NUM_RUNOUT_SENSORS, _CASE_INSERTED) + LOOP_S_LE_N(i, 1, NUM_RUNOUT_SENSORS) { + pin_t pin; + switch (i) { + default: continue; + #define _CASE_RUNOUT(N) case N: pin = FIL_RUNOUT##N##_PIN; break; + REPEAT_1(NUM_RUNOUT_SENSORS, _CASE_RUNOUT) + #undef _CASE_RUNOUT + } + const RunoutMode rm = runout.mode[i - 1]; + if (rm != RM_NONE && rm != RM_MOTION_SENSOR && extDigitalRead(pin) != runout.out_state(i - 1)) + wait_for_user = false; } #else - if (READ(FIL_RUNOUT_PIN) != FIL_RUNOUT_STATE) wait_for_user = false; + if (READ(FIL_RUNOUT_PIN) != runout.out_state(active_extruder)) + wait_for_user = false; #endif #endif idle_no_sleep(); @@ -236,8 +243,6 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load TERN_(BELTPRINTER, do_blocking_move_to_xy(0.00, 50.00)); - TERN_(MPCTEMP, MPC::e_paused = true); - // Slow Load filament if (slow_load_length) unscaled_e_move(slow_load_length, FILAMENT_CHANGE_SLOW_LOAD_FEEDRATE); @@ -264,7 +269,7 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_PURGE); TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE))); - TERN_(HOST_PROMPT_SUPPORT, hostui.continue_prompt(GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE))); + TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE), FPSTR(CONTINUE_STR))); wait_for_user = true; // A click or M108 breaks the purge_length loop for (float purge_count = purge_length; purge_count > 0 && wait_for_user; --purge_count) unscaled_e_move(1, ADVANCED_PAUSE_PURGE_FEEDRATE); @@ -288,8 +293,8 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load // Show "Purge More" / "Resume" menu and wait for reply KEEPALIVE_STATE(PAUSED_FOR_USER); wait_for_user = false; - #if ANY(HAS_MARLINUI_MENU, EXTENSIBLE_UI) - ui.pause_show_message(PAUSE_MESSAGE_OPTION); // MarlinUI and MKS UI also set PAUSE_RESPONSE_WAIT_FOR + #if EITHER(HAS_MARLINUI_MENU, DWIN_LCD_PROUI) + ui.pause_show_message(PAUSE_MESSAGE_OPTION); // Also sets PAUSE_RESPONSE_WAIT_FOR #else pause_menu_response = PAUSE_RESPONSE_WAIT_FOR; #endif @@ -301,9 +306,6 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load } while (TERN0(M600_PURGE_MORE_RESUMABLE, pause_menu_response == PAUSE_RESPONSE_EXTRUDE_MORE)); #endif - - TERN_(MPCTEMP, MPC::e_paused = false); - TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_end()); return true; @@ -333,18 +335,18 @@ inline void disable_active_extruder() { */ bool unload_filament(const_float_t unload_length, const bool show_lcd/*=false*/, const PauseMode mode/*=PAUSE_MODE_PAUSE_PRINT*/ - #if ALL(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) + #if BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) , const_float_t mix_multiplier/*=1.0*/ #endif ) { DEBUG_SECTION(uf, "unload_filament", true); DEBUG_ECHOLNPGM("... unloadlen:", unload_length, " showlcd:", show_lcd, " mode:", mode - #if ALL(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) + #if BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) , " mixmult:", mix_multiplier #endif ); - #if !ALL(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) + #if !BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) constexpr float mix_multiplier = 1.0f; #endif @@ -404,6 +406,8 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool DEBUG_SECTION(pp, "pause_print", true); DEBUG_ECHOLNPGM("... park.x:", park_point.x, " y:", park_point.y, " z:", park_point.z, " unloadlen:", unload_length, " showlcd:", show_lcd DXC_SAY); + UNUSED(show_lcd); + if (did_pause_print) return false; // already paused #if ENABLED(HOST_ACTION_COMMANDS) @@ -415,12 +419,13 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool #endif TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_open(PROMPT_INFO, F("Pause"), FPSTR(DISMISS_STR))); + TERN_(DWIN_LCD_PROUI, DWIN_Print_Pause()); // Indicate that the printer is paused ++did_pause_print; // Pause the print job and timer - #if HAS_MEDIA + #if ENABLED(SDSUPPORT) const bool was_sd_printing = IS_SD_PRINTING(); if (was_sd_printing) { card.pauseSDPrint(); @@ -445,7 +450,7 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool // Wait for buffered blocks to complete planner.synchronize(); - #if ALL(ADVANCED_PAUSE_FANS_PAUSE, HAS_FAN) + #if ENABLED(ADVANCED_PAUSE_FANS_PAUSE) && HAS_FAN thermalManager.set_fans_paused(true); #endif @@ -465,7 +470,6 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool // If axes don't need to home then the nozzle can park if (do_park) nozzle.park(0, park_point); // Park the nozzle by doing a Minimum Z Raise followed by an XY Move - if (!do_park) LCD_MESSAGE(MSG_PARK_FAILED); #if ENABLED(DUAL_X_CARRIAGE) const int8_t saved_ext = active_extruder; @@ -477,7 +481,9 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool if (unload_length) unload_filament(unload_length, show_lcd, PAUSE_MODE_CHANGE_FILAMENT); - TERN_(DUAL_X_CARRIAGE, set_duplication_enabled(saved_ext_dup_mode, saved_ext)); + #if ENABLED(DUAL_X_CARRIAGE) + set_duplication_enabled(saved_ext_dup_mode, saved_ext); + #endif // Disable the Extruder for manual change disable_active_extruder(); @@ -504,7 +510,7 @@ void show_continue_prompt(const bool is_reload) { ui.pause_show_message(is_reload ? PAUSE_MESSAGE_INSERT : PAUSE_MESSAGE_WAITING); SERIAL_ECHO_START(); - SERIAL_ECHO(is_reload ? F(_PMSG(STR_FILAMENT_CHANGE_INSERT) "\n") : F(_PMSG(STR_FILAMENT_CHANGE_WAIT) "\n")); + SERIAL_ECHOF(is_reload ? F(_PMSG(STR_FILAMENT_CHANGE_INSERT) "\n") : F(_PMSG(STR_FILAMENT_CHANGE_WAIT) "\n")); } void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep_count/*=0*/ DXC_ARGS) { @@ -530,7 +536,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep // Wait for filament insert by user and press button KEEPALIVE_STATE(PAUSED_FOR_USER); - TERN_(HOST_PROMPT_SUPPORT, hostui.continue_prompt(GET_TEXT_F(MSG_NOZZLE_PARKED))); + TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, GET_TEXT_F(MSG_NOZZLE_PARKED), FPSTR(CONTINUE_STR))); TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_NOZZLE_PARKED))); wait_for_user = true; // LCD click or M108 will clear this while (wait_for_user) { @@ -548,17 +554,15 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, GET_TEXT_F(MSG_HEATER_TIMEOUT), GET_TEXT_F(MSG_REHEAT))); - #if ENABLED(TOUCH_UI_FTDI_EVE) - ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_FTDI_HEATER_TIMEOUT)); - #elif ENABLED(EXTENSIBLE_UI) - ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_HEATER_TIMEOUT)); - #endif + TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_HEATER_TIMEOUT))); TERN_(HAS_RESUME_CONTINUE, wait_for_user_response(0, true)); // Wait for LCD click or M108 TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_INFO, GET_TEXT_F(MSG_REHEATING))); - LCD_MESSAGE(MSG_REHEATING); + TERN_(EXTENSIBLE_UI, ExtUI::onStatusChanged(GET_TEXT_F(MSG_REHEATING))); + + TERN_(DWIN_LCD_PROUI, LCD_MESSAGE(MSG_REHEATING)); // Re-enable the heaters if they timed out HOTEND_LOOP() thermalManager.reset_hotend_idle_timer(e); @@ -574,12 +578,9 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep HOTEND_LOOP() thermalManager.heater_idle[e].start(nozzle_timeout); - TERN_(HOST_PROMPT_SUPPORT, hostui.continue_prompt(GET_TEXT_F(MSG_REHEATDONE))); - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_REHEATDONE)); - #else - LCD_MESSAGE(MSG_REHEATDONE); - #endif + TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, GET_TEXT_F(MSG_REHEATDONE), FPSTR(CONTINUE_STR))); + TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_REHEATDONE))); + TERN_(DWIN_LCD_PROUI, LCD_MESSAGE(MSG_REHEATDONE)); IF_DISABLED(PAUSE_REHEAT_FAST_RESUME, wait_for_user = true); @@ -588,7 +589,9 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep } idle_no_sleep(); } - TERN_(DUAL_X_CARRIAGE, set_duplication_enabled(saved_ext_dup_mode, saved_ext)); + #if ENABLED(DUAL_X_CARRIAGE) + set_duplication_enabled(saved_ext_dup_mode, saved_ext); + #endif } /** @@ -705,7 +708,7 @@ void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_ // Resume the print job timer if it was running if (print_job_timer.isPaused()) print_job_timer.start(); - #if HAS_MEDIA + #if ENABLED(SDSUPPORT) if (did_pause_print) { --did_pause_print; card.startOrResumeFilePrinting(); @@ -720,8 +723,13 @@ void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_ TERN_(HAS_FILAMENT_SENSOR, runout.reset()); - ui.reset_status(); - ui.return_to_status(); + #if ENABLED(DWIN_LCD_PROUI) + DWIN_Print_Resume(); + HMI_ReturnScreen(); + #else + ui.reset_status(); + ui.return_to_status(); + #endif } #endif // ADVANCED_PAUSE_FEATURE diff --git a/Marlin/src/feature/runout.cpp b/Marlin/src/feature/runout.cpp index 2bcb47e99a..d6317edb46 100644 --- a/Marlin/src/feature/runout.cpp +++ b/Marlin/src/feature/runout.cpp @@ -32,28 +32,23 @@ FilamentMonitor runout; -bool FilamentMonitorBase::enabled = true, - FilamentMonitorBase::filament_ran_out; // = false - +bool FilamentMonitorBase::enabled[NUM_RUNOUT_SENSORS], // Initialized by settings.load + FilamentMonitorBase::filament_ran_out; // = false +RunoutMode FilamentMonitorBase::mode[NUM_RUNOUT_SENSORS]; // Initialized by settings.load #if ENABLED(HOST_ACTION_COMMANDS) bool FilamentMonitorBase::host_handling; // = false #endif #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) + #define DEBUG_TOOLCHANGE_MIGRATION_FEATURE #include "../module/tool_change.h" #define DEBUG_OUT ENABLED(DEBUG_TOOLCHANGE_MIGRATION_FEATURE) #include "../core/debug_out.h" #endif -#if HAS_FILAMENT_RUNOUT_DISTANCE - float RunoutResponseDelayed::runout_distance_mm = FILAMENT_RUNOUT_DISTANCE_MM; - countdown_t RunoutResponseDelayed::mm_countdown; - #if ENABLED(FILAMENT_MOTION_SENSOR) - uint8_t FilamentSensorEncoder::motion_detected; - #endif -#else - int8_t RunoutResponseDebounced::runout_count[NUM_RUNOUT_SENSORS]; // = 0 -#endif +float RunoutResponseDelayed::runout_distance_mm[NUM_RUNOUT_SENSORS]; // Initialized by settings.load +volatile float RunoutResponseDelayed::runout_mm_countdown[NUM_RUNOUT_SENSORS]; +uint8_t FilamentSensorCore::motion_detected; // // Filament Runout event handler @@ -68,6 +63,8 @@ bool FilamentMonitorBase::enabled = true, #if ENABLED(EXTENSIBLE_UI) #include "../lcd/extui/ui_api.h" +#elif ENABLED(DWIN_LCD_PROUI) + #include "../lcd/e3v2/proui/dwin.h" #endif void event_filament_runout(const uint8_t extruder) { @@ -86,6 +83,7 @@ void event_filament_runout(const uint8_t extruder) { #endif TERN_(EXTENSIBLE_UI, ExtUI::onFilamentRunout(ExtUI::getTool(extruder))); + TERN_(DWIN_LCD_PROUI, DWIN_FilamentRunout(extruder)); #if ANY(HOST_PROMPT_SUPPORT, HOST_ACTION_COMMANDS, MULTI_FILAMENT_SENSOR) const char tool = '0' + TERN0(MULTI_FILAMENT_SENSOR, extruder); @@ -99,16 +97,12 @@ void event_filament_runout(const uint8_t extruder) { const bool run_runout_script = !runout.host_handling; #if ENABLED(HOST_ACTION_COMMANDS) - - const bool park_or_pause = (false - #ifdef FILAMENT_RUNOUT_SCRIPT - || strstr(FILAMENT_RUNOUT_SCRIPT, "M600") + if (run_runout_script + && ( strstr(FILAMENT_RUNOUT_SCRIPT, "M600") || strstr(FILAMENT_RUNOUT_SCRIPT, "M125") || TERN0(ADVANCED_PAUSE_FEATURE, strstr(FILAMENT_RUNOUT_SCRIPT, "M25")) - #endif - ); - - if (run_runout_script && park_or_pause) { + ) + ) { hostui.paused(false); } else { @@ -125,27 +119,24 @@ void event_filament_runout(const uint8_t extruder) { SERIAL_ECHOPGM(" " ACTION_REASON_ON_FILAMENT_RUNOUT " "); SERIAL_CHAR(tool); SERIAL_EOL(); - #endif // HOST_ACTION_COMMANDS - #ifdef FILAMENT_RUNOUT_SCRIPT - if (run_runout_script) { - #if MULTI_FILAMENT_SENSOR - MString script; - script.setf(F(FILAMENT_RUNOUT_SCRIPT), C(tool)); - #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) - SERIAL_ECHOLNPGM("Runout Command: ", &script); - #endif - queue.inject(&script); - #else - #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) - SERIAL_ECHOPGM("Runout Command: "); - SERIAL_ECHOLNPGM(FILAMENT_RUNOUT_SCRIPT); - #endif - queue.inject(F(FILAMENT_RUNOUT_SCRIPT)); + if (run_runout_script) { + #if MULTI_FILAMENT_SENSOR + char script[strlen(FILAMENT_RUNOUT_SCRIPT) + 1]; + sprintf_P(script, PSTR(FILAMENT_RUNOUT_SCRIPT), tool); + #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) + SERIAL_ECHOLNPGM("Runout Command: ", script); #endif - } - #endif + queue.inject(script); + #else + #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) + SERIAL_ECHOPGM("Runout Command: "); + SERIAL_ECHOLNPGM(FILAMENT_RUNOUT_SCRIPT); + #endif + queue.inject(F(FILAMENT_RUNOUT_SCRIPT)); + #endif + } } #endif // HAS_FILAMENT_SENSOR diff --git a/Marlin/src/feature/runout.h b/Marlin/src/feature/runout.h index c95c39f273..261831403b 100644 --- a/Marlin/src/feature/runout.h +++ b/Marlin/src/feature/runout.h @@ -30,8 +30,7 @@ #include "../module/planner.h" #include "../module/stepper.h" // for block_t #include "../gcode/queue.h" -#include "../feature/pause.h" // for did_pause_print -#include "../MarlinCore.h" // for printingIsActive() +#include "../feature/pause.h" #include "../inc/MarlinConfig.h" @@ -44,44 +43,41 @@ #define FILAMENT_RUNOUT_THRESHOLD 5 #endif -#if ENABLED(FILAMENT_MOTION_SENSOR) - #define HAS_FILAMENT_MOTION 1 -#endif -#if DISABLED(FILAMENT_MOTION_SENSOR) || ENABLED(FILAMENT_SWITCH_AND_MOTION) - #define HAS_FILAMENT_SWITCH 1 -#endif - -typedef Flags< - #if NUM_MOTION_SENSORS > NUM_RUNOUT_SENSORS - NUM_MOTION_SENSORS - #else - NUM_RUNOUT_SENSORS - #endif - > runout_flags_t; - void event_filament_runout(const uint8_t extruder); -inline bool should_monitor_runout() { return did_pause_print || printingIsActive(); } template class TFilamentMonitor; -class FilamentSensor; +class FilamentSensorCore; class RunoutResponseDelayed; -class RunoutResponseDebounced; /********************************* TEMPLATE SPECIALIZATION *********************************/ typedef TFilamentMonitor< - TERN(HAS_FILAMENT_RUNOUT_DISTANCE, RunoutResponseDelayed, RunoutResponseDebounced), - FilamentSensor + RunoutResponseDelayed, + FilamentSensorCore > FilamentMonitor; extern FilamentMonitor runout; /*******************************************************************************************/ +enum RunoutMode : uint8_t { + RM_NONE, + RM_OUT_ON_LOW, + RM_OUT_ON_HIGH, + RM_RESERVED3, + RM_RESERVED4, + RM_RESERVED5, + RM_RESERVED6, + RM_MOTION_SENSOR +}; + class FilamentMonitorBase { public: - static bool enabled, filament_ran_out; + static bool enabled[NUM_RUNOUT_SENSORS], filament_ran_out; + static RunoutMode mode[NUM_RUNOUT_SENSORS]; + + static uint8_t out_state(const uint8_t e=0) { return mode[e] == RM_OUT_ON_HIGH ? HIGH : LOW; } #if ENABLED(HOST_ACTION_COMMANDS) static bool host_handling; @@ -111,24 +107,14 @@ class TFilamentMonitor : public FilamentMonitorBase { // Call this method when filament is present, // so the response can reset its counter. - static void filament_present(const uint8_t extruder) { - response.filament_present(extruder); - } - #if ENABLED(FILAMENT_SWITCH_AND_MOTION) - static void filament_motion_present(const uint8_t extruder) { - response.filament_motion_present(extruder); - } - #endif - - #if HAS_FILAMENT_RUNOUT_DISTANCE - static float& runout_distance() { return response.runout_distance_mm; } - static void set_runout_distance(const_float_t mm) { response.runout_distance_mm = mm; } - #endif + static void filament_present(const uint8_t e) { response.filament_present(e); } + static float& runout_distance(const uint8_t e=0) { return response.runout_distance_mm[e]; } + static void set_runout_distance(const_float_t mm, const uint8_t e=0) { response.runout_distance_mm[e] = mm; } // Handle a block completion. RunoutResponseDelayed uses this to // add up the length of filament moved while the filament is out. static void block_completed(const block_t * const b) { - if (enabled) { + if (enabled[active_extruder]) { response.block_completed(b); sensor.block_completed(b); } @@ -136,33 +122,43 @@ class TFilamentMonitor : public FilamentMonitorBase { // Give the response a chance to update its counter. static void run() { - if (enabled && !filament_ran_out && should_monitor_runout()) { - TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, cli()); // Prevent RunoutResponseDelayed::block_completed from accumulating here + if (enabled[active_extruder] && mode[active_extruder] != RM_NONE && !filament_ran_out && (printingIsActive() || did_pause_print)) { + cli(); // Prevent RunoutResponseDelayed::block_completed from accumulating here response.run(); sensor.run(); - const runout_flags_t runout_flags = response.has_run_out(); - TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, sei()); + const uint8_t runout_flags = response.has_run_out(); + sei(); #if MULTI_FILAMENT_SENSOR #if ENABLED(WATCH_ALL_RUNOUT_SENSORS) - const bool ran_out = bool(runout_flags); // any sensor triggers + const bool ran_out = !!runout_flags; // any sensor triggers uint8_t extruder = 0; - if (ran_out) while (!runout_flags.test(extruder)) extruder++; + if (ran_out) { + uint8_t bitmask = runout_flags; + while (!(bitmask & 1)) { + bitmask >>= 1; + extruder++; + } + } #else - const bool ran_out = runout_flags[active_extruder]; // suppress non active extruders + const bool ran_out = TEST(runout_flags, active_extruder); // suppress non active extruders uint8_t extruder = active_extruder; #endif #else - const bool ran_out = bool(runout_flags); + const bool ran_out = !!runout_flags; uint8_t extruder = active_extruder; #endif - if (ran_out) { - #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) + #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) + if (runout_flags) { SERIAL_ECHOPGM("Runout Sensors: "); - for (uint8_t i = 0; i < 8; ++i) SERIAL_CHAR('0' + char(runout_flags[i])); - SERIAL_ECHOLNPGM(" -> ", extruder, " RUN OUT"); - #endif + LOOP_L_N(i, 8) SERIAL_ECHO('0' + TEST(runout_flags, i)); + SERIAL_ECHOPGM(" -> ", extruder); + if (ran_out) SERIAL_ECHOPGM(" RUN OUT"); + SERIAL_EOL(); + } + #endif + if (ran_out) { filament_ran_out = true; event_filament_runout(extruder); planner.synchronize(); @@ -182,26 +178,39 @@ class FilamentSensorBase { static void filament_present(const uint8_t extruder) { runout.filament_present(extruder); // ...which calls response.filament_present(extruder) } - #if ENABLED(FILAMENT_SWITCH_AND_MOTION) - static void filament_motion_present(const uint8_t extruder) { - runout.filament_motion_present(extruder); // ...which calls response.filament_motion_present(extruder) - } - #endif public: static void setup() { - #define _INIT_RUNOUT_PIN(P,S,U,D) do{ if (ENABLED(U)) SET_INPUT_PULLUP(P); else if (ENABLED(D)) SET_INPUT_PULLDOWN(P); else SET_INPUT(P); }while(0); - #define INIT_RUNOUT_PIN(N) _INIT_RUNOUT_PIN(FIL_RUNOUT##N##_PIN, FIL_RUNOUT##N##_STATE, FIL_RUNOUT##N##_PULLUP, FIL_RUNOUT##N##_PULLDOWN); - REPEAT_1(NUM_RUNOUT_SENSORS, INIT_RUNOUT_PIN) - #undef INIT_RUNOUT_PIN - - #if ENABLED(FILAMENT_SWITCH_AND_MOTION) - #define INIT_MOTION_PIN(N) _INIT_RUNOUT_PIN(FIL_MOTION##N##_PIN, FIL_MOTION##N##_STATE, FIL_MOTION##N##_PULLUP, FIL_MOTION##N##_PULLDOWN); - REPEAT_1(NUM_MOTION_SENSORS, INIT_MOTION_PIN) - #undef INIT_MOTION_PIN + #define _INIT_RUNOUT_PIN(P,S,U,D) do{ if (ENABLED(U)) SET_INPUT_PULLUP(P); else if (ENABLED(D)) SET_INPUT_PULLDOWN(P); else SET_INPUT(P); }while(0) + #define INIT_RUNOUT_PIN(N) _INIT_RUNOUT_PIN(FIL_RUNOUT##N##_PIN, FIL_RUNOUT##N##_STATE, FIL_RUNOUT##N##_PULLUP, FIL_RUNOUT##N##_PULLDOWN) + #if NUM_RUNOUT_SENSORS >= 1 + INIT_RUNOUT_PIN(1); + #endif + #if NUM_RUNOUT_SENSORS >= 2 + INIT_RUNOUT_PIN(2); + #endif + #if NUM_RUNOUT_SENSORS >= 3 + INIT_RUNOUT_PIN(3); + #endif + #if NUM_RUNOUT_SENSORS >= 4 + INIT_RUNOUT_PIN(4); + #endif + #if NUM_RUNOUT_SENSORS >= 5 + INIT_RUNOUT_PIN(5); + #endif + #if NUM_RUNOUT_SENSORS >= 6 + INIT_RUNOUT_PIN(6); + #endif + #if NUM_RUNOUT_SENSORS >= 7 + INIT_RUNOUT_PIN(7); + #endif + #if NUM_RUNOUT_SENSORS >= 8 + INIT_RUNOUT_PIN(8); #endif #undef _INIT_RUNOUT_PIN + #undef INIT_RUNOUT_PIN } + // Return a bitmask of runout pin states static uint8_t poll_runout_pins() { @@ -212,275 +221,125 @@ class FilamentSensorBase { // Return a bitmask of runout flag states (1 bits always indicates runout) static uint8_t poll_runout_states() { - #define _INVERT_BIT(N) | (FIL_RUNOUT##N##_STATE ? 0 : _BV(N - 1)) - return poll_runout_pins() ^ uint8_t(0 REPEAT_1(NUM_RUNOUT_SENSORS, _INVERT_BIT)); - #undef _INVERT_BIT + #define _OR_INVERT(N) | (runout.out_state(N-1) ? 0 : _BV(N-1)) + return poll_runout_pins() ^ uint8_t(0 REPEAT_1(NUM_RUNOUT_SENSORS, _OR_INVERT)); + #undef _OR_INVERT } - - #if ENABLED(FILAMENT_SWITCH_AND_MOTION) - // Return a bitmask of motion pin states - static uint8_t poll_motion_pins() { - #define _OR_MOTION(N) | (READ(FIL_MOTION##N##_PIN) ? _BV((N) - 1) : 0) - return (0 REPEAT_1(NUM_MOTION_SENSORS, _OR_MOTION)); - #undef _OR_MOTION - } - - // Return a bitmask of motion flag states (1 bits always indicates runout) - static uint8_t poll_motion_states() { - #define _OR_MOTION(N) | (FIL_MOTION##N##_STATE ? 0 : _BV(N - 1)) - return poll_motion_pins() ^ uint8_t(0 REPEAT_1(NUM_MOTION_SENSORS, _OR_MOTION)); - #undef _OR_MOTION - } - #endif }; -#if HAS_FILAMENT_MOTION +class FilamentSensorCore : public FilamentSensorBase { + private: + static uint8_t motion_detected; - /** - * This sensor uses a magnetic encoder disc and a Hall effect - * sensor (or a slotted disc and optical sensor). The state - * will toggle between 0 and 1 on filament movement. It can detect - * filament runout and stripouts or jams. - */ - class FilamentSensorEncoder : public FilamentSensorBase { - private: - static uint8_t motion_detected; + static bool poll_runout_state(const uint8_t extruder) { + const uint8_t runout_states = poll_runout_states(); + #if MULTI_FILAMENT_SENSOR + if ( !TERN0(DUAL_X_CARRIAGE, idex_is_duplicating()) + && !TERN0(MULTI_NOZZLE_DUPLICATION, extruder_duplication_enabled) + ) return TEST(runout_states, extruder); // A specific extruder ran out + #else + UNUSED(extruder); + #endif + return !!runout_states; // Any extruder ran out + } - static void poll_motion_sensor() { - static uint8_t old_state; - const uint8_t new_state = TERN(FILAMENT_SWITCH_AND_MOTION, poll_motion_pins, poll_runout_pins)(), - change = old_state ^ new_state; - old_state = new_state; + static void poll_motion_sensor() { + static uint8_t old_state; + const uint8_t new_state = poll_runout_pins(), + change = old_state ^ new_state; + old_state = new_state; - #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) - if (change) { - SERIAL_ECHOPGM("Motion detected:"); - for (uint8_t e = 0; e < TERN(FILAMENT_SWITCH_AND_MOTION, NUM_MOTION_SENSORS, NUM_RUNOUT_SENSORS); ++e) - if (TEST(change, e)) SERIAL_CHAR(' ', '0' + e); - SERIAL_EOL(); - } - #endif + #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) + if (change) { + SERIAL_ECHOPGM("Motion detected:"); + LOOP_L_N(e, NUM_RUNOUT_SENSORS) + if (TEST(change, e)) SERIAL_CHAR(' ', '0' + e); + SERIAL_EOL(); + } + #endif - motion_detected |= change; + motion_detected |= change; + } + + public: + static void block_completed(const block_t * const b) { + if (runout.mode[active_extruder] != RM_MOTION_SENSOR) return; + + // If the sensor wheel has moved since the last call to + // this method reset the runout counter for the extruder. + if (TEST(motion_detected, b->extruder)) + filament_present(b->extruder); + + // Clear motion triggers for next block + motion_detected = 0; + } + + static void run() { + if (runout.mode[active_extruder] == RM_MOTION_SENSOR) { + poll_motion_sensor(); } - - public: - static void block_completed(const block_t * const b) { - // If the sensor wheel has moved since the last call to - // this method reset the runout counter for the extruder. - if (TEST(motion_detected, b->extruder)) - TERN(FILAMENT_SWITCH_AND_MOTION, filament_motion_present, filament_present)(b->extruder); - - // Clear motion triggers for next block - motion_detected = 0; - } - - static void run() { poll_motion_sensor(); } - }; - -#endif // HAS_FILAMENT_MOTION - -#if HAS_FILAMENT_SWITCH - - /** - * This is a simple endstop switch in the path of the filament. - * It can detect filament runout, but not stripouts or jams. - */ - class FilamentSensorSwitch : public FilamentSensorBase { - private: - static bool poll_runout_state(const uint8_t extruder) { - const uint8_t runout_states = poll_runout_states(); - #if MULTI_FILAMENT_SENSOR - if ( !TERN0(DUAL_X_CARRIAGE, idex_is_duplicating()) - && !TERN0(MULTI_NOZZLE_DUPLICATION, extruder_duplication_enabled) - ) return TEST(runout_states, extruder); // A specific extruder ran out - #else - UNUSED(extruder); - #endif - return !!runout_states; // Any extruder ran out - } - - public: - static void block_completed(const block_t * const) {} - - static void run() { - for (uint8_t s = 0; s < NUM_RUNOUT_SENSORS; ++s) { + else if (runout.mode[active_extruder] != RM_NONE) { + LOOP_L_N(s, NUM_RUNOUT_SENSORS) { const bool out = poll_runout_state(s); if (!out) filament_present(s); #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) static uint8_t was_out; // = 0 if (out != TEST(was_out, s)) { TBI(was_out, s); - SERIAL_ECHOLN(F("Filament Sensor "), AS_DIGIT(s), out ? F(" OUT") : F(" IN")); + SERIAL_ECHOLNF(F("Filament Sensor "), AS_DIGIT(s), out ? F(" OUT") : F(" IN")); } #endif } } - }; + } +}; - #endif // HAS_FILAMENT_SWITCH - - /** - * This is a simple endstop switch in the path of the filament. - * It can detect filament runout, but not stripouts or jams. - */ - class FilamentSensor : public FilamentSensorBase { - private: - TERN_(HAS_FILAMENT_MOTION, static FilamentSensorEncoder encoder_sensor); - TERN_(HAS_FILAMENT_SWITCH, static FilamentSensorSwitch switch_sensor); - - public: - static void block_completed(const block_t * const b) { - TERN_(HAS_FILAMENT_MOTION, encoder_sensor.block_completed(b)); - TERN_(HAS_FILAMENT_SWITCH, switch_sensor.block_completed(b)); - } - - static void run() { - TERN_(HAS_FILAMENT_MOTION, encoder_sensor.run()); - TERN_(HAS_FILAMENT_SWITCH, switch_sensor.run()); - } - }; /********************************* RESPONSE TYPE *********************************/ -#if HAS_FILAMENT_RUNOUT_DISTANCE +// RunoutResponseDelayed triggers a runout event only if the length +// of filament specified by FIL_RUNOUT_DISTANCE_MM has been fed +// during a runout condition. +class RunoutResponseDelayed { + private: + static volatile float runout_mm_countdown[NUM_RUNOUT_SENSORS]; - typedef struct { - float runout[NUM_RUNOUT_SENSORS]; - Flags runout_reset; // Reset runout later - #if ENABLED(FILAMENT_SWITCH_AND_MOTION) - float motion[NUM_MOTION_SENSORS]; - Flags motion_reset; // Reset motion later - #endif - } countdown_t; + public: + static float runout_distance_mm[NUM_RUNOUT_SENSORS]; - // RunoutResponseDelayed triggers a runout event only if the length - // of filament specified by FILAMENT_RUNOUT_DISTANCE_MM has been fed - // during a runout condition. - class RunoutResponseDelayed { - private: - static countdown_t mm_countdown; + static void reset() { + LOOP_L_N(i, NUM_RUNOUT_SENSORS) filament_present(i); + } - public: - static float runout_distance_mm; - - static void reset() { - for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) filament_present(i); - #if ENABLED(FILAMENT_SWITCH_AND_MOTION) - for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i) filament_motion_present(i); - #endif - } - - static void run() { - #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) - static millis_t t = 0; - const millis_t ms = millis(); - if (ELAPSED(ms, t)) { - t = millis() + 1000UL; - for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) - SERIAL_ECHO(i ? F(", ") : F("Runout remaining mm: "), mm_countdown.runout[i]); - #if ENABLED(FILAMENT_SWITCH_AND_MOTION) - for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i) - SERIAL_ECHO(i ? F(", ") : F("Motion remaining mm: "), mm_countdown.motion[i]); - #endif - SERIAL_EOL(); - } - #endif - } - - static runout_flags_t has_run_out() { - runout_flags_t runout_flags{0}; - for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) if (mm_countdown.runout[i] < 0) runout_flags.set(i); - #if ENABLED(FILAMENT_SWITCH_AND_MOTION) - for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i) if (mm_countdown.motion[i] < 0) runout_flags.set(i); - #endif - return runout_flags; - } - - static void filament_present(const uint8_t extruder) { - if (mm_countdown.runout[extruder] < runout_distance_mm || did_pause_print) { - // Reset runout only if it is smaller than runout_distance or printing is paused. - // On Bowden systems retract may be larger than runout_distance_mm, so if retract - // was added leave it in place, or the following unretract will cause runout event. - mm_countdown.runout[extruder] = runout_distance_mm; - mm_countdown.runout_reset.clear(extruder); - } - else { - // If runout is larger than runout distance, we cannot reset right now, as Bowden and retract - // distance larger than runout_distance_mm leads to negative runout right after unretract. - // But we cannot ignore filament_present event. After unretract, runout will become smaller - // than runout_distance_mm and should be reset after that. So activate delayed reset. - mm_countdown.runout_reset.set(extruder); - } - } - - #if ENABLED(FILAMENT_SWITCH_AND_MOTION) - static void filament_motion_present(const uint8_t extruder) { - // Same logic as filament_present - if (mm_countdown.motion[extruder] < runout_distance_mm || did_pause_print) { - mm_countdown.motion[extruder] = runout_distance_mm; - mm_countdown.motion_reset.clear(extruder); - } - else - mm_countdown.motion_reset.set(extruder); + static void run() { + #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) + static millis_t t = 0; + const millis_t ms = millis(); + if (ELAPSED(ms, t)) { + t = millis() + 1000UL; + LOOP_L_N(i, NUM_RUNOUT_SENSORS) + SERIAL_ECHOF(i ? F(", ") : F("Remaining mm: "), runout_mm_countdown[i]); + SERIAL_EOL(); } #endif + } - static void block_completed(const block_t * const b) { - const int32_t esteps = b->steps.e; - if (!esteps) return; + static uint8_t has_run_out() { + uint8_t runout_flags = 0; + LOOP_L_N(i, NUM_RUNOUT_SENSORS) if (runout_mm_countdown[i] < 0) SBI(runout_flags, i); + return runout_flags; + } - // No calculation unless paused or printing - if (!should_monitor_runout()) return; + static void filament_present(const uint8_t extruder) { + runout_mm_countdown[extruder] = runout_distance_mm[extruder]; + } - // No need to ignore retract/unretract movement since they complement each other + static void block_completed(const block_t * const b) { + if (b->steps.x || b->steps.y || b->steps.z || did_pause_print) { // Allow pause purge move to re-trigger runout state + // Only trigger on extrusion with XYZ movement to allow filament change and retract/recover. const uint8_t e = b->extruder; - const float mm = (b->direction_bits.e ? esteps : -esteps) * planner.mm_per_step[E_AXIS_N(e)]; - - if (e < NUM_RUNOUT_SENSORS) { - mm_countdown.runout[e] -= mm; - if (mm_countdown.runout_reset[e]) filament_present(e); // Reset pending. Try to reset. - } - - #if ENABLED(FILAMENT_SWITCH_AND_MOTION) - if (e < NUM_MOTION_SENSORS) { - mm_countdown.motion[e] -= mm; - if (mm_countdown.motion_reset[e]) filament_motion_present(e); // Reset pending. Try to reset. - } - #endif + const int32_t steps = b->steps.e; + runout_mm_countdown[e] -= (TEST(b->direction_bits, E_AXIS) ? -steps : steps) * planner.mm_per_step[E_AXIS_N(e)]; } - }; - -#else // !HAS_FILAMENT_RUNOUT_DISTANCE - - // RunoutResponseDebounced triggers a runout event after a runout - // condition has been detected runout_threshold times in a row. - - class RunoutResponseDebounced { - private: - static constexpr int8_t runout_threshold = FILAMENT_RUNOUT_THRESHOLD; - static int8_t runout_count[NUM_RUNOUT_SENSORS]; - - public: - static void reset() { - for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) filament_present(i); - } - - static void run() { - for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) if (runout_count[i] >= 0) runout_count[i]--; - } - - static runout_flags_t has_run_out() { - runout_flags_t runout_flags{0}; - for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) if (runout_count[i] < 0) runout_flags.set(i); - return runout_flags; - } - - static void block_completed(const block_t * const) { } - - static void filament_present(const uint8_t extruder) { - runout_count[extruder] = runout_threshold; - } - }; - -#endif // !HAS_FILAMENT_RUNOUT_DISTANCE + } +}; diff --git a/Marlin/src/gcode/feature/pause/M600.cpp b/Marlin/src/gcode/feature/pause/M600.cpp index c42db203b6..4d0da2897d 100644 --- a/Marlin/src/gcode/feature/pause/M600.cpp +++ b/Marlin/src/gcode/feature/pause/M600.cpp @@ -94,7 +94,7 @@ void GcodeSuite::M600() { // In this case, for duplicating modes set DXC_ext to the extruder that ran out. #if MULTI_FILAMENT_SENSOR if (idex_is_duplicating()) - DXC_ext = (READ(FIL_RUNOUT2_PIN) == FIL_RUNOUT2_STATE) ? 1 : 0; + DXC_ext = (READ(FIL_RUNOUT2_PIN) == runout.out_state(1)) ? 1 : 0; #else DXC_ext = active_extruder; #endif diff --git a/Marlin/src/gcode/feature/runout/M412.cpp b/Marlin/src/gcode/feature/runout/M412.cpp deleted file mode 100644 index 4cfb238309..0000000000 --- a/Marlin/src/gcode/feature/runout/M412.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/** - * 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 . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if HAS_FILAMENT_SENSOR - -#include "../../gcode.h" -#include "../../../feature/runout.h" - -/** - * M412: Enable / Disable filament runout detection - * - * Parameters - * R : Reset the runout sensor - * S : Reset and enable/disable the runout sensor - * H : Enable/disable host handling of filament runout - * D : Extra distance to continue after runout is triggered - */ -void GcodeSuite::M412() { - if (parser.seen("RS" - TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, "D") - TERN_(HOST_ACTION_COMMANDS, "H") - )) { - #if ENABLED(HOST_ACTION_COMMANDS) - if (parser.seen('H')) runout.host_handling = parser.value_bool(); - #endif - const bool seenR = parser.seen_test('R'), seenS = parser.seen('S'); - if (seenR || seenS) runout.reset(); - if (seenS) runout.enabled = parser.value_bool(); - #if HAS_FILAMENT_RUNOUT_DISTANCE - if (parser.seenval('D')) runout.set_runout_distance(parser.value_linear_units()); - #endif - } - else { - SERIAL_ECHO_START(); - SERIAL_ECHOPGM("Filament runout "); - serialprint_onoff(runout.enabled); - #if HAS_FILAMENT_RUNOUT_DISTANCE - SERIAL_ECHOPGM(" ; Distance ", runout.runout_distance(), "mm"); - #endif - #if ENABLED(HOST_ACTION_COMMANDS) - SERIAL_ECHOPGM(" ; Host handling "); - serialprint_onoff(runout.host_handling); - #endif - SERIAL_EOL(); - } -} - -void GcodeSuite::M412_report(const bool forReplay/*=true*/) { - TERN_(MARLIN_SMALL_BUILD, return); - - report_heading_etc(forReplay, F(STR_FILAMENT_RUNOUT_SENSOR)); - SERIAL_ECHOPGM( - " M412 S", runout.enabled - #if HAS_FILAMENT_RUNOUT_DISTANCE - , " D", LINEAR_UNIT(runout.runout_distance()) - #endif - , " ; Sensor " - ); - serialprintln_onoff(runout.enabled); -} - -#endif // HAS_FILAMENT_SENSOR diff --git a/Marlin/src/gcode/feature/runout/M591.cpp b/Marlin/src/gcode/feature/runout/M591.cpp new file mode 100644 index 0000000000..adb1bb8599 --- /dev/null +++ b/Marlin/src/gcode/feature/runout/M591.cpp @@ -0,0 +1,97 @@ +/** + * 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 . + * + */ + +#include "../../../inc/MarlinConfig.h" + +#if HAS_FILAMENT_SENSOR + +#include "../../gcode.h" +#include "../../../feature/runout.h" + +/** + * M591: Configure filament runout detection + * + * Parameters + * R : Reset the runout sensor + * S : Reset and enable/disable the runout sensor + * H : Enable/disable host handling of filament runout + * L : Extra distance to continue after runout is triggered or motion interval + * D : Alias for L + * P : Mode 0 = NONE + * 1 = Switch NO (HIGH = filament present) + * 2 = Switch NC (LOW = filament present) + * 3 = Encoder / Motion Sensor + */ +void GcodeSuite::M591() { + if (parser.seen("RSDP" TERN_(HOST_ACTION_COMMANDS, "H"))) { + #if ENABLED(HOST_ACTION_COMMANDS) + if (parser.seen('H')) runout.host_handling = parser.value_bool(); + #endif + const bool seenR = parser.seen_test('R'), seenS = parser.seen('S'); + if (seenR || seenS) runout.reset(); + const uint8_t tool = TERN0(MULTI_FILAMENT_SENSOR, parser.ushortval('E', active_extruder)); + if (seenS) runout.enabled[tool] = parser.value_bool(); + if (parser.seen('D') || parser.seen('L')) runout.set_runout_distance(parser.value_linear_units(), tool); + if (parser.seen('P')) { + const RunoutMode tmp_mode = (RunoutMode)parser.value_int(); + switch (tmp_mode) { + case RM_NONE ... RM_OUT_ON_HIGH: + case RM_MOTION_SENSOR: + runout.mode[tool] = tmp_mode; + runout.setup(); + default: break; + } + } + } + else { + #if DISABLED(SLIM_LCD_MENUS) + SERIAL_ECHO_START(); + SERIAL_ECHOPGM("Filament runout "); + serialprint_onoff(runout.enabled[active_extruder]); + SERIAL_ECHOPGM(" ; Distance ", runout.runout_distance(active_extruder), "mm"); + SERIAL_ECHOPGM(" ; Mode ", runout.mode[active_extruder]); + #if ENABLED(HOST_ACTION_COMMANDS) + SERIAL_ECHOPGM(" ; Host handling "); + serialprint_onoff(runout.host_handling); + #endif + SERIAL_EOL(); + #else + M591_report(false); + #endif + } +} + +void GcodeSuite::M591_report(const bool forReplay/*=true*/) { + report_heading_etc(forReplay, F(STR_FILAMENT_RUNOUT_SENSOR)); + LOOP_S_L_N(e, 1, NUM_RUNOUT_SENSORS) + SERIAL_ECHOLNPGM( + " M591" + #if MULTI_FILAMENT_SENSOR + " E", e, + #endif + " S", runout.enabled[e] + , " D", LINEAR_UNIT(runout.runout_distance(e)) + , " P", runout.mode[e] + ); +} + +#endif // HAS_FILAMENT_SENSOR diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index 1ff643dc21..c13b5428af 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -75,14 +75,26 @@ GcodeSuite gcode; millis_t GcodeSuite::previous_move_ms = 0, GcodeSuite::max_inactive_time = 0; -#if HAS_DISABLE_IDLE_AXES - millis_t GcodeSuite::stepper_inactive_time = SEC_TO_MS(DEFAULT_STEPPER_TIMEOUT_SEC); +#if HAS_DISABLE_INACTIVE_AXIS + millis_t GcodeSuite::stepper_inactive_time = SEC_TO_MS(DEFAULT_STEPPER_DEACTIVE_TIME); #endif // Relative motion mode for each logical axis -relative_t GcodeSuite::axis_relative; // Init in constructor +static constexpr xyze_bool_t ar_init = AXIS_RELATIVE_MODES; +axis_bits_t GcodeSuite::axis_relative = 0 LOGICAL_AXIS_GANG( + | (ar_init.e << REL_E), + | (ar_init.x << REL_X), + | (ar_init.y << REL_Y), + | (ar_init.z << REL_Z), + | (ar_init.i << REL_I), + | (ar_init.j << REL_J), + | (ar_init.k << REL_K), + | (ar_init.u << REL_U), + | (ar_init.v << REL_V), + | (ar_init.w << REL_W) +); -#if ANY(HAS_AUTO_REPORTING, HOST_KEEPALIVE_FEATURE) +#if EITHER(HAS_AUTO_REPORTING, HOST_KEEPALIVE_FEATURE) bool GcodeSuite::autoreport_paused; // = false #endif @@ -105,7 +117,8 @@ void GcodeSuite::report_heading(const bool forReplay, FSTR_P const fstr, const b if (forReplay) return; if (fstr) { SERIAL_ECHO_START(); - SERIAL_ECHO(F("; "), fstr); + SERIAL_ECHOPGM("; "); + SERIAL_ECHOF(fstr); } if (eol) { SERIAL_CHAR(':'); SERIAL_EOL(); } } @@ -122,16 +135,14 @@ void GcodeSuite::say_units() { * Return -1 if the T parameter is out of range */ int8_t GcodeSuite::get_target_extruder_from_command() { - #if HAS_TOOLCHANGE - if (parser.seenval('T')) { - const int8_t e = parser.value_byte(); - if (e < EXTRUDERS) return e; - SERIAL_ECHO_START(); - SERIAL_CHAR('M'); SERIAL_ECHO(parser.codenum); - SERIAL_ECHOLNPGM(" " STR_INVALID_EXTRUDER " ", e); - return -1; - } - #endif + if (parser.seenval('T')) { + const int8_t e = parser.value_byte(); + if (e < EXTRUDERS) return e; + SERIAL_ECHO_START(); + SERIAL_CHAR('M'); SERIAL_ECHO(parser.codenum); + SERIAL_ECHOLNPGM(" " STR_INVALID_EXTRUDER " ", e); + return -1; + } return active_extruder; } @@ -155,7 +166,7 @@ int8_t GcodeSuite::get_target_e_stepper_from_command(const int8_t dval/*=-1*/) { } /** - * Set XYZ...E destination and feedrate from the current G-Code command + * Set XYZ...E destination and feedrate from the current GCode command * * - Set destination from included axis codes * - Set to current for missing axis codes @@ -205,13 +216,13 @@ void GcodeSuite::get_destination_from_command() { TERN_(LASER_FEATURE, cutter.feedrate_mm_m = MMS_TO_MMM(feedrate_mm_s)); } - #if ALL(PRINTCOUNTER, HAS_EXTRUDERS) + #if BOTH(PRINTCOUNTER, HAS_EXTRUDERS) if (!DEBUGGING(DRYRUN) && !skip_move) print_job_timer.incFilamentUsed(destination.e - current_position.e); #endif // Get ABCDHI mixing factors - #if ALL(MIXING_EXTRUDER, DIRECT_MIXING_IN_G1) + #if BOTH(MIXING_EXTRUDER, DIRECT_MIXING_IN_G1) M165(); #endif @@ -443,7 +454,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 61: G61(); break; // G61: Apply/restore saved coordinates. #endif - #if ALL(PTC_PROBE, PTC_BED) + #if BOTH(PTC_PROBE, PTC_BED) case 76: G76(); break; // G76: Calibrate first layer compensation values #endif @@ -461,7 +472,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { #endif #if ENABLED(DEBUG_GCODE_PARSER) - case 800: parser.debug(); break; // G800: G-Code Parser Test for G + case 800: parser.debug(); break; // G800: GCode Parser Test for G #endif default: parser.unknown_command_warning(); break; @@ -485,11 +496,11 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 7: M7(); break; // M7: Coolant Mist ON #endif - #if ANY(AIR_ASSIST, COOLANT_FLOOD) + #if EITHER(AIR_ASSIST, COOLANT_FLOOD) case 8: M8(); break; // M8: Air Assist / Coolant Flood ON #endif - #if ANY(AIR_ASSIST, COOLANT_CONTROL) + #if EITHER(AIR_ASSIST, COOLANT_CONTROL) case 9: M9(); break; // M9: Air Assist / Coolant OFF #endif @@ -508,7 +519,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 17: M17(); break; // M17: Enable all stepper motors - #if HAS_MEDIA + #if ENABLED(SDSUPPORT) case 20: M20(); break; // M20: List SD card case 21: M21(); break; // M21: Init SD card case 22: M22(); break; // M22: Release SD card @@ -529,12 +540,12 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 33: M33(); break; // M33: Get the long full path to a file or folder #endif - #if ALL(SDCARD_SORT_ALPHA, SDSORT_GCODE) + #if BOTH(SDCARD_SORT_ALPHA, SDSORT_GCODE) case 34: M34(); break; // M34: Set SD card sorting options #endif case 928: M928(); break; // M928: Start SD write - #endif // HAS_MEDIA + #endif // SDSUPPORT case 31: M31(); break; // M31: Report time since the start of SD print or last M109 @@ -570,7 +581,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 102: M102(); break; // M102: Configure Bed Distance Sensor #endif - #if HAS_HOTEND + #if HAS_EXTRUDERS case 104: M104(); break; // M104: Set hot end temperature case 109: M109(); break; // M109: Wait for hotend temperature to reach target #endif @@ -629,7 +640,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 154: M154(); break; // M154: Set position auto-report interval #endif - #if ALL(AUTO_REPORT_TEMPERATURES, HAS_TEMP_SENSOR) + #if BOTH(AUTO_REPORT_TEMPERATURES, HAS_TEMP_SENSOR) case 155: M155(); break; // M155: Set temperature auto-report interval #endif @@ -660,24 +671,11 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 82: M82(); break; // M82: Set E axis normal mode (same as other axes) case 83: M83(); break; // M83: Set E axis relative mode #endif - case 18: case 84: M18_M84(); break; // M18/M84: Disable Steppers / Set Timeout case 85: M85(); break; // M85: Set inactivity stepper shutdown timeout - - #if ENABLED(HOTEND_IDLE_TIMEOUT) - case 86: M86(); break; // M86: Set Hotend Idle Timeout - case 87: M87(); break; // M87: Cancel Hotend Idle Timeout - #endif - - #if ENABLED(EDITABLE_STEPS_PER_UNIT) - case 92: M92(); break; // M92: Set the steps-per-unit for one or more axes - #endif - + case 92: M92(); break; // M92: Set the steps-per-unit for one or more axes case 114: M114(); break; // M114: Report current position - - #if ENABLED(CAPABILITIES_REPORT) - case 115: M115(); break; // M115: Report capabilities - #endif + case 115: M115(); break; // M115: Report capabilities case 117: TERN_(HAS_STATUS_MESSAGE, M117()); break; // M117: Set LCD message text, if possible @@ -723,7 +721,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 204: M204(); break; // M204: Set acceleration case 205: M205(); break; // M205: Set advanced settings - #if HAS_HOME_OFFSET + #if HAS_M206_COMMAND case 206: M206(); break; // M206: Set home offsets #endif @@ -771,10 +769,6 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { #if ENABLED(BABYSTEPPING) case 290: M290(); break; // M290: Babystepping - #if ENABLED(EP_BABYSTEPPING) - case 293: IF_DISABLED(EMERGENCY_PARSER, M293()); break; // M293: Babystep up - case 294: IF_DISABLED(EMERGENCY_PARSER, M294()); break; // M294: Babystep down - #endif #endif #if HAS_SOUND @@ -801,7 +795,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 250: M250(); break; // M250: Set LCD contrast #endif - #if ENABLED(EDITABLE_DISPLAY_TIMEOUT) + #if HAS_GCODE_M255 case 255: M255(); break; // M255: Set LCD Sleep/Backlight Timeout (Minutes) #endif @@ -842,7 +836,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 364: if (M364()) return; break; // M364: SCARA Psi pos3 (90 deg to Theta) #endif - #if ANY(EXT_SOLENOID, MANUAL_SOLENOID_CONTROL) + #if EITHER(EXT_SOLENOID, MANUAL_SOLENOID_CONTROL) case 380: M380(); break; // M380: Activate solenoid on active (or specified) extruder case 381: M381(); break; // M381: Disable all solenoids or, if MANUAL_SOLENOID_CONTROL, active (or specified) solenoid #endif @@ -865,10 +859,6 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 407: M407(); break; // M407: Display measured filament diameter #endif - #if HAS_FILAMENT_SENSOR - case 412: M412(); break; // M412: Enable/Disable filament runout detection - #endif - #if HAS_MULTI_LANGUAGE case 414: M414(); break; // M414: Select multi language menu #endif @@ -889,7 +879,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 425: M425(); break; // M425: Tune backlash compensation #endif - #if HAS_HOME_OFFSET + #if HAS_M206_COMMAND case 428: M428(); break; // M428: Apply current_position to home_offset #endif @@ -901,10 +891,6 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 486: M486(); break; // M486: Identify and cancel objects #endif - #if ENABLED(FT_MOTION) - case 493: M493(); break; // M493: Fixed-Time Motion control - #endif - case 500: M500(); break; // M500: Store settings in EEPROM case 501: M501(); break; // M501: Read settings from EEPROM case 502: M502(); break; // M502: Revert to default settings @@ -925,7 +911,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { #endif #endif - #if HAS_MEDIA + #if ENABLED(SDSUPPORT) case 524: M524(); break; // M524: Abort the current SD print job #endif @@ -943,19 +929,14 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 575: M575(); break; // M575: Set serial baudrate #endif - #if ENABLED(NONLINEAR_EXTRUSION) - case 592: M592(); break; // M592: Nonlinear Extrusion control - #endif - - #if HAS_ZV_SHAPING - case 593: M593(); break; // M593: Input Shaping control + #if HAS_FILAMENT_SENSOR + case 412: M412(); break; // Alias to M591 + case 591: M591(); break; // M591 Configure filament runout detection #endif #if ENABLED(ADVANCED_PAUSE_FEATURE) case 600: M600(); break; // M600: Pause for Filament Change - #if ENABLED(CONFIGURE_FILAMENT_CHANGE) - case 603: M603(); break; // M603: Configure Filament Change - #endif + case 603: M603(); break; // M603: Configure Filament Change #endif #if HAS_DUPLICATION_MODE @@ -966,7 +947,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 665: M665(); break; // M665: Set Kinematics parameters #endif - #if ANY(DELTA, HAS_EXTRA_ENDSTOPS) + #if ENABLED(DELTA) || HAS_EXTRA_ENDSTOPS case 666: M666(); break; // M666: Set delta or multiple endstop adjustment #endif @@ -1007,7 +988,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { #if ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_PWM, HAS_MOTOR_CURRENT_I2C, HAS_MOTOR_CURRENT_DAC) case 907: M907(); break; // M907: Set digital trimpot motor current using axis codes. - #if ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_DAC) + #if EITHER(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_DAC) case 908: M908(); break; // M908: Control digital trimpot directly. #if HAS_MOTOR_CURRENT_DAC case 909: M909(); break; // M909: Print digipot/DAC current value @@ -1045,7 +1026,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { #endif #if ENABLED(DEBUG_GCODE_PARSER) - case 800: parser.debug(); break; // M800: G-Code Parser Test for M + case 800: parser.debug(); break; // M800: GCode Parser Test for M #endif #if ENABLED(GCODE_REPEAT_MARKERS) @@ -1073,11 +1054,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 422: M422(); break; // M422: Set Z Stepper automatic alignment position using probe #endif - #if ENABLED(OTA_FIRMWARE_UPDATE) - case 936: M936(); break; // M936: OTA update firmware. - #endif - - #if SPI_FLASH_BACKUP + #if ALL(SPI_FLASH, SDSUPPORT, MARLIN_DEV_MODE) case 993: M993(); break; // M993: Backup SPI Flash to SD case 994: M994(); break; // M994: Load a Backup from SD to SPI Flash #endif @@ -1097,11 +1074,11 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 1000: M1000(); break; // M1000: [INTERNAL] Resume from power-loss #endif - #if HAS_MEDIA + #if ENABLED(SDSUPPORT) case 1001: M1001(); break; // M1001: [INTERNAL] Handle SD completion #endif - #if DGUS_LCD_UI_MKS + #if ENABLED(DGUS_LCD_UI_MKS) case 1002: M1002(); break; // M1002: [INTERNAL] Tool-change and Relative E Move #endif @@ -1140,7 +1117,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { if (!no_ok) queue.ok_to_send(); - SERIAL_IMPL.msgDone(); // Call the msgDone serial hook to signal command processing done + SERIAL_OUT(msgDone); // Call the msgDone serial hook to signal command processing done } #if ENABLED(M100_FREE_MEMORY_DUMPER) @@ -1187,7 +1164,10 @@ void GcodeSuite::process_subcommands_now(FSTR_P fgcode) { for (;;) { PGM_P const delim = strchr_P(pgcode, '\n'); // Get address of next newline const size_t len = delim ? delim - pgcode : strlen_P(pgcode); // Get the command length - parser.parse(MString().setn_P(pgcode, len)); // Parse the command + char cmd[len + 1]; // Allocate a stack buffer + strncpy_P(cmd, pgcode, len); // Copy the command to the stack + cmd[len] = '\0'; // End with a nul + parser.parse(cmd); // Parse the command process_parsed_command(true); // Process it (no "ok") if (!delim) break; // Last command? pgcode = delim + 1; // Get the next command diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index 8004187903..2b506018e2 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -234,7 +234,6 @@ * M406 - Disable Filament Sensor flow control. (Requires FILAMENT_WIDTH_SENSOR) * M407 - Display measured filament diameter in millimeters. (Requires FILAMENT_WIDTH_SENSOR) * M410 - Quickstop. Abort all planned moves. - * M412 - Enable / Disable Filament Runout Detection. (Requires FILAMENT_RUNOUT_SENSOR) * M413 - Enable / Disable Power-Loss Recovery. (Requires POWER_LOSS_RECOVERY) * M414 - Set language by index. (Requires LCD_LANGUAGE_2...) * M420 - Enable/Disable Leveling (with current values) S1=enable S0=disable (Requires MESH_BED_LEVELING or ABL) @@ -261,6 +260,7 @@ * M575 - Change the serial baud rate. (Requires BAUD_RATE_GCODE) * M592 - Get or set nonlinear extrusion parameters. (Requires NONLINEAR_EXTRUSION) * M593 - Get or set input shaping parameters. (Requires INPUT_SHAPING_[XY]) + * M591 - Configure Filament Runout Detection. (Requires FILAMENT_RUNOUT_SENSOR) * M600 - Pause for filament change: "M600 X Y Z E L". (Requires ADVANCED_PAUSE_FEATURE) * M603 - Configure filament change: "M603 T U L". (Requires ADVANCED_PAUSE_FEATURE) * M605 - Set Dual X-Carriage movement mode: "M605 S [X] [R]". (Requires DUAL_X_CARRIAGE) @@ -1035,8 +1035,9 @@ private: #endif #if HAS_FILAMENT_SENSOR - static void M412(); - static void M412_report(const bool forReplay=true); + static void M412() { M591(); } + static void M591(); + static void M591_report(const bool forReplay=true); #endif #if HAS_MULTI_LANGUAGE diff --git a/Marlin/src/gcode/host/M115.cpp b/Marlin/src/gcode/host/M115.cpp index 0d38d3147b..043fdda5c3 100644 --- a/Marlin/src/gcode/host/M115.cpp +++ b/Marlin/src/gcode/host/M115.cpp @@ -154,7 +154,7 @@ void GcodeSuite::M115() { // AUTOLEVEL (G29) cap_line(F("AUTOLEVEL"), ENABLED(HAS_AUTOLEVEL)); - // RUNOUT (M412, M600) + // RUNOUT (M591, M600) cap_line(F("RUNOUT"), ENABLED(FILAMENT_RUNOUT_SENSOR)); // Z_PROBE (G30) diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index a3756217e6..5c6dee752f 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -26,581 +26,16 @@ * Conditionals that need to be set before Configuration_adv.h or pins.h */ -/** - * Extruders have some combination of stepper motors and hotends - * so we separate these concepts into the defines: - * - * EXTRUDERS - Number of Selectable Tools - * HOTENDS - Number of hotends, whether connected or separate - * E_STEPPERS - Number of actual E stepper motors - * E_MANUAL - Number of E steppers for LCD move options - * - * These defines must be simple constants for use in REPEAT, etc. - */ -#if EXTRUDERS - #define HAS_EXTRUDERS 1 - #if EXTRUDERS > 1 - #define HAS_MULTI_EXTRUDER 1 - #endif - #define E_AXIS_N(E) AxisEnum(E_AXIS + E_INDEX_N(E)) -#else - #undef EXTRUDERS - #define EXTRUDERS 0 - #undef TEMP_SENSOR_0 - #undef TEMP_SENSOR_1 - #undef TEMP_SENSOR_2 - #undef TEMP_SENSOR_3 - #undef TEMP_SENSOR_4 - #undef TEMP_SENSOR_5 - #undef TEMP_SENSOR_6 - #undef TEMP_SENSOR_7 - #undef SINGLENOZZLE - #undef SWITCHING_EXTRUDER - #undef MECHANICAL_SWITCHING_EXTRUDER - #undef SWITCHING_NOZZLE - #undef MECHANICAL_SWITCHING_NOZZLE - #undef MIXING_EXTRUDER - #undef HOTEND_IDLE_TIMEOUT - #undef DISABLE_E - #undef PREVENT_LENGTHY_EXTRUDE - #undef FILAMENT_RUNOUT_SENSOR - #undef FILAMENT_RUNOUT_DISTANCE_MM - #undef DISABLE_OTHER_EXTRUDERS -#endif - -#define E_OPTARG(N) OPTARG(HAS_MULTI_EXTRUDER, N) -#define E_TERN_(N) TERN_(HAS_MULTI_EXTRUDER, N) -#define E_TERN0(N) TERN0(HAS_MULTI_EXTRUDER, N) - -#if ANY(SWITCHING_EXTRUDER, MECHANICAL_SWITCHING_EXTRUDER) - #define HAS_SWITCHING_EXTRUDER 1 -#endif -#if ANY(SWITCHING_NOZZLE, MECHANICAL_SWITCHING_NOZZLE) - #define HAS_SWITCHING_NOZZLE 1 -#endif - -/** - * Multi-Material-Unit supported models - */ -#ifdef MMU_MODEL - #define HAS_MMU 1 - #define SINGLENOZZLE - - #define _PRUSA_MMU1 1 - #define _PRUSA_MMU2 2 - #define _PRUSA_MMU2S 3 - #define _EXTENDABLE_EMU_MMU2 12 - #define _EXTENDABLE_EMU_MMU2S 13 - #define _MMU CAT(_,MMU_MODEL) - - #if _MMU == _PRUSA_MMU1 - #define HAS_PRUSA_MMU1 1 - #elif _MMU % 10 == _PRUSA_MMU2 - #define HAS_PRUSA_MMU2 1 - #elif _MMU % 10 == _PRUSA_MMU2S - #define HAS_PRUSA_MMU2 1 - #define HAS_PRUSA_MMU2S 1 - #endif - #if _MMU == _EXTENDABLE_EMU_MMU2 || _MMU == _EXTENDABLE_EMU_MMU2S - #define HAS_EXTENDABLE_MMU 1 - #endif - - #undef _MMU - #undef _PRUSA_MMU1 - #undef _PRUSA_MMU2 - #undef _PRUSA_MMU2S - #undef _EXTENDABLE_EMU_MMU2 - #undef _EXTENDABLE_EMU_MMU2S -#endif - -#if ENABLED(E_DUAL_STEPPER_DRIVERS) // E0/E1 steppers act in tandem as E0 - - #define E_STEPPERS 2 - #define E_MANUAL 1 - -#elif HAS_SWITCHING_EXTRUDER // One stepper for every two EXTRUDERS - - #if EXTRUDERS > 4 - #define E_STEPPERS 3 - #elif EXTRUDERS > 2 - #define E_STEPPERS 2 - #else - #define E_STEPPERS 1 - #endif - -#elif ENABLED(MIXING_EXTRUDER) // Multiple feeds are mixed proportionally - - #define E_STEPPERS MIXING_STEPPERS - #define E_MANUAL 1 - #if MIXING_STEPPERS == 2 - #define HAS_DUAL_MIXING 1 - #endif - #ifndef MIXING_VIRTUAL_TOOLS - #define MIXING_VIRTUAL_TOOLS 1 - #endif - -#elif ENABLED(SWITCHING_TOOLHEAD) // Toolchanger - - #define E_STEPPERS EXTRUDERS - #define E_MANUAL EXTRUDERS - -#elif HAS_PRUSA_MMU2 // Průša Multi-Material Unit v2 - - #define E_STEPPERS 1 - #define E_MANUAL 1 - -#endif - -// Default E steppers / manual motion is one per extruder -#ifndef E_STEPPERS - #define E_STEPPERS EXTRUDERS -#endif -#ifndef E_MANUAL - #define E_MANUAL EXTRUDERS -#endif - -// Number of hotends... -#if ANY(SINGLENOZZLE, MIXING_EXTRUDER) // Only one for singlenozzle or mixing extruder - #define HOTENDS 1 -#elif HAS_SWITCHING_EXTRUDER && !HAS_SWITCHING_NOZZLE // One for each pair of abstract "extruders" - #define HOTENDS E_STEPPERS -#elif TEMP_SENSOR_0 - #define HOTENDS EXTRUDERS // One per extruder if at least one heater exists -#else - #define HOTENDS 0 // A machine with no hotends at all can still extrude -#endif - -// At least one hotend... -#if HOTENDS - #define HAS_HOTEND 1 - #ifndef HOTEND_OVERSHOOT - #define HOTEND_OVERSHOOT 15 - #endif -#endif - -// More than one hotend... -#if HOTENDS > 1 - #define HAS_MULTI_HOTEND 1 - #define HAS_HOTEND_OFFSET 1 - #ifndef HOTEND_OFFSET_X - #define HOTEND_OFFSET_X { 0 } // X offsets for each extruder - #endif - #ifndef HOTEND_OFFSET_Y - #define HOTEND_OFFSET_Y { 0 } // Y offsets for each extruder - #endif - #ifndef HOTEND_OFFSET_Z - #define HOTEND_OFFSET_Z { 0 } // Z offsets for each extruder - #endif -#else - #undef HOTEND_OFFSET_X - #undef HOTEND_OFFSET_Y - #undef HOTEND_OFFSET_Z -#endif - -// Clean up E-stepper-based settings... -#if E_STEPPERS <= 7 - #undef INVERT_E7_DIR - #undef E7_DRIVER_TYPE - #if E_STEPPERS <= 6 - #undef INVERT_E6_DIR - #undef E6_DRIVER_TYPE - #if E_STEPPERS <= 5 - #undef INVERT_E5_DIR - #undef E5_DRIVER_TYPE - #if E_STEPPERS <= 4 - #undef INVERT_E4_DIR - #undef E4_DRIVER_TYPE - #if E_STEPPERS <= 3 - #undef INVERT_E3_DIR - #undef E3_DRIVER_TYPE - #if E_STEPPERS <= 2 - #undef INVERT_E2_DIR - #undef E2_DRIVER_TYPE - #if E_STEPPERS <= 1 - #undef INVERT_E1_DIR - #undef E1_DRIVER_TYPE - #if E_STEPPERS == 0 - #undef INVERT_E0_DIR - #undef E0_DRIVER_TYPE - #endif - #endif - #endif - #endif - #endif - #endif - #endif -#endif - -/** - * Number of Linear Axes (e.g., XYZIJKUVW) - * All the logical axes except for the tool (E) axis - */ -#ifdef NUM_AXES - #undef NUM_AXES - #define NUM_AXES_WARNING 1 -#endif - -#ifdef W_DRIVER_TYPE - #define NUM_AXES 9 -#elif defined(V_DRIVER_TYPE) - #define NUM_AXES 8 -#elif defined(U_DRIVER_TYPE) - #define NUM_AXES 7 -#elif defined(K_DRIVER_TYPE) - #define NUM_AXES 6 -#elif defined(J_DRIVER_TYPE) - #define NUM_AXES 5 -#elif defined(I_DRIVER_TYPE) - #define NUM_AXES 4 -#elif defined(Z_DRIVER_TYPE) - #define NUM_AXES 3 -#elif defined(Y_DRIVER_TYPE) - #define NUM_AXES 2 -#elif defined(X_DRIVER_TYPE) - #define NUM_AXES 1 -#else - #define NUM_AXES 0 -#endif -#if NUM_AXES >= 1 - #define HAS_X_AXIS 1 - #define HAS_A_AXIS 1 - #if NUM_AXES >= XY - #define HAS_Y_AXIS 1 - #define HAS_B_AXIS 1 - #if NUM_AXES >= XYZ - #define HAS_Z_AXIS 1 - #define HAS_C_AXIS 1 - #if NUM_AXES >= 4 - #define HAS_I_AXIS 1 - #if NUM_AXES >= 5 - #define HAS_J_AXIS 1 - #if NUM_AXES >= 6 - #define HAS_K_AXIS 1 - #if NUM_AXES >= 7 - #define HAS_U_AXIS 1 - #if NUM_AXES >= 8 - #define HAS_V_AXIS 1 - #if NUM_AXES >= 9 - #define HAS_W_AXIS 1 - #endif - #endif - #endif - #endif - #endif - #endif - #endif - #endif -#endif - -#if !HAS_X_AXIS - #undef AVOID_OBSTACLES - #undef ENDSTOPPULLUP_XMIN - #undef ENDSTOPPULLUP_XMAX - #undef X_MIN_ENDSTOP_HIT_STATE - #undef X_MAX_ENDSTOP_HIT_STATE - #undef X2_DRIVER_TYPE - #undef X_ENABLE_ON - #undef DISABLE_X - #undef INVERT_X_DIR - #undef X_HOME_DIR - #undef X_MIN_POS - #undef X_MAX_POS - #undef MANUAL_X_HOME_POS - #undef MIN_SOFTWARE_ENDSTOPS - #undef MAX_SOFTWARE_ENDSTOPS -#endif - -#if !HAS_Y_AXIS - #undef AVOID_OBSTACLES - #undef ENDSTOPPULLUP_YMIN - #undef ENDSTOPPULLUP_YMAX - #undef Y_MIN_ENDSTOP_HIT_STATE - #undef Y_MAX_ENDSTOP_HIT_STATE - #undef Y2_DRIVER_TYPE - #undef Y_ENABLE_ON - #undef DISABLE_Y - #undef INVERT_Y_DIR - #undef Y_HOME_DIR - #undef Y_MIN_POS - #undef Y_MAX_POS - #undef MANUAL_Y_HOME_POS - #undef MIN_SOFTWARE_ENDSTOP_Y - #undef MAX_SOFTWARE_ENDSTOP_Y -#endif - -#if HAS_Z_AXIS - #ifdef Z4_DRIVER_TYPE - #define NUM_Z_STEPPERS 4 - #elif defined(Z3_DRIVER_TYPE) - #define NUM_Z_STEPPERS 3 - #elif defined(Z2_DRIVER_TYPE) - #define NUM_Z_STEPPERS 2 - #else - #define NUM_Z_STEPPERS 1 - #endif -#else - #undef ENDSTOPPULLUP_ZMIN - #undef ENDSTOPPULLUP_ZMAX - #undef Z_MIN_ENDSTOP_HIT_STATE - #undef Z_MAX_ENDSTOP_HIT_STATE - #undef Z2_DRIVER_TYPE - #undef Z3_DRIVER_TYPE - #undef Z4_DRIVER_TYPE - #undef Z_ENABLE_ON - #undef DISABLE_Z - #undef INVERT_Z_DIR - #undef Z_HOME_DIR - #undef Z_MIN_POS - #undef Z_MAX_POS - #undef MANUAL_Z_HOME_POS - #undef Z_SAFE_HOMING - #undef MIN_SOFTWARE_ENDSTOP_Z - #undef MAX_SOFTWARE_ENDSTOP_Z -#endif - -#if !HAS_I_AXIS - #undef ENDSTOPPULLUP_IMIN - #undef ENDSTOPPULLUP_IMAX - #undef I_MIN_ENDSTOP_HIT_STATE - #undef I_MAX_ENDSTOP_HIT_STATE - #undef I_ENABLE_ON - #undef DISABLE_I - #undef INVERT_I_DIR - #undef I_HOME_DIR - #undef I_MIN_POS - #undef I_MAX_POS - #undef MANUAL_I_HOME_POS - #undef MIN_SOFTWARE_ENDSTOP_I - #undef MAX_SOFTWARE_ENDSTOP_I -#endif - -#if !HAS_J_AXIS - #undef ENDSTOPPULLUP_JMIN - #undef ENDSTOPPULLUP_JMAX - #undef J_MIN_ENDSTOP_HIT_STATE - #undef J_MAX_ENDSTOP_HIT_STATE - #undef J_ENABLE_ON - #undef DISABLE_J - #undef INVERT_J_DIR - #undef J_HOME_DIR - #undef J_MIN_POS - #undef J_MAX_POS - #undef MANUAL_J_HOME_POS - #undef MIN_SOFTWARE_ENDSTOP_J - #undef MAX_SOFTWARE_ENDSTOP_J -#endif - -#if !HAS_K_AXIS - #undef ENDSTOPPULLUP_KMIN - #undef ENDSTOPPULLUP_KMAX - #undef K_MIN_ENDSTOP_HIT_STATE - #undef K_MAX_ENDSTOP_HIT_STATE - #undef K_ENABLE_ON - #undef DISABLE_K - #undef INVERT_K_DIR - #undef K_HOME_DIR - #undef K_MIN_POS - #undef K_MAX_POS - #undef MANUAL_K_HOME_POS - #undef MIN_SOFTWARE_ENDSTOP_K - #undef MAX_SOFTWARE_ENDSTOP_K -#endif - -#if !HAS_U_AXIS - #undef ENDSTOPPULLUP_UMIN - #undef ENDSTOPPULLUP_UMAX - #undef U_MIN_ENDSTOP_HIT_STATE - #undef U_MAX_ENDSTOP_HIT_STATE - #undef U_ENABLE_ON - #undef DISABLE_U - #undef INVERT_U_DIR - #undef U_HOME_DIR - #undef U_MIN_POS - #undef U_MAX_POS - #undef MANUAL_U_HOME_POS - #undef MIN_SOFTWARE_ENDSTOP_U - #undef MAX_SOFTWARE_ENDSTOP_U -#endif - -#if !HAS_V_AXIS - #undef ENDSTOPPULLUP_VMIN - #undef ENDSTOPPULLUP_VMAX - #undef V_MIN_ENDSTOP_HIT_STATE - #undef V_MAX_ENDSTOP_HIT_STATE - #undef V_ENABLE_ON - #undef DISABLE_V - #undef INVERT_V_DIR - #undef V_HOME_DIR - #undef V_MIN_POS - #undef V_MAX_POS - #undef MANUAL_V_HOME_POS - #undef MIN_SOFTWARE_ENDSTOP_V - #undef MAX_SOFTWARE_ENDSTOP_V -#endif - -#if !HAS_W_AXIS - #undef ENDSTOPPULLUP_WMIN - #undef ENDSTOPPULLUP_WMAX - #undef W_MIN_ENDSTOP_HIT_STATE - #undef W_MAX_ENDSTOP_HIT_STATE - #undef W_ENABLE_ON - #undef DISABLE_W - #undef INVERT_W_DIR - #undef W_HOME_DIR - #undef W_MIN_POS - #undef W_MAX_POS - #undef MANUAL_W_HOME_POS - #undef MIN_SOFTWARE_ENDSTOP_W - #undef MAX_SOFTWARE_ENDSTOP_W -#endif - -#define _OR_HAS_DA(A) ENABLED(DISABLE_##A) || -#if MAP(_OR_HAS_DA, X, Y, Z, I, J, K, U, V, W) 0 - #define HAS_DISABLE_MAIN_AXES 1 -#endif -#if HAS_DISABLE_MAIN_AXES || ENABLED(DISABLE_E) - #define HAS_DISABLE_AXES 1 -#endif -#undef _OR_HAS_DA - -#ifdef X2_DRIVER_TYPE - #define HAS_X2_STEPPER 1 -#endif -#ifdef Y2_DRIVER_TYPE - #define HAS_Y2_STEPPER 1 -#endif - -/** - * Number of Primary Linear Axes (e.g., XYZ) - * X, XY, or XYZ axes. Excluding duplicate axes (X2, Y2, Z2, Z3, Z4) - */ -#if NUM_AXES >= 3 - #define PRIMARY_LINEAR_AXES 3 -#else - #define PRIMARY_LINEAR_AXES NUM_AXES -#endif - -/** - * Number of Secondary Axes (e.g., IJKUVW) - * All linear/rotational axes between XYZ and E. - */ -#define SECONDARY_AXES SUB3(NUM_AXES) - -/** - * Number of Rotational Axes (e.g., IJK) - * All axes for which AXIS*_ROTATES is defined. - * For these axes, positions are specified in angular degrees. - */ -#if ENABLED(AXIS9_ROTATES) - #define ROTATIONAL_AXES 6 -#elif ENABLED(AXIS8_ROTATES) - #define ROTATIONAL_AXES 5 -#elif ENABLED(AXIS7_ROTATES) - #define ROTATIONAL_AXES 4 -#elif ENABLED(AXIS6_ROTATES) - #define ROTATIONAL_AXES 3 -#elif ENABLED(AXIS5_ROTATES) - #define ROTATIONAL_AXES 2 -#elif ENABLED(AXIS4_ROTATES) - #define ROTATIONAL_AXES 1 -#else - #define ROTATIONAL_AXES 0 -#endif - -#if ROTATIONAL_AXES - #define HAS_ROTATIONAL_AXES 1 -#endif - -/** - * Number of Secondary Linear Axes (e.g., UVW) - * All secondary axes for which AXIS*_ROTATES is not defined. - * Excluding primary axes and excluding duplicate axes (X2, Y2, Z2, Z3, Z4) - */ -#define SECONDARY_LINEAR_AXES (NUM_AXES - PRIMARY_LINEAR_AXES - ROTATIONAL_AXES) - -/** - * Number of Logical Axes (e.g., XYZIJKUVWE) - * All logical axes that can be commanded directly by G-code. - * Delta maps stepper-specific values to ABC steppers. - */ -#if HAS_EXTRUDERS - #define LOGICAL_AXES INCREMENT(NUM_AXES) -#else - #define LOGICAL_AXES NUM_AXES -#endif - -/** - * DISTINCT_E_FACTORS is set to give extruders (some) individual settings. - * - * DISTINCT_AXES is the number of distinct addressable axes (not steppers). - * Includes all linear axes plus all distinguished extruders. - * The default behavior is to treat all extruders as a single E axis - * with shared motion and temperature settings. - * - * DISTINCT_E is the number of distinguished extruders. By default this - * will be 1 which indicates all extruders share the same settings. - * - * E_INDEX_N(E) should be used to get the E index of any item that might be - * distinguished. - */ -#if ENABLED(DISTINCT_E_FACTORS) && E_STEPPERS > 1 - #define DISTINCT_AXES (NUM_AXES + E_STEPPERS) - #define DISTINCT_E E_STEPPERS - #define E_INDEX_N(E) (E) -#else - #undef DISTINCT_E_FACTORS - #define DISTINCT_AXES LOGICAL_AXES - #define DISTINCT_E 1 - #define E_INDEX_N(E) 0 -#endif - -// Helper macros for extruder and hotend arrays -#define _EXTRUDER_LOOP(E) for (int8_t E = 0; E < EXTRUDERS; E++) -#define EXTRUDER_LOOP() _EXTRUDER_LOOP(e) -#define _HOTEND_LOOP(H) for (int8_t H = 0; H < HOTENDS; H++) -#define HOTEND_LOOP() _HOTEND_LOOP(e) - -#define ARRAY_BY_EXTRUDERS(V...) ARRAY_N(EXTRUDERS, V) -#define ARRAY_BY_EXTRUDERS1(v1) ARRAY_N_1(EXTRUDERS, v1) -#define ARRAY_BY_HOTENDS(V...) ARRAY_N(HOTENDS, V) -#define ARRAY_BY_HOTENDS1(v1) ARRAY_N_1(HOTENDS, v1) - -// Support for SD Card and other file storage -#if ENABLED(SDSUPPORT) - #define HAS_MEDIA 1 -#endif - -/** - * Conditionals for the configured LCD / Controller - */ - // MKS_LCD12864A/B is a variant of MKS_MINI_12864 -#if ANY(MKS_LCD12864A, MKS_LCD12864B) +#if EITHER(MKS_LCD12864A, MKS_LCD12864B) #define MKS_MINI_12864 #endif -// MKS_MINI_12864_V3 , BTT_MINI_12864 and BEEZ_MINI_12864 are nearly identical to FYSETC_MINI_12864_2_1 -#if ANY(MKS_MINI_12864_V3, BTT_MINI_12864, BEEZ_MINI_12864) +// MKS_MINI_12864_V3 and BTT_MINI_12864_V1 are identical to FYSETC_MINI_12864_2_1 +#if EITHER(MKS_MINI_12864_V3, BTT_MINI_12864_V1) #define FYSETC_MINI_12864_2_1 #endif -// Old settings are now conditional on DGUS_LCD_UI -#if DGUS_UI_IS(ORIGIN) - #define DGUS_LCD_UI_ORIGIN 1 -#elif DGUS_UI_IS(FYSETC) - #define DGUS_LCD_UI_FYSETC 1 -#elif DGUS_UI_IS(HIPRECY) - #define DGUS_LCD_UI_HIPRECY 1 -#elif DGUS_UI_IS(MKS) - #define DGUS_LCD_UI_MKS 1 -#elif DGUS_UI_IS(RELOADED) - #define DGUS_LCD_UI_RELOADED 1 -#elif DGUS_UI_IS(IA_CREALITY) - #define DGUS_LCD_UI_IA_CREALITY 1 -#elif DGUS_UI_IS(E3S1PRO) - #define DGUS_LCD_UI_E3S1PRO 1 -#endif - /** * General Flags that may be set below by specific LCDs * @@ -616,7 +51,7 @@ * IS_U8GLIB_ST7565_64128N : ST7565 128x64 LCD with SPI interface via U8GLib * IS_U8GLIB_LM6059_AF : LM6059 with Hardware SPI via U8GLib */ -#if ANY(MKS_MINI_12864, ENDER2_STOCKDISPLAY) +#if EITHER(MKS_MINI_12864, ENDER2_STOCKDISPLAY) #define MINIPANEL @@ -629,7 +64,7 @@ #define DOGLCD #define IS_ULTIPANEL 1 -#elif ANY(DWIN_MARLINUI_PORTRAIT, DWIN_MARLINUI_LANDSCAPE) +#elif EITHER(DWIN_MARLINUI_PORTRAIT, DWIN_MARLINUI_LANDSCAPE) #define IS_DWIN_MARLINUI 1 #define IS_ULTIPANEL 1 @@ -702,7 +137,6 @@ #define DOGLCD #define IS_U8GLIB_ST7920 1 #define IS_ULTIPANEL 1 - #define ENCODER_PULSES_PER_STEP 2 #elif ENABLED(MKS_12864OLED) @@ -762,12 +196,12 @@ #define LCD_WIDTH 16 #define LCD_HEIGHT 2 -#elif ANY(TFTGLCD_PANEL_SPI, TFTGLCD_PANEL_I2C) +#elif EITHER(TFTGLCD_PANEL_SPI, TFTGLCD_PANEL_I2C) #define IS_TFTGLCD_PANEL 1 #define IS_ULTIPANEL 1 // Note that IS_ULTIPANEL leads to HAS_WIRED_LCD - #if HAS_MEDIA && DISABLED(LCD_PROGRESS_BAR) + #if ENABLED(SDSUPPORT) && DISABLED(LCD_PROGRESS_BAR) #define LCD_PROGRESS_BAR #endif #if ENABLED(TFTGLCD_PANEL_I2C) @@ -788,12 +222,11 @@ #elif ENABLED(CR10_STOCKDISPLAY) #define IS_RRD_FG_SC 1 - #define NO_LCD_SDCARD #define LCD_ST7920_DELAY_1 125 #define LCD_ST7920_DELAY_2 125 #define LCD_ST7920_DELAY_3 125 -#elif ANY(ANET_FULL_GRAPHICS_LCD, CTC_A10S_A13) +#elif EITHER(ANET_FULL_GRAPHICS_LCD, ANET_FULL_GRAPHICS_LCD_ALT_WIRING) #define IS_RRD_FG_SC 1 #define LCD_ST7920_DELAY_1 150 @@ -823,7 +256,7 @@ #endif // ST7565 / 64128N graphical displays -#if ANY(MAKRPANEL, MINIPANEL) +#if EITHER(MAKRPANEL, MINIPANEL) #define IS_ULTIPANEL 1 #define DOGLCD #if ENABLED(MAKRPANEL) @@ -875,22 +308,24 @@ #define IS_ULTIPANEL 1 #endif -// TFT Legacy options masquerade as TFT_GENERIC +// TFT Compatibility #if ANY(FSMC_GRAPHICAL_TFT, SPI_GRAPHICAL_TFT, TFT_320x240, TFT_480x320, TFT_320x240_SPI, TFT_480x320_SPI, TFT_LVGL_UI_FSMC, TFT_LVGL_UI_SPI) #define IS_LEGACY_TFT 1 #define TFT_GENERIC - #if ANY(FSMC_GRAPHICAL_TFT, TFT_320x240, TFT_480x320, TFT_LVGL_UI_FSMC) - #define TFT_INTERFACE_FSMC - #elif ANY(SPI_GRAPHICAL_TFT, TFT_320x240_SPI, TFT_480x320_SPI, TFT_LVGL_UI_SPI) - #define TFT_INTERFACE_SPI - #endif - #if ANY(FSMC_GRAPHICAL_TFT, SPI_GRAPHICAL_TFT) - #define TFT_CLASSIC_UI - #elif ANY(TFT_320x240, TFT_480x320, TFT_320x240_SPI, TFT_480x320_SPI) - #define TFT_COLOR_UI - #elif ANY(TFT_LVGL_UI_FSMC, TFT_LVGL_UI_SPI) - #define TFT_LVGL_UI - #endif +#endif + +#if ANY(FSMC_GRAPHICAL_TFT, TFT_320x240, TFT_480x320, TFT_LVGL_UI_FSMC) + #define TFT_INTERFACE_FSMC +#elif ANY(SPI_GRAPHICAL_TFT, TFT_320x240_SPI, TFT_480x320_SPI, TFT_LVGL_UI_SPI) + #define TFT_INTERFACE_SPI +#endif + +#if EITHER(FSMC_GRAPHICAL_TFT, SPI_GRAPHICAL_TFT) + #define TFT_CLASSIC_UI +#elif ANY(TFT_320x240, TFT_480x320, TFT_320x240_SPI, TFT_480x320_SPI) + #define TFT_COLOR_UI +#elif EITHER(TFT_LVGL_UI_FSMC, TFT_LVGL_UI_SPI) + #define TFT_LVGL_UI #endif // FSMC/SPI TFT Panels (LVGL) @@ -934,7 +369,7 @@ #define IS_ULTIPANEL 1 #endif -#elif ANY(LCD_SAINSMART_I2C_1602, LCD_SAINSMART_I2C_2004) +#elif EITHER(LCD_SAINSMART_I2C_1602, LCD_SAINSMART_I2C_2004) #define LCD_I2C_TYPE_PCF8575 // I2C Character-based 12864 display #define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander @@ -972,11 +407,10 @@ #endif -#if ANY(LCD_I2C_TYPE_MCP23017, LCD_I2C_TYPE_MCP23008) && DISABLED(NO_LCD_DETECT) +#if EITHER(LCD_I2C_TYPE_MCP23017, LCD_I2C_TYPE_MCP23008) && DISABLED(NO_LCD_DETECT) #define DETECT_I2C_LCD_DEVICE 1 #endif -// Encoder behavior #ifndef STD_ENCODER_PULSES_PER_STEP #if ENABLED(TOUCH_SCREEN) #define STD_ENCODER_PULSES_PER_STEP 2 @@ -1000,7 +434,7 @@ // Shift register panels // --------------------- // 2 wire Non-latching LCD SR from: -// https://github.com/fmalpartida/New-LiquidCrystal/wiki/schematics#user-content-ShiftRegister_connection +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection #if ENABLED(FF_INTERFACEBOARD) #define SR_LCD_3W_NL // Non latching 3 wire shift register #define IS_ULTIPANEL 1 @@ -1011,15 +445,15 @@ #define IS_ULTIPANEL 1 #endif -#if ANY(IS_ULTIPANEL, ULTRA_LCD) +#if EITHER(IS_ULTIPANEL, ULTRA_LCD) #define HAS_WIRED_LCD 1 #endif -#if ANY(IS_ULTIPANEL, REPRAPWORLD_KEYPAD) +#if EITHER(IS_ULTIPANEL, REPRAPWORLD_KEYPAD) #define IS_NEWPANEL 1 #endif -#if ANY(ZONESTAR_LCD, REPRAPWORLD_KEYPAD) +#if EITHER(ZONESTAR_LCD, REPRAPWORLD_KEYPAD) #define IS_RRW_KEYPAD 1 #ifndef REPRAPWORLD_KEYPAD_MOVE_STEP #define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 @@ -1027,40 +461,39 @@ #endif // Aliases for LCD features -#if !DGUS_UI_IS(NONE) || ENABLED(ANYCUBIC_LCD_VYPER) +#if ANY(DGUS_LCD_UI_ORIGIN, DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_HIPRECY, DGUS_LCD_UI_MKS) + #define HAS_DGUS_LCD_CLASSIC 1 +#endif + +#if EITHER(HAS_DGUS_LCD_CLASSIC, DGUS_LCD_UI_RELOADED) #define HAS_DGUS_LCD 1 - #if DGUS_UI_IS(ORIGIN, FYSETC, HIPRECY, MKS) - #define HAS_DGUS_LCD_CLASSIC 1 - #endif #endif // Extensible UI serial touch screens. (See src/lcd/extui) -#if ANY(HAS_DGUS_LCD, MALYAN_LCD, ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON, NEXTION_TFT, TOUCH_UI_FTDI_EVE, DWIN_LCD_PROUI) - #define IS_EXTUI 1 // Just for sanity check. +#if ANY(HAS_DGUS_LCD, MALYAN_LCD, TOUCH_UI_FTDI_EVE, ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON, NEXTION_TFT) + #define IS_EXTUI 1 #define EXTENSIBLE_UI #endif // Aliases for LCD features -#if ANY(DWIN_CREALITY_LCD, DWIN_LCD_PROUI, DWIN_CREALITY_LCD_JYERSUI) +#if EITHER(DWIN_CREALITY_LCD, DWIN_LCD_PROUI) + #define HAS_DWIN_E3V2_BASIC 1 +#endif +#if EITHER(HAS_DWIN_E3V2_BASIC, DWIN_CREALITY_LCD_JYERSUI) #define HAS_DWIN_E3V2 1 #endif +#if ENABLED(DWIN_LCD_PROUI) + #define DO_LIST_BIN_FILES 1 +#endif // E3V2 extras #if HAS_DWIN_E3V2 || IS_DWIN_MARLINUI #define SERIAL_CATCHALL 0 #define HAS_LCD_BRIGHTNESS 1 #define LCD_BRIGHTNESS_MAX 250 -#endif - -#if ENABLED(DWIN_LCD_PROUI) - #define DO_LIST_BIN_FILES 1 - #define LCD_BRIGHTNESS_DEFAULT 127 - #define STATUS_DO_CLEAR_EMPTY -#endif - -// Serial Controllers require LCD_SERIAL_PORT -#if ANY(IS_DWIN_MARLINUI, HAS_DWIN_E3V2, HAS_DGUS_LCD, MALYAN_LCD, ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON, NEXTION_TFT) - #define LCD_IS_SERIAL_HOST 1 + #if ENABLED(DWIN_LCD_PROUI) + #define LCD_BRIGHTNESS_DEFAULT 127 + #endif #endif #if HAS_WIRED_LCD @@ -1077,37 +510,14 @@ #endif #if ANY(HAS_WIRED_LCD, EXTENSIBLE_UI, DWIN_LCD_PROUI, DWIN_CREALITY_LCD_JYERSUI) - /** - * HAS_DISPLAY indicates the display uses these MarlinUI methods... - * - update - * - abort_print - * - pause_print - * - resume_print - * - poweroff (for PSU_CONTROL and HAS_MARLINUI_MENU) - * - * ...and implements these MarlinUI methods: - * - zoffset_overlay (if BABYSTEP_GFX_OVERLAY or MESH_EDIT_GFX_OVERLAY are supported) - * - draw_kill_screen - * - kill_screen - * - draw_status_message - * (calling advance_status_scroll, status_and_len for a scrolling status message) - */ #define HAS_DISPLAY 1 #endif -#if ANY(HAS_DISPLAY, DWIN_CREALITY_LCD) - #define HAS_UI_UPDATE 1 -#endif - #if HAS_WIRED_LCD && !HAS_GRAPHICAL_TFT && !IS_DWIN_MARLINUI #define HAS_LCDPRINT 1 #endif -#if HAS_DISPLAY || HAS_LCDPRINT - #define HAS_UTF8_UTILS 1 -#endif - -#if ANY(HAS_DISPLAY, HAS_DWIN_E3V2) +#if HAS_DISPLAY || HAS_DWIN_E3V2 #define HAS_STATUS_MESSAGE 1 #endif @@ -1128,23 +538,522 @@ #endif #endif +/** + * Multi-Material-Unit supported models + */ +#define PRUSA_MMU1 1 +#define PRUSA_MMU2 2 +#define PRUSA_MMU2S 3 +#define EXTENDABLE_EMU_MMU2 12 +#define EXTENDABLE_EMU_MMU2S 13 + +#ifdef MMU_MODEL + #define HAS_MMU 1 + #if MMU_MODEL == PRUSA_MMU1 + #define HAS_PRUSA_MMU1 1 + #elif MMU_MODEL % 10 == PRUSA_MMU2 + #define HAS_PRUSA_MMU2 1 + #elif MMU_MODEL % 10 == PRUSA_MMU2S + #define HAS_PRUSA_MMU2 1 + #define HAS_PRUSA_MMU2S 1 + #endif + #if MMU_MODEL >= EXTENDABLE_EMU_MMU2 + #define HAS_EXTENDABLE_MMU 1 + #endif +#endif + +#undef PRUSA_MMU1 +#undef PRUSA_MMU2 +#undef PRUSA_MMU2S +#undef EXTENDABLE_EMU_MMU2 +#undef EXTENDABLE_EMU_MMU2S + +/** + * Extruders have some combination of stepper motors and hotends + * so we separate these concepts into the defines: + * + * EXTRUDERS - Number of Selectable Tools + * HOTENDS - Number of hotends, whether connected or separate + * E_STEPPERS - Number of actual E stepper motors + * E_MANUAL - Number of E steppers for LCD move options + * + * These defines must be simple constants for use in REPEAT, etc. + */ +#if EXTRUDERS + #define HAS_EXTRUDERS 1 + #if EXTRUDERS > 1 + #define HAS_MULTI_EXTRUDER 1 + #endif + #define E_AXIS_N(E) AxisEnum(E_AXIS + E_INDEX_N(E)) +#else + #undef EXTRUDERS + #define EXTRUDERS 0 + #undef SINGLENOZZLE + #undef SWITCHING_EXTRUDER + #undef SWITCHING_NOZZLE + #undef MIXING_EXTRUDER + #undef HOTEND_IDLE_TIMEOUT + #undef DISABLE_E +#endif + +#define E_OPTARG(N) OPTARG(HAS_MULTI_EXTRUDER, N) +#define E_TERN_(N) TERN_(HAS_MULTI_EXTRUDER, N) +#define E_TERN0(N) TERN0(HAS_MULTI_EXTRUDER, N) + +#if ENABLED(E_DUAL_STEPPER_DRIVERS) // E0/E1 steppers act in tandem as E0 + + #define E_STEPPERS 2 + #define E_MANUAL 1 + +#elif ENABLED(SWITCHING_EXTRUDER) // One stepper for every two EXTRUDERS + + #if EXTRUDERS > 4 + #define E_STEPPERS 3 + #elif EXTRUDERS > 2 + #define E_STEPPERS 2 + #else + #define E_STEPPERS 1 + #endif + #if DISABLED(SWITCHING_NOZZLE) + #define HOTENDS E_STEPPERS + #endif + +#elif ENABLED(MIXING_EXTRUDER) // Multiple feeds are mixed proportionally + + #define E_STEPPERS MIXING_STEPPERS + #define E_MANUAL 1 + #if MIXING_STEPPERS == 2 + #define HAS_DUAL_MIXING 1 + #endif + +#elif ENABLED(SWITCHING_TOOLHEAD) // Toolchanger + + #define E_STEPPERS EXTRUDERS + #define E_MANUAL EXTRUDERS + +#elif HAS_PRUSA_MMU2 // Průša Multi-Material Unit v2 + + #define E_STEPPERS 1 + #define E_MANUAL 1 + +#endif + +// No inactive extruders with SWITCHING_NOZZLE or Průša MMU1 +#if ENABLED(SWITCHING_NOZZLE) || HAS_PRUSA_MMU1 + #undef DISABLE_INACTIVE_EXTRUDER +#endif + +// Průša MMU1, MMU(S) 2.0 and EXTENDABLE_EMU_MMU2(S) force SINGLENOZZLE +#if HAS_MMU + #define SINGLENOZZLE +#endif + +#if EITHER(SINGLENOZZLE, MIXING_EXTRUDER) // One hotend, one thermistor, no XY offset + #undef HOTENDS + #define HOTENDS 1 + #undef HOTEND_OFFSET_X + #undef HOTEND_OFFSET_Y +#endif + +#ifndef HOTENDS + #define HOTENDS EXTRUDERS +#endif +#ifndef E_STEPPERS + #define E_STEPPERS EXTRUDERS +#endif +#ifndef E_MANUAL + #define E_MANUAL EXTRUDERS +#endif + +#if E_STEPPERS <= 7 + #undef INVERT_E7_DIR + #if E_STEPPERS <= 6 + #undef INVERT_E6_DIR + #if E_STEPPERS <= 5 + #undef INVERT_E5_DIR + #if E_STEPPERS <= 4 + #undef INVERT_E4_DIR + #if E_STEPPERS <= 3 + #undef INVERT_E3_DIR + #if E_STEPPERS <= 2 + #undef INVERT_E2_DIR + #if E_STEPPERS <= 1 + #undef INVERT_E1_DIR + #if E_STEPPERS == 0 + #undef INVERT_E0_DIR + #endif + #endif + #endif + #endif + #endif + #endif + #endif +#endif + +/** + * Number of Linear Axes (e.g., XYZIJKUVW) + * All the logical axes except for the tool (E) axis + */ +#ifdef NUM_AXES + #undef NUM_AXES + #define NUM_AXES_WARNING 1 +#endif + +#ifdef W_DRIVER_TYPE + #define NUM_AXES 9 +#elif defined(V_DRIVER_TYPE) + #define NUM_AXES 8 +#elif defined(U_DRIVER_TYPE) + #define NUM_AXES 7 +#elif defined(K_DRIVER_TYPE) + #define NUM_AXES 6 +#elif defined(J_DRIVER_TYPE) + #define NUM_AXES 5 +#elif defined(I_DRIVER_TYPE) + #define NUM_AXES 4 +#elif defined(Z_DRIVER_TYPE) + #define NUM_AXES 3 +#elif defined(Y_DRIVER_TYPE) + #define NUM_AXES 2 +#else + #define NUM_AXES 1 +#endif +#if NUM_AXES >= XY + #define HAS_Y_AXIS 1 + #if NUM_AXES >= XYZ + #define HAS_Z_AXIS 1 + #ifdef Z4_DRIVER_TYPE + #define NUM_Z_STEPPERS 4 + #elif defined(Z3_DRIVER_TYPE) + #define NUM_Z_STEPPERS 3 + #elif defined(Z2_DRIVER_TYPE) + #define NUM_Z_STEPPERS 2 + #else + #define NUM_Z_STEPPERS 1 + #endif + #if NUM_AXES >= 4 + #define HAS_I_AXIS 1 + #if NUM_AXES >= 5 + #define HAS_J_AXIS 1 + #if NUM_AXES >= 6 + #define HAS_K_AXIS 1 + #if NUM_AXES >= 7 + #define HAS_U_AXIS 1 + #if NUM_AXES >= 8 + #define HAS_V_AXIS 1 + #if NUM_AXES >= 9 + #define HAS_W_AXIS 1 + #endif + #endif + #endif + #endif + #endif + #endif + #endif +#endif + +#if E_STEPPERS <= 0 + #undef E0_DRIVER_TYPE +#endif +#if E_STEPPERS <= 1 + #undef E1_DRIVER_TYPE +#endif +#if E_STEPPERS <= 2 + #undef E2_DRIVER_TYPE +#endif +#if E_STEPPERS <= 3 + #undef E3_DRIVER_TYPE +#endif +#if E_STEPPERS <= 4 + #undef E4_DRIVER_TYPE +#endif +#if E_STEPPERS <= 5 + #undef E5_DRIVER_TYPE +#endif +#if E_STEPPERS <= 6 + #undef E6_DRIVER_TYPE +#endif +#if E_STEPPERS <= 7 + #undef E7_DRIVER_TYPE +#endif + +#if !HAS_Y_AXIS + #undef ENDSTOPPULLUP_YMIN + #undef ENDSTOPPULLUP_YMAX + #undef Y_MIN_ENDSTOP_INVERTING + #undef Y_MAX_ENDSTOP_INVERTING + #undef Y2_DRIVER_TYPE + #undef Y_ENABLE_ON + #undef DISABLE_Y + #undef INVERT_Y_DIR + #undef Y_HOME_DIR + #undef Y_MIN_POS + #undef Y_MAX_POS + #undef MANUAL_Y_HOME_POS + #undef MIN_SOFTWARE_ENDSTOP_Y + #undef MAX_SOFTWARE_ENDSTOP_Y + #undef SAFE_BED_LEVELING_START_Y +#endif + +#if !HAS_Z_AXIS + #undef ENDSTOPPULLUP_ZMIN + #undef ENDSTOPPULLUP_ZMAX + #undef Z_MIN_ENDSTOP_INVERTING + #undef Z_MAX_ENDSTOP_INVERTING + #undef Z2_DRIVER_TYPE + #undef Z3_DRIVER_TYPE + #undef Z4_DRIVER_TYPE + #undef Z_ENABLE_ON + #undef DISABLE_Z + #undef INVERT_Z_DIR + #undef Z_HOME_DIR + #undef Z_MIN_POS + #undef Z_MAX_POS + #undef MANUAL_Z_HOME_POS + #undef MIN_SOFTWARE_ENDSTOP_Z + #undef MAX_SOFTWARE_ENDSTOP_Z + #undef SAFE_BED_LEVELING_START_Z +#endif + +#if !HAS_I_AXIS + #undef ENDSTOPPULLUP_IMIN + #undef ENDSTOPPULLUP_IMAX + #undef I_MIN_ENDSTOP_INVERTING + #undef I_MAX_ENDSTOP_INVERTING + #undef I_ENABLE_ON + #undef DISABLE_I + #undef INVERT_I_DIR + #undef I_HOME_DIR + #undef I_MIN_POS + #undef I_MAX_POS + #undef MANUAL_I_HOME_POS + #undef MIN_SOFTWARE_ENDSTOP_I + #undef MAX_SOFTWARE_ENDSTOP_I + #undef SAFE_BED_LEVELING_START_I +#endif + +#if !HAS_J_AXIS + #undef ENDSTOPPULLUP_JMIN + #undef ENDSTOPPULLUP_JMAX + #undef J_MIN_ENDSTOP_INVERTING + #undef J_MAX_ENDSTOP_INVERTING + #undef J_ENABLE_ON + #undef DISABLE_J + #undef INVERT_J_DIR + #undef J_HOME_DIR + #undef J_MIN_POS + #undef J_MAX_POS + #undef MANUAL_J_HOME_POS + #undef MIN_SOFTWARE_ENDSTOP_J + #undef MAX_SOFTWARE_ENDSTOP_J + #undef SAFE_BED_LEVELING_START_J +#endif + +#if !HAS_K_AXIS + #undef ENDSTOPPULLUP_KMIN + #undef ENDSTOPPULLUP_KMAX + #undef K_MIN_ENDSTOP_INVERTING + #undef K_MAX_ENDSTOP_INVERTING + #undef K_ENABLE_ON + #undef DISABLE_K + #undef INVERT_K_DIR + #undef K_HOME_DIR + #undef K_MIN_POS + #undef K_MAX_POS + #undef MANUAL_K_HOME_POS + #undef MIN_SOFTWARE_ENDSTOP_K + #undef MAX_SOFTWARE_ENDSTOP_K + #undef SAFE_BED_LEVELING_START_K +#endif + +#if !HAS_U_AXIS + #undef ENDSTOPPULLUP_UMIN + #undef ENDSTOPPULLUP_UMAX + #undef U_MIN_ENDSTOP_INVERTING + #undef U_MAX_ENDSTOP_INVERTING + #undef U_ENABLE_ON + #undef DISABLE_U + #undef INVERT_U_DIR + #undef U_HOME_DIR + #undef U_MIN_POS + #undef U_MAX_POS + #undef MANUAL_U_HOME_POS + #undef MIN_SOFTWARE_ENDSTOP_U + #undef MAX_SOFTWARE_ENDSTOP_U + #undef SAFE_BED_LEVELING_START_U +#endif + +#if !HAS_V_AXIS + #undef ENDSTOPPULLUP_VMIN + #undef ENDSTOPPULLUP_VMAX + #undef V_MIN_ENDSTOP_INVERTING + #undef V_MAX_ENDSTOP_INVERTING + #undef V_ENABLE_ON + #undef DISABLE_V + #undef INVERT_V_DIR + #undef V_HOME_DIR + #undef V_MIN_POS + #undef V_MAX_POS + #undef MANUAL_V_HOME_POS + #undef MIN_SOFTWARE_ENDSTOP_V + #undef MAX_SOFTWARE_ENDSTOP_V + #undef SAFE_BED_LEVELING_START_V +#endif + +#if !HAS_W_AXIS + #undef ENDSTOPPULLUP_WMIN + #undef ENDSTOPPULLUP_WMAX + #undef W_MIN_ENDSTOP_INVERTING + #undef W_MAX_ENDSTOP_INVERTING + #undef W_ENABLE_ON + #undef DISABLE_W + #undef INVERT_W_DIR + #undef W_HOME_DIR + #undef W_MIN_POS + #undef W_MAX_POS + #undef MANUAL_W_HOME_POS + #undef MIN_SOFTWARE_ENDSTOP_W + #undef MAX_SOFTWARE_ENDSTOP_W + #undef SAFE_BED_LEVELING_START_W +#endif + +#ifdef X2_DRIVER_TYPE + #define HAS_X2_STEPPER 1 + // Dual X Carriage isn't known yet. TODO: Consider moving it to Configuration.h. +#endif +#ifdef Y2_DRIVER_TYPE + #define HAS_Y2_STEPPER 1 + #define HAS_DUAL_Y_STEPPERS 1 +#endif + +/** + * Number of Primary Linear Axes (e.g., XYZ) + * X, XY, or XYZ axes. Excluding duplicate axes (X2, Y2. Z2. Z3, Z4) + */ +#if NUM_AXES >= 3 + #define PRIMARY_LINEAR_AXES 3 +#else + #define PRIMARY_LINEAR_AXES NUM_AXES +#endif + +/** + * Number of Secondary Axes (e.g., IJKUVW) + * All linear/rotational axes between XYZ and E. + */ +#define SECONDARY_AXES SUB3(NUM_AXES) + +/** + * Number of Rotational Axes (e.g., IJK) + * All axes for which AXIS*_ROTATES is defined. + * For these axes, positions are specified in angular degrees. + */ +#if ENABLED(AXIS9_ROTATES) + #define ROTATIONAL_AXES 6 +#elif ENABLED(AXIS8_ROTATES) + #define ROTATIONAL_AXES 5 +#elif ENABLED(AXIS7_ROTATES) + #define ROTATIONAL_AXES 4 +#elif ENABLED(AXIS6_ROTATES) + #define ROTATIONAL_AXES 3 +#elif ENABLED(AXIS5_ROTATES) + #define ROTATIONAL_AXES 2 +#elif ENABLED(AXIS4_ROTATES) + #define ROTATIONAL_AXES 1 +#else + #define ROTATIONAL_AXES 0 +#endif + +/** + * Number of Secondary Linear Axes (e.g., UVW) + * All secondary axes for which AXIS*_ROTATES is not defined. + * Excluding primary axes and excluding duplicate axes (X2, Y2, Z2, Z3, Z4) + */ +#define SECONDARY_LINEAR_AXES (NUM_AXES - PRIMARY_LINEAR_AXES - ROTATIONAL_AXES) + +/** + * Number of Logical Axes (e.g., XYZIJKUVWE) + * All logical axes that can be commanded directly by G-code. + * Delta maps stepper-specific values to ABC steppers. + */ +#if HAS_EXTRUDERS + #define LOGICAL_AXES INCREMENT(NUM_AXES) +#else + #define LOGICAL_AXES NUM_AXES +#endif + +/** + * DISTINCT_E_FACTORS is set to give extruders (some) individual settings. + * + * DISTINCT_AXES is the number of distinct addressable axes (not steppers). + * Includes all linear axes plus all distinguished extruders. + * The default behavior is to treat all extruders as a single E axis + * with shared motion and temperature settings. + * + * DISTINCT_E is the number of distinguished extruders. By default this + * will be 1 which indicates all extruders share the same settings. + * + * E_INDEX_N(E) should be used to get the E index of any item that might be + * distinguished. + */ +#if ENABLED(DISTINCT_E_FACTORS) && E_STEPPERS > 1 + #define DISTINCT_AXES (NUM_AXES + E_STEPPERS) + #define DISTINCT_E E_STEPPERS + #define E_INDEX_N(E) (E) +#else + #undef DISTINCT_E_FACTORS + #define DISTINCT_AXES LOGICAL_AXES + #define DISTINCT_E 1 + #define E_INDEX_N(E) 0 +#endif + +#if HOTENDS + #define HAS_HOTEND 1 + #ifndef HOTEND_OVERSHOOT + #define HOTEND_OVERSHOOT 15 + #endif + #if HOTENDS > 1 + #define HAS_MULTI_HOTEND 1 + #define HAS_HOTEND_OFFSET 1 + #endif +#else + #undef PID_PARAMS_PER_HOTEND +#endif + +// Helper macros for extruder and hotend arrays +#define EXTRUDER_LOOP() for (int8_t e = 0; e < EXTRUDERS; e++) +#define HOTEND_LOOP() for (int8_t e = 0; e < HOTENDS; e++) +#define ARRAY_BY_EXTRUDERS(V...) ARRAY_N(EXTRUDERS, V) +#define ARRAY_BY_EXTRUDERS1(v1) ARRAY_N_1(EXTRUDERS, v1) +#define ARRAY_BY_HOTENDS(V...) ARRAY_N(HOTENDS, V) +#define ARRAY_BY_HOTENDS1(v1) ARRAY_N_1(HOTENDS, v1) + +/** + * Default hotend offsets, if not defined + */ +#if HAS_HOTEND_OFFSET + #ifndef HOTEND_OFFSET_X + #define HOTEND_OFFSET_X { 0 } // X offsets for each extruder + #endif + #ifndef HOTEND_OFFSET_Y + #define HOTEND_OFFSET_Y { 0 } // Y offsets for each extruder + #endif + #ifndef HOTEND_OFFSET_Z + #define HOTEND_OFFSET_Z { 0 } // Z offsets for each extruder + #endif +#endif + /** * Disable unused SINGLENOZZLE sub-options */ #if DISABLED(SINGLENOZZLE) #undef SINGLENOZZLE_STANDBY_TEMP #endif -#if !ALL(HAS_FAN, SINGLENOZZLE) +#if !BOTH(HAS_FAN, SINGLENOZZLE) #undef SINGLENOZZLE_STANDBY_FAN #endif -// No inactive extruders with SWITCHING_NOZZLE or Průša MMU1 or just 1 E stepper exists -#if HAS_SWITCHING_NOZZLE || HAS_PRUSA_MMU1 || E_STEPPERS < 2 - #undef DISABLE_OTHER_EXTRUDERS -#endif - // Switching extruder has its own servo? -#if ENABLED(SWITCHING_EXTRUDER) && (!HAS_SWITCHING_NOZZLE || SWITCHING_EXTRUDER_SERVO_NR != SWITCHING_NOZZLE_SERVO_NR) +#if ENABLED(SWITCHING_EXTRUDER) && (DISABLED(SWITCHING_NOZZLE) || SWITCHING_EXTRUDER_SERVO_NR != SWITCHING_NOZZLE_SERVO_NR) #define DO_SWITCH_EXTRUDER 1 #endif @@ -1152,8 +1061,24 @@ * The BLTouch Probe emulates a servo probe * and uses "special" angles for its state. */ -#if ENABLED(BLTOUCH) && !defined(Z_PROBE_SERVO_NR) - #define Z_PROBE_SERVO_NR 0 +#if ENABLED(BLTOUCH) + #ifndef Z_PROBE_SERVO_NR + #define Z_PROBE_SERVO_NR 0 + #endif + #ifdef DEACTIVATE_SERVOS_AFTER_MOVE + #error "BLTOUCH requires DEACTIVATE_SERVOS_AFTER_MOVE to be to disabled. Please update your Configuration.h file." + #endif + + // Always disable probe pin inverting for BLTouch + #if Z_MIN_PROBE_ENDSTOP_INVERTING + #error "BLTOUCH requires Z_MIN_PROBE_ENDSTOP_INVERTING set to false. Please update your Configuration.h file." + #endif + + #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) + #if Z_MIN_ENDSTOP_INVERTING + #error "BLTOUCH requires Z_MIN_ENDSTOP_INVERTING set to false. Please update your Configuration.h file." + #endif + #endif #endif /** @@ -1172,29 +1097,25 @@ /** * Set flags for any form of bed probe */ -#if ANY(TOUCH_MI_PROBE, Z_PROBE_ALLEN_KEY, HAS_Z_SERVO_PROBE, SOLENOID_PROBE, Z_PROBE_SLED, RACK_AND_PINION_PROBE, SENSORLESS_PROBING, MAGLEV4, MAG_MOUNTED_PROBE, BIQU_MICROPROBE_V1, BIQU_MICROPROBE_V2) +#if ANY(TOUCH_MI_PROBE, Z_PROBE_ALLEN_KEY, SOLENOID_PROBE, Z_PROBE_SLED, RACK_AND_PINION_PROBE, SENSORLESS_PROBING, MAGLEV4, MAG_MOUNTED_PROBE) #define HAS_STOWABLE_PROBE 1 #endif -#if ANY(HAS_STOWABLE_PROBE, FIX_MOUNTED_PROBE, BD_SENSOR, NOZZLE_AS_PROBE) +#if ANY(HAS_STOWABLE_PROBE, HAS_Z_SERVO_PROBE, FIX_MOUNTED_PROBE, BD_SENSOR, NOZZLE_AS_PROBE) #define HAS_BED_PROBE 1 #endif -// Probing tool change -#if !HAS_MULTI_EXTRUDER - #undef PROBING_TOOL -#endif -#if HAS_BED_PROBE && defined(PROBING_TOOL) - #define DO_TOOLCHANGE_FOR_PROBING 1 -#endif - /** * Fill in undefined Filament Sensor options */ #if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define HAS_FILAMENT_SENSOR 1 + #ifndef NUM_RUNOUT_SENSORS + #define NUM_RUNOUT_SENSORS E_STEPPERS + #endif + #if ENABLED(MIXING_EXTRUDER) + #define WATCH_ALL_RUNOUT_SENSORS + #endif #if NUM_RUNOUT_SENSORS >= 1 - #ifndef FIL_RUNOUT1_STATE - #define FIL_RUNOUT1_STATE FIL_RUNOUT_STATE - #endif #ifndef FIL_RUNOUT1_PULLUP #define FIL_RUNOUT1_PULLUP FIL_RUNOUT_PULLUP #endif @@ -1203,9 +1124,7 @@ #endif #endif #if NUM_RUNOUT_SENSORS >= 2 - #ifndef FIL_RUNOUT2_STATE - #define FIL_RUNOUT2_STATE FIL_RUNOUT_STATE - #endif + #define MULTI_FILAMENT_SENSOR 1 #ifndef FIL_RUNOUT2_PULLUP #define FIL_RUNOUT2_PULLUP FIL_RUNOUT_PULLUP #endif @@ -1214,9 +1133,6 @@ #endif #endif #if NUM_RUNOUT_SENSORS >= 3 - #ifndef FIL_RUNOUT3_STATE - #define FIL_RUNOUT3_STATE FIL_RUNOUT_STATE - #endif #ifndef FIL_RUNOUT3_PULLUP #define FIL_RUNOUT3_PULLUP FIL_RUNOUT_PULLUP #endif @@ -1225,9 +1141,6 @@ #endif #endif #if NUM_RUNOUT_SENSORS >= 4 - #ifndef FIL_RUNOUT4_STATE - #define FIL_RUNOUT4_STATE FIL_RUNOUT_STATE - #endif #ifndef FIL_RUNOUT4_PULLUP #define FIL_RUNOUT4_PULLUP FIL_RUNOUT_PULLUP #endif @@ -1236,9 +1149,6 @@ #endif #endif #if NUM_RUNOUT_SENSORS >= 5 - #ifndef FIL_RUNOUT5_STATE - #define FIL_RUNOUT5_STATE FIL_RUNOUT_STATE - #endif #ifndef FIL_RUNOUT5_PULLUP #define FIL_RUNOUT5_PULLUP FIL_RUNOUT_PULLUP #endif @@ -1247,9 +1157,6 @@ #endif #endif #if NUM_RUNOUT_SENSORS >= 6 - #ifndef FIL_RUNOUT6_STATE - #define FIL_RUNOUT6_STATE FIL_RUNOUT_STATE - #endif #ifndef FIL_RUNOUT6_PULLUP #define FIL_RUNOUT6_PULLUP FIL_RUNOUT_PULLUP #endif @@ -1258,9 +1165,6 @@ #endif #endif #if NUM_RUNOUT_SENSORS >= 7 - #ifndef FIL_RUNOUT7_STATE - #define FIL_RUNOUT7_STATE FIL_RUNOUT_STATE - #endif #ifndef FIL_RUNOUT7_PULLUP #define FIL_RUNOUT7_PULLUP FIL_RUNOUT_PULLUP #endif @@ -1269,9 +1173,6 @@ #endif #endif #if NUM_RUNOUT_SENSORS >= 8 - #ifndef FIL_RUNOUT8_STATE - #define FIL_RUNOUT8_STATE FIL_RUNOUT_STATE - #endif #ifndef FIL_RUNOUT8_PULLUP #define FIL_RUNOUT8_PULLUP FIL_RUNOUT_PULLUP #endif @@ -1281,104 +1182,11 @@ #endif #endif // FILAMENT_RUNOUT_SENSOR -#if ENABLED(FILAMENT_SWITCH_AND_MOTION) - #if NUM_MOTION_SENSORS >= 1 - #ifndef FIL_MOTION1_STATE - #define FIL_MOTION1_STATE FIL_RUNOUT_STATE - #endif - #ifndef FIL_MOTION1_PULLUP - #define FIL_MOTION1_PULLUP FIL_RUNOUT_PULLUP - #endif - #ifndef FIL_MOTION1_PULLDOWN - #define FIL_MOTION1_PULLDOWN FIL_RUNOUT_PULLDOWN - #endif - #endif - #if NUM_MOTION_SENSORS >= 2 - #ifndef FIL_MOTION2_STATE - #define FIL_MOTION2_STATE FIL_RUNOUT_STATE - #endif - #ifndef FIL_MOTION2_PULLUP - #define FIL_MOTION2_PULLUP FIL_RUNOUT_PULLUP - #endif - #ifndef FIL_MOTION2_PULLDOWN - #define FIL_MOTION2_PULLDOWN FIL_RUNOUT_PULLDOWN - #endif - #endif - #if NUM_MOTION_SENSORS >= 3 - #ifndef FIL_MOTION3_STATE - #define FIL_MOTION3_STATE FIL_RUNOUT_STATE - #endif - #ifndef FIL_MOTION3_PULLUP - #define FIL_MOTION3_PULLUP FIL_RUNOUT_PULLUP - #endif - #ifndef FIL_MOTION3_PULLDOWN - #define FIL_MOTION3_PULLDOWN FIL_RUNOUT_PULLDOWN - #endif - #endif - #if NUM_MOTION_SENSORS >= 4 - #ifndef FIL_MOTION4_STATE - #define FIL_MOTION4_STATE FIL_RUNOUT_STATE - #endif - #ifndef FIL_MOTION4_PULLUP - #define FIL_MOTION4_PULLUP FIL_RUNOUT_PULLUP - #endif - #ifndef FIL_MOTION4_PULLDOWN - #define FIL_MOTION4_PULLDOWN FIL_RUNOUT_PULLDOWN - #endif - #endif - #if NUM_MOTION_SENSORS >= 5 - #ifndef FIL_MOTION5_STATE - #define FIL_MOTION5_STATE FIL_RUNOUT_STATE - #endif - #ifndef FIL_MOTION5_PULLUP - #define FIL_MOTION5_PULLUP FIL_RUNOUT_PULLUP - #endif - #ifndef FIL_MOTION5_PULLDOWN - #define FIL_MOTION5_PULLDOWN FIL_RUNOUT_PULLDOWN - #endif - #endif - #if NUM_MOTION_SENSORS >= 6 - #ifndef FIL_MOTION6_STATE - #define FIL_MOTION6_STATE FIL_RUNOUT_STATE - #endif - #ifndef FIL_MOTION6_PULLUP - #define FIL_MOTION6_PULLUP FIL_RUNOUT_PULLUP - #endif - #ifndef FIL_MOTION6_PULLDOWN - #define FIL_MOTION6_PULLDOWN FIL_RUNOUT_PULLDOWN - #endif - #endif - #if NUM_MOTION_SENSORS >= 7 - #ifndef FIL_MOTION7_STATE - #define FIL_MOTION7_STATE FIL_RUNOUT_STATE - #endif - #ifndef FIL_MOTION7_PULLUP - #define FIL_MOTION7_PULLUP FIL_RUNOUT_PULLUP - #endif - #ifndef FIL_MOTION7_PULLDOWN - #define FIL_MOTION7_PULLDOWN FIL_RUNOUT_PULLDOWN - #endif - #endif - #if NUM_MOTION_SENSORS >= 8 - #ifndef FIL_MOTION8_STATE - #define FIL_MOTION8_STATE FIL_RUNOUT_STATE - #endif - #ifndef FIL_MOTION8_PULLUP - #define FIL_MOTION8_PULLUP FIL_RUNOUT_PULLUP - #endif - #ifndef FIL_MOTION8_PULLDOWN - #define FILMOTION8_PULLDOWN FIL_RUNOUT_PULLDOWN - #endif - #endif -#endif // FILAMENT_SWITCH_AND_MOTION - // Homing to Min or Max -#if HAS_X_AXIS - #if X_HOME_DIR > 0 - #define X_HOME_TO_MAX 1 - #elif X_HOME_DIR < 0 - #define X_HOME_TO_MIN 1 - #endif +#if X_HOME_DIR > 0 + #define X_HOME_TO_MAX 1 +#elif X_HOME_DIR < 0 + #define X_HOME_TO_MIN 1 #endif #if HAS_Y_AXIS #if Y_HOME_DIR > 0 @@ -1441,32 +1249,24 @@ * Conditionals based on the type of Bed Probe */ #if HAS_BED_PROBE - #if ALL(DELTA, SENSORLESS_PROBING) - #define HAS_DELTA_SENSORLESS_PROBING 1 - #else - #define HAS_REAL_BED_PROBE 1 - #endif - #if HAS_REAL_BED_PROBE && NONE(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, Z_SPI_SENSORLESS) - #define NEED_Z_MIN_PROBE_PIN 1 - #endif - #if Z_HOME_TO_MIN && (!NEED_Z_MIN_PROBE_PIN || ENABLED(USE_PROBE_FOR_Z_HOMING)) - #define HOMING_Z_WITH_PROBE 1 - #endif #if DISABLED(NOZZLE_AS_PROBE) #define HAS_PROBE_XY_OFFSET 1 #endif - #if ANY(Z_PROBE_ALLEN_KEY, MAG_MOUNTED_PROBE) + #if BOTH(DELTA, SENSORLESS_PROBING) + #define HAS_DELTA_SENSORLESS_PROBING 1 + #endif + #if NONE(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, HAS_DELTA_SENSORLESS_PROBING) + #define USES_Z_MIN_PROBE_PIN 1 + #endif + #if Z_HOME_TO_MIN && (DISABLED(USES_Z_MIN_PROBE_PIN) || ENABLED(USE_PROBE_FOR_Z_HOMING)) + #define HOMING_Z_WITH_PROBE 1 + #endif + #ifndef Z_PROBE_LOW_POINT + #define Z_PROBE_LOW_POINT -5 + #endif + #if EITHER(Z_PROBE_ALLEN_KEY, MAG_MOUNTED_PROBE) #define PROBE_TRIGGERED_WHEN_STOWED_TEST 1 // Extra test for Allen Key Probe #endif - #ifndef Z_CLEARANCE_BETWEEN_PROBES - #define Z_CLEARANCE_BETWEEN_PROBES 5 - #endif - #ifndef Z_CLEARANCE_MULTI_PROBE - #define Z_CLEARANCE_MULTI_PROBE 5 - #endif - #ifndef Z_PROBE_ERROR_TOLERANCE - #define Z_PROBE_ERROR_TOLERANCE Z_CLEARANCE_MULTI_PROBE - #endif #if MULTIPLE_PROBING > 1 #if EXTRA_PROBING > 0 #define TOTAL_PROBING (MULTIPLE_PROBING + EXTRA_PROBING) @@ -1478,32 +1278,6 @@ // Clear probe pin settings when no probe is selected #undef Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN #undef USE_PROBE_FOR_Z_HOMING - #undef Z_MIN_PROBE_REPEATABILITY_TEST - #undef HOMING_Z_WITH_PROBE - #undef Z_CLEARANCE_MULTI_PROBE - #undef Z_PROBE_ERROR_TOLERANCE - #undef MULTIPLE_PROBING - #undef EXTRA_PROBING - #undef PROBE_OFFSET_ZMIN - #undef PROBE_OFFSET_ZMAX - #undef PAUSE_BEFORE_DEPLOY_STOW - #undef PAUSE_PROBE_DEPLOY_WHEN_TRIGGERED - #undef PROBING_HEATERS_OFF - #undef WAIT_FOR_BED_HEATER - #undef WAIT_FOR_HOTEND - #undef PROBING_STEPPERS_OFF - #undef DELAY_BEFORE_PROBING - #undef PREHEAT_BEFORE_PROBING - #undef PROBING_NOZZLE_TEMP - #undef PROBING_BED_TEMP - #undef NOZZLE_TO_PROBE_OFFSET -#endif - -#ifndef Z_CLEARANCE_DEPLOY_PROBE - #define Z_CLEARANCE_DEPLOY_PROBE 10 -#endif -#ifndef Z_PROBE_LOW_POINT - #define Z_PROBE_LOW_POINT -5 #endif #if ENABLED(BELTPRINTER) && !defined(HOME_Y_BEFORE_X) @@ -1519,14 +1293,14 @@ */ #if ENABLED(AUTO_BED_LEVELING_UBL) #undef LCD_BED_LEVELING - #if ANY(DELTA, SEGMENT_LEVELED_MOVES) + #if EITHER(DELTA, SEGMENT_LEVELED_MOVES) #define UBL_SEGMENTED 1 #endif #endif -#if ANY(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_3POINT) +#if EITHER(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_3POINT) #define ABL_PLANAR 1 #endif -#if ANY(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR) +#if EITHER(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR) #define ABL_USES_GRID 1 #endif #if ANY(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_3POINT) @@ -1535,16 +1309,16 @@ #if ANY(AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_UBL, MESH_BED_LEVELING) #define HAS_MESH 1 #endif -#if ANY(AUTO_BED_LEVELING_UBL, AUTO_BED_LEVELING_3POINT) +#if EITHER(AUTO_BED_LEVELING_UBL, AUTO_BED_LEVELING_3POINT) #define NEEDS_THREE_PROBE_POINTS 1 #endif -#if ANY(HAS_ABL_NOT_UBL, AUTO_BED_LEVELING_UBL) +#if EITHER(HAS_ABL_NOT_UBL, AUTO_BED_LEVELING_UBL) #define HAS_ABL_OR_UBL 1 #if DISABLED(PROBE_MANUALLY) #define HAS_AUTOLEVEL 1 #endif #endif -#if ANY(HAS_ABL_OR_UBL, MESH_BED_LEVELING) +#if EITHER(HAS_ABL_OR_UBL, MESH_BED_LEVELING) #define HAS_LEVELING 1 #if DISABLED(AUTO_BED_LEVELING_UBL) #define PLANNER_LEVELING 1 @@ -1555,7 +1329,7 @@ #undef ENABLE_LEVELING_AFTER_G28 #undef G29_RETRY_AND_RECOVER #endif -#if !HAS_LEVELING || ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL) +#if !HAS_LEVELING || EITHER(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL) #undef PROBE_MANUALLY #endif #if ANY(HAS_BED_PROBE, PROBE_MANUALLY, MESH_BED_LEVELING) @@ -1564,7 +1338,7 @@ #ifdef GRID_MAX_POINTS_X #define GRID_MAX_POINTS ((GRID_MAX_POINTS_X) * (GRID_MAX_POINTS_Y)) - #define GRID_LOOP(A,B) for (uint8_t A = 0; A < GRID_MAX_POINTS_X; ++A) for (uint8_t B = 0; B < GRID_MAX_POINTS_Y; ++B) + #define GRID_LOOP(A,B) LOOP_L_N(A, GRID_MAX_POINTS_X) LOOP_L_N(B, GRID_MAX_POINTS_Y) #endif // Slim menu optimizations @@ -1572,24 +1346,16 @@ #define BOOT_MARLIN_LOGO_SMALL #endif -// Flow and feedrate editing -#if HAS_EXTRUDERS && ANY(HAS_MARLINUI_MENU, DWIN_CREALITY_LCD, DWIN_LCD_PROUI, MALYAN_LCD, TOUCH_SCREEN) - #define HAS_FLOW_EDIT 1 -#endif -#if ANY(HAS_MARLINUI_MENU, ULTIPANEL_FEEDMULTIPLY, DWIN_CREALITY_LCD, DWIN_LCD_PROUI, MALYAN_LCD, TOUCH_SCREEN) - #define HAS_FEEDRATE_EDIT 1 -#endif - /** * CoreXY, CoreXZ, and CoreYZ - and their reverse */ -#if ANY(COREXY, COREYX) +#if EITHER(COREXY, COREYX) #define CORE_IS_XY 1 #endif -#if ANY(COREXZ, COREZX) +#if EITHER(COREXZ, COREZX) #define CORE_IS_XZ 1 #endif -#if ANY(COREYZ, COREZY) +#if EITHER(COREYZ, COREZY) #define CORE_IS_YZ 1 #endif #if CORE_IS_XY || CORE_IS_XZ || CORE_IS_YZ @@ -1610,7 +1376,7 @@ #define CORE_AXIS_2 C_AXIS #endif #define CORESIGN(n) (ANY(COREYX, COREZX, COREZY) ? (-(n)) : (n)) -#elif ANY(MARKFORGED_XY, MARKFORGED_YX) +#elif EITHER(MARKFORGED_XY, MARKFORGED_YX) // Markforged kinematics #define CORE_AXIS_1 A_AXIS #define CORE_AXIS_2 B_AXIS @@ -1620,7 +1386,7 @@ #if ANY(MORGAN_SCARA, MP_SCARA, AXEL_TPARA) #define IS_SCARA 1 #define IS_KINEMATIC 1 -#elif ANY(DELTA, POLARGRAPH, POLAR) +#elif EITHER(DELTA, POLARGRAPH) #define IS_KINEMATIC 1 #else #define IS_CARTESIAN 1 @@ -1633,6 +1399,20 @@ #undef DELTA_HOME_TO_SAFE_ZONE #endif +// This flag indicates some kind of jerk storage is needed +#if EITHER(CLASSIC_JERK, IS_KINEMATIC) + #define HAS_CLASSIC_JERK 1 +#endif + +#if DISABLED(CLASSIC_JERK) + #define HAS_JUNCTION_DEVIATION 1 +#endif + +// E jerk exists with JD disabled (of course) but also when Linear Advance is disabled on Delta/SCARA +#if HAS_EXTRUDERS && (ENABLED(CLASSIC_JERK) || (IS_KINEMATIC && DISABLED(LIN_ADVANCE))) + #define HAS_CLASSIC_E_JERK 1 +#endif + // // Serial Port Info // @@ -1668,10 +1448,6 @@ #define HAS_PID_DEBUG 1 #endif -#if DISABLED(MPC_AUTOTUNE) - #undef MPC_AUTOTUNE_MENU -#endif - /** * TFT Displays * @@ -1684,13 +1460,12 @@ * - TFT_COLOR * - GRAPHICAL_TFT_UPSCALE */ -#if ANY(MKS_TS35_V2_0, BTT_TFT35_SPI_V1_0) // ST7796 +#if EITHER(MKS_TS35_V2_0, BTT_TFT35_SPI_V1_0) // ST7796 #define TFT_DEFAULT_DRIVER ST7796 #define TFT_DEFAULT_ORIENTATION TFT_EXCHANGE_XY #define TFT_RES_480x320 #define TFT_INTERFACE_SPI - #define NO_LCD_SDCARD -#elif ANY(LERDGE_TFT35, ANET_ET5_TFT35) // ST7796 +#elif EITHER(LERDGE_TFT35, ANET_ET5_TFT35) // ST7796 #define TFT_DEFAULT_ORIENTATION TFT_EXCHANGE_XY #define TFT_RES_480x320 #define TFT_INTERFACE_FSMC @@ -1708,7 +1483,7 @@ #define TFT_DEFAULT_ORIENTATION 0 #define TFT_RES_480x272 #define TFT_INTERFACE_FSMC -#elif ANY(MKS_ROBIN_TFT_V1_1R, LONGER_LK_TFT28) // ILI9328 or R61505 +#elif EITHER(MKS_ROBIN_TFT_V1_1R, LONGER_LK_TFT28) // ILI9328 or R61505 #define TFT_DEFAULT_ORIENTATION (TFT_EXCHANGE_XY | TFT_INVERT_X | TFT_INVERT_Y) #define TFT_RES_320x240 #define TFT_INTERFACE_FSMC @@ -1729,6 +1504,30 @@ #endif #endif +#if ENABLED(TFT_RES_320x240) + #define TFT_WIDTH 320 + #define TFT_HEIGHT 240 + #define GRAPHICAL_TFT_UPSCALE 2 +#elif ENABLED(TFT_RES_480x272) + #define TFT_WIDTH 480 + #define TFT_HEIGHT 272 + #define GRAPHICAL_TFT_UPSCALE 2 +#elif ENABLED(TFT_RES_480x320) + #define TFT_WIDTH 480 + #define TFT_HEIGHT 320 + #define GRAPHICAL_TFT_UPSCALE 3 +#elif ENABLED(TFT_RES_1024x600) + #define TFT_WIDTH 1024 + #define TFT_HEIGHT 600 + #if ENABLED(TOUCH_SCREEN) + #define GRAPHICAL_TFT_UPSCALE 6 + #define TFT_PIXEL_OFFSET_X 120 + #else + #define GRAPHICAL_TFT_UPSCALE 8 + #define TFT_PIXEL_OFFSET_X 0 + #endif +#endif + // FSMC/SPI TFT Panels using standard HAL/tft/tft_(fsmc|spi|ltdc).h #if ENABLED(TFT_INTERFACE_FSMC) #define HAS_FSMC_TFT 1 @@ -1753,52 +1552,14 @@ #endif #endif -#if ANY(HAS_SPI_TFT, HAS_FSMC_TFT, HAS_LTDC_TFT) - #include "../lcd/tft_io/tft_orientation.h" // for TFT_COLOR_UI_PORTRAIT -#endif - -#if ENABLED(TFT_RES_320x240) - #if ENABLED(TFT_COLOR_UI_PORTRAIT) - #define TFT_WIDTH 240 - #define TFT_HEIGHT 320 - #else - #define TFT_WIDTH 320 - #define TFT_HEIGHT 240 - #endif - #define GRAPHICAL_TFT_UPSCALE 2 -#elif ENABLED(TFT_RES_480x272) - #define TFT_WIDTH 480 - #define TFT_HEIGHT 272 - #define GRAPHICAL_TFT_UPSCALE 2 -#elif ENABLED(TFT_RES_480x320) - #if ENABLED(TFT_COLOR_UI_PORTRAIT) - #define TFT_WIDTH 320 - #define TFT_HEIGHT 480 - #else - #define TFT_WIDTH 480 - #define TFT_HEIGHT 320 - #endif - #define GRAPHICAL_TFT_UPSCALE 3 -#elif ENABLED(TFT_RES_1024x600) - #define TFT_WIDTH 1024 - #define TFT_HEIGHT 600 - #if ENABLED(TOUCH_SCREEN) - #define GRAPHICAL_TFT_UPSCALE 6 - #define TFT_PIXEL_OFFSET_X 120 - #else - #define GRAPHICAL_TFT_UPSCALE 8 - #define TFT_PIXEL_OFFSET_X 0 - #endif -#endif - #if ENABLED(TFT_COLOR_UI) - #if (TFT_WIDTH == 320 && TFT_HEIGHT == 240) || (TFT_WIDTH == 240 && TFT_HEIGHT == 320) + #if TFT_HEIGHT == 240 #if ENABLED(TFT_INTERFACE_SPI) #define TFT_320x240_SPI #elif ENABLED(TFT_INTERFACE_FSMC) #define TFT_320x240 #endif - #elif TFT_HEIGHT == 320 || (TFT_HEIGHT == 480 && ENABLED(TFT_COLOR_UI_PORTRAIT)) + #elif TFT_HEIGHT == 320 #if ENABLED(TFT_INTERFACE_SPI) #define TFT_480x320_SPI #elif ENABLED(TFT_INTERFACE_FSMC) @@ -1819,39 +1580,33 @@ #endif #endif -#if ANY(TFT_320x240, TFT_320x240_SPI) +#if EITHER(TFT_320x240, TFT_320x240_SPI) #define HAS_UI_320x240 1 -#elif ANY(TFT_480x320, TFT_480x320_SPI) +#elif EITHER(TFT_480x320, TFT_480x320_SPI) #define HAS_UI_480x320 1 -#elif ANY(TFT_480x272, TFT_480x272_SPI) +#elif EITHER(TFT_480x272, TFT_480x272_SPI) #define HAS_UI_480x272 1 -#elif ANY(TFT_1024x600_LTDC, TFT_1024x600_SIM) +#elif EITHER(TFT_1024x600_LTDC, TFT_1024x600_SIM) #define HAS_UI_1024x600 1 #endif - -// Number of text lines the screen can display (may depend on font used) -// Touch screens leave space for extra buttons at the bottom -#if ANY(HAS_UI_320x240, HAS_UI_480x272) - #if ENABLED(TFT_COLOR_UI_PORTRAIT) - #define LCD_HEIGHT TERN(TOUCH_SCREEN, 8, 9) - #else - #define LCD_HEIGHT TERN(TOUCH_SCREEN, 6, 7) - #endif -#elif HAS_UI_480x320 - #if ENABLED(TFT_COLOR_UI_PORTRAIT) - #define LCD_HEIGHT TERN(TOUCH_SCREEN, 9, 10) - #else - #define LCD_HEIGHT TERN(TOUCH_SCREEN, 6, 7) - #endif +#if ANY(HAS_UI_320x240, HAS_UI_480x320, HAS_UI_480x272) + #define LCD_HEIGHT TERN(TOUCH_SCREEN, 6, 7) // Fewer lines with touch buttons onscreen #elif HAS_UI_1024x600 - #define LCD_HEIGHT TERN(TOUCH_SCREEN, 12, 13) + #define LCD_HEIGHT TERN(TOUCH_SCREEN, 12, 13) // Fewer lines with touch buttons onscreen #endif // This emulated DOGM has 'touch/xpt2046', not 'tft/xpt2046' #if ENABLED(TOUCH_SCREEN) + #if TOUCH_IDLE_SLEEP_MINS + #define HAS_TOUCH_SLEEP 1 + #endif #if NONE(TFT_TOUCH_DEVICE_GT911, TFT_TOUCH_DEVICE_XPT2046) #define TFT_TOUCH_DEVICE_XPT2046 // ADS7843/XPT2046 ADC Touchscreen such as ILI9341 2.8 #endif + #if ENABLED(TFT_TOUCH_DEVICE_GT911) // GT911 Capacitive touch screen such as BIQU_BX_TFT70 + #undef TOUCH_SCREEN_CALIBRATION + #undef TOUCH_CALIBRATION_AUTO_SAVE + #endif #if !HAS_GRAPHICAL_TFT #undef TOUCH_SCREEN #if ENABLED(TFT_CLASSIC_UI) @@ -1865,9 +1620,18 @@ #endif #endif -#if (HAS_X_AXIS && X_HOME_DIR) || (HAS_Y_AXIS && Y_HOME_DIR) || (HAS_Z_AXIS && Z_HOME_DIR) \ - || (HAS_I_AXIS && I_HOME_DIR) || (HAS_J_AXIS && J_HOME_DIR) || (HAS_K_AXIS && K_HOME_DIR) \ - || (HAS_U_AXIS && U_HOME_DIR) || (HAS_V_AXIS && V_HOME_DIR) || (HAS_W_AXIS && W_HOME_DIR) +// XPT2046_** Compatibility +#if !(defined(TOUCH_CALIBRATION_X) || defined(TOUCH_CALIBRATION_Y) || defined(TOUCH_OFFSET_X) || defined(TOUCH_OFFSET_Y) || defined(TOUCH_ORIENTATION)) + #if defined(XPT2046_X_CALIBRATION) && defined(XPT2046_Y_CALIBRATION) && defined(XPT2046_X_OFFSET) && defined(XPT2046_Y_OFFSET) + #define TOUCH_CALIBRATION_X XPT2046_X_CALIBRATION + #define TOUCH_CALIBRATION_Y XPT2046_Y_CALIBRATION + #define TOUCH_OFFSET_X XPT2046_X_OFFSET + #define TOUCH_OFFSET_Y XPT2046_Y_OFFSET + #define TOUCH_ORIENTATION TOUCH_LANDSCAPE + #endif +#endif + +#if X_HOME_DIR || (HAS_Y_AXIS && Y_HOME_DIR) || (HAS_Z_AXIS && Z_HOME_DIR) || (HAS_I_AXIS && I_HOME_DIR) || (HAS_J_AXIS && J_HOME_DIR) || (HAS_K_AXIS && K_HOME_DIR) #define HAS_ENDSTOPS 1 #define COORDINATE_OKAY(N,L,H) WITHIN(N,L,H) #else @@ -1881,6 +1645,27 @@ #define NEOPIXEL_BKGD_INDEX_LAST NEOPIXEL_BKGD_INDEX_FIRST #endif -#if ALL(SPI_FLASH, HAS_MEDIA, MARLIN_DEV_MODE) - #define SPI_FLASH_BACKUP 1 +/*** TEMPORARY COMPATIBILITY ***/ + +#if HAS_FILAMENT_SENSOR + #ifndef FIL_RUNOUT_ENABLED + #if FIL_RUNOUT_ENABLED_DEFAULT + #define FIL_RUNOUT_ENABLED ARRAY_N_1(NUM_RUNOUT_SENSORS, true) + #else + #define FIL_RUNOUT_ENABLED ARRAY_N_1(NUM_RUNOUT_SENSORS, false) + #endif + #endif + #ifndef FIL_RUNOUT_MODE + #if FIL_RUNOUT_STATE + #define FIL_RUNOUT_MODE ARRAY_N_1(NUM_RUNOUT_SENSORS, 1) + #else + #define FIL_RUNOUT_MODE ARRAY_N_1(NUM_RUNOUT_SENSORS, 2) + #endif + #endif + #ifndef FIL_RUNOUT_DISTANCE_MM + #define FIL_RUNOUT_DISTANCE_MM ARRAY_N_1(NUM_RUNOUT_SENSORS, 10) + #endif + #undef FIL_RUNOUT_ENABLED_DEFAULT + #undef FIL_RUNOUT_STATE + #undef FILAMENT_RUNOUT_DISTANCE_MM #endif diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index aa55731d90..0dd5c30d09 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -26,36 +26,30 @@ * Conditionals set before pins.h and which depend on Configuration_adv.h. */ -#if ENABLED(MARLIN_SMALL_BUILD) - #undef EEPROM_CHITCHAT - #undef CAPABILITIES_REPORT - #define DISABLE_M503 -#endif - #ifndef AXIS_RELATIVE_MODES #define AXIS_RELATIVE_MODES {} #endif -#if defined(SWITCHING_NOZZLE_E1_SERVO_NR) && DISABLED(MECHANICAL_SWITCHING_NOZZLE) +#ifdef SWITCHING_NOZZLE_E1_SERVO_NR #define SWITCHING_NOZZLE_TWO_SERVOS 1 #endif // Determine NUM_SERVOS if none was supplied #ifndef NUM_SERVOS #define NUM_SERVOS 0 - #if HAS_Z_SERVO_PROBE && NUM_SERVOS <= Z_PROBE_SERVO_NR - #undef NUM_SERVOS - #define NUM_SERVOS (Z_PROBE_SERVO_NR + 1) - #endif - #if ENABLED(CHAMBER_VENT) && NUM_SERVOS <= CHAMBER_VENT_SERVO_NR - #undef NUM_SERVOS - #define NUM_SERVOS (CHAMBER_VENT_SERVO_NR + 1) - #endif - #if ENABLED(SWITCHING_TOOLHEAD) && NUM_SERVOS <= SWITCHING_TOOLHEAD_SERVO_NR - #undef NUM_SERVOS - #define NUM_SERVOS (SWITCHING_TOOLHEAD_SERVO_NR + 1) - #endif - #if ENABLED(SWITCHING_NOZZLE) + #if ANY(HAS_Z_SERVO_PROBE, CHAMBER_VENT, SWITCHING_TOOLHEAD, SWITCHING_EXTRUDER, SWITCHING_NOZZLE, SPINDLE_SERVO) + #if NUM_SERVOS <= Z_PROBE_SERVO_NR + #undef NUM_SERVOS + #define NUM_SERVOS (Z_PROBE_SERVO_NR + 1) + #endif + #if NUM_SERVOS <= CHAMBER_VENT_SERVO_NR + #undef NUM_SERVOS + #define NUM_SERVOS (CHAMBER_VENT_SERVO_NR + 1) + #endif + #if NUM_SERVOS <= SWITCHING_TOOLHEAD_SERVO_NR + #undef NUM_SERVOS + #define NUM_SERVOS (SWITCHING_TOOLHEAD_SERVO_NR + 1) + #endif #if NUM_SERVOS <= SWITCHING_NOZZLE_SERVO_NR #undef NUM_SERVOS #define NUM_SERVOS (SWITCHING_NOZZLE_SERVO_NR + 1) @@ -64,8 +58,6 @@ #undef NUM_SERVOS #define NUM_SERVOS (SWITCHING_NOZZLE_E1_SERVO_NR + 1) #endif - #endif - #if ENABLED(SWITCHING_EXTRUDER) #if NUM_SERVOS <= SWITCHING_EXTRUDER_SERVO_NR #undef NUM_SERVOS #define NUM_SERVOS (SWITCHING_EXTRUDER_SERVO_NR + 1) @@ -74,231 +66,73 @@ #undef NUM_SERVOS #define NUM_SERVOS (SWITCHING_EXTRUDER_E23_SERVO_NR + 1) #endif + #if NUM_SERVOS <= SPINDLE_SERVO_NR + #undef NUM_SERVOS + #define NUM_SERVOS (SPINDLE_SERVO_NR + 1) + #endif #endif - #if ENABLED(SPINDLE_SERVO) && NUM_SERVOS <= SPINDLE_SERVO_NR - #undef NUM_SERVOS - #define NUM_SERVOS (SPINDLE_SERVO_NR + 1) - #endif -#endif // !defined(NUM_SERVOS) +#endif // Convenience override for a BLTouch alone -#if ENABLED(BLTOUCH) - #ifdef BLTOUCH_HS_MODE - #define HAS_BLTOUCH_HS_MODE 1 - #endif - #if NUM_SERVOS == 1 - #undef SERVO_DELAY - #define SERVO_DELAY { 50 } - #endif +#if ENABLED(BLTOUCH) && NUM_SERVOS == 1 + #undef SERVO_DELAY + #define SERVO_DELAY { 50 } #endif -#if !HAS_BED_PROBE - #undef BABYSTEP_ZPROBE_OFFSET -#endif #if !HAS_STOWABLE_PROBE #undef PROBE_DEPLOY_STOW_MENU #endif -// Some options are disallowed without required axes -#if !HAS_X_AXIS - //#define LCD_SHOW_E_TOTAL - #define NO_WORKSPACE_OFFSETS - #define NO_HOME_OFFSETS - #undef AUTOTEMP - #undef CALIBRATION_MEASURE_LEFT - #undef CALIBRATION_MEASURE_RIGHT - #undef CALIBRATION_MEASURE_XMAX - #undef CALIBRATION_MEASURE_XMIN - #undef DISABLE_IDLE_X - #undef INPUT_SHAPING_X - #undef SAFE_BED_LEVELING_START_X - #undef SHAPING_BUFFER_X - #undef SHAPING_FREQ_X - #undef STEALTHCHOP_X -#endif - -#if !HAS_Y_AXIS - #undef ARC_SUPPORT - #undef CALIBRATION_MEASURE_BACK - #undef CALIBRATION_MEASURE_FRONT - #undef CALIBRATION_MEASURE_YMAX - #undef CALIBRATION_MEASURE_YMIN - #undef DISABLE_IDLE_Y - #undef HOME_Y_BEFORE_X - #undef INPUT_SHAPING_Y - #undef QUICK_HOME - #undef SAFE_BED_LEVELING_START_Y - #undef SHAPING_BUFFER_Y - #undef SHAPING_FREQ_Y - #undef STEALTHCHOP_Y - #undef STEP_STATE_Y -#endif - -#if !HAS_Z_AXIS - #undef CALIBRATION_MEASURE_ZMAX - #undef CALIBRATION_MEASURE_ZMIN - #undef CNC_WORKSPACE_PLANES - #undef DISABLE_IDLE_Z - #undef ENABLE_LEVELING_FADE_HEIGHT - #undef HOME_Z_FIRST - #undef HOMING_Z_WITH_PROBE - #undef NUM_Z_STEPPERS - #undef SAFE_BED_LEVELING_START_Z - #undef STEALTHCHOP_Z - #undef STEP_STATE_Z - #undef Z_IDLE_HEIGHT - #undef Z_PROBE_SLED - #undef Z_SAFE_HOMING -#endif - -#if !HAS_I_AXIS - #undef CALIBRATION_MEASURE_IMAX - #undef CALIBRATION_MEASURE_IMIN - #undef DISABLE_IDLE_I - #undef SAFE_BED_LEVELING_START_I - #undef STEALTHCHOP_I - #undef STEP_STATE_I -#endif - -#if !HAS_J_AXIS - #undef CALIBRATION_MEASURE_JMAX - #undef CALIBRATION_MEASURE_JMIN - #undef DISABLE_IDLE_J - #undef SAFE_BED_LEVELING_START_J - #undef STEALTHCHOP_J - #undef STEP_STATE_J -#endif - -#if !HAS_K_AXIS - #undef CALIBRATION_MEASURE_KMAX - #undef CALIBRATION_MEASURE_KMIN - #undef DISABLE_IDLE_K - #undef SAFE_BED_LEVELING_START_K - #undef STEALTHCHOP_K - #undef STEP_STATE_K -#endif - -#if !HAS_U_AXIS - #undef CALIBRATION_MEASURE_UMAX - #undef CALIBRATION_MEASURE_UMIN - #undef DISABLE_IDLE_U - #undef SAFE_BED_LEVELING_START_U - #undef STEALTHCHOP_U - #undef STEP_STATE_U -#endif - -#if !HAS_V_AXIS - #undef CALIBRATION_MEASURE_VMAX - #undef CALIBRATION_MEASURE_VMIN - #undef DISABLE_IDLE_V - #undef SAFE_BED_LEVELING_START_V - #undef STEALTHCHOP_V - #undef STEP_STATE_V -#endif - -#if !HAS_W_AXIS - #undef CALIBRATION_MEASURE_WMAX - #undef CALIBRATION_MEASURE_WMIN - #undef DISABLE_IDLE_W - #undef SAFE_BED_LEVELING_START_W - #undef STEALTHCHOP_W - #undef STEP_STATE_W -#endif - -// Disallowed with no extruders #if !HAS_EXTRUDERS #define NO_VOLUMETRICS - #undef ADVANCED_PAUSE_FEATURE - #undef DISABLE_IDLE_E - #undef EXTRUDER_RUNOUT_PREVENT - #undef FILAMENT_LOAD_UNLOAD_GCODES + #undef TEMP_SENSOR_0 + #undef TEMP_SENSOR_1 + #undef TEMP_SENSOR_2 + #undef TEMP_SENSOR_3 + #undef TEMP_SENSOR_4 + #undef TEMP_SENSOR_5 + #undef TEMP_SENSOR_6 + #undef TEMP_SENSOR_7 #undef FWRETRACT - #undef LCD_SHOW_E_TOTAL - #undef LIN_ADVANCE - #undef MANUAL_E_MOVES_RELATIVE + #undef PIDTEMP + #undef AUTOTEMP #undef PID_EXTRUSION_SCALING + #undef LIN_ADVANCE + #undef FILAMENT_RUNOUT_SENSOR + #undef FIL_RUNOUT_ENABLED + #undef FIL_RUNOUT_MODE + #undef FIL_RUNOUT_DISTANCE_MM + #undef ADVANCED_PAUSE_FEATURE + #undef FILAMENT_LOAD_UNLOAD_GCODES + #undef DISABLE_INACTIVE_EXTRUDER + #undef EXTRUDER_RUNOUT_PREVENT + #undef PREVENT_COLD_EXTRUSION + #undef PREVENT_LENGTHY_EXTRUDE + #undef THERMAL_PROTECTION_HOTENDS + #undef THERMAL_PROTECTION_PERIOD + #undef WATCH_TEMP_PERIOD #undef SHOW_TEMP_ADC_VALUES + #undef LCD_SHOW_E_TOTAL + #undef MANUAL_E_MOVES_RELATIVE #undef STEALTHCHOP_E #endif -#if ENABLED(DISABLE_X) && !defined(DISABLE_IDLE_X) - #define DISABLE_IDLE_X -#endif -#if ENABLED(DISABLE_Y) && !defined(DISABLE_IDLE_Y) - #define DISABLE_IDLE_Y -#endif -#if ENABLED(DISABLE_Z) && !defined(DISABLE_IDLE_Z) - #define DISABLE_IDLE_Z -#endif -#if ENABLED(DISABLE_I) && !defined(DISABLE_IDLE_I) - #define DISABLE_IDLE_I -#endif -#if ENABLED(DISABLE_J) && !defined(DISABLE_IDLE_J) - #define DISABLE_IDLE_J -#endif -#if ENABLED(DISABLE_K) && !defined(DISABLE_IDLE_K) - #define DISABLE_IDLE_K -#endif -#if ENABLED(DISABLE_U) && !defined(DISABLE_IDLE_U) - #define DISABLE_IDLE_U -#endif -#if ENABLED(DISABLE_V) && !defined(DISABLE_IDLE_V) - #define DISABLE_IDLE_V -#endif -#if ENABLED(DISABLE_W) && !defined(DISABLE_IDLE_W) - #define DISABLE_IDLE_W -#endif -#if ENABLED(DISABLE_E) && !defined(DISABLE_IDLE_E) - #define DISABLE_IDLE_E -#endif - -#define _OR_HAS_DI(A) || ALL(HAS_##A##_AXIS, DISABLE_IDLE_##A) -#if ALL(HAS_EXTRUDERS, DISABLE_IDLE_E) MAP(_OR_HAS_DI, X, Y, Z, I, J, K, U, V, W) - #define HAS_DISABLE_IDLE_AXES 1 -#endif -#undef _OR_HAS_DI - -// Remove hotend-dependent settings -#if HOTENDS < 8 +#if HOTENDS <= 7 #undef E7_AUTO_FAN_PIN - #undef HEATER_7_MAXTEMP - #undef HEATER_7_MINTEMP - #if HOTENDS < 7 + #if HOTENDS <= 6 #undef E6_AUTO_FAN_PIN - #undef HEATER_6_MAXTEMP - #undef HEATER_6_MINTEMP - #if HOTENDS < 6 + #if HOTENDS <= 5 #undef E5_AUTO_FAN_PIN - #undef HEATER_5_MAXTEMP - #undef HEATER_5_MINTEMP - #if HOTENDS < 5 + #if HOTENDS <= 4 #undef E4_AUTO_FAN_PIN - #undef HEATER_4_MAXTEMP - #undef HEATER_4_MINTEMP - #if HOTENDS < 4 + #if HOTENDS <= 3 #undef E3_AUTO_FAN_PIN - #undef HEATER_3_MAXTEMP - #undef HEATER_3_MINTEMP - #if HOTENDS < 3 + #if HOTENDS <= 2 #undef E2_AUTO_FAN_PIN - #undef HEATER_2_MAXTEMP - #undef HEATER_2_MINTEMP - #if HOTENDS < 2 + #if HOTENDS <= 1 #undef E1_AUTO_FAN_PIN - #undef HEATER_1_MAXTEMP - #undef HEATER_1_MINTEMP - #if HOTENDS < 1 - #undef AUTOTEMP + #if HOTENDS == 0 #undef E0_AUTO_FAN_PIN - #undef HEATER_0_MAXTEMP - #undef HEATER_0_MINTEMP - #undef PID_PARAMS_PER_HOTEND - #undef PIDTEMP - #undef MPCTEMP - #undef PREVENT_COLD_EXTRUSION - #undef THERMAL_PROTECTION_HOTENDS - #undef THERMAL_PROTECTION_PERIOD - #undef WATCH_TEMP_PERIOD #endif #endif #endif @@ -308,62 +142,39 @@ #endif #endif -// Use Junction Deviation for motion if Jerk is disabled -#if DISABLED(CLASSIC_JERK) - #define HAS_JUNCTION_DEVIATION 1 -#endif - -// E jerk exists with JD disabled (of course) but also when Linear Advance is disabled on Delta/SCARA -#if HAS_EXTRUDERS && (ENABLED(CLASSIC_JERK) || (IS_KINEMATIC && DISABLED(LIN_ADVANCE))) - #define HAS_CLASSIC_E_JERK 1 -#endif - -// Linear advance uses Jerk since E is an isolated axis -#if ALL(HAS_JUNCTION_DEVIATION, LIN_ADVANCE) - #define HAS_LINEAR_E_JERK 1 -#endif - -// Some displays can toggle Adaptive Step Smoothing. -// The state is saved to EEPROM. -// In future this may be added to a G-code such as M205 A. -#if ALL(ADAPTIVE_STEP_SMOOTHING, DWIN_LCD_PROUI) - #define ADAPTIVE_STEP_SMOOTHING_TOGGLE -#endif - /** * Temperature Sensors; define what sensor(s) we have. */ // Temperature sensor IDs -#define H_NONE -128 -#define H_REDUNDANT -7 -#define H_SOC -6 -#define H_BOARD -5 -#define H_COOLER -4 -#define H_PROBE -3 -#define H_CHAMBER -2 -#define H_BED -1 -#define H_E0 0 -#define H_E1 1 -#define H_E2 2 -#define H_E3 3 -#define H_E4 4 -#define H_E5 5 -#define H_E6 6 -#define H_E7 7 +#define HID_REDUNDANT -6 +#define HID_BOARD -5 +#define HID_COOLER -4 +#define HID_PROBE -3 +#define HID_CHAMBER -2 +#define HID_BED -1 +#define HID_E0 0 +#define HID_E1 1 +#define HID_E2 2 +#define HID_E3 3 +#define HID_E4 4 +#define HID_E5 5 +#define HID_E6 6 +#define HID_E7 7 #define _SENSOR_IS(I,N) || (TEMP_SENSOR(N) == I) #define _E_SENSOR_IS(I,N) _SENSOR_IS(N,I) #define ANY_E_SENSOR_IS(N) (0 REPEAT2(HOTENDS, _E_SENSOR_IS, N)) -#define ANY_THERMISTOR_IS(N) ( ANY_E_SENSOR_IS(N) _SENSOR_IS(N,REDUNDANT) \ - _SENSOR_IS(N,BED) _SENSOR_IS(N,PROBE) _SENSOR_IS(N,CHAMBER) _SENSOR_IS(N,COOLER) _SENSOR_IS(N,BOARD) ) +#define ANY_THERMISTOR_IS(N) ( ANY_E_SENSOR_IS(N) \ + _SENSOR_IS(N,BED) _SENSOR_IS(N,PROBE) _SENSOR_IS(N,CHAMBER) \ + _SENSOR_IS(N,COOLER) _SENSOR_IS(N,BOARD) _SENSOR_IS(N,REDUNDANT) ) #if ANY_THERMISTOR_IS(1000) #define HAS_USER_THERMISTORS 1 #endif #if TEMP_SENSOR_REDUNDANT - #define _HEATER_ID(M) H_##M + #define _HEATER_ID(M) HID_##M #define HEATER_ID(M) _HEATER_ID(M) #define REDUNDANT_TEMP_MATCH(M,N) (HEATER_ID(TEMP_SENSOR_REDUNDANT_##M) == _HEATER_ID(N)) #else @@ -401,6 +212,9 @@ #elif TEMP_SENSOR_0 == 998 || TEMP_SENSOR_0 == 999 #define TEMP_SENSOR_0_IS_DUMMY 1 #endif +#else + #undef HEATER_0_MINTEMP + #undef HEATER_0_MAXTEMP #endif #if TEMP_SENSOR_IS_MAX_TC(1) @@ -444,126 +258,39 @@ #elif TEMP_SENSOR_1 == 998 || TEMP_SENSOR_1 == 999 #define TEMP_SENSOR_1_IS_DUMMY 1 #endif -#endif - -#if TEMP_SENSOR_IS_MAX_TC(2) - #if TEMP_SENSOR_2 == -5 - #define TEMP_SENSOR_2_IS_MAX31865 1 - #define TEMP_SENSOR_2_MAX_TC_TMIN 0 - #define TEMP_SENSOR_2_MAX_TC_TMAX 1024 - #ifndef MAX31865_SENSOR_WIRES_2 - #define MAX31865_SENSOR_WIRES_2 2 - #endif - #ifndef MAX31865_WIRE_OHMS_2 - #define MAX31865_WIRE_OHMS_2 0.0f - #endif - #elif TEMP_SENSOR_2 == -3 - #define TEMP_SENSOR_2_IS_MAX31855 1 - #define TEMP_SENSOR_2_MAX_TC_TMIN -270 - #define TEMP_SENSOR_2_MAX_TC_TMAX 1800 - #elif TEMP_SENSOR_2 == -2 - #define TEMP_SENSOR_2_IS_MAX6675 1 - #define TEMP_SENSOR_2_MAX_TC_TMIN 0 - #define TEMP_SENSOR_2_MAX_TC_TMAX 1024 - #endif - - #if TEMP_SENSOR_2 != TEMP_SENSOR_0 - #if TEMP_SENSOR_2 == -5 - #error "If MAX31865 Thermocouple (-5) is used for TEMP_SENSOR_2 then TEMP_SENSOR_0 must match." - #elif TEMP_SENSOR_2 == -3 - #error "If MAX31855 Thermocouple (-3) is used for TEMP_SENSOR_2 then TEMP_SENSOR_0 must match." - #elif TEMP_SENSOR_2 == -2 - #error "If MAX6675 Thermocouple (-2) is used for TEMP_SENSOR_2 then TEMP_SENSOR_0 must match." - #endif - #endif -#elif TEMP_SENSOR_2 == -4 - #define TEMP_SENSOR_2_IS_AD8495 1 -#elif TEMP_SENSOR_2 == -1 - #define TEMP_SENSOR_2_IS_AD595 1 -#elif TEMP_SENSOR_2 > 0 - #define TEMP_SENSOR_2_IS_THERMISTOR 1 - #if TEMP_SENSOR_2 == 1000 - #define TEMP_SENSOR_2_IS_CUSTOM 1 - #elif TEMP_SENSOR_2 == 998 || TEMP_SENSOR_2 == 999 - #define TEMP_SENSOR_2_IS_DUMMY 1 - #endif -#endif - -#if TEMP_SENSOR_3 > 0 - #define TEMP_SENSOR_3_IS_THERMISTOR 1 - #if TEMP_SENSOR_3 == 1000 - #define TEMP_SENSOR_3_IS_CUSTOM 1 - #elif TEMP_SENSOR_3 == 998 || TEMP_SENSOR_3 == 999 - #define TEMP_SENSOR_3_IS_DUMMY 1 - #endif -#endif - -#if TEMP_SENSOR_4 > 0 - #define TEMP_SENSOR_4_IS_THERMISTOR 1 - #if TEMP_SENSOR_4 == 1000 - #define TEMP_SENSOR_4_IS_CUSTOM 1 - #elif TEMP_SENSOR_4 == 998 || TEMP_SENSOR_4 == 999 - #define TEMP_SENSOR_4_IS_DUMMY 1 - #endif -#endif - -#if TEMP_SENSOR_5 > 0 - #define TEMP_SENSOR_5_IS_THERMISTOR 1 - #if TEMP_SENSOR_5 == 1000 - #define TEMP_SENSOR_5_IS_CUSTOM 1 - #elif TEMP_SENSOR_5 == 998 || TEMP_SENSOR_5 == 999 - #define TEMP_SENSOR_5_IS_DUMMY 1 - #endif -#endif - -#if TEMP_SENSOR_6 > 0 - #define TEMP_SENSOR_6_IS_THERMISTOR 1 - #if TEMP_SENSOR_6 == 1000 - #define TEMP_SENSOR_6_IS_CUSTOM 1 - #elif TEMP_SENSOR_6 == 998 || TEMP_SENSOR_6 == 999 - #define TEMP_SENSOR_6_IS_DUMMY 1 - #endif -#endif - -#if TEMP_SENSOR_7 > 0 - #define TEMP_SENSOR_7_IS_THERMISTOR 1 - #if TEMP_SENSOR_7 == 1000 - #define TEMP_SENSOR_7_IS_CUSTOM 1 - #elif TEMP_SENSOR_7 == 998 || TEMP_SENSOR_7 == 999 - #define TEMP_SENSOR_7_IS_DUMMY 1 - #endif +#else + #undef HEATER_1_MINTEMP + #undef HEATER_1_MAXTEMP #endif #if TEMP_SENSOR_IS_MAX_TC(REDUNDANT) - #define _REDUNDANT_E (REDUNDANT_TEMP_MATCH(SOURCE, E0) || REDUNDANT_TEMP_MATCH(SOURCE, E1) || REDUNDANT_TEMP_MATCH(SOURCE, E2)) #if TEMP_SENSOR_REDUNDANT == -5 - #if !_REDUNDANT_E - #error "MAX31865 Thermocouples (-5) not supported for TEMP_SENSOR_REDUNDANT_SOURCE other than TEMP_SENSOR_[0-2]." + #if !REDUNDANT_TEMP_MATCH(SOURCE, E0) && !REDUNDANT_TEMP_MATCH(SOURCE, E1) + #error "MAX31865 Thermocouples (-5) not supported for TEMP_SENSOR_REDUNDANT_SOURCE other than TEMP_SENSOR_0/TEMP_SENSOR_1 (0/1)." #endif #define TEMP_SENSOR_REDUNDANT_IS_MAX31865 1 #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN 0 #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX 1024 #elif TEMP_SENSOR_REDUNDANT == -3 - #if !_REDUNDANT_E - #error "MAX31855 Thermocouples (-3) not supported for TEMP_SENSOR_REDUNDANT_SOURCE other than TEMP_SENSOR_[0-2]." + #if !REDUNDANT_TEMP_MATCH(SOURCE, E0) && !REDUNDANT_TEMP_MATCH(SOURCE, E1) + #error "MAX31855 Thermocouples (-3) not supported for TEMP_SENSOR_REDUNDANT_SOURCE other than TEMP_SENSOR_0/TEMP_SENSOR_1 (0/1)." #endif #define TEMP_SENSOR_REDUNDANT_IS_MAX31855 1 #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN -270 #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX 1800 #elif TEMP_SENSOR_REDUNDANT == -2 - #if !_REDUNDANT_E - #error "MAX6675 Thermocouples (-2) not supported for TEMP_SENSOR_REDUNDANT_SOURCE other than TEMP_SENSOR_[0-2]." + #if !REDUNDANT_TEMP_MATCH(SOURCE, E0) && !REDUNDANT_TEMP_MATCH(SOURCE, E1) + #error "MAX6675 Thermocouples (-2) not supported for TEMP_SENSOR_REDUNDANT_SOURCE other than TEMP_SENSOR_0/TEMP_SENSOR_1 (0/1)." #endif #define TEMP_SENSOR_REDUNDANT_IS_MAX6675 1 #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN 0 #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX 1024 #endif - #undef _REDUNDANT_E - // Mimic setting up the source TEMP_SENSOR + // mimic setting up the source TEMP_SENSOR #if REDUNDANT_TEMP_MATCH(SOURCE, E0) #define TEMP_SENSOR_0_MAX_TC_TMIN TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN #define TEMP_SENSOR_0_MAX_TC_TMAX TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX @@ -576,49 +303,63 @@ #ifndef MAX31865_SENSOR_WIRES_1 #define MAX31865_SENSOR_WIRES_1 2 #endif - #elif REDUNDANT_TEMP_MATCH(SOURCE, E2) - #define TEMP_SENSOR_2_MAX_TC_TMIN TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN - #define TEMP_SENSOR_2_MAX_TC_TMAX TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX - #ifndef MAX31865_SENSOR_WIRES_2 - #define MAX31865_SENSOR_WIRES_2 2 - #endif #endif - #if (TEMP_SENSOR_IS_MAX_TC(0) && TEMP_SENSOR_REDUNDANT != TEMP_SENSOR_0) || (TEMP_SENSOR_IS_MAX_TC(1) && TEMP_SENSOR_REDUNDANT != TEMP_SENSOR_1) || (TEMP_SENSOR_IS_MAX_TC(2) && TEMP_SENSOR_REDUNDANT != TEMP_SENSOR_2) + #if (TEMP_SENSOR_IS_MAX_TC(0) && TEMP_SENSOR_REDUNDANT != TEMP_SENSOR_0) || (TEMP_SENSOR_IS_MAX_TC(1) && TEMP_SENSOR_REDUNDANT != TEMP_SENSOR_1) #if TEMP_SENSOR_REDUNDANT == -5 - #error "If MAX31865 Thermocouple (-5) is used for TEMP_SENSOR_[0-2] then TEMP_SENSOR_REDUNDANT must match." + #error "If MAX31865 Thermocouple (-5) is used for TEMP_SENSOR_0/TEMP_SENSOR_1 then TEMP_SENSOR_REDUNDANT must match." #elif TEMP_SENSOR_REDUNDANT == -3 - #error "If MAX31855 Thermocouple (-3) is used for TEMP_SENSOR_[0-2] then TEMP_SENSOR_REDUNDANT must match." + #error "If MAX31855 Thermocouple (-3) is used for TEMP_SENSOR_0/TEMP_SENSOR_1 then TEMP_SENSOR_REDUNDANT must match." #elif TEMP_SENSOR_REDUNDANT == -2 - #error "If MAX6675 Thermocouple (-2) is used for TEMP_SENSOR_[0-2] then TEMP_SENSOR_REDUNDANT must match." + #error "If MAX6675 Thermocouple (-2) is used for TEMP_SENSOR_0/TEMP_SENSOR_1 then TEMP_SENSOR_REDUNDANT must match." #endif #endif #elif TEMP_SENSOR_REDUNDANT == -4 #define TEMP_SENSOR_REDUNDANT_IS_AD8495 1 #elif TEMP_SENSOR_REDUNDANT == -1 #define TEMP_SENSOR_REDUNDANT_IS_AD595 1 -#elif TEMP_SENSOR_REDUNDANT == 998 || TEMP_SENSOR_REDUNDANT == 999 - #error "Dummy sensors are not supported for TEMP_SENSOR_REDUNDANT." #elif TEMP_SENSOR_REDUNDANT > 0 #define TEMP_SENSOR_REDUNDANT_IS_THERMISTOR 1 #if TEMP_SENSOR_REDUNDANT == 1000 #define TEMP_SENSOR_REDUNDANT_IS_CUSTOM 1 + #elif TEMP_SENSOR_REDUNDANT == 998 || TEMP_SENSOR_REDUNDANT == 999 + #error "Dummy sensors are not supported for TEMP_SENSOR_REDUNDANT." #endif #endif -#if TEMP_SENSOR_IS_MAX_TC(0) || TEMP_SENSOR_IS_MAX_TC(1) || TEMP_SENSOR_IS_MAX_TC(2) || TEMP_SENSOR_IS_MAX_TC(BED) || TEMP_SENSOR_IS_MAX_TC(REDUNDANT) +#if TEMP_SENSOR_IS_MAX_TC(0) || TEMP_SENSOR_IS_MAX_TC(1) || TEMP_SENSOR_IS_MAX_TC(REDUNDANT) #define HAS_MAX_TC 1 #endif -#if TEMP_SENSOR_0_IS_MAX6675 || TEMP_SENSOR_1_IS_MAX6675 || TEMP_SENSOR_2_IS_MAX6675 || TEMP_SENSOR_BED_IS_MAX6675 || TEMP_SENSOR_REDUNDANT_IS_MAX6675 +#if TEMP_SENSOR_0_IS_MAX6675 || TEMP_SENSOR_1_IS_MAX6675 || TEMP_SENSOR_REDUNDANT_IS_MAX6675 #define HAS_MAX6675 1 #endif -#if TEMP_SENSOR_0_IS_MAX31855 || TEMP_SENSOR_1_IS_MAX31855 || TEMP_SENSOR_2_IS_MAX31855 || TEMP_SENSOR_BED_IS_MAX31855 || TEMP_SENSOR_REDUNDANT_IS_MAX31855 +#if TEMP_SENSOR_0_IS_MAX31855 || TEMP_SENSOR_1_IS_MAX31855 || TEMP_SENSOR_REDUNDANT_IS_MAX31855 #define HAS_MAX31855 1 #endif -#if TEMP_SENSOR_0_IS_MAX31865 || TEMP_SENSOR_1_IS_MAX31865 || TEMP_SENSOR_2_IS_MAX31865 || TEMP_SENSOR_BED_IS_MAX31865 || TEMP_SENSOR_REDUNDANT_IS_MAX31865 +#if TEMP_SENSOR_0_IS_MAX31865 || TEMP_SENSOR_1_IS_MAX31865 || TEMP_SENSOR_REDUNDANT_IS_MAX31865 #define HAS_MAX31865 1 #endif +#if TEMP_SENSOR_2 == -4 + #define TEMP_SENSOR_2_IS_AD8495 1 +#elif TEMP_SENSOR_2 == -3 + #error "MAX31855 Thermocouples (-3) not supported for TEMP_SENSOR_2." +#elif TEMP_SENSOR_2 == -2 + #error "MAX6675 Thermocouples (-2) not supported for TEMP_SENSOR_2." +#elif TEMP_SENSOR_2 == -1 + #define TEMP_SENSOR_2_IS_AD595 1 +#elif TEMP_SENSOR_2 > 0 + #define TEMP_SENSOR_2_IS_THERMISTOR 1 + #if TEMP_SENSOR_2 == 1000 + #define TEMP_SENSOR_2_IS_CUSTOM 1 + #elif TEMP_SENSOR_2 == 998 || TEMP_SENSOR_2 == 999 + #define TEMP_SENSOR_2_IS_DUMMY 1 + #endif +#else + #undef HEATER_2_MINTEMP + #undef HEATER_2_MAXTEMP +#endif + #if TEMP_SENSOR_3 == -4 #define TEMP_SENSOR_3_IS_AD8495 1 #elif TEMP_SENSOR_3 == -3 @@ -627,13 +368,16 @@ #error "MAX6675 Thermocouples (-2) not supported for TEMP_SENSOR_3." #elif TEMP_SENSOR_3 == -1 #define TEMP_SENSOR_3_IS_AD595 1 -#elif TEMP_SENSOR_3 == 998 || TEMP_SENSOR_3 == 999 - #define TEMP_SENSOR_3_IS_DUMMY 1 #elif TEMP_SENSOR_3 > 0 #define TEMP_SENSOR_3_IS_THERMISTOR 1 #if TEMP_SENSOR_3 == 1000 #define TEMP_SENSOR_3_IS_CUSTOM 1 + #elif TEMP_SENSOR_3 == 998 || TEMP_SENSOR_3 == 999 + #define TEMP_SENSOR_3_IS_DUMMY 1 #endif +#else + #undef HEATER_3_MINTEMP + #undef HEATER_3_MAXTEMP #endif #if TEMP_SENSOR_4 == -4 @@ -644,13 +388,16 @@ #error "MAX6675 Thermocouples (-2) not supported for TEMP_SENSOR_4." #elif TEMP_SENSOR_4 == -1 #define TEMP_SENSOR_4_IS_AD595 1 -#elif TEMP_SENSOR_4 == 998 || TEMP_SENSOR_4 == 999 - #define TEMP_SENSOR_4_IS_DUMMY 1 #elif TEMP_SENSOR_4 > 0 #define TEMP_SENSOR_4_IS_THERMISTOR 1 #if TEMP_SENSOR_4 == 1000 #define TEMP_SENSOR_4_IS_CUSTOM 1 + #elif TEMP_SENSOR_4 == 998 || TEMP_SENSOR_4 == 999 + #define TEMP_SENSOR_4_IS_DUMMY 1 #endif +#else + #undef HEATER_4_MINTEMP + #undef HEATER_4_MAXTEMP #endif #if TEMP_SENSOR_5 == -4 @@ -661,13 +408,16 @@ #error "MAX6675 Thermocouples (-2) not supported for TEMP_SENSOR_5." #elif TEMP_SENSOR_5 == -1 #define TEMP_SENSOR_5_IS_AD595 1 -#elif TEMP_SENSOR_5 == 998 || TEMP_SENSOR_5 == 999 - #define TEMP_SENSOR_5_IS_DUMMY 1 #elif TEMP_SENSOR_5 > 0 #define TEMP_SENSOR_5_IS_THERMISTOR 1 #if TEMP_SENSOR_5 == 1000 #define TEMP_SENSOR_5_IS_CUSTOM 1 + #elif TEMP_SENSOR_5 == 998 || TEMP_SENSOR_5 == 999 + #define TEMP_SENSOR_5_IS_DUMMY 1 #endif +#else + #undef HEATER_5_MINTEMP + #undef HEATER_5_MAXTEMP #endif #if TEMP_SENSOR_6 == -4 @@ -678,13 +428,16 @@ #error "MAX6675 Thermocouples (-2) not supported for TEMP_SENSOR_6." #elif TEMP_SENSOR_6 == -1 #define TEMP_SENSOR_6_IS_AD595 1 -#elif TEMP_SENSOR_6 == 998 || TEMP_SENSOR_6 == 999 - #define TEMP_SENSOR_6_IS_DUMMY 1 #elif TEMP_SENSOR_6 > 0 #define TEMP_SENSOR_6_IS_THERMISTOR 1 #if TEMP_SENSOR_6 == 1000 #define TEMP_SENSOR_6_IS_CUSTOM 1 + #elif TEMP_SENSOR_6 == 998 || TEMP_SENSOR_6 == 999 + #define TEMP_SENSOR_6_IS_DUMMY 1 #endif +#else + #undef HEATER_6_MINTEMP + #undef HEATER_6_MAXTEMP #endif #if TEMP_SENSOR_7 == -4 @@ -695,37 +448,24 @@ #error "MAX7775 Thermocouples (-2) not supported for TEMP_SENSOR_7." #elif TEMP_SENSOR_7 == -1 #define TEMP_SENSOR_7_IS_AD595 1 -#elif TEMP_SENSOR_7 == 998 || TEMP_SENSOR_7 == 999 - #define TEMP_SENSOR_7_IS_DUMMY 1 #elif TEMP_SENSOR_7 > 0 #define TEMP_SENSOR_7_IS_THERMISTOR 1 #if TEMP_SENSOR_7 == 1000 #define TEMP_SENSOR_7_IS_CUSTOM 1 + #elif TEMP_SENSOR_7 == 998 || TEMP_SENSOR_7 == 999 + #define TEMP_SENSOR_7_IS_DUMMY 1 #endif +#else + #undef HEATER_7_MINTEMP + #undef HEATER_7_MAXTEMP #endif -#if TEMP_SENSOR_IS_MAX_TC(BED) - #if TEMP_SENSOR_BED == -5 - #define TEMP_SENSOR_BED_IS_MAX31865 1 - #define TEMP_SENSOR_BED_MAX_TC_TMIN 0 - #define TEMP_SENSOR_BED_MAX_TC_TMAX 1024 - #ifndef MAX31865_SENSOR_WIRES_BED - #define MAX31865_SENSOR_WIRES_BED 2 - #endif - #ifndef MAX31865_WIRE_OHMS_BED - #define MAX31865_WIRE_OHMS_BED 0.0f - #endif - #elif TEMP_SENSOR_BED == -3 - #define TEMP_SENSOR_BED_IS_MAX31855 1 - #define TEMP_SENSOR_BED_MAX_TC_TMIN -270 - #define TEMP_SENSOR_BED_MAX_TC_TMAX 1800 - #elif TEMP_SENSOR_BED == -2 - #define TEMP_SENSOR_BED_IS_MAX6675 1 - #define TEMP_SENSOR_BED_MAX_TC_TMIN 0 - #define TEMP_SENSOR_BED_MAX_TC_TMAX 1024 - #endif -#elif TEMP_SENSOR_BED == -4 +#if TEMP_SENSOR_BED == -4 #define TEMP_SENSOR_BED_IS_AD8495 1 +#elif TEMP_SENSOR_BED == -3 + #error "MAX31855 Thermocouples (-3) not supported for TEMP_SENSOR_BED." +#elif TEMP_SENSOR_BED == -2 + #error "MAX6675 Thermocouples (-2) not supported for TEMP_SENSOR_BED." #elif TEMP_SENSOR_BED == -1 #define TEMP_SENSOR_BED_IS_AD595 1 #elif TEMP_SENSOR_BED > 0 @@ -736,6 +476,8 @@ #define TEMP_SENSOR_BED_IS_DUMMY 1 #endif #else + #undef THERMAL_PROTECTION_BED + #undef THERMAL_PROTECTION_BED_PERIOD #undef BED_MINTEMP #undef BED_MAXTEMP #endif @@ -769,12 +511,12 @@ #error "MAX6675 Thermocouples (-2) not supported for TEMP_SENSOR_COOLER." #elif TEMP_SENSOR_COOLER == -1 #define TEMP_SENSOR_COOLER_IS_AD595 1 -#elif TEMP_SENSOR_COOLER == 998 || TEMP_SENSOR_COOLER == 999 - #define TEMP_SENSOR_COOLER_IS_DUMMY 1 #elif TEMP_SENSOR_COOLER > 0 #define TEMP_SENSOR_COOLER_IS_THERMISTOR 1 #if TEMP_SENSOR_COOLER == 1000 #define TEMP_SENSOR_COOLER_IS_CUSTOM 1 + #elif TEMP_SENSOR_COOLER == 998 || TEMP_SENSOR_COOLER == 999 + #define TEMP_SENSOR_COOLER_IS_DUMMY 1 #endif #else #undef THERMAL_PROTECTION_COOLER @@ -816,15 +558,11 @@ #endif #endif -#if HAS_MULTI_EXTRUDER || HAS_MULTI_HOTEND || HAS_PRUSA_MMU2 || (ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1) - #define HAS_TOOLCHANGE 1 -#endif - -#if ENABLED(MIXING_EXTRUDER) && (ENABLED(RETRACT_SYNC_MIXING) || ALL(FILAMENT_LOAD_UNLOAD_GCODES, FILAMENT_UNLOAD_ALL_EXTRUDERS)) +#if ENABLED(MIXING_EXTRUDER) && (ENABLED(RETRACT_SYNC_MIXING) || BOTH(FILAMENT_LOAD_UNLOAD_GCODES, FILAMENT_UNLOAD_ALL_EXTRUDERS)) #define HAS_MIXER_SYNC_CHANNEL 1 #endif -#if ANY(DUAL_X_CARRIAGE, MULTI_NOZZLE_DUPLICATION) +#if EITHER(DUAL_X_CARRIAGE, MULTI_NOZZLE_DUPLICATION) #define HAS_DUPLICATION_MODE 1 #endif @@ -862,7 +600,7 @@ #undef MENU_ADDAUTOSTART #endif -#if ANY(HAS_MEDIA, SET_PROGRESS_MANUALLY) +#if EITHER(SDSUPPORT, SET_PROGRESS_MANUALLY) #define HAS_PRINT_PROGRESS 1 #endif @@ -876,41 +614,15 @@ #define HAS_ENCODER_ACTION 1 #endif -#if ENABLED(ENCODER_RATE_MULTIPLIER) - #ifndef ENCODER_5X_STEPS_PER_SEC - #define ENCODER_5X_STEPS_PER_SEC 0 - #endif - #ifndef ENCODER_10X_STEPS_PER_SEC - #define ENCODER_10X_STEPS_PER_SEC 0 - #endif - #ifndef ENCODER_100X_STEPS_PER_SEC - #define ENCODER_100X_STEPS_PER_SEC 0 - #endif - #if !((HAS_MARLINUI_MENU || HAS_DWIN_E3V2) && (ENCODER_5X_STEPS_PER_SEC || ENCODER_10X_STEPS_PER_SEC || ENCODER_100X_STEPS_PER_SEC)) - #undef ENCODER_RATE_MULTIPLIER - #undef ENCODER_5X_STEPS_PER_SEC - #undef ENCODER_10X_STEPS_PER_SEC - #undef ENCODER_100X_STEPS_PER_SEC - #endif -#endif - #if STATUS_MESSAGE_TIMEOUT_SEC > 0 #define HAS_STATUS_MESSAGE_TIMEOUT 1 #endif -#if HAS_MEDIA && SD_PROCEDURE_DEPTH +#if ENABLED(SDSUPPORT) && SD_PROCEDURE_DEPTH #define HAS_MEDIA_SUBCALLS 1 #endif -#if ANY(SHOW_ELAPSED_TIME, SHOW_REMAINING_TIME, SHOW_INTERACTION_TIME) - #define HAS_TIME_DISPLAY 1 -#endif - -#if ANY(SHOW_PROGRESS_PERCENT, HAS_TIME_DISPLAY) && !HAS_GRAPHICAL_TFT - #define HAS_EXTRA_PROGRESS 1 -#endif - -#if HAS_PRINT_PROGRESS && ANY(PRINT_PROGRESS_SHOW_DECIMALS, SHOW_REMAINING_TIME) +#if HAS_PRINT_PROGRESS && EITHER(PRINT_PROGRESS_SHOW_DECIMALS, SHOW_REMAINING_TIME) #define HAS_PRINT_PROGRESS_PERMYRIAD 1 #endif @@ -928,7 +640,7 @@ #if ANY(X_DUAL_ENDSTOPS, Y_DUAL_ENDSTOPS, Z_MULTI_ENDSTOPS) #define HAS_EXTRA_ENDSTOPS 1 #endif -#if ANY(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS) +#if EITHER(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS) #define HAS_SOFTWARE_ENDSTOPS 1 #endif #if ANY(EXTENSIBLE_UI, IS_NEWPANEL, EMERGENCY_PARSER, HAS_ADC_BUTTONS, HAS_DWIN_E3V2) @@ -940,53 +652,20 @@ #else #undef LED_POWEROFF_TIMEOUT #endif -#if ALL(HAS_RESUME_CONTINUE, PRINTER_EVENT_LEDS, HAS_MEDIA) +#if ALL(HAS_RESUME_CONTINUE, PRINTER_EVENT_LEDS, SDSUPPORT) #define HAS_LEDS_OFF_FLAG 1 #endif -#ifdef DISPLAY_SLEEP_MINUTES +#if DISPLAY_SLEEP_MINUTES || TOUCH_IDLE_SLEEP_MINS #define HAS_DISPLAY_SLEEP 1 #endif -#ifdef LCD_BACKLIGHT_TIMEOUT_MINS - #define HAS_BACKLIGHT_TIMEOUT 1 +#if HAS_DISPLAY_SLEEP || LCD_BACKLIGHT_TIMEOUT_MINS + #define HAS_GCODE_M255 1 #endif -#if ANY(DIGIPOT_MCP4018, DIGIPOT_MCP4451) +#if EITHER(DIGIPOT_MCP4018, DIGIPOT_MCP4451) #define HAS_MOTOR_CURRENT_I2C 1 #endif -// X2 but not IDEX => Dual Synchronized X Steppers -#if defined(X2_DRIVER_TYPE) && DISABLED(DUAL_X_CARRIAGE) - #define HAS_SYNCED_X_STEPPERS 1 -#endif - -// Y2 Stepper => Dual Synchronized Y Steppers -#ifdef Y2_DRIVER_TYPE - #define HAS_SYNCED_Y_STEPPERS 1 -#endif - -// Multiple Z steppers -#ifdef INVERT_Z_DIR - #if NUM_Z_STEPPERS >= 2 && !defined(INVERT_Z2_DIR) - #define INVERT_Z2_DIR INVERT_Z_DIR - #if NUM_Z_STEPPERS >= 3 && !defined(INVERT_Z3_DIR) - #define INVERT_Z3_DIR INVERT_Z_DIR - #if NUM_Z_STEPPERS >= 4 && !defined(INVERT_Z4_DIR) - #define INVERT_Z4_DIR INVERT_Z_DIR - #endif - #endif - #endif -#endif -#if NUM_Z_STEPPERS < 4 - #undef INVERT_Z4_VS_Z_DIR - #if NUM_Z_STEPPERS < 3 - #undef INVERT_Z3_VS_Z_DIR - #if NUM_Z_STEPPERS < 2 - #undef INVERT_Z2_VS_Z_DIR - #endif - #endif -#endif - -// Z Stepper Auto-align #if ENABLED(Z_STEPPER_AUTO_ALIGN) #ifdef Z_STEPPER_ALIGN_STEPPER_XY #define HAS_Z_STEPPER_ALIGN_STEPPER_XY 1 @@ -997,11 +676,26 @@ #endif #endif +// Multiple Z steppers +#if NUM_Z_STEPPERS < 4 + #undef INVERT_Z4_VS_Z_DIR + #if NUM_Z_STEPPERS < 3 + #undef INVERT_Z3_VS_Z_DIR + #if NUM_Z_STEPPERS < 2 + #undef INVERT_Z2_VS_Z_DIR + #endif + #endif +#endif + +#if defined(X2_DRIVER_TYPE) && DISABLED(DUAL_X_CARRIAGE) + #define HAS_DUAL_X_STEPPERS 1 +#endif + // // Spindle/Laser power display types // Defined here so sanity checks can use them // -#if ANY(SPINDLE_FEATURE, LASER_FEATURE) +#if EITHER(SPINDLE_FEATURE, LASER_FEATURE) #define HAS_CUTTER 1 #define _CUTTER_POWER_PWM255 1 #define _CUTTER_POWER_PERCENT 2 @@ -1074,7 +768,7 @@ #endif #endif -#if ANY(FYSETC_MINI_12864_2_1, FYSETC_242_OLED_12864) +#if EITHER(FYSETC_MINI_12864_2_1, FYSETC_242_OLED_12864) #ifndef LED_USER_PRESET_GREEN #define LED_USER_PRESET_GREEN 128 #endif @@ -1109,7 +803,7 @@ #endif #endif -#if ALL(LED_CONTROL_MENU, NEOPIXEL2_SEPARATE) +#if BOTH(LED_CONTROL_MENU, NEOPIXEL2_SEPARATE) #ifndef LED2_USER_PRESET_RED #define LED2_USER_PRESET_RED 255 #endif @@ -1132,7 +826,7 @@ #endif // Full Touch Screen needs 'tft/xpt2046' -#if ANY(TFT_TOUCH_DEVICE_XPT2046, HAS_TFT_LVGL_UI) +#if EITHER(TFT_TOUCH_DEVICE_XPT2046, HAS_TFT_LVGL_UI) #define HAS_TFT_XPT2046 1 #endif @@ -1152,6 +846,12 @@ #define POLL_JOG #endif +#if X2_HOME_DIR > 0 + #define X2_HOME_TO_MAX 1 +#elif X2_HOME_DIR < 0 + #define X2_HOME_TO_MIN 1 +#endif + #ifndef HOMING_BUMP_MM #define HOMING_BUMP_MM { 0, 0, 0 } #endif @@ -1179,7 +879,7 @@ #elif HAS_DRIVER(A4988) #define MINIMUM_STEPPER_POST_DIR_DELAY 200 #elif HAS_TRINAMIC_CONFIG || HAS_TRINAMIC_STANDALONE - #define MINIMUM_STEPPER_POST_DIR_DELAY 70 + #define MINIMUM_STEPPER_POST_DIR_DELAY 60 #else #define MINIMUM_STEPPER_POST_DIR_DELAY 0 // Expect at least 10µS since one Stepper ISR must transpire #endif @@ -1225,9 +925,6 @@ #endif #endif -// Test for edge stepping on any axis -#define AXIS_HAS_DEDGE(A) (ENABLED(EDGE_STEPPING) && AXIS_IS_TMC(A)) - #if ENABLED(DIRECT_STEPPING) #ifndef STEPPER_PAGES #define STEPPER_PAGES 16 @@ -1240,17 +937,57 @@ #endif #endif -#if defined(SAFE_BED_LEVELING_START_X) || defined(SAFE_BED_LEVELING_START_Y) || defined(SAFE_BED_LEVELING_START_Z) \ - || defined(SAFE_BED_LEVELING_START_I) || defined(SAFE_BED_LEVELING_START_J) || defined(SAFE_BED_LEVELING_START_K) \ - || defined(SAFE_BED_LEVELING_START_U) || defined(SAFE_BED_LEVELING_START_V) || defined(SAFE_BED_LEVELING_START_W) - #define HAS_SAFE_BED_LEVELING 1 +// Remove unused STEALTHCHOP flags +#if NUM_AXES < 9 + #undef STEALTHCHOP_W + #undef CALIBRATION_MEASURE_WMIN + #undef CALIBRATION_MEASURE_WMAX + #if NUM_AXES < 8 + #undef STEALTHCHOP_V + #undef CALIBRATION_MEASURE_VMIN + #undef CALIBRATION_MEASURE_VMAX + #if NUM_AXES < 7 + #undef STEALTHCHOP_U + #undef CALIBRATION_MEASURE_UMIN + #undef CALIBRATION_MEASURE_UMAX + #if NUM_AXES < 6 + #undef STEALTHCHOP_K + #undef CALIBRATION_MEASURE_KMIN + #undef CALIBRATION_MEASURE_KMAX + #if NUM_AXES < 5 + #undef STEALTHCHOP_J + #undef CALIBRATION_MEASURE_JMIN + #undef CALIBRATION_MEASURE_JMAX + #if NUM_AXES < 4 + #undef STEALTHCHOP_I + #undef CALIBRATION_MEASURE_IMIN + #undef CALIBRATION_MEASURE_IMAX + #if NUM_AXES < 3 + #undef Z_IDLE_HEIGHT + #undef STEALTHCHOP_Z + #undef Z_PROBE_SLED + #undef Z_SAFE_HOMING + #undef HOME_Z_FIRST + #undef HOMING_Z_WITH_PROBE + #undef ENABLE_LEVELING_FADE_HEIGHT + #undef NUM_Z_STEPPERS + #undef CNC_WORKSPACE_PLANES + #if NUM_AXES < 2 + #undef STEALTHCHOP_Y + #endif + #endif + #endif + #endif + #endif + #endif + #endif #endif // // SD Card connection methods // Defined here so pins and sanity checks can use them // -#if HAS_MEDIA +#if ENABLED(SDSUPPORT) #define _SDCARD_LCD 1 #define _SDCARD_ONBOARD 2 #define _SDCARD_CUSTOM_CABLE 3 @@ -1258,11 +995,10 @@ #define SD_CONNECTION_IS(V) (_SDCARD_ID(SDCARD_CONNECTION) == _SDCARD_ID(V)) #else #define SD_CONNECTION_IS(...) 0 - #undef SD_ABORT_ON_ENDSTOP_HIT #endif // Power Monitor sensors -#if ANY(POWER_MONITOR_CURRENT, POWER_MONITOR_VOLTAGE) +#if EITHER(POWER_MONITOR_CURRENT, POWER_MONITOR_VOLTAGE) #define HAS_POWER_MONITOR 1 #if ENABLED(POWER_MONITOR_CURRENT) && (ENABLED(POWER_MONITOR_VOLTAGE) || defined(POWER_MONITOR_FIXED_VOLTAGE)) #define HAS_POWER_MONITOR_WATTS 1 @@ -1274,9 +1010,14 @@ #define NO_EEPROM_SELECTED 1 #endif +// Flag whether hex_print.cpp is used +#if ANY(AUTO_BED_LEVELING_UBL, M100_FREE_MEMORY_WATCHER, DEBUG_GCODE_PARSER, TMC_DEBUG, MARLIN_DEV_MODE, DEBUG_CARDREADER, M20_TIMESTAMP_SUPPORT) + #define NEED_HEX_PRINT 1 +#endif + // Flags for Case Light having a color property or a single pin #if ENABLED(CASE_LIGHT_ENABLE) - #if ANY(CASE_LIGHT_USE_NEOPIXEL, CASE_LIGHT_USE_RGB_LED) + #if EITHER(CASE_LIGHT_USE_NEOPIXEL, CASE_LIGHT_USE_RGB_LED) #define CASE_LIGHT_IS_COLOR_LED 1 #else #define NEED_CASE_LIGHT_PIN 1 @@ -1293,24 +1034,25 @@ #define NEED_LSF 1 #endif -#if ALL(HAS_TFT_LVGL_UI, CUSTOM_MENU_MAIN) +#if BOTH(HAS_TFT_LVGL_UI, CUSTOM_MENU_MAIN) #define _HAS_1(N) (defined(MAIN_MENU_ITEM_##N##_DESC) && defined(MAIN_MENU_ITEM_##N##_GCODE)) #define HAS_USER_ITEM(V...) DO(HAS,||,V) #else - #define HAS_USER_ITEM(...) 0 + #define HAS_USER_ITEM(N) 0 #endif /** - * LCD_SERIAL_PORT must be defined ahead of HAL.h and - * currently HAL.h must be included ahead of pins.h. + * LCD_SERIAL_PORT must be defined ahead of HAL.h */ -#if LCD_IS_SERIAL_HOST && !defined(LCD_SERIAL_PORT) - #if MB(MKS_MONSTER8_V1, BTT_SKR_MINI_E3_V1_0, BTT_SKR_MINI_E3_V1_2, BTT_SKR_MINI_E3_V2_0, BTT_SKR_MINI_E3_V3_0, BTT_SKR_MINI_E3_V3_0_1, BTT_SKR_E3_TURBO, BTT_OCTOPUS_V1_1, AQUILA_V101) - #define LCD_SERIAL_PORT 1 - #elif MB(CREALITY_V24S1_301, CREALITY_V24S1_301F4, CREALITY_F401RE, CREALITY_V423, CREALITY_CR4NTXXC10, MKS_ROBIN, PANOWIN_CUTLASS, KODAMA_BARDO) - #define LCD_SERIAL_PORT 2 - #else - #define LCD_SERIAL_PORT 3 +#ifndef LCD_SERIAL_PORT + #if HAS_DWIN_E3V2 || IS_DWIN_MARLINUI || HAS_DGUS_LCD + #if MB(BTT_SKR_MINI_E3_V1_0, BTT_SKR_MINI_E3_V1_2, BTT_SKR_MINI_E3_V2_0, BTT_SKR_MINI_E3_V3_0, BTT_SKR_E3_TURBO) + #define LCD_SERIAL_PORT 1 + #elif MB(CREALITY_V24S1_301, CREALITY_V24S1_301F4, CREALITY_V423, MKS_ROBIN) + #define LCD_SERIAL_PORT 2 // Creality Ender3S1, MKS Robin + #else + #define LCD_SERIAL_PORT 3 // Other boards + #endif #endif #ifdef LCD_SERIAL_PORT #define AUTO_ASSIGNED_LCD_SERIAL 1 @@ -1320,79 +1062,16 @@ #if !HAS_MULTI_SERIAL #undef MEATPACK_ON_SERIAL_PORT_2 #endif -#if ANY(MEATPACK_ON_SERIAL_PORT_1, MEATPACK_ON_SERIAL_PORT_2) +#if EITHER(MEATPACK_ON_SERIAL_PORT_1, MEATPACK_ON_SERIAL_PORT_2) #define HAS_MEATPACK 1 #endif // AVR are (usually) too limited in resources to store the configuration into the binary -#if ENABLED(CONFIGURATION_EMBEDDING) && !defined(FORCE_CONFIG_EMBED) && (defined(__AVR__) || !HAS_MEDIA || ANY(SDCARD_READONLY, DISABLE_M503)) +#if ENABLED(CONFIGURATION_EMBEDDING) && !defined(FORCE_CONFIG_EMBED) && (defined(__AVR__) || DISABLED(SDSUPPORT) || EITHER(SDCARD_READONLY, DISABLE_M503)) #undef CONFIGURATION_EMBEDDING #define CANNOT_EMBED_CONFIGURATION defined(__AVR__) #endif -// Input shaping -#if ANY(INPUT_SHAPING_X, INPUT_SHAPING_Y) - #define HAS_ZV_SHAPING 1 -#endif - -// FT Motion unified window and batch size -#if ALL(FT_MOTION, FTM_UNIFIED_BWS) - #define FTM_WINDOW_SIZE FTM_BW_SIZE - #define FTM_BATCH_SIZE FTM_BW_SIZE -#endif - -// Toolchange Event G-code -#if !HAS_MULTI_EXTRUDER || !(defined(EVENT_GCODE_TOOLCHANGE_T0) || defined(EVENT_GCODE_TOOLCHANGE_T1) || defined(EVENT_GCODE_TOOLCHANGE_T2) || defined(EVENT_GCODE_TOOLCHANGE_T3) || defined(EVENT_GCODE_TOOLCHANGE_T4) || defined(EVENT_GCODE_TOOLCHANGE_T5) || defined(EVENT_GCODE_TOOLCHANGE_T6) || defined(EVENT_GCODE_TOOLCHANGE_T7)) - #undef TC_GCODE_USE_GLOBAL_X - #undef TC_GCODE_USE_GLOBAL_Y - #undef TC_GCODE_USE_GLOBAL_Z -#endif - -// TOOLCHANGE_MIGRATION_FEATURE - Clean up after sloppy auto config -#if DISABLED(TOOLCHANGE_MIGRATION_FEATURE) - #undef MIGRATION_ZRAISE - #undef MIGRATION_FS_EXTRA_PRIME - #undef MIGRATION_FS_WIPE_RETRACT - #undef MIGRATION_FS_FAN_SPEED - #undef MIGRATION_FS_FAN_TIME - #undef TOOLCHANGE_MIGRATION_DO_PARK -#endif -// TOOLCHANGE_PARK - Clean up after sloppy auto config -#if DISABLED(TOOLCHANGE_PARK) - #undef TOOLCHANGE_PARK_XY - #undef TOOLCHANGE_PARK_XY_FEEDRATE - #undef TOOLCHANGE_PARK_X_ONLY - #undef TOOLCHANGE_PARK_Y_ONLY - #undef TOOLCHANGE_MIGRATION_DO_PARK -#endif - -// Multi-Stepping Limit -#ifndef MULTISTEPPING_LIMIT - #define MULTISTEPPING_LIMIT 128 - #define MULTISTEPPING_LIMIT_WARNING 1 -#endif - -// One redundant cooling fan by default -#if defined(REDUNDANT_PART_COOLING_FAN) && !defined(NUM_REDUNDANT_FANS) - #define NUM_REDUNDANT_FANS 1 -#endif - -// Clean up if only mm units are used -#if DISABLED(INCH_MODE_SUPPORT) - #undef MANUAL_MOVE_DISTANCE_IN -#endif - -// Clean up if no rotational axes exist -#if !HAS_ROTATIONAL_AXES - #undef MANUAL_MOVE_DISTANCE_DEG -#endif - -// Power-Loss Recovery -#if ENABLED(POWER_LOSS_RECOVERY) - #ifdef PLR_BED_THRESHOLD - #define HAS_PLR_BED_THRESHOLD 1 - #endif - #if ANY(DWIN_CREALITY_LCD, DWIN_LCD_PROUI) - #define HAS_PLR_UI_FLAG 1 // recovery.ui_flag_resume - #endif +#if ANY(DISABLE_INACTIVE_X, DISABLE_INACTIVE_Y, DISABLE_INACTIVE_Z, DISABLE_INACTIVE_I, DISABLE_INACTIVE_J, DISABLE_INACTIVE_K, DISABLE_INACTIVE_U, DISABLE_INACTIVE_V, DISABLE_INACTIVE_W, DISABLE_INACTIVE_E) + #define HAS_DISABLE_INACTIVE_AXIS 1 #endif diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index eea7d15d9b..568da11e41 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -46,8 +46,8 @@ #if ENABLED(TEST0) || !ENABLED(TEST2) || ENABLED(TEST3) || !ENABLED(TEST1, TEST2, TEST4) #error "ENABLED is borked!" #endif -#if ALL(TEST0, TEST1) - #error "ALL is borked!" +#if BOTH(TEST0, TEST1) + #error "BOTH is borked!" #endif #if DISABLED(TEST1) || !DISABLED(TEST3) || DISABLED(TEST4) || DISABLED(TEST0, TEST1, TEST2, TEST4) || !DISABLED(TEST0, TEST3) #error "DISABLED is borked!" @@ -88,69 +88,611 @@ * Warnings for old configurations */ #ifndef MOTHERBOARD - #error "MOTHERBOARD is required. You must '#define MOTHERBOARD BOARD_MYNAME' (not just '#define BOARD_MYNAME')." + #error "MOTHERBOARD is required." +#elif !defined(X_BED_SIZE) || !defined(Y_BED_SIZE) + #error "X_BED_SIZE and Y_BED_SIZE are now required!" +#elif WATCH_TEMP_PERIOD > 500 + #error "WATCH_TEMP_PERIOD now uses seconds instead of milliseconds." +#elif DISABLED(THERMAL_PROTECTION_HOTENDS) && (defined(WATCH_TEMP_PERIOD) || defined(THERMAL_PROTECTION_PERIOD)) + #error "Thermal Runaway Protection for hotends is now enabled with THERMAL_PROTECTION_HOTENDS." +#elif DISABLED(THERMAL_PROTECTION_BED) && defined(THERMAL_PROTECTION_BED_PERIOD) + #error "Thermal Runaway Protection for the bed is now enabled with THERMAL_PROTECTION_BED." +#elif (CORE_IS_XZ || CORE_IS_YZ) && ENABLED(Z_LATE_ENABLE) + #error "Z_LATE_ENABLE can't be used with COREXZ, COREZX, COREYZ, or COREZY." +#elif defined(X_HOME_RETRACT_MM) + #error "[XYZ]_HOME_RETRACT_MM settings have been renamed [XYZ]_HOME_BUMP_MM." +#elif defined(SDCARDDETECTINVERTED) + #error "SDCARDDETECTINVERTED is now SD_DETECT_STATE (HIGH)." +#elif defined(SD_DETECT_INVERTED) + #error "SD_DETECT_INVERTED is now SD_DETECT_STATE (HIGH)." +#elif defined(BTENABLED) + #error "BTENABLED is now BLUETOOTH." +#elif defined(CUSTOM_MENDEL_NAME) + #error "CUSTOM_MENDEL_NAME is now CUSTOM_MACHINE_NAME." +#elif defined(HAS_AUTOMATIC_VERSIONING) + #error "HAS_AUTOMATIC_VERSIONING is now CUSTOM_VERSION_FILE." +#elif defined(USE_AUTOMATIC_VERSIONING) + #error "USE_AUTOMATIC_VERSIONING is now CUSTOM_VERSION_FILE." +#elif defined(SDSLOW) + #error "SDSLOW deprecated. Set SD_SPI_SPEED to SPI_HALF_SPEED instead." +#elif defined(SDEXTRASLOW) + #error "SDEXTRASLOW deprecated. Set SD_SPI_SPEED to SPI_QUARTER_SPEED instead." +#elif defined(FILAMENT_SENSOR) + #error "FILAMENT_SENSOR is now FILAMENT_WIDTH_SENSOR." +#elif defined(ENDSTOPPULLUP_FIL_RUNOUT) + #error "ENDSTOPPULLUP_FIL_RUNOUT is now FIL_RUNOUT_PULLUP." +#elif defined(DISABLE_MAX_ENDSTOPS) || defined(DISABLE_MIN_ENDSTOPS) + #error "DISABLE_MAX_ENDSTOPS and DISABLE_MIN_ENDSTOPS deprecated. Use individual USE_*_PLUG options instead." +#elif defined(LANGUAGE_INCLUDE) + #error "LANGUAGE_INCLUDE has been replaced by LCD_LANGUAGE." +#elif defined(EXTRUDER_OFFSET_X) || defined(EXTRUDER_OFFSET_Y) + #error "EXTRUDER_OFFSET_[XY] is deprecated. Use HOTEND_OFFSET_[XY] instead." +#elif defined(PID_PARAMS_PER_EXTRUDER) + #error "PID_PARAMS_PER_EXTRUDER is deprecated. Use PID_PARAMS_PER_HOTEND instead." +#elif defined(EXTRUDER_WATTS) || defined(BED_WATTS) + #error "EXTRUDER_WATTS and BED_WATTS are deprecated and should be removed." +#elif defined(SERVO_ENDSTOP_ANGLES) + #error "SERVO_ENDSTOP_ANGLES is deprecated. Use Z_SERVO_ANGLES instead." +#elif defined(X_ENDSTOP_SERVO_NR) || defined(Y_ENDSTOP_SERVO_NR) + #error "X_ENDSTOP_SERVO_NR and Y_ENDSTOP_SERVO_NR are deprecated and should be removed." +#elif defined(Z_ENDSTOP_SERVO_NR) + #error "Z_ENDSTOP_SERVO_NR is now Z_PROBE_SERVO_NR." +#elif defined(DEFAULT_XYJERK) + #error "DEFAULT_XYJERK is deprecated. Use DEFAULT_XJERK and DEFAULT_YJERK instead." +#elif defined(XY_TRAVEL_SPEED) + #error "XY_TRAVEL_SPEED is now XY_PROBE_FEEDRATE." +#elif defined(XY_PROBE_SPEED) + #error "XY_PROBE_SPEED is now XY_PROBE_FEEDRATE." +#elif defined(Z_PROBE_SPEED_FAST) + #error "Z_PROBE_SPEED_FAST is now Z_PROBE_FEEDRATE_FAST." +#elif defined(Z_PROBE_SPEED_SLOW) + #error "Z_PROBE_SPEED_SLOW is now Z_PROBE_FEEDRATE_SLOW." +#elif defined(PROBE_SERVO_DEACTIVATION_DELAY) + #error "PROBE_SERVO_DEACTIVATION_DELAY is deprecated. Use DEACTIVATE_SERVOS_AFTER_MOVE instead." +#elif defined(SERVO_DEACTIVATION_DELAY) + #error "SERVO_DEACTIVATION_DELAY is now SERVO_DELAY." +#elif ENABLED(FILAMENTCHANGEENABLE) + #error "FILAMENTCHANGEENABLE is now ADVANCED_PAUSE_FEATURE." +#elif ENABLED(FILAMENT_CHANGE_FEATURE) + #error "FILAMENT_CHANGE_FEATURE is now ADVANCED_PAUSE_FEATURE." +#elif defined(FILAMENT_CHANGE_X_POS) || defined(FILAMENT_CHANGE_Y_POS) + #error "FILAMENT_CHANGE_[XY]_POS is now set with NOZZLE_PARK_POINT." +#elif defined(FILAMENT_CHANGE_Z_ADD) + #error "FILAMENT_CHANGE_Z_ADD is now set with NOZZLE_PARK_POINT." +#elif defined(FILAMENT_CHANGE_XY_FEEDRATE) + #error "FILAMENT_CHANGE_XY_FEEDRATE is now NOZZLE_PARK_XY_FEEDRATE." +#elif defined(FILAMENT_CHANGE_Z_FEEDRATE) + #error "FILAMENT_CHANGE_Z_FEEDRATE is now NOZZLE_PARK_Z_FEEDRATE." +#elif defined(PAUSE_PARK_X_POS) || defined(PAUSE_PARK_Y_POS) + #error "PAUSE_PARK_[XY]_POS is now set with NOZZLE_PARK_POINT." +#elif defined(PAUSE_PARK_Z_ADD) + #error "PAUSE_PARK_Z_ADD is now set with NOZZLE_PARK_POINT." +#elif defined(PAUSE_PARK_XY_FEEDRATE) + #error "PAUSE_PARK_XY_FEEDRATE is now NOZZLE_PARK_XY_FEEDRATE." +#elif defined(PAUSE_PARK_Z_FEEDRATE) + #error "PAUSE_PARK_Z_FEEDRATE is now NOZZLE_PARK_Z_FEEDRATE." +#elif defined(FILAMENT_CHANGE_RETRACT_FEEDRATE) + #error "FILAMENT_CHANGE_RETRACT_FEEDRATE is now PAUSE_PARK_RETRACT_FEEDRATE." +#elif defined(FILAMENT_CHANGE_RETRACT_LENGTH) + #error "FILAMENT_CHANGE_RETRACT_LENGTH is now PAUSE_PARK_RETRACT_LENGTH." +#elif defined(FILAMENT_CHANGE_EXTRUDE_FEEDRATE) + #error "FILAMENT_CHANGE_EXTRUDE_FEEDRATE is now ADVANCED_PAUSE_PURGE_FEEDRATE." +#elif defined(ADVANCED_PAUSE_EXTRUDE_FEEDRATE) + #error "ADVANCED_PAUSE_EXTRUDE_FEEDRATE is now ADVANCED_PAUSE_PURGE_FEEDRATE." +#elif defined(FILAMENT_CHANGE_EXTRUDE_LENGTH) + #error "FILAMENT_CHANGE_EXTRUDE_LENGTH is now ADVANCED_PAUSE_PURGE_LENGTH." +#elif defined(ADVANCED_PAUSE_EXTRUDE_LENGTH) + #error "ADVANCED_PAUSE_EXTRUDE_LENGTH is now ADVANCED_PAUSE_PURGE_LENGTH." +#elif defined(FILAMENT_CHANGE_NOZZLE_TIMEOUT) + #error "FILAMENT_CHANGE_NOZZLE_TIMEOUT is now PAUSE_PARK_NOZZLE_TIMEOUT." +#elif defined(FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS) + #error "FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS is now FILAMENT_CHANGE_ALERT_BEEPS." +#elif defined(FILAMENT_CHANGE_NO_STEPPER_TIMEOUT) + #error "FILAMENT_CHANGE_NO_STEPPER_TIMEOUT is now PAUSE_PARK_NO_STEPPER_TIMEOUT." +#elif defined(PLA_PREHEAT_HOTEND_TEMP) + #error "PLA_PREHEAT_HOTEND_TEMP is now PREHEAT_1_TEMP_HOTEND." +#elif defined(PLA_PREHEAT_HPB_TEMP) + #error "PLA_PREHEAT_HPB_TEMP is now PREHEAT_1_TEMP_BED." +#elif defined(PLA_PREHEAT_FAN_SPEED) + #error "PLA_PREHEAT_FAN_SPEED is now PREHEAT_1_FAN_SPEED." +#elif defined(ABS_PREHEAT_HOTEND_TEMP) + #error "ABS_PREHEAT_HOTEND_TEMP is now PREHEAT_2_TEMP_HOTEND." +#elif defined(ABS_PREHEAT_HPB_TEMP) + #error "ABS_PREHEAT_HPB_TEMP is now PREHEAT_2_TEMP_BED." +#elif defined(ABS_PREHEAT_FAN_SPEED) + #error "ABS_PREHEAT_FAN_SPEED is now PREHEAT_2_FAN_SPEED." +#elif defined(ENDSTOPS_ONLY_FOR_HOMING) + #error "ENDSTOPS_ONLY_FOR_HOMING is deprecated. Use (disable) ENDSTOPS_ALWAYS_ON_DEFAULT instead." +#elif defined(HOMING_FEEDRATE) + #error "HOMING_FEEDRATE is now set using the HOMING_FEEDRATE_MM_M array instead." +#elif (defined(HOMING_FEEDRATE_XY) || defined(HOMING_FEEDRATE_Z)) && !defined(HOMING_FEEDRATE_MM_M) + #error "HOMING_FEEDRATE_XY and HOMING_FEEDRATE_Z are now set using the HOMING_FEEDRATE_MM_M array instead." +#elif defined(MANUAL_HOME_POSITIONS) + #error "MANUAL_HOME_POSITIONS is deprecated. Set MANUAL_[XYZ]_HOME_POS as-needed instead." +#elif defined(PID_ADD_EXTRUSION_RATE) + #error "PID_ADD_EXTRUSION_RATE is now PID_EXTRUSION_SCALING and is DISABLED by default." +#elif defined(Z_RAISE_BEFORE_HOMING) + #error "Z_RAISE_BEFORE_HOMING is now Z_HOMING_HEIGHT." +#elif defined(MIN_Z_HEIGHT_FOR_HOMING) + #error "MIN_Z_HEIGHT_FOR_HOMING is now Z_HOMING_HEIGHT." +#elif defined(Z_RAISE_BEFORE_PROBING) || defined(Z_RAISE_AFTER_PROBING) + #error "Z_RAISE_(BEFORE|AFTER)_PROBING are deprecated. Use Z_CLEARANCE_DEPLOY_PROBE and Z_AFTER_PROBING instead." +#elif defined(Z_RAISE_PROBE_DEPLOY_STOW) || defined(Z_RAISE_BETWEEN_PROBINGS) + #error "Z_RAISE_PROBE_DEPLOY_STOW and Z_RAISE_BETWEEN_PROBINGS are now Z_CLEARANCE_DEPLOY_PROBE and Z_CLEARANCE_BETWEEN_PROBES." +#elif defined(Z_PROBE_DEPLOY_HEIGHT) || defined(Z_PROBE_TRAVEL_HEIGHT) + #error "Z_PROBE_DEPLOY_HEIGHT and Z_PROBE_TRAVEL_HEIGHT are now Z_CLEARANCE_DEPLOY_PROBE and Z_CLEARANCE_BETWEEN_PROBES." +#elif defined(MANUAL_BED_LEVELING) + #error "MANUAL_BED_LEVELING is now LCD_BED_LEVELING." +#elif defined(MESH_HOME_SEARCH_Z) + #error "MESH_HOME_SEARCH_Z is now LCD_PROBE_Z_RANGE." +#elif defined(MANUAL_PROBE_Z_RANGE) + #error "MANUAL_PROBE_Z_RANGE is now LCD_PROBE_Z_RANGE." +#elif !defined(MIN_STEPS_PER_SEGMENT) + #error "Please replace 'const int dropsegments' with '#define MIN_STEPS_PER_SEGMENT' (and increase by 1)." +#elif MIN_STEPS_PER_SEGMENT <= 0 + #error "MIN_STEPS_PER_SEGMENT must be at least 1." +#elif defined(PREVENT_DANGEROUS_EXTRUDE) + #error "PREVENT_DANGEROUS_EXTRUDE is now PREVENT_COLD_EXTRUSION." +#elif defined(SCARA) + #error "SCARA is now MORGAN_SCARA." +#elif defined(ENABLE_AUTO_BED_LEVELING) + #error "ENABLE_AUTO_BED_LEVELING is deprecated. Specify AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR, or AUTO_BED_LEVELING_3POINT." +#elif defined(AUTO_BED_LEVELING_FEATURE) + #error "AUTO_BED_LEVELING_FEATURE is deprecated. Specify AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR, or AUTO_BED_LEVELING_3POINT." +#elif defined(ABL_GRID_POINTS) + #error "ABL_GRID_POINTS is now GRID_MAX_POINTS_X and GRID_MAX_POINTS_Y." +#elif defined(ABL_GRID_POINTS_X) || defined(ABL_GRID_POINTS_Y) + #error "ABL_GRID_POINTS_[XY] is now GRID_MAX_POINTS_[XY]." +#elif defined(ABL_GRID_MAX_POINTS_X) || defined(ABL_GRID_MAX_POINTS_Y) + #error "ABL_GRID_MAX_POINTS_[XY] is now GRID_MAX_POINTS_[XY]." +#elif defined(MESH_NUM_X_POINTS) || defined(MESH_NUM_Y_POINTS) + #error "MESH_NUM_[XY]_POINTS is now GRID_MAX_POINTS_[XY]." +#elif defined(UBL_MESH_NUM_X_POINTS) || defined(UBL_MESH_NUM_Y_POINTS) + #error "UBL_MESH_NUM_[XY]_POINTS is now GRID_MAX_POINTS_[XY]." +#elif defined(UBL_G26_MESH_VALIDATION) + #error "UBL_G26_MESH_VALIDATION is now G26_MESH_VALIDATION." +#elif defined(UBL_MESH_EDIT_ENABLED) + #error "UBL_MESH_EDIT_ENABLED is now G26_MESH_VALIDATION." +#elif defined(UBL_MESH_EDITING) + #error "UBL_MESH_EDITING is now G26_MESH_VALIDATION." +#elif defined(BLTOUCH_HEATERS_OFF) + #error "BLTOUCH_HEATERS_OFF is now PROBING_HEATERS_OFF." +#elif defined(BLTOUCH_V3) + #error "BLTOUCH_V3 is obsolete." +#elif defined(BLTOUCH_FORCE_OPEN_DRAIN_MODE) + #error "BLTOUCH_FORCE_OPEN_DRAIN_MODE is obsolete." +#elif defined(BEEPER) + #error "BEEPER is now BEEPER_PIN." +#elif defined(SDCARDDETECT) + #error "SDCARDDETECT is now SD_DETECT_PIN." +#elif defined(STAT_LED_RED) || defined(STAT_LED_BLUE) + #error "STAT_LED_RED/STAT_LED_BLUE are now STAT_LED_RED_PIN/STAT_LED_BLUE_PIN." +#elif defined(LCD_PIN_BL) + #error "LCD_PIN_BL is now LCD_BACKLIGHT_PIN." +#elif defined(LCD_PIN_RESET) + #error "LCD_PIN_RESET is now LCD_RESET_PIN." +#elif defined(EXTRUDER_0_AUTO_FAN_PIN) || defined(EXTRUDER_1_AUTO_FAN_PIN) || defined(EXTRUDER_2_AUTO_FAN_PIN) || defined(EXTRUDER_3_AUTO_FAN_PIN) + #error "EXTRUDER_[0123]_AUTO_FAN_PIN is now E[0123]_AUTO_FAN_PIN." +#elif defined(PID_FAN_SCALING) && !HAS_FAN + #error "PID_FAN_SCALING needs at least one fan enabled." +#elif defined(min_software_endstops) || defined(max_software_endstops) + #error "(min|max)_software_endstops are now (MIN|MAX)_SOFTWARE_ENDSTOPS." +#elif ENABLED(Z_PROBE_SLED) && defined(SLED_PIN) + #error "Replace SLED_PIN with SOL1_PIN (applies to both Z_PROBE_SLED and SOLENOID_PROBE)." +#elif defined(CONTROLLERFAN_PIN) + #error "CONTROLLERFAN_PIN is now CONTROLLER_FAN_PIN, enabled with USE_CONTROLLER_FAN." +#elif defined(CONTROLLERFAN_SPEED) + #error "CONTROLLERFAN_SPEED is now CONTROLLERFAN_SPEED_ACTIVE." +#elif defined(CONTROLLERFAN_SECS) + #error "CONTROLLERFAN_SECS is now CONTROLLERFAN_IDLE_TIME." +#elif defined(MIN_RETRACT) + #error "MIN_RETRACT is now MIN_AUTORETRACT and MAX_AUTORETRACT." +#elif defined(ADVANCE) + #error "ADVANCE is now LIN_ADVANCE." +#elif defined(LIN_ADVANCE_E_D_RATIO) + #error "LIN_ADVANCE (1.5) no longer uses LIN_ADVANCE_E_D_RATIO." +#elif defined(NEOPIXEL_RGBW_LED) + #error "NEOPIXEL_RGBW_LED is now NEOPIXEL_LED." +#elif ENABLED(DELTA) && defined(DELTA_PROBEABLE_RADIUS) + #error "Remove DELTA_PROBEABLE_RADIUS and use PROBING_MARGIN to inset the probe area instead." +#elif ENABLED(DELTA) && defined(DELTA_CALIBRATION_RADIUS) + #error "Remove DELTA_CALIBRATION_RADIUS and use PROBING_MARGIN to inset the probe area instead." +#elif defined(UBL_MESH_INSET) + #error "UBL_MESH_INSET is now just MESH_INSET." +#elif defined(UBL_MESH_MIN_X) || defined(UBL_MESH_MIN_Y) || defined(UBL_MESH_MAX_X) || defined(UBL_MESH_MAX_Y) + #error "UBL_MESH_(MIN|MAX)_[XY] is now just MESH_(MIN|MAX)_[XY]." +#elif defined(ABL_PROBE_PT_1_X) || defined(ABL_PROBE_PT_1_Y) || defined(ABL_PROBE_PT_2_X) || defined(ABL_PROBE_PT_2_Y) || defined(ABL_PROBE_PT_3_X) || defined(ABL_PROBE_PT_3_Y) + #error "ABL_PROBE_PT_[123]_[XY] is no longer required. Please remove it." +#elif defined(UBL_PROBE_PT_1_X) || defined(UBL_PROBE_PT_1_Y) || defined(UBL_PROBE_PT_2_X) || defined(UBL_PROBE_PT_2_Y) || defined(UBL_PROBE_PT_3_X) || defined(UBL_PROBE_PT_3_Y) + #error "UBL_PROBE_PT_[123]_[XY] is no longer required. Please remove it." +#elif defined(MIN_PROBE_EDGE) + #error "MIN_PROBE_EDGE is now called PROBING_MARGIN." +#elif defined(MIN_PROBE_EDGE_LEFT) + #error "MIN_PROBE_EDGE_LEFT is now called PROBING_MARGIN_LEFT." +#elif defined(MIN_PROBE_EDGE_RIGHT) + #error "MIN_PROBE_EDGE_RIGHT is now called PROBING_MARGIN_RIGHT." +#elif defined(MIN_PROBE_EDGE_FRONT) + #error "MIN_PROBE_EDGE_FRONT is now called PROBING_MARGIN_FRONT." +#elif defined(MIN_PROBE_EDGE_BACK) + #error "MIN_PROBE_EDGE_BACK is now called PROBING_MARGIN_BACK." +#elif defined(LEFT_PROBE_BED_POSITION) + #error "LEFT_PROBE_BED_POSITION is obsolete. Set a margin with PROBING_MARGIN or PROBING_MARGIN_LEFT instead." +#elif defined(RIGHT_PROBE_BED_POSITION) + #error "RIGHT_PROBE_BED_POSITION is obsolete. Set a margin with PROBING_MARGIN or PROBING_MARGIN_RIGHT instead." +#elif defined(FRONT_PROBE_BED_POSITION) + #error "FRONT_PROBE_BED_POSITION is obsolete. Set a margin with PROBING_MARGIN or PROBING_MARGIN_FRONT instead." +#elif defined(BACK_PROBE_BED_POSITION) + #error "BACK_PROBE_BED_POSITION is obsolete. Set a margin with PROBING_MARGIN or PROBING_MARGIN_BACK instead." +#elif defined(ENABLE_MESH_EDIT_GFX_OVERLAY) + #error "ENABLE_MESH_EDIT_GFX_OVERLAY is now MESH_EDIT_GFX_OVERLAY." +#elif defined(BABYSTEP_ZPROBE_GFX_REVERSE) + #error "BABYSTEP_ZPROBE_GFX_REVERSE is now set by OVERLAY_GFX_REVERSE." +#elif defined(UBL_GRANULAR_SEGMENTATION_FOR_CARTESIAN) + #error "UBL_GRANULAR_SEGMENTATION_FOR_CARTESIAN is now SEGMENT_LEVELED_MOVES." +#elif HAS_PID_HEATING && (defined(K1) || !defined(PID_K1)) + #error "K1 is now PID_K1." +#elif defined(PROBE_DOUBLE_TOUCH) + #error "PROBE_DOUBLE_TOUCH is now MULTIPLE_PROBING." +#elif defined(ANET_KEYPAD_LCD) + #error "ANET_KEYPAD_LCD is now ZONESTAR_LCD." +#elif defined(LCD_I2C_SAINSMART_YWROBOT) + #error "LCD_I2C_SAINSMART_YWROBOT is now LCD_SAINSMART_I2C_(1602|2004)." +#elif defined(MEASURED_LOWER_LIMIT) || defined(MEASURED_UPPER_LIMIT) + #error "MEASURED_(UPPER|LOWER)_LIMIT is now FILWIDTH_ERROR_MARGIN." +#elif defined(HAVE_TMCDRIVER) + #error "HAVE_TMCDRIVER is now [AXIS]_DRIVER_TYPE TMC26X." +#elif defined(STEALTHCHOP) + #error "STEALTHCHOP is now STEALTHCHOP_(XY|Z|E)." +#elif defined(HAVE_TMC26X) + #error "HAVE_TMC26X is now [AXIS]_DRIVER_TYPE TMC26X." +#elif defined(HAVE_TMC2130) + #error "HAVE_TMC2130 is now [AXIS]_DRIVER_TYPE TMC2130." +#elif defined(HAVE_TMC2208) + #error "HAVE_TMC2208 is now [AXIS]_DRIVER_TYPE TMC2208." +#elif defined(HAVE_L6470DRIVER) + #error "HAVE_L6470DRIVER is obsolete. L64xx stepper drivers are no longer supported in Marlin." +#elif defined(X_IS_TMC) || defined(X2_IS_TMC) || defined(Y_IS_TMC) || defined(Y2_IS_TMC) || defined(Z_IS_TMC) || defined(Z2_IS_TMC) || defined(Z3_IS_TMC) \ + || defined(E0_IS_TMC) || defined(E1_IS_TMC) || defined(E2_IS_TMC) || defined(E3_IS_TMC) || defined(E4_IS_TMC) || defined(E5_IS_TMC) || defined(E6_IS_TMC) || defined(E7_IS_TMC) + #error "[AXIS]_IS_TMC is now [AXIS]_DRIVER_TYPE TMC26X." +#elif defined(X_IS_TMC26X) || defined(X2_IS_TMC26X) || defined(Y_IS_TMC26X) || defined(Y2_IS_TMC26X) || defined(Z_IS_TMC26X) || defined(Z2_IS_TMC26X) || defined(Z3_IS_TMC26X) \ + || defined(E0_IS_TMC26X) || defined(E1_IS_TMC26X) || defined(E2_IS_TMC26X) || defined(E3_IS_TMC26X) || defined(E4_IS_TMC26X) || defined(E5_IS_TMC26X) || defined(E6_IS_TMC26X) || defined(E7_IS_TMC26X) + #error "[AXIS]_IS_TMC26X is now [AXIS]_DRIVER_TYPE TMC26X." +#elif defined(X_IS_TMC2130) || defined(X2_IS_TMC2130) || defined(Y_IS_TMC2130) || defined(Y2_IS_TMC2130) || defined(Z_IS_TMC2130) || defined(Z2_IS_TMC2130) || defined(Z3_IS_TMC2130) \ + || defined(E0_IS_TMC2130) || defined(E1_IS_TMC2130) || defined(E2_IS_TMC2130) || defined(E3_IS_TMC2130) || defined(E4_IS_TMC2130) || defined(E5_IS_TMC2130) || defined(E6_IS_TMC2130) || defined(E7_IS_TMC2130) + #error "[AXIS]_IS_TMC2130 is now [AXIS]_DRIVER_TYPE TMC2130." +#elif defined(X_IS_TMC2208) || defined(X2_IS_TMC2208) || defined(Y_IS_TMC2208) || defined(Y2_IS_TMC2208) || defined(Z_IS_TMC2208) || defined(Z2_IS_TMC2208) || defined(Z3_IS_TMC2208) \ + || defined(E0_IS_TMC2208) || defined(E1_IS_TMC2208) || defined(E2_IS_TMC2208) || defined(E3_IS_TMC2208) || defined(E4_IS_TMC2208) || defined(E5_IS_TMC2208) || defined(E6_IS_TMC2208) || defined(E7_IS_TMC2208) + #error "[AXIS]_IS_TMC2208 is now [AXIS]_DRIVER_TYPE TMC2208." +#elif defined(AUTOMATIC_CURRENT_CONTROL) + #error "AUTOMATIC_CURRENT_CONTROL is now MONITOR_DRIVER_STATUS." +#elif defined(FILAMENT_CHANGE_LOAD_LENGTH) + #error "FILAMENT_CHANGE_LOAD_LENGTH is now FILAMENT_CHANGE_FAST_LOAD_LENGTH." +#elif defined(LEVEL_CORNERS_INSET) + #error "LEVEL_CORNERS_INSET is now BED_TRAMMING_INSET_LFRB." +#elif defined(BEZIER_JERK_CONTROL) + #error "BEZIER_JERK_CONTROL is now S_CURVE_ACCELERATION." +#elif HAS_JUNCTION_DEVIATION && defined(JUNCTION_DEVIATION_FACTOR) + #error "JUNCTION_DEVIATION_FACTOR is now JUNCTION_DEVIATION_MM." +#elif defined(JUNCTION_ACCELERATION_FACTOR) + #error "JUNCTION_ACCELERATION_FACTOR is obsolete. Delete it from Configuration_adv.h." +#elif defined(JUNCTION_ACCELERATION) + #error "JUNCTION_ACCELERATION is obsolete. Delete it from Configuration_adv.h." +#elif defined(MAX7219_DEBUG_STEPPER_HEAD) + #error "MAX7219_DEBUG_STEPPER_HEAD is now MAX7219_DEBUG_PLANNER_HEAD." +#elif defined(MAX7219_DEBUG_STEPPER_TAIL) + #error "MAX7219_DEBUG_STEPPER_TAIL is now MAX7219_DEBUG_PLANNER_TAIL." +#elif defined(MAX7219_DEBUG_STEPPER_QUEUE) + #error "MAX7219_DEBUG_STEPPER_QUEUE is now MAX7219_DEBUG_PLANNER_QUEUE." +#elif defined(ENDSTOP_NOISE_FILTER) + #error "ENDSTOP_NOISE_FILTER is now ENDSTOP_NOISE_THRESHOLD [2-7]." +#elif defined(RETRACT_ZLIFT) + #error "RETRACT_ZLIFT is now RETRACT_ZRAISE." +#elif defined(TOOLCHANGE_FS_INIT_BEFORE_SWAP) + #error "TOOLCHANGE_FS_INIT_BEFORE_SWAP is now TOOLCHANGE_FS_SLOW_FIRST_PRIME." +#elif defined(TOOLCHANGE_PARK_ZLIFT) || defined(TOOLCHANGE_UNPARK_ZLIFT) + #error "TOOLCHANGE_PARK_ZLIFT and TOOLCHANGE_UNPARK_ZLIFT are now TOOLCHANGE_ZRAISE." +#elif defined(SINGLENOZZLE_TOOLCHANGE_ZRAISE) + #error "SINGLENOZZLE_TOOLCHANGE_ZRAISE is now TOOLCHANGE_ZRAISE." +#elif defined(SINGLENOZZLE_SWAP_LENGTH) + #error "SINGLENOZZLE_SWAP_LENGTH is now TOOLCHANGE_FIL_SWAP_LENGTH." +#elif defined(SINGLENOZZLE_SWAP_RETRACT_SPEED) + #error "SINGLENOZZLE_SWAP_RETRACT_SPEED is now TOOLCHANGE_FIL_SWAP_RETRACT_SPEED." +#elif defined(SINGLENOZZLE_SWAP_PRIME_SPEED) + #error "SINGLENOZZLE_SWAP_PRIME_SPEED is now TOOLCHANGE_FIL_SWAP_PRIME_SPEED." +#elif defined(SINGLENOZZLE_SWAP_PARK) + #error "SINGLENOZZLE_SWAP_PARK is now TOOLCHANGE_PARK." +#elif defined(SINGLENOZZLE_TOOLCHANGE_XY) + #error "SINGLENOZZLE_TOOLCHANGE_XY is now TOOLCHANGE_PARK_XY." +#elif defined(SINGLENOZZLE_PARK_XY_FEEDRATE) + #error "SINGLENOZZLE_PARK_XY_FEEDRATE is now TOOLCHANGE_PARK_XY_FEEDRATE." +#elif defined(PARKING_EXTRUDER_SECURITY_RAISE) + #error "PARKING_EXTRUDER_SECURITY_RAISE is now TOOLCHANGE_ZRAISE." +#elif defined(SWITCHING_TOOLHEAD_SECURITY_RAISE) + #error "SWITCHING_TOOLHEAD_SECURITY_RAISE is now TOOLCHANGE_ZRAISE." +#elif defined(G0_FEEDRATE) && G0_FEEDRATE == 0 + #error "G0_FEEDRATE is now used to set the G0 feedrate." +#elif defined(MBL_Z_STEP) + #error "MBL_Z_STEP is now MESH_EDIT_Z_STEP." +#elif defined(CHDK) + #error "CHDK is now CHDK_PIN." +#elif ANY_PIN( \ + MAX6675_SS, MAX6675_SS2, MAX6675_CS, MAX6675_CS2, \ + MAX31855_SS, MAX31855_SS2, MAX31855_CS, MAX31855_CS2, \ + MAX31865_SS, MAX31865_SS2, MAX31865_CS, MAX31865_CS2) + #warning "MAX*_SS_PIN, MAX*_SS2_PIN, MAX*_CS_PIN, and MAX*_CS2_PIN are deprecated and will be removed in a future version. Please use TEMP_0_CS_PIN/TEMP_1_CS_PIN instead." +#elif ANY_PIN(MAX6675_SCK, MAX31855_SCK, MAX31865_SCK) + #warning "MAX*_SCK_PIN is deprecated and will be removed in a future version. Please use TEMP_0_SCK_PIN/TEMP_1_SCK_PIN instead." +#elif ANY_PIN(MAX6675_MISO, MAX6675_DO, MAX31855_MISO, MAX31855_DO, MAX31865_MISO, MAX31865_DO) + #warning "MAX*_MISO_PIN and MAX*_DO_PIN are deprecated and will be removed in a future version. Please use TEMP_0_MISO_PIN/TEMP_1_MISO_PIN instead." +#elif PIN_EXISTS(MAX31865_MOSI) + #warning "MAX31865_MOSI_PIN is deprecated and will be removed in a future version. Please use TEMP_0_MOSI_PIN/TEMP_1_MOSI_PIN instead." +#elif ANY_PIN(THERMO_CS1_PIN, THERMO_CS2_PIN, THERMO_DO_PIN, THERMO_SCK_PIN) + #error "THERMO_*_PIN is now TEMP_n_CS_PIN, TEMP_n_SCK_PIN, TEMP_n_MOSI_PIN, TEMP_n_MISO_PIN." +#elif defined(MAX31865_SENSOR_OHMS) + #error "MAX31865_SENSOR_OHMS is now MAX31865_SENSOR_OHMS_0." +#elif defined(MAX31865_CALIBRATION_OHMS) + #error "MAX31865_CALIBRATION_OHMS is now MAX31865_CALIBRATION_OHMS_0." +#elif defined(SPINDLE_LASER_ENABLE) + #error "SPINDLE_LASER_ENABLE is now SPINDLE_FEATURE or LASER_FEATURE." +#elif defined(SPINDLE_LASER_ENABLE_PIN) + #error "SPINDLE_LASER_ENABLE_PIN is now SPINDLE_LASER_ENA_PIN." +#elif defined(SPINDLE_DIR_CHANGE) + #error "SPINDLE_DIR_CHANGE is now SPINDLE_CHANGE_DIR." +#elif defined(SPINDLE_STOP_ON_DIR_CHANGE) + #error "SPINDLE_STOP_ON_DIR_CHANGE is now SPINDLE_CHANGE_DIR_STOP." +#elif defined(SPINDLE_LASER_ACTIVE_HIGH) + #error "SPINDLE_LASER_ACTIVE_HIGH is now SPINDLE_LASER_ACTIVE_STATE." +#elif defined(SPINDLE_LASER_ENABLE_INVERT) + #error "SPINDLE_LASER_ENABLE_INVERT is now SPINDLE_LASER_ACTIVE_STATE." +#elif defined(LASER_POWER_INLINE) + #error "LASER_POWER_INLINE is not required, inline mode is enabled with 'M3 I' and disabled with 'M5 I'." +#elif defined(LASER_POWER_INLINE_TRAPEZOID) + #error "LASER_POWER_INLINE_TRAPEZOID is now LASER_POWER_TRAP." +#elif defined(LASER_POWER_INLINE_TRAPEZOID_CONT) + #error "LASER_POWER_INLINE_TRAPEZOID_CONT is replaced with LASER_POWER_TRAP." +#elif defined(LASER_POWER_INLINE_TRAPEZOID_PER) + #error "LASER_POWER_INLINE_TRAPEZOID_CONT_PER replaced with LASER_POWER_TRAP." +#elif defined(LASER_POWER_INLINE_CONTINUOUS) + #error "LASER_POWER_INLINE_CONTINUOUS is not required, inline mode is enabled with 'M3 I' and disabled with 'M5 I'." +#elif defined(CUTTER_POWER_DISPLAY) + #error "CUTTER_POWER_DISPLAY is now CUTTER_POWER_UNIT." +#elif defined(CHAMBER_HEATER_PIN) + #error "CHAMBER_HEATER_PIN is now HEATER_CHAMBER_PIN." +#elif defined(TMC_Z_CALIBRATION) + #error "TMC_Z_CALIBRATION has been deprecated in favor of MECHANICAL_GANTRY_CALIBRATION." +#elif defined(Z_MIN_PROBE_ENDSTOP) + #error "Z_MIN_PROBE_ENDSTOP is no longer required. Please remove it." +#elif defined(DUAL_NOZZLE_DUPLICATION_MODE) + #error "DUAL_NOZZLE_DUPLICATION_MODE is now MULTI_NOZZLE_DUPLICATION." +#elif defined(MENU_ITEM_CASE_LIGHT) + #error "MENU_ITEM_CASE_LIGHT is now CASE_LIGHT_MENU." +#elif defined(CASE_LIGHT_NEOPIXEL_COLOR) + #error "CASE_LIGHT_NEOPIXEL_COLOR is now CASE_LIGHT_DEFAULT_COLOR." +#elif defined(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) + #error "ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED is now SD_ABORT_ON_ENDSTOP_HIT." +#elif defined(LPC_SD_LCD) || defined(LPC_SD_ONBOARD) || defined(LPC_SD_CUSTOM_CABLE) + #error "LPC_SD_(LCD|ONBOARD|CUSTOM_CABLE) are now SDCARD_CONNECTION." +#elif defined(USB_SD_DISABLED) + #error "USB_SD_DISABLED is now NO_SD_HOST_DRIVE." +#elif defined(USB_SD_ONBOARD) + #error "USB_SD_ONBOARD is obsolete. Disable NO_SD_HOST_DRIVE instead." +#elif defined(PSU_ACTIVE_HIGH) + #error "PSU_ACTIVE_HIGH is now PSU_ACTIVE_STATE." +#elif POWER_SUPPLY == 1 + #error "Replace POWER_SUPPLY 1 by enabling PSU_CONTROL and setting PSU_ACTIVE_STATE to 'LOW'." +#elif POWER_SUPPLY == 2 + #error "Replace POWER_SUPPLY 2 by enabling PSU_CONTROL and setting PSU_ACTIVE_STATE to 'HIGH'." +#elif defined(POWER_SUPPLY) + #error "POWER_SUPPLY is now obsolete. Please remove it." +#elif defined(MKS_ROBIN_TFT) + #error "MKS_ROBIN_TFT is now FSMC_GRAPHICAL_TFT." +#elif defined(SDPOWER) + #error "SDPOWER is now SDPOWER_PIN." +#elif defined(STRING_SPLASH_LINE1) || defined(STRING_SPLASH_LINE2) + #error "STRING_SPLASH_LINE[12] are now obsolete. Please remove them." +#elif defined(Z_PROBE_ALLEN_KEY_DEPLOY_1_X) || defined(Z_PROBE_ALLEN_KEY_STOW_1_X) + #error "Z_PROBE_ALLEN_KEY_(DEPLOY|STOW) coordinates are now a single setting." +#elif defined(X_PROBE_OFFSET_FROM_EXTRUDER) || defined(Y_PROBE_OFFSET_FROM_EXTRUDER) || defined(Z_PROBE_OFFSET_FROM_EXTRUDER) + #error "[XYZ]_PROBE_OFFSET_FROM_EXTRUDER is now NOZZLE_TO_PROBE_OFFSET." +#elif defined(MIN_PROBE_X) || defined(MIN_PROBE_Y) || defined(MAX_PROBE_X) || defined(MAX_PROBE_Y) + #error "(MIN|MAX)_PROBE_[XY] are now calculated at runtime. Please remove them." +#elif defined(Z_STEPPER_ALIGN_X) || defined(Z_STEPPER_ALIGN_X) + #error "Z_STEPPER_ALIGN_X and Z_STEPPER_ALIGN_Y are now combined as Z_STEPPER_ALIGN_XY." +#elif defined(JUNCTION_DEVIATION) + #error "JUNCTION_DEVIATION is no longer required. (See CLASSIC_JERK). Please remove it." +#elif defined(BABYSTEP_MULTIPLICATOR) + #error "BABYSTEP_MULTIPLICATOR is now BABYSTEP_MULTIPLICATOR_[XY|Z]." +#elif defined(LULZBOT_TOUCH_UI) + #error "LULZBOT_TOUCH_UI is now TOUCH_UI_FTDI_EVE." +#elif defined(PS_DEFAULT_OFF) + #error "PS_DEFAULT_OFF is now PSU_DEFAULT_OFF." +#elif defined(FILAMENT_UNLOAD_RETRACT_LENGTH) + #error "FILAMENT_UNLOAD_RETRACT_LENGTH is now FILAMENT_UNLOAD_PURGE_RETRACT." +#elif defined(FILAMENT_UNLOAD_DELAY) + #error "FILAMENT_UNLOAD_DELAY is now FILAMENT_UNLOAD_PURGE_DELAY." +#elif defined(HOME_USING_SPREADCYCLE) + #error "HOME_USING_SPREADCYCLE is now obsolete. Please remove it." +#elif defined(DGUS_LCD) + #error "DGUS_LCD is now DGUS_LCD_UI_(ORIGIN|FYSETC|HIPRECY)." +#elif defined(DGUS_SERIAL_PORT) + #error "DGUS_SERIAL_PORT is now LCD_SERIAL_PORT." +#elif defined(DGUS_BAUDRATE) + #error "DGUS_BAUDRATE is now LCD_BAUDRATE." +#elif defined(DGUS_STATS_RX_BUFFER_OVERRUNS) + #error "DGUS_STATS_RX_BUFFER_OVERRUNS is now STATS_RX_BUFFER_OVERRUNS." +#elif defined(ANYCUBIC_LCD_SERIAL_PORT) + #error "ANYCUBIC_LCD_SERIAL_PORT is now LCD_SERIAL_PORT." +#elif defined(INTERNAL_SERIAL_PORT) + #error "INTERNAL_SERIAL_PORT is now MMU2_SERIAL_PORT." +#elif defined(X_DUAL_ENDSTOPS_ADJUSTMENT) || defined(Y_DUAL_ENDSTOPS_ADJUSTMENT) || defined(Z_DUAL_ENDSTOPS_ADJUSTMENT) + #error "[XYZ]_DUAL_ENDSTOPS_ADJUSTMENT is now [XYZ]2_ENDSTOP_ADJUSTMENT." +#elif defined(Z_TRIPLE_ENDSTOPS_ADJUSTMENT2) || defined(Z_TRIPLE_ENDSTOPS_ADJUSTMENT3) + #error "Z_TRIPLE_ENDSTOPS_ADJUSTMENT[23] is now Z[23]_ENDSTOP_ADJUSTMENT." +#elif defined(Z_QUAD_ENDSTOPS_ADJUSTMENT2) || defined(Z_QUAD_ENDSTOPS_ADJUSTMENT3) || defined(Z_QUAD_ENDSTOPS_ADJUSTMENT4) + #error "Z_QUAD_ENDSTOPS_ADJUSTMENT[234] is now Z[234]_ENDSTOP_ADJUSTMENT." +#elif defined(Z_DUAL_STEPPER_DRIVERS) + #error "Z_DUAL_STEPPER_DRIVERS is no longer needed and should be removed." +#elif defined(Z_TRIPLE_STEPPER_DRIVERS) + #error "Z_TRIPLE_STEPPER_DRIVERS is no longer needed and should be removed." +#elif defined(Z_QUAD_STEPPER_DRIVERS) + #error "Z_QUAD_STEPPER_DRIVERS is no longer needed and should be removed." +#elif defined(Z_DUAL_ENDSTOPS) || defined(Z_TRIPLE_ENDSTOPS) || defined(Z_QUAD_ENDSTOPS) + #error "Z_(DUAL|TRIPLE|QUAD)_ENDSTOPS is now Z_MULTI_ENDSTOPS." +#elif defined(DUGS_UI_MOVE_DIS_OPTION) + #error "DUGS_UI_MOVE_DIS_OPTION is spelled DGUS_UI_MOVE_DIS_OPTION." +#elif defined(ORIG_E0_AUTO_FAN_PIN) || defined(ORIG_E1_AUTO_FAN_PIN) || defined(ORIG_E2_AUTO_FAN_PIN) || defined(ORIG_E3_AUTO_FAN_PIN) || defined(ORIG_E4_AUTO_FAN_PIN) || defined(ORIG_E5_AUTO_FAN_PIN) || defined(ORIG_E6_AUTO_FAN_PIN) || defined(ORIG_E7_AUTO_FAN_PIN) + #error "ORIG_Ex_AUTO_FAN_PIN is now just Ex_AUTO_FAN_PIN." +#elif defined(ORIG_CHAMBER_AUTO_FAN_PIN) + #error "ORIG_CHAMBER_AUTO_FAN_PIN is now just CHAMBER_AUTO_FAN_PIN." +#elif defined(HOMING_BACKOFF_MM) + #error "HOMING_BACKOFF_MM is now HOMING_BACKOFF_POST_MM." +#elif defined(X_HOME_BUMP_MM) || defined(Y_HOME_BUMP_MM) || defined(Z_HOME_BUMP_MM) + #error "[XYZ]_HOME_BUMP_MM is now HOMING_BUMP_MM." +#elif defined(DIGIPOT_I2C) + #error "DIGIPOT_I2C is now DIGIPOT_MCP4451 (or DIGIPOT_MCP4018)." +#elif defined(TOUCH_BUTTONS) + #error "TOUCH_BUTTONS is now TOUCH_SCREEN." +#elif defined(LCD_FULL_PIXEL_HEIGHT) || defined(LCD_FULL_PIXEL_WIDTH) + #error "LCD_FULL_PIXEL_(WIDTH|HEIGHT) is deprecated and should be removed." +#elif defined(FSMC_UPSCALE) + #error "FSMC_UPSCALE is now GRAPHICAL_TFT_UPSCALE." +#elif defined(ANYCUBIC_TFT_MODEL) + #error "ANYCUBIC_TFT_MODEL is now ANYCUBIC_LCD_I3MEGA." +#elif defined(EVENT_GCODE_SD_STOP) + #error "EVENT_GCODE_SD_STOP is now EVENT_GCODE_SD_ABORT." +#elif defined(GRAPHICAL_TFT_ROTATE_180) + #error "GRAPHICAL_TFT_ROTATE_180 is now TFT_ROTATION set to TFT_ROTATE_180." +#elif defined(PROBE_OFFSET_START) + #error "PROBE_OFFSET_START is now PROBE_OFFSET_WIZARD_START_Z." +#elif defined(POWER_LOSS_PULL) + #error "POWER_LOSS_PULL is now specifically POWER_LOSS_PULL(UP|DOWN)." +#elif defined(SHORT_MANUAL_Z_MOVE) + #error "SHORT_MANUAL_Z_MOVE is now FINE_MANUAL_MOVE, applying to Z on most printers." +#elif defined(FIL_RUNOUT_INVERTING) + #if FIL_RUNOUT_INVERTING + #error "FIL_RUNOUT_INVERTING true is now FIL_RUNOUT_MODE {HIGH}." + #else + #error "FIL_RUNOUT_INVERTING false is now FIL_RUNOUT_MODE {LOW}." + #endif +#elif defined(ASSISTED_TRAMMING_MENU_ITEM) + #error "ASSISTED_TRAMMING_MENU_ITEM is deprecated and should be removed." +#elif defined(UNKNOWN_Z_NO_RAISE) + #error "UNKNOWN_Z_NO_RAISE is replaced by setting Z_IDLE_HEIGHT to Z_MAX_POS." +#elif defined(Z_AFTER_DEACTIVATE) + #error "Z_AFTER_DEACTIVATE is replaced by Z_IDLE_HEIGHT." +#elif defined(MEATPACK) + #error "MEATPACK is now enabled with MEATPACK_ON_SERIAL_PORT_1, MEATPACK_ON_SERIAL_PORT_2, etc." +#elif defined(CUSTOM_USER_MENUS) + #error "CUSTOM_USER_MENUS has been replaced by CUSTOM_MENU_MAIN and CUSTOM_MENU_CONFIG." +#elif defined(MKS_LCD12864) + #error "MKS_LCD12864 is now MKS_LCD12864A or MKS_LCD12864B." +#elif defined(DOGM_SD_PERCENT) + #error "DOGM_SD_PERCENT is now SHOW_PROGRESS_PERCENT." +#elif defined(NEOPIXEL_BKGD_LED_INDEX) + #error "NEOPIXEL_BKGD_LED_INDEX is now NEOPIXEL_BKGD_INDEX_FIRST." +#elif defined(TEMP_SENSOR_1_AS_REDUNDANT) + #error "TEMP_SENSOR_1_AS_REDUNDANT is now TEMP_SENSOR_REDUNDANT, with associated TEMP_SENSOR_REDUNDANT_* config." +#elif defined(MAX_REDUNDANT_TEMP_SENSOR_DIFF) + #error "MAX_REDUNDANT_TEMP_SENSOR_DIFF is now TEMP_SENSOR_REDUNDANT_MAX_DIFF" +#elif defined(LCD_ALEPHOBJECTS_CLCD_UI) + #error "LCD_ALEPHOBJECTS_CLCD_UI is now LCD_LULZBOT_CLCD_UI." +#elif defined(MIN_ARC_SEGMENTS) + #error "MIN_ARC_SEGMENTS is now MIN_CIRCLE_SEGMENTS." +#elif defined(ARC_SEGMENTS_PER_R) + #error "ARC_SUPPORT no longer uses ARC_SEGMENTS_PER_R." +#elif ENABLED(ARC_SUPPORT) && (!defined(MIN_ARC_SEGMENT_MM) || !defined(MAX_ARC_SEGMENT_MM)) + #error "ARC_SUPPORT now requires MIN_ARC_SEGMENT_MM and MAX_ARC_SEGMENT_MM." +#elif defined(LASER_POWER_INLINE) + #error "LASER_POWER_INLINE is obsolete." +#elif defined(SPINDLE_LASER_PWM) + #error "SPINDLE_LASER_PWM (true) is now set with SPINDLE_LASER_USE_PWM (enabled)." +#elif ANY(IS_RAMPS_EEB, IS_RAMPS_EEF, IS_RAMPS_EFB, IS_RAMPS_EFF, IS_RAMPS_SF) + #error "The IS_RAMPS_* conditionals (for heater/fan/bed pins) are now called FET_ORDER_*." +#elif defined(PROBE_TEMP_COMPENSATION) + #error "PROBE_TEMP_COMPENSATION is now set using the PTC_PROBE, PTC_BED, PTC_HOTEND options." +#elif defined(BTC_PROBE_TEMP) + #error "BTC_PROBE_TEMP is now PTC_PROBE_TEMP." +#elif defined(LCD_SCREEN_ROT_90) + #error "LCD_SCREEN_ROT_90 is now LCD_SCREEN_ROTATE with a value of 90." +#elif defined(LCD_SCREEN_ROT_180) + #error "LCD_SCREEN_ROT_180 is now LCD_SCREEN_ROTATE with a value of 180." +#elif defined(LCD_SCREEN_ROT_270) + #error "LCD_SCREEN_ROT_270 is now LCD_SCREEN_ROTATE with a value of 270." +#elif defined(DEFAULT_LCD_BRIGHTNESS) + #error "DEFAULT_LCD_BRIGHTNESS is now LCD_BRIGHTNESS_DEFAULT." +#elif defined(NOZZLE_PARK_X_ONLY) + #error "NOZZLE_PARK_X_ONLY is now NOZZLE_PARK_MOVE 1." +#elif defined(NOZZLE_PARK_Y_ONLY) + #error "NOZZLE_PARK_Y_ONLY is now NOZZLE_PARK_MOVE 2." +#elif defined(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) + #error "Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS is now just Z_STEPPER_ALIGN_STEPPER_XY." +#elif defined(DWIN_CREALITY_LCD_ENHANCED) + #error "DWIN_CREALITY_LCD_ENHANCED is now DWIN_LCD_PROUI." +#elif defined(LINEAR_AXES) + #error "LINEAR_AXES is now NUM_AXES (to account for rotational axes)." +#elif defined(X_DUAL_STEPPER_DRIVERS) + #error "X_DUAL_STEPPER_DRIVERS is no longer needed and should be removed." +#elif defined(Y_DUAL_STEPPER_DRIVERS) + #error "Y_DUAL_STEPPER_DRIVERS is no longer needed and should be removed." +#elif defined(NUM_Z_STEPPER_DRIVERS) + #error "NUM_Z_STEPPER_DRIVERS is no longer needed and should be removed." +#elif defined(LEVEL_BED_CORNERS) + #error "LEVEL_BED_CORNERS is now LCD_BED_TRAMMING." +#elif defined(LEVEL_CORNERS_INSET_LFRB) || defined(LEVEL_CORNERS_HEIGHT) || defined(LEVEL_CORNERS_Z_HOP) || defined(LEVEL_CORNERS_USE_PROBE) || defined(LEVEL_CORNERS_PROBE_TOLERANCE) || defined(LEVEL_CORNERS_VERIFY_RAISED) || defined(LEVEL_CORNERS_AUDIO_FEEDBACK) + #error "LEVEL_CORNERS_* settings have been renamed BED_TRAMMING_*." +#elif defined(LEVEL_CENTER_TOO) + #error "LEVEL_CENTER_TOO is now BED_TRAMMING_INCLUDE_CENTER." +#elif defined(TOUCH_IDLE_SLEEP) + #error "TOUCH_IDLE_SLEEP (seconds) is now TOUCH_IDLE_SLEEP_MINS (minutes)." +#elif defined(LCD_BACKLIGHT_TIMEOUT) + #error "LCD_BACKLIGHT_TIMEOUT (seconds) is now LCD_BACKLIGHT_TIMEOUT_MINS (minutes)." +#elif defined(LCD_SET_PROGRESS_MANUALLY) + #error "LCD_SET_PROGRESS_MANUALLY is now SET_PROGRESS_MANUALLY." +#elif defined(USE_M73_REMAINING_TIME) + #error "USE_M73_REMAINING_TIME is now SET_REMAINING_TIME." +#elif defined(SHOW_SD_PERCENT) + #error "SHOW_SD_PERCENT is now SHOW_PROGRESS_PERCENT." +#elif defined(EXTRA_LIN_ADVANCE_K) + #error "EXTRA_LIN_ADVANCE_K is now ADVANCE_K_EXTRA." #endif -/** - * Required Version defines - */ -#ifndef SHORT_BUILD_VERSION - #error "SHORT_BUILD_VERSION must be specified." -#elif !defined(DETAILED_BUILD_VERSION) - #error "BUILD_VERSION must be specified." -#elif !defined(STRING_DISTRIBUTION_DATE) - #error "STRING_DISTRIBUTION_DATE must be specified." -#elif !defined(PROTOCOL_VERSION) - #error "PROTOCOL_VERSION must be specified." -#elif !defined(MACHINE_NAME) - #error "MACHINE_NAME must be specified." -#elif !defined(SOURCE_CODE_URL) - #error "SOURCE_CODE_URL must be specified." -#elif !defined(DEFAULT_MACHINE_UUID) - #error "DEFAULT_MACHINE_UUID must be specified." -#elif !defined(WEBSITE_URL) - #error "WEBSITE_URL must be specified." +// L64xx stepper drivers have been removed +#define _L6470 0x6470 +#define _L6474 0x6474 +#define _L6480 0x6480 +#define _POWERSTEP01 0xF00D +#if HAS_DRIVER(L6470) + #error "L6470 stepper drivers are no longer supported in Marlin." +#elif HAS_DRIVER(L6474) + #error "L6474 stepper drivers are no longer supported in Marlin." +#elif HAS_DRIVER(L6480) + #error "L6480 stepper drivers are no longer supported in Marlin." +#elif HAS_DRIVER(POWERSTEP01) + #error "POWERSTEP01 stepper drivers are no longer supported in Marlin." #endif +#undef _L6470 +#undef _L6474 +#undef _L6480 +#undef _POWERSTEP01 // Check AXIS_RELATIVE_MODES constexpr float arm[] = AXIS_RELATIVE_MODES; static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _LOGICAL_AXES_STR "elements."); -/** - * RADDS is forbidden for non-DUE boards, for now. - */ -#if ENABLED(RADDS_DISPLAY) && !defined(__SAM3X8E__) - #error "RADDS_DISPLAY is currently only incompatible with DUE boards." -#endif - -/** - * Heated Bed requirements - */ -#if HAS_HEATED_BED - #if !HAS_TEMP_BED - #error "The Heated Bed requires a TEMP_BED_PIN or Thermocouple." - #elif !HAS_HEATER_BED - #error "The Heated Bed requires HEATER_BED_PIN." - #endif -#endif - -/** - * Hephestos 2 Heated Bed Kit requirements - */ -#if ENABLED(HEPHESTOS2_HEATED_BED_KIT) - #if TEMP_SENSOR_BED != 70 - #error "HEPHESTOS2_HEATED_BED_KIT requires TEMP_SENSOR_BED 70." - #elif DISABLED(HEATER_BED_INVERTING) - #error "HEPHESTOS2_HEATED_BED_KIT requires HEATER_BED_INVERTING." - #endif -#endif - /** * Probe temp compensation requirements */ #if HAS_PTC - #if TEMP_SENSOR_PROBE && TEMP_SENSOR_BED && !(defined(PTC_PARK_POS) && defined(PTC_PROBE_POS)) - #error "PTC_PARK_POS and PTC_PROBE_POS are required for Probe Temperature Compensation." + #if TEMP_SENSOR_PROBE && TEMP_SENSOR_BED + #if defined(PTC_PARK_POS_X) || defined(PTC_PARK_POS_Y) || defined(PTC_PARK_POS_Z) + #error "PTC_PARK_POS_[XYZ] is now PTC_PARK_POS (array)." + #elif !defined(PTC_PARK_POS) + #error "PTC_PARK_POS is required for Probe Temperature Compensation." + #elif defined(PTC_PROBE_POS_X) || defined(PTC_PROBE_POS_Y) + #error "PTC_PROBE_POS_[XY] is now PTC_PROBE_POS (array)." + #elif !defined(PTC_PROBE_POS) + #error "PTC_PROBE_POS is required for Probe Temperature Compensation." + #endif #endif #if ENABLED(PTC_PROBE) @@ -207,6 +749,27 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L #endif #endif // HAS_PTC +/** + * Marlin release, version and default string + */ +#ifndef SHORT_BUILD_VERSION + #error "SHORT_BUILD_VERSION must be specified." +#elif !defined(DETAILED_BUILD_VERSION) + #error "BUILD_VERSION must be specified." +#elif !defined(STRING_DISTRIBUTION_DATE) + #error "STRING_DISTRIBUTION_DATE must be specified." +#elif !defined(PROTOCOL_VERSION) + #error "PROTOCOL_VERSION must be specified." +#elif !defined(MACHINE_NAME) + #error "MACHINE_NAME must be specified." +#elif !defined(SOURCE_CODE_URL) + #error "SOURCE_CODE_URL must be specified." +#elif !defined(DEFAULT_MACHINE_UUID) + #error "DEFAULT_MACHINE_UUID must be specified." +#elif !defined(WEBSITE_URL) + #error "WEBSITE_URL must be specified." +#endif + /** * Serial */ @@ -235,25 +798,18 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L #error "SERIAL_XON_XOFF and SERIAL_STATS_* features not supported on USB-native AVR devices." #endif -// Serial DMA is only available for some STM32 MCUs -#if ENABLED(SERIAL_DMA) - #if !HAL_STM32 || NONE(STM32F0xx, STM32F1xx, STM32F2xx, STM32F4xx, STM32F7xx) - #error "SERIAL_DMA is only available for some STM32 MCUs and requires HAL/STM32." - #elif !defined(HAL_UART_MODULE_ENABLED) || defined(HAL_UART_MODULE_ONLY) - #error "SERIAL_DMA requires STM32 platform HAL UART (without HAL_UART_MODULE_ONLY)." - #endif -#endif - /** * Multiple Stepper Drivers Per Axis */ -#define GOOD_AXIS_PINS(A) PINS_EXIST(A##_ENABLE, A##_STEP, A##_DIR) -#if HAS_X2_STEPPER && !GOOD_AXIS_PINS(X2) +#define GOOD_AXIS_PINS(A) (HAS_##A##_ENABLE && HAS_##A##_STEP && HAS_##A##_DIR) +#if HAS_X2_STEPPER && !GOOD_AXIS_PINS(X) #error "If X2_DRIVER_TYPE is defined, then X2 ENABLE/STEP/DIR pins are also needed." #endif -#if HAS_Y2_STEPPER && !GOOD_AXIS_PINS(Y2) + +#if HAS_DUAL_Y_STEPPERS && !GOOD_AXIS_PINS(Y) #error "If Y2_DRIVER_TYPE is defined, then Y2 ENABLE/STEP/DIR pins are also needed." #endif + #if HAS_Z_AXIS #if NUM_Z_STEPPERS >= 2 && !GOOD_AXIS_PINS(Z2) #error "If Z2_DRIVER_TYPE is defined, then Z2 ENABLE/STEP/DIR pins are also needed." @@ -265,18 +821,10 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L #endif /** - * Validate bed size + * Validate that the bed size fits */ -#if !defined(X_BED_SIZE) || !defined(Y_BED_SIZE) - #error "X_BED_SIZE and Y_BED_SIZE are required!" -#else - #if HAS_X_AXIS - static_assert(X_MAX_LENGTH >= X_BED_SIZE, "Movement bounds (X_MIN_POS, X_MAX_POS) are too narrow to contain X_BED_SIZE."); - #endif - #if HAS_Y_AXIS - static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS) are too narrow to contain Y_BED_SIZE."); - #endif -#endif +static_assert(X_MAX_LENGTH >= X_BED_SIZE, "Movement bounds (X_MIN_POS, X_MAX_POS) are too narrow to contain X_BED_SIZE."); +static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS) are too narrow to contain Y_BED_SIZE."); /** * Granular software endstops (Marlin >= 1.1.7) @@ -297,45 +845,45 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L #endif #endif -#if ALL(ENDSTOPPULLUPS, ENDSTOPPULLDOWNS) +#if BOTH(ENDSTOPPULLUPS, ENDSTOPPULLDOWNS) #error "Enable only one of ENDSTOPPULLUPS or ENDSTOPPULLDOWNS." -#elif ALL(FIL_RUNOUT_PULLUP, FIL_RUNOUT_PULLDOWN) +#elif BOTH(FIL_RUNOUT_PULLUP, FIL_RUNOUT_PULLDOWN) #error "Enable only one of FIL_RUNOUT_PULLUP or FIL_RUNOUT_PULLDOWN." -#elif ALL(ENDSTOPPULLUP_XMAX, ENDSTOPPULLDOWN_XMAX) +#elif BOTH(ENDSTOPPULLUP_XMAX, ENDSTOPPULLDOWN_XMAX) #error "Enable only one of ENDSTOPPULLUP_X_MAX or ENDSTOPPULLDOWN_X_MAX." -#elif ALL(ENDSTOPPULLUP_YMAX, ENDSTOPPULLDOWN_YMAX) +#elif BOTH(ENDSTOPPULLUP_YMAX, ENDSTOPPULLDOWN_YMAX) #error "Enable only one of ENDSTOPPULLUP_Y_MAX or ENDSTOPPULLDOWN_Y_MAX." -#elif ALL(ENDSTOPPULLUP_ZMAX, ENDSTOPPULLDOWN_ZMAX) +#elif BOTH(ENDSTOPPULLUP_ZMAX, ENDSTOPPULLDOWN_ZMAX) #error "Enable only one of ENDSTOPPULLUP_Z_MAX or ENDSTOPPULLDOWN_Z_MAX." -#elif ALL(ENDSTOPPULLUP_IMAX, ENDSTOPPULLDOWN_IMAX) +#elif BOTH(ENDSTOPPULLUP_IMAX, ENDSTOPPULLDOWN_IMAX) #error "Enable only one of ENDSTOPPULLUP_I_MAX or ENDSTOPPULLDOWN_I_MAX." -#elif ALL(ENDSTOPPULLUP_JMAX, ENDSTOPPULLDOWN_JMAX) +#elif BOTH(ENDSTOPPULLUP_JMAX, ENDSTOPPULLDOWN_JMAX) #error "Enable only one of ENDSTOPPULLUP_J_MAX or ENDSTOPPULLDOWN_J_MAX." -#elif ALL(ENDSTOPPULLUP_KMAX, ENDSTOPPULLDOWN_KMAX) +#elif BOTH(ENDSTOPPULLUP_KMAX, ENDSTOPPULLDOWN_KMAX) #error "Enable only one of ENDSTOPPULLUP_K_MAX or ENDSTOPPULLDOWN_K_MAX." -#elif ALL(ENDSTOPPULLUP_UMAX, ENDSTOPPULLDOWN_UMAX) +#elif BOTH(ENDSTOPPULLUP_UMAX, ENDSTOPPULLDOWN_UMAX) #error "Enable only one of ENDSTOPPULLUP_U_MAX or ENDSTOPPULLDOWN_U_MAX." -#elif ALL(ENDSTOPPULLUP_VMAX, ENDSTOPPULLDOWN_VMAX) +#elif BOTH(ENDSTOPPULLUP_VMAX, ENDSTOPPULLDOWN_VMAX) #error "Enable only one of ENDSTOPPULLUP_V_MAX or ENDSTOPPULLDOWN_V_MAX." -#elif ALL(ENDSTOPPULLUP_WMAX, ENDSTOPPULLDOWN_WMAX) +#elif BOTH(ENDSTOPPULLUP_WMAX, ENDSTOPPULLDOWN_WMAX) #error "Enable only one of ENDSTOPPULLUP_W_MAX or ENDSTOPPULLDOWN_W_MAX." -#elif ALL(ENDSTOPPULLUP_XMIN, ENDSTOPPULLDOWN_XMIN) +#elif BOTH(ENDSTOPPULLUP_XMIN, ENDSTOPPULLDOWN_XMIN) #error "Enable only one of ENDSTOPPULLUP_X_MIN or ENDSTOPPULLDOWN_X_MIN." -#elif ALL(ENDSTOPPULLUP_YMIN, ENDSTOPPULLDOWN_YMIN) +#elif BOTH(ENDSTOPPULLUP_YMIN, ENDSTOPPULLDOWN_YMIN) #error "Enable only one of ENDSTOPPULLUP_Y_MIN or ENDSTOPPULLDOWN_Y_MIN." -#elif ALL(ENDSTOPPULLUP_ZMIN, ENDSTOPPULLDOWN_ZMIN) +#elif BOTH(ENDSTOPPULLUP_ZMIN, ENDSTOPPULLDOWN_ZMIN) #error "Enable only one of ENDSTOPPULLUP_Z_MIN or ENDSTOPPULLDOWN_Z_MIN." -#elif ALL(ENDSTOPPULLUP_IMIN, ENDSTOPPULLDOWN_IMIN) +#elif BOTH(ENDSTOPPULLUP_IMIN, ENDSTOPPULLDOWN_IMIN) #error "Enable only one of ENDSTOPPULLUP_I_MIN or ENDSTOPPULLDOWN_I_MIN." -#elif ALL(ENDSTOPPULLUP_JMIN, ENDSTOPPULLDOWN_JMIN) +#elif BOTH(ENDSTOPPULLUP_JMIN, ENDSTOPPULLDOWN_JMIN) #error "Enable only one of ENDSTOPPULLUP_J_MIN or ENDSTOPPULLDOWN_J_MIN." -#elif ALL(ENDSTOPPULLUP_KMIN, ENDSTOPPULLDOWN_KMIN) +#elif BOTH(ENDSTOPPULLUP_KMIN, ENDSTOPPULLDOWN_KMIN) #error "Enable only one of ENDSTOPPULLUP_K_MIN or ENDSTOPPULLDOWN_K_MIN." -#elif ALL(ENDSTOPPULLUP_UMIN, ENDSTOPPULLDOWN_UMIN) +#elif BOTH(ENDSTOPPULLUP_UMIN, ENDSTOPPULLDOWN_UMIN) #error "Enable only one of ENDSTOPPULLUP_U_MIN or ENDSTOPPULLDOWN_U_MIN." -#elif ALL(ENDSTOPPULLUP_VMIN, ENDSTOPPULLDOWN_VMIN) +#elif BOTH(ENDSTOPPULLUP_VMIN, ENDSTOPPULLDOWN_VMIN) #error "Enable only one of ENDSTOPPULLUP_V_MIN or ENDSTOPPULLDOWN_V_MIN." -#elif ALL(ENDSTOPPULLUP_WMIN, ENDSTOPPULLDOWN_WMIN) +#elif BOTH(ENDSTOPPULLUP_WMIN, ENDSTOPPULLDOWN_WMIN) #error "Enable only one of ENDSTOPPULLUP_W_MIN or ENDSTOPPULLDOWN_W_MIN." #endif @@ -345,8 +893,8 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L #if LCD_INFO_SCREEN_STYLE > 0 #if HAS_MARLINUI_U8GLIB || LCD_WIDTH < 20 || LCD_HEIGHT < 4 #error "Alternative LCD_INFO_SCREEN_STYLE requires 20x4 Character LCD." - #elif LCD_INFO_SCREEN_STYLE > 2 - #error "LCD_INFO_SCREEN_STYLE only has options 0 (Classic), 1 (Průša), and 2 (CNC)." + #elif LCD_INFO_SCREEN_STYLE > 1 + #error "LCD_INFO_SCREEN_STYLE only has options 0 and 1 at this time." #endif #endif @@ -354,7 +902,7 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L * Progress Bar */ #if ENABLED(LCD_PROGRESS_BAR) - #if NONE(HAS_MEDIA, SET_PROGRESS_MANUALLY) + #if NONE(SDSUPPORT, SET_PROGRESS_MANUALLY) #error "LCD_PROGRESS_BAR requires SDSUPPORT or SET_PROGRESS_MANUALLY." #elif NONE(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL) #error "LCD_PROGRESS_BAR only applies to HD44780 character LCD and TFTGLCD_PANEL_(SPI|I2C)." @@ -371,16 +919,16 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L #error "SET_PROGRESS_MANUALLY requires at least one of SET_PROGRESS_PERCENT, SET_REMAINING_TIME, SET_INTERACTION_TIME to be enabled." #endif -#if HAS_LCDPRINT && HAS_EXTRA_PROGRESS && LCD_HEIGHT < 4 - #error "Displays with fewer than 4 rows can't show progress values (e.g., SHOW_PROGRESS_PERCENT, SHOW_ELAPSED_TIME, SHOW_REMAINING_TIME, SHOW_INTERACTION_TIME)." +#if HAS_LCDPRINT && LCD_HEIGHT < 4 && ANY(SHOW_PROGRESS_PERCENT, SHOW_ELAPSED_TIME, SHOW_REMAINING_TIME, SHOW_INTERACTION_TIME) + #error "Displays with fewer than 4 rows of text can't show progress values." #endif #if !HAS_MARLINUI_MENU && ENABLED(SD_REPRINT_LAST_SELECTED_FILE) #error "SD_REPRINT_LAST_SELECTED_FILE currently requires a Marlin-native LCD menu." #endif -#if ANY(HAS_MARLINUI_MENU, TOUCH_UI_FTDI_EVE, EXTENSIBLE_UI, DWIN_LCD_PROUI) && !defined(MANUAL_FEEDRATE) - #error "MANUAL_FEEDRATE is required for ProUI, MarlinUI, ExtUI, or FTDI EVE Touch UI." +#if ANY(HAS_MARLINUI_MENU, TOUCH_UI_FTDI_EVE, EXTENSIBLE_UI) && !defined(MANUAL_FEEDRATE) + #error "MANUAL_FEEDRATE is required for MarlinUI, ExtUI, or FTDI EVE Touch UI." #endif /** @@ -394,10 +942,6 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L #error "CUSTOM_STATUS_SCREEN_IMAGE requires a 128x64 DOGM B/W Graphical LCD." #endif -#if ALL(STATUS_HEAT_PERCENT, STATUS_HEAT_POWER) - #error "Only enable STATUS_HEAT_PERCENT or STATUS_HEAT_POWER, but not both." -#endif - /** * LCD Lightweight Screen Style */ @@ -408,7 +952,7 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L /** * SD Card Settings */ -#if ALL(HAS_MEDIA, HAS_SD_DETECT, SD_CONNECTION_TYPICAL, ELB_FULL_GRAPHIC_CONTROLLER, HAS_MARLINUI_MENU) && SD_DETECT_STATE == LOW +#if ALL(SDSUPPORT, HAS_SD_DETECT, SD_CONNECTION_TYPICAL, ELB_FULL_GRAPHIC_CONTROLLER, HAS_MARLINUI_MENU) && SD_DETECT_STATE == LOW #error "SD_DETECT_STATE must be set HIGH for SD on the ELB_FULL_GRAPHIC_CONTROLLER." #endif #undef SD_CONNECTION_TYPICAL @@ -417,49 +961,39 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L * SD File Sorting */ #if ENABLED(SDCARD_SORT_ALPHA) - #if NONE(EXTENSIBLE_UI, HAS_MARLINUI_MENU, DWIN_CREALITY_LCD, DWIN_CREALITY_LCD_JYERSUI, DWIN_LCD_PROUI) - #error "SDCARD_SORT_ALPHA requires an LCD that supports it. (It doesn't apply to M20, etc.)" - #elif SDSORT_LIMIT > 256 + #if SDSORT_LIMIT > 256 #error "SDSORT_LIMIT must be 256 or smaller." #elif SDSORT_LIMIT < 10 #error "SDSORT_LIMIT should be greater than 9 to be useful." - #elif ENABLED(SDSORT_DYNAMIC_RAM) && DISABLED(SDSORT_USES_RAM) - #error "SDSORT_DYNAMIC_RAM requires SDSORT_USES_RAM (which reads the directory into RAM)." - #elif ENABLED(SDSORT_CACHE_NAMES) && DISABLED(SDSORT_USES_RAM) - #error "SDSORT_CACHE_NAMES requires SDSORT_USES_RAM (which reads the directory into RAM)." - #elif ENABLED(SDSORT_DYNAMIC_RAM) && DISABLED(SDSORT_CACHE_NAMES) - #error "SDSORT_DYNAMIC_RAM requires SDSORT_CACHE_NAMES." + #elif DISABLED(SDSORT_USES_RAM) + #if ENABLED(SDSORT_DYNAMIC_RAM) + #error "SDSORT_DYNAMIC_RAM requires SDSORT_USES_RAM (which reads the directory into RAM)." + #elif ENABLED(SDSORT_CACHE_NAMES) + #error "SDSORT_CACHE_NAMES requires SDSORT_USES_RAM (which reads the directory into RAM)." + #endif #endif #if ENABLED(SDSORT_CACHE_NAMES) && DISABLED(SDSORT_DYNAMIC_RAM) #if SDSORT_CACHE_VFATS < 2 #error "SDSORT_CACHE_VFATS must be 2 or greater!" - #elif SDSORT_CACHE_VFATS > VFAT_ENTRIES_LIMIT + #elif SDSORT_CACHE_VFATS > MAX_VFAT_ENTRIES #undef SDSORT_CACHE_VFATS - #define SDSORT_CACHE_VFATS VFAT_ENTRIES_LIMIT - #define SDSORT_CACHE_VFATS_WARNING 1 + #define SDSORT_CACHE_VFATS MAX_VFAT_ENTRIES + #warning "SDSORT_CACHE_VFATS was reduced to MAX_VFAT_ENTRIES!" #endif #endif #endif -/** - * Custom Event G-code - */ #if defined(EVENT_GCODE_SD_ABORT) && DISABLED(NOZZLE_PARK_FEATURE) static_assert(nullptr == strstr(EVENT_GCODE_SD_ABORT, "G27"), "NOZZLE_PARK_FEATURE is required to use G27 in EVENT_GCODE_SD_ABORT."); #endif -#if ANY(TC_GCODE_USE_GLOBAL_X, TC_GCODE_USE_GLOBAL_Y, TC_GCODE_USE_GLOBAL_Z) && ENABLED(NO_WORKSPACE_OFFSETS) - #error "TC_GCODE_USE_GLOBAL_* options are incompatible with NO_WORKSPACE_OFFSETS." -#endif /** * I2C Position Encoders */ #if ENABLED(I2C_POSITION_ENCODERS) - #if !ALL(BABYSTEPPING, BABYSTEP_XY) + #if !BOTH(BABYSTEPPING, BABYSTEP_XY) #error "I2C_POSITION_ENCODERS requires BABYSTEPPING and BABYSTEP_XY." - #elif DISABLED(EDITABLE_STEPS_PER_UNIT) - #error "EDITABLE_STEPS_PER_UNIT is required for I2C_POSITION_ENCODERS." #elif !WITHIN(I2CPE_ENCODER_CNT, 1, 5) #error "I2CPE_ENCODER_CNT must be between 1 and 5." #endif @@ -471,21 +1005,21 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L #if ENABLED(BABYSTEPPING) #if ENABLED(SCARA) #error "BABYSTEPPING is not implemented for SCARA yet." - #elif ENABLED(BABYSTEP_XY) && ANY(MARKFORGED_XY, MARKFORGED_YX) + #elif ENABLED(BABYSTEP_XY) && EITHER(MARKFORGED_XY, MARKFORGED_YX) #error "BABYSTEPPING only implemented for Z axis on MarkForged." - #elif ALL(DELTA, BABYSTEP_XY) + #elif BOTH(DELTA, BABYSTEP_XY) #error "BABYSTEPPING only implemented for Z axis on deltabots." - #elif ALL(BABYSTEP_ZPROBE_OFFSET, MESH_BED_LEVELING) + #elif BOTH(BABYSTEP_ZPROBE_OFFSET, MESH_BED_LEVELING) #error "MESH_BED_LEVELING and BABYSTEP_ZPROBE_OFFSET is not a valid combination" #elif ENABLED(BABYSTEP_ZPROBE_OFFSET) && !HAS_BED_PROBE #error "BABYSTEP_ZPROBE_OFFSET requires a probe." - #elif ENABLED(BABYSTEP_GFX_OVERLAY) && NONE(HAS_MARLINUI_U8GLIB, IS_DWIN_MARLINUI) - #error "BABYSTEP_GFX_OVERLAY requires a Graphical LCD." - #elif ENABLED(BABYSTEP_GFX_OVERLAY) && DISABLED(BABYSTEP_ZPROBE_OFFSET) - #error "BABYSTEP_GFX_OVERLAY requires a BABYSTEP_ZPROBE_OFFSET." + #elif ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY) && NONE(HAS_MARLINUI_U8GLIB, IS_DWIN_MARLINUI) + #error "BABYSTEP_ZPROBE_GFX_OVERLAY requires a Graphical LCD." + #elif ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY) && DISABLED(BABYSTEP_ZPROBE_OFFSET) + #error "BABYSTEP_ZPROBE_GFX_OVERLAY requires a BABYSTEP_ZPROBE_OFFSET." #elif ENABLED(BABYSTEP_HOTEND_Z_OFFSET) && !HAS_HOTEND_OFFSET #error "BABYSTEP_HOTEND_Z_OFFSET requires 2 or more HOTENDS." - #elif ALL(BABYSTEP_ALWAYS_AVAILABLE, MOVE_Z_WHEN_IDLE) + #elif BOTH(BABYSTEP_ALWAYS_AVAILABLE, MOVE_Z_WHEN_IDLE) #error "BABYSTEP_ALWAYS_AVAILABLE and MOVE_Z_WHEN_IDLE are incompatible." #elif !defined(BABYSTEP_MULTIPLICATOR_Z) #error "BABYSTEPPING requires BABYSTEP_MULTIPLICATOR_Z." @@ -523,26 +1057,87 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L #error "FIL_RUNOUT3_PIN is required with NUM_RUNOUT_SENSORS >= 3." #elif NUM_RUNOUT_SENSORS >= 2 && !PIN_EXISTS(FIL_RUNOUT2) #error "FIL_RUNOUT2_PIN is required with NUM_RUNOUT_SENSORS >= 2." - #elif ALL(FIL_RUNOUT1_PULLUP, FIL_RUNOUT1_PULLDOWN) + #elif BOTH(FIL_RUNOUT1_PULLUP, FIL_RUNOUT1_PULLDOWN) #error "You can't enable FIL_RUNOUT1_PULLUP and FIL_RUNOUT1_PULLDOWN at the same time." - #elif ALL(FIL_RUNOUT2_PULLUP, FIL_RUNOUT2_PULLDOWN) + #elif BOTH(FIL_RUNOUT2_PULLUP, FIL_RUNOUT2_PULLDOWN) #error "You can't enable FIL_RUNOUT2_PULLUP and FIL_RUNOUT2_PULLDOWN at the same time." - #elif ALL(FIL_RUNOUT3_PULLUP, FIL_RUNOUT3_PULLDOWN) + #elif BOTH(FIL_RUNOUT3_PULLUP, FIL_RUNOUT3_PULLDOWN) #error "You can't enable FIL_RUNOUT3_PULLUP and FIL_RUNOUT3_PULLDOWN at the same time." - #elif ALL(FIL_RUNOUT4_PULLUP, FIL_RUNOUT4_PULLDOWN) + #elif BOTH(FIL_RUNOUT4_PULLUP, FIL_RUNOUT4_PULLDOWN) #error "You can't enable FIL_RUNOUT4_PULLUP and FIL_RUNOUT4_PULLDOWN at the same time." - #elif ALL(FIL_RUNOUT5_PULLUP, FIL_RUNOUT5_PULLDOWN) + #elif BOTH(FIL_RUNOUT5_PULLUP, FIL_RUNOUT5_PULLDOWN) #error "You can't enable FIL_RUNOUT5_PULLUP and FIL_RUNOUT5_PULLDOWN at the same time." - #elif ALL(FIL_RUNOUT6_PULLUP, FIL_RUNOUT6_PULLDOWN) + #elif BOTH(FIL_RUNOUT6_PULLUP, FIL_RUNOUT6_PULLDOWN) #error "You can't enable FIL_RUNOUT6_PULLUP and FIL_RUNOUT6_PULLDOWN at the same time." - #elif ALL(FIL_RUNOUT7_PULLUP, FIL_RUNOUT7_PULLDOWN) + #elif BOTH(FIL_RUNOUT7_PULLUP, FIL_RUNOUT7_PULLDOWN) #error "You can't enable FIL_RUNOUT7_PULLUP and FIL_RUNOUT7_PULLDOWN at the same time." - #elif ALL(FIL_RUNOUT8_PULLUP, FIL_RUNOUT8_PULLDOWN) + #elif BOTH(FIL_RUNOUT8_PULLUP, FIL_RUNOUT8_PULLDOWN) #error "You can't enable FIL_RUNOUT8_PULLUP and FIL_RUNOUT8_PULLDOWN at the same time." - #elif FILAMENT_RUNOUT_DISTANCE_MM < 0 - #error "FILAMENT_RUNOUT_DISTANCE_MM must be greater than or equal to zero." - #elif DISABLED(ADVANCED_PAUSE_FEATURE) && defined(FILAMENT_RUNOUT_SCRIPT) - static_assert(nullptr == strstr(FILAMENT_RUNOUT_SCRIPT, "M600"), "FILAMENT_RUNOUT_SCRIPT cannot make use of M600 unless ADVANCED_PAUSE_FEATURE is enabled"); + #elif DISABLED(ADVANCED_PAUSE_FEATURE) + static_assert(nullptr == strstr(FILAMENT_RUNOUT_SCRIPT, "M600"), "ADVANCED_PAUSE_FEATURE is required to use M600 with FILAMENT_RUNOUT_SENSOR."); + #elif defined(FIL_RUNOUT_ENABLED_DEFAULT) + #error "FIL_RUNOUT_ENABLED_DEFAULT is now set with the FILAMENT_RUNOUT_ENABLED array." + #elif defined(FILAMENT_RUNOUT_DISTANCE_MM) + #error "FILAMENT_RUNOUT_DISTANCE_MM is now set with the FIL_RUNOUT_DISTANCE_MM array." + #elif defined(FIL_RUNOUT_STATE) || defined(FIL_RUNOUT2_STATE) || defined(FIL_RUNOUT3_STATE) || defined(FIL_RUNOUT4_STATE) || defined(FIL_RUNOUT5_STATE) || defined(FIL_RUNOUT6_STATE) || defined(FIL_RUNOUT7_STATE) || defined(FIL_RUNOUT8_STATE) + #ifdef FIL_RUNOUT_STATE + #if FIL_RUNOUT_STATE + #error "FIL_RUNOUT_STATE HIGH is now set with FIL_RUNOUT_MODE { 2 ... }." + #else + #error "FIL_RUNOUT_STATE LOW is now set with FIL_RUNOUT_MODE { 1 ... }." + #endif + #endif + #ifdef FIL_RUNOUT2_STATE + #if FIL_RUNOUT2_STATE + #error "FIL_RUNOUT2_STATE HIGH is now set with FIL_RUNOUT_MODE { n, 2 ... }." + #else + #error "FIL_RUNOUT2_STATE LOW is now set with FIL_RUNOUT_MODE { n, 1 ... }." + #endif + #endif + #ifdef FIL_RUNOUT3_STATE + #if FIL_RUNOUT3_STATE + #error "FIL_RUNOUT3_STATE HIGH is now set with FIL_RUNOUT_MODE { n, n, 2 ... }." + #else + #error "FIL_RUNOUT3_STATE LOW is now set with FIL_RUNOUT_MODE { n, n, 1 ... }." + #endif + #endif + #ifdef FIL_RUNOUT4_STATE + #if FIL_RUNOUT4_STATE + #error "FIL_RUNOUT4_STATE HIGH is now set with FIL_RUNOUT_MODE { n, n, n, 2 ... }." + #else + #error "FIL_RUNOUT4_STATE LOW is now set with FIL_RUNOUT_MODE { n, n, n, 1 ... }." + #endif + #endif + #ifdef FIL_RUNOUT5_STATE + #if FIL_RUNOUT5_STATE + #error "FIL_RUNOUT5_STATE HIGH is now set with FIL_RUNOUT_MODE { n, n, n, n, 2 ... }." + #else + #error "FIL_RUNOUT5_STATE LOW is now set with FIL_RUNOUT_MODE { n, n, n, n, 1 ... }." + #endif + #endif + #ifdef FIL_RUNOUT6_STATE + #if FIL_RUNOUT6_STATE + #error "FIL_RUNOUT6_STATE HIGH is now set with FIL_RUNOUT_MODE { n, n, n, n, n, 2 ... }." + #else + #error "FIL_RUNOUT6_STATE LOW is now set with FIL_RUNOUT_MODE { n, n, n, n, n, 1 ... }." + #endif + #endif + #ifdef FIL_RUNOUT7_STATE + #if FIL_RUNOUT7_STATE + #error "FIL_RUNOUT7_STATE HIGH is now set with FIL_RUNOUT_MODE { n, n, n, n, n, n, 2 ... }." + #else + #error "FIL_RUNOUT7_STATE LOW is now set with FIL_RUNOUT_MODE { n, n, n, n, n, n, 1 ... }." + #endif + #endif + #ifdef FIL_RUNOUT8_STATE + #if FIL_RUNOUT8_STATE + #error "FIL_RUNOUT8_STATE HIGH is now set with FIL_RUNOUT_MODE { n, n, n, n, n, n, n, 2 ... }." + #else + #error "FIL_RUNOUT8_STATE LOW is now set with FIL_RUNOUT_MODE { n, n, n, n, n, n, n, 1 ... }." + #endif + #endif + #elif ENABLED(FILAMENT_MOTION_SENSOR) + #error "FILAMENT_MOTION_SENSOR is now set with FIL_RUNOUT_MODE { 7 ... }." #endif #endif @@ -558,8 +1153,8 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L #error "ADVANCED_PAUSE_FEATURE requires FILAMENT_UNLOAD_PURGE_FEEDRATE." #elif ENABLED(EXTRUDER_RUNOUT_PREVENT) #error "EXTRUDER_RUNOUT_PREVENT is incompatible with ADVANCED_PAUSE_FEATURE." - #elif ENABLED(PARK_HEAD_ON_PAUSE) && NONE(HAS_MEDIA, IS_NEWPANEL, EMERGENCY_PARSER) - #error "PARK_HEAD_ON_PAUSE requires HAS_MEDIA, EMERGENCY_PARSER, or an LCD controller." + #elif ENABLED(PARK_HEAD_ON_PAUSE) && NONE(SDSUPPORT, IS_NEWPANEL, EMERGENCY_PARSER) + #error "PARK_HEAD_ON_PAUSE requires SDSUPPORT, EMERGENCY_PARSER, or an LCD controller." #elif ENABLED(HOME_BEFORE_FILAMENT_CHANGE) && DISABLED(PAUSE_PARK_NO_STEPPER_TIMEOUT) #error "HOME_BEFORE_FILAMENT_CHANGE requires PAUSE_PARK_NO_STEPPER_TIMEOUT." #elif ENABLED(PREVENT_LENGTHY_EXTRUDE) && FILAMENT_CHANGE_UNLOAD_LENGTH > EXTRUDE_MAXLENGTH @@ -573,11 +1168,11 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L #if ENABLED(NOZZLE_PARK_FEATURE) constexpr float npp[] = NOZZLE_PARK_POINT; - static_assert(COUNT(npp) == _MIN(NUM_AXES, XYZ), "NOZZLE_PARK_POINT requires coordinates for enabled axes, but only up to X,Y,Z."); + static_assert(COUNT(npp) == XYZ, "NOZZLE_PARK_POINT requires X, Y, and Z values."); constexpr xyz_pos_t npp_xyz = NOZZLE_PARK_POINT; static_assert(WITHIN(npp_xyz.x, X_MIN_POS, X_MAX_POS), "NOZZLE_PARK_POINT.X is out of bounds (X_MIN_POS, X_MAX_POS)."); - static_assert(TERN1(HAS_Y_AXIS, WITHIN(npp_xyz.y, Y_MIN_POS, Y_MAX_POS)), "NOZZLE_PARK_POINT.Y is out of bounds (Y_MIN_POS, Y_MAX_POS)."); - static_assert(TERN1(HAS_Z_AXIS, WITHIN(npp_xyz.z, Z_MIN_POS, Z_MAX_POS)), "NOZZLE_PARK_POINT.Z is out of bounds (Z_MIN_POS, Z_MAX_POS)."); + static_assert(WITHIN(npp_xyz.y, Y_MIN_POS, Y_MAX_POS), "NOZZLE_PARK_POINT.Y is out of bounds (Y_MIN_POS, Y_MAX_POS)."); + static_assert(WITHIN(npp_xyz.z, Z_MIN_POS, Z_MAX_POS), "NOZZLE_PARK_POINT.Z is out of bounds (Z_MIN_POS, Z_MAX_POS)."); #endif /** @@ -590,10 +1185,27 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L /** * Individual axis homing is useless for DELTAS */ -#if ALL(INDIVIDUAL_AXIS_HOMING_MENU, DELTA) +#if BOTH(INDIVIDUAL_AXIS_HOMING_MENU, DELTA) #error "INDIVIDUAL_AXIS_HOMING_MENU is incompatible with DELTA kinematics." #endif +/** + * Sanity checking for all Průša MMU + */ +#ifdef SNMM + #error "SNMM is obsolete. Define MMU_MODEL as PRUSA_MMU1 instead." +#elif ENABLED(MK2_MULTIPLEXER) + #error "MK2_MULTIPLEXER is obsolete. Define MMU_MODEL as PRUSA_MMU1 instead." +#elif ENABLED(PRUSA_MMU2) + #error "PRUSA_MMU2 is obsolete. Define MMU_MODEL as PRUSA_MMU2 instead." +#elif ENABLED(PRUSA_MMU2_S_MODE) + #error "PRUSA_MMU2_S_MODE is obsolete. Define MMU_MODEL as PRUSA_MMU2S instead." +#elif ENABLED(SMUFF_EMU_MMU2) + #error "SMUFF_EMU_MMU2 is obsolete. Define MMU_MODEL as EXTENDABLE_EMU_MMU2 instead." +#elif ENABLED(SMUFF_EMU_MMU2S) + #error "SMUFF_EMU_MMU2S is obsolete. Define MMU_MODEL as EXTENDABLE_EMU_MMU2S instead." +#endif + /** * Multi-Material-Unit 2 / EXTENDABLE_EMU_MMU2 requirements */ @@ -614,7 +1226,7 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L #elif ENABLED(MMU2_MENUS) && !HAS_MARLINUI_MENU #error "MMU2_MENUS requires an LCD supporting MarlinUI." #elif DISABLED(ADVANCED_PAUSE_FEATURE) - static_assert(nullptr == strstr(MMU2_FILAMENT_RUNOUT_SCRIPT, "M600"), "MMU2_FILAMENT_RUNOUT_SCRIPT cannot make use of M600 unless ADVANCED_PAUSE_FEATURE is enabled"); + static_assert(nullptr == strstr(MMU2_FILAMENT_RUNOUT_SCRIPT, "M600"), "ADVANCED_PAUSE_FEATURE is required to use M600 with PRUSA_MMU2(S) / HAS_EXTENDABLE_MMU(S)."); #endif #endif @@ -623,12 +1235,10 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L */ #if HAS_MULTI_EXTRUDER - #ifndef MAX_EXTRUDERS - #if HAS_EXTENDABLE_MMU - #define MAX_EXTRUDERS 15 - #else - #define MAX_EXTRUDERS 8 - #endif + #if HAS_EXTENDABLE_MMU + #define MAX_EXTRUDERS 15 + #else + #define MAX_EXTRUDERS 8 #endif static_assert(EXTRUDERS <= MAX_EXTRUDERS, "Marlin supports a maximum of " STRINGIFY(MAX_EXTRUDERS) " EXTRUDERS."); #undef MAX_EXTRUDERS @@ -679,34 +1289,20 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L /** * A Dual Nozzle carriage with switching servo */ -#if ALL(SWITCHING_NOZZLE, MECHANICAL_SWITCHING_NOZZLE) - #error "Enable only one of SWITCHING_NOZZLE or MECHANICAL_SWITCHING_NOZZLE." -#elif ENABLED(MECHANICAL_SWITCHING_NOZZLE) - #if EXTRUDERS != 2 - #error "MECHANICAL_SWITCHING_NOZZLE requires exactly 2 EXTRUDERS." - #elif ENABLED(DUAL_X_CARRIAGE) - #error "MECHANICAL_SWITCHING_NOZZLE and DUAL_X_CARRIAGE are incompatible." - #elif ENABLED(SINGLENOZZLE) - #error "MECHANICAL_SWITCHING_NOZZLE and SINGLENOZZLE are incompatible." - #elif HAS_PRUSA_MMU2 - #error "MECHANICAL_SWITCHING_NOZZLE and PRUSA_MMU2(S) are incompatible." - #elif !defined(EVENT_GCODE_TOOLCHANGE_T0) - #error "MECHANICAL_SWITCHING_NOZZLE requires EVENT_GCODE_TOOLCHANGE_T0." - #elif !defined(EVENT_GCODE_TOOLCHANGE_T1) - #error "MECHANICAL_SWITCHING_NOZZLE requires EVENT_GCODE_TOOLCHANGE_T1." - #endif -#elif ENABLED(SWITCHING_NOZZLE) - #if EXTRUDERS != 2 - #error "SWITCHING_NOZZLE requires exactly 2 EXTRUDERS." - #elif ENABLED(DUAL_X_CARRIAGE) +#if ENABLED(SWITCHING_NOZZLE) + #if ENABLED(DUAL_X_CARRIAGE) #error "SWITCHING_NOZZLE and DUAL_X_CARRIAGE are incompatible." #elif ENABLED(SINGLENOZZLE) #error "SWITCHING_NOZZLE and SINGLENOZZLE are incompatible." #elif HAS_PRUSA_MMU2 #error "SWITCHING_NOZZLE and PRUSA_MMU2(S) are incompatible." + #elif EXTRUDERS != 2 + #error "SWITCHING_NOZZLE requires exactly 2 EXTRUDERS." #elif NUM_SERVOS < 1 #error "SWITCHING_NOZZLE requires NUM_SERVOS >= 1." - #elif !defined(SWITCHING_NOZZLE_SERVO_NR) + #endif + + #ifndef SWITCHING_NOZZLE_SERVO_NR #error "SWITCHING_NOZZLE requires SWITCHING_NOZZLE_SERVO_NR." #elif SWITCHING_NOZZLE_SERVO_NR == 0 && !PIN_EXISTS(SERVO0) #error "SERVO0_PIN must be defined for your SWITCHING_NOZZLE." @@ -717,6 +1313,7 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L #elif SWITCHING_NOZZLE_SERVO_NR == 3 && !PIN_EXISTS(SERVO3) #error "SERVO3_PIN must be defined for your SWITCHING_NOZZLE." #endif + #ifdef SWITCHING_NOZZLE_E1_SERVO_NR #if SWITCHING_NOZZLE_E1_SERVO_NR == SWITCHING_NOZZLE_SERVO_NR #error "SWITCHING_NOZZLE_E1_SERVO_NR must be different from SWITCHING_NOZZLE_SERVO_NR." @@ -730,26 +1327,14 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L #error "SERVO3_PIN must be defined for your SWITCHING_NOZZLE." #endif #endif -#endif // SWITCHING_NOZZLE +#endif /** * Single Stepper Dual Extruder with switching servo */ -#if ALL(SWITCHING_EXTRUDER, MECHANICAL_SWITCHING_EXTRUDER) - #error "Enable only one of SWITCHING_EXTRUDER or MECHANICAL_SWITCHING_EXTRUDER." -#elif ENABLED(MECHANICAL_SWITCHING_EXTRUDER) - #if EXTRUDERS < 2 - #error "MECHANICAL_SWITCHING_EXTRUDER requires EXTRUDERS >= 2." - #elif !defined(EVENT_GCODE_TOOLCHANGE_T0) - #error "MECHANICAL_SWITCHING_EXTRUDER requires EVENT_GCODE_TOOLCHANGE_T0." - #elif !defined(EVENT_GCODE_TOOLCHANGE_T1) - #error "MECHANICAL_SWITCHING_EXTRUDER requires EVENT_GCODE_TOOLCHANGE_T1." - #endif -#elif ENABLED(SWITCHING_EXTRUDER) +#if ENABLED(SWITCHING_EXTRUDER) #if NUM_SERVOS < 1 #error "SWITCHING_EXTRUDER requires NUM_SERVOS >= 1." - #elif !defined(SWITCHING_EXTRUDER_SERVO_NR) - #error "SWITCHING_EXTRUDER requires SWITCHING_EXTRUDER_SERVO_NR." #elif SWITCHING_EXTRUDER_SERVO_NR == 0 && !PIN_EXISTS(SERVO0) #error "SERVO0_PIN must be defined for your SWITCHING_EXTRUDER." #elif SWITCHING_EXTRUDER_SERVO_NR == 1 && !PIN_EXISTS(SERVO1) @@ -773,10 +1358,8 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L #elif SWITCHING_EXTRUDER_E23_SERVO_NR == SWITCHING_EXTRUDER_SERVO_NR #error "SWITCHING_EXTRUDER_E23_SERVO_NR should be a different extruder from SWITCHING_EXTRUDER_SERVO_NR." #endif - #elif EXTRUDERS < 2 - #error "SWITCHING_EXTRUDER requires EXTRUDERS >= 2." #endif -#endif // SWITCHING_EXTRUDER +#endif /** * Mixing Extruder requirements @@ -788,14 +1371,12 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L #error "You must set MIXING_STEPPERS >= 2 for a mixing extruder." #elif ENABLED(FILAMENT_WIDTH_SENSOR) #error "MIXING_EXTRUDER is incompatible with FILAMENT_WIDTH_SENSOR. Comment out this line to use it anyway." - #elif HAS_SWITCHING_EXTRUDER - #error "MIXING_EXTRUDER is incompatible with (MECHANICAL_)SWITCHING_EXTRUDER." + #elif ENABLED(SWITCHING_EXTRUDER) + #error "Please select either MIXING_EXTRUDER or SWITCHING_EXTRUDER, not both." #elif ENABLED(SINGLENOZZLE) #error "MIXING_EXTRUDER is incompatible with SINGLENOZZLE." - #elif ENABLED(DISABLE_OTHER_EXTRUDERS) - #error "MIXING_EXTRUDER is incompatible with DISABLE_OTHER_EXTRUDERS." - #elif HAS_FILAMENT_RUNOUT_DISTANCE - #error "MIXING_EXTRUDER is incompatible with FILAMENT_RUNOUT_DISTANCE_MM." + #elif ENABLED(DISABLE_INACTIVE_EXTRUDER) + #error "MIXING_EXTRUDER is incompatible with DISABLE_INACTIVE_EXTRUDER." #endif #endif @@ -807,8 +1388,8 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L #error "E_DUAL_STEPPER_DRIVERS can only be used with EXTRUDERS set to 1." #elif ENABLED(MIXING_EXTRUDER) #error "E_DUAL_STEPPER_DRIVERS is incompatible with MIXING_EXTRUDER." - #elif HAS_SWITCHING_EXTRUDER - #error "E_DUAL_STEPPER_DRIVERS is incompatible with (MECHANICAL_)SWITCHING_EXTRUDER." + #elif ENABLED(SWITCHING_EXTRUDER) + #error "E_DUAL_STEPPER_DRIVERS is incompatible with SWITCHING_EXTRUDER." #endif #endif @@ -818,29 +1399,19 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L #if ENABLED(LIN_ADVANCE) #if DISTINCT_E > 1 constexpr float lak[] = ADVANCE_K; - static_assert(COUNT(lak) <= DISTINCT_E, "The ADVANCE_K array has too many elements (i.e., more than " STRINGIFY(DISTINCT_E) ")."); + static_assert(COUNT(lak) < DISTINCT_E, "The ADVANCE_K array has too many elements (i.e., more than " STRINGIFY(DISTINCT_E) ")."); #define _LIN_ASSERT(N) static_assert(N >= COUNT(lak) || WITHIN(lak[N], 0, 10), "ADVANCE_K values must be from 0 to 10 (Changed in LIN_ADVANCE v1.5, Marlin 1.1.9)."); REPEAT(DISTINCT_E, _LIN_ASSERT) #undef _LIN_ASSERT #else static_assert(WITHIN(ADVANCE_K, 0, 10), "ADVANCE_K must be from 0 to 10 (Changed in LIN_ADVANCE v1.5, Marlin 1.1.9)."); #endif - - #if ENABLED(DIRECT_STEPPING) - #error "DIRECT_STEPPING is incompatible with LIN_ADVANCE. (Extrusion is controlled externally by the Step Daemon.)" - #endif -#endif - -/** - * Nonlinear Extrusion requirements - */ -#if ENABLED(NONLINEAR_EXTRUSION) - #if DISABLED(ADAPTIVE_STEP_SMOOTHING) - #error "ADAPTIVE_STEP_SMOOTHING is required for NONLINEAR_EXTRUSION." - #elif HAS_MULTI_EXTRUDER - #error "NONLINEAR_EXTRUSION doesn't currently support multi-extruder setups." - #elif DISABLED(CPU_32_BIT) - #error "NONLINEAR_EXTRUSION requires a 32-bit CPU." + #if ENABLED(S_CURVE_ACCELERATION) && DISABLED(EXPERIMENTAL_SCURVE) + #error "LIN_ADVANCE and S_CURVE_ACCELERATION may not play well together! Enable EXPERIMENTAL_SCURVE to continue." + #elif ENABLED(DIRECT_STEPPING) + #error "DIRECT_STEPPING is incompatible with LIN_ADVANCE. Enable in external planner if possible." + #elif NONE(HAS_JUNCTION_DEVIATION, ALLOW_LOW_EJERK) && defined(DEFAULT_EJERK) + static_assert(DEFAULT_EJERK >= 10, "It is strongly recommended to set DEFAULT_EJERK >= 10 when using LIN_ADVANCE. Enable ALLOW_LOW_EJERK to bypass this alert (e.g., for direct drive)."); #endif #endif @@ -854,7 +1425,7 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L /** * (Magnetic) Parking Extruder requirements */ -#if ANY(PARKING_EXTRUDER, MAGNETIC_PARKING_EXTRUDER) +#if EITHER(PARKING_EXTRUDER, MAGNETIC_PARKING_EXTRUDER) #if ENABLED(EXT_SOLENOID) #error "(MAGNETIC_)PARKING_EXTRUDER and EXT_SOLENOID are incompatible. (Pins are used twice.)" #elif EXTRUDERS != 2 @@ -912,7 +1483,7 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L /** * Magnetic / Electromagnetic Switching Toolhead requirements */ -#if ANY(MAGNETIC_SWITCHING_TOOLHEAD, ELECTROMAGNETIC_SWITCHING_TOOLHEAD) +#if EITHER(MAGNETIC_SWITCHING_TOOLHEAD, ELECTROMAGNETIC_SWITCHING_TOOLHEAD) #ifndef SWITCHING_TOOLHEAD_Y_POS #error "(ELECTRO)?MAGNETIC_SWITCHING_TOOLHEAD requires SWITCHING_TOOLHEAD_Y_POS" #elif !defined(SWITCHING_TOOLHEAD_X_POS) @@ -938,19 +1509,14 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L /** * Part-Cooling Fan Multiplexer requirements */ -#if HAS_FANMUX && !HAS_FAN0 - #error "FAN0_PIN must be defined to use Fan Multiplexing." -#elif PIN_EXISTS(FANMUX1) && !PIN_EXISTS(FANMUX0) - #error "FANMUX0_PIN must be set before FANMUX1_PIN can be set." -#elif PIN_EXISTS(FANMUX2) && !PINS_EXIST(FANMUX0, FANMUX1) +#if PIN_EXISTS(FANMUX1) + #if !HAS_FANMUX + #error "FANMUX0_PIN must be set before FANMUX1_PIN can be set." + #endif +#elif PIN_EXISTS(FANMUX2) #error "FANMUX0_PIN and FANMUX1_PIN must be set before FANMUX2_PIN can be set." #endif -// PID Fan Scaling requires a fan -#if defined(PID_FAN_SCALING) && !HAS_FAN - #error "PID_FAN_SCALING needs at least one fan enabled." -#endif - /** * Limited user-controlled fans */ @@ -961,7 +1527,9 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L /** * Limited number of servos */ -static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) is too large. The selected board only has " STRINGIFY(NUM_SERVO_PLUGS) " servos."); +#if NUM_SERVOS > NUM_SERVO_PLUGS + #error "The selected board doesn't support enough servos for your configuration. Reduce NUM_SERVOS." +#endif /** * Servo deactivation depends on servo endstops, switching nozzle, or switching extruder @@ -980,16 +1548,12 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i /** * Extruder temperature control algorithm - There can be only one! */ -#if ALL(PIDTEMP, MPCTEMP) +#if BOTH(PIDTEMP, MPCTEMP) #error "Only enable PIDTEMP or MPCTEMP, but not both." - #undef MPCTEMP - #undef MPC_AUTOTUNE - #undef MPC_EDIT_MENU - #undef MPC_AUTOTUNE_MENU #endif #if ENABLED(MPC_INCLUDE_FAN) - #if !HAS_FAN + #if FAN_COUNT < 1 #error "MPC_INCLUDE_FAN requires at least one fan." #endif #if FAN_COUNT < HOTENDS @@ -1004,15 +1568,10 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i /** * Bed Heating Options - PID vs Limit Switching */ -#if ALL(PIDTEMPBED, BED_LIMIT_SWITCHING) +#if BOTH(PIDTEMPBED, BED_LIMIT_SWITCHING) #error "To use BED_LIMIT_SWITCHING you must disable PIDTEMPBED." #endif -// Fan Kickstart power -#if FAN_KICKSTART_TIME && !WITHIN(FAN_KICKSTART_POWER, 64, 255) - #error "FAN_KICKSTART_POWER must be an integer from 64 to 255." -#endif - /** * Synchronous M106/M107 checks */ @@ -1027,38 +1586,23 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i /** * Chamber Heating Options - PID vs Limit Switching */ -#if ALL(PIDTEMPCHAMBER, CHAMBER_LIMIT_SWITCHING) +#if BOTH(PIDTEMPCHAMBER, CHAMBER_LIMIT_SWITCHING) #error "To use CHAMBER_LIMIT_SWITCHING you must disable PIDTEMPCHAMBER." #endif /** - * AUTOTEMP - */ -#if ENABLED(AUTOTEMP) - #ifndef AUTOTEMP_MIN - #error "AUTOTEMP requires AUTOTEMP_MIN." - #elif !defined(AUTOTEMP_MAX) - #error "AUTOTEMP requires AUTOTEMP_MAX." - #elif !defined(AUTOTEMP_FACTOR) - #error "AUTOTEMP requires AUTOTEMP_FACTOR." - #elif AUTOTEMP_MAX < AUTOTEMP_MIN - #error "AUTOTEMP_MAX must be greater than or equal to AUTOTEMP_MIN." - #endif -#endif - -/** - * Features that require a min/max/specific steppers / axes to be enabled. + * Features that require a min/max/specific NUM_AXES */ #if HAS_LEVELING && !HAS_Z_AXIS #error "Leveling in Marlin requires three or more axes, with Z as the vertical axis." #elif ENABLED(CNC_WORKSPACE_PLANES) && !HAS_Z_AXIS - #error "CNC_WORKSPACE_PLANES currently requires a Z axis" + #error "CNC_WORKSPACE_PLANES currently requires NUM_AXES >= 3" #elif ENABLED(DIRECT_STEPPING) && NUM_AXES > XYZ - #error "DIRECT_STEPPING does not currently support more than 3 axes (i.e., XYZ)." -#elif ENABLED(FOAMCUTTER_XYUV) && !(HAS_I_AXIS && HAS_J_AXIS) - #error "FOAMCUTTER_XYUV requires I and J steppers to be enabled." + #error "DIRECT_STEPPING currently requires NUM_AXES 3" +#elif ENABLED(FOAMCUTTER_XYUV) && NUM_AXES < 5 + #error "FOAMCUTTER_XYUV requires NUM_AXES >= 5." #elif ENABLED(LINEAR_ADVANCE) && HAS_I_AXIS - #error "LINEAR_ADVANCE does not currently support the inclusion of an I axis." + #error "LINEAR_ADVANCE currently requires NUM_AXES <= 3." #endif /** @@ -1066,13 +1610,11 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i */ #if HAS_I_AXIS #if !defined(I_MIN_POS) || !defined(I_MAX_POS) - #error "I_MIN_POS and I_MAX_POS are required for the I axis." + #error "I_MIN_POS and I_MAX_POS are required with NUM_AXES >= 4." #elif !defined(I_HOME_DIR) - #error "I_HOME_DIR is required for the I axis." + #error "I_HOME_DIR is required with NUM_AXES >= 4." #elif HAS_I_ENABLE && !defined(I_ENABLE_ON) - #error "I_ENABLE_ON is required for the I stepper." - #elif !defined(INVERT_I_DIR) - #error "INVERT_I_DIR is required for the I stepper." + #error "I_ENABLE_ON is required for your I driver with NUM_AXES >= 4." #endif #endif #if HAS_J_AXIS @@ -1081,13 +1623,11 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #elif ENABLED(AXIS5_ROTATES) && DISABLED(AXIS4_ROTATES) #error "AXIS5_ROTATES requires AXIS4_ROTATES." #elif !defined(J_MIN_POS) || !defined(J_MAX_POS) - #error "J_MIN_POS and J_MAX_POS are required for the J axis." + #error "J_MIN_POS and J_MAX_POS are required with NUM_AXES >= 5." #elif !defined(J_HOME_DIR) - #error "J_HOME_DIR is required for the J axis." + #error "J_HOME_DIR is required with NUM_AXES >= 5." #elif HAS_J_ENABLE && !defined(J_ENABLE_ON) - #error "J_ENABLE_ON is required for the J stepper." - #elif !defined(INVERT_J_DIR) - #error "INVERT_J_DIR is required for the J stepper." + #error "J_ENABLE_ON is required for your J driver with NUM_AXES >= 5." #endif #endif #if HAS_K_AXIS @@ -1096,13 +1636,11 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #elif ENABLED(AXIS6_ROTATES) && DISABLED(AXIS5_ROTATES) #error "AXIS6_ROTATES requires AXIS5_ROTATES." #elif !defined(K_MIN_POS) || !defined(K_MAX_POS) - #error "K_MIN_POS and K_MAX_POS are required for the K axis." + #error "K_MIN_POS and K_MAX_POS are required with NUM_AXES >= 6." #elif !defined(K_HOME_DIR) - #error "K_HOME_DIR is required for the K axis." + #error "K_HOME_DIR is required with NUM_AXES >= 6." #elif HAS_K_ENABLE && !defined(K_ENABLE_ON) - #error "K_ENABLE_ON is required for the K stepper." - #elif !defined(INVERT_K_DIR) - #error "INVERT_K_DIR is required for the K stepper." + #error "K_ENABLE_ON is required for your K driver with NUM_AXES >= 6." #endif #endif #if HAS_U_AXIS @@ -1111,13 +1649,11 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #elif ENABLED(AXIS7_ROTATES) && DISABLED(AXIS6_ROTATES) #error "AXIS7_ROTATES requires AXIS6_ROTATES." #elif !defined(U_MIN_POS) || !defined(U_MAX_POS) - #error "U_MIN_POS and U_MAX_POS are required for the U axis." + #error "U_MIN_POS and U_MAX_POS are required with NUM_AXES >= 7." #elif !defined(U_HOME_DIR) - #error "U_HOME_DIR is required for the U axis." + #error "U_HOME_DIR is required with NUM_AXES >= 7." #elif HAS_U_ENABLE && !defined(U_ENABLE_ON) - #error "U_ENABLE_ON is required for the U stepper." - #elif !defined(INVERT_U_DIR) - #error "INVERT_U_DIR is required for the U stepper." + #error "U_ENABLE_ON is required for your U driver with NUM_AXES >= 7." #endif #endif #if HAS_V_AXIS @@ -1126,13 +1662,11 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #elif ENABLED(AXIS8_ROTATES) && DISABLED(AXIS7_ROTATES) #error "AXIS8_ROTATES requires AXIS7_ROTATES." #elif !defined(V_MIN_POS) || !defined(V_MAX_POS) - #error "V_MIN_POS and V_MAX_POS are required for the V axis." + #error "V_MIN_POS and V_MAX_POS are required with NUM_AXES >= 8." #elif !defined(V_HOME_DIR) - #error "V_HOME_DIR is required for the V axis." + #error "V_HOME_DIR is required with NUM_AXES >= 8." #elif HAS_V_ENABLE && !defined(V_ENABLE_ON) - #error "V_ENABLE_ON is required for the V stepper." - #elif !defined(INVERT_V_DIR) - #error "INVERT_V_DIR is required for the V stepper." + #error "V_ENABLE_ON is required for your V driver with NUM_AXES >= 8." #endif #endif #if HAS_W_AXIS @@ -1141,13 +1675,11 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #elif ENABLED(AXIS9_ROTATES) && DISABLED(AXIS8_ROTATES) #error "AXIS9_ROTATES requires AXIS8_ROTATES." #elif !defined(W_MIN_POS) || !defined(W_MAX_POS) - #error "W_MIN_POS and W_MAX_POS are required for the W axis." + #error "W_MIN_POS and W_MAX_POS are required with NUM_AXES >= 9." #elif !defined(W_HOME_DIR) - #error "W_HOME_DIR is required for the W axis." + #error "W_HOME_DIR is required with NUM_AXES >= 9." #elif HAS_W_ENABLE && !defined(W_ENABLE_ON) - #error "W_ENABLE_ON is required for the W stepper." - #elif !defined(INVERT_W_DIR) - #error "INVERT_W_DIR is required for the W stepper." + #error "W_ENABLE_ON is required for your W driver with NUM_AXES >= 9." #endif #endif @@ -1158,16 +1690,16 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i /** * Allow only one kinematic type to be defined */ -#if MANY(DELTA, MORGAN_SCARA, MP_SCARA, AXEL_TPARA, COREXY, COREXZ, COREYZ, COREYX, COREZX, COREZY, MARKFORGED_XY, MARKFORGED_YX, ARTICULATED_ROBOT_ARM, FOAMCUTTER_XYUV, POLAR) - #error "Please enable only one of DELTA, MORGAN_SCARA, MP_SCARA, AXEL_TPARA, COREXY, COREXZ, COREYZ, COREYX, COREZX, COREZY, MARKFORGED_XY, MARKFORGED_YX, ARTICULATED_ROBOT_ARM, FOAMCUTTER_XYUV, or POLAR." +#if MANY(DELTA, MORGAN_SCARA, MP_SCARA, AXEL_TPARA, COREXY, COREXZ, COREYZ, COREYX, COREZX, COREZY, MARKFORGED_XY, MARKFORGED_YX, ARTICULATED_ROBOT_ARM, FOAMCUTTER_XYUV) + #error "Please enable only one of DELTA, MORGAN_SCARA, MP_SCARA, AXEL_TPARA, COREXY, COREXZ, COREYZ, COREYX, COREZX, COREZY, MARKFORGED_XY, MARKFORGED_YX, ARTICULATED_ROBOT_ARM, or FOAMCUTTER_XYUV." #endif /** * Delta requirements */ #if ENABLED(DELTA) - #if ANY(X_HOME_TO_MIN, Y_HOME_TO_MIN, Z_HOME_TO_MIN) - #error "DELTA kinematics require homing "XYZ" axes to MAX. Set [XYZ]_HOME_DIR to 1." + #if NONE(USE_XMAX_PLUG, USE_YMAX_PLUG, USE_ZMAX_PLUG) + #error "You probably want to use Max Endstops for DELTA!" #elif ENABLED(ENABLE_LEVELING_FADE_HEIGHT) && DISABLED(AUTO_BED_LEVELING_BILINEAR) && !UBL_SEGMENTED #error "ENABLE_LEVELING_FADE_HEIGHT on DELTA requires AUTO_BED_LEVELING_BILINEAR or AUTO_BED_LEVELING_UBL." #elif ENABLED(DELTA_AUTO_CALIBRATION) && !(HAS_BED_PROBE || HAS_MARLINUI_MENU) @@ -1187,13 +1719,13 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i * Junction deviation is incompatible with kinematic systems. */ #if HAS_JUNCTION_DEVIATION && IS_KINEMATIC - #error "CLASSIC_JERK is required for the kinematics of DELTA, SCARA, POLAR, etc." + #error "CLASSIC_JERK is required for DELTA and SCARA." #endif /** * Some things should not be used on Belt Printers */ -#if ALL(BELTPRINTER, HAS_LEVELING) +#if BOTH(BELTPRINTER, HAS_LEVELING) #error "Bed Leveling is not compatible with BELTPRINTER." #endif @@ -1206,8 +1738,8 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i */ #if 1 < 0 \ + (DISABLED(BLTOUCH) && HAS_Z_SERVO_PROBE) \ - + COUNT_ENABLED(PROBE_MANUALLY, BLTOUCH, BD_SENSOR, FIX_MOUNTED_PROBE, NOZZLE_AS_PROBE, TOUCH_MI_PROBE, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, RACK_AND_PINION_PROBE, SENSORLESS_PROBING, MAGLEV4, MAG_MOUNTED_PROBE, BIQU_MICROPROBE_V1, BIQU_MICROPROBE_V2) - #error "Please enable only one probe option: PROBE_MANUALLY, SENSORLESS_PROBING, BLTOUCH, BD_SENSOR, FIX_MOUNTED_PROBE, NOZZLE_AS_PROBE, TOUCH_MI_PROBE, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, MAGLEV4, MAG_MOUNTED_PROBE, BIQU_MICROPROBE_V1, BIQU_MICROPROBE_V2, or Z Servo." + + COUNT_ENABLED(PROBE_MANUALLY, BLTOUCH, BD_SENSOR, FIX_MOUNTED_PROBE, NOZZLE_AS_PROBE, TOUCH_MI_PROBE, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, RACK_AND_PINION_PROBE, SENSORLESS_PROBING, MAGLEV4, MAG_MOUNTED_PROBE) + #error "Please enable only one probe option: PROBE_MANUALLY, SENSORLESS_PROBING, BLTOUCH, BD_SENSOR, FIX_MOUNTED_PROBE, NOZZLE_AS_PROBE, TOUCH_MI_PROBE, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, MAGLEV4, MAG_MOUNTED_PROBE or Z Servo." #endif #if HAS_BED_PROBE @@ -1215,7 +1747,7 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i /** * Z_PROBE_SLED is incompatible with DELTA */ - #if ALL(Z_PROBE_SLED, DELTA) + #if BOTH(Z_PROBE_SLED, DELTA) #error "You cannot use Z_PROBE_SLED with DELTA." #endif @@ -1261,7 +1793,7 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #else #define _IS_5V_TOLERANT(P) 1 // Assume 5V tolerance #endif - #if USE_Z_MIN_PROBE + #if USES_Z_MIN_PROBE_PIN #if !_IS_5V_TOLERANT(Z_MIN_PROBE_PIN) #error "BLTOUCH_SET_5V_MODE is not compatible with the Z_MIN_PROBE_PIN." #endif @@ -1273,48 +1805,20 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #undef _IS_5V_TOLERANT #undef _5V #elif NONE(ONBOARD_ENDSTOPPULLUPS, ENDSTOPPULLUPS, ENDSTOPPULLUP_ZMIN, ENDSTOPPULLUP_ZMIN_PROBE) - #if USE_Z_MIN_PROBE + #if USES_Z_MIN_PROBE_PIN #error "BLTOUCH on Z_MIN_PROBE_PIN requires ENDSTOPPULLUP_ZMIN_PROBE, ENDSTOPPULLUPS, or BLTOUCH_SET_5V_MODE." #else #error "BLTOUCH on Z_MIN_PIN requires ENDSTOPPULLUP_ZMIN, ENDSTOPPULLUPS, or BLTOUCH_SET_5V_MODE." #endif #endif - #if HAS_BLTOUCH_HS_MODE - constexpr char hs[] = STRINGIFY(BLTOUCH_HS_MODE); - static_assert(!(strcmp(hs, "1") && strcmp(hs, "0x1") && strcmp(hs, "true") && strcmp(hs, "0") && strcmp(hs, "0x0") && strcmp(hs, "false")), \ - "BLTOUCH_HS_MODE must now be defined as true or false, indicating the default state."); - #ifdef BLTOUCH_HS_EXTRA_CLEARANCE - static_assert(BLTOUCH_HS_EXTRA_CLEARANCE >= 0, "BLTOUCH_HS_MODE requires BLTOUCH_HS_EXTRA_CLEARANCE >= 0."); - #endif + #if ENABLED(BLTOUCH_HS_MODE) && BLTOUCH_HS_MODE == 0 + #error "BLTOUCH_HS_MODE must now be defined as true or false, indicating the default state." #endif - #if BLTOUCH_DELAY < 200 #error "BLTOUCH_DELAY less than 200 is unsafe and is not supported." #endif - - #ifdef DEACTIVATE_SERVOS_AFTER_MOVE - #error "BLTOUCH requires DEACTIVATE_SERVOS_AFTER_MOVE to be to disabled. Please update your Configuration.h file." - #endif - - #if ENABLED(INVERTED_PROBE_STATE) - #if Z_MIN_PROBE_ENDSTOP_HIT_STATE != LOW - #error "BLTOUCH requires Z_MIN_PROBE_ENDSTOP_HIT_STATE LOW." - #endif - #elif Z_MIN_PROBE_ENDSTOP_HIT_STATE != HIGH - #error "BLTOUCH requires Z_MIN_PROBE_ENDSTOP_HIT_STATE HIGH." - #endif - #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) - #if ENABLED(INVERTED_PROBE_STATE) - #if Z_MIN_ENDSTOP_HIT_STATE != LOW - #error "BLTOUCH requires Z_MIN_ENDSTOP_HIT_STATE LOW." - #endif - #elif Z_MIN_ENDSTOP_HIT_STATE != HIGH - #error "BLTOUCH requires Z_MIN_ENDSTOP_HIT_STATE HIGH." - #endif - #endif - - #endif // BLTOUCH + #endif #if ENABLED(RACK_AND_PINION_PROBE) && !(defined(Z_PROBE_DEPLOY_X) && defined(Z_PROBE_RETRACT_X)) #error "RACK_AND_PINION_PROBE requires Z_PROBE_DEPLOY_X and Z_PROBE_RETRACT_X." @@ -1330,35 +1834,21 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #error "TOUCH_MI_PROBE requires TOUCH_MI_RETRACT_Z." #elif defined(Z_AFTER_PROBING) #error "TOUCH_MI_PROBE requires Z_AFTER_PROBING to be disabled." - #elif Z_CLEARANCE_FOR_HOMING < 10 - #error "TOUCH_MI_PROBE requires Z_CLEARANCE_FOR_HOMING >= 10." + #elif Z_HOMING_HEIGHT < 10 + #error "TOUCH_MI_PROBE requires Z_HOMING_HEIGHT >= 10." + #elif Z_MIN_PROBE_ENDSTOP_INVERTING + #error "TOUCH_MI_PROBE requires Z_MIN_PROBE_ENDSTOP_INVERTING to be set to false." #elif DISABLED(BABYSTEP_ZPROBE_OFFSET) #error "TOUCH_MI_PROBE requires BABYSTEPPING with BABYSTEP_ZPROBE_OFFSET." #elif !HAS_RESUME_CONTINUE #error "TOUCH_MI_PROBE currently requires an LCD controller or EMERGENCY_PARSER." #endif - #if ENABLED(INVERTED_PROBE_STATE) - #if Z_MIN_PROBE_ENDSTOP_HIT_STATE != LOW - #error "TOUCH_MI_PROBE requires Z_MIN_PROBE_ENDSTOP_HIT_STATE LOW." - #endif - #elif Z_MIN_PROBE_ENDSTOP_HIT_STATE != HIGH - #error "TOUCH_MI_PROBE requires Z_MIN_PROBE_ENDSTOP_HIT_STATE HIGH." - #endif - #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) - #if ENABLED(INVERTED_PROBE_STATE) - #if Z_MIN_ENDSTOP_HIT_STATE != LOW - #error "TOUCH_MI_PROBE requires Z_MIN_ENDSTOP_HIT_STATE LOW." - #endif - #elif Z_MIN_ENDSTOP_HIT_STATE != HIGH - #error "TOUCH_MI_PROBE requires Z_MIN_ENDSTOP_HIT_STATE HIGH." - #endif - #endif - #endif // TOUCH_MI_PROBE + #endif /** * Mag mounted probe requirements */ - #if ALL(MAG_MOUNTED_PROBE, USE_PROBE_FOR_Z_HOMING) && DISABLED(Z_SAFE_HOMING) + #if BOTH(MAG_MOUNTED_PROBE, USE_PROBE_FOR_Z_HOMING) && DISABLED(Z_SAFE_HOMING) #error "MAG_MOUNTED_PROBE requires Z_SAFE_HOMING if it's being used to home Z." #endif @@ -1375,77 +1865,43 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #endif #endif - /** - * BIQU MicroProbe requirements - */ - #if ANY(BIQU_MICROPROBE_V1, BIQU_MICROPROBE_V2) - #if DISABLED(PROBE_ENABLE_DISABLE) - #error "BIQU MicroProbe requires PROBE_ENABLE_DISABLE." - #elif !PIN_EXISTS(PROBE_ENABLE) - #error "BIQU MicroProbe requires a PROBE_ENABLE_PIN." - #endif - - #if ENABLED(BIQU_MICROPROBE_V1) - #if ENABLED(INVERTED_PROBE_STATE) - #if Z_MIN_PROBE_ENDSTOP_HIT_STATE != LOW - #error "BIQU_MICROPROBE_V1 requires Z_MIN_PROBE_ENDSTOP_HIT_STATE LOW." - #endif - #elif Z_MIN_PROBE_ENDSTOP_HIT_STATE != HIGH - #error "BIQU_MICROPROBE_V1 requires Z_MIN_PROBE_ENDSTOP_HIT_STATE HIGH." - #endif - #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) - #if ENABLED(INVERTED_PROBE_STATE) - #if Z_MIN_ENDSTOP_HIT_STATE != LOW - #error "BIQU_MICROPROBE_V1 requires Z_MIN_ENDSTOP_HIT_STATE LOW." - #endif - #elif Z_MIN_ENDSTOP_HIT_STATE != HIGH - #error "BIQU_MICROPROBE_V1 requires Z_MIN_ENDSTOP_HIT_STATE HIGH." - #endif - #endif - #elif ENABLED(BIQU_MICROPROBE_V2) - #if ENABLED(INVERTED_PROBE_STATE) - #if Z_MIN_PROBE_ENDSTOP_HIT_STATE != HIGH - #error "BIQU_MICROPROBE_V2 requires Z_MIN_PROBE_ENDSTOP_HIT_STATE HIGH." - #endif - #elif Z_MIN_PROBE_ENDSTOP_HIT_STATE != LOW - #error "BIQU_MICROPROBE_V2 requires Z_MIN_PROBE_ENDSTOP_HIT_STATE LOW." - #endif - #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) - #if ENABLED(INVERTED_PROBE_STATE) - #if Z_MIN_ENDSTOP_HIT_STATE != HIGH - #error "BIQU_MICROPROBE_V2 requires Z_MIN_ENDSTOP_HIT_STATE HIGH." - #endif - #elif Z_MIN_ENDSTOP_HIT_STATE != LOW - #error "BIQU_MICROPROBE_V2 requires Z_MIN_ENDSTOP_HIT_STATE LOW." - #endif - #endif - #endif - #endif // BIQU_MICROPROBE_V1 || BIQU_MICROPROBE_V2 - /** * Require pin options and pins to be defined */ - #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) - #if !USE_Z_MIN - #error "Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN requires the Z_MIN_PIN to be defined." - #elif Z_MIN_PROBE_ENDSTOP_HIT_STATE != Z_MIN_ENDSTOP_HIT_STATE - #error "Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN requires Z_MIN_ENDSTOP_HIT_STATE to match Z_MIN_PROBE_ENDSTOP_HIT_STATE." + #if ENABLED(SENSORLESS_PROBING) + #if ENABLED(DELTA) && !(X_SENSORLESS && Y_SENSORLESS && Z_SENSORLESS) + #error "SENSORLESS_PROBING requires TMC2130/2160/2209/5130/5160 drivers on X, Y, and Z." + #elif !Z_SENSORLESS + #error "SENSORLESS_PROBING requires a TMC2130/2160/2209/5130/5160 driver on Z." #endif - #elif !PIN_EXISTS(Z_MIN_PROBE) + #elif ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) + #if DISABLED(USE_ZMIN_PLUG) + #error "Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN requires USE_ZMIN_PLUG to be enabled." + #elif !HAS_Z_MIN + #error "Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN requires the Z_MIN_PIN to be defined." + #elif Z_MIN_PROBE_ENDSTOP_INVERTING != Z_MIN_ENDSTOP_INVERTING + #error "Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN requires Z_MIN_ENDSTOP_INVERTING to match Z_MIN_PROBE_ENDSTOP_INVERTING." + #endif + #elif !HAS_Z_MIN_PROBE_PIN #error "Z_MIN_PROBE_PIN must be defined if Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN is not enabled." #endif /** - * Check for improper PROBING_MARGIN + * Check for improper NOZZLE_TO_PROBE_OFFSET */ - #if NONE(NOZZLE_AS_PROBE, IS_KINEMATIC) + constexpr xyz_pos_t sanity_nozzle_to_probe_offset = NOZZLE_TO_PROBE_OFFSET; + #if ENABLED(NOZZLE_AS_PROBE) + static_assert(sanity_nozzle_to_probe_offset.x == 0 && sanity_nozzle_to_probe_offset.y == 0, + "NOZZLE_AS_PROBE requires the XY offsets in NOZZLE_TO_PROBE_OFFSET to both be 0."); + #elif !IS_KINEMATIC static_assert(PROBING_MARGIN >= 0, "PROBING_MARGIN must be >= 0."); static_assert(PROBING_MARGIN_BACK >= 0, "PROBING_MARGIN_BACK must be >= 0."); static_assert(PROBING_MARGIN_FRONT >= 0, "PROBING_MARGIN_FRONT must be >= 0."); static_assert(PROBING_MARGIN_LEFT >= 0, "PROBING_MARGIN_LEFT must be >= 0."); static_assert(PROBING_MARGIN_RIGHT >= 0, "PROBING_MARGIN_RIGHT must be >= 0."); #endif - #define _MARGIN(A) TERN(IS_KINEMATIC, PRINTABLE_RADIUS, ((A##_BED_SIZE) / 2)) + + #define _MARGIN(A) TERN(IS_SCARA, SCARA_PRINTABLE_RADIUS, TERN(DELTA, DELTA_PRINTABLE_RADIUS, ((A##_BED_SIZE) / 2))) static_assert(PROBING_MARGIN < _MARGIN(X), "PROBING_MARGIN is too large."); static_assert(PROBING_MARGIN_BACK < _MARGIN(Y), "PROBING_MARGIN_BACK is too large."); static_assert(PROBING_MARGIN_FRONT < _MARGIN(Y), "PROBING_MARGIN_FRONT is too large."); @@ -1453,49 +1909,19 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i static_assert(PROBING_MARGIN_RIGHT < _MARGIN(X), "PROBING_MARGIN_RIGHT is too large."); #undef _MARGIN - /** - * Check for improper PROBE_OFFSET_[XYZ](MIN|MAX) - */ - #define PROBE_OFFSET_ASSERT(varname, x, min, max) static_assert(WITHIN(x, min, max), varname " must be within " STRINGIFY(min) " and " STRINGIFY(max)) - #if HAS_PROBE_XY_OFFSET - PROBE_OFFSET_ASSERT("PROBE_OFFSET_XMIN", PROBE_OFFSET_XMIN, -(X_BED_SIZE), X_BED_SIZE); - PROBE_OFFSET_ASSERT("PROBE_OFFSET_XMAX", PROBE_OFFSET_XMAX, -(X_BED_SIZE), X_BED_SIZE); - PROBE_OFFSET_ASSERT("PROBE_OFFSET_YMIN", PROBE_OFFSET_YMIN, -(Y_BED_SIZE), Y_BED_SIZE); - PROBE_OFFSET_ASSERT("PROBE_OFFSET_YMAX", PROBE_OFFSET_YMAX, -(Y_BED_SIZE), Y_BED_SIZE); - #endif - PROBE_OFFSET_ASSERT("PROBE_OFFSET_ZMIN", PROBE_OFFSET_ZMIN, -(Z_MAX_POS), Z_MAX_POS); - PROBE_OFFSET_ASSERT("PROBE_OFFSET_ZMAX", PROBE_OFFSET_ZMAX, -(Z_MAX_POS), Z_MAX_POS); - - /** - * Check for improper NOZZLE_AS_PROBE or NOZZLE_TO_PROBE_OFFSET - */ - constexpr xyz_pos_t sanity_nozzle_to_probe_offset = NOZZLE_TO_PROBE_OFFSET; - #if ENABLED(NOZZLE_AS_PROBE) - static_assert(sanity_nozzle_to_probe_offset.x == 0 && sanity_nozzle_to_probe_offset.y == 0, - "NOZZLE_AS_PROBE requires the XY offsets in NOZZLE_TO_PROBE_OFFSET to both be 0."); - #endif - #if HAS_PROBE_XY_OFFSET - PROBE_OFFSET_ASSERT("NOZZLE_TO_PROBE_OFFSET.x", sanity_nozzle_to_probe_offset.x, PROBE_OFFSET_XMIN, PROBE_OFFSET_XMAX); - PROBE_OFFSET_ASSERT("NOZZLE_TO_PROBE_OFFSET.y", sanity_nozzle_to_probe_offset.y, PROBE_OFFSET_YMIN, PROBE_OFFSET_YMAX); - #endif - PROBE_OFFSET_ASSERT("NOZZLE_TO_PROBE_OFFSET.z", sanity_nozzle_to_probe_offset.z, PROBE_OFFSET_ZMIN, PROBE_OFFSET_ZMAX); - #undef PROBE_OFFSET_ASSERT - /** * Make sure Z raise values are set */ #ifndef Z_CLEARANCE_DEPLOY_PROBE - #error "Z_CLEARANCE_DEPLOY_PROBE is required for bed probes." - #else - static_assert(Z_CLEARANCE_DEPLOY_PROBE >= 0, "Probes require Z_CLEARANCE_DEPLOY_PROBE >= 0."); - #endif - #ifndef Z_CLEARANCE_BETWEEN_PROBES - #error "Z_CLEARANCE_BETWEEN_PROBES is required for bed probes." - #else - static_assert(Z_CLEARANCE_BETWEEN_PROBES >= 0, "Probes require Z_CLEARANCE_BETWEEN_PROBES >= 0."); - #endif - #ifdef Z_AFTER_PROBING - static_assert(Z_AFTER_PROBING >= 0, "Probes require Z_AFTER_PROBING >= 0."); + #error "You must define Z_CLEARANCE_DEPLOY_PROBE in your configuration." + #elif !defined(Z_CLEARANCE_BETWEEN_PROBES) + #error "You must define Z_CLEARANCE_BETWEEN_PROBES in your configuration." + #elif Z_CLEARANCE_DEPLOY_PROBE < 0 + #error "Probes need Z_CLEARANCE_DEPLOY_PROBE >= 0." + #elif Z_CLEARANCE_BETWEEN_PROBES < 0 + #error "Probes need Z_CLEARANCE_BETWEEN_PROBES >= 0." + #elif Z_AFTER_PROBING < 0 + #error "Probes need Z_AFTER_PROBING >= 0." #endif #if MULTIPLE_PROBING > 0 || EXTRA_PROBING > 0 @@ -1508,7 +1934,9 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #endif #endif - static_assert(Z_PROBE_LOW_POINT <= 0, "Z_PROBE_LOW_POINT must be less than or equal to 0."); + #if Z_PROBE_LOW_POINT > 0 + #error "Z_PROBE_LOW_POINT must be less than or equal to 0." + #endif #if ENABLED(PROBE_ACTIVATION_SWITCH) #ifndef PROBE_ACTIVATION_SWITCH_STATE @@ -1549,53 +1977,58 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i * Allow only one bed leveling option to be defined */ #if MANY(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_3POINT, AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_UBL, MESH_BED_LEVELING) - #error "Select only one of: MESH_BED_LEVELING, AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_3POINT, AUTO_BED_LEVELING_BILINEAR, or AUTO_BED_LEVELING_UBL." + #error "Select only one of: MESH_BED_LEVELING, AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_3POINT, AUTO_BED_LEVELING_BILINEAR or AUTO_BED_LEVELING_UBL." #endif /** * Bed Leveling Requirements */ -#if IS_SCARA && ANY(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_3POINT, AUTO_BED_LEVELING_UBL) - #error "SCARA machines can only use AUTO_BED_LEVELING_BILINEAR or MESH_BED_LEVELING." -#elif ENABLED(AUTO_BED_LEVELING_LINEAR) && !(WITHIN(GRID_MAX_POINTS_X, 2, 255) && WITHIN(GRID_MAX_POINTS_Y, 2, 255)) - #error "GRID_MAX_POINTS_[XY] must be between 2 and 255 with AUTO_BED_LEVELING_LINEAR." -#elif ENABLED(AUTO_BED_LEVELING_BILINEAR) && !(WITHIN(GRID_MAX_POINTS_X, 3, 255) && WITHIN(GRID_MAX_POINTS_Y, 3, 255)) - #error "GRID_MAX_POINTS_[XY] must be between 3 and 255 with AUTO_BED_LEVELING_BILINEAR." -#elif ENABLED(AUTO_BED_LEVELING_UBL) - #if ENABLED(POLAR) - #error "AUTO_BED_LEVELING_UBL does not yet support POLAR printers." +#if ENABLED(AUTO_BED_LEVELING_UBL) + + /** + * Unified Bed Leveling + */ + + #if IS_SCARA + #error "AUTO_BED_LEVELING_UBL does not yet support SCARA printers." #elif DISABLED(EEPROM_SETTINGS) #error "AUTO_BED_LEVELING_UBL requires EEPROM_SETTINGS." - #elif !WITHIN(GRID_MAX_POINTS_X, 3, 255) || !WITHIN(GRID_MAX_POINTS_Y, 3, 255) - #error "GRID_MAX_POINTS_[XY] must be between 3 and 255." - #elif ALL(UBL_HILBERT_CURVE, DELTA) - #error "UBL_HILBERT_CURVE can only be used with a square / rectangular printable area." + #elif !WITHIN(GRID_MAX_POINTS_X, 3, 15) || !WITHIN(GRID_MAX_POINTS_Y, 3, 15) + #error "GRID_MAX_POINTS_[XY] must be a whole number between 3 and 15." #endif + +#elif HAS_ABL_NOT_UBL + + /** + * Auto Bed Leveling + */ + + /** + * Delta and SCARA have limited bed leveling options + */ + #if IS_SCARA && DISABLED(AUTO_BED_LEVELING_BILINEAR) + #error "SCARA machines can only use the AUTO_BED_LEVELING_BILINEAR leveling option." + #endif + #elif ENABLED(MESH_BED_LEVELING) + + // Mesh Bed Leveling #if ENABLED(DELTA) #error "MESH_BED_LEVELING is not compatible with DELTA printers." #elif (GRID_MAX_POINTS_X) > 9 || (GRID_MAX_POINTS_Y) > 9 #error "GRID_MAX_POINTS_X and GRID_MAX_POINTS_Y must be less than 10 for MBL." #endif -#endif -#define _POINT_COUNT (defined(PROBE_PT_1) + defined(PROBE_PT_2) + defined(PROBE_PT_3)) -#if _POINT_COUNT != 0 && _POINT_COUNT != 3 - #error "For 3-Point Procedures all XY points must be defined (or none for the defaults)." #endif -#undef _POINT_COUNT #if ALL(HAS_LEVELING, RESTORE_LEVELING_AFTER_G28, ENABLE_LEVELING_AFTER_G28) #error "Only enable RESTORE_LEVELING_AFTER_G28 or ENABLE_LEVELING_AFTER_G28, but not both." #endif -#if ALL(HAS_MESH, CLASSIC_JERK) +#if HAS_MESH && HAS_CLASSIC_JERK static_assert(DEFAULT_ZJERK > 0.1, "Low DEFAULT_ZJERK values are incompatible with mesh-based leveling."); #endif -#if HAS_MESH && DGUS_LCD_UI_IA_CREALITY && GRID_MAX_POINTS > 25 - #error "DGUS_LCD_UI IA_CREALITY requires a mesh with no more than 25 points as defined by GRID_MAX_POINTS_X/Y." -#endif #if ENABLED(G26_MESH_VALIDATION) #if !HAS_EXTRUDERS @@ -1626,11 +2059,11 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #elif !(ENABLED(MESH_BED_LEVELING) || HAS_ABL_NOT_UBL) #error "LCD_BED_LEVELING requires MESH_BED_LEVELING or AUTO_BED_LEVELING." #elif ENABLED(MESH_EDIT_MENU) && !HAS_MESH - #error "MESH_EDIT_MENU requires MESH_BED_LEVELING, AUTO_BED_LEVELING_BILINEAR, or AUTO_BED_LEVELING_UBL." + #error "MESH_EDIT_MENU requires MESH_BED_LEVELING, AUTO_BED_LEVELING_BILINEAR or AUTO_BED_LEVELING_UBL." #endif #endif -#if ALL(PREHEAT_BEFORE_PROBING, PREHEAT_BEFORE_LEVELING) +#if BOTH(PREHEAT_BEFORE_PROBING, PREHEAT_BEFORE_LEVELING) #error "Disable PREHEAT_BEFORE_LEVELING when using PREHEAT_BEFORE_PROBING." #endif @@ -1723,39 +2156,13 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i static_assert(WITHIN(Z_SAFE_HOMING_Y_POINT, Y_MIN_POS, Y_MAX_POS), "Z_SAFE_HOMING_Y_POINT can't be reached by the nozzle."); #endif -/** - * Make sure Z_CLEARANCE_FOR_HOMING is below Z_MAX_POS - */ -#if HAS_Z_AXIS - static_assert(Z_CLEARANCE_FOR_HOMING <= Z_MAX_POS, "Z_CLEARANCE_FOR_HOMING must be smaller than or equal to Z_MAX_POS."); -#endif - -// Check Safe Bed Leveling settings -#if HAS_SAFE_BED_LEVELING - #if defined(SAFE_BED_LEVELING_START_Y) && !defined(SAFE_BED_LEVELING_START_X) - #error "If SAFE_BED_LEVELING_START_Y is defined, SAFE_BED_LEVELING_START_X must also be defined." - #elif defined(SAFE_BED_LEVELING_START_Z) && !defined(SAFE_BED_LEVELING_START_Y) - #error "If SAFE_BED_LEVELING_START_Z is defined, SAFE_BED_LEVELING_START_Y must also be defined." - #elif defined(SAFE_BED_LEVELING_START_I) && !defined(SAFE_BED_LEVELING_START_Z) - #error "If SAFE_BED_LEVELING_START_I is defined, SAFE_BED_LEVELING_START_Z must also be defined." - #elif defined(SAFE_BED_LEVELING_START_J) && !defined(SAFE_BED_LEVELING_START_I) - #error "If SAFE_BED_LEVELING_START_J is defined, SAFE_BED_LEVELING_START_I must also be defined." - #elif defined(SAFE_BED_LEVELING_START_K) && !defined(SAFE_BED_LEVELING_START_J) - #error "If SAFE_BED_LEVELING_START_K is defined, SAFE_BED_LEVELING_START_J must also be defined." - #elif defined(SAFE_BED_LEVELING_START_U) && !defined(SAFE_BED_LEVELING_START_K) - #error "If SAFE_BED_LEVELING_START_U is defined, SAFE_BED_LEVELING_START_K must also be defined." - #elif defined(SAFE_BED_LEVELING_START_V) && !defined(SAFE_BED_LEVELING_START_U) - #error "If SAFE_BED_LEVELING_START_V is defined, SAFE_BED_LEVELING_START_U must also be defined." - #elif defined(SAFE_BED_LEVELING_START_W) && !defined(SAFE_BED_LEVELING_START_V) - #error "If SAFE_BED_LEVELING_START_W is defined, SAFE_BED_LEVELING_START_V must also be defined." - #endif -#endif - /** * Make sure DISABLE_[XYZ] compatible with selected homing options */ -#if HAS_DISABLE_MAIN_AXES && ANY(HOME_AFTER_DEACTIVATE, Z_SAFE_HOMING) - #error "DISABLE_[XYZIJKUVW] is not compatible with HOME_AFTER_DEACTIVATE or Z_SAFE_HOMING." +#if ANY(DISABLE_X, DISABLE_Y, DISABLE_Z, DISABLE_I, DISABLE_J, DISABLE_K, DISABLE_U, DISABLE_V, DISABLE_W) + #if EITHER(HOME_AFTER_DEACTIVATE, Z_SAFE_HOMING) + #error "DISABLE_[XYZIJKUVW] is not compatible with HOME_AFTER_DEACTIVATE or Z_SAFE_HOMING." + #endif #endif /** @@ -1776,7 +2183,7 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #error "POWER_MONITOR_CURRENT requires a valid POWER_MONITOR_CURRENT_PIN." #elif ENABLED(POWER_MONITOR_VOLTAGE) && !PIN_EXISTS(POWER_MONITOR_VOLTAGE) #error "POWER_MONITOR_VOLTAGE requires POWER_MONITOR_VOLTAGE_PIN to be defined." -#elif ALL(POWER_MONITOR_CURRENT, POWER_MONITOR_VOLTAGE) && POWER_MONITOR_CURRENT_PIN == POWER_MONITOR_VOLTAGE_PIN +#elif BOTH(POWER_MONITOR_CURRENT, POWER_MONITOR_VOLTAGE) && POWER_MONITOR_CURRENT_PIN == POWER_MONITOR_VOLTAGE_PIN #error "POWER_MONITOR_CURRENT_PIN and POWER_MONITOR_VOLTAGE_PIN must be different." #endif @@ -1808,7 +2215,7 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #if ENABLED(SAV_3DGLCD) #if NONE(U8GLIB_SSD1306, U8GLIB_SH1106) #error "Enable a SAV_3DGLCD display type: U8GLIB_SSD1306 or U8GLIB_SH1106." - #elif ALL(U8GLIB_SSD1306, U8GLIB_SH1106) + #elif BOTH(U8GLIB_SSD1306, U8GLIB_SH1106) #error "Only enable one SAV_3DGLCD display type: U8GLIB_SSD1306 or U8GLIB_SH1106." #endif #endif @@ -1831,43 +2238,37 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #error "DUAL_X_CARRIAGE cannot be used with COREXY, COREYX, COREXZ, COREZX, MARKFORGED_YX, or MARKFORGED_XY." #elif !GOOD_AXIS_PINS(X2) #error "DUAL_X_CARRIAGE requires X2 stepper pins to be defined." - #elif !USE_X_MAX - #error "DUAL_X_CARRIAGE requires an X_MAX_PIN in addition to the X_MIN_PIN." + #elif !HAS_X_MAX + #error "DUAL_X_CARRIAGE requires USE_XMAX_PLUG and an X Max Endstop." #elif !defined(X2_HOME_POS) || !defined(X2_MIN_POS) || !defined(X2_MAX_POS) #error "DUAL_X_CARRIAGE requires X2_HOME_POS, X2_MIN_POS, and X2_MAX_POS." - #elif X_HOME_TO_MAX - #error "DUAL_X_CARRIAGE requires X_HOME_DIR -1." + #elif X_HOME_TO_MAX || X2_HOME_TO_MIN + #error "DUAL_X_CARRIAGE requires X_HOME_DIR -1 and X2_HOME_DIR 1." #endif #endif #undef GOOD_AXIS_PINS /** - * Make sure auto fan pins don't conflict with the first fan pin + * Make sure auto fan pins don't conflict with the fan pin */ #if HAS_AUTO_FAN - #if PINS_EXIST(E0_AUTO_FAN, FAN0) && E0_AUTO_FAN_PIN == FAN0_PIN - #error "You cannot set E0_AUTO_FAN_PIN equal to FAN0_PIN." - #elif PINS_EXIST(E1_AUTO_FAN, FAN0) && E1_AUTO_FAN_PIN == FAN0_PIN - #error "You cannot set E1_AUTO_FAN_PIN equal to FAN0_PIN." - #elif PINS_EXIST(E2_AUTO_FAN, FAN0) && E2_AUTO_FAN_PIN == FAN0_PIN - #error "You cannot set E2_AUTO_FAN_PIN equal to FAN0_PIN." - #elif PINS_EXIST(E3_AUTO_FAN, FAN0) && E3_AUTO_FAN_PIN == FAN0_PIN - #error "You cannot set E3_AUTO_FAN_PIN equal to FAN0_PIN." - #elif PINS_EXIST(E4_AUTO_FAN, FAN0) && E4_AUTO_FAN_PIN == FAN0_PIN - #error "You cannot set E4_AUTO_FAN_PIN equal to FAN0_PIN." - #elif PINS_EXIST(E5_AUTO_FAN, FAN0) && E5_AUTO_FAN_PIN == FAN0_PIN - #error "You cannot set E5_AUTO_FAN_PIN equal to FAN0_PIN." - #elif PINS_EXIST(E6_AUTO_FAN, FAN0) && E6_AUTO_FAN_PIN == FAN0_PIN - #error "You cannot set E6_AUTO_FAN_PIN equal to FAN0_PIN." - #elif PINS_EXIST(E7_AUTO_FAN, FAN0) && E7_AUTO_FAN_PIN == FAN0_PIN - #error "You cannot set E7_AUTO_FAN_PIN equal to FAN0_PIN." + #if HAS_FAN0 + #if PIN_EXISTS(E0_AUTO_FAN) && E0_AUTO_FAN_PIN == FAN_PIN + #error "You cannot set E0_AUTO_FAN_PIN equal to FAN_PIN." + #elif PIN_EXISTS(E1_AUTO_FAN) && E1_AUTO_FAN_PIN == FAN_PIN + #error "You cannot set E1_AUTO_FAN_PIN equal to FAN_PIN." + #elif PIN_EXISTS(E2_AUTO_FAN) && E2_AUTO_FAN_PIN == FAN_PIN + #error "You cannot set E2_AUTO_FAN_PIN equal to FAN_PIN." + #elif PIN_EXISTS(E3_AUTO_FAN) && E3_AUTO_FAN_PIN == FAN_PIN + #error "You cannot set E3_AUTO_FAN_PIN equal to FAN_PIN." + #endif #endif #endif #if HAS_FAN0 - #if CONTROLLER_FAN_PIN == FAN0_PIN - #error "You cannot set CONTROLLER_FAN_PIN equal to FAN0_PIN." + #if CONTROLLER_FAN_PIN == FAN_PIN + #error "You cannot set CONTROLLER_FAN_PIN equal to FAN_PIN." #elif ENABLED(FAN_SOFT_PWM_REQUIRED) && DISABLED(FAN_SOFT_PWM) #error "FAN_SOFT_PWM is required for your board. Enable it to continue." #endif @@ -1895,28 +2296,11 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #endif #endif -/** - * Make sure FAN_*_PWM values are sensible - */ -#if ANY(HAS_FAN, USE_CONTROLLER_FAN) - #if !WITHIN(FAN_MIN_PWM, 0, 255) - #error "FAN_MIN_PWM must be a value from 0 to 255." - #elif !WITHIN(FAN_MAX_PWM, 0, 255) - #error "FAN_MAX_PWM must be a value from 0 to 255." - #elif FAN_MIN_PWM > FAN_MAX_PWM - #error "FAN_MIN_PWM must be less than or equal to FAN_MAX_PWM." - #elif FAN_OFF_PWM > FAN_MIN_PWM - #error "FAN_OFF_PWM must be less than or equal to FAN_MIN_PWM." - #endif -#endif - #ifdef REDUNDANT_PART_COOLING_FAN #if FAN_COUNT < 2 #error "REDUNDANT_PART_COOLING_FAN requires a board with at least two PWM fans." - #elif !WITHIN(REDUNDANT_PART_COOLING_FAN, 1, FAN_COUNT - 1) - static_assert(false, "REDUNDANT_PART_COOLING_FAN must be between 1 and " STRINGIFY(DECREMENT(FAN_COUNT)) "."); - #elif !WITHIN(REDUNDANT_PART_COOLING_FAN + NUM_REDUNDANT_FANS - 1, 1, FAN_COUNT - 1) - #error "Not enough fans available for NUM_REDUNDANT_FANS." + #else + static_assert(WITHIN(REDUNDANT_PART_COOLING_FAN, 1, FAN_COUNT - 1), "REDUNDANT_PART_COOLING_FAN must be between 1 and " STRINGIFY(DECREMENT(FAN_COUNT)) "."); #endif #endif @@ -1926,8 +2310,8 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #if NEED_CASE_LIGHT_PIN #if !PIN_EXISTS(CASE_LIGHT) #error "CASE_LIGHT_ENABLE requires CASE_LIGHT_PIN, CASE_LIGHT_USE_NEOPIXEL, or CASE_LIGHT_USE_RGB_LED." - #elif CASE_LIGHT_PIN == FAN0_PIN - #error "CASE_LIGHT_PIN conflicts with FAN0_PIN. Resolve before continuing." + #elif CASE_LIGHT_PIN == FAN_PIN + #error "CASE_LIGHT_PIN conflicts with FAN_PIN. Resolve before continuing." #endif #endif @@ -1987,16 +2371,12 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #endif #if MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED < 5 #error "Thermistor 66 requires MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED ≥ 5." - #elif PREHEAT_TIME_HOTEND_MS < 15000 - #error "Thermistor 66 requires PREHEAT_TIME_HOTEND_MS ≥ 15000, but 30000 or higher is recommended." + #elif MILLISECONDS_PREHEAT_TIME < 30000 + #error "Thermistor 66 requires MILLISECONDS_PREHEAT_TIME ≥ 30000." #endif #undef _BAD_MINTEMP #endif -#if TEMP_SENSOR_BED == 66 && PREHEAT_TIME_BED_MS < 15000 - #error "Thermistor 66 requires PREHEAT_TIME_BED_MS ≥ 15000, but 30000 or higher is recommended." -#endif - /** * Required MAX31865 settings */ @@ -2014,13 +2394,6 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #error "MAX31865_SENSOR_OHMS_1 and MAX31865_CALIBRATION_OHMS_1 must be set if TEMP_SENSOR_1/TEMP_SENSOR_REDUNDANT is MAX31865." #endif #endif -#if TEMP_SENSOR_2_IS_MAX31865 || (TEMP_SENSOR_REDUNDANT_IS_MAX31865 && REDUNDANT_TEMP_MATCH(SOURCE, E2)) - #if !defined(MAX31865_SENSOR_WIRES_2) || !WITHIN(MAX31865_SENSOR_WIRES_2, 2, 4) - #error "MAX31865_SENSOR_WIRES_2 must be defined as an integer between 2 and 4." - #elif !defined(MAX31865_SENSOR_OHMS_2) || !defined(MAX31865_CALIBRATION_OHMS_2) - #error "MAX31865_SENSOR_OHMS_2 and MAX31865_CALIBRATION_OHMS_2 must be set if TEMP_SENSOR_2/TEMP_SENSOR_REDUNDANT is MAX31865." - #endif -#endif /** * Redundant temperature sensor config @@ -2044,8 +2417,6 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #error "TEMP_SENSOR_REDUNDANT_SOURCE can't be PROBE. TEMP_SENSOR_PROBE is in use." #elif REDUNDANT_TEMP_MATCH(SOURCE, BOARD) && HAS_TEMP_BOARD #error "TEMP_SENSOR_REDUNDANT_SOURCE can't be BOARD. TEMP_SENSOR_BOARD is in use." - #elif REDUNDANT_TEMP_MATCH(SOURCE, SOC) - #error "TEMP_SENSOR_REDUNDANT_SOURCE can't be SOC." #elif REDUNDANT_TEMP_MATCH(SOURCE, CHAMBER) && HAS_TEMP_CHAMBER #error "TEMP_SENSOR_REDUNDANT_SOURCE can't be CHAMBER. TEMP_SENSOR_CHAMBER is in use." #elif REDUNDANT_TEMP_MATCH(SOURCE, BED) && HAS_TEMP_BED @@ -2074,8 +2445,6 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #error "TEMP_SENSOR_REDUNDANT_TARGET can't be CHAMBER without TEMP_CHAMBER_PIN defined." #elif REDUNDANT_TEMP_MATCH(TARGET, BOARD) && !PIN_EXISTS(TEMP_BOARD) #error "TEMP_SENSOR_REDUNDANT_TARGET can't be BOARD without TEMP_BOARD_PIN defined." - #elif REDUNDANT_TEMP_MATCH(TARGET, SOC) - #error "TEMP_SENSOR_REDUNDANT_TARGET can't be SOC." #elif REDUNDANT_TEMP_MATCH(TARGET, PROBE) && !PIN_EXISTS(TEMP_PROBE) #error "TEMP_SENSOR_REDUNDANT_TARGET can't be PROBE without TEMP_PROBE_PIN defined." #elif REDUNDANT_TEMP_MATCH(TARGET, COOLER) && !PIN_EXISTS(TEMP_COOLER) @@ -2086,133 +2455,98 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #error "TEMP_SENSOR_REDUNDANT MAX Thermocouple with TEMP_SENSOR_REDUNDANT_SOURCE E0 requires TEMP_0_CS_PIN." #elif TEMP_SENSOR_IS_MAX_TC(REDUNDANT) && REDUNDANT_TEMP_MATCH(SOURCE, E1) && !PIN_EXISTS(TEMP_1_CS) #error "TEMP_SENSOR_REDUNDANT MAX Thermocouple with TEMP_SENSOR_REDUNDANT_SOURCE E1 requires TEMP_1_CS_PIN." - #elif TEMP_SENSOR_IS_MAX_TC(REDUNDANT) && REDUNDANT_TEMP_MATCH(SOURCE, E2) && !PIN_EXISTS(TEMP_2_CS) - #error "TEMP_SENSOR_REDUNDANT MAX Thermocouple with TEMP_SENSOR_REDUNDANT_SOURCE E2 requires TEMP_2_CS_PIN." #endif #endif /** + * Test Sensor & Heater pin combos. * Pins and Sensor IDs must be set for each heater */ -#if HAS_HOTEND - #if !HAS_HEATER_0 - #error "HEATER_0_PIN not defined for this board." - #elif TEMP_SENSOR_IS_MAX_TC(0) && !PIN_EXISTS(TEMP_0_CS) - #error "TEMP_SENSOR_0 MAX thermocouple requires TEMP_0_CS_PIN." - #elif TEMP_SENSOR_0 == 100 - #error "TEMP_SENSOR_0 can't use Soc temperature sensor." - #elif TEMP_SENSOR_0 == 0 - #error "TEMP_SENSOR_0 is required with 1 or more HOTENDS." - #elif !ANY_PIN(TEMP_0, TEMP_0_CS) && !TEMP_SENSOR_0_IS_DUMMY - #error "TEMP_0_PIN or TEMP_0_CS_PIN not defined for this board." - #endif - #if ANY(HAS_MULTI_HOTEND, HEATERS_PARALLEL) && !HAS_HEATER_1 - #error "HEATER_1_PIN is not defined. TEMP_SENSOR_1 might not be set, or the board (not EEB / EEF?) doesn't define a pin." - #endif - #if HAS_MULTI_HOTEND - #if TEMP_SENSOR_IS_MAX_TC(1) && !PIN_EXISTS(TEMP_1_CS) - #error "TEMP_SENSOR_1 MAX thermocouple requires TEMP_1_CS_PIN." - #elif TEMP_SENSOR_1 == 100 - #error "TEMP_SENSOR_1 can't use Soc temperature sensor." - #elif TEMP_SENSOR_1 == 0 - #error "TEMP_SENSOR_1 is required with 2 or more HOTENDS." - #elif !ANY_PIN(TEMP_1, TEMP_1_CS) && !TEMP_SENSOR_1_IS_DUMMY - #error "TEMP_1_PIN or TEMP_1_CS_PIN not defined for this board." - #endif - #if HOTENDS > 2 - #if TEMP_SENSOR_IS_MAX_TC(2) && !PIN_EXISTS(TEMP_2_CS) - #error "TEMP_SENSOR_2 MAX thermocouple requires TEMP_2_CS_PIN." - #elif TEMP_SENSOR_2 == 100 - #error "TEMP_SENSOR_2 can't use Soc temperature sensor." - #elif TEMP_SENSOR_2 == 0 - #error "TEMP_SENSOR_2 is required with 3 or more HOTENDS." - #elif !HAS_HEATER_2 - #error "HEATER_2_PIN not defined for this board." - #elif !ANY_PIN(TEMP_2, TEMP_2_CS) && !TEMP_SENSOR_2_IS_DUMMY - #error "TEMP_2_PIN or TEMP_2_CS_PIN not defined for this board." - #endif - #if HOTENDS > 3 - #if TEMP_SENSOR_3 == 100 - #error "TEMP_SENSOR_3 can't use Soc temperature sensor." - #elif TEMP_SENSOR_3 == 0 - #error "TEMP_SENSOR_3 is required with 4 or more HOTENDS." - #elif !HAS_HEATER_3 - #error "HEATER_3_PIN not defined for this board." - #elif !PIN_EXISTS(TEMP_3) && !TEMP_SENSOR_3_IS_DUMMY - #error "TEMP_3_PIN not defined for this board." - #endif - #if HOTENDS > 4 - #if TEMP_SENSOR_4 == 100 - #error "TEMP_SENSOR_4 can't use Soc temperature sensor." - #elif TEMP_SENSOR_4 == 0 - #error "TEMP_SENSOR_4 is required with 5 or more HOTENDS." - #elif !HAS_HEATER_4 - #error "HEATER_4_PIN not defined for this board." - #elif !PIN_EXISTS(TEMP_4) && !TEMP_SENSOR_4_IS_DUMMY - #error "TEMP_4_PIN not defined for this board." - #endif - #if HOTENDS > 5 - #if TEMP_SENSOR_5 == 100 - #error "TEMP_SENSOR_5 can't use Soc temperature sensor." - #elif TEMP_SENSOR_5 == 0 - #error "TEMP_SENSOR_5 is required with 6 HOTENDS." - #elif !HAS_HEATER_5 - #error "HEATER_5_PIN not defined for this board." - #elif !PIN_EXISTS(TEMP_5) && !TEMP_SENSOR_5_IS_DUMMY - #error "TEMP_5_PIN not defined for this board." - #endif - #if HOTENDS > 6 - #if TEMP_SENSOR_6 == 100 - #error "TEMP_SENSOR_6 can't use Soc temperature sensor." - #elif TEMP_SENSOR_6 == 0 - #error "TEMP_SENSOR_6 is required with 6 HOTENDS." - #elif !HAS_HEATER_6 - #error "HEATER_6_PIN not defined for this board." - #elif !PIN_EXISTS(TEMP_6) && !TEMP_SENSOR_6_IS_DUMMY - #error "TEMP_6_PIN not defined for this board." - #endif - #if HOTENDS > 7 - #if TEMP_SENSOR_7 == 100 - #error "TEMP_SENSOR_7 can't use Soc temperature sensor." - #elif TEMP_SENSOR_7 == 0 - #error "TEMP_SENSOR_7 is required with 7 HOTENDS." - #elif !HAS_HEATER_7 - #error "HEATER_7_PIN not defined for this board." - #elif !PIN_EXISTS(TEMP_7) && !TEMP_SENSOR_7_IS_DUMMY - #error "TEMP_7_PIN not defined for this board." - #endif - #endif // HOTENDS > 7 - #endif // HOTENDS > 6 - #endif // HOTENDS > 5 - #endif // HOTENDS > 4 - #endif // HOTENDS > 3 - #endif // HOTENDS > 2 - #endif // HAS_MULTI_HOTEND -#endif // HAS_HOTEND - -#if DO_TOOLCHANGE_FOR_PROBING && PROBING_TOOL >= EXTRUDERS - #error "PROBING_TOOL must be a valid tool index." +#if HAS_EXTRUDERS && !ANY_PIN(TEMP_0, TEMP_0_CS) + #error "TEMP_0_PIN or TEMP_0_CS_PIN not defined for this board." +#elif HAS_EXTRUDERS && !HAS_HEATER_0 + #error "HEATER_0_PIN not defined for this board." +#elif TEMP_SENSOR_IS_MAX_TC(0) && !PIN_EXISTS(TEMP_0_CS) + #error "TEMP_SENSOR_0 MAX thermocouple requires TEMP_0_CS_PIN." +#elif HAS_HOTEND && !HAS_TEMP_HOTEND && !TEMP_SENSOR_0_IS_DUMMY + #error "TEMP_0_PIN (required for TEMP_SENSOR_0) not defined for this board." +#elif EITHER(HAS_MULTI_HOTEND, HEATERS_PARALLEL) && !HAS_HEATER_1 + #error "HEATER_1_PIN is not defined. TEMP_SENSOR_1 might not be set, or the board (not EEB / EEF?) doesn't define a pin." #endif +#if HAS_MULTI_HOTEND + #if TEMP_SENSOR_IS_MAX_TC(1) && !PIN_EXISTS(TEMP_1_CS) + #error "TEMP_SENSOR_1 MAX thermocouple requires TEMP_1_CS_PIN." + #elif TEMP_SENSOR_1 == 0 + #error "TEMP_SENSOR_1 is required with 2 or more HOTENDS." + #elif !ANY_PIN(TEMP_1, TEMP_1_CS) && !TEMP_SENSOR_1_IS_DUMMY + #error "TEMP_1_PIN or TEMP_1_CS_PIN not defined for this board." + #endif + #if HOTENDS > 2 + #if TEMP_SENSOR_2 == 0 + #error "TEMP_SENSOR_2 is required with 3 or more HOTENDS." + #elif !HAS_HEATER_2 + #error "HEATER_2_PIN not defined for this board." + #elif !PIN_EXISTS(TEMP_2) && !TEMP_SENSOR_2_IS_DUMMY + #error "TEMP_2_PIN not defined for this board." + #endif + #if HOTENDS > 3 + #if TEMP_SENSOR_3 == 0 + #error "TEMP_SENSOR_3 is required with 4 or more HOTENDS." + #elif !HAS_HEATER_3 + #error "HEATER_3_PIN not defined for this board." + #elif !PIN_EXISTS(TEMP_3) && !TEMP_SENSOR_3_IS_DUMMY + #error "TEMP_3_PIN not defined for this board." + #endif + #if HOTENDS > 4 + #if TEMP_SENSOR_4 == 0 + #error "TEMP_SENSOR_4 is required with 5 or more HOTENDS." + #elif !HAS_HEATER_4 + #error "HEATER_4_PIN not defined for this board." + #elif !PIN_EXISTS(TEMP_4) && !TEMP_SENSOR_4_IS_DUMMY + #error "TEMP_4_PIN not defined for this board." + #endif + #if HOTENDS > 5 + #if TEMP_SENSOR_5 == 0 + #error "TEMP_SENSOR_5 is required with 6 HOTENDS." + #elif !HAS_HEATER_5 + #error "HEATER_5_PIN not defined for this board." + #elif !PIN_EXISTS(TEMP_5) && !TEMP_SENSOR_5_IS_DUMMY + #error "TEMP_5_PIN not defined for this board." + #endif + #if HOTENDS > 6 + #if TEMP_SENSOR_6 == 0 + #error "TEMP_SENSOR_6 is required with 6 HOTENDS." + #elif !HAS_HEATER_6 + #error "HEATER_6_PIN not defined for this board." + #elif !PIN_EXISTS(TEMP_6) && !TEMP_SENSOR_6_IS_DUMMY + #error "TEMP_6_PIN not defined for this board." + #endif + #if HOTENDS > 7 + #if TEMP_SENSOR_7 == 0 + #error "TEMP_SENSOR_7 is required with 7 HOTENDS." + #elif !HAS_HEATER_7 + #error "HEATER_7_PIN not defined for this board." + #elif !PIN_EXISTS(TEMP_7) && !TEMP_SENSOR_7_IS_DUMMY + #error "TEMP_7_PIN not defined for this board." + #endif + #endif // HOTENDS > 7 + #endif // HOTENDS > 6 + #endif // HOTENDS > 5 + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 +#endif // HAS_MULTI_HOTEND + /** * Pins must be set for temp sensors, with some other feature requirements. */ -#if TEMP_SENSOR_BED == 100 - #error "TEMP_SENSOR_BED can't use Soc temperature sensor." -#endif - -#if TEMP_SENSOR_CHAMBER - #if TEMP_SENSOR_CHAMBER == 100 - #error "TEMP_SENSOR_CHAMBER can't use Soc temperature sensor." - #elif !PIN_EXISTS(TEMP_CHAMBER) - #error "TEMP_SENSOR_CHAMBER requires TEMP_CHAMBER_PIN." - #endif +#if TEMP_SENSOR_CHAMBER && !PIN_EXISTS(TEMP_CHAMBER) + #error "TEMP_SENSOR_CHAMBER requires TEMP_CHAMBER_PIN." #endif #if TEMP_SENSOR_COOLER - #if TEMP_SENSOR_COOLER == 100 - #error "TEMP_SENSOR_COOLER can't use Soc temperature sensor." - #elif !PIN_EXISTS(TEMP_COOLER) + #if !PIN_EXISTS(TEMP_COOLER) #error "TEMP_SENSOR_COOLER requires TEMP_COOLER_PIN." #elif DISABLED(LASER_FEATURE) #error "TEMP_SENSOR_COOLER requires LASER_FEATURE." @@ -2220,9 +2554,7 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #endif #if TEMP_SENSOR_PROBE - #if TEMP_SENSOR_PROBE == 100 - #error "TEMP_SENSOR_PROBE can't use Soc temperature sensor." - #elif !PIN_EXISTS(TEMP_PROBE) + #if !PIN_EXISTS(TEMP_PROBE) #error "TEMP_SENSOR_PROBE requires TEMP_PROBE_PIN." #elif DISABLED(FIX_MOUNTED_PROBE) #error "TEMP_SENSOR_PROBE shouldn't be set without FIX_MOUNTED_PROBE." @@ -2230,9 +2562,7 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #endif #if TEMP_SENSOR_BOARD - #if TEMP_SENSOR_BOARD == 100 - #error "TEMP_SENSOR_BOARD can't use Soc temperature sensor." - #elif !PIN_EXISTS(TEMP_BOARD) + #if !PIN_EXISTS(TEMP_BOARD) #error "TEMP_SENSOR_BOARD requires TEMP_BOARD_PIN." #elif ENABLED(THERMAL_PROTECTION_BOARD) && (!defined(BOARD_MINTEMP) || !defined(BOARD_MAXTEMP)) #error "THERMAL_PROTECTION_BOARD requires BOARD_MINTEMP and BOARD_MAXTEMP." @@ -2241,16 +2571,8 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #error "CONTROLLER_FAN_MIN_BOARD_TEMP requires TEMP_SENSOR_BOARD." #endif -#if TEMP_SENSOR_SOC - #if TEMP_SENSOR_SOC != 100 - #error "TEMP_SENSOR_SOC requires TEMP_SENSOR_SOC 100." - #elif !PIN_EXISTS(TEMP_SOC) - #error "TEMP_SENSOR_SOC requires TEMP_SOC_PIN." - #elif ENABLED(THERMAL_PROTECTION_SOC) && !defined(SOC_MAXTEMP) - #error "THERMAL_PROTECTION_SOC requires SOC_MAXTEMP." - #endif -#elif CONTROLLER_FAN_MIN_SOC_TEMP - #error "CONTROLLER_FAN_MIN_SOC_TEMP requires TEMP_SENSOR_SOC." +#if TEMP_SENSOR_BOARD && !PIN_EXISTS(TEMP_BOARD) + #error "TEMP_SENSOR_BOARD requires TEMP_BOARD_PIN." #endif #if ENABLED(LASER_COOLANT_FLOW_METER) && !(PIN_EXISTS(FLOWMETER) && ENABLED(LASER_FEATURE)) @@ -2289,23 +2611,23 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #endif /** - * FYSETC/MKS/BTT/BEEZ Mini Panel Requirements + * FYSETC/MKS/BTT Mini Panel Requirements */ -#if ANY(FYSETC_242_OLED_12864, FYSETC_MINI_12864_2_1) +#if EITHER(FYSETC_242_OLED_12864, FYSETC_MINI_12864_2_1) #ifndef NEO_RGB #define NEO_RGB 123 #define FAUX_RGB 1 #endif #if defined(NEOPIXEL_TYPE) && NEOPIXEL_TYPE != NEO_RGB - #error "Your FYSETC/MKS/BTT/BEEZ Mini Panel requires NEOPIXEL_TYPE to be NEO_RGB." + #error "Your FYSETC/MKS/BTT Mini Panel requires NEOPIXEL_TYPE to be NEO_RGB." #elif defined(NEOPIXEL_PIXELS) && NEOPIXEL_PIXELS < 3 - #error "Your FYSETC/MKS/BTT/BEEZ Mini Panel requires NEOPIXEL_PIXELS >= 3." + #error "Your FYSETC/MKS/BTT Mini Panel requires NEOPIXEL_PIXELS >= 3." #endif #if FAUX_RGB #undef NEO_RGB #undef FAUX_RGB #endif -#elif ANY(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) && DISABLED(RGB_LED) +#elif EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0) && DISABLED(RGB_LED) #error "Your FYSETC Mini Panel requires RGB_LED." #endif @@ -2326,8 +2648,8 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #error "MULTI_NOZZLE_DUPLICATION is incompatible with DUAL_X_CARRIAGE." #elif ENABLED(MIXING_EXTRUDER) #error "MULTI_NOZZLE_DUPLICATION is incompatible with MIXING_EXTRUDER." - #elif HAS_SWITCHING_EXTRUDER - #error "MULTI_NOZZLE_DUPLICATION is incompatible with (MECHANICAL_)SWITCHING_EXTRUDER." + #elif ENABLED(SWITCHING_EXTRUDER) + #error "MULTI_NOZZLE_DUPLICATION is incompatible with SWITCHING_EXTRUDER." #elif HOTENDS < 2 #error "MULTI_NOZZLE_DUPLICATION requires 2 or more hotends." #endif @@ -2341,8 +2663,8 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #error "E0_STEP_PIN or E0_DIR_PIN not defined for this board." #elif ( !(defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && (!PINS_EXIST(E0_STEP, E0_DIR) || !HAS_E0_ENABLE)) #error "E0_STEP_PIN, E0_DIR_PIN, or E0_ENABLE_PIN not defined for this board." - #elif HOTENDS && TEMP_SENSOR_0 == 0 - #error "TEMP_SENSOR_0 is required if there are any hotends." + #elif EXTRUDERS && TEMP_SENSOR_0 == 0 + #error "TEMP_SENSOR_0 is required if there are any extruders." #endif #endif @@ -2374,90 +2696,121 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i /** * Endstop Tests */ -#if !IS_SCARA - // Delta and Cartesian require some kind of endstop - #if X_HOME_TO_MIN && !HAS_X_MIN_STATE - #error "X_MIN_PIN, X_STOP_PIN, or X_SPI_SENSORLESS is required for X axis homing." - #elif X_HOME_TO_MAX && !HAS_X_MAX_STATE - #error "X_MAX_PIN, X_STOP_PIN, or X_SPI_SENSORLESS is required for X axis homing." - #elif Y_HOME_TO_MIN && !HAS_Y_MIN_STATE - #error "Y_MIN_PIN, Y_STOP_PIN, or Y_SPI_SENSORLESS is required for Y axis homing." - #elif Y_HOME_TO_MAX && !HAS_Y_MAX_STATE - #error "Y_MAX_PIN, Y_STOP_PIN, or Y_SPI_SENSORLESS is required for Y axis homing." - #elif Z_HOME_TO_MIN && NONE(HAS_Z_MIN_STATE, USE_PROBE_FOR_Z_HOMING) - #error "Z_MIN_PIN, Z_STOP_PIN, Z_SPI_SENSORLESS, or USE_PROBE_FOR_Z_HOMING is required for Z axis homing." - #elif Z_HOME_TO_MAX && !HAS_Z_MAX_STATE - #error "Z_MAX_PIN, Z_STOP_PIN, or Z_SPI_SENSORLESS is required for Z axis homing." - #elif I_HOME_TO_MIN && !HAS_I_MIN_STATE - #error "I_MIN_PIN, I_STOP_PIN, or I_SPI_SENSORLESS is required for I axis homing." - #elif I_HOME_TO_MAX && !HAS_I_MAX_STATE - #error "I_MAX_PIN, I_STOP_PIN, or I_SPI_SENSORLESS is required for I axis homing." - #elif J_HOME_TO_MIN && !HAS_J_MIN_STATE - #error "J_MIN_PIN, J_STOP_PIN, or J_SPI_SENSORLESS is required for J axis homing." - #elif J_HOME_TO_MAX && !HAS_J_MAX_STATE - #error "J_MAX_PIN, J_STOP_PIN, or J_SPI_SENSORLESS is required for J axis homing." - #elif K_HOME_TO_MIN && !HAS_K_MIN_STATE - #error "K_MIN_PIN, K_STOP_PIN, or K_SPI_SENSORLESS is required for K axis homing." - #elif K_HOME_TO_MAX && !HAS_K_MAX_STATE - #error "K_MAX_PIN, K_STOP_PIN, or K_SPI_SENSORLESS is required for K axis homing." - #elif U_HOME_TO_MIN && !HAS_U_MIN_STATE - #error "U_MIN_PIN, U_STOP_PIN, or U_SPI_SENSORLESS is required for U axis homing." - #elif U_HOME_TO_MAX && !HAS_U_MAX_STATE - #error "U_MAX_PIN, U_STOP_PIN, or U_SPI_SENSORLESS is required for U axis homing." - #elif V_HOME_TO_MIN && !HAS_V_MIN_STATE - #error "V_MIN_PIN, V_STOP_PIN, or V_SPI_SENSORLESS is required for V axis homing." - #elif V_HOME_TO_MAX && !HAS_V_MAX_STATE - #error "V_MAX_PIN, V_STOP_PIN, or V_SPI_SENSORLESS is required for V axis homing." - #elif W_HOME_TO_MIN && !HAS_W_MIN_STATE - #error "W_MIN_PIN, W_STOP_PIN, or W_SPI_SENSORLESS is required for W axis homing." - #elif W_HOME_TO_MAX && !HAS_W_MAX_STATE - #error "W_MAX_PIN, W_STOP_PIN, or W_SPI_SENSORLESS is required for W axis homing." + +#define _PLUG_UNUSED_TEST(A,P) (DISABLED(USE_##P##MIN_PLUG, USE_##P##MAX_PLUG) \ + && !(ENABLED(A##_DUAL_ENDSTOPS) && WITHIN(A##2_USE_ENDSTOP, _##P##MAX_, _##P##MIN_)) \ + && !(ENABLED(A##_MULTI_ENDSTOPS) && WITHIN(A##2_USE_ENDSTOP, _##P##MAX_, _##P##MIN_)) ) +#define _AXIS_PLUG_UNUSED_TEST(A) (HAS_##A##_A NUM_AXIS_GANG(&& _PLUG_UNUSED_TEST(A,X), && _PLUG_UNUSED_TEST(A,Y), && _PLUG_UNUSED_TEST(A,Z), \ + && _PLUG_UNUSED_TEST(A,I), && _PLUG_UNUSED_TEST(A,J), && _PLUG_UNUSED_TEST(A,K), \ + && _PLUG_UNUSED_TEST(A,U), && _PLUG_UNUSED_TEST(A,V), && _PLUG_UNUSED_TEST(A,W) ) ) + +// A machine with endstops must have a minimum of 3 +#if HAS_ENDSTOPS + #if _AXIS_PLUG_UNUSED_TEST(X) + #error "You must enable USE_XMIN_PLUG or USE_XMAX_PLUG." + #endif + #if _AXIS_PLUG_UNUSED_TEST(Y) + #error "You must enable USE_YMIN_PLUG or USE_YMAX_PLUG." + #endif + #if _AXIS_PLUG_UNUSED_TEST(Z) + #error "You must enable USE_ZMIN_PLUG or USE_ZMAX_PLUG." + #endif + #if _AXIS_PLUG_UNUSED_TEST(I) + #error "You must enable USE_IMIN_PLUG or USE_IMAX_PLUG." + #endif + #if _AXIS_PLUG_UNUSED_TEST(J) + #error "You must enable USE_JMIN_PLUG or USE_JMAX_PLUG." + #endif + #if _AXIS_PLUG_UNUSED_TEST(K) + #error "You must enable USE_KMIN_PLUG or USE_KMAX_PLUG." + #endif + #if _AXIS_PLUG_UNUSED_TEST(U) + #error "You must enable USE_UMIN_PLUG or USE_UMAX_PLUG." + #endif + #if _AXIS_PLUG_UNUSED_TEST(V) + #error "You must enable USE_VMIN_PLUG or USE_VMAX_PLUG." + #endif + #if _AXIS_PLUG_UNUSED_TEST(W) + #error "You must enable USE_WMIN_PLUG or USE_WMAX_PLUG." + #endif + + // Delta and Cartesian use 3 homing endstops + #if NONE(IS_SCARA, SPI_ENDSTOPS) + #if X_HOME_TO_MIN && DISABLED(USE_XMIN_PLUG) + #error "Enable USE_XMIN_PLUG when homing X to MIN." + #elif X_HOME_TO_MAX && DISABLED(USE_XMAX_PLUG) + #error "Enable USE_XMAX_PLUG when homing X to MAX." + #elif Y_HOME_TO_MIN && DISABLED(USE_YMIN_PLUG) + #error "Enable USE_YMIN_PLUG when homing Y to MIN." + #elif Y_HOME_TO_MAX && DISABLED(USE_YMAX_PLUG) + #error "Enable USE_YMAX_PLUG when homing Y to MAX." + #elif I_HOME_TO_MIN && DISABLED(USE_IMIN_PLUG) + #error "Enable USE_IMIN_PLUG when homing I to MIN." + #elif I_HOME_TO_MAX && DISABLED(USE_IMAX_PLUG) + #error "Enable USE_IMAX_PLUG when homing I to MAX." + #elif J_HOME_TO_MIN && DISABLED(USE_JMIN_PLUG) + #error "Enable USE_JMIN_PLUG when homing J to MIN." + #elif J_HOME_TO_MAX && DISABLED(USE_JMAX_PLUG) + #error "Enable USE_JMAX_PLUG when homing J to MAX." + #elif K_HOME_TO_MIN && DISABLED(USE_KMIN_PLUG) + #error "Enable USE_KMIN_PLUG when homing K to MIN." + #elif K_HOME_TO_MAX && DISABLED(USE_KMAX_PLUG) + #error "Enable USE_KMAX_PLUG when homing K to MAX." + #elif U_HOME_TO_MIN && DISABLED(USE_UMIN_PLUG) + #error "Enable USE_UMIN_PLUG when homing U to MIN." + #elif U_HOME_TO_MAX && DISABLED(USE_UMAX_PLUG) + #error "Enable USE_UMAX_PLUG when homing U to MAX." + #elif V_HOME_TO_MIN && DISABLED(USE_VMIN_PLUG) + #error "Enable USE_VMIN_PLUG when homing V to MIN." + #elif V_HOME_TO_MAX && DISABLED(USE_VMAX_PLUG) + #error "Enable USE_VMAX_PLUG when homing V to MAX." + #elif W_HOME_TO_MIN && DISABLED(USE_WMIN_PLUG) + #error "Enable USE_WMIN_PLUG when homing W to MIN." + #elif W_HOME_TO_MAX && DISABLED(USE_WMAX_PLUG) + #error "Enable USE_WMAX_PLUG when homing W to MAX." + #endif + #endif + + // Z homing direction and plug usage flags + #if Z_HOME_TO_MIN && NONE(USE_ZMIN_PLUG, HOMING_Z_WITH_PROBE) + #error "Enable USE_ZMIN_PLUG when homing Z to MIN." + #elif Z_HOME_TO_MAX && ENABLED(USE_PROBE_FOR_Z_HOMING) + #error "Z_HOME_DIR must be -1 when homing Z with the probe." + #elif BOTH(HOMING_Z_WITH_PROBE, Z_MULTI_ENDSTOPS) + #error "Z_MULTI_ENDSTOPS is incompatible with USE_PROBE_FOR_Z_HOMING." + #elif Z_HOME_TO_MAX && DISABLED(USE_ZMAX_PLUG) + #error "Enable USE_ZMAX_PLUG when homing Z to MAX." #endif #endif -// Z homing with probe requirements -#if ALL(HOMING_Z_WITH_PROBE, Z_MULTI_ENDSTOPS) - #error "Z_MULTI_ENDSTOPS is incompatible with USE_PROBE_FOR_Z_HOMING (i.e., Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)." -#elif ALL(USE_PROBE_FOR_Z_HOMING, Z_HOME_TO_MAX) - #error "Z_HOME_DIR must be -1 when homing Z with the probe." -#elif ALL(USE_PROBE_FOR_Z_HOMING, HOME_Z_FIRST) +#if BOTH(HOME_Z_FIRST, USE_PROBE_FOR_Z_HOMING) #error "HOME_Z_FIRST can't be used when homing Z with a probe." #endif -#if Z_HOME_TO_MAX && defined(Z_AFTER_HOMING) && DISABLED(ALLOW_Z_AFTER_HOMING) - #error "Z_AFTER_HOMING shouldn't be used with Z max homing to keep 'G28 Z' safe for end-of-print usage. Define ALLOW_Z_AFTER_HOMING to allow this at your own risk." -#endif - // Dual/multiple endstops requirements #if ENABLED(X_DUAL_ENDSTOPS) #if ENABLED(DELTA) #error "X_DUAL_ENDSTOPS is not compatible with DELTA." - #elif !HAS_X2_STATE - #error "Some kind of X2 Endstop must be defined for X_DUAL_ENDSTOPS." - #elif X_SPI_SENSORLESS && !AXIS_HAS_SPI(X2) - #error "All X Stepper Drivers must be SPI-capable to use SPI Endstops on X." + #elif !X2_USE_ENDSTOP + #error "X2_USE_ENDSTOP must be set with X_DUAL_ENDSTOPS." #endif #endif #if ENABLED(Y_DUAL_ENDSTOPS) #if ENABLED(DELTA) #error "Y_DUAL_ENDSTOPS is not compatible with DELTA." - #elif !HAS_Y2_STATE - #error "Some kind of Y2 Endstop must be defined for Y_DUAL_ENDSTOPS." - #elif Y_SPI_SENSORLESS && !AXIS_HAS_SPI(Y2) - #error "All Y Stepper Drivers must be SPI-capable to use SPI Endstops on Y." + #elif !Y2_USE_ENDSTOP + #error "Y2_USE_ENDSTOP must be set with Y_DUAL_ENDSTOPS." #endif #endif #if ENABLED(Z_MULTI_ENDSTOPS) #if ENABLED(DELTA) #error "Z_MULTI_ENDSTOPS is not compatible with DELTA." - #elif !HAS_Z2_STATE - #error "Some kind of Z2 Endstop must be defined for Z_MULTI_ENDSTOPS." - #elif NUM_Z_STEPPERS >= 3 && !HAS_Z3_STATE - #error "Some kind of Z3 Endstop must be defined for Z_MULTI_ENDSTOPS and Z3_DRIVER_TYPE." - #elif NUM_Z_STEPPERS >= 4 && !HAS_Z4_STATE - #error "Some kind of Z4 Endstop must be defined for Z_MULTI_ENDSTOPS and Z4_DRIVER_TYPE." - #elif Z_SPI_SENSORLESS && !(AXIS_HAS_SPI(Z2) && (NUM_Z_STEPPERS < 3 || AXIS_HAS_SPI(Z3)) && (NUM_Z_STEPPERS < 4 || AXIS_HAS_SPI(Z4))) - #error "All Z Stepper Drivers must be SPI-capable to use SPI Endstops on Z." + #elif !Z2_USE_ENDSTOP + #error "Z2_USE_ENDSTOP must be set with Z_MULTI_ENDSTOPS." + #elif !Z3_USE_ENDSTOP && NUM_Z_STEPPERS >= 3 + #error "Z3_USE_ENDSTOP must be set with Z_MULTI_ENDSTOPS and Z3_DRIVER_TYPE." + #elif !Z4_USE_ENDSTOP && NUM_Z_STEPPERS >= 4 + #error "Z4_USE_ENDSTOP must be set with Z_MULTI_ENDSTOPS and Z4_DRIVER_TYPE." #endif #endif @@ -2556,30 +2909,45 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i * Auto Fan check for PWM pins */ #if HAS_AUTO_FAN && EXTRUDER_AUTO_FAN_SPEED != 255 - #define AF_ASSERT(N) OPTCODE(HAS_AUTO_FAN_##N, static_assert(_TEST_PWM(E##N##_AUTO_FAN_PIN), "E" STRINGIFY(N) "_AUTO_FAN_PIN is not a PWM pin. Set EXTRUDER_AUTO_FAN_SPEED to 255.")) - REPEAT(8, AF_ASSERT) - #undef AF_ASSERT + #define AF_ERR_SUFF "_AUTO_FAN_PIN is not a PWM pin. Set EXTRUDER_AUTO_FAN_SPEED to 255." + #if HAS_AUTO_FAN_0 + static_assert(_TEST_PWM(E0_AUTO_FAN_PIN), "E0" AF_ERR_SUFF); + #elif HAS_AUTO_FAN_1 + static_assert(_TEST_PWM(E1_AUTO_FAN_PIN), "E1" AF_ERR_SUFF); + #elif HAS_AUTO_FAN_2 + static_assert(_TEST_PWM(E2_AUTO_FAN_PIN), "E2" AF_ERR_SUFF); + #elif HAS_AUTO_FAN_3 + static_assert(_TEST_PWM(E3_AUTO_FAN_PIN), "E3" AF_ERR_SUFF); + #elif HAS_AUTO_FAN_4 + static_assert(_TEST_PWM(E4_AUTO_FAN_PIN), "E4" AF_ERR_SUFF); + #elif HAS_AUTO_FAN_5 + static_assert(_TEST_PWM(E5_AUTO_FAN_PIN), "E5" AF_ERR_SUFF); + #elif HAS_AUTO_FAN_6 + static_assert(_TEST_PWM(E6_AUTO_FAN_PIN), "E6" AF_ERR_SUFF); + #elif HAS_AUTO_FAN_7 + static_assert(_TEST_PWM(E7_AUTO_FAN_PIN), "E7" AF_ERR_SUFF); + #endif #endif /** * Fan check */ #if HAS_FANCHECK - #if ALL(E0_FAN_TACHO_PULLUP, E0_FAN_TACHO_PULLDOWN) + #if BOTH(E0_FAN_TACHO_PULLUP, E0_FAN_TACHO_PULLDOWN) #error "Enable only one of E0_FAN_TACHO_PULLUP or E0_FAN_TACHO_PULLDOWN." - #elif ALL(E1_FAN_TACHO_PULLUP, E1_FAN_TACHO_PULLDOWN) + #elif BOTH(E1_FAN_TACHO_PULLUP, E1_FAN_TACHO_PULLDOWN) #error "Enable only one of E1_FAN_TACHO_PULLUP or E1_FAN_TACHO_PULLDOWN." - #elif ALL(E2_FAN_TACHO_PULLUP, E2_FAN_TACHO_PULLDOWN) + #elif BOTH(E2_FAN_TACHO_PULLUP, E2_FAN_TACHO_PULLDOWN) #error "Enable only one of E2_FAN_TACHO_PULLUP or E2_FAN_TACHO_PULLDOWN." - #elif ALL(E3_FAN_TACHO_PULLUP, E3_FAN_TACHO_PULLDOWN) + #elif BOTH(E3_FAN_TACHO_PULLUP, E3_FAN_TACHO_PULLDOWN) #error "Enable only one of E3_FAN_TACHO_PULLUP or E3_FAN_TACHO_PULLDOWN." - #elif ALL(E4_FAN_TACHO_PULLUP, E4_FAN_TACHO_PULLDOWN) + #elif BOTH(E4_FAN_TACHO_PULLUP, E4_FAN_TACHO_PULLDOWN) #error "Enable only one of E4_FAN_TACHO_PULLUP or E4_FAN_TACHO_PULLDOWN." - #elif ALL(E5_FAN_TACHO_PULLUP, E5_FAN_TACHO_PULLDOWN) + #elif BOTH(E5_FAN_TACHO_PULLUP, E5_FAN_TACHO_PULLDOWN) #error "Enable only one of E5_FAN_TACHO_PULLUP or E5_FAN_TACHO_PULLDOWN." - #elif ALL(E6_FAN_TACHO_PULLUP, E6_FAN_TACHO_PULLDOWN) + #elif BOTH(E6_FAN_TACHO_PULLUP, E6_FAN_TACHO_PULLDOWN) #error "Enable only one of E6_FAN_TACHO_PULLUP or E6_FAN_TACHO_PULLDOWN." - #elif ALL(E7_FAN_TACHO_PULLUP, E7_FAN_TACHO_PULLDOWN) + #elif BOTH(E7_FAN_TACHO_PULLUP, E7_FAN_TACHO_PULLDOWN) #error "Enable only one of E7_FAN_TACHO_PULLUP or E7_FAN_TACHO_PULLDOWN." #endif #elif ENABLED(AUTO_REPORT_FANS) @@ -2605,13 +2973,14 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i /** * Make sure features that need to write to the SD card can */ -#if ENABLED(SDCARD_READONLY) +#if ENABLED(SDCARD_READONLY) && ANY(POWER_LOSS_RECOVERY, BINARY_FILE_TRANSFER, SDCARD_EEPROM_EMULATION) + #undef SDCARD_READONLY #if ENABLED(POWER_LOSS_RECOVERY) - #error "Either disable SDCARD_READONLY or disable POWER_LOSS_RECOVERY." + #warning "Either disable SDCARD_READONLY or disable POWER_LOSS_RECOVERY." #elif ENABLED(BINARY_FILE_TRANSFER) - #error "Either disable SDCARD_READONLY or disable BINARY_FILE_TRANSFER." + #warning "Either disable SDCARD_READONLY or disable BINARY_FILE_TRANSFER." #elif ENABLED(SDCARD_EEPROM_EMULATION) - #error "Either disable SDCARD_READONLY or disable SDCARD_EEPROM_EMULATION." + #warning "Either disable SDCARD_READONLY or disable SDCARD_EEPROM_EMULATION." #endif #endif @@ -2632,25 +3001,24 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i + (ENABLED(U8GLIB_SSD1306) && DISABLED(IS_U8GLIB_SSD1306)) \ + (ENABLED(MINIPANEL) && NONE(MKS_MINI_12864, ENDER2_STOCKDISPLAY)) \ + (ENABLED(MKS_MINI_12864) && NONE(MKS_LCD12864A, MKS_LCD12864B)) \ - + (ENABLED(FYSETC_MINI_12864_2_1) && NONE(MKS_MINI_12864_V3, BTT_MINI_12864, BEEZ_MINI_12864)) \ - + COUNT_ENABLED(MKS_MINI_12864_V3, BTT_MINI_12864, BEEZ_MINI_12864) \ + + (ENABLED(FYSETC_MINI_12864_2_1) && NONE(MKS_MINI_12864_V3, BTT_MINI_12864_V1)) \ + + COUNT_ENABLED(MKS_MINI_12864_V3, BTT_MINI_12864_V1) \ + (ENABLED(EXTENSIBLE_UI) && DISABLED(IS_EXTUI)) \ + (DISABLED(IS_LEGACY_TFT) && ENABLED(TFT_GENERIC)) \ + (ENABLED(IS_LEGACY_TFT) && COUNT_ENABLED(TFT_320x240, TFT_320x240_SPI, TFT_480x320, TFT_480x320_SPI)) \ - + COUNT_ENABLED(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON, ANYCUBIC_TFT35, ANYCUBIC_LCD_VYPER) \ - + DGUS_UI_IS(ORIGIN) + DGUS_UI_IS(FYSETC) + DGUS_UI_IS(HIPRECY) + DGUS_UI_IS(MKS) + DGUS_UI_IS(RELOADED) + DGUS_UI_IS(IA_CREALITY) \ + + COUNT_ENABLED(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON, ANYCUBIC_TFT35) \ + + COUNT_ENABLED(DGUS_LCD_UI_ORIGIN, DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_HIPRECY, DGUS_LCD_UI_MKS, DGUS_LCD_UI_RELOADED) \ + COUNT_ENABLED(ENDER2_STOCKDISPLAY, CR10_STOCKDISPLAY) \ + COUNT_ENABLED(DWIN_CREALITY_LCD, DWIN_LCD_PROUI, DWIN_CREALITY_LCD_JYERSUI, DWIN_MARLINUI_PORTRAIT, DWIN_MARLINUI_LANDSCAPE) \ + COUNT_ENABLED(FYSETC_MINI_12864_X_X, FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0, FYSETC_GENERIC_12864_1_1) \ + COUNT_ENABLED(LCD_SAINSMART_I2C_1602, LCD_SAINSMART_I2C_2004) \ + COUNT_ENABLED(MKS_12864OLED, MKS_12864OLED_SSD1306) \ - + COUNT_ENABLED(MKS_TS35_V2_0, MKS_ROBIN_TFT24, MKS_ROBIN_TFT28, MKS_ROBIN_TFT32, MKS_ROBIN_TFT35, MKS_ROBIN_TFT43, \ - MKS_ROBIN_TFT_V1_1R, ANET_ET4_TFT28, ANET_ET5_TFT35, BIQU_BX_TFT70, BTT_TFT35_SPI_V1_0) \ + + COUNT_ENABLED(MKS_TS35_V2_0, MKS_ROBIN_TFT24, MKS_ROBIN_TFT28, MKS_ROBIN_TFT32, MKS_ROBIN_TFT35, MKS_ROBIN_TFT43, MKS_ROBIN_TFT_V1_1R, ANET_ET4_TFT28, ANET_ET5_TFT35, BIQU_BX_TFT70, BTT_TFT35_SPI_V1_0) \ + COUNT_ENABLED(TFTGLCD_PANEL_SPI, TFTGLCD_PANEL_I2C) \ + COUNT_ENABLED(VIKI2, miniVIKI) \ + ENABLED(WYH_L12864) \ + COUNT_ENABLED(ZONESTAR_12864LCD, ZONESTAR_12864OLED, ZONESTAR_12864OLED_SSD1306) \ - + COUNT_ENABLED(ANET_FULL_GRAPHICS_LCD, CTC_A10S_A13) \ + + COUNT_ENABLED(ANET_FULL_GRAPHICS_LCD, ANET_FULL_GRAPHICS_LCD_ALT_WIRING) \ + ENABLED(AZSMZ_12864) \ + ENABLED(BQ_LCD_SMART_CONTROLLER) \ + ENABLED(CARTESIO_UI) \ @@ -2696,8 +3064,7 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #undef IS_U8GLIB_SSD1306 #undef IS_EXTUI -#if ANY(TFT_GENERIC, MKS_TS35_V2_0, MKS_ROBIN_TFT24, MKS_ROBIN_TFT28, MKS_ROBIN_TFT32, MKS_ROBIN_TFT35, MKS_ROBIN_TFT43, MKS_ROBIN_TFT_V1_1R, \ - TFT_TRONXY_X5SA, ANYCUBIC_TFT35, ANYCUBIC_TFT35, LONGER_LK_TFT28, ANET_ET4_TFT28, ANET_ET5_TFT35, BIQU_BX_TFT70, BTT_TFT35_SPI_V1_0) +#if ANY(TFT_GENERIC, MKS_TS35_V2_0, MKS_ROBIN_TFT24, MKS_ROBIN_TFT28, MKS_ROBIN_TFT32, MKS_ROBIN_TFT35, MKS_ROBIN_TFT43, MKS_ROBIN_TFT_V1_1R, TFT_TRONXY_X5SA, ANYCUBIC_TFT35, ANYCUBIC_TFT35, LONGER_LK_TFT28, ANET_ET4_TFT28, ANET_ET5_TFT35, BIQU_BX_TFT70, BTT_TFT35_SPI_V1_0) #if NONE(TFT_COLOR_UI, TFT_CLASSIC_UI, TFT_LVGL_UI) #error "TFT_COLOR_UI, TFT_CLASSIC_UI, TFT_LVGL_UI is required for your TFT. Please enable one." #elif MANY(TFT_COLOR_UI, TFT_CLASSIC_UI, TFT_LVGL_UI) @@ -2709,8 +3076,10 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #if ENABLED(TFT_GENERIC) && NONE(TFT_INTERFACE_FSMC, TFT_INTERFACE_SPI) #error "TFT_GENERIC requires either TFT_INTERFACE_FSMC or TFT_INTERFACE_SPI interface." -#elif ALL(TFT_INTERFACE_FSMC, TFT_INTERFACE_SPI) - #error "Please enable only one of TFT_INTERFACE_FSMC or TFT_INTERFACE_SPI." +#endif + +#if BOTH(TFT_INTERFACE_FSMC, TFT_INTERFACE_SPI) + #error "Please enable only one of TFT_INTERFACE_SPI or TFT_INTERFACE_SPI." #endif #if defined(LCD_SCREEN_ROTATE) && LCD_SCREEN_ROTATE != 0 && LCD_SCREEN_ROTATE != 90 && LCD_SCREEN_ROTATE != 180 && LCD_SCREEN_ROTATE != 270 @@ -2724,7 +3093,7 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #if ENABLED(TFT_LVGL_UI) #if DISABLED(TFT_RES_480x320) #error "TFT_LVGL_UI requires TFT_RES_480x320." - #elif !HAS_MEDIA + #elif DISABLED(SDSUPPORT) #error "TFT_LVGL_UI requires SDSUPPORT." #endif #endif @@ -2733,14 +3102,14 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #error "GRAPHICAL_TFT_UPSCALE must be between 2 and 8." #endif -#if ALL(CHIRON_TFT_STANDARD, CHIRON_TFT_NEW) +#if BOTH(CHIRON_TFT_STANDARD, CHIRON_TFT_NEW) #error "Please select only one of CHIRON_TFT_STANDARD or CHIRON_TFT_NEW." #endif #if ENABLED(ANYCUBIC_LCD_CHIRON) #ifndef BEEPER_PIN #error "ANYCUBIC_LCD_CHIRON requires BEEPER_PIN" - #elif !HAS_MEDIA + #elif DISABLED(SDSUPPORT) #error "ANYCUBIC_LCD_CHIRON requires SDSUPPORT" #elif TEMP_SENSOR_BED == 0 #error "ANYCUBIC_LCD_CHIRON requires heatbed (TEMP_SENSOR_BED)" @@ -2751,69 +3120,55 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #endif #endif -#if ENABLED(ANYCUBIC_LCD_VYPER) - static_assert(strcmp(STRINGIFY(LCD_LANGUAGE_2), "zh_CN") == 0, "LCD_LANGUAGE_2 must be set to zh_CN for ANYCUBIC_LCD_VYPER."); -#endif - -#if ENABLED(NO_LCD_SDCARD) && SD_CONNECTION_IS(LCD) - #error "SDCARD_CONNECTION cannot be set to LCD for the enabled display. No available SD card reader." +#if EITHER(MKS_TS35_V2_0, BTT_TFT35_SPI_V1_0) && SD_CONNECTION_IS(LCD) + #error "SDCARD_CONNECTION cannot be set to LCD for the enabled TFT. No available SD card reader." #endif /** - * Ender-3 V2 controller has some limitations + * Ender 3 V2 controller has some limitations */ #if ENABLED(DWIN_CREALITY_LCD) - #if !HAS_MEDIA + #if DISABLED(SDSUPPORT) #error "DWIN_CREALITY_LCD requires SDSUPPORT to be enabled." - #elif ANY(PID_EDIT_MENU, PID_AUTOTUNE_MENU) + #elif EITHER(PID_EDIT_MENU, PID_AUTOTUNE_MENU) #error "DWIN_CREALITY_LCD does not support PID_EDIT_MENU or PID_AUTOTUNE_MENU." - #elif ANY(MPC_EDIT_MENU, MPC_AUTOTUNE_MENU) + #elif EITHER(MPC_EDIT_MENU, MPC_AUTOTUNE_MENU) #error "DWIN_CREALITY_LCD does not support MPC_EDIT_MENU or MPC_AUTOTUNE_MENU." #elif ENABLED(LCD_BED_TRAMMING) #error "DWIN_CREALITY_LCD does not support LCD_BED_TRAMMING." - #elif ALL(LCD_BED_LEVELING, PROBE_MANUALLY) + #elif BOTH(LCD_BED_LEVELING, PROBE_MANUALLY) #error "DWIN_CREALITY_LCD does not support LCD_BED_LEVELING with PROBE_MANUALLY." #endif #elif ENABLED(DWIN_LCD_PROUI) - #if !HAS_MEDIA + #if DISABLED(SDSUPPORT) #error "DWIN_LCD_PROUI requires SDSUPPORT to be enabled." - #elif ALL(LCD_BED_LEVELING, PROBE_MANUALLY) + #elif EITHER(PID_EDIT_MENU, PID_AUTOTUNE_MENU) + #error "DWIN_LCD_PROUI does not support PID_EDIT_MENU or PID_AUTOTUNE_MENU." + #elif EITHER(MPC_EDIT_MENU, MPC_AUTOTUNE_MENU) + #error "DWIN_LCD_PROUI does not support MPC_EDIT_MENU or MPC_AUTOTUNE_MENU." + #elif ENABLED(LCD_BED_TRAMMING) + #error "DWIN_LCD_PROUI does not support LCD_BED_TRAMMING." + #elif BOTH(LCD_BED_LEVELING, PROBE_MANUALLY) #error "DWIN_LCD_PROUI does not support LCD_BED_LEVELING with PROBE_MANUALLY." #endif #endif -#if HAS_BACKLIGHT_TIMEOUT - #if !HAS_ENCODER_ACTION && DISABLED(HAS_DWIN_E3V2) +#if LCD_BACKLIGHT_TIMEOUT_MINS + #if !HAS_ENCODER_ACTION #error "LCD_BACKLIGHT_TIMEOUT_MINS requires an LCD with encoder or keypad." - #elif HAS_DISPLAY_SLEEP - #error "LCD_BACKLIGHT_TIMEOUT_MINS and DISPLAY_SLEEP_MINUTES are not currently supported at the same time." - #elif ENABLED(NEOPIXEL_BKGD_INDEX_FIRST) - #if PIN_EXISTS(LCD_BACKLIGHT) - #error "LCD_BACKLIGHT_PIN and NEOPIXEL_BKGD_INDEX_FIRST are not supported at the same time." - #elif ENABLED(NEOPIXEL_BKGD_ALWAYS_ON) - #error "LCD_BACKLIGHT_TIMEOUT is not compatible with NEOPIXEL_BKGD_ALWAYS_ON." - #endif - #elif !PIN_EXISTS(LCD_BACKLIGHT) && DISABLED(HAS_DWIN_E3V2) - #error "LCD_BACKLIGHT_TIMEOUT_MINS requires LCD_BACKLIGHT_PIN, NEOPIXEL_BKGD_INDEX_FIRST, or an Ender-3 V2 DWIN LCD." - #endif -#elif HAS_DISPLAY_SLEEP - #if NONE(TOUCH_SCREEN, HAS_MARLINUI_U8GLIB) || ANY(IS_U8GLIB_LM6059_AF, IS_U8GLIB_ST7565_64128, REPRAPWORLD_GRAPHICAL_LCD, FYSETC_MINI_12864, CR10_STOCKDISPLAY, MINIPANEL) - #error "DISPLAY_SLEEP_MINUTES is not supported by your display." - #undef HAS_DISPLAY_SLEEP - #elif !WITHIN(DISPLAY_SLEEP_MINUTES, 0, 255) - #error "DISPLAY_SLEEP_MINUTES must be between 0 and 255." - #elif DISABLED(EDITABLE_DISPLAY_TIMEOUT) && DISPLAY_SLEEP_MINUTES == 0 - #error "DISPLAY_SLEEP_MINUTES must be greater than 0 with EDITABLE_DISPLAY_TIMEOUT disabled." + #elif !PIN_EXISTS(LCD_BACKLIGHT) + #error "LCD_BACKLIGHT_TIMEOUT_MINS requires LCD_BACKLIGHT_PIN." #endif #endif -// Startup Tune requirements -#ifdef STARTUP_TUNE - #if ANY(ANYCUBIC_LCD_CHIRON, ANYCUBIC_LCD_VYPER) - #error "STARTUP_TUNE should be disabled with ANYCUBIC_LCD_CHIRON or ANYCUBIC_LCD_VYPER." - #elif !(ALL(HAS_BEEPER, SPEAKER) || USE_MARLINUI_BUZZER) - #error "STARTUP_TUNE requires a BEEPER_PIN with SPEAKER or USE_MARLINUI_BUZZER." - #undef STARTUP_TUNE +/** + * Display Sleep is not supported by these common displays + */ +#if HAS_DISPLAY_SLEEP + #if ANY(IS_U8GLIB_LM6059_AF, IS_U8GLIB_ST7565_64128, REPRAPWORLD_GRAPHICAL_LCD, FYSETC_MINI, CR10_STOCKDISPLAY, ENDER2_STOCKDISPLAY, MINIPANEL) + #error "DISPLAY_SLEEP_MINUTES is not supported by your display." + #elif !WITHIN(DISPLAY_SLEEP_MINUTES, 0, 255) + #error "DISPLAY_SLEEP_MINUTES must be between 0 and 255." #endif #endif @@ -2858,8 +3213,8 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #else #if HAS_DGUS_LCD #error "The DGUS LCD requires LCD_SERIAL_PORT to be defined." - #elif ANY(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON, ANYCUBIC_LCD_VYPER) - #error "ANYCUBIC_LCD_* requires LCD_SERIAL_PORT to be defined." + #elif EITHER(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON) + #error "The ANYCUBIC LCD requires LCD_SERIAL_PORT to be defined." #elif ENABLED(MALYAN_LCD) #error "MALYAN_LCD requires LCD_SERIAL_PORT to be defined." #elif ENABLED(NEXTION_LCD) @@ -2954,17 +3309,17 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #error "TMC2208 or TMC2209 on E6 requires E6_HARDWARE_SERIAL or E6_SERIAL_(RX|TX)_PIN." #elif INVALID_TMC_UART(E7) #error "TMC2208 or TMC2209 on E7 requires E7_HARDWARE_SERIAL or E7_SERIAL_(RX|TX)_PIN." -#elif INVALID_TMC_UART(I) +#elif HAS_I_AXIS && INVALID_TMC_UART(I) #error "TMC2208 or TMC2209 on I requires I_HARDWARE_SERIAL or I_SERIAL_(RX|TX)_PIN." -#elif INVALID_TMC_UART(J) +#elif HAS_J_AXIS && INVALID_TMC_UART(J) #error "TMC2208 or TMC2209 on J requires J_HARDWARE_SERIAL or J_SERIAL_(RX|TX)_PIN." -#elif INVALID_TMC_UART(K) +#elif HAS_K_AXIS && INVALID_TMC_UART(K) #error "TMC2208 or TMC2209 on K requires K_HARDWARE_SERIAL or K_SERIAL_(RX|TX)_PIN." -#elif INVALID_TMC_UART(U) +#elif HAS_U_AXIS && INVALID_TMC_UART(U) #error "TMC2208 or TMC2209 on U requires U_HARDWARE_SERIAL or U_SERIAL_(RX|TX)_PIN." -#elif INVALID_TMC_UART(V) +#elif HAS_V_AXIS && INVALID_TMC_UART(V) #error "TMC2208 or TMC2209 on V requires V_HARDWARE_SERIAL or V_SERIAL_(RX|TX)_PIN." -#elif INVALID_TMC_UART(W) +#elif HAS_W_AXIS && INVALID_TMC_UART(W) #error "TMC2208 or TMC2209 on W requires W_HARDWARE_SERIAL or W_SERIAL_(RX|TX)_PIN." #endif @@ -3057,17 +3412,17 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i INVALID_TMC_MS(E6) #elif !TMC_MICROSTEP_IS_VALID(E7) INVALID_TMC_MS(E7) -#elif !TMC_MICROSTEP_IS_VALID(I) +#elif HAS_I_AXIS && !TMC_MICROSTEP_IS_VALID(I) INVALID_TMC_MS(I) -#elif !TMC_MICROSTEP_IS_VALID(J) +#elif HAS_J_AXIS && !TMC_MICROSTEP_IS_VALID(J) INVALID_TMC_MS(J) -#elif !TMC_MICROSTEP_IS_VALID(K) +#elif HAS_K_AXIS && !TMC_MICROSTEP_IS_VALID(K) INVALID_TMC_MS(K) -#elif !TMC_MICROSTEP_IS_VALID(U) +#elif HAS_U_AXIS && !TMC_MICROSTEP_IS_VALID(U) INVALID_TMC_MS(U) -#elif !TMC_MICROSTEP_IS_VALID(V) +#elif HAS_V_AXIS && !TMC_MICROSTEP_IS_VALID(V) INVALID_TMC_MS(V) -#elif !TMC_MICROSTEP_IS_VALID(W) +#elif HAS_W_AXIS && !TMC_MICROSTEP_IS_VALID(W) INVALID_TMC_MS(W) #endif #undef INVALID_TMC_MS @@ -3078,243 +3433,194 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #error "STEALTHCHOP_XY and STEALTHCHOP_Z must be the same on DELTA." #endif -// H-Bot kinematic axes can't use homing phases -#if ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX) && defined(TMC_HOME_PHASE) - constexpr float _phases[] = TMC_HOME_PHASE, _vphase[9] = TMC_HOME_PHASE; - constexpr int _nphase = COUNT(_phases); - static_assert(_nphase == NUM_AXES, "TMC_HOME_PHASE must have exactly " _NUM_AXES_STR " elements."); - static_assert(_nphase < 0 || _vphase[0] == -1 || NORMAL_AXIS == 0, "TMC_HOME_PHASE.x must be -1 for the selected kinematics."); - static_assert(_nphase < 1 || _vphase[1] == -1 || NORMAL_AXIS == 1, "TMC_HOME_PHASE.y must be -1 for the selected kinematics."); - static_assert(_nphase < 2 || _vphase[2] == -1 || NORMAL_AXIS == 2, "TMC_HOME_PHASE.z must be -1 for the selected kinematics."); - static_assert(_nphase < 0 || WITHIN(_vphase[0], -1, 1023), "TMC_HOME_PHASE.x must be between -1 and 1023."); - static_assert(_nphase < 1 || WITHIN(_vphase[1], -1, 1023), "TMC_HOME_PHASE.y must be between -1 and 1023."); - static_assert(_nphase < 2 || WITHIN(_vphase[2], -1, 1023), "TMC_HOME_PHASE.z must be between -1 and 1023."); - static_assert(_nphase < 3 || WITHIN(_vphase[3], -1, 1023), "TMC_HOME_PHASE.i must be between -1 and 1023."); - static_assert(_nphase < 4 || WITHIN(_vphase[4], -1, 1023), "TMC_HOME_PHASE.j must be between -1 and 1023."); - static_assert(_nphase < 5 || WITHIN(_vphase[5], -1, 1023), "TMC_HOME_PHASE.k must be between -1 and 1023."); - static_assert(_nphase < 6 || WITHIN(_vphase[6], -1, 1023), "TMC_HOME_PHASE.u must be between -1 and 1023."); - static_assert(_nphase < 7 || WITHIN(_vphase[7], -1, 1023), "TMC_HOME_PHASE.v must be between -1 and 1023."); - static_assert(_nphase < 8 || WITHIN(_vphase[8], -1, 1023), "TMC_HOME_PHASE.w must be between -1 and 1023."); -#endif - #if ENABLED(SENSORLESS_HOMING) // Require STEALTHCHOP for SENSORLESS_HOMING on DELTA as the transition from spreadCycle to stealthChop // is necessary in order to reset the stallGuard indication between the initial movement of all three // towers to +Z and the individual homing of each tower. This restriction can be removed once a means of // clearing the stallGuard activated status is found. + // Stall detection DIAG = HIGH : TMC2209 + // Stall detection DIAG = LOW : TMC2130/TMC2160/TMC2660/TMC5130/TMC5160 + #define X_ENDSTOP_INVERTING !AXIS_DRIVER_TYPE(X,TMC2209) + #define Y_ENDSTOP_INVERTING !AXIS_DRIVER_TYPE(Y,TMC2209) + #define Z_ENDSTOP_INVERTING !AXIS_DRIVER_TYPE(Z,TMC2209) + #if HAS_I_AXIS + #define I_ENDSTOP_INVERTING !AXIS_DRIVER_TYPE(I,TMC2209) + #endif + #if HAS_J_AXIS + #define J_ENDSTOP_INVERTING !AXIS_DRIVER_TYPE(J,TMC2209) + #endif + #if HAS_K_AXIS + #define K_ENDSTOP_INVERTING !AXIS_DRIVER_TYPE(K,TMC2209) + #endif + #if HAS_U_AXIS + #define U_ENDSTOP_INVERTING !AXIS_DRIVER_TYPE(U,TMC2209) + #endif + #if HAS_V_AXIS + #define V_ENDSTOP_INVERTING !AXIS_DRIVER_TYPE(V,TMC2209) + #endif + #if HAS_W_AXIS + #define W_ENDSTOP_INVERTING !AXIS_DRIVER_TYPE(W,TMC2209) + #endif + #if NONE(SPI_ENDSTOPS, ONBOARD_ENDSTOPPULLUPS, ENDSTOPPULLUPS) #if X_SENSORLESS && X_HOME_TO_MIN && DISABLED(ENDSTOPPULLUP_XMIN) - #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_XMIN (or ENDSTOPPULLUPS) for X MIN homing." + #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_XMIN (or ENDSTOPPULLUPS) when homing to X_MIN." #elif X_SENSORLESS && X_HOME_TO_MAX && DISABLED(ENDSTOPPULLUP_XMAX) - #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_XMAX (or ENDSTOPPULLUPS) for X MAX homing." + #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_XMAX (or ENDSTOPPULLUPS) when homing to X_MAX." #elif Y_SENSORLESS && Y_HOME_TO_MIN && DISABLED(ENDSTOPPULLUP_YMIN) - #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_YMIN (or ENDSTOPPULLUPS) for Y MIN homing." + #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_YMIN (or ENDSTOPPULLUPS) when homing to Y_MIN." #elif Y_SENSORLESS && Y_HOME_TO_MAX && DISABLED(ENDSTOPPULLUP_YMAX) - #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_YMAX (or ENDSTOPPULLUPS) for Y MAX homing." + #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_YMAX (or ENDSTOPPULLUPS) when homing to Y_MAX." #elif Z_SENSORLESS && Z_HOME_TO_MIN && DISABLED(ENDSTOPPULLUP_ZMIN) - #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_ZMIN (or ENDSTOPPULLUPS) for Z MIN homing." + #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_ZMIN (or ENDSTOPPULLUPS) when homing to Z_MIN." #elif Z_SENSORLESS && Z_HOME_TO_MAX && DISABLED(ENDSTOPPULLUP_ZMAX) - #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_ZMAX (or ENDSTOPPULLUPS) for Z MAX homing." - #elif I_SENSORLESS && I_HOME_TO_MIN && DISABLED(ENDSTOPPULLUP_IMIN) - #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_IMIN (or ENDSTOPPULLUPS) for I MIN homing." - #elif I_SENSORLESS && I_HOME_TO_MAX && DISABLED(ENDSTOPPULLUP_IMAX) - #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_IMAX (or ENDSTOPPULLUPS) for I MAX homing." - #elif J_SENSORLESS && J_HOME_TO_MIN && DISABLED(ENDSTOPPULLUP_JMIN) - #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_JMIN (or ENDSTOPPULLUPS) for J MIN homing." - #elif J_SENSORLESS && J_HOME_TO_MAX && DISABLED(ENDSTOPPULLUP_JMAX) - #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_JMAX (or ENDSTOPPULLUPS) for J MAX homing." - #elif K_SENSORLESS && K_HOME_TO_MIN && DISABLED(ENDSTOPPULLUP_KMIN) - #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_KMIN (or ENDSTOPPULLUPS) for K MIN homing." - #elif K_SENSORLESS && K_HOME_TO_MAX && DISABLED(ENDSTOPPULLUP_KMAX) - #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_KMAX (or ENDSTOPPULLUPS) for K MAX homing." - #elif U_SENSORLESS && U_HOME_TO_MIN && DISABLED(ENDSTOPPULLUP_UMIN) - #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_UMIN (or ENDSTOPPULLUPS) for U MIN homing." - #elif U_SENSORLESS && U_HOME_TO_MAX && DISABLED(ENDSTOPPULLUP_UMAX) - #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_UMAX (or ENDSTOPPULLUPS) for U MAX homing." - #elif V_SENSORLESS && V_HOME_TO_MIN && DISABLED(ENDSTOPPULLUP_VMIN) - #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_VMIN (or ENDSTOPPULLUPS) for V MIN homing." - #elif V_SENSORLESS && V_HOME_TO_MAX && DISABLED(ENDSTOPPULLUP_VMAX) - #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_VMAX (or ENDSTOPPULLUPS) for V MAX homing." - #elif W_SENSORLESS && W_HOME_TO_MIN && DISABLED(ENDSTOPPULLUP_WMIN) - #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_WMIN (or ENDSTOPPULLUPS) for W MIN homing." - #elif W_SENSORLESS && W_HOME_TO_MAX && DISABLED(ENDSTOPPULLUP_WMAX) - #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_WMAX (or ENDSTOPPULLUPS) for W MAX homing." + #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_ZMAX (or ENDSTOPPULLUPS) when homing to Z_MAX." + #elif ALL(HAS_I_AXIS, I_SENSORLESS, I_HOME_TO_MIN) && DISABLED(ENDSTOPPULLUP_IMIN) + #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_IMIN (or ENDSTOPPULLUPS) when homing to I_MIN." + #elif ALL(HAS_I_AXIS, I_SENSORLESS, I_HOME_TO_MAX) && DISABLED(ENDSTOPPULLUP_IMAX) + #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_IMAX (or ENDSTOPPULLUPS) when homing to I_MAX." + #elif ALL(HAS_J_AXIS, J_SENSORLESS, J_HOME_TO_MIN) && DISABLED(ENDSTOPPULLUP_JMIN) + #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_JMIN (or ENDSTOPPULLUPS) when homing to J_MIN." + #elif ALL(HAS_J_AXIS, J_SENSORLESS, J_HOME_TO_MAX) && DISABLED(ENDSTOPPULLUP_JMAX) + #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_JMAX (or ENDSTOPPULLUPS) when homing to J_MAX." + #elif ALL(HAS_K_AXIS, K_SENSORLESS, K_HOME_TO_MIN) && DISABLED(ENDSTOPPULLUP_KMIN) + #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_KMIN (or ENDSTOPPULLUPS) when homing to K_MIN." + #elif ALL(HAS_K_AXIS, K_SENSORLESS, K_HOME_TO_MAX) && DISABLED(ENDSTOPPULLUP_KMAX) + #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_KMAX (or ENDSTOPPULLUPS) when homing to K_MAX." + #elif HAS_U_AXIS && U_SENSORLESS && U_HOME_TO_MIN && DISABLED(ENDSTOPPULLUP_UMIN) + #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_UMIN (or ENDSTOPPULLUPS) when homing to U_MIN." + #elif HAS_U_AXIS && U_SENSORLESS && U_HOME_TO_MAX && DISABLED(ENDSTOPPULLUP_UMAX) + #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_UMAX (or ENDSTOPPULLUPS) when homing to U_MAX." + #elif HAS_V_AXIS && V_SENSORLESS && V_HOME_TO_MIN && DISABLED(ENDSTOPPULLUP_VMIN) + #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_VMIN (or ENDSTOPPULLUPS) when homing to V_MIN." + #elif HAS_V_AXIS && V_SENSORLESS && V_HOME_TO_MAX && DISABLED(ENDSTOPPULLUP_VMAX) + #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_VMAX (or ENDSTOPPULLUPS) when homing to V_MAX." + #elif HAS_W_AXIS && W_SENSORLESS && W_HOME_TO_MIN && DISABLED(ENDSTOPPULLUP_WMIN) + #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_WMIN (or ENDSTOPPULLUPS) when homing to W_MIN." + #elif HAS_W_AXIS && W_SENSORLESS && W_HOME_TO_MAX && DISABLED(ENDSTOPPULLUP_WMAX) + #error "SENSORLESS_HOMING requires ENDSTOPPULLUP_WMAX (or ENDSTOPPULLUPS) when homing to W_MAX." + #endif #endif #if ENABLED(SPI_ENDSTOPS) - #if !ANY_AXIS_HAS(SPI) - #error "SPI_ENDSTOPS requires stepper drivers with SPI support." + #if ENABLED(QUICK_HOME) + #warning "SPI_ENDSTOPS may be unreliable with QUICK_HOME. Adjust back-offs for better results." #endif - #else // !SPI_ENDSTOPS - // Stall detection DIAG = HIGH : TMC2209 - // Stall detection DIAG = LOW : TMC2130/TMC2160/TMC2660/TMC5130/TMC5160 - #if X_SENSORLESS - #define _HIT_STATE AXIS_DRIVER_TYPE(X,TMC2209) - #if X_HOME_TO_MIN && X_MIN_ENDSTOP_HIT_STATE != _HIT_STATE - #if _HIT_STATE - #error "SENSORLESS_HOMING requires X_MIN_ENDSTOP_HIT_STATE HIGH for X MIN homing with TMC2209." - #else - #error "SENSORLESS_HOMING requires X_MIN_ENDSTOP_HIT_STATE LOW for X MIN homing." - #endif - #elif X_HOME_TO_MAX && X_MAX_ENDSTOP_HIT_STATE != _HIT_STATE - #if _HIT_STATE - #error "SENSORLESS_HOMING requires X_MAX_ENDSTOP_HIT_STATE HIGH for X MAX homing with TMC2209." - #else - #error "SENSORLESS_HOMING requires X_MAX_ENDSTOP_HIT_STATE LOW for X MAX homing." - #endif + #else + #if X_SENSORLESS && X_HOME_TO_MIN && X_MIN_ENDSTOP_INVERTING != X_ENDSTOP_INVERTING + #if X_ENDSTOP_INVERTING + #error "SENSORLESS_HOMING requires X_MIN_ENDSTOP_INVERTING = true when homing to X_MIN." + #else + #error "SENSORLESS_HOMING requires X_MIN_ENDSTOP_INVERTING = false when homing TMC2209 to X_MIN." #endif - #undef _HIT_STATE - #endif - - #if Y_SENSORLESS - #define _HIT_STATE AXIS_DRIVER_TYPE(Y,TMC2209) - #if Y_HOME_TO_MIN && Y_MIN_ENDSTOP_HIT_STATE != _HIT_STATE - #if _HIT_STATE - #error "SENSORLESS_HOMING requires Y_MIN_ENDSTOP_HIT_STATE HIGH for Y MIN homing with TMC2209." - #else - #error "SENSORLESS_HOMING requires Y_MIN_ENDSTOP_HIT_STATE LOW for Y MIN homing." - #endif - #elif Y_HOME_TO_MAX && Y_MAX_ENDSTOP_HIT_STATE != _HIT_STATE - #if _HIT_STATE - #error "SENSORLESS_HOMING requires Y_MAX_ENDSTOP_HIT_STATE HIGH for Y MAX homing with TMC2209." - #else - #error "SENSORLESS_HOMING requires Y_MAX_ENDSTOP_HIT_STATE LOW for Y MAX homing." - #endif + #elif X_SENSORLESS && X_HOME_TO_MAX && X_MAX_ENDSTOP_INVERTING != X_ENDSTOP_INVERTING + #if X_ENDSTOP_INVERTING + #error "SENSORLESS_HOMING requires X_MAX_ENDSTOP_INVERTING = true when homing to X_MAX." + #else + #error "SENSORLESS_HOMING requires X_MAX_ENDSTOP_INVERTING = false when homing TMC2209 to X_MAX." #endif - #undef _HIT_STATE - #endif - - #if Z_SENSORLESS - #define _HIT_STATE AXIS_DRIVER_TYPE(Z,TMC2209) - #if Z_HOME_TO_MIN && Z_MIN_ENDSTOP_HIT_STATE != _HIT_STATE - #if _HIT_STATE - #error "SENSORLESS_HOMING requires Z_MIN_ENDSTOP_HIT_STATE HIGH for Z MIN homing with TMC2209." - #else - #error "SENSORLESS_HOMING requires Z_MIN_ENDSTOP_HIT_STATE LOW for Z MIN homing." - #endif - #elif Z_HOME_TO_MAX && Z_MAX_ENDSTOP_HIT_STATE != _HIT_STATE - #if _HIT_STATE - #error "SENSORLESS_HOMING requires Z_MAX_ENDSTOP_HIT_STATE HIGH for Z MAX homing with TMC2209." - #else - #error "SENSORLESS_HOMING requires Z_MAX_ENDSTOP_HIT_STATE LOW for Z MAX homing." - #endif + #elif Y_SENSORLESS && Y_HOME_TO_MIN && Y_MIN_ENDSTOP_INVERTING != Y_ENDSTOP_INVERTING + #if Y_ENDSTOP_INVERTING + #error "SENSORLESS_HOMING requires Y_MIN_ENDSTOP_INVERTING = true when homing to Y_MIN." + #else + #error "SENSORLESS_HOMING requires Y_MIN_ENDSTOP_INVERTING = false when homing TMC2209 to Y_MIN." #endif - #undef _HIT_STATE - #endif - - #if I_SENSORLESS - #define _HIT_STATE AXIS_DRIVER_TYPE(I,TMC2209) - #if I_HOME_TO_MIN && I_MIN_ENDSTOP_HIT_STATE != _HIT_STATE - #if _HIT_STATE - #error "SENSORLESS_HOMING requires I_MIN_ENDSTOP_HIT_STATE HIGH for I MIN homing with TMC2209." - #else - #error "SENSORLESS_HOMING requires I_MIN_ENDSTOP_HIT_STATE LOW for I MIN homing." - #endif - #elif I_HOME_TO_MAX && I_MAX_ENDSTOP_HIT_STATE != _HIT_STATE - #if _HIT_STATE - #error "SENSORLESS_HOMING requires I_MAX_ENDSTOP_HIT_STATE HIGH for I MAX homing with TMC2209." - #else - #error "SENSORLESS_HOMING requires I_MAX_ENDSTOP_HIT_STATE LOW for I MAX homing." - #endif + #elif Y_SENSORLESS && Y_HOME_TO_MAX && Y_MAX_ENDSTOP_INVERTING != Y_ENDSTOP_INVERTING + #if Y_ENDSTOP_INVERTING + #error "SENSORLESS_HOMING requires Y_MAX_ENDSTOP_INVERTING = true when homing to Y_MAX." + #else + #error "SENSORLESS_HOMING requires Y_MAX_ENDSTOP_INVERTING = false when homing TMC2209 to Y_MAX." #endif - #undef _HIT_STATE - #endif - - #if J_SENSORLESS - #define _HIT_STATE AXIS_DRIVER_TYPE(J,TMC2209) - #if J_HOME_TO_MIN && J_MIN_ENDSTOP_HIT_STATE != _HIT_STATE - #if _HIT_STATE - #error "SENSORLESS_HOMING requires J_MIN_ENDSTOP_HIT_STATE HIGH for J MIN homing with TMC2209." - #else - #error "SENSORLESS_HOMING requires J_MIN_ENDSTOP_HIT_STATE LOW for J MIN homing." - #endif - #elif J_HOME_TO_MAX && J_MAX_ENDSTOP_HIT_STATE != _HIT_STATE - #if _HIT_STATE - #error "SENSORLESS_HOMING requires J_MAX_ENDSTOP_HIT_STATE HIGH for J MAX homing with TMC2209." - #else - #error "SENSORLESS_HOMING requires J_MAX_ENDSTOP_HIT_STATE LOW for J MAX homing." - #endif + #elif Z_SENSORLESS && Z_HOME_TO_MIN && Z_MIN_ENDSTOP_INVERTING != Z_ENDSTOP_INVERTING + #if Z_ENDSTOP_INVERTING + #error "SENSORLESS_HOMING requires Z_MIN_ENDSTOP_INVERTING = true when homing to Z_MIN." + #else + #error "SENSORLESS_HOMING requires Z_MIN_ENDSTOP_INVERTING = false when homing TMC2209 to Z_MIN." #endif - #undef _HIT_STATE - #endif - - #if K_SENSORLESS - #define _HIT_STATE AXIS_DRIVER_TYPE(K,TMC2209) - #if K_HOME_TO_MIN && K_MIN_ENDSTOP_HIT_STATE != _HIT_STATE - #if _HIT_STATE - #error "SENSORLESS_HOMING requires K_MIN_ENDSTOP_HIT_STATE HIGH for K MIN homing with TMC2209." - #else - #error "SENSORLESS_HOMING requires K_MIN_ENDSTOP_HIT_STATE LOW for K MIN homing." - #endif - #elif K_HOME_TO_MAX && K_MAX_ENDSTOP_HIT_STATE != _HIT_STATE - #if _HIT_STATE - #error "SENSORLESS_HOMING requires K_MAX_ENDSTOP_HIT_STATE HIGH for K MAX homing with TMC2209." - #else - #error "SENSORLESS_HOMING requires K_MAX_ENDSTOP_HIT_STATE LOW for K MAX homing." - #endif + #elif Z_SENSORLESS && Z_HOME_TO_MAX && Z_MAX_ENDSTOP_INVERTING != Z_ENDSTOP_INVERTING + #if Z_ENDSTOP_INVERTING + #error "SENSORLESS_HOMING requires Z_MAX_ENDSTOP_INVERTING = true when homing to Z_MAX." + #else + #error "SENSORLESS_HOMING requires Z_MAX_ENDSTOP_INVERTING = false when homing TMC2209 to Z_MAX." #endif - #undef _HIT_STATE - #endif - - #if U_SENSORLESS - #define _HIT_STATE AXIS_DRIVER_TYPE(U,TMC2209) - #if U_HOME_TO_MIN && U_MIN_ENDSTOP_HIT_STATE != _HIT_STATE - #if _HIT_STATE - #error "SENSORLESS_HOMING requires U_MIN_ENDSTOP_HIT_STATE HIGH for U MIN homing with TMC2209." - #else - #error "SENSORLESS_HOMING requires U_MIN_ENDSTOP_HIT_STATE LOW for U MIN homing." - #endif - #elif U_HOME_TO_MAX && U_MAX_ENDSTOP_HIT_STATE != _HIT_STATE - #if _HIT_STATE - #error "SENSORLESS_HOMING requires U_MAX_ENDSTOP_HIT_STATE HIGH for U MAX homing with TMC2209." - #else - #error "SENSORLESS_HOMING requires U_MAX_ENDSTOP_HIT_STATE LOW for U MAX homing." - #endif + #elif ALL(HAS_I_AXIS, I_SENSORLESS, I_HOME_TO_MIN) && I_MIN_ENDSTOP_INVERTING != I_ENDSTOP_INVERTING + #if I_ENDSTOP_INVERTING + #error "SENSORLESS_HOMING requires I_MIN_ENDSTOP_INVERTING = true when homing to I_MIN." + #else + #error "SENSORLESS_HOMING requires I_MIN_ENDSTOP_INVERTING = false when homing TMC2209 to I_MIN." #endif - #undef _HIT_STATE - #endif - - #if V_SENSORLESS - #define _HIT_STATE AXIS_DRIVER_TYPE(V,TMC2209) - #if V_HOME_TO_MIN && V_MIN_ENDSTOP_HIT_STATE != _HIT_STATE - #if _HIT_STATE - #error "SENSORLESS_HOMING requires V_MIN_ENDSTOP_HIT_STATE HIGH for V MIN homing with TMC2209." - #else - #error "SENSORLESS_HOMING requires V_MIN_ENDSTOP_HIT_STATE LOW for V MIN homing." - #endif - #elif V_HOME_TO_MAX && V_MAX_ENDSTOP_HIT_STATE != _HIT_STATE - #if _HIT_STATE - #error "SENSORLESS_HOMING requires V_MAX_ENDSTOP_HIT_STATE HIGH for V MAX homing with TMC2209." - #else - #error "SENSORLESS_HOMING requires V_MAX_ENDSTOP_HIT_STATE LOW for V MAX homing." - #endif + #elif ALL(HAS_I_AXIS, I_SENSORLESS, I_HOME_TO_MAX) && I_MAX_ENDSTOP_INVERTING != I_ENDSTOP_INVERTING + #if I_ENDSTOP_INVERTING + #error "SENSORLESS_HOMING requires I_MAX_ENDSTOP_INVERTING = true when homing to I_MAX." + #else + #error "SENSORLESS_HOMING requires I_MAX_ENDSTOP_INVERTING = false when homing TMC2209 to I_MAX." #endif - #undef _HIT_STATE - #endif - - #if W_SENSORLESS - #define _HIT_STATE AXIS_DRIVER_TYPE(W,TMC2209) - #if W_HOME_TO_MIN && W_MIN_ENDSTOP_HIT_STATE != _HIT_STATE - #if _HIT_STATE - #error "SENSORLESS_HOMING requires W_MIN_ENDSTOP_HIT_STATE HIGH for W MIN homing with TMC2209." - #else - #error "SENSORLESS_HOMING requires W_MIN_ENDSTOP_HIT_STATE LOW for W MIN homing." - #endif - #elif W_HOME_TO_MAX && W_MAX_ENDSTOP_HIT_STATE != _HIT_STATE - #if _HIT_STATE - #error "SENSORLESS_HOMING requires W_MAX_ENDSTOP_HIT_STATE HIGH for W MAX homing with TMC2209." - #else - #error "SENSORLESS_HOMING requires W_MAX_ENDSTOP_HIT_STATE LOW for W MAX homing." - #endif + #elif ALL(HAS_J_AXIS, J_SENSORLESS, J_HOME_TO_MIN) && J_MIN_ENDSTOP_INVERTING != J_ENDSTOP_INVERTING + #if J_ENDSTOP_INVERTING + #error "SENSORLESS_HOMING requires J_MIN_ENDSTOP_INVERTING = true when homing to J_MIN." + #else + #error "SENSORLESS_HOMING requires J_MIN_ENDSTOP_INVERTING = false when homing TMC2209 to J_MIN." + #endif + #elif ALL(HAS_J_AXIS, J_SENSORLESS, J_HOME_TO_MAX) && J_MAX_ENDSTOP_INVERTING != J_ENDSTOP_INVERTING + #if J_ENDSTOP_INVERTING + #error "SENSORLESS_HOMING requires J_MAX_ENDSTOP_INVERTING = true when homing to J_MAX." + #else + #error "SENSORLESS_HOMING requires J_MAX_ENDSTOP_INVERTING = false when homing TMC2209 to J_MAX." + #endif + #elif ALL(HAS_K_AXIS, K_SENSORLESS, K_HOME_TO_MIN) && K_MIN_ENDSTOP_INVERTING != K_ENDSTOP_INVERTING + #if K_ENDSTOP_INVERTING + #error "SENSORLESS_HOMING requires K_MIN_ENDSTOP_INVERTING = true when homing to K_MIN." + #else + #error "SENSORLESS_HOMING requires K_MIN_ENDSTOP_INVERTING = false when homing TMC2209 to K_MIN." + #endif + #elif ALL(HAS_K_AXIS, K_SENSORLESS, K_HOME_TO_MAX) && K_MAX_ENDSTOP_INVERTING != K_ENDSTOP_INVERTING + #if K_ENDSTOP_INVERTING + #error "SENSORLESS_HOMING requires K_MAX_ENDSTOP_INVERTING = true when homing to K_MAX." + #else + #error "SENSORLESS_HOMING requires K_MAX_ENDSTOP_INVERTING = false when homing TMC2209 to K_MAX." + #endif + #elif ALL(HAS_U_AXIS, U_SENSORLESS, U_HOME_TO_MIN) && U_MIN_ENDSTOP_INVERTING != U_ENDSTOP_INVERTING + #if U_ENDSTOP_INVERTING + #error "SENSORLESS_HOMING requires U_MIN_ENDSTOP_INVERTING = true when homing to U_MIN." + #else + #error "SENSORLESS_HOMING requires U_MIN_ENDSTOP_INVERTING = false when homing TMC2209 to U_MIN." + #endif + #elif ALL(HAS_U_AXIS, U_SENSORLESS, U_HOME_TO_MAX) && U_MAX_ENDSTOP_INVERTING != U_ENDSTOP_INVERTING + #if U_ENDSTOP_INVERTING + #error "SENSORLESS_HOMING requires U_MAX_ENDSTOP_INVERTING = true when homing to U_MAX." + #else + #error "SENSORLESS_HOMING requires U_MAX_ENDSTOP_INVERTING = false when homing TMC2209 to U_MAX." + #endif + #elif ALL(HAS_V_AXIS, V_SENSORLESS, V_HOME_TO_MIN) && V_MIN_ENDSTOP_INVERTING != V_ENDSTOP_INVERTING + #if V_ENDSTOP_INVERTING + #error "SENSORLESS_HOMING requires V_MIN_ENDSTOP_INVERTING = true when homing to V_MIN." + #else + #error "SENSORLESS_HOMING requires V_MIN_ENDSTOP_INVERTING = false when homing TMC2209 to V_MIN." + #endif + #elif ALL(HAS_V_AXIS, V_SENSORLESS, V_HOME_TO_MAX) && V_MAX_ENDSTOP_INVERTING != V_ENDSTOP_INVERTING + #if V_ENDSTOP_INVERTING + #error "SENSORLESS_HOMING requires V_MAX_ENDSTOP_INVERTING = true when homing to V_MAX." + #else + #error "SENSORLESS_HOMING requires V_MAX_ENDSTOP_INVERTING = false when homing TMC2209 to V_MAX." + #endif + #elif ALL(HAS_W_AXIS, W_SENSORLESS, W_HOME_TO_MIN) && W_MIN_ENDSTOP_INVERTING != W_ENDSTOP_INVERTING + #if W_ENDSTOP_INVERTING + #error "SENSORLESS_HOMING requires W_MIN_ENDSTOP_INVERTING = true when homing to W_MIN." + #else + #error "SENSORLESS_HOMING requires W_MIN_ENDSTOP_INVERTING = false when homing TMC2209 to W_MIN." + #endif + #elif ALL(HAS_W_AXIS, W_SENSORLESS, W_HOME_TO_MAX0) && W_MAX_ENDSTOP_INVERTING != W_ENDSTOP_INVERTING + #if W_ENDSTOP_INVERTING + #error "SENSORLESS_HOMING requires W_MAX_ENDSTOP_INVERTING = true when homing to W_MAX." + #else + #error "SENSORLESS_HOMING requires W_MAX_ENDSTOP_INVERTING = false when homing TMC2209 to W_MAX." #endif - #undef _HIT_STATE #endif + #endif - #endif // !SPI_ENDSTOPS - - #if ENABLED(DELTA) && !ALL(STEALTHCHOP_XY, STEALTHCHOP_Z) + #if ENABLED(DELTA) && !BOTH(STEALTHCHOP_XY, STEALTHCHOP_Z) #error "SENSORLESS_HOMING on DELTA currently requires STEALTHCHOP_XY and STEALTHCHOP_Z." #elif ENDSTOP_NOISE_THRESHOLD #error "SENSORLESS_HOMING is incompatible with ENDSTOP_NOISE_THRESHOLD." @@ -3322,7 +3628,16 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #error "SENSORLESS_HOMING requires a TMC stepper driver with StallGuard on X, Y, Z, I, J, K, U, V, or W axes." #endif -#endif // SENSORLESS_HOMING + #undef X_ENDSTOP_INVERTING + #undef Y_ENDSTOP_INVERTING + #undef Z_ENDSTOP_INVERTING + #undef I_ENDSTOP_INVERTING + #undef J_ENDSTOP_INVERTING + #undef K_ENDSTOP_INVERTING + #undef U_ENDSTOP_INVERTING + #undef V_ENDSTOP_INVERTING + #undef W_ENDSTOP_INVERTING +#endif // Sensorless probing requirements #if ENABLED(SENSORLESS_PROBING) @@ -3344,63 +3659,14 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #error "CoreXZ requires both X and Z to use sensorless homing if either one does." #elif CORE_IS_YZ && Y_SENSORLESS != Z_SENSORLESS && !HOMING_Z_WITH_PROBE #error "CoreYZ requires both Y and Z to use sensorless homing if either one does." -#elif ANY(MARKFORGED_XY, MARKFORGED_YX) && X_SENSORLESS != Y_SENSORLESS +#elif EITHER(MARKFORGED_XY, MARKFORGED_YX) && X_SENSORLESS != Y_SENSORLESS #error "MARKFORGED requires both X and Y to use sensorless homing if either one does." #endif -// TMC Hybrid Threshold -#if ENABLED(HYBRID_THRESHOLD) - #if !STEALTHCHOP_ENABLED - #error "Enable STEALTHCHOP_(XY|Z|E) to use HYBRID_THRESHOLD." - #elif defined(X_HYBRID_THRESHOLD) && X_HYBRID_THRESHOLD == 0 - #error "X_HYBRID_THRESHOLD must be greater than 0." - #elif defined(X2_HYBRID_THRESHOLD) && X2_HYBRID_THRESHOLD == 0 - #error "X2_HYBRID_THRESHOLD must be greater than 0." - #elif defined(Y_HYBRID_THRESHOLD) && Y_HYBRID_THRESHOLD == 0 - #error "Y_HYBRID_THRESHOLD must be greater than 0." - #elif defined(Y2_HYBRID_THRESHOLD) && Y2_HYBRID_THRESHOLD == 0 - #error "Y2_HYBRID_THRESHOLD must be greater than 0." - #elif defined(Z_HYBRID_THRESHOLD) && Z_HYBRID_THRESHOLD == 0 - #error "Z_HYBRID_THRESHOLD must be greater than 0." - #elif defined(Z2_HYBRID_THRESHOLD) && Z2_HYBRID_THRESHOLD == 0 - #error "Z2_HYBRID_THRESHOLD must be greater than 0." - #elif defined(Z3_HYBRID_THRESHOLD) && Z3_HYBRID_THRESHOLD == 0 - #error "Z3_HYBRID_THRESHOLD must be greater than 0." - #elif defined(Z4_HYBRID_THRESHOLD) && Z4_HYBRID_THRESHOLD == 0 - #error "Z4_HYBRID_THRESHOLD must be greater than 0." - #elif defined(I_HYBRID_THRESHOLD) && I_HYBRID_THRESHOLD == 0 - #error "I_HYBRID_THRESHOLD must be greater than 0." - #elif defined(J_HYBRID_THRESHOLD) && J_HYBRID_THRESHOLD == 0 - #error "J_HYBRID_THRESHOLD must be greater than 0." - #elif defined(K_HYBRID_THRESHOLD) && K_HYBRID_THRESHOLD == 0 - #error "K_HYBRID_THRESHOLD must be greater than 0." - #elif defined(U_HYBRID_THRESHOLD) && U_HYBRID_THRESHOLD == 0 - #error "U_HYBRID_THRESHOLD must be greater than 0." - #elif defined(V_HYBRID_THRESHOLD) && V_HYBRID_THRESHOLD == 0 - #error "V_HYBRID_THRESHOLD must be greater than 0." - #elif defined(W_HYBRID_THRESHOLD) && W_HYBRID_THRESHOLD == 0 - #error "W_HYBRID_THRESHOLD must be greater than 0." - #elif defined(E0_HYBRID_THRESHOLD) && E0_HYBRID_THRESHOLD == 0 - #error "E0_HYBRID_THRESHOLD must be greater than 0." - #elif defined(E1_HYBRID_THRESHOLD) && E1_HYBRID_THRESHOLD == 0 - #error "E1_HYBRID_THRESHOLD must be greater than 0." - #elif defined(E2_HYBRID_THRESHOLD) && E2_HYBRID_THRESHOLD == 0 - #error "E2_HYBRID_THRESHOLD must be greater than 0." - #elif defined(E3_HYBRID_THRESHOLD) && E3_HYBRID_THRESHOLD == 0 - #error "E3_HYBRID_THRESHOLD must be greater than 0." - #elif defined(E4_HYBRID_THRESHOLD) && E4_HYBRID_THRESHOLD == 0 - #error "E4_HYBRID_THRESHOLD must be greater than 0." - #elif defined(E5_HYBRID_THRESHOLD) && E5_HYBRID_THRESHOLD == 0 - #error "E5_HYBRID_THRESHOLD must be greater than 0." - #elif defined(E6_HYBRID_THRESHOLD) && E6_HYBRID_THRESHOLD == 0 - #error "E6_HYBRID_THRESHOLD must be greater than 0." - #elif defined(E7_HYBRID_THRESHOLD) && E7_HYBRID_THRESHOLD == 0 - #error "E7_HYBRID_THRESHOLD must be greater than 0." - #endif -#endif // HYBRID_THRESHOLD - // Other TMC feature requirements -#if ENABLED(SENSORLESS_HOMING) && !HAS_STALLGUARD +#if ENABLED(HYBRID_THRESHOLD) && !STEALTHCHOP_ENABLED + #error "Enable STEALTHCHOP_(XY|Z|E) to use HYBRID_THRESHOLD." +#elif ENABLED(SENSORLESS_HOMING) && !HAS_STALLGUARD #error "SENSORLESS_HOMING requires TMC2130, TMC2160, TMC2209, TMC2660, or TMC5160 stepper drivers." #elif ENABLED(SENSORLESS_PROBING) && !HAS_STALLGUARD #error "SENSORLESS_PROBING requires TMC2130, TMC2160, TMC2209, TMC2660, or TMC5160 stepper drivers." @@ -3412,12 +3678,10 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i * TMC SPI Chaining */ #define IN_CHAIN(A) A##_CHAIN_POS > 0 -#if IN_CHAIN(X) || IN_CHAIN(Y) || IN_CHAIN(Z) || IN_CHAIN(I) || IN_CHAIN(J) || IN_CHAIN(K) || IN_CHAIN(U) || IN_CHAIN(V) || IN_CHAIN(W) \ - || IN_CHAIN(X2) || IN_CHAIN(Y2) || IN_CHAIN(Z2) || IN_CHAIN(Z3) || IN_CHAIN(Z4) \ +#if IN_CHAIN(X ) || IN_CHAIN(Y ) || IN_CHAIN(Z ) || IN_CHAIN(X2) || IN_CHAIN(Y2) || IN_CHAIN(Z2) || IN_CHAIN(Z3) || IN_CHAIN(Z4) \ || IN_CHAIN(E0) || IN_CHAIN(E1) || IN_CHAIN(E2) || IN_CHAIN(E3) || IN_CHAIN(E4) || IN_CHAIN(E5) || IN_CHAIN(E6) || IN_CHAIN(E7) #define BAD_CHAIN(A) (IN_CHAIN(A) && !PIN_EXISTS(A##_CS)) - #if BAD_CHAIN(X) || BAD_CHAIN(Y) || BAD_CHAIN(Z) || BAD_CHAIN(I) || BAD_CHAIN(J) || BAD_CHAIN(K) || BAD_CHAIN(U) || BAD_CHAIN(V) || BAD_CHAIN(W) \ - || BAD_CHAIN(X2) || BAD_CHAIN(Y2) || BAD_CHAIN(Z2) || BAD_CHAIN(Z3) || BAD_CHAIN(Z4) \ + #if BAD_CHAIN(X ) || BAD_CHAIN(Y ) || BAD_CHAIN(Z ) || BAD_CHAIN(X2) || BAD_CHAIN(Y2) || BAD_CHAIN(Z2) || BAD_CHAIN(Z3) || BAD_CHAIN(Z4) \ || BAD_CHAIN(E0) || BAD_CHAIN(E1) || BAD_CHAIN(E2) || BAD_CHAIN(E3) || BAD_CHAIN(E4) || BAD_CHAIN(E5) || BAD_CHAIN(E6) || BAD_CHAIN(E7) #error "All chained TMC drivers need a CS pin." #else @@ -3465,8 +3729,9 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #define CS_COMPARE E7_CS_PIN #endif #define BAD_CS_PIN(A) (IN_CHAIN(A) && A##_CS_PIN != CS_COMPARE) - #if BAD_CS_PIN(X) || BAD_CS_PIN(Y) || BAD_CS_PIN(Z) || BAD_CS_PIN(I) || BAD_CS_PIN(J) || BAD_CS_PIN(K) || BAD_CS_PIN(U) || BAD_CS_PIN(V) || BAD_CS_PIN(W) \ - || BAD_CS_PIN(X2) || BAD_CS_PIN(Y2) || BAD_CS_PIN(Z2) || BAD_CS_PIN(Z3) || BAD_CS_PIN(Z4) \ + #if BAD_CS_PIN(X ) || BAD_CS_PIN(Y ) || BAD_CS_PIN(Z ) || BAD_CS_PIN(X2) || BAD_CS_PIN(Y2) || BAD_CS_PIN(Z2) || BAD_CS_PIN(Z3) || BAD_CS_PIN(Z4) \ + || BAD_CS_PIN(I) || BAD_CS_PIN(J) || BAD_CS_PIN(K) \ + || BAD_CS_PIN(U) || BAD_CS_PIN(V) || BAD_CS_PIN(W) \ || BAD_CS_PIN(E0) || BAD_CS_PIN(E1) || BAD_CS_PIN(E2) || BAD_CS_PIN(E3) || BAD_CS_PIN(E4) || BAD_CS_PIN(E5) || BAD_CS_PIN(E6) || BAD_CS_PIN(E7) #error "All chained TMC drivers must use the same CS pin." #endif @@ -3481,7 +3746,7 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i * Digipot requirement */ #if HAS_MOTOR_CURRENT_I2C - #if ALL(DIGIPOT_MCP4018, DIGIPOT_MCP4451) + #if BOTH(DIGIPOT_MCP4018, DIGIPOT_MCP4451) #error "Enable only one of DIGIPOT_MCP4018 or DIGIPOT_MCP4451." #elif !MB(MKS_SBASE, AZTEEG_X5_GT, AZTEEG_X5_MINI, AZTEEG_X5_MINI_WIFI) \ && (!defined(DIGIPOTS_I2C_SDA_X) || !defined(DIGIPOTS_I2C_SDA_Y) || !defined(DIGIPOTS_I2C_SDA_Z) || !defined(DIGIPOTS_I2C_SDA_E0) || !defined(DIGIPOTS_I2C_SDA_E1)) @@ -3516,11 +3781,9 @@ static_assert(COUNT(sanity_arr_3) >= LOGICAL_AXES, "DEFAULT_MAX_ACCELERATION re static_assert(COUNT(sanity_arr_3) <= DISTINCT_AXES, "DEFAULT_MAX_ACCELERATION has too many elements." _EXTRA_NOTE); static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive."); -#if NUM_AXES - constexpr float sanity_arr_4[] = HOMING_FEEDRATE_MM_M; - static_assert(COUNT(sanity_arr_4) == NUM_AXES, "HOMING_FEEDRATE_MM_M requires " _NUM_AXES_STR "elements (and no others)."); - static_assert(_PLUS_TEST(4), "HOMING_FEEDRATE_MM_M values must be positive."); -#endif +constexpr float sanity_arr_4[] = HOMING_FEEDRATE_MM_M; +static_assert(COUNT(sanity_arr_4) == NUM_AXES, "HOMING_FEEDRATE_MM_M requires " _NUM_AXES_STR "elements (and no others)."); +static_assert(_PLUS_TEST(4), "HOMING_FEEDRATE_MM_M values must be positive."); #ifdef MAX_ACCEL_EDIT_VALUES constexpr float sanity_arr_5[] = MAX_ACCEL_EDIT_VALUES; @@ -3554,12 +3817,12 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive." #undef _PLUS_TEST #undef _EXTRA_NOTE -#if ALL(CNC_COORDINATE_SYSTEMS, NO_WORKSPACE_OFFSETS) +#if BOTH(CNC_COORDINATE_SYSTEMS, NO_WORKSPACE_OFFSETS) #error "CNC_COORDINATE_SYSTEMS is incompatible with NO_WORKSPACE_OFFSETS." #endif -#if !BLOCK_BUFFER_SIZE - #error "BLOCK_BUFFER_SIZE must be non-zero." +#if !BLOCK_BUFFER_SIZE || !IS_POWER_OF_2(BLOCK_BUFFER_SIZE) + #error "BLOCK_BUFFER_SIZE must be a power of 2." #elif BLOCK_BUFFER_SIZE > 64 #error "A very large BLOCK_BUFFER_SIZE is not needed and takes longer to drain the buffer on pause / cancel." #endif @@ -3568,10 +3831,6 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive." #error "LED_CONTROL_MENU requires an LCD controller that implements the menu." #endif -#if ENABLED(CUSTOM_MENU_MAIN) && NONE(HAS_MARLINUI_MENU, TOUCH_UI_FTDI_EVE, TFT_LVGL_UI) - #error "CUSTOM_MENU_MAIN requires an LCD controller that implements the menu." -#endif - #if ENABLED(CASE_LIGHT_USE_NEOPIXEL) && DISABLED(NEOPIXEL_LED) #error "CASE_LIGHT_USE_NEOPIXEL requires NEOPIXEL_LED." #endif @@ -3590,18 +3849,18 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive." #endif #endif -#if ALL(X_AXIS_TWIST_COMPENSATION, NOZZLE_AS_PROBE) +#if BOTH(X_AXIS_TWIST_COMPENSATION, NOZZLE_AS_PROBE) #error "X_AXIS_TWIST_COMPENSATION is incompatible with NOZZLE_AS_PROBE." #endif #if ENABLED(POWER_LOSS_RECOVERY) #if ENABLED(BACKUP_POWER_SUPPLY) && !PIN_EXISTS(POWER_LOSS) #error "BACKUP_POWER_SUPPLY requires a POWER_LOSS_PIN." - #elif ALL(POWER_LOSS_PULLUP, POWER_LOSS_PULLDOWN) + #elif BOTH(POWER_LOSS_PULLUP, POWER_LOSS_PULLDOWN) #error "You can't enable POWER_LOSS_PULLUP and POWER_LOSS_PULLDOWN at the same time." #elif ENABLED(POWER_LOSS_RECOVER_ZHOME) && Z_HOME_TO_MAX #error "POWER_LOSS_RECOVER_ZHOME is not needed on a machine that homes to ZMAX." - #elif ALL(IS_CARTESIAN, POWER_LOSS_RECOVER_ZHOME) && Z_HOME_TO_MIN && !defined(POWER_LOSS_ZHOME_POS) + #elif BOTH(IS_CARTESIAN, POWER_LOSS_RECOVER_ZHOME) && Z_HOME_TO_MIN && !defined(POWER_LOSS_ZHOME_POS) #error "POWER_LOSS_RECOVER_ZHOME requires POWER_LOSS_ZHOME_POS for a Cartesian that homes to ZMIN." #endif #endif @@ -3617,7 +3876,6 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive." #error "Z_STEPPER_ALIGN_STEPPER_XY requires 3 or 4 Z steppers." #endif #endif - static_assert(WITHIN(Z_STEPPER_ALIGN_ACC, 0.001, 1.0), "Z_STEPPER_ALIGN_ACC needs to be between 0.001 and 1.0"); #endif #if ENABLED(MECHANICAL_GANTRY_CALIBRATION) @@ -3664,7 +3922,7 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive." #error "BACKLASH_COMPENSATION requires BACKLASH_DISTANCE_MM." #elif !defined(BACKLASH_CORRECTION) #error "BACKLASH_COMPENSATION requires BACKLASH_CORRECTION." - #elif ANY(MARKFORGED_XY, MARKFORGED_YX) + #elif EITHER(MARKFORGED_XY, MARKFORGED_YX) constexpr float backlash_arr[] = BACKLASH_DISTANCE_MM; static_assert(!backlash_arr[CORE_AXIS_1] && !backlash_arr[CORE_AXIS_2], "BACKLASH_COMPENSATION can only apply to " STRINGIFY(NORMAL_AXIS) " on a MarkForged system."); @@ -3714,11 +3972,11 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive." /** * Require soft endstops for certain setups */ -#if !ALL(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS) +#if !BOTH(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS) #if ENABLED(DUAL_X_CARRIAGE) #error "DUAL_X_CARRIAGE requires both MIN_ and MAX_SOFTWARE_ENDSTOPS." #elif HAS_HOTEND_OFFSET - #error "Multi-hotends with offset requires both MIN_ and MAX_SOFTWARE_ENDSTOPS." + #error "MIN_ and MAX_SOFTWARE_ENDSTOPS are both required with offset hotends." #endif #endif @@ -3741,8 +3999,6 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive." #error "POWER_OFF_DELAY must be a positive value." #elif ENABLED(POWER_OFF_WAIT_FOR_COOLDOWN) && !(defined(AUTO_POWER_E_TEMP) || defined(AUTO_POWER_CHAMBER_TEMP) || defined(AUTO_POWER_COOLER_TEMP)) #error "POWER_OFF_WAIT_FOR_COOLDOWN requires AUTO_POWER_E_TEMP, AUTO_POWER_CHAMBER_TEMP, and/or AUTO_POWER_COOLER_TEMP." - #elif ENABLED(PSU_OFF_REDUNDANT) && !PIN_EXISTS(PS_ON1) - #error "PSU_OFF_REDUNDANT requires PS_ON1_PIN." #endif #endif @@ -3777,7 +4033,7 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive." #endif #define _PIN_CONFLICT(P) (PIN_EXISTS(P) && P##_PIN == SPINDLE_LASER_PWM_PIN) - #if ALL(SPINDLE_FEATURE, LASER_FEATURE) + #if BOTH(SPINDLE_FEATURE, LASER_FEATURE) #error "Enable only one of SPINDLE_FEATURE or LASER_FEATURE." #elif NONE(SPINDLE_SERVO, SPINDLE_LASER_USE_PWM) && !PIN_EXISTS(SPINDLE_LASER_ENA) #error "(SPINDLE|LASER)_FEATURE requires SPINDLE_LASER_ENA_PIN, SPINDLE_LASER_USE_PWM, or SPINDLE_SERVO to control the power." @@ -3793,11 +4049,11 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive." #elif !(defined(SPEED_POWER_MIN) && defined(SPEED_POWER_MAX) && defined(SPEED_POWER_STARTUP)) #error "SPINDLE_LASER_USE_PWM equation constant(s) missing." #elif _PIN_CONFLICT(X_MIN) - #error "SPINDLE_LASER_PWM_PIN conflicts with X_MIN_PIN." + #error "SPINDLE_LASER_USE_PWM pin conflicts with X_MIN_PIN." #elif _PIN_CONFLICT(X_MAX) - #error "SPINDLE_LASER_PWM_PIN conflicts with X_MAX_PIN." + #error "SPINDLE_LASER_USE_PWM pin conflicts with X_MAX_PIN." #elif _PIN_CONFLICT(Z_STEP) - #error "SPINDLE_LASER_PWM_PIN conflicts with Z_STEP_PIN." + #error "SPINDLE_LASER_USE_PWM pin conflicts with Z_STEP_PIN." #elif _PIN_CONFLICT(CASE_LIGHT) #error "SPINDLE_LASER_PWM_PIN conflicts with CASE_LIGHT_PIN." #elif _PIN_CONFLICT(E0_AUTO_FAN) @@ -3816,8 +4072,8 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive." #error "SPINDLE_LASER_PWM_PIN conflicts with E6_AUTO_FAN_PIN." #elif _PIN_CONFLICT(E7_AUTO_FAN) #error "SPINDLE_LASER_PWM_PIN conflicts with E7_AUTO_FAN_PIN." - #elif _PIN_CONFLICT(FAN0) - #error "SPINDLE_LASER_PWM_PIN conflicts with FAN0_PIN." + #elif _PIN_CONFLICT(FAN) + #error "SPINDLE_LASER_PWM_PIN conflicts with FAN_PIN." #elif _PIN_CONFLICT(FAN1) #error "SPINDLE_LASER_PWM_PIN conflicts with FAN1_PIN." #elif _PIN_CONFLICT(FAN2) @@ -3845,19 +4101,15 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive." #undef _PIN_CONFLICT #ifdef LASER_SAFETY_TIMEOUT_MS - static_assert(LASER_SAFETY_TIMEOUT_MS < (DEFAULT_STEPPER_TIMEOUT_SEC) * 1000UL, "LASER_SAFETY_TIMEOUT_MS must be less than DEFAULT_STEPPER_TIMEOUT_SEC (" STRINGIFY(DEFAULT_STEPPER_TIMEOUT_SEC) " seconds)"); + static_assert(LASER_SAFETY_TIMEOUT_MS < (DEFAULT_STEPPER_DEACTIVE_TIME) * 1000UL, "LASER_SAFETY_TIMEOUT_MS must be less than DEFAULT_STEPPER_DEACTIVE_TIME (" STRINGIFY(DEFAULT_STEPPER_DEACTIVE_TIME) " seconds)"); #endif #endif -#if ENABLED(COOLANT_CONTROL) - #if NONE(COOLANT_MIST, COOLANT_FLOOD) - #error "COOLANT_CONTROL requires either COOLANT_MIST or COOLANT_FLOOD." - #elif ENABLED(COOLANT_MIST) && !PIN_EXISTS(COOLANT_MIST) - #error "COOLANT_MIST requires COOLANT_MIST_PIN to be defined." - #elif ENABLED(COOLANT_FLOOD) && !PIN_EXISTS(COOLANT_FLOOD) - #error "COOLANT_FLOOD requires COOLANT_FLOOD_PIN to be defined." - #endif +#if ENABLED(COOLANT_MIST) && !PIN_EXISTS(COOLANT_MIST) + #error "COOLANT_MIST requires COOLANT_MIST_PIN to be defined." +#elif ENABLED(COOLANT_FLOOD) && !PIN_EXISTS(COOLANT_FLOOD) + #error "COOLANT_FLOOD requires COOLANT_FLOOD_PIN to be defined." #endif #if HAS_ADC_BUTTONS && defined(ADC_BUTTON_DEBOUNCE_DELAY) && ADC_BUTTON_DEBOUNCE_DELAY < 16 @@ -3868,44 +4120,10 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive." * Check to make sure MONITOR_DRIVER_STATUS isn't enabled * on boards where TMC drivers share the SPI bus with SD. */ -#if HAS_TMC_SPI && ALL(MONITOR_DRIVER_STATUS, HAS_MEDIA, USES_SHARED_SPI) +#if HAS_TMC_SPI && ALL(MONITOR_DRIVER_STATUS, SDSUPPORT, USES_SHARED_SPI) #error "MONITOR_DRIVER_STATUS and SDSUPPORT cannot be used together on boards with shared SPI." #endif -// Although it just toggles STEP, EDGE_STEPPING requires HIGH state for logic -#if ENABLED(EDGE_STEPPING) - #if AXIS_HAS_DEDGE(X) && STEP_STATE_X != HIGH - #error "STEP_STATE_X must be HIGH for EDGE_STEPPING." - #endif - #if AXIS_HAS_DEDGE(Y) && STEP_STATE_Y != HIGH - #error "STEP_STATE_Y must be HIGH for EDGE_STEPPING." - #endif - #if AXIS_HAS_DEDGE(Z) && STEP_STATE_Z != HIGH - #error "STEP_STATE_Z must be HIGH for EDGE_STEPPING." - #endif - #if AXIS_HAS_DEDGE(I) && STEP_STATE_I != HIGH - #error "STEP_STATE_I must be HIGH for EDGE_STEPPING." - #endif - #if AXIS_HAS_DEDGE(J) && STEP_STATE_J != HIGH - #error "STEP_STATE_J must be HIGH for EDGE_STEPPING." - #endif - #if AXIS_HAS_DEDGE(K) && STEP_STATE_K != HIGH - #error "STEP_STATE_K must be HIGH for EDGE_STEPPING." - #endif - #if AXIS_HAS_DEDGE(U) && STEP_STATE_U != HIGH - #error "STEP_STATE_U must be HIGH for EDGE_STEPPING." - #endif - #if AXIS_HAS_DEDGE(V) && STEP_STATE_V != HIGH - #error "STEP_STATE_V must be HIGH for EDGE_STEPPING." - #endif - #if AXIS_HAS_DEDGE(W) && STEP_STATE_W != HIGH - #error "STEP_STATE_W must be HIGH for EDGE_STEPPING." - #endif - #if AXIS_HAS_DEDGE(E0) && STEP_STATE_E != HIGH - #error "STEP_STATE_E must be HIGH for EDGE_STEPPING." - #endif -#endif - // G60/G61 Position Save #if SAVED_POSITIONS > 256 #error "SAVED_POSITIONS must be an integer from 0 to 256." @@ -3914,33 +4132,16 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive." /** * Touch Screen Calibration */ -#if !MB(SIMULATED) && ENABLED(TFT_TOUCH_DEVICE_XPT2046) && DISABLED(TOUCH_SCREEN_CALIBRATION) \ +#if !MB(LINUX_RAMPS) && ENABLED(TFT_TOUCH_DEVICE_XPT2046) && DISABLED(TOUCH_SCREEN_CALIBRATION) \ && !(defined(TOUCH_CALIBRATION_X) && defined(TOUCH_CALIBRATION_Y) && defined(TOUCH_OFFSET_X) && defined(TOUCH_OFFSET_Y)) #error "TOUCH_CALIBRATION_[XY] and TOUCH_OFFSET_[XY] are required for resistive touch screens with TOUCH_SCREEN_CALIBRATION disabled." #endif -// GT911 Capacitive touch screen such as BIQU_BX_TFT70 -#if ALL(TFT_TOUCH_DEVICE_GT911, TOUCH_SCREEN_CALIBRATION) - #error "TOUCH_SCREEN_CALIBRATION is not supported by the selected LCD controller." -#endif - /** - * Sanity check WiFi options + * Sanity check for WIFI */ -#if ALL(WIFISUPPORT, ESP3D_WIFISUPPORT) - #error "Enable only one of WIFISUPPORT or ESP3D_WIFISUPPORT." -#elif ENABLED(ESP3D_WIFISUPPORT) && DISABLED(ARDUINO_ARCH_ESP32) - #error "ESP3D_WIFISUPPORT requires an ESP32 motherboard." -#elif ALL(ARDUINO_ARCH_ESP32, WIFISUPPORT) - #if !(defined(WIFI_SSID) && defined(WIFI_PWD)) - #error "ESP32 motherboard with WIFISUPPORT requires WIFI_SSID and WIFI_PWD." - #endif -#elif ENABLED(WIFI_CUSTOM_COMMAND) && NONE(ESP3D_WIFISUPPORT, WIFISUPPORT) - #error "WIFI_CUSTOM_COMMAND requires an ESP32 motherboard and WIFISUPPORT." -#elif ENABLED(OTASUPPORT) && NONE(ESP3D_WIFISUPPORT, WIFISUPPORT) - #error "OTASUPPORT requires an ESP32 motherboard and WIFISUPPORT." -#elif (defined(WIFI_SSID) || defined(WIFI_PWD)) && NONE(ESP3D_WIFISUPPORT, WIFISUPPORT) - #error "WIFI_SSID and WIFI_PWD only apply to ESP32 motherboard with WIFISUPPORT." +#if EITHER(ESP3D_WIFISUPPORT, WIFISUPPORT) && DISABLED(ARDUINO_ARCH_ESP32) + #error "ESP3D_WIFISUPPORT or WIFISUPPORT requires an ESP32 MOTHERBOARD." #endif /** @@ -3957,15 +4158,15 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive." /** * Sanity Check for MEATPACK and BINARY_FILE_TRANSFER Features */ -#if ALL(HAS_MEATPACK, BINARY_FILE_TRANSFER) +#if BOTH(HAS_MEATPACK, BINARY_FILE_TRANSFER) #error "Either enable MEATPACK_ON_SERIAL_PORT_* or BINARY_FILE_TRANSFER, not both." #endif /** * Sanity Check for Slim LCD Menus and Probe Offset Wizard */ -#if ALL(SLIM_LCD_MENUS, PROBE_OFFSET_WIZARD) - #error "SLIM_LCD_MENUS disables 'Advanced Settings > Probe Offsets > PROBE_OFFSET_WIZARD.'" +#if BOTH(SLIM_LCD_MENUS, PROBE_OFFSET_WIZARD) + #error "SLIM_LCD_MENUS disables \"Advanced Settings > Probe Offsets > PROBE_OFFSET_WIZARD.\"" #endif /** @@ -3983,25 +4184,10 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive." #undef _CLEAN_ASSERT #endif -/** - * Sanity check nozzle cleaning pattern settings - */ -#if ENABLED(NOZZLE_CLEAN_FEATURE) - #if NONE(NOZZLE_CLEAN_PATTERN_LINE, NOZZLE_CLEAN_PATTERN_ZIGZAG, NOZZLE_CLEAN_PATTERN_CIRCLE) - #error "NOZZLE_CLEAN_FEATURE requires at least one of NOZZLE_CLEAN_PATTERN_LINE, NOZZLE_CLEAN_PATTERN_ZIGZAG, and/or NOZZLE_CLEAN_PATTERN_CIRCLE." - #elif NOZZLE_CLEAN_DEFAULT_PATTERN == 0 && DISABLED(NOZZLE_CLEAN_PATTERN_LINE) - #error "NOZZLE_CLEAN_DEFAULT_PATTERN 0 (LINE) is not available. Enable NOZZLE_CLEAN_PATTERN_LINE or set a different NOZZLE_CLEAN_DEFAULT_PATTERN." - #elif NOZZLE_CLEAN_DEFAULT_PATTERN == 1 && DISABLED(NOZZLE_CLEAN_PATTERN_ZIGZAG) - #error "NOZZLE_CLEAN_DEFAULT_PATTERN 1 (ZIGZAG) is not available. Enable NOZZLE_CLEAN_PATTERN_ZIGZAG or set a different NOZZLE_CLEAN_DEFAULT_PATTERN." - #elif NOZZLE_CLEAN_DEFAULT_PATTERN == 2 && DISABLED(NOZZLE_CLEAN_PATTERN_CIRCLE) - #error "NOZZLE_CLEAN_DEFAULT_PATTERN 2 (CIRCLE) is not available. Enable NOZZLE_CLEAN_PATTERN_CIRCLE or set a different NOZZLE_CLEAN_DEFAULT_PATTERN." - #endif -#endif - /** * Sanity check for MIXING_EXTRUDER & DISTINCT_E_FACTORS these are not compatible */ -#if ALL(MIXING_EXTRUDER, DISTINCT_E_FACTORS) +#if BOTH(MIXING_EXTRUDER, DISTINCT_E_FACTORS) #error "MIXING_EXTRUDER can't be used with DISTINCT_E_FACTORS. But you may use SINGLENOZZLE with DISTINCT_E_FACTORS." #endif @@ -4078,89 +4264,38 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive." #undef _BAD_DRIVER /** - * Require certain features for DGUS_LCD_UI RELOADED. + * Require certain features for DGUS_LCD_UI_RELOADED. */ -#if DGUS_UI_IS(RELOADED) +#if ENABLED(DGUS_LCD_UI_RELOADED) #if BUFSIZE < 4 - #error "DGUS_LCD_UI RELOADED requires a BUFSIZE of at least 4." + #error "DGUS_LCD_UI_RELOADED requires a BUFSIZE of at least 4." #elif HOTENDS < 1 - #error "DGUS_LCD_UI RELOADED requires at least 1 hotend." + #error "DGUS_LCD_UI_RELOADED requires at least 1 hotend." #elif EXTRUDERS < 1 - #error "DGUS_LCD_UI RELOADED requires at least 1 extruder." + #error "DGUS_LCD_UI_RELOADED requires at least 1 extruder." #elif !HAS_HEATED_BED - #error "DGUS_LCD_UI RELOADED requires a heated bed." + #error "DGUS_LCD_UI_RELOADED requires a heated bed." #elif FAN_COUNT < 1 - #error "DGUS_LCD_UI RELOADED requires a fan." + #error "DGUS_LCD_UI_RELOADED requires a fan." #elif !HAS_BED_PROBE - #error "DGUS_LCD_UI RELOADED requires a bed probe." + #error "DGUS_LCD_UI_RELOADED requires a bed probe." #elif !HAS_MESH - #error "DGUS_LCD_UI RELOADED requires mesh leveling." + #error "DGUS_LCD_UI_RELOADED requires mesh leveling." #elif DISABLED(LCD_BED_TRAMMING) - #error "DGUS_LCD_UI RELOADED requires LCD_BED_TRAMMING." + #error "DGUS_LCD_UI_RELOADED requires LCD_BED_TRAMMING." #elif DISABLED(BABYSTEP_ALWAYS_AVAILABLE) - #error "DGUS_LCD_UI RELOADED requires BABYSTEP_ALWAYS_AVAILABLE." + #error "DGUS_LCD_UI_RELOADED requires BABYSTEP_ALWAYS_AVAILABLE." #elif DISABLED(BABYSTEP_ZPROBE_OFFSET) - #error "DGUS_LCD_UI RELOADED requires BABYSTEP_ZPROBE_OFFSET." - #elif ENABLED(HOME_AFTER_DEACTIVATE) - #error "DGUS_LCD_UI RELOADED requires HOME_AFTER_DEACTIVATE to be disabled." + #error "DGUS_LCD_UI_RELOADED requires BABYSTEP_ZPROBE_OFFSET." #elif ENABLED(AUTO_BED_LEVELING_UBL) && DISABLED(UBL_SAVE_ACTIVE_ON_M500) #warning "Without UBL_SAVE_ACTIVE_ON_M500, your mesh will not be saved when using the touchscreen." #endif #endif -/** - * Require certain features for DGUS_LCD_UI IA_CREALITY. - */ -#if DGUS_UI_IS(IA_CREALITY) - #if DISABLED(ADVANCED_PAUSE_FEATURE) - #error "DGUS_LCD_UI IA_CREALITY requires ADVANCED_PAUSE_FEATURE." - #elif DISABLED(LCD_BED_TRAMMING) - #error "DGUS_LCD_UI IA_CREALITY requires LCD_BED_TRAMMING." - #elif DISABLED(CLASSIC_JERK) - #error "DGUS_LCD_UI IA_CREALITY requires CLASSIC_JERK." - #elif DISABLED(BABYSTEPPING) - #error "DGUS_LCD_UI IA_CREALITY requires BABYSTEPPING." - #elif NUM_RUNOUT_SENSORS > 1 - #error "DGUS_LCD_UI IA_CREALITY requires NUM_RUNOUT_SENSORS < 2." - #elif NONE(AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_UBL, MESH_BED_LEVELING) - #error "DGUS_LCD_UI IA_CREALITY requires AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_UBL, or MESH_BED_LEVELING." - #endif -#endif - -/** - * Require certain features for DGUS_LCD_UI E3S1PRO. - */ -#if DGUS_UI_IS(E3S1PRO) - #if BUFSIZE < 4 - #error "DGUS_LCD_UI E3S1PRO requires a BUFSIZE of at least 4." - #elif !(HOTENDS == 1) - #error "DGUS_LCD_UI E3S1PRO requires 1 hotend." - #elif !(EXTRUDERS == 1) - #error "DGUS_LCD_UI E3S1PRO requires at least 1 extruder." - #elif !HAS_HEATED_BED - #error "DGUS_LCD_UI E3S1PRO requires a heated bed." - #elif FAN_COUNT < 1 - #error "DGUS_LCD_UI E3S1PRO requires a fan." - #elif !HAS_BED_PROBE - #error "DGUS_LCD_UI E3S1PRO requires a bed probe." - #elif !HAS_MESH - #error "DGUS_LCD_UI E3S1PRO requires mesh leveling." - #elif !HAS_MEDIA - #error "DGUS_LCD_UI E3S1PRO requires SDSUPPORT." - #elif DISABLED(POWER_LOSS_RECOVERY) - #error "DGUS_LCD_UI E3S1PRO requires POWER_LOSS_RECOVERY." - #elif DISABLED(LCD_BED_TRAMMING) - #error "DGUS_LCD_UI E3S1PRO requires LCD_BED_TRAMMING." - #elif DISABLED(BABYSTEP_ALWAYS_AVAILABLE) - #error "DGUS_LCD_UI E3S1PRO requires BABYSTEP_ALWAYS_AVAILABLE." - #elif DISABLED(BABYSTEP_ZPROBE_OFFSET) - #error "DGUS_LCD_UI E3S1PRO requires BABYSTEP_ZPROBE_OFFSET." - #elif !defined(PREHEAT_1_TEMP_HOTEND) || !defined(PREHEAT_2_TEMP_HOTEND) - #error "DGUS_LCD_UI E3S1PRO requires 2 preheating presets." - #elif ENABLED(AUTO_BED_LEVELING_UBL) && DISABLED(UBL_SAVE_ACTIVE_ON_M500) - #warning "Without UBL_SAVE_ACTIVE_ON_M500, your mesh will not be saved when using the touchscreen." - #endif -#endif +// Misc. Cleanup +#undef _TEST_PWM +#undef _NUM_AXES_STR +#undef _LOGICAL_AXES_STR // JTAG support in the HAL #if ENABLED(DISABLE_DEBUG) && !defined(JTAGSWD_DISABLE) @@ -4170,95 +4305,6 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive." #endif // Check requirements for upload.py -#if ENABLED(XFER_BUILD) && !ALL(SDSUPPORT, BINARY_FILE_TRANSFER, CUSTOM_FIRMWARE_UPLOAD) - #error "SDSUPPORT, BINARY_FILE_TRANSFER, and CUSTOM_FIRMWARE_UPLOAD are required for custom upload." +#if ENABLED(XFER_BUILD) && !BOTH(BINARY_FILE_TRANSFER, CUSTOM_FIRMWARE_UPLOAD) + #error "BINARY_FILE_TRANSFER and CUSTOM_FIRMWARE_UPLOAD are required for custom upload." #endif - -/** - * Input Shaping requirements - */ -#if HAS_ZV_SHAPING - #if ENABLED(DELTA) - #error "Input Shaping is not compatible with DELTA kinematics." - #elif ENABLED(SCARA) - #error "Input Shaping is not compatible with SCARA kinematics." - #elif ENABLED(TPARA) - #error "Input Shaping is not compatible with TPARA kinematics." - #elif ENABLED(POLAR) - #error "Input Shaping is not compatible with POLAR kinematics." - #elif ENABLED(POLARGRAPH) - #error "Input Shaping is not compatible with POLARGRAPH kinematics." - #elif ENABLED(DIRECT_STEPPING) - #error "Input Shaping is not compatible with DIRECT_STEPPING." - #elif ALL(INPUT_SHAPING_X, CORE_IS_XZ) - #error "INPUT_SHAPING_X is not supported with COREXZ." - #elif ALL(INPUT_SHAPING_Y, CORE_IS_YZ) - #error "INPUT_SHAPING_Y is not supported with COREYZ." - #elif ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) - #if !ALL(INPUT_SHAPING_X, INPUT_SHAPING_Y) - #error "INPUT_SHAPING_X and INPUT_SHAPING_Y must both be enabled for COREXY, COREYX, or MARKFORGED_*." - #else - static_assert(SHAPING_FREQ_X == SHAPING_FREQ_Y, "SHAPING_FREQ_X and SHAPING_FREQ_Y must be the same for COREXY / COREYX / MARKFORGED_*."); - static_assert(SHAPING_ZETA_X == SHAPING_ZETA_Y, "SHAPING_ZETA_X and SHAPING_ZETA_Y must be the same for COREXY / COREYX / MARKFORGED_*."); - #endif - #endif - - #ifdef SHAPING_MIN_FREQ - static_assert((SHAPING_MIN_FREQ) > 0, "SHAPING_MIN_FREQ must be > 0."); - #else - TERN_(INPUT_SHAPING_X, static_assert((SHAPING_FREQ_X) > 0, "SHAPING_FREQ_X must be > 0 or SHAPING_MIN_FREQ must be set.")); - TERN_(INPUT_SHAPING_Y, static_assert((SHAPING_FREQ_Y) > 0, "SHAPING_FREQ_Y must be > 0 or SHAPING_MIN_FREQ must be set.")); - #endif - #ifdef __AVR__ - #if ENABLED(INPUT_SHAPING_X) - #if F_CPU > 16000000 - static_assert((SHAPING_FREQ_X) == 0 || (SHAPING_FREQ_X) * 2 * 0x10000 >= (STEPPER_TIMER_RATE), "SHAPING_FREQ_X is below the minimum (20) for AVR 20MHz."); - #else - static_assert((SHAPING_FREQ_X) == 0 || (SHAPING_FREQ_X) * 2 * 0x10000 >= (STEPPER_TIMER_RATE), "SHAPING_FREQ_X is below the minimum (16) for AVR 16MHz."); - #endif - #endif - #if ENABLED(INPUT_SHAPING_Y) - #if F_CPU > 16000000 - static_assert((SHAPING_FREQ_Y) == 0 || (SHAPING_FREQ_Y) * 2 * 0x10000 >= (STEPPER_TIMER_RATE), "SHAPING_FREQ_Y is below the minimum (20) for AVR 20MHz."); - #else - static_assert((SHAPING_FREQ_Y) == 0 || (SHAPING_FREQ_Y) * 2 * 0x10000 >= (STEPPER_TIMER_RATE), "SHAPING_FREQ_Y is below the minimum (16) for AVR 16MHz."); - #endif - #endif - #endif -#endif - -/** - * Fixed-Time Motion limitations - */ -#if ENABLED(FT_MOTION) - #if ENABLED(MIXING_EXTRUDER) - #error "FT_MOTION does not currently support MIXING_EXTRUDER." - #elif DISABLED(FTM_UNIFIED_BWS) - #error "FT_MOTION requires FTM_UNIFIED_BWS to be enabled because FBS is not yet implemented." - #endif -#endif - -// Multi-Stepping Limit -static_assert(WITHIN(MULTISTEPPING_LIMIT, 1, 128) && IS_POWER_OF_2(MULTISTEPPING_LIMIT), "MULTISTEPPING_LIMIT must be 1, 2, 4, 8, 16, 32, 64, or 128."); - -// One Click Print -#if ENABLED(ONE_CLICK_PRINT) - #if !HAS_MEDIA - #error "SD Card or Flash Drive is required for ONE_CLICK_PRINT." - #elif ENABLED(BROWSE_MEDIA_ON_INSERT) - #error "ONE_CLICK_PRINT is incompatible with BROWSE_MEDIA_ON_INSERT." - #elif DISABLED(NO_SD_AUTOSTART) - #error "NO_SD_AUTOSTART must be enabled for ONE_CLICK_PRINT." - #elif !defined(HAS_MARLINUI_MENU) - #error "ONE_CLICK_PRINT needs a display that has Marlin UI menus." - #endif -#endif - -#if ALL(ULTIPANEL_FEEDMULTIPLY, ULTIPANEL_FLOWPERCENT) - #error "Only enable ULTIPANEL_FEEDMULTIPLY or ULTIPANEL_FLOWPERCENT, but not both." -#endif - -// Misc. Cleanup -#undef _TEST_PWM -#undef _NUM_AXES_STR -#undef _LOGICAL_AXES_STR diff --git a/Marlin/src/lcd/e3v2/jyersui/dwin.cpp b/Marlin/src/lcd/e3v2/jyersui/dwin.cpp index a29f5fc42f..a000698bb8 100644 --- a/Marlin/src/lcd/e3v2/jyersui/dwin.cpp +++ b/Marlin/src/lcd/e3v2/jyersui/dwin.cpp @@ -38,6 +38,7 @@ #include "../../../module/planner.h" #include "../../../module/settings.h" #include "../../../libs/buzzer.h" +#include "../../../inc/Conditionals_post.h" //#define DEBUG_OUT 1 #include "../../../core/debug_out.h" @@ -58,6 +59,10 @@ #define HAS_ZOFFSET_ITEM 1 #endif +#ifndef strcasecmp_P + #define strcasecmp_P(a, b) strcasecmp((a), (b)) +#endif + #if HAS_LEVELING #include "../../../feature/bedlevel/bedlevel.h" #endif @@ -75,13 +80,6 @@ #include "../../../feature/powerloss.h" #endif -#if HAS_TRINAMIC_CONFIG - #include "../../../module/stepper/trinamic.h" - - #define TMC_MIN_CURRENT 400 - #define TMC_MAX_CURRENT 1500 -#endif - #define MACHINE_SIZE STRINGIFY(X_BED_SIZE) "x" STRINGIFY(Y_BED_SIZE) "x" STRINGIFY(Z_MAX_POS) #define DWIN_FONT_MENU font8x16 @@ -91,7 +89,7 @@ #define MENU_CHAR_LIMIT 24 #define STATUS_Y 352 -#define MAX_PRINT_SPEED 999 +#define MAX_PRINT_SPEED 500 #define MIN_PRINT_SPEED 10 #if HAS_FAN @@ -111,26 +109,21 @@ #endif #if HAS_HOTEND - #define MAX_FLOW_RATE 299 + #define MAX_FLOW_RATE 200 #define MIN_FLOW_RATE 10 - #define MAX_E_TEMP thermalManager.hotend_max_target(0) + #define MAX_E_TEMP (HEATER_0_MAXTEMP - HOTEND_OVERSHOOT) #define MIN_E_TEMP 0 #endif #if HAS_HEATED_BED - #define MAX_BED_TEMP BED_MAX_TARGET + #define MAX_BED_TEMP BED_MAXTEMP #define MIN_BED_TEMP 0 #endif -#define FEEDRATE_UNIT 1 -#define ACCELERATION_UNIT 1 -#define JERK_UNIT 10 -#define STEPS_UNIT 10 - -// -// Custom menu items with JyersLCD -// +/** + * Custom menu items with jyersLCD + */ #if ENABLED(CUSTOM_MENU_CONFIG) #ifdef CONFIG_MENU_ITEM_5_DESC #define CUSTOM_MENU_COUNT 5 @@ -156,6 +149,13 @@ constexpr uint16_t TROWS = 6, MROWS = TROWS - 1, #define MBASE(L) (49 + MLINE * (L)) +constexpr float default_max_feedrate[] = DEFAULT_MAX_FEEDRATE; +constexpr float default_max_acceleration[] = DEFAULT_MAX_ACCELERATION; +constexpr float default_steps[] = DEFAULT_AXIS_STEPS_PER_UNIT; +#if HAS_CLASSIC_JERK + constexpr float default_max_jerk[] = { DEFAULT_XJERK, DEFAULT_YJERK, DEFAULT_ZJERK, DEFAULT_EJERK }; +#endif + enum SelectItem : uint8_t { PAGE_PRINT = 0, PAGE_PREPARE, @@ -169,10 +169,10 @@ enum SelectItem : uint8_t { PRINT_COUNT }; -uint8_t active_menu = ID_MainMenu, last_menu = ID_MainMenu; +uint8_t active_menu = MainMenu, last_menu = MainMenu; uint8_t selection = 0, last_selection = 0; uint8_t scrollpos = 0; -uint8_t process = Proc_Main, last_process = Proc_Main; +uint8_t process = Main, last_process = Main; PopupID popup, last_popup; void (*funcpointer)() = nullptr; @@ -183,6 +183,7 @@ float valuemax; uint8_t valueunit; uint8_t valuetype; +char cmd[MAX_CMD_SIZE+16], str_1[16], str_2[16], str_3[16]; char statusmsg[64]; char filename[LONG_FILENAME_LENGTH]; bool printing = false; @@ -195,13 +196,13 @@ bool livemove = false; bool liveadjust = false; uint8_t preheatmode = 0; float zoffsetvalue = 0; -grid_count_t gridpoint; +uint8_t gridpoint; float corner_avg; float corner_pos; bool probe_deployed = false; -JyersDWIN jyersDWIN; +CrealityDWINClass CrealityDWIN; template class TextScroller { @@ -254,7 +255,7 @@ private: #if HAS_MESH - struct { + struct Mesh_Settings { bool viewer_asymmetric_range = false; bool viewer_print_value = false; bool goto_mesh_value = false; @@ -265,14 +266,13 @@ private: #if ENABLED(AUTO_BED_LEVELING_UBL) uint8_t tilt_grid = 1; - void manualValueUpdate(bool undefined=false) { - gcode.process_subcommands_now( - TS(F("M421I"), mesh_x, 'J', mesh_y, 'Z', p_float_t(current_position.z, 3), undefined ? "N" : "") - ); + void manual_value_update(bool undefined=false) { + sprintf_P(cmd, PSTR("M421 I%i J%i Z%s %s"), mesh_x, mesh_y, dtostrf(current_position.z, 1, 3, str_1), undefined ? "N" : ""); + gcode.process_subcommands_now(cmd); planner.synchronize(); } - bool createPlaneFromMesh() { + bool create_plane_from_mesh() { struct linear_fit_data lsf_results; incremental_LSF_reset(&lsf_results); GRID_LOOP(x, y) { @@ -291,17 +291,29 @@ private: matrix_3x3 rotation = matrix_3x3::create_look_at(vector_3(lsf_results.A, lsf_results.B, 1)); GRID_LOOP(i, j) { - float mx = bedlevel.get_mesh_x(i), my = bedlevel.get_mesh_y(j), mz = bedlevel.z_values[i][j]; + float mx = bedlevel.get_mesh_x(i), + my = bedlevel.get_mesh_y(j), + mz = bedlevel.z_values[i][j]; if (DEBUGGING(LEVELING)) { - DEBUG_ECHOLN(F("before rotation = ["), p_float_t(mx, 7), C(','), p_float_t(my, 7), C(','), p_float_t(mz, 7), F("] ---> ")); + DEBUG_ECHOPAIR_F("before rotation = [", mx, 7); + DEBUG_CHAR(','); + DEBUG_ECHO_F(my, 7); + DEBUG_CHAR(','); + DEBUG_ECHO_F(mz, 7); + DEBUG_ECHOPGM("] ---> "); DEBUG_DELAY(20); } rotation.apply_rotation_xyz(mx, my, mz); if (DEBUGGING(LEVELING)) { - DEBUG_ECHOLN(F("after rotation = ["), p_float_t(mx, 7), C(','), p_float_t(my, 7), C(','), p_float_t(mz, 7), C(']')); + DEBUG_ECHOPAIR_F("after rotation = [", mx, 7); + DEBUG_CHAR(','); + DEBUG_ECHO_F(my, 7); + DEBUG_CHAR(','); + DEBUG_ECHO_F(mz, 7); + DEBUG_ECHOLNPGM("]"); DEBUG_DELAY(20); } @@ -312,10 +324,9 @@ private: #else - void manualValueUpdate() { - gcode.process_subcommands_now( - TS(F("G29I"), mesh_x, 'J', mesh_y, 'Z', p_float_t(current_position.z, 3)) - ); + void manual_value_update() { + sprintf_P(cmd, PSTR("G29 I%i J%i Z%s"), mesh_x, mesh_y, dtostrf(current_position.z, 1, 3, str_1)); + gcode.process_subcommands_now(cmd); planner.synchronize(); } @@ -329,57 +340,66 @@ private: planner.synchronize(); } else { - jyersDWIN.popupHandler(Popup_MoveWait); - gcode.process_subcommands_now(TS(F("G0F300Z"), p_float_t(current_position.z, 3))); - gcode.process_subcommands_now(TS(F("G42 F4000 I"), mesh_x, 'J', mesh_y)); + CrealityDWIN.Popup_Handler(MoveWait); + sprintf_P(cmd, PSTR("G0 F300 Z%s"), dtostrf(Z_CLEARANCE_BETWEEN_PROBES, 1, 3, str_1)); + gcode.process_subcommands_now(cmd); + sprintf_P(cmd, PSTR("G42 F4000 I%i J%i"), mesh_x, mesh_y); + gcode.process_subcommands_now(cmd); planner.synchronize(); current_position.z = goto_mesh_value ? bedlevel.z_values[mesh_x][mesh_y] : Z_CLEARANCE_BETWEEN_PROBES; planner.buffer_line(current_position, homing_feedrate(Z_AXIS), active_extruder); planner.synchronize(); - jyersDWIN.redrawMenu(); + CrealityDWIN.Redraw_Menu(); } } - float getMaxValue() { - float max = -(__FLT_MAX__); - GRID_LOOP(x, y) { const float z = bedlevel.z_values[x][y]; if (!isnan(z)) NOLESS(max, z); } + float get_max_value() { + float max = __FLT_MIN__; + GRID_LOOP(x, y) { + if (!isnan(bedlevel.z_values[x][y]) && bedlevel.z_values[x][y] > max) + max = bedlevel.z_values[x][y]; + } return max; } - float getMinValue() { + float get_min_value() { float min = __FLT_MAX__; - GRID_LOOP(x, y) { const float z = bedlevel.z_values[x][y]; if (!isnan(z)) NOMORE(min, z); } + GRID_LOOP(x, y) { + if (!isnan(bedlevel.z_values[x][y]) && bedlevel.z_values[x][y] < min) + min = bedlevel.z_values[x][y]; + } return min; } - void drawBedMesh(const int16_t selected=-1, const uint8_t gridline_width=1, const uint16_t padding_x=8, const uint16_t padding_y_top=40 + 53 - 7) { + void Draw_Bed_Mesh(int16_t selected = -1, uint8_t gridline_width = 1, uint16_t padding_x = 8, uint16_t padding_y_top = 40 + 53 - 7) { drawing_mesh = true; const uint16_t total_width_px = DWIN_WIDTH - padding_x - padding_x, cell_width_px = total_width_px / (GRID_MAX_POINTS_X), cell_height_px = total_width_px / (GRID_MAX_POINTS_Y); - const float v_max = abs(getMaxValue()), v_min = abs(getMinValue()), rmax = _MAX(v_min, v_max); + const float v_max = abs(get_max_value()), v_min = abs(get_min_value()), range = _MAX(v_min, v_max); // Clear background from previous selection and select new square - dwinDrawRectangle(1, COLOR_BG_BLACK, _MAX(0, padding_x - gridline_width), _MAX(0, padding_y_top - gridline_width), padding_x + total_width_px, padding_y_top + total_width_px); + DWIN_Draw_Rectangle(1, Color_Bg_Black, _MAX(0, padding_x - gridline_width), _MAX(0, padding_y_top - gridline_width), padding_x + total_width_px, padding_y_top + total_width_px); if (selected >= 0) { const auto selected_y = selected / (GRID_MAX_POINTS_X); const auto selected_x = selected - (GRID_MAX_POINTS_X) * selected_y; const auto start_y_px = padding_y_top + selected_y * cell_height_px; const auto start_x_px = padding_x + selected_x * cell_width_px; - dwinDrawRectangle(1, COLOR_WHITE, _MAX(0, start_x_px - gridline_width), _MAX(0, start_y_px - gridline_width), start_x_px + cell_width_px, start_y_px + cell_height_px); + DWIN_Draw_Rectangle(1, Color_White, _MAX(0, start_x_px - gridline_width), _MAX(0, start_y_px - gridline_width), start_x_px + cell_width_px, start_y_px + cell_height_px); } // Draw value square grid + char buf[8]; GRID_LOOP(x, y) { const auto start_x_px = padding_x + x * cell_width_px; const auto end_x_px = start_x_px + cell_width_px - 1 - gridline_width; const auto start_y_px = padding_y_top + (GRID_MAX_POINTS_Y - y - 1) * cell_height_px; const auto end_y_px = start_y_px + cell_height_px - 1 - gridline_width; - dwinDrawRectangle(1, // RGB565 colors: http://www.barth-dev.de/online/rgb565-color-picker/ - isnan(bedlevel.z_values[x][y]) ? COLOR_GREY : ( // gray if undefined + DWIN_Draw_Rectangle(1, // RGB565 colors: http://www.barth-dev.de/online/rgb565-color-picker/ + isnan(bedlevel.z_values[x][y]) ? Color_Grey : ( // gray if undefined (bedlevel.z_values[x][y] < 0 ? - (uint16_t)round(0x1F * -bedlevel.z_values[x][y] / (!viewer_asymmetric_range ? rmax : v_min)) << 11 : // red if mesh point value is negative - (uint16_t)round(0x3F * bedlevel.z_values[x][y] / (!viewer_asymmetric_range ? rmax : v_max)) << 5) | // green if mesh point value is positive + (uint16_t)round(0x1F * -bedlevel.z_values[x][y] / (!viewer_asymmetric_range ? range : v_min)) << 11 : // red if mesh point value is negative + (uint16_t)round(0x3F * bedlevel.z_values[x][y] / (!viewer_asymmetric_range ? range : v_max)) << 5) | // green if mesh point value is positive _MIN(0x1F, (((uint8_t)abs(bedlevel.z_values[x][y]) / 10) * 4))), // + blue stepping for every mm start_x_px, start_y_px, end_x_px, end_y_px ); @@ -389,20 +409,19 @@ private: // Draw value text on if (viewer_print_value) { - const int8_t offset_y = cell_height_px / 2 - 6; + int8_t offset_x, offset_y = cell_height_px / 2 - 6; if (isnan(bedlevel.z_values[x][y])) { // undefined - dwinDrawString(false, font6x12, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + cell_width_px / 2 - 5, start_y_px + offset_y, F("X")); + DWIN_Draw_String(false, font6x12, Color_White, Color_Bg_Blue, start_x_px + cell_width_px / 2 - 5, start_y_px + offset_y, F("X")); } else { // has value - MString<12> msg; if (GRID_MAX_POINTS_X < 10) - msg.set(p_float_t(abs(bedlevel.z_values[x][y]), 2)); + sprintf_P(buf, PSTR("%s"), dtostrf(abs(bedlevel.z_values[x][y]), 1, 2, str_1)); else - msg.setf(F("%02i"), uint16_t(abs(bedlevel.z_values[x][y] - int16_t(bedlevel.z_values[x][y])) * 100)); - const int8_t offset_x = cell_width_px / 2 - 3 * msg.length() - 2; - if (GRID_MAX_POINTS_X >= 10) - dwinDrawString(false, font6x12, COLOR_WHITE, COLOR_BG_BLUE, start_x_px - 2 + offset_x, start_y_px + offset_y /*+ square / 2 - 6*/, F(".")); - dwinDrawString(false, font6x12, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + 1 + offset_x, start_y_px + offset_y /*+ square / 2 - 6*/, msg); + sprintf_P(buf, PSTR("%02i"), (uint16_t)(abs(bedlevel.z_values[x][y] - (int16_t)bedlevel.z_values[x][y]) * 100)); + offset_x = cell_width_px / 2 - 3 * (strlen(buf)) - 2; + if (!(GRID_MAX_POINTS_X < 10)) + DWIN_Draw_String(false, font6x12, Color_White, Color_Bg_Blue, start_x_px - 2 + offset_x, start_y_px + offset_y /*+ square / 2 - 6*/, F(".")); + DWIN_Draw_String(false, font6x12, Color_White, Color_Bg_Blue, start_x_px + 1 + offset_x, start_y_px + offset_y /*+ square / 2 - 6*/, buf); } safe_delay(10); LCD_SERIAL.flushTX(); @@ -410,360 +429,379 @@ private: } } - void setMeshViewerStatus() { // TODO: draw gradient with values as a legend instead - float v1, v2, - v_min = abs(getMinValue()), - v_max = abs(getMaxValue()); + void Set_Mesh_Viewer_Status() { // TODO: draw gradient with values as a legend instead + float v_max = abs(get_max_value()), v_min = abs(get_min_value()), range = _MAX(v_min, v_max); + if (v_min > 3e+10F) v_min = 0.0000001; + if (v_max > 3e+10F) v_max = 0.0000001; + if (range > 3e+10F) range = 0.0000001; + char msg[46]; if (viewer_asymmetric_range) { - if (v_min > 3e+10f) v_min = 0.0000001; - if (v_max > 3e+10f) v_max = 0.0000001; - v1 = -v_min; - v2 = v_max; + dtostrf(-v_min, 1, 3, str_1); + dtostrf( v_max, 1, 3, str_2); } else { - float rmax = _MAX(v_min, v_max), rmin = _MIN(v_min, v_max); - if (rmax > 3e+10f) rmax = 0.0000001; - if (rmin > 3e+10f) rmin = 0.0000001; - v1 = -rmax; - v2 = rmin; + dtostrf(-range, 1, 3, str_1); + dtostrf( range, 1, 3, str_2); } - jyersDWIN.updateStatus(TS(GET_TEXT_F(MSG_COLORS_RED), ' ', p_float_t(v1, 3) , F("..0.."), p_float_t(v2, 3), ' ', GET_TEXT_F(MSG_COLORS_GREEN))); + sprintf_P(msg, PSTR("Red %s..0..%s Green"), str_1, str_2); + CrealityDWIN.Update_Status(msg); drawing_mesh = false; } - } mesh_conf; + }; + Mesh_Settings mesh_conf; #endif // HAS_MESH -// -// General Display Functions -// +/* General Display Functions */ -struct JyersDWIN::EEPROM_Settings JyersDWIN::eeprom_settings{0}; -constexpr const char * const JyersDWIN::color_names[11]; -constexpr const char * const JyersDWIN::preheat_modes[3]; +struct CrealityDWINClass::EEPROM_Settings CrealityDWINClass::eeprom_settings{0}; +constexpr const char * const CrealityDWINClass::color_names[11]; +constexpr const char * const CrealityDWINClass::preheat_modes[3]; // Clear a part of the screen // 4=Entire screen // 3=Title bar and Menu area (default) // 2=Menu area // 1=Title bar -void JyersDWIN::clearScreen(const uint8_t e/*=3*/) { - if (e == 1 || e == 3 || e == 4) dwinDrawRectangle(1, getColor(eeprom_settings.menu_top_bg, COLOR_BG_BLUE, false), 0, 0, DWIN_WIDTH, TITLE_HEIGHT); // Clear Title Bar - if (e == 2 || e == 3) dwinDrawRectangle(1, COLOR_BG_BLACK, 0, 31, DWIN_WIDTH, STATUS_Y); // Clear Menu Area - if (e == 4) dwinDrawRectangle(1, COLOR_BG_BLACK, 0, 31, DWIN_WIDTH, DWIN_HEIGHT); // Clear Popup Area +void CrealityDWINClass::Clear_Screen(uint8_t e/*=3*/) { + if (e == 1 || e == 3 || e == 4) DWIN_Draw_Rectangle(1, GetColor(eeprom_settings.menu_top_bg, Color_Bg_Blue, false), 0, 0, DWIN_WIDTH, TITLE_HEIGHT); // Clear Title Bar + if (e == 2 || e == 3) DWIN_Draw_Rectangle(1, Color_Bg_Black, 0, 31, DWIN_WIDTH, STATUS_Y); // Clear Menu Area + if (e == 4) DWIN_Draw_Rectangle(1, Color_Bg_Black, 0, 31, DWIN_WIDTH, DWIN_HEIGHT); // Clear Popup Area } -void JyersDWIN::drawFloat(const_float_t value, const uint8_t row, const bool selected/*=false*/, const uint8_t minunit/*=10*/) { +void CrealityDWINClass::Draw_Float(float value, uint8_t row, bool selected/*=false*/, uint8_t minunit/*=10*/) { const uint8_t digits = (uint8_t)floor(log10(abs(value))) + log10(minunit) + (minunit > 1); - const uint16_t bColor = selected ? COLOR_SELECT : COLOR_BG_BLACK; + const uint16_t bColor = (selected) ? Select_Color : Color_Bg_Black; const uint16_t xpos = 240 - (digits * 8); - dwinDrawRectangle(1, COLOR_BG_BLACK, 194, MBASE(row), 234 - (digits * 8), MBASE(row) + 16); + DWIN_Draw_Rectangle(1, Color_Bg_Black, 194, MBASE(row), 234 - (digits * 8), MBASE(row) + 16); if (isnan(value)) - dwinDrawString(true, DWIN_FONT_MENU, COLOR_WHITE, bColor, xpos - 8, MBASE(row), F(" NaN")); + DWIN_Draw_String(true, DWIN_FONT_MENU, Color_White, bColor, xpos - 8, MBASE(row), F(" NaN")); else { - dwinDrawFloatValue(true, true, 0, DWIN_FONT_MENU, COLOR_WHITE, bColor, digits - log10(minunit) + 1, log10(minunit), xpos, MBASE(row), (value < 0 ? -value : value)); - dwinDrawString(true, DWIN_FONT_MENU, COLOR_WHITE, bColor, xpos - 8, MBASE(row), value < 0 ? F("-") : F(" ")); + DWIN_Draw_FloatValue(true, true, 0, DWIN_FONT_MENU, Color_White, bColor, digits - log10(minunit) + 1, log10(minunit), xpos, MBASE(row), (value < 0 ? -value : value)); + DWIN_Draw_String(true, DWIN_FONT_MENU, Color_White, bColor, xpos - 8, MBASE(row), value < 0 ? F("-") : F(" ")); } } -void JyersDWIN::drawOption(const uint8_t value, const char * const * options, const uint8_t row, const bool selected/*=false*/, const bool color/*=false*/) { - const uint16_t bColor = selected ? COLOR_SELECT : COLOR_BG_BLACK, - tColor = color ? getColor(value, COLOR_WHITE, false) : COLOR_WHITE; - dwinDrawRectangle(1, bColor, 202, MBASE(row) + 14, 258, MBASE(row) - 2); - dwinDrawString(false, DWIN_FONT_MENU, tColor, bColor, 202, MBASE(row) - 1, options[value]); +void CrealityDWINClass::Draw_Option(uint8_t value, const char * const * options, uint8_t row, bool selected/*=false*/, bool color/*=false*/) { + uint16_t bColor = (selected) ? Select_Color : Color_Bg_Black, + tColor = (color) ? GetColor(value, Color_White, false) : Color_White; + DWIN_Draw_Rectangle(1, bColor, 202, MBASE(row) + 14, 258, MBASE(row) - 2); + DWIN_Draw_String(false, DWIN_FONT_MENU, tColor, bColor, 202, MBASE(row) - 1, options[value]); } -uint16_t JyersDWIN::getColor(const uint8_t color, const uint16_t original, const bool light/*=false*/) { +uint16_t CrealityDWINClass::GetColor(uint8_t color, uint16_t original, bool light/*=false*/) { switch (color) { - case White: return light ? COLOR_LIGHT_WHITE : COLOR_WHITE; - case Green: return light ? COLOR_LIGHT_GREEN : COLOR_GREEN; - case Cyan: return light ? COLOR_LIGHT_CYAN : COLOR_CYAN; - case Blue: return light ? COLOR_LIGHT_BLUE : COLOR_BLUE; - case Magenta: return light ? COLOR_LIGHT_MAGENTA : COLOR_MAGENTA; - case Red: return light ? COLOR_LIGHT_RED : COLOR_RED; - case Orange: return light ? COLOR_LIGHT_ORANGE : COLOR_ORANGE; - case Yellow: return light ? COLOR_LIGHT_YELLOW : COLOR_YELLOW; - case Brown: return light ? COLOR_LIGHT_BROWN : COLOR_BROWN; - case Black: return COLOR_BLACK; - case Default: return original; + case Default: + return original; + break; + case White: + return (light) ? Color_Light_White : Color_White; + break; + case Green: + return (light) ? Color_Light_Green : Color_Green; + break; + case Cyan: + return (light) ? Color_Light_Cyan : Color_Cyan; + break; + case Blue: + return (light) ? Color_Light_Blue : Color_Blue; + break; + case Magenta: + return (light) ? Color_Light_Magenta : Color_Magenta; + break; + case Red: + return (light) ? Color_Light_Red : Color_Red; + break; + case Orange: + return (light) ? Color_Light_Orange : Color_Orange; + break; + case Yellow: + return (light) ? Color_Light_Yellow : Color_Yellow; + break; + case Brown: + return (light) ? Color_Light_Brown : Color_Brown; + break; + case Black: + return Color_Black; + break; } - return COLOR_WHITE; + return Color_White; } -void JyersDWIN::drawTitle(const char * const ctitle) { - dwinDrawString(false, DWIN_FONT_HEAD, getColor(eeprom_settings.menu_top_txt, COLOR_WHITE, false), COLOR_BG_BLUE, (DWIN_WIDTH - strlen(ctitle) * STAT_CHR_W) / 2, 5, ctitle); +void CrealityDWINClass::Draw_Title(const char * ctitle) { + DWIN_Draw_String(false, DWIN_FONT_HEAD, GetColor(eeprom_settings.menu_top_txt, Color_White, false), Color_Bg_Blue, (DWIN_WIDTH - strlen(ctitle) * STAT_CHR_W) / 2, 5, ctitle); } -void JyersDWIN::drawTitle(FSTR_P const ftitle) { - dwinDrawString(false, DWIN_FONT_HEAD, getColor(eeprom_settings.menu_top_txt, COLOR_WHITE, false), COLOR_BG_BLUE, (DWIN_WIDTH - strlen_P(FTOP(ftitle)) * STAT_CHR_W) / 2, 5, ftitle); +void CrealityDWINClass::Draw_Title(FSTR_P const ftitle) { + DWIN_Draw_String(false, DWIN_FONT_HEAD, GetColor(eeprom_settings.menu_top_txt, Color_White, false), Color_Bg_Blue, (DWIN_WIDTH - strlen_P(FTOP(ftitle)) * STAT_CHR_W) / 2, 5, ftitle); } -void _decorateMenuItem(uint8_t row, uint8_t icon, bool more) { - if (icon) dwinIconShow(ICON, icon, 26, MBASE(row) - 3); // Draw Menu Icon - if (more) dwinIconShow(ICON, ICON_More, 226, MBASE(row) - 3); // Draw More Arrow - dwinDrawLine(jyersDWIN.getColor(jyersDWIN.eeprom_settings.menu_split_line, COLOR_LINE, true), 16, MBASE(row) + 33, 256, MBASE(row) + 33); // Draw Menu Line +void _Decorate_Menu_Item(uint8_t row, uint8_t icon, bool more) { + if (icon) DWIN_ICON_Show(ICON, icon, 26, MBASE(row) - 3); //Draw Menu Icon + if (more) DWIN_ICON_Show(ICON, ICON_More, 226, MBASE(row) - 3); // Draw More Arrow + DWIN_Draw_Line(CrealityDWIN.GetColor(CrealityDWIN.eeprom_settings.menu_split_line, Line_Color, true), 16, MBASE(row) + 33, 256, MBASE(row) + 33); // Draw Menu Line } -void JyersDWIN::drawMenuItem(const uint8_t row, const uint8_t icon/*=0*/, const char * const label1, const char * const label2, const bool more/*=false*/, const bool centered/*=false*/) { - const uint8_t label_offset_y = label2 ? MENU_CHR_H * 3 / 5 : 0, +void CrealityDWINClass::Draw_Menu_Item(uint8_t row, uint8_t icon/*=0*/, const char * label1, const char * label2, bool more/*=false*/, bool centered/*=false*/) { + const uint8_t label_offset_y = (label1 || label2) ? MENU_CHR_H * 3 / 5 : 0, label1_offset_x = !centered ? LBLX : LBLX * 4/5 + _MAX(LBLX * 1U/5, (DWIN_WIDTH - LBLX - (label1 ? strlen(label1) : 0) * MENU_CHR_W) / 2), label2_offset_x = !centered ? LBLX : LBLX * 4/5 + _MAX(LBLX * 1U/5, (DWIN_WIDTH - LBLX - (label2 ? strlen(label2) : 0) * MENU_CHR_W) / 2); - if (label1) dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLACK, label1_offset_x, MBASE(row) - 1 - label_offset_y, label1); // Draw Label - if (label2) dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLACK, label2_offset_x, MBASE(row) - 1 + label_offset_y, label2); // Draw Label - _decorateMenuItem(row, icon, more); + if (label1) DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Black, label1_offset_x, MBASE(row) - 1 - label_offset_y, label1); // Draw Label + if (label2) DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Black, label2_offset_x, MBASE(row) - 1 + label_offset_y, label2); // Draw Label + _Decorate_Menu_Item(row, icon, more); } -void JyersDWIN::drawMenuItem(const uint8_t row, const uint8_t icon/*=0*/, FSTR_P const flabel1, FSTR_P const flabel2, const bool more/*=false*/, const bool centered/*=false*/) { - const uint8_t label_offset_y = flabel2 ? MENU_CHR_H * 3 / 5 : 0, +void CrealityDWINClass::Draw_Menu_Item(uint8_t row, uint8_t icon/*=0*/, FSTR_P const flabel1, FSTR_P const flabel2, bool more/*=false*/, bool centered/*=false*/) { + const uint8_t label_offset_y = (flabel1 || flabel2) ? MENU_CHR_H * 3 / 5 : 0, label1_offset_x = !centered ? LBLX : LBLX * 4/5 + _MAX(LBLX * 1U/5, (DWIN_WIDTH - LBLX - (flabel1 ? strlen_P(FTOP(flabel1)) : 0) * MENU_CHR_W) / 2), label2_offset_x = !centered ? LBLX : LBLX * 4/5 + _MAX(LBLX * 1U/5, (DWIN_WIDTH - LBLX - (flabel2 ? strlen_P(FTOP(flabel2)) : 0) * MENU_CHR_W) / 2); - if (flabel1) dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLACK, label1_offset_x, MBASE(row) - 1 - label_offset_y, flabel1); // Draw Label - if (flabel2) dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLACK, label2_offset_x, MBASE(row) - 1 + label_offset_y, flabel2); // Draw Label - _decorateMenuItem(row, icon, more); + if (flabel1) DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Black, label1_offset_x, MBASE(row) - 1 - label_offset_y, flabel1); // Draw Label + if (flabel2) DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Black, label2_offset_x, MBASE(row) - 1 + label_offset_y, flabel2); // Draw Label + _Decorate_Menu_Item(row, icon, more); } -void JyersDWIN::drawCheckbox(const uint8_t row, const bool value) { - #if ENABLED(DWIN_CREALITY_LCD_CUSTOM_ICONS) // Draw appropriate checkbox icon - dwinIconShow(ICON, (value ? ICON_Checkbox_T : ICON_Checkbox_F), 226, MBASE(row) - 3); +void CrealityDWINClass::Draw_Checkbox(uint8_t row, bool value) { + #if ENABLED(DWIN_CREALITY_LCD_CUSTOM_ICONS) // Draw appropriate checkbox icon + DWIN_ICON_Show(ICON, (value ? ICON_Checkbox_T : ICON_Checkbox_F), 226, MBASE(row) - 3); #else // Draw a basic checkbox using rectangles and lines - dwinDrawRectangle(1, COLOR_BG_BLACK, 226, MBASE(row) - 3, 226 + 20, MBASE(row) - 3 + 20); - dwinDrawRectangle(0, COLOR_WHITE, 226, MBASE(row) - 3, 226 + 20, MBASE(row) - 3 + 20); + DWIN_Draw_Rectangle(1, Color_Bg_Black, 226, MBASE(row) - 3, 226 + 20, MBASE(row) - 3 + 20); + DWIN_Draw_Rectangle(0, Color_White, 226, MBASE(row) - 3, 226 + 20, MBASE(row) - 3 + 20); if (value) { - dwinDrawLine(COLOR_CHECKBOX, 227, MBASE(row) - 3 + 11, 226 + 8, MBASE(row) - 3 + 17); - dwinDrawLine(COLOR_CHECKBOX, 227 + 8, MBASE(row) - 3 + 17, 226 + 19, MBASE(row) - 3 + 1); - dwinDrawLine(COLOR_CHECKBOX, 227, MBASE(row) - 3 + 12, 226 + 8, MBASE(row) - 3 + 18); - dwinDrawLine(COLOR_CHECKBOX, 227 + 8, MBASE(row) - 3 + 18, 226 + 19, MBASE(row) - 3 + 2); - dwinDrawLine(COLOR_CHECKBOX, 227, MBASE(row) - 3 + 13, 226 + 8, MBASE(row) - 3 + 19); - dwinDrawLine(COLOR_CHECKBOX, 227 + 8, MBASE(row) - 3 + 19, 226 + 19, MBASE(row) - 3 + 3); + DWIN_Draw_Line(Check_Color, 227, MBASE(row) - 3 + 11, 226 + 8, MBASE(row) - 3 + 17); + DWIN_Draw_Line(Check_Color, 227 + 8, MBASE(row) - 3 + 17, 226 + 19, MBASE(row) - 3 + 1); + DWIN_Draw_Line(Check_Color, 227, MBASE(row) - 3 + 12, 226 + 8, MBASE(row) - 3 + 18); + DWIN_Draw_Line(Check_Color, 227 + 8, MBASE(row) - 3 + 18, 226 + 19, MBASE(row) - 3 + 2); + DWIN_Draw_Line(Check_Color, 227, MBASE(row) - 3 + 13, 226 + 8, MBASE(row) - 3 + 19); + DWIN_Draw_Line(Check_Color, 227 + 8, MBASE(row) - 3 + 19, 226 + 19, MBASE(row) - 3 + 3); } #endif } -void JyersDWIN::drawMenu(const uint8_t menu, const uint8_t select/*=0*/, const uint8_t scroll/*=0*/) { +void CrealityDWINClass::Draw_Menu(uint8_t menu, uint8_t select/*=0*/, uint8_t scroll/*=0*/) { if (active_menu != menu) { last_menu = active_menu; - if (process == Proc_Menu) last_selection = selection; + if (process == Menu) last_selection = selection; } - selection = _MIN(select, getMenuSize(menu)); + selection = _MIN(select, Get_Menu_Size(menu)); scrollpos = scroll; - if (selection - scrollpos > MROWS) scrollpos = selection - MROWS; // i.e., NOLESS(scrollpos, selection - MROWS); - process = Proc_Menu; + if (selection - scrollpos > MROWS) + scrollpos = selection - MROWS; + process = Menu; active_menu = menu; - clearScreen(); - drawTitle(getMenuTitle(menu)); - for (uint8_t i = 0; i < TROWS; ++i) menuItemHandler(menu, i + scrollpos); - dwinDrawRectangle(1, getColor(eeprom_settings.cursor_color, COLOR_RECTANGLE), 0, MBASE(selection - scrollpos) - 18, 14, MBASE(selection - scrollpos) + 33); + Clear_Screen(); + Draw_Title(Get_Menu_Title(menu)); + LOOP_L_N(i, TROWS) Menu_Item_Handler(menu, i + scrollpos); + DWIN_Draw_Rectangle(1, GetColor(eeprom_settings.cursor_color, Rectangle_Color), 0, MBASE(selection - scrollpos) - 18, 14, MBASE(selection - scrollpos) + 33); } -void JyersDWIN::redrawMenu(const bool lastproc/*=true*/, const bool lastsel/*=false*/, const bool lastmenu/*=false*/) { - switch (lastproc ? last_process : process) { - case Proc_Menu: - drawMenu(lastmenu ? last_menu : active_menu, lastsel ? last_selection : selection, lastmenu ? 0 : scrollpos); +void CrealityDWINClass::Redraw_Menu(bool lastprocess/*=true*/, bool lastselection/*=false*/, bool lastmenu/*=false*/) { + switch ((lastprocess) ? last_process : process) { + case Menu: + Draw_Menu((lastmenu) ? last_menu : active_menu, (lastselection) ? last_selection : selection, (lastmenu) ? 0 : scrollpos); break; - case Proc_Main: drawMainMenu(lastsel ? last_selection : selection); break; - case Proc_Print: drawPrintScreen(); break; - case Proc_File: drawSDList(); break; + case Main: Draw_Main_Menu((lastselection) ? last_selection : selection); break; + case Print: Draw_Print_Screen(); break; + case File: Draw_SD_List(); break; default: break; } } -void JyersDWIN::redrawScreen() { - redrawMenu(false); - drawStatusArea(true); - updateStatusBar(true); +void CrealityDWINClass::Redraw_Screen() { + Redraw_Menu(false); + Draw_Status_Area(true); + Update_Status_Bar(true); } -// -// Primary Menus and Screen Elements -// -void JyersDWIN::mainMenuIcons() { +/* Primary Menus and Screen Elements */ + +void CrealityDWINClass::Main_Menu_Icons() { if (selection == 0) { - dwinIconShow(ICON, ICON_Print_1, 17, 130); - dwinDrawRectangle(0, getColor(eeprom_settings.highlight_box, COLOR_WHITE), 17, 130, 126, 229); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLUE, 52, 200, GET_TEXT_F(MSG_BUTTON_PRINT)); + DWIN_ICON_Show(ICON, ICON_Print_1, 17, 130); + DWIN_Draw_Rectangle(0, GetColor(eeprom_settings.highlight_box, Color_White), 17, 130, 126, 229); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Blue, 52, 200, F("Print")); } else { - dwinIconShow(ICON, ICON_Print_0, 17, 130); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLUE, 52, 200, GET_TEXT_F(MSG_BUTTON_PRINT)); + DWIN_ICON_Show(ICON, ICON_Print_0, 17, 130); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Blue, 52, 200, F("Print")); } if (selection == 1) { - dwinIconShow(ICON, ICON_Prepare_1, 145, 130); - dwinDrawRectangle(0, getColor(eeprom_settings.highlight_box, COLOR_WHITE), 145, 130, 254, 229); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLUE, 170, 200, GET_TEXT_F(MSG_PREPARE)); + DWIN_ICON_Show(ICON, ICON_Prepare_1, 145, 130); + DWIN_Draw_Rectangle(0, GetColor(eeprom_settings.highlight_box, Color_White), 145, 130, 254, 229); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Blue, 170, 200, F("Prepare")); } else { - dwinIconShow(ICON, ICON_Prepare_0, 145, 130); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLUE, 170, 200, GET_TEXT_F(MSG_PREPARE)); + DWIN_ICON_Show(ICON, ICON_Prepare_0, 145, 130); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Blue, 170, 200, F("Prepare")); } if (selection == 2) { - dwinIconShow(ICON, ICON_Control_1, 17, 246); - dwinDrawRectangle(0, getColor(eeprom_settings.highlight_box, COLOR_WHITE), 17, 246, 126, 345); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLUE, 43, 317, GET_TEXT_F(MSG_CONTROL)); + DWIN_ICON_Show(ICON, ICON_Control_1, 17, 246); + DWIN_Draw_Rectangle(0, GetColor(eeprom_settings.highlight_box, Color_White), 17, 246, 126, 345); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Blue, 43, 317, F("Control")); } else { - dwinIconShow(ICON, ICON_Control_0, 17, 246); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLUE, 43, 317, GET_TEXT_F(MSG_CONTROL)); + DWIN_ICON_Show(ICON, ICON_Control_0, 17, 246); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Blue, 43, 317, F("Control")); } #if HAS_ABL_OR_UBL if (selection == 3) { - dwinIconShow(ICON, ICON_Leveling_1, 145, 246); - dwinDrawRectangle(0, getColor(eeprom_settings.highlight_box, COLOR_WHITE), 145, 246, 254, 345); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLUE, 179, 317, GET_TEXT_F(MSG_BUTTON_LEVEL)); + DWIN_ICON_Show(ICON, ICON_Leveling_1, 145, 246); + DWIN_Draw_Rectangle(0, GetColor(eeprom_settings.highlight_box, Color_White), 145, 246, 254, 345); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Blue, 179, 317, F("Level")); } else { - dwinIconShow(ICON, ICON_Leveling_0, 145, 246); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLUE, 179, 317, GET_TEXT_F(MSG_BUTTON_LEVEL)); + DWIN_ICON_Show(ICON, ICON_Leveling_0, 145, 246); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Blue, 179, 317, F("Level")); } #else if (selection == 3) { - dwinIconShow(ICON, ICON_Info_1, 145, 246); - dwinDrawRectangle(0, getColor(eeprom_settings.highlight_box, COLOR_WHITE), 145, 246, 254, 345); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLUE, 181, 317, GET_TEXT_F(MSG_BUTTON_INFO)); + DWIN_ICON_Show(ICON, ICON_Info_1, 145, 246); + DWIN_Draw_Rectangle(0, GetColor(eeprom_settings.highlight_box, Color_White), 145, 246, 254, 345); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Blue, 181, 317, F("Info")); } else { - dwinIconShow(ICON, ICON_Info_0, 145, 246); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLUE, 181, 317, GET_TEXT_F(MSG_BUTTON_INFO)); + DWIN_ICON_Show(ICON, ICON_Info_0, 145, 246); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Blue, 181, 317, F("Info")); } #endif } -void JyersDWIN::drawMainMenu(const uint8_t select/*=0*/) { - process = Proc_Main; - active_menu = ID_MainMenu; +void CrealityDWINClass::Draw_Main_Menu(uint8_t select/*=0*/) { + process = Main; + active_menu = MainMenu; selection = select; - clearScreen(); - drawTitle(getMenuTitle(ID_MainMenu)); + Clear_Screen(); + Draw_Title(Get_Menu_Title(MainMenu)); SERIAL_ECHOPGM("\nDWIN handshake "); - dwinIconShow(ICON, ICON_LOGO, 71, 72); - mainMenuIcons(); + DWIN_ICON_Show(ICON, ICON_LOGO, 71, 72); + Main_Menu_Icons(); } -void JyersDWIN::printScreenIcons() { +void CrealityDWINClass::Print_Screen_Icons() { if (selection == 0) { - dwinIconShow(ICON, ICON_Setup_1, 8, 252); - dwinDrawRectangle(0, getColor(eeprom_settings.highlight_box, COLOR_WHITE), 8, 252, 87, 351); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLUE, 30, 322, GET_TEXT_F(MSG_TUNE)); + DWIN_ICON_Show(ICON, ICON_Setup_1, 8, 252); + DWIN_Draw_Rectangle(0, GetColor(eeprom_settings.highlight_box, Color_White), 8, 252, 87, 351); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Blue, 30, 322, F("Tune")); } else { - dwinIconShow(ICON, ICON_Setup_0, 8, 252); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLUE, 30, 322, GET_TEXT_F(MSG_TUNE)); + DWIN_ICON_Show(ICON, ICON_Setup_0, 8, 252); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Blue, 30, 322, F("Tune")); } if (selection == 2) { - dwinIconShow(ICON, ICON_Stop_1, 184, 252); - dwinDrawRectangle(0, getColor(eeprom_settings.highlight_box, COLOR_WHITE), 184, 252, 263, 351); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLUE, 205, 322, GET_TEXT_F(MSG_BUTTON_STOP)); + DWIN_ICON_Show(ICON, ICON_Stop_1, 184, 252); + DWIN_Draw_Rectangle(0, GetColor(eeprom_settings.highlight_box, Color_White), 184, 252, 263, 351); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Blue, 205, 322, F("Stop")); } else { - dwinIconShow(ICON, ICON_Stop_0, 184, 252); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLUE, 205, 322, GET_TEXT_F(MSG_BUTTON_STOP)); + DWIN_ICON_Show(ICON, ICON_Stop_0, 184, 252); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Blue, 205, 322, F("Stop")); } if (paused) { if (selection == 1) { - dwinIconShow(ICON, ICON_Continue_1, 96, 252); - dwinDrawRectangle(0, getColor(eeprom_settings.highlight_box, COLOR_WHITE), 96, 252, 175, 351); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLUE, 114, 322, GET_TEXT_F(MSG_BUTTON_PRINT)); + DWIN_ICON_Show(ICON, ICON_Continue_1, 96, 252); + DWIN_Draw_Rectangle(0, GetColor(eeprom_settings.highlight_box, Color_White), 96, 252, 175, 351); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Blue, 114, 322, F("Print")); } else { - dwinIconShow(ICON, ICON_Continue_0, 96, 252); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLUE, 114, 322, GET_TEXT_F(MSG_BUTTON_PRINT)); + DWIN_ICON_Show(ICON, ICON_Continue_0, 96, 252); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Blue, 114, 322, F("Print")); } } else { if (selection == 1) { - dwinIconShow(ICON, ICON_Pause_1, 96, 252); - dwinDrawRectangle(0, getColor(eeprom_settings.highlight_box, COLOR_WHITE), 96, 252, 175, 351); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLUE, 114, 322, GET_TEXT_F(MSG_BUTTON_PAUSE)); + DWIN_ICON_Show(ICON, ICON_Pause_1, 96, 252); + DWIN_Draw_Rectangle(0, GetColor(eeprom_settings.highlight_box, Color_White), 96, 252, 175, 351); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Blue, 114, 322, F("Pause")); } else { - dwinIconShow(ICON, ICON_Pause_0, 96, 252); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLUE, 114, 322, GET_TEXT_F(MSG_BUTTON_PAUSE)); + DWIN_ICON_Show(ICON, ICON_Pause_0, 96, 252); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Blue, 114, 322, F("Pause")); } } } -void JyersDWIN::drawPrintScreen() { - process = Proc_Print; +void CrealityDWINClass::Draw_Print_Screen() { + process = Print; selection = 0; - clearScreen(); - dwinDrawRectangle(1, COLOR_BG_BLACK, 8, 352, DWIN_WIDTH - 8, 376); - drawTitle(GET_TEXT_F(MSG_PRINTING)); - printScreenIcons(); - dwinIconShow(ICON, ICON_PrintTime, 14, 171); - dwinIconShow(ICON, ICON_RemainTime, 147, 169); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLACK, 41, 163, F("Elapsed")); - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLACK, 176, 163, GET_TEXT_F(MSG_REMAINING_TIME)); - updateStatusBar(true); - drawPrintProgressBar(); - drawPrintProgressElapsed(); - TERN_(SET_REMAINING_TIME, drawPrintProgressRemain()); - drawPrintFilename(true); + Clear_Screen(); + DWIN_Draw_Rectangle(1, Color_Bg_Black, 8, 352, DWIN_WIDTH - 8, 376); + Draw_Title("Printing..."); + Print_Screen_Icons(); + DWIN_ICON_Show(ICON, ICON_PrintTime, 14, 171); + DWIN_ICON_Show(ICON, ICON_RemainTime, 147, 169); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Black, 41, 163, F("Elapsed")); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Black, 176, 163, F("Remaining")); + Update_Status_Bar(true); + Draw_Print_ProgressBar(); + Draw_Print_ProgressElapsed(); + TERN_(SET_REMAINING_TIME, Draw_Print_ProgressRemain()); + Draw_Print_Filename(true); } -void JyersDWIN::drawPrintFilename(const bool reset/*=false*/) { +void CrealityDWINClass::Draw_Print_Filename(const bool reset/*=false*/) { typedef TextScroller<30> Scroller; static Scroller scroller; if (reset) scroller.reset(); - if (process == Proc_Print) { + if (process == Print) { Scroller::Buffer buf; size_t outlen = 0; const char* outstr = scroller.scroll(outlen, buf, filename); - dwinDrawRectangle(1, COLOR_BG_BLACK, 8, 50, DWIN_WIDTH - 8, 80); + DWIN_Draw_Rectangle(1, Color_Bg_Black, 8, 50, DWIN_WIDTH - 8, 80); const int8_t npos = (DWIN_WIDTH - outlen * MENU_CHR_W) / 2; - dwinDrawString(false, DWIN_FONT_MENU, COLOR_WHITE, COLOR_BG_BLACK, npos, 60, outstr); + DWIN_Draw_String(false, DWIN_FONT_MENU, Color_White, Color_Bg_Black, npos, 60, outstr); } } -void JyersDWIN::drawPrintProgressBar() { +void CrealityDWINClass::Draw_Print_ProgressBar() { uint8_t printpercent = sdprint ? card.percentDone() : (ui._get_progress() / 100); - dwinIconShow(ICON, ICON_Bar, 15, 93); - dwinDrawRectangle(1, COLOR_BARFILL, 16 + printpercent * 240 / 100, 93, 256, 113); - dwinDrawIntValue(true, true, 0, DWIN_FONT_MENU, getColor(eeprom_settings.progress_percent, COLOR_PERCENT), COLOR_BG_BLACK, 3, 109, 133, printpercent); - dwinDrawString(false, DWIN_FONT_MENU, getColor(eeprom_settings.progress_percent, COLOR_PERCENT), COLOR_BG_BLACK, 133, 133, F("%")); + DWIN_ICON_Show(ICON, ICON_Bar, 15, 93); + DWIN_Draw_Rectangle(1, BarFill_Color, 16 + printpercent * 240 / 100, 93, 256, 113); + DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_MENU, GetColor(eeprom_settings.progress_percent, Percent_Color), Color_Bg_Black, 3, 109, 133, printpercent); + DWIN_Draw_String(false, DWIN_FONT_MENU, GetColor(eeprom_settings.progress_percent, Percent_Color), Color_Bg_Black, 133, 133, F("%")); } #if ENABLED(SET_REMAINING_TIME) - void JyersDWIN::drawPrintProgressRemain() { + void CrealityDWINClass::Draw_Print_ProgressRemain() { uint16_t remainingtime = ui.get_remaining_time(); - dwinDrawIntValue(true, true, 1, DWIN_FONT_MENU, getColor(eeprom_settings.progress_time, COLOR_WHITE), COLOR_BG_BLACK, 2, 176, 187, remainingtime / 3600); - dwinDrawIntValue(true, true, 1, DWIN_FONT_MENU, getColor(eeprom_settings.progress_time, COLOR_WHITE), COLOR_BG_BLACK, 2, 200, 187, (remainingtime % 3600) / 60); + DWIN_Draw_IntValue(true, true, 1, DWIN_FONT_MENU, GetColor(eeprom_settings.progress_time, Color_White), Color_Bg_Black, 2, 176, 187, remainingtime / 3600); + DWIN_Draw_IntValue(true, true, 1, DWIN_FONT_MENU, GetColor(eeprom_settings.progress_time, Color_White), Color_Bg_Black, 2, 200, 187, (remainingtime % 3600) / 60); if (eeprom_settings.time_format_textual) { - dwinDrawString(false, DWIN_FONT_MENU, getColor(eeprom_settings.progress_time, COLOR_WHITE), COLOR_BG_BLACK, 192, 187, F("h")); - dwinDrawString(false, DWIN_FONT_MENU, getColor(eeprom_settings.progress_time, COLOR_WHITE), COLOR_BG_BLACK, 216, 187, F("m")); + DWIN_Draw_String(false, DWIN_FONT_MENU, GetColor(eeprom_settings.progress_time, Color_White), Color_Bg_Black, 192, 187, F("h")); + DWIN_Draw_String(false, DWIN_FONT_MENU, GetColor(eeprom_settings.progress_time, Color_White), Color_Bg_Black, 216, 187, F("m")); } else - dwinDrawString(false, DWIN_FONT_MENU, getColor(eeprom_settings.progress_time, COLOR_WHITE), COLOR_BG_BLACK, 192, 187, F(":")); + DWIN_Draw_String(false, DWIN_FONT_MENU, GetColor(eeprom_settings.progress_time, Color_White), Color_Bg_Black, 192, 187, F(":")); } #endif -void JyersDWIN::drawPrintProgressElapsed() { +void CrealityDWINClass::Draw_Print_ProgressElapsed() { duration_t elapsed = print_job_timer.duration(); - dwinDrawIntValue(true, true, 1, DWIN_FONT_MENU, getColor(eeprom_settings.progress_time, COLOR_WHITE), COLOR_BG_BLACK, 2, 42, 187, elapsed.value / 3600); - dwinDrawIntValue(true, true, 1, DWIN_FONT_MENU, getColor(eeprom_settings.progress_time, COLOR_WHITE), COLOR_BG_BLACK, 2, 66, 187, (elapsed.value % 3600) / 60); + DWIN_Draw_IntValue(true, true, 1, DWIN_FONT_MENU, GetColor(eeprom_settings.progress_time, Color_White), Color_Bg_Black, 2, 42, 187, elapsed.value / 3600); + DWIN_Draw_IntValue(true, true, 1, DWIN_FONT_MENU, GetColor(eeprom_settings.progress_time, Color_White), Color_Bg_Black, 2, 66, 187, (elapsed.value % 3600) / 60); if (eeprom_settings.time_format_textual) { - dwinDrawString(false, DWIN_FONT_MENU, getColor(eeprom_settings.progress_time, COLOR_WHITE), COLOR_BG_BLACK, 58, 187, F("h")); - dwinDrawString(false, DWIN_FONT_MENU, getColor(eeprom_settings.progress_time, COLOR_WHITE), COLOR_BG_BLACK, 82, 187, F("m")); + DWIN_Draw_String(false, DWIN_FONT_MENU, GetColor(eeprom_settings.progress_time, Color_White), Color_Bg_Black, 58, 187, F("h")); + DWIN_Draw_String(false, DWIN_FONT_MENU, GetColor(eeprom_settings.progress_time, Color_White), Color_Bg_Black, 82, 187, F("m")); } else - dwinDrawString(false, DWIN_FONT_MENU, getColor(eeprom_settings.progress_time, COLOR_WHITE), COLOR_BG_BLACK, 58, 187, F(":")); + DWIN_Draw_String(false, DWIN_FONT_MENU, GetColor(eeprom_settings.progress_time, Color_White), Color_Bg_Black, 58, 187, F(":")); } -void JyersDWIN::drawPrintConfirm() { - drawPrintScreen(); - process = Proc_Confirm; - popup = Popup_Complete; - dwinDrawRectangle(1, COLOR_BG_BLACK, 8, 252, 263, 351); - dwinIconShow(ICON, ICON_Confirm_E, 87, 283); - dwinDrawRectangle(0, getColor(eeprom_settings.highlight_box, COLOR_WHITE), 86, 282, 187, 321); - dwinDrawRectangle(0, getColor(eeprom_settings.highlight_box, COLOR_WHITE), 85, 281, 188, 322); +void CrealityDWINClass::Draw_Print_confirm() { + Draw_Print_Screen(); + process = Confirm; + popup = Complete; + DWIN_Draw_Rectangle(1, Color_Bg_Black, 8, 252, 263, 351); + DWIN_ICON_Show(ICON, ICON_Confirm_E, 87, 283); + DWIN_Draw_Rectangle(0, GetColor(eeprom_settings.highlight_box, Color_White), 86, 282, 187, 321); + DWIN_Draw_Rectangle(0, GetColor(eeprom_settings.highlight_box, Color_White), 85, 281, 188, 322); } -void JyersDWIN::drawSDItem(const uint8_t item, const uint8_t row) { +void CrealityDWINClass::Draw_SD_Item(uint8_t item, uint8_t row) { if (item == 0) - drawMenuItem(0, ICON_Back, card.flag.workDirIsRoot ? GET_TEXT_F(MSG_BACK) : F("..")); + Draw_Menu_Item(0, ICON_Back, card.flag.workDirIsRoot ? F("Back") : F("..")); else { - card.selectFileByIndexSorted(item - 1); + card.getfilename_sorted(SD_ORDER(item - 1, card.get_num_Files())); char * const filename = card.longest_filename(); size_t max = MENU_CHAR_LIMIT; size_t pos = strlen(filename), len = pos; @@ -772,35 +810,35 @@ void JyersDWIN::drawSDItem(const uint8_t item, const uint8_t row) { len = pos; if (len > max) len = max; char name[len + 1]; - for (uint8_t i = 0; i < len; ++i) name[i] = filename[i]; + LOOP_L_N(i, len) name[i] = filename[i]; if (pos > max) - for (uint8_t i = len - 3; i < len; ++i) name[i] = '.'; + LOOP_S_L_N(i, len - 3, len) name[i] = '.'; name[len] = '\0'; - drawMenuItem(row, card.flag.filenameIsDir ? ICON_More : ICON_File, name); + Draw_Menu_Item(row, card.flag.filenameIsDir ? ICON_More : ICON_File, name); } } -void JyersDWIN::drawSDList(const bool removed/*=false*/) { - clearScreen(); - drawTitle(GET_TEXT_F(MSG_MEDIA_MENU)); +void CrealityDWINClass::Draw_SD_List(bool removed/*=false*/) { + Clear_Screen(); + Draw_Title("Select File"); selection = 0; scrollpos = 0; - process = Proc_File; + process = File; if (card.isMounted() && !removed) { - for (uint8_t i = 0; i < _MIN(card.get_num_items() + 1, TROWS); ++i) - drawSDItem(i, i); + LOOP_L_N(i, _MIN(card.get_num_Files() + 1, TROWS)) + Draw_SD_Item(i, i); } else { - drawMenuItem(0, ICON_Back, GET_TEXT_F(MSG_BACK)); - dwinDrawRectangle(1, COLOR_BG_RED, 10, MBASE(3) - 10, DWIN_WIDTH - 10, MBASE(4)); - dwinDrawString(false, font16x32, COLOR_YELLOW, COLOR_BG_RED, ((DWIN_WIDTH) - 8 * 16) / 2, MBASE(3), GET_TEXT_F(MSG_NO_MEDIA)); + Draw_Menu_Item(0, ICON_Back, F("Back")); + DWIN_Draw_Rectangle(1, Color_Bg_Red, 10, MBASE(3) - 10, DWIN_WIDTH - 10, MBASE(4)); + DWIN_Draw_String(false, font16x32, Color_Yellow, Color_Bg_Red, ((DWIN_WIDTH) - 8 * 16) / 2, MBASE(3), F("No Media")); } - dwinDrawRectangle(1, getColor(eeprom_settings.cursor_color, COLOR_RECTANGLE), 0, MBASE(0) - 18, 14, MBASE(0) + 33); + DWIN_Draw_Rectangle(1, GetColor(eeprom_settings.cursor_color, Rectangle_Color), 0, MBASE(0) - 18, 14, MBASE(0) + 33); } -void JyersDWIN::drawStatusArea(const bool icons/*=false*/) { +void CrealityDWINClass::Draw_Status_Area(bool icons/*=false*/) { - if (icons) dwinDrawRectangle(1, COLOR_BG_BLACK, 0, STATUS_Y, DWIN_WIDTH, DWIN_HEIGHT - 1); + if (icons) DWIN_Draw_Rectangle(1, Color_Bg_Black, 0, STATUS_Y, DWIN_WIDTH, DWIN_HEIGHT - 1); #if HAS_HOTEND static float hotend = -1; @@ -808,27 +846,27 @@ void JyersDWIN::drawStatusArea(const bool icons/*=false*/) { if (icons) { hotend = -1; hotendtarget = -1; - dwinIconShow(ICON, ICON_HotendTemp, 10, 383); - dwinDrawString(false, DWIN_FONT_STAT, getColor(eeprom_settings.status_area_text, COLOR_WHITE), COLOR_BG_BLACK, 25 + 3 * STAT_CHR_W + 5, 384, F("/")); + DWIN_ICON_Show(ICON, ICON_HotendTemp, 10, 383); + DWIN_Draw_String(false, DWIN_FONT_STAT, GetColor(eeprom_settings.status_area_text, Color_White), Color_Bg_Black, 25 + 3 * STAT_CHR_W + 5, 384, F("/")); } - if (thermalManager.degHotend(0) != hotend) { - hotend = thermalManager.degHotend(0); - dwinDrawIntValue(true, true, 0, DWIN_FONT_STAT, getColor(eeprom_settings.status_area_text, COLOR_WHITE), COLOR_BG_BLACK, 3, 28, 384, hotend); - dwinDrawDegreeSymbol(getColor(eeprom_settings.status_area_text, COLOR_WHITE), 25 + 3 * STAT_CHR_W + 5, 386); + if (thermalManager.temp_hotend[0].celsius != hotend) { + hotend = thermalManager.temp_hotend[0].celsius; + DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, GetColor(eeprom_settings.status_area_text, Color_White), Color_Bg_Black, 3, 28, 384, thermalManager.temp_hotend[0].celsius); + DWIN_Draw_DegreeSymbol(GetColor(eeprom_settings.status_area_text, Color_White), 25 + 3 * STAT_CHR_W + 5, 386); } - if (thermalManager.wholeDegHotend(0) != hotendtarget) { - hotendtarget = thermalManager.degTargetHotend(0); - dwinDrawIntValue(true, true, 0, DWIN_FONT_STAT, getColor(eeprom_settings.status_area_text, COLOR_WHITE), COLOR_BG_BLACK, 3, 25 + 4 * STAT_CHR_W + 6, 384, hotendtarget); - dwinDrawDegreeSymbol(getColor(eeprom_settings.status_area_text, COLOR_WHITE), 25 + 4 * STAT_CHR_W + 39, 386); + if (thermalManager.temp_hotend[0].target != hotendtarget) { + hotendtarget = thermalManager.temp_hotend[0].target; + DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, GetColor(eeprom_settings.status_area_text, Color_White), Color_Bg_Black, 3, 25 + 4 * STAT_CHR_W + 6, 384, thermalManager.temp_hotend[0].target); + DWIN_Draw_DegreeSymbol(GetColor(eeprom_settings.status_area_text, Color_White), 25 + 4 * STAT_CHR_W + 39, 386); } if (icons) { flow = -1; - dwinIconShow(ICON, ICON_StepE, 112, 417); - dwinDrawString(false, DWIN_FONT_STAT, getColor(eeprom_settings.status_area_text, COLOR_WHITE), COLOR_BG_BLACK, 116 + 5 * STAT_CHR_W + 2, 417, F("%")); + DWIN_ICON_Show(ICON, ICON_StepE, 112, 417); + DWIN_Draw_String(false, DWIN_FONT_STAT, GetColor(eeprom_settings.status_area_text, Color_White), Color_Bg_Black, 116 + 5 * STAT_CHR_W + 2, 417, F("%")); } if (planner.flow_percentage[0] != flow) { flow = planner.flow_percentage[0]; - dwinDrawIntValue(true, true, 0, DWIN_FONT_STAT, getColor(eeprom_settings.status_area_text, COLOR_WHITE), COLOR_BG_BLACK, 3, 116 + 2 * STAT_CHR_W, 417, planner.flow_percentage[0]); + DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, GetColor(eeprom_settings.status_area_text, Color_White), Color_Bg_Black, 3, 116 + 2 * STAT_CHR_W, 417, planner.flow_percentage[0]); } #endif @@ -838,18 +876,18 @@ void JyersDWIN::drawStatusArea(const bool icons/*=false*/) { if (icons) { bed = -1; bedtarget = -1; - dwinIconShow(ICON, ICON_BedTemp, 10, 416); - dwinDrawString(false, DWIN_FONT_STAT, getColor(eeprom_settings.status_area_text, COLOR_WHITE), COLOR_BG_BLACK, 25 + 3 * STAT_CHR_W + 5, 417, F("/")); + DWIN_ICON_Show(ICON, ICON_BedTemp, 10, 416); + DWIN_Draw_String(false, DWIN_FONT_STAT, GetColor(eeprom_settings.status_area_text, Color_White), Color_Bg_Black, 25 + 3 * STAT_CHR_W + 5, 417, F("/")); } - if (thermalManager.degBed() != bed) { - bed = thermalManager.degBed(); - dwinDrawIntValue(true, true, 0, DWIN_FONT_STAT, getColor(eeprom_settings.status_area_text, COLOR_WHITE), COLOR_BG_BLACK, 3, 28, 417, bed); - dwinDrawDegreeSymbol(getColor(eeprom_settings.status_area_text, COLOR_WHITE), 25 + 3 * STAT_CHR_W + 5, 419); + if (thermalManager.temp_bed.celsius != bed) { + bed = thermalManager.temp_bed.celsius; + DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, GetColor(eeprom_settings.status_area_text, Color_White), Color_Bg_Black, 3, 28, 417, thermalManager.temp_bed.celsius); + DWIN_Draw_DegreeSymbol(GetColor(eeprom_settings.status_area_text, Color_White), 25 + 3 * STAT_CHR_W + 5, 419); } - if (thermalManager.degTargetBed() != bedtarget) { - bedtarget = thermalManager.degTargetBed(); - dwinDrawIntValue(true, true, 0, DWIN_FONT_STAT, getColor(eeprom_settings.status_area_text, COLOR_WHITE), COLOR_BG_BLACK, 3, 25 + 4 * STAT_CHR_W + 6, 417, bedtarget); - dwinDrawDegreeSymbol(getColor(eeprom_settings.status_area_text, COLOR_WHITE), 25 + 4 * STAT_CHR_W + 39, 419); + if (thermalManager.temp_bed.target != bedtarget) { + bedtarget = thermalManager.temp_bed.target; + DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, GetColor(eeprom_settings.status_area_text, Color_White), Color_Bg_Black, 3, 25 + 4 * STAT_CHR_W + 6, 417, thermalManager.temp_bed.target); + DWIN_Draw_DegreeSymbol(GetColor(eeprom_settings.status_area_text, Color_White), 25 + 4 * STAT_CHR_W + 39, 419); } #endif @@ -857,11 +895,11 @@ void JyersDWIN::drawStatusArea(const bool icons/*=false*/) { static uint8_t fan = -1; if (icons) { fan = -1; - dwinIconShow(ICON, ICON_FanSpeed, 187, 383); + DWIN_ICON_Show(ICON, ICON_FanSpeed, 187, 383); } if (thermalManager.fan_speed[0] != fan) { fan = thermalManager.fan_speed[0]; - dwinDrawIntValue(true, true, 0, DWIN_FONT_STAT, getColor(eeprom_settings.status_area_text, COLOR_WHITE), COLOR_BG_BLACK, 3, 195 + 2 * STAT_CHR_W, 384, thermalManager.fan_speed[0]); + DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, GetColor(eeprom_settings.status_area_text, Color_White), Color_Bg_Black, 3, 195 + 2 * STAT_CHR_W, 384, thermalManager.fan_speed[0]); } #endif @@ -870,24 +908,24 @@ void JyersDWIN::drawStatusArea(const bool icons/*=false*/) { if (icons) { offset = -1; - dwinIconShow(ICON, ICON_Zoffset, 187, 416); + DWIN_ICON_Show(ICON, ICON_Zoffset, 187, 416); } if (zoffsetvalue != offset) { offset = zoffsetvalue; - dwinDrawFloatValue(true, true, 0, DWIN_FONT_STAT, getColor(eeprom_settings.status_area_text, COLOR_WHITE), COLOR_BG_BLACK, 2, 2, 207, 417, (zoffsetvalue < 0 ? -zoffsetvalue : zoffsetvalue)); - dwinDrawString(true, DWIN_FONT_MENU, getColor(eeprom_settings.status_area_text, COLOR_WHITE), COLOR_BG_BLACK, 205, 419, zoffsetvalue < 0 ? F("-") : F(" ")); + DWIN_Draw_FloatValue(true, true, 0, DWIN_FONT_STAT, GetColor(eeprom_settings.status_area_text, Color_White), Color_Bg_Black, 2, 2, 207, 417, (zoffsetvalue < 0 ? -zoffsetvalue : zoffsetvalue)); + DWIN_Draw_String(true, DWIN_FONT_MENU, GetColor(eeprom_settings.status_area_text, Color_White), Color_Bg_Black, 205, 419, zoffsetvalue < 0 ? F("-") : F(" ")); } #endif static int16_t feedrate = -1; if (icons) { feedrate = -1; - dwinIconShow(ICON, ICON_Speed, 113, 383); - dwinDrawString(false, DWIN_FONT_STAT, getColor(eeprom_settings.status_area_text, COLOR_WHITE), COLOR_BG_BLACK, 116 + 5 * STAT_CHR_W + 2, 384, F("%")); + DWIN_ICON_Show(ICON, ICON_Speed, 113, 383); + DWIN_Draw_String(false, DWIN_FONT_STAT, GetColor(eeprom_settings.status_area_text, Color_White), Color_Bg_Black, 116 + 5 * STAT_CHR_W + 2, 384, F("%")); } if (feedrate_percentage != feedrate) { feedrate = feedrate_percentage; - dwinDrawIntValue(true, true, 0, DWIN_FONT_STAT, getColor(eeprom_settings.status_area_text, COLOR_WHITE), COLOR_BG_BLACK, 3, 116 + 2 * STAT_CHR_W, 384, feedrate_percentage); + DWIN_Draw_IntValue(true, true, 0, DWIN_FONT_STAT, GetColor(eeprom_settings.status_area_text, Color_White), Color_Bg_Black, 3, 116 + 2 * STAT_CHR_W, 384, feedrate_percentage); } static float x = -1, y = -1, z = -1; @@ -897,75 +935,75 @@ void JyersDWIN::drawStatusArea(const bool icons/*=false*/) { update_z = (current_position.z != z || axis_should_home(Z_AXIS) || update_z); if (icons) { x = y = z = -1; - dwinDrawLine(getColor(eeprom_settings.coordinates_split_line, COLOR_LINE, true), 16, 450, 256, 450); - dwinIconShow(ICON, ICON_MaxSpeedX, 10, 456); - dwinIconShow(ICON, ICON_MaxSpeedY, 95, 456); - dwinIconShow(ICON, ICON_MaxSpeedZ, 180, 456); + DWIN_Draw_Line(GetColor(eeprom_settings.coordinates_split_line, Line_Color, true), 16, 450, 256, 450); + DWIN_ICON_Show(ICON, ICON_MaxSpeedX, 10, 456); + DWIN_ICON_Show(ICON, ICON_MaxSpeedY, 95, 456); + DWIN_ICON_Show(ICON, ICON_MaxSpeedZ, 180, 456); } if (update_x) { x = current_position.x; if ((update_x = axis_should_home(X_AXIS) && ui.get_blink())) - dwinDrawString(true, DWIN_FONT_MENU, getColor(eeprom_settings.coordinates_text, COLOR_WHITE), COLOR_BG_BLACK, 35, 459, F(" -?- ")); + DWIN_Draw_String(true, DWIN_FONT_MENU, GetColor(eeprom_settings.coordinates_text, Color_White), Color_Bg_Black, 35, 459, F(" -?- ")); else - dwinDrawFloatValue(true, true, 0, DWIN_FONT_MENU, getColor(eeprom_settings.coordinates_text, COLOR_WHITE), COLOR_BG_BLACK, 3, 1, 35, 459, current_position.x); + DWIN_Draw_FloatValue(true, true, 0, DWIN_FONT_MENU, GetColor(eeprom_settings.coordinates_text, Color_White), Color_Bg_Black, 3, 1, 35, 459, current_position.x); } if (update_y) { y = current_position.y; if ((update_y = axis_should_home(Y_AXIS) && ui.get_blink())) - dwinDrawString(true, DWIN_FONT_MENU, getColor(eeprom_settings.coordinates_text, COLOR_WHITE), COLOR_BG_BLACK, 120, 459, F(" -?- ")); + DWIN_Draw_String(true, DWIN_FONT_MENU, GetColor(eeprom_settings.coordinates_text, Color_White), Color_Bg_Black, 120, 459, F(" -?- ")); else - dwinDrawFloatValue(true, true, 0, DWIN_FONT_MENU, getColor(eeprom_settings.coordinates_text, COLOR_WHITE), COLOR_BG_BLACK, 3, 1, 120, 459, current_position.y); + DWIN_Draw_FloatValue(true, true, 0, DWIN_FONT_MENU, GetColor(eeprom_settings.coordinates_text, Color_White), Color_Bg_Black, 3, 1, 120, 459, current_position.y); } if (update_z) { z = current_position.z; if ((update_z = axis_should_home(Z_AXIS) && ui.get_blink())) - dwinDrawString(true, DWIN_FONT_MENU, getColor(eeprom_settings.coordinates_text, COLOR_WHITE), COLOR_BG_BLACK, 205, 459, F(" -?- ")); + DWIN_Draw_String(true, DWIN_FONT_MENU, GetColor(eeprom_settings.coordinates_text, Color_White), Color_Bg_Black, 205, 459, F(" -?- ")); else - dwinDrawFloatValue(true, true, 0, DWIN_FONT_MENU, getColor(eeprom_settings.coordinates_text, COLOR_WHITE), COLOR_BG_BLACK, 3, 2, 205, 459, current_position.z >= 0 ? current_position.z : 0); + DWIN_Draw_FloatValue(true, true, 0, DWIN_FONT_MENU, GetColor(eeprom_settings.coordinates_text, Color_White), Color_Bg_Black, 3, 2, 205, 459, (current_position.z>=0) ? current_position.z : 0); } - dwinUpdateLCD(); + DWIN_UpdateLCD(); } -void JyersDWIN::drawPopup(FSTR_P const line1, FSTR_P const line2, FSTR_P const line3, uint8_t mode, uint8_t icon/*=0*/) { - if (process != Proc_Confirm && process != Proc_Popup && process != Proc_Wait) last_process = process; - if ((process == Proc_Menu || process == Proc_Wait) && mode == Proc_Popup) last_selection = selection; +void CrealityDWINClass::Draw_Popup(FSTR_P const line1, FSTR_P const line2, FSTR_P const line3, uint8_t mode, uint8_t icon/*=0*/) { + if (process != Confirm && process != Popup && process != Wait) last_process = process; + if ((process == Menu || process == Wait) && mode == Popup) last_selection = selection; process = mode; - clearScreen(); - dwinDrawRectangle(0, COLOR_WHITE, 13, 59, 259, 351); - dwinDrawRectangle(1, COLOR_BG_WINDOW, 14, 60, 258, 350); - const uint8_t ypos = (mode == Proc_Popup || mode == Proc_Confirm) ? 150 : 230; - if (icon > 0) dwinIconShow(ICON, icon, 101, 105); - dwinDrawString(true, DWIN_FONT_MENU, COLOR_POPUP_TEXT, COLOR_BG_WINDOW, (272 - 8 * strlen_P(FTOP(line1))) / 2, ypos, line1); - dwinDrawString(true, DWIN_FONT_MENU, COLOR_POPUP_TEXT, COLOR_BG_WINDOW, (272 - 8 * strlen_P(FTOP(line2))) / 2, ypos + 30, line2); - dwinDrawString(true, DWIN_FONT_MENU, COLOR_POPUP_TEXT, COLOR_BG_WINDOW, (272 - 8 * strlen_P(FTOP(line3))) / 2, ypos + 60, line3); - if (mode == Proc_Popup) { + Clear_Screen(); + DWIN_Draw_Rectangle(0, Color_White, 13, 59, 259, 351); + DWIN_Draw_Rectangle(1, Color_Bg_Window, 14, 60, 258, 350); + const uint8_t ypos = (mode == Popup || mode == Confirm) ? 150 : 230; + if (icon > 0) DWIN_ICON_Show(ICON, icon, 101, 105); + DWIN_Draw_String(true, DWIN_FONT_MENU, Popup_Text_Color, Color_Bg_Window, (272 - 8 * strlen_P(FTOP(line1))) / 2, ypos, line1); + DWIN_Draw_String(true, DWIN_FONT_MENU, Popup_Text_Color, Color_Bg_Window, (272 - 8 * strlen_P(FTOP(line2))) / 2, ypos + 30, line2); + DWIN_Draw_String(true, DWIN_FONT_MENU, Popup_Text_Color, Color_Bg_Window, (272 - 8 * strlen_P(FTOP(line3))) / 2, ypos + 60, line3); + if (mode == Popup) { selection = 0; - dwinDrawRectangle(1, COLOR_CONFIRM, 26, 280, 125, 317); - dwinDrawRectangle(1, COLOR_CANCEL, 146, 280, 245, 317); - dwinDrawString(false, DWIN_FONT_STAT, COLOR_WHITE, COLOR_BG_WINDOW, 39, 290, GET_TEXT_F(MSG_BUTTON_CONFIRM)); - dwinDrawString(false, DWIN_FONT_STAT, COLOR_WHITE, COLOR_BG_WINDOW, 165, 290, GET_TEXT_F(MSG_BUTTON_CANCEL)); - popupSelect(); + DWIN_Draw_Rectangle(1, Confirm_Color, 26, 280, 125, 317); + DWIN_Draw_Rectangle(1, Cancel_Color, 146, 280, 245, 317); + DWIN_Draw_String(false, DWIN_FONT_STAT, Color_White, Color_Bg_Window, 39, 290, F("Confirm")); + DWIN_Draw_String(false, DWIN_FONT_STAT, Color_White, Color_Bg_Window, 165, 290, F("Cancel")); + Popup_Select(); } - else if (mode == Proc_Confirm) { - dwinDrawRectangle(1, COLOR_CONFIRM, 87, 280, 186, 317); - dwinDrawString(false, DWIN_FONT_STAT, COLOR_WHITE, COLOR_BG_WINDOW, 96, 290, GET_TEXT_F(MSG_BUTTON_CONTINUE)); + else if (mode == Confirm) { + DWIN_Draw_Rectangle(1, Confirm_Color, 87, 280, 186, 317); + DWIN_Draw_String(false, DWIN_FONT_STAT, Color_White, Color_Bg_Window, 96, 290, F("Continue")); } } void MarlinUI::kill_screen(FSTR_P const error, FSTR_P const) { - jyersDWIN.drawPopup(F("Printer Kill Reason:"), error, F("Restart Required"), Proc_Wait, ICON_BLTouch); + CrealityDWIN.Draw_Popup(F("Printer Kill Reason:"), error, F("Restart Required"), Wait, ICON_BLTouch); } -void JyersDWIN::popupSelect() { - const uint16_t c1 = selection ? COLOR_BG_WINDOW : getColor(eeprom_settings.highlight_box, COLOR_WHITE), - c2 = selection ? getColor(eeprom_settings.highlight_box, COLOR_WHITE) : COLOR_BG_WINDOW; - dwinDrawRectangle(0, c1, 25, 279, 126, 318); - dwinDrawRectangle(0, c1, 24, 278, 127, 319); - dwinDrawRectangle(0, c2, 145, 279, 246, 318); - dwinDrawRectangle(0, c2, 144, 278, 247, 319); +void CrealityDWINClass::Popup_Select() { + const uint16_t c1 = (selection == 0) ? GetColor(eeprom_settings.highlight_box, Color_White) : Color_Bg_Window, + c2 = (selection == 0) ? Color_Bg_Window : GetColor(eeprom_settings.highlight_box, Color_White); + DWIN_Draw_Rectangle(0, c1, 25, 279, 126, 318); + DWIN_Draw_Rectangle(0, c1, 24, 278, 127, 319); + DWIN_Draw_Rectangle(0, c2, 145, 279, 246, 318); + DWIN_Draw_Rectangle(0, c2, 144, 278, 247, 319); } -void JyersDWIN::updateStatusBar(const bool refresh/*=false*/) { +void CrealityDWINClass::Update_Status_Bar(bool refresh/*=false*/) { typedef TextScroller<30> Scroller; static bool new_msg; static Scroller scroller; @@ -980,24 +1018,22 @@ void JyersDWIN::updateStatusBar(const bool refresh/*=false*/) { const char* dispmsg = scroller.scroll(len, buf, statusmsg, &new_msg); if (new_msg) { new_msg = false; - if (process == Proc_Print) { - dwinDrawRectangle(1, COLOR_GREY, 8, 214, DWIN_WIDTH - 8, 238); + if (process == Print) { + DWIN_Draw_Rectangle(1, Color_Grey, 8, 214, DWIN_WIDTH - 8, 238); const int8_t npos = (DWIN_WIDTH - len * MENU_CHR_W) / 2; - dwinDrawString(false, DWIN_FONT_MENU, getColor(eeprom_settings.status_bar_text, COLOR_WHITE), COLOR_BG_BLACK, npos, 219, dispmsg); + DWIN_Draw_String(false, DWIN_FONT_MENU, GetColor(eeprom_settings.status_bar_text, Color_White), Color_Bg_Black, npos, 219, dispmsg); } else { - dwinDrawRectangle(1, COLOR_BG_BLACK, 8, 352, DWIN_WIDTH - 8, 376); + DWIN_Draw_Rectangle(1, Color_Bg_Black, 8, 352, DWIN_WIDTH - 8, 376); const int8_t npos = (DWIN_WIDTH - len * MENU_CHR_W) / 2; - dwinDrawString(false, DWIN_FONT_MENU, getColor(eeprom_settings.status_bar_text, COLOR_WHITE), COLOR_BG_BLACK, npos, 357, dispmsg); + DWIN_Draw_String(false, DWIN_FONT_MENU, GetColor(eeprom_settings.status_bar_text, Color_White), Color_Bg_Black, npos, 357, dispmsg); } } } -// -// Menu Item Config -// +/* Menu Item Config */ -void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool draw/*=true*/) { +void CrealityDWINClass::Menu_Item_Handler(uint8_t menu, uint8_t item, bool draw/*=true*/) { const uint8_t row = item - scrollpos; #if HAS_LEVELING static bool level_state; @@ -1015,38 +1051,38 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case PREHEAT_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_TempMenu, sel); + Draw_Menu(TempMenu, sel); break; #if HAS_HOTEND case PREHEAT_SUBMENU_HOTEND: if (draw) { - drawMenuItem(row, ICON_SetEndTemp, GET_TEXT_F(MSG_NOZZLE)); - drawFloat(ui.material_preset[index].hotend_temp, row, false, 1); + Draw_Menu_Item(row, ICON_SetEndTemp, F("Hotend")); + Draw_Float(ui.material_preset[index].hotend_temp, row, false, 1); } else - modifyValue(ui.material_preset[index].hotend_temp, MIN_E_TEMP, MAX_E_TEMP, 1); + Modify_Value(ui.material_preset[index].hotend_temp, MIN_E_TEMP, MAX_E_TEMP, 1); break; #endif #if HAS_HEATED_BED case PREHEAT_SUBMENU_BED: if (draw) { - drawMenuItem(row, ICON_SetBedTemp, GET_TEXT_F(MSG_BED)); - drawFloat(ui.material_preset[index].bed_temp, row, false, 1); + Draw_Menu_Item(row, ICON_SetBedTemp, F("Bed")); + Draw_Float(ui.material_preset[index].bed_temp, row, false, 1); } else - modifyValue(ui.material_preset[index].bed_temp, MIN_BED_TEMP, MAX_BED_TEMP, 1); + Modify_Value(ui.material_preset[index].bed_temp, MIN_BED_TEMP, MAX_BED_TEMP, 1); break; #endif #if HAS_FAN case PREHEAT_SUBMENU_FAN: if (draw) { - drawMenuItem(row, ICON_FanSpeed, GET_TEXT_F(MSG_FAN_SPEED)); - drawFloat(ui.material_preset[index].fan_speed, row, false, 1); + Draw_Menu_Item(row, ICON_FanSpeed, F("Fan")); + Draw_Float(ui.material_preset[index].fan_speed, row, false, 1); } else - modifyValue(ui.material_preset[index].fan_speed, MIN_FAN_SPEED, MAX_FAN_SPEED, 1); + Modify_Value(ui.material_preset[index].fan_speed, MIN_FAN_SPEED, MAX_FAN_SPEED, 1); break; #endif } @@ -1055,7 +1091,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra #endif switch (menu) { - case ID_Prepare: + case Prepare: #define PREPARE_BACK 0 #define PREPARE_MOVE (PREPARE_BACK + 1) @@ -1064,63 +1100,62 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra #define PREPARE_MANUALLEVEL (PREPARE_HOME + 1) #define PREPARE_ZOFFSET (PREPARE_MANUALLEVEL + ENABLED(HAS_ZOFFSET_ITEM)) #define PREPARE_PREHEAT (PREPARE_ZOFFSET + ENABLED(HAS_PREHEAT)) - #define PREPARE_COOLDOWN (PREPARE_PREHEAT + ANY(HAS_HOTEND, HAS_HEATED_BED)) + #define PREPARE_COOLDOWN (PREPARE_PREHEAT + EITHER(HAS_HOTEND, HAS_HEATED_BED)) #define PREPARE_CHANGEFIL (PREPARE_COOLDOWN + ENABLED(ADVANCED_PAUSE_FEATURE)) #define PREPARE_CUSTOM_MENU (PREPARE_CHANGEFIL + ENABLED(HAS_CUSTOM_MENU)) - #define PREPARE_FWRETRACT (PREPARE_CUSTOM_MENU + ENABLED(FWRETRACT)) - #define PREPARE_TOTAL PREPARE_FWRETRACT + #define PREPARE_TOTAL PREPARE_CUSTOM_MENU switch (item) { case PREPARE_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMainMenu(1); + Draw_Main_Menu(1); break; case PREPARE_MOVE: if (draw) - drawMenuItem(row, ICON_Axis, GET_TEXT_F(MSG_MOVE_AXIS), nullptr, true); + Draw_Menu_Item(row, ICON_Axis, F("Move"), nullptr, true); else - drawMenu(ID_Move); + Draw_Menu(Move); break; case PREPARE_DISABLE: if (draw) - drawMenuItem(row, ICON_CloseMotor, GET_TEXT_F(MSG_DISABLE_STEPPERS)); + Draw_Menu_Item(row, ICON_CloseMotor, F("Disable Stepper")); else queue.inject(F("M84")); break; case PREPARE_HOME: if (draw) - drawMenuItem(row, ICON_SetHome, GET_TEXT_F(MSG_HOMING), nullptr, true); + Draw_Menu_Item(row, ICON_SetHome, F("Homing"), nullptr, true); else - drawMenu(ID_HomeMenu); + Draw_Menu(HomeMenu); break; case PREPARE_MANUALLEVEL: if (draw) - drawMenuItem(row, ICON_PrintSize, F("Manual Leveling"), nullptr, true); + Draw_Menu_Item(row, ICON_PrintSize, F("Manual Leveling"), nullptr, true); else { if (axes_should_home()) { - popupHandler(Popup_Home); + Popup_Handler(Home); gcode.home_all_axes(true); } #if HAS_LEVELING level_state = planner.leveling_active; set_bed_leveling_enabled(false); #endif - drawMenu(ID_ManualLevel); + Draw_Menu(ManualLevel); } break; #if HAS_ZOFFSET_ITEM case PREPARE_ZOFFSET: if (draw) - drawMenuItem(row, ICON_Zoffset, F("Z-Offset"), nullptr, true); + Draw_Menu_Item(row, ICON_Zoffset, F("Z-Offset"), nullptr, true); else { #if HAS_LEVELING level_state = planner.leveling_active; set_bed_leveling_enabled(false); #endif - drawMenu(ID_ZOffset); + Draw_Menu(ZOffset); } break; #endif @@ -1128,16 +1163,16 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra #if HAS_PREHEAT case PREPARE_PREHEAT: if (draw) - drawMenuItem(row, ICON_Temperature, F("Preheat"), nullptr, true); + Draw_Menu_Item(row, ICON_Temperature, F("Preheat"), nullptr, true); else - drawMenu(ID_Preheat); + Draw_Menu(Preheat); break; #endif #if HAS_HOTEND || HAS_HEATED_BED case PREPARE_COOLDOWN: if (draw) - drawMenuItem(row, ICON_Cool, GET_TEXT_F(MSG_COOLDOWN)); + Draw_Menu_Item(row, ICON_Cool, F("Cooldown")); else thermalManager.cooldown(); break; @@ -1149,16 +1184,16 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra #define CUSTOM_MENU_CONFIG_TITLE "Custom Commands" #endif if (draw) - drawMenuItem(row, ICON_Version, F(CUSTOM_MENU_CONFIG_TITLE)); + Draw_Menu_Item(row, ICON_Version, F(CUSTOM_MENU_CONFIG_TITLE)); else - drawMenu(ID_MenuCustom); + Draw_Menu(MenuCustom); break; #endif #if ENABLED(ADVANCED_PAUSE_FEATURE) case PREPARE_CHANGEFIL: if (draw) { - drawMenuItem(row, ICON_ResetEEPROM, GET_TEXT_F(MSG_FILAMENTCHANGE) + Draw_Menu_Item(row, ICON_ResumeEEPROM, F("Change Filament") #if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES) , nullptr, true #endif @@ -1166,35 +1201,27 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra } else { #if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES) - drawMenu(ID_ChangeFilament); + Draw_Menu(ChangeFilament); #else - if (thermalManager.targetTooColdToExtrude(0)) - popupHandler(Popup_ETemp); + if (thermalManager.temp_hotend[0].target < thermalManager.extrude_min_temp) + Popup_Handler(ETemp); else { - if (thermalManager.temp_hotend[0].is_below_target(2)) { - popupHandler(Popup_Heating); + if (thermalManager.temp_hotend[0].is_below_target(-2)) { + Popup_Handler(Heating); thermalManager.wait_for_hotend(0); } - popupHandler(Popup_FilChange); - gcode.process_subcommands_now(TS(F("M600 B1 R"), thermalManager.degTargetHotend(0))); + Popup_Handler(FilChange); + sprintf_P(cmd, PSTR("M600 B1 R%i"), thermalManager.temp_hotend[0].target); + gcode.process_subcommands_now(cmd); } #endif } break; #endif - - #if ENABLED(FWRETRACT) - case PREPARE_FWRETRACT: - if (draw) - drawMenuItem(row, ICON_SetHome, GET_TEXT_F(MSG_FWRETRACT), nullptr, true); - else - drawMenu(ID_FWMenu); - break; - #endif } break; - case ID_HomeMenu: + case HomeMenu: #define HOME_BACK 0 #define HOME_ALL (HOME_BACK + 1) @@ -1207,61 +1234,61 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case HOME_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_Prepare, PREPARE_HOME); + Draw_Menu(Prepare, PREPARE_HOME); break; case HOME_ALL: if (draw) - drawMenuItem(row, ICON_Homing, GET_TEXT_F(MSG_AUTO_HOME)); + Draw_Menu_Item(row, ICON_Homing, F("Home All")); else { - popupHandler(Popup_Home); + Popup_Handler(Home); gcode.home_all_axes(true); - redrawMenu(); + Redraw_Menu(); } break; case HOME_X: if (draw) - drawMenuItem(row, ICON_MoveX, GET_TEXT_F(MSG_AUTO_HOME_X)); + Draw_Menu_Item(row, ICON_MoveX, F("Home X")); else { - popupHandler(Popup_Home); - gcode.process_subcommands_now(F("G28X")); + Popup_Handler(Home); + gcode.process_subcommands_now(F("G28 X")); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); } break; case HOME_Y: if (draw) - drawMenuItem(row, ICON_MoveY, GET_TEXT_F(MSG_AUTO_HOME_X)); + Draw_Menu_Item(row, ICON_MoveY, F("Home Y")); else { - popupHandler(Popup_Home); - gcode.process_subcommands_now(F("G28Y")); + Popup_Handler(Home); + gcode.process_subcommands_now(F("G28 Y")); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); } break; case HOME_Z: if (draw) - drawMenuItem(row, ICON_MoveZ, GET_TEXT_F(MSG_AUTO_HOME_X)); + Draw_Menu_Item(row, ICON_MoveZ, F("Home Z")); else { - popupHandler(Popup_Home); - gcode.process_subcommands_now(F("G28Z")); + Popup_Handler(Home); + gcode.process_subcommands_now(F("G28 Z")); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); } break; case HOME_SET: if (draw) - drawMenuItem(row, ICON_SetHome, F("Set Home Here")); + Draw_Menu_Item(row, ICON_SetHome, F("Set Home Position")); else { gcode.process_subcommands_now(F("G92X0Y0Z0")); - audioFeedback(); + AudioFeedback(); } break; } break; - case ID_Move: + case Move: #define MOVE_BACK 0 #define MOVE_X (MOVE_BACK + 1) @@ -1275,61 +1302,61 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case MOVE_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else { #if HAS_BED_PROBE probe_deployed = false; probe.set_deployed(probe_deployed); #endif - drawMenu(ID_Prepare, PREPARE_MOVE); + Draw_Menu(Prepare, PREPARE_MOVE); } break; case MOVE_X: if (draw) { - drawMenuItem(row, ICON_MoveX, GET_TEXT_F(MSG_MOVE_X)); - drawFloat(current_position.x, row, false); + Draw_Menu_Item(row, ICON_MoveX, F("Move X")); + Draw_Float(current_position.x, row, false); } else - modifyValue(current_position.x, X_MIN_POS, X_MAX_POS, 10); + Modify_Value(current_position.x, X_MIN_POS, X_MAX_POS, 10); break; case MOVE_Y: if (draw) { - drawMenuItem(row, ICON_MoveY, GET_TEXT_F(MSG_MOVE_Y)); - drawFloat(current_position.y, row); + Draw_Menu_Item(row, ICON_MoveY, F("Move Y")); + Draw_Float(current_position.y, row); } else - modifyValue(current_position.y, Y_MIN_POS, Y_MAX_POS, 10); + Modify_Value(current_position.y, Y_MIN_POS, Y_MAX_POS, 10); break; case MOVE_Z: if (draw) { - drawMenuItem(row, ICON_MoveZ, GET_TEXT_F(MSG_MOVE_Z)); - drawFloat(current_position.z, row); + Draw_Menu_Item(row, ICON_MoveZ, F("Move Z")); + Draw_Float(current_position.z, row); } else - modifyValue(current_position.z, Z_MIN_POS, Z_MAX_POS, 10); + Modify_Value(current_position.z, Z_MIN_POS, Z_MAX_POS, 10); break; #if HAS_HOTEND case MOVE_E: if (draw) { - drawMenuItem(row, ICON_Extruder, GET_TEXT_F(MSG_MOVE_E)); + Draw_Menu_Item(row, ICON_Extruder, F("Extruder")); current_position.e = 0; sync_plan_position(); - drawFloat(current_position.e, row); + Draw_Float(current_position.e, row); } else { - if (thermalManager.targetTooColdToExtrude(0)) { - popupHandler(Popup_ETemp); + if (thermalManager.temp_hotend[0].target < thermalManager.extrude_min_temp) { + Popup_Handler(ETemp); } else { - if (thermalManager.temp_hotend[0].is_below_target(2)) { - popupHandler(Popup_Heating); + if (thermalManager.temp_hotend[0].is_below_target(-2)) { + Popup_Handler(Heating); thermalManager.wait_for_hotend(0); - redrawMenu(); + Redraw_Menu(); } current_position.e = 0; sync_plan_position(); - modifyValue(current_position.e, -500, 500, 10); + Modify_Value(current_position.e, -500, 500, 10); } } break; @@ -1338,30 +1365,30 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra #if HAS_BED_PROBE case MOVE_P: if (draw) { - drawMenuItem(row, ICON_StockConfiguration, F("Probe")); - drawCheckbox(row, probe_deployed); + Draw_Menu_Item(row, ICON_StockConfiguration, F("Probe")); + Draw_Checkbox(row, probe_deployed); } else { - probe_deployed ^= true; + probe_deployed = !probe_deployed; probe.set_deployed(probe_deployed); - drawCheckbox(row, probe_deployed); + Draw_Checkbox(row, probe_deployed); } break; #endif case MOVE_LIVE: if (draw) { - drawMenuItem(row, ICON_Axis, GET_TEXT_F(MSG_LIVE_MOVE)); - drawCheckbox(row, livemove); + Draw_Menu_Item(row, ICON_Axis, F("Live Movement")); + Draw_Checkbox(row, livemove); } else { - livemove ^= true; - drawCheckbox(row, livemove); + livemove = !livemove; + Draw_Checkbox(row, livemove); } break; } break; - case ID_ManualLevel: { + case ManualLevel: #define MLEVEL_BACK 0 #define MLEVEL_PROBE (MLEVEL_BACK + ENABLED(HAS_BED_PROBE)) @@ -1376,182 +1403,158 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra static float mlev_z_pos = 0; static bool use_probe = false; - #if HAS_BED_PROBE - const float probe_x_min = _MAX(0 + corner_pos, X_MIN_POS + probe.offset.x, X_MIN_POS + PROBING_MARGIN) - probe.offset.x, - probe_x_max = _MIN((X_BED_SIZE + X_MIN_POS) - corner_pos, X_MAX_POS + probe.offset.x, X_MAX_POS - PROBING_MARGIN) - probe.offset.x, - probe_y_min = _MAX(0 + corner_pos, Y_MIN_POS + probe.offset.y, Y_MIN_POS + PROBING_MARGIN) - probe.offset.y, - probe_y_max = _MIN((Y_BED_SIZE + Y_MIN_POS) - corner_pos, Y_MAX_POS + probe.offset.y, Y_MAX_POS - PROBING_MARGIN) - probe.offset.y; - #endif - switch (item) { case MLEVEL_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else { TERN_(HAS_LEVELING, set_bed_leveling_enabled(level_state)); - drawMenu(ID_Prepare, PREPARE_MANUALLEVEL); + Draw_Menu(Prepare, PREPARE_MANUALLEVEL); } break; - #if HAS_BED_PROBE case MLEVEL_PROBE: if (draw) { - drawMenuItem(row, ICON_Zoffset, F("Use Probe")); - drawCheckbox(row, use_probe); + Draw_Menu_Item(row, ICON_Zoffset, F("Use Probe")); + Draw_Checkbox(row, use_probe); } else { - use_probe ^= true; - drawCheckbox(row, use_probe); + use_probe = !use_probe; + Draw_Checkbox(row, use_probe); if (use_probe) { - popupHandler(Popup_Level); - const struct { xy_pos_t p; ProbePtRaise r; } points[] = { - { { probe_x_min, probe_y_min }, PROBE_PT_RAISE }, - { { probe_x_min, probe_y_max }, PROBE_PT_RAISE }, - { { probe_x_max, probe_y_max }, PROBE_PT_RAISE }, - { { probe_x_max, probe_y_min }, PROBE_PT_STOW } - }; + Popup_Handler(Level); corner_avg = 0; - for (uint8_t i = 0; i < COUNT(points); i++) { - const float mz = probe.probe_at_point(points[i].p, points[i].r, 0, false); - if (isnan(mz)) { corner_avg = 0; break; } - corner_avg += mz; - } + #define PROBE_X_MIN _MAX(0 + corner_pos, X_MIN_POS + probe.offset.x, X_MIN_POS + PROBING_MARGIN) - probe.offset.x + #define PROBE_X_MAX _MIN((X_BED_SIZE + X_MIN_POS) - corner_pos, X_MAX_POS + probe.offset.x, X_MAX_POS - PROBING_MARGIN) - probe.offset.x + #define PROBE_Y_MIN _MAX(0 + corner_pos, Y_MIN_POS + probe.offset.y, Y_MIN_POS + PROBING_MARGIN) - probe.offset.y + #define PROBE_Y_MAX _MIN((Y_BED_SIZE + Y_MIN_POS) - corner_pos, Y_MAX_POS + probe.offset.y, Y_MAX_POS - PROBING_MARGIN) - probe.offset.y + corner_avg += probe.probe_at_point(PROBE_X_MIN, PROBE_Y_MIN, PROBE_PT_RAISE, 0, false); + corner_avg += probe.probe_at_point(PROBE_X_MIN, PROBE_Y_MAX, PROBE_PT_RAISE, 0, false); + corner_avg += probe.probe_at_point(PROBE_X_MAX, PROBE_Y_MAX, PROBE_PT_RAISE, 0, false); + corner_avg += probe.probe_at_point(PROBE_X_MAX, PROBE_Y_MIN, PROBE_PT_STOW, 0, false); corner_avg /= 4; - redrawMenu(); + Redraw_Menu(); } } break; #endif - case MLEVEL_BL: if (draw) - drawMenuItem(row, ICON_AxisBL, GET_TEXT_F(MSG_BOTTOM_LEFT)); + Draw_Menu_Item(row, ICON_AxisBL, F("Bottom Left")); else { - popupHandler(Popup_MoveWait); + Popup_Handler(MoveWait); if (use_probe) { #if HAS_BED_PROBE - gcode.process_subcommands_now( - TS(F("G0F4000\nG0Z10\nG0X"), p_float_t(probe_x_min, 3), 'Y', p_float_t(probe_y_min, 3)) - ); + sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s"), dtostrf(PROBE_X_MIN, 1, 3, str_1), dtostrf(PROBE_Y_MIN, 1, 3, str_2)); + gcode.process_subcommands_now(cmd); planner.synchronize(); - popupHandler(Popup_ManualProbing); + Popup_Handler(ManualProbing); #endif } else { - gcode.process_subcommands_now( - TS(F("G0F4000\nG0Z10\nG0X"), p_float_t(corner_pos, 3), 'Y', p_float_t(corner_pos, 3), F("\nG0F300Z"), p_float_t(mlev_z_pos, 3)) - ); + sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s\nG0 F300 Z%s"), dtostrf(corner_pos, 1, 3, str_1), dtostrf(corner_pos, 1, 3, str_2), dtostrf(mlev_z_pos, 1, 3, str_3)); + gcode.process_subcommands_now(cmd); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); } } break; case MLEVEL_TL: if (draw) - drawMenuItem(row, ICON_AxisTL, GET_TEXT_F(MSG_TOP_LEFT)); + Draw_Menu_Item(row, ICON_AxisTL, F("Top Left")); else { - popupHandler(Popup_MoveWait); + Popup_Handler(MoveWait); if (use_probe) { #if HAS_BED_PROBE - gcode.process_subcommands_now( - TS(F("G0F4000\nG0Z10\nG0X"), p_float_t(probe_x_min, 3), 'Y', p_float_t(probe_y_max, 3)) - ); + sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s"), dtostrf(PROBE_X_MIN, 1, 3, str_1), dtostrf(PROBE_Y_MAX, 1, 3, str_2)); + gcode.process_subcommands_now(cmd); planner.synchronize(); - popupHandler(Popup_ManualProbing); + Popup_Handler(ManualProbing); #endif } else { - gcode.process_subcommands_now( - TS(F("G0F4000\nG0Z10\nG0X"), p_float_t(corner_pos, 3), 'Y', p_float_t((Y_BED_SIZE + Y_MIN_POS) - corner_pos, 3), F("\nG0F300Z"), p_float_t(mlev_z_pos, 3)) - ); + sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s\nG0 F300 Z%s"), dtostrf(corner_pos, 1, 3, str_1), dtostrf((Y_BED_SIZE + Y_MIN_POS) - corner_pos, 1, 3, str_2), dtostrf(mlev_z_pos, 1, 3, str_3)); + gcode.process_subcommands_now(cmd); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); } } break; case MLEVEL_TR: if (draw) - drawMenuItem(row, ICON_AxisTR, GET_TEXT_F(MSG_TOP_RIGHT)); + Draw_Menu_Item(row, ICON_AxisTR, F("Top Right")); else { - popupHandler(Popup_MoveWait); + Popup_Handler(MoveWait); if (use_probe) { #if HAS_BED_PROBE - gcode.process_subcommands_now( - TS(F("G0F4000\nG0Z10\nG0X"), p_float_t(probe_x_max, 3), 'Y', p_float_t(probe_y_max, 3), F("\nG0F300Z"), p_float_t(mlev_z_pos, 3)) - ); + sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s"), dtostrf(PROBE_X_MAX, 1, 3, str_1), dtostrf(PROBE_Y_MAX, 1, 3, str_2)); + gcode.process_subcommands_now(cmd); planner.synchronize(); - popupHandler(Popup_ManualProbing); + Popup_Handler(ManualProbing); #endif } else { - gcode.process_subcommands_now( - TS(F("G0F4000\nG0Z10\nG0X"), p_float_t((X_BED_SIZE + X_MIN_POS) - corner_pos, 3), 'Y', p_float_t((Y_BED_SIZE + Y_MIN_POS) - corner_pos, 3), F("\nG0F300Z"), p_float_t(mlev_z_pos, 3)) - ); + sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s\nG0 F300 Z%s"), dtostrf((X_BED_SIZE + X_MIN_POS) - corner_pos, 1, 3, str_1), dtostrf((Y_BED_SIZE + Y_MIN_POS) - corner_pos, 1, 3, str_2), dtostrf(mlev_z_pos, 1, 3, str_3)); + gcode.process_subcommands_now(cmd); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); } } break; case MLEVEL_BR: if (draw) - drawMenuItem(row, ICON_AxisBR, GET_TEXT_F(MSG_BOTTOM_RIGHT)); + Draw_Menu_Item(row, ICON_AxisBR, F("Bottom Right")); else { - popupHandler(Popup_MoveWait); + Popup_Handler(MoveWait); if (use_probe) { #if HAS_BED_PROBE - gcode.process_subcommands_now( - TS(F("G0F4000\nG0Z10\nG0X"), p_float_t(probe_x_max, 3), 'Y', p_float_t(probe_y_min, 3)) - ); + sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s"), dtostrf(PROBE_X_MAX, 1, 3, str_1), dtostrf(PROBE_Y_MIN, 1, 3, str_2)); + gcode.process_subcommands_now(cmd); planner.synchronize(); - popupHandler(Popup_ManualProbing); + Popup_Handler(ManualProbing); #endif } else { - gcode.process_subcommands_now( - TS(F("G0F4000\nG0Z10\nG0X"), p_float_t((X_BED_SIZE + X_MIN_POS) - corner_pos, 3), 'Y', p_float_t(corner_pos, 3), F("\nG0F300Z"), p_float_t(mlev_z_pos, 3)) - ); + sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s\nG0 F300 Z%s"), dtostrf((X_BED_SIZE + X_MIN_POS) - corner_pos, 1, 3, str_1), dtostrf(corner_pos, 1, 3, str_2), dtostrf(mlev_z_pos, 1, 3, str_3)); + gcode.process_subcommands_now(cmd); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); } } break; case MLEVEL_C: if (draw) - drawMenuItem(row, ICON_AxisC, GET_TEXT_F(MSG_TRAM_C)); + Draw_Menu_Item(row, ICON_AxisC, F("Center")); else { - popupHandler(Popup_MoveWait); + Popup_Handler(MoveWait); if (use_probe) { #if HAS_BED_PROBE - gcode.process_subcommands_now( - TS(F("G0F4000\nG0Z10\nG0X"), p_float_t((X_MAX_POS) / 2.0f - probe.offset.x, 3), 'Y', p_float_t((Y_MAX_POS) / 2.0f - probe.offset.y, 3)) - ); + sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s"), dtostrf(X_MAX_POS / 2.0f - probe.offset.x, 1, 3, str_1), dtostrf(Y_MAX_POS / 2.0f - probe.offset.y, 1, 3, str_2)); + gcode.process_subcommands_now(cmd); planner.synchronize(); - popupHandler(Popup_ManualProbing); + Popup_Handler(ManualProbing); #endif } else { - gcode.process_subcommands_now( - TS(F("G0F4000\nG0Z10\nG0X"), p_float_t((X_BED_SIZE + X_MIN_POS) - corner_pos, 3), 'Y', p_float_t((Y_BED_SIZE + Y_MIN_POS) / 2.0f, 3), F("\nG0F300Z"), p_float_t(mlev_z_pos, 3)) - ); + sprintf_P(cmd, PSTR("G0 F4000\nG0 Z10\nG0 X%s Y%s\nG0 F300 Z%s"), dtostrf((X_BED_SIZE + X_MIN_POS) / 2.0f, 1, 3, str_1), dtostrf((Y_BED_SIZE + Y_MIN_POS) / 2.0f, 1, 3, str_2), dtostrf(mlev_z_pos, 1, 3, str_3)); + gcode.process_subcommands_now(cmd); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); } } break; case MLEVEL_ZPOS: if (draw) { - drawMenuItem(row, ICON_SetZOffset, F("Z Position")); - drawFloat(mlev_z_pos, row, false, 100); + Draw_Menu_Item(row, ICON_SetZOffset, F("Z Position")); + Draw_Float(mlev_z_pos, row, false, 100); } else - modifyValue(mlev_z_pos, 0, MAX_Z_OFFSET, 100); + Modify_Value(mlev_z_pos, 0, MAX_Z_OFFSET, 100); break; } - - } break; - + break; #if HAS_ZOFFSET_ITEM - case ID_ZOffset: + case ZOffset: #define ZOFFSET_BACK 0 #define ZOFFSET_HOME (ZOFFSET_BACK + 1) @@ -1565,72 +1568,70 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case ZOFFSET_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else { liveadjust = false; TERN_(HAS_LEVELING, set_bed_leveling_enabled(level_state)); - drawMenu(ID_Prepare, PREPARE_ZOFFSET); + Draw_Menu(Prepare, PREPARE_ZOFFSET); } break; case ZOFFSET_HOME: if (draw) - drawMenuItem(row, ICON_Homing, GET_TEXT_F(MSG_AUTO_HOME_Z)); + Draw_Menu_Item(row, ICON_Homing, F("Home Z Axis")); else { - popupHandler(Popup_Home); - gcode.process_subcommands_now(F("G28Z")); - popupHandler(Popup_MoveWait); + Popup_Handler(Home); + gcode.process_subcommands_now(F("G28 Z")); + Popup_Handler(MoveWait); #if ENABLED(Z_SAFE_HOMING) planner.synchronize(); - gcode.process_subcommands_now( - TS(F("G0F4000X"), p_float_t(Z_SAFE_HOMING_X_POINT, 3), 'Y', p_float_t(Z_SAFE_HOMING_Y_POINT, 3)) - ); + sprintf_P(cmd, PSTR("G0 F4000 X%s Y%s"), dtostrf(Z_SAFE_HOMING_X_POINT, 1, 3, str_1), dtostrf(Z_SAFE_HOMING_Y_POINT, 1, 3, str_2)); + gcode.process_subcommands_now(cmd); #else gcode.process_subcommands_now(F("G0 F4000 X117.5 Y117.5")); #endif - gcode.process_subcommands_now(F("G0F300Z0")); + gcode.process_subcommands_now(F("G0 F300 Z0")); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); } break; case ZOFFSET_MODE: if (draw) { - drawMenuItem(row, ICON_Zoffset, F("Live Adjustment")); - drawCheckbox(row, liveadjust); + Draw_Menu_Item(row, ICON_Zoffset, F("Live Adjustment")); + Draw_Checkbox(row, liveadjust); } else { if (!liveadjust) { if (axes_should_home()) { - popupHandler(Popup_Home); + Popup_Handler(Home); gcode.home_all_axes(true); } - popupHandler(Popup_MoveWait); + Popup_Handler(MoveWait); #if ENABLED(Z_SAFE_HOMING) planner.synchronize(); - gcode.process_subcommands_now( - TS(F("G0F4000X"), p_float_t(Z_SAFE_HOMING_X_POINT, 3), 'Y', p_float_t(Z_SAFE_HOMING_Y_POINT, 3)) - ); + sprintf_P(cmd, PSTR("G0 F4000 X%s Y%s"), dtostrf(Z_SAFE_HOMING_X_POINT, 1, 3, str_1), dtostrf(Z_SAFE_HOMING_Y_POINT, 1, 3, str_2)); + gcode.process_subcommands_now(cmd); #else gcode.process_subcommands_now(F("G0 F4000 X117.5 Y117.5")); #endif - gcode.process_subcommands_now(F("G0F300Z0")); + gcode.process_subcommands_now(F("G0 F300 Z0")); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); } - liveadjust ^= true; - drawCheckbox(row, liveadjust); + liveadjust = !liveadjust; + Draw_Checkbox(row, liveadjust); } break; case ZOFFSET_OFFSET: if (draw) { - drawMenuItem(row, ICON_SetZOffset, F("Z Offset")); - drawFloat(zoffsetvalue, row, false, 100); + Draw_Menu_Item(row, ICON_SetZOffset, F("Z Offset")); + Draw_Float(zoffsetvalue, row, false, 100); } else - modifyValue(zoffsetvalue, MIN_Z_OFFSET, MAX_Z_OFFSET, 100); + Modify_Value(zoffsetvalue, MIN_Z_OFFSET, MAX_Z_OFFSET, 100); break; case ZOFFSET_UP: if (draw) - drawMenuItem(row, ICON_Axis, F("+0.01mm Up")); + Draw_Menu_Item(row, ICON_Axis, F("Microstep Up")); else { if (zoffsetvalue < MAX_Z_OFFSET) { if (liveadjust) { @@ -1638,13 +1639,13 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra planner.synchronize(); } zoffsetvalue += 0.01; - drawFloat(zoffsetvalue, row - 1, false, 100); + Draw_Float(zoffsetvalue, row - 1, false, 100); } } break; case ZOFFSET_DOWN: if (draw) - drawMenuItem(row, ICON_AxisD, F("-0.01mm Down")); + Draw_Menu_Item(row, ICON_AxisD, F("Microstep Down")); else { if (zoffsetvalue > MIN_Z_OFFSET) { if (liveadjust) { @@ -1652,16 +1653,16 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra planner.synchronize(); } zoffsetvalue -= 0.01; - drawFloat(zoffsetvalue, row - 2, false, 100); + Draw_Float(zoffsetvalue, row - 2, false, 100); } } break; #if ENABLED(EEPROM_SETTINGS) case ZOFFSET_SAVE: if (draw) - drawMenuItem(row, ICON_WriteEEPROM, GET_TEXT_F(MSG_BUTTON_SAVE)); + Draw_Menu_Item(row, ICON_WriteEEPROM, F("Save")); else - audioFeedback(settings.save()); + AudioFeedback(settings.save()); break; #endif } @@ -1669,7 +1670,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra #endif #if HAS_PREHEAT - case ID_Preheat: { + case Preheat: { #define PREHEAT_MODE (PREHEAT_BACK + 1) #define PREHEAT_1 (PREHEAT_MODE + 1) #define PREHEAT_2 (PREHEAT_1 + (PREHEAT_COUNT >= 2)) @@ -1687,22 +1688,23 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case PREHEAT_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_Prepare, PREPARE_PREHEAT); + Draw_Menu(Prepare, PREPARE_PREHEAT); break; + case PREHEAT_MODE: if (draw) { - drawMenuItem(row, ICON_Homing, F("Preheat Mode")); - drawOption(preheatmode, preheat_modes, row); + Draw_Menu_Item(row, ICON_Homing, F("Preheat Mode")); + Draw_Option(preheatmode, preheat_modes, row); } else - modifyOption(preheatmode, preheat_modes, 2); + Modify_Option(preheatmode, preheat_modes, 2); break; #define _PREHEAT_CASE(N) \ case PREHEAT_##N: { \ - if (draw) drawMenuItem(row, ICON_Temperature, F(PREHEAT_## N ##_LABEL)); \ + if (draw) Draw_Menu_Item(row, ICON_Temperature, F(PREHEAT_## N ##_LABEL)); \ else do_preheat(N - 1); \ } break; @@ -1712,7 +1714,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra #endif // HAS_PREHEAT #if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES) - case ID_ChangeFilament: + case ChangeFilament: #define CHANGEFIL_BACK 0 #define CHANGEFIL_LOAD (CHANGEFIL_BACK + 1) @@ -1723,60 +1725,61 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case CHANGEFIL_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_Prepare, PREPARE_CHANGEFIL); + Draw_Menu(Prepare, PREPARE_CHANGEFIL); break; case CHANGEFIL_LOAD: if (draw) - drawMenuItem(row, ICON_WriteEEPROM, GET_TEXT_F(MSG_FILAMENTLOAD)); + Draw_Menu_Item(row, ICON_WriteEEPROM, F("Load Filament")); else { - if (thermalManager.targetTooColdToExtrude(0)) - popupHandler(Popup_ETemp); + if (thermalManager.temp_hotend[0].target < thermalManager.extrude_min_temp) + Popup_Handler(ETemp); else { - if (thermalManager.temp_hotend[0].is_below_target(2)) { - popupHandler(Popup_Heating); + if (thermalManager.temp_hotend[0].is_below_target(-2)) { + Popup_Handler(Heating); thermalManager.wait_for_hotend(0); } - popupHandler(Popup_FilLoad); + Popup_Handler(FilLoad); gcode.process_subcommands_now(F("M701")); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); } } break; case CHANGEFIL_UNLOAD: if (draw) - drawMenuItem(row, ICON_ReadEEPROM, GET_TEXT_F(MSG_FILAMENTUNLOAD)); + Draw_Menu_Item(row, ICON_ReadEEPROM, F("Unload Filament")); else { - if (thermalManager.targetTooColdToExtrude(0)) { - popupHandler(Popup_ETemp); + if (thermalManager.temp_hotend[0].target < thermalManager.extrude_min_temp) { + Popup_Handler(ETemp); } else { - if (thermalManager.temp_hotend[0].is_below_target(2)) { - popupHandler(Popup_Heating); + if (thermalManager.temp_hotend[0].is_below_target(-2)) { + Popup_Handler(Heating); thermalManager.wait_for_hotend(0); } - popupHandler(Popup_FilLoad, true); + Popup_Handler(FilLoad, true); gcode.process_subcommands_now(F("M702")); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); } } break; case CHANGEFIL_CHANGE: if (draw) - drawMenuItem(row, ICON_ResetEEPROM, GET_TEXT_F(MSG_FILAMENTCHANGE)); + Draw_Menu_Item(row, ICON_ResumeEEPROM, F("Change Filament")); else { - if (thermalManager.targetTooColdToExtrude(0)) - popupHandler(Popup_ETemp); + if (thermalManager.temp_hotend[0].target < thermalManager.extrude_min_temp) + Popup_Handler(ETemp); else { - if (thermalManager.temp_hotend[0].is_below_target(2)) { - popupHandler(Popup_Heating); + if (thermalManager.temp_hotend[0].is_below_target(-2)) { + Popup_Handler(Heating); thermalManager.wait_for_hotend(0); } - popupHandler(Popup_FilChange); - gcode.process_subcommands_now(TS(F("M600B1R"), thermalManager.degTargetHotend(0))); + Popup_Handler(FilChange); + sprintf_P(cmd, PSTR("M600 B1 R%i"), thermalManager.temp_hotend[0].target); + gcode.process_subcommands_now(cmd); } } break; @@ -1785,7 +1788,8 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra #endif // FILAMENT_LOAD_UNLOAD_GCODES #if HAS_CUSTOM_MENU - case ID_MenuCustom: + + case MenuCustom: #define CUSTOM_MENU_BACK 0 #define CUSTOM_MENU_1 1 @@ -1798,23 +1802,23 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case CUSTOM_MENU_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_Prepare, PREPARE_CUSTOM_MENU); + Draw_Menu(Prepare, PREPARE_CUSTOM_MENU); break; #if CUSTOM_MENU_COUNT >= 1 case CUSTOM_MENU_1: if (draw) - drawMenuItem(row, ICON_Info, F(CONFIG_MENU_ITEM_1_DESC)); + Draw_Menu_Item(row, ICON_Info, F(CONFIG_MENU_ITEM_1_DESC)); else { - popupHandler(Popup_Custom); + Popup_Handler(Custom); //queue.inject(F(CONFIG_MENU_ITEM_1_GCODE)); // Old code gcode.process_subcommands_now(F(CONFIG_MENU_ITEM_1_GCODE)); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); #if ENABLED(CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK) - audioFeedback(); + AudioFeedback(); #endif #ifdef CUSTOM_MENU_CONFIG_SCRIPT_RETURN queue.inject(F(CUSTOM_MENU_CONFIG_SCRIPT_DONE)); @@ -1826,14 +1830,14 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra #if CUSTOM_MENU_COUNT >= 2 case CUSTOM_MENU_2: if (draw) - drawMenuItem(row, ICON_Info, F(CONFIG_MENU_ITEM_2_DESC)); + Draw_Menu_Item(row, ICON_Info, F(CONFIG_MENU_ITEM_2_DESC)); else { - popupHandler(Popup_Custom); + Popup_Handler(Custom); gcode.process_subcommands_now(F(CONFIG_MENU_ITEM_2_GCODE)); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); #if ENABLED(CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK) - audioFeedback(); + AudioFeedback(); #endif #ifdef CUSTOM_MENU_CONFIG_SCRIPT_RETURN queue.inject(F(CUSTOM_MENU_CONFIG_SCRIPT_DONE)); @@ -1845,14 +1849,14 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra #if CUSTOM_MENU_COUNT >= 3 case CUSTOM_MENU_3: if (draw) - drawMenuItem(row, ICON_Info, F(CONFIG_MENU_ITEM_3_DESC)); + Draw_Menu_Item(row, ICON_Info, F(CONFIG_MENU_ITEM_3_DESC)); else { - popupHandler(Popup_Custom); + Popup_Handler(Custom); gcode.process_subcommands_now(F(CONFIG_MENU_ITEM_3_GCODE)); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); #if ENABLED(CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK) - audioFeedback(); + AudioFeedback(); #endif #ifdef CUSTOM_MENU_CONFIG_SCRIPT_RETURN queue.inject(F(CUSTOM_MENU_CONFIG_SCRIPT_DONE)); @@ -1864,14 +1868,14 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra #if CUSTOM_MENU_COUNT >= 4 case CUSTOM_MENU_4: if (draw) - drawMenuItem(row, ICON_Info, F(CONFIG_MENU_ITEM_4_DESC)); + Draw_Menu_Item(row, ICON_Info, F(CONFIG_MENU_ITEM_4_DESC)); else { - popupHandler(Popup_Custom); + Popup_Handler(Custom); gcode.process_subcommands_now(F(CONFIG_MENU_ITEM_4_GCODE)); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); #if ENABLED(CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK) - audioFeedback(); + AudioFeedback(); #endif #ifdef CUSTOM_MENU_CONFIG_SCRIPT_RETURN queue.inject(F(CUSTOM_MENU_CONFIG_SCRIPT_DONE)); @@ -1883,14 +1887,14 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra #if CUSTOM_MENU_COUNT >= 5 case CUSTOM_MENU_5: if (draw) - drawMenuItem(row, ICON_Info, F(CONFIG_MENU_ITEM_5_DESC)); + Draw_Menu_Item(row, ICON_Info, F(CONFIG_MENU_ITEM_5_DESC)); else { - popupHandler(Popup_Custom); + Popup_Handler(Custom); gcode.process_subcommands_now(F(CONFIG_MENU_ITEM_5_GCODE)); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); #if ENABLED(CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK) - audioFeedback(); + AudioFeedback(); #endif #ifdef CUSTOM_MENU_CONFIG_SCRIPT_RETURN queue.inject(F(CUSTOM_MENU_CONFIG_SCRIPT_DONE)); @@ -1900,9 +1904,10 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra #endif // Custom Menu } break; + #endif // HAS_CUSTOM_MENU - case ID_Control: + case Control: #define CONTROL_BACK 0 #define CONTROL_TEMP (CONTROL_BACK + 1) @@ -1910,82 +1915,81 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra #define CONTROL_VISUAL (CONTROL_MOTION + 1) #define CONTROL_ADVANCED (CONTROL_VISUAL + 1) #define CONTROL_SAVE (CONTROL_ADVANCED + ENABLED(EEPROM_SETTINGS)) - #define CONTROL_LOAD (CONTROL_SAVE + ENABLED(EEPROM_SETTINGS)) - #define CONTROL_RESET (CONTROL_LOAD + ENABLED(EEPROM_SETTINGS)) + #define CONTROL_RESTORE (CONTROL_SAVE + ENABLED(EEPROM_SETTINGS)) + #define CONTROL_RESET (CONTROL_RESTORE + ENABLED(EEPROM_SETTINGS)) #define CONTROL_INFO (CONTROL_RESET + 1) #define CONTROL_TOTAL CONTROL_INFO switch (item) { case CONTROL_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMainMenu(2); + Draw_Main_Menu(2); break; case CONTROL_TEMP: if (draw) - drawMenuItem(row, ICON_Temperature, GET_TEXT_F(MSG_TEMPERATURE), nullptr, true); + Draw_Menu_Item(row, ICON_Temperature, F("Temperature"), nullptr, true); else - drawMenu(ID_TempMenu); + Draw_Menu(TempMenu); break; case CONTROL_MOTION: if (draw) - drawMenuItem(row, ICON_Motion, GET_TEXT_F(MSG_MOTION), nullptr, true); + Draw_Menu_Item(row, ICON_Motion, F("Motion"), nullptr, true); else - drawMenu(ID_Motion); + Draw_Menu(Motion); break; case CONTROL_VISUAL: if (draw) - drawMenuItem(row, ICON_PrintSize, F("Visual"), nullptr, true); + Draw_Menu_Item(row, ICON_PrintSize, F("Visual"), nullptr, true); else - drawMenu(ID_Visual); + Draw_Menu(Visual); break; case CONTROL_ADVANCED: if (draw) - drawMenuItem(row, ICON_Version, GET_TEXT_F(MSG_ADVANCED_SETTINGS), nullptr, true); + Draw_Menu_Item(row, ICON_Version, F("Advanced"), nullptr, true); else - drawMenu(ID_Advanced); + Draw_Menu(Advanced); break; #if ENABLED(EEPROM_SETTINGS) case CONTROL_SAVE: if (draw) - drawMenuItem(row, ICON_WriteEEPROM, GET_TEXT_F(MSG_STORE_EEPROM)); + Draw_Menu_Item(row, ICON_WriteEEPROM, F("Store Settings")); else - audioFeedback(settings.save()); + AudioFeedback(settings.save()); break; - case CONTROL_LOAD: + case CONTROL_RESTORE: if (draw) - drawMenuItem(row, ICON_ReadEEPROM, GET_TEXT_F(MSG_LOAD_EEPROM)); + Draw_Menu_Item(row, ICON_ReadEEPROM, F("Restore Settings")); else - audioFeedback(settings.load()); + AudioFeedback(settings.load()); break; case CONTROL_RESET: if (draw) - drawMenuItem(row, ICON_Temperature, GET_TEXT_F(MSG_RESTORE_DEFAULTS)); + Draw_Menu_Item(row, ICON_Temperature, F("Reset to Defaults")); else { settings.reset(); - audioFeedback(); + AudioFeedback(); } break; #endif case CONTROL_INFO: if (draw) - drawMenuItem(row, ICON_Info, GET_TEXT_F(MSG_INFO_SCREEN)); + Draw_Menu_Item(row, ICON_Info, F("Info")); else - drawMenu(ID_Info); + Draw_Menu(Info); break; } break; - case ID_TempMenu: + case TempMenu: #define TEMP_BACK 0 #define TEMP_HOTEND (TEMP_BACK + ENABLED(HAS_HOTEND)) #define TEMP_BED (TEMP_HOTEND + ENABLED(HAS_HEATED_BED)) #define TEMP_FAN (TEMP_BED + ENABLED(HAS_FAN)) - #define TEMP_PID (TEMP_FAN + ANY(PIDTEMP, PIDTEMPBED)) - #define TEMP_MPC (TEMP_PID + ANY(MPC_EDIT_MENU, MPC_AUTOTUNE_MENU)) - #define TEMP_PREHEAT1 (TEMP_MPC + (PREHEAT_COUNT >= 1)) + #define TEMP_PID (TEMP_FAN + ANY(HAS_HOTEND, HAS_HEATED_BED)) + #define TEMP_PREHEAT1 (TEMP_PID + (PREHEAT_COUNT >= 1)) #define TEMP_PREHEAT2 (TEMP_PREHEAT1 + (PREHEAT_COUNT >= 2)) #define TEMP_PREHEAT3 (TEMP_PREHEAT2 + (PREHEAT_COUNT >= 3)) #define TEMP_PREHEAT4 (TEMP_PREHEAT3 + (PREHEAT_COUNT >= 4)) @@ -1995,73 +1999,65 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case TEMP_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_Control, CONTROL_TEMP); + Draw_Menu(Control, CONTROL_TEMP); break; #if HAS_HOTEND case TEMP_HOTEND: if (draw) { - drawMenuItem(row, ICON_SetEndTemp, GET_TEXT_F(MSG_NOZZLE)); - drawFloat(thermalManager.degTargetHotend(0), row, false, 1); + Draw_Menu_Item(row, ICON_SetEndTemp, F("Hotend")); + Draw_Float(thermalManager.temp_hotend[0].target, row, false, 1); } else - modifyValue(thermalManager.temp_hotend[0].target, MIN_E_TEMP, MAX_E_TEMP, 1); + Modify_Value(thermalManager.temp_hotend[0].target, MIN_E_TEMP, MAX_E_TEMP, 1); break; #endif #if HAS_HEATED_BED case TEMP_BED: if (draw) { - drawMenuItem(row, ICON_SetBedTemp, GET_TEXT_F(MSG_BED)); - drawFloat(thermalManager.degTargetBed(), row, false, 1); + Draw_Menu_Item(row, ICON_SetBedTemp, F("Bed")); + Draw_Float(thermalManager.temp_bed.target, row, false, 1); } else - modifyValue(thermalManager.temp_bed.target, MIN_BED_TEMP, MAX_BED_TEMP, 1); + Modify_Value(thermalManager.temp_bed.target, MIN_BED_TEMP, MAX_BED_TEMP, 1); break; #endif #if HAS_FAN case TEMP_FAN: if (draw) { - drawMenuItem(row, ICON_FanSpeed, GET_TEXT_F(MSG_FAN_SPEED)); - drawFloat(thermalManager.fan_speed[0], row, false, 1); + Draw_Menu_Item(row, ICON_FanSpeed, F("Fan")); + Draw_Float(thermalManager.fan_speed[0], row, false, 1); } else - modifyValue(thermalManager.fan_speed[0], MIN_FAN_SPEED, MAX_FAN_SPEED, 1); + Modify_Value(thermalManager.fan_speed[0], MIN_FAN_SPEED, MAX_FAN_SPEED, 1); break; #endif - #if ANY(PIDTEMP, PIDTEMPBED) + #if HAS_HOTEND || HAS_HEATED_BED case TEMP_PID: if (draw) - drawMenuItem(row, ICON_Step, F("PID"), nullptr, true); + Draw_Menu_Item(row, ICON_Step, F("PID"), nullptr, true); else - drawMenu(ID_PID); - break; - #endif - #if ANY(MPC_EDIT_MENU, MPC_AUTOTUNE_MENU) - case TEMP_MPC: - if (draw) - drawMenuItem(row, ICON_Step, F("MPC"), nullptr, true); - else - drawMenu(ID_MPC); + Draw_Menu(PID); break; #endif #define _TEMP_PREHEAT_CASE(N) \ case TEMP_PREHEAT##N: { \ - if (draw) drawMenuItem(row, ICON_Step, F(PREHEAT_## N ##_LABEL), nullptr, true); \ - else drawMenu(ID_Preheat##N); \ + if (draw) Draw_Menu_Item(row, ICON_Step, F(PREHEAT_## N ##_LABEL), nullptr, true); \ + else Draw_Menu(Preheat##N); \ } break; REPEAT_1(PREHEAT_COUNT, _TEMP_PREHEAT_CASE) } break; - #if ANY(PIDTEMP, PIDTEMPBED) - case ID_PID: + #if HAS_HOTEND || HAS_HEATED_BED + case PID: #define PID_BACK 0 - #define PID_HOTEND (PID_BACK + ENABLED(PIDTEMP)) - #define PID_BED (PID_HOTEND + ENABLED(PIDTEMPBED)) + #define PID_HOTEND (PID_BACK + ENABLED(HAS_HOTEND)) + #define PID_BED (PID_HOTEND + ENABLED(HAS_HEATED_BED)) #define PID_CYCLES (PID_BED + 1) #define PID_TOTAL PID_CYCLES @@ -2070,40 +2066,40 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case PID_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_TempMenu, TEMP_PID); + Draw_Menu(TempMenu, TEMP_PID); break; - #if ENABLED(PIDTEMP) + #if HAS_HOTEND case PID_HOTEND: if (draw) - drawMenuItem(row, ICON_HotendTemp, GET_TEXT_F(MSG_NOZZLE), nullptr, true); + Draw_Menu_Item(row, ICON_HotendTemp, F("Hotend"), nullptr, true); else - drawMenu(ID_HotendPID); + Draw_Menu(HotendPID); break; #endif - #if ENABLED(PIDTEMPBED) + #if HAS_HEATED_BED case PID_BED: if (draw) - drawMenuItem(row, ICON_BedTemp, GET_TEXT_F(MSG_BED), nullptr, true); + Draw_Menu_Item(row, ICON_BedTemp, F("Bed"), nullptr, true); else - drawMenu(ID_BedPID); + Draw_Menu(BedPID); break; #endif case PID_CYCLES: if (draw) { - drawMenuItem(row, ICON_FanSpeed, F("Cycles")); - drawFloat(PID_cycles, row, false, 1); + Draw_Menu_Item(row, ICON_FanSpeed, F("Cycles")); + Draw_Float(PID_cycles, row, false, 1); } else - modifyValue(PID_cycles, 3, 50, 1); + Modify_Value(PID_cycles, 3, 50, 1); break; } break; - #endif // PIDTEMP || PIDTEMPBED + #endif // HAS_HOTEND || HAS_HEATED_BED - #if ENABLED(PIDTEMP) - case ID_HotendPID: + #if HAS_HOTEND + case HotendPID: #define HOTENDPID_BACK 0 #define HOTENDPID_TUNE (HOTENDPID_BACK + 1) @@ -2118,58 +2114,59 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case HOTENDPID_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_PID, PID_HOTEND); + Draw_Menu(PID, PID_HOTEND); break; case HOTENDPID_TUNE: if (draw) - drawMenuItem(row, ICON_HotendTemp, GET_TEXT_F(MSG_PID_AUTOTUNE)); + Draw_Menu_Item(row, ICON_HotendTemp, F("Autotune")); else { - popupHandler(Popup_PIDWait); - gcode.process_subcommands_now(TS(F("M303E0C"), PID_cycles, 'S', PID_e_temp, 'U')); + Popup_Handler(PIDWait); + sprintf_P(cmd, PSTR("M303 E0 C%i S%i U1"), PID_cycles, PID_e_temp); + gcode.process_subcommands_now(cmd); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); } break; case HOTENDPID_TEMP: if (draw) { - drawMenuItem(row, ICON_Temperature, GET_TEXT_F(MSG_TEMPERATURE)); - drawFloat(PID_e_temp, row, false, 1); + Draw_Menu_Item(row, ICON_Temperature, F("Temperature")); + Draw_Float(PID_e_temp, row, false, 1); } else - modifyValue(PID_e_temp, MIN_E_TEMP, MAX_E_TEMP, 1); + Modify_Value(PID_e_temp, MIN_E_TEMP, MAX_E_TEMP, 1); break; case HOTENDPID_KP: if (draw) { - drawMenuItem(row, ICON_Version, GET_TEXT_F(MSG_PID_P)); - drawFloat(thermalManager.temp_hotend[0].pid.p(), row, false, 100); + Draw_Menu_Item(row, ICON_Version, F("Kp Value")); + Draw_Float(thermalManager.temp_hotend[0].pid.p(), row, false, 100); } else - modifyValue(thermalManager.temp_hotend[0].pid.Kp, 0, 5000, 100, thermalManager.updatePID); + Modify_Value(thermalManager.temp_hotend[0].pid.Kp, 0, 5000, 100, thermalManager.updatePID); break; case HOTENDPID_KI: if (draw) { - drawMenuItem(row, ICON_Version, GET_TEXT_F(MSG_PID_I)); - drawFloat(thermalManager.temp_hotend[0].pid.i(), row, false, 100); + Draw_Menu_Item(row, ICON_Version, F("Ki Value")); + Draw_Float(thermalManager.temp_hotend[0].pid.i(), row, false, 100); } else - modifyValue(thermalManager.temp_hotend[0].pid.Ki, 0, 5000, 100, thermalManager.updatePID); + Modify_Value(thermalManager.temp_hotend[0].pid.Ki, 0, 5000, 100, thermalManager.updatePID); break; case HOTENDPID_KD: if (draw) { - drawMenuItem(row, ICON_Version, GET_TEXT_F(MSG_PID_D)); - drawFloat(thermalManager.temp_hotend[0].pid.d(), row, false, 100); + Draw_Menu_Item(row, ICON_Version, F("Kd Value")); + Draw_Float(thermalManager.temp_hotend[0].pid.d(), row, false, 100); } else - modifyValue(thermalManager.temp_hotend[0].pid.Kd, 0, 5000, 100, thermalManager.updatePID); + Modify_Value(thermalManager.temp_hotend[0].pid.Kd, 0, 5000, 100, thermalManager.updatePID); break; } break; - #endif // PIDTEMP + #endif // HAS_HOTEND - #if ENABLED(PIDTEMPBED) - case ID_BedPID: + #if HAS_HEATED_BED + case BedPID: #define BEDPID_BACK 0 #define BEDPID_TUNE (BEDPID_BACK + 1) @@ -2184,230 +2181,127 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case BEDPID_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_PID, PID_BED); + Draw_Menu(PID, PID_BED); break; case BEDPID_TUNE: if (draw) - drawMenuItem(row, ICON_HotendTemp, GET_TEXT_F(MSG_PID_AUTOTUNE)); + Draw_Menu_Item(row, ICON_HotendTemp, F("Autotune")); else { - popupHandler(Popup_PIDWait); - gcode.process_subcommands_now(TS(F("M303E-1C"), PID_cycles, 'S', PID_bed_temp, 'U')); + Popup_Handler(PIDWait); + sprintf_P(cmd, PSTR("M303 E-1 C%i S%i U1"), PID_cycles, PID_bed_temp); + gcode.process_subcommands_now(cmd); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); } break; case BEDPID_TEMP: if (draw) { - drawMenuItem(row, ICON_Temperature, GET_TEXT_F(MSG_TEMPERATURE)); - drawFloat(PID_bed_temp, row, false, 1); + Draw_Menu_Item(row, ICON_Temperature, F("Temperature")); + Draw_Float(PID_bed_temp, row, false, 1); } else - modifyValue(PID_bed_temp, MIN_BED_TEMP, MAX_BED_TEMP, 1); + Modify_Value(PID_bed_temp, MIN_BED_TEMP, MAX_BED_TEMP, 1); break; case BEDPID_KP: if (draw) { - drawMenuItem(row, ICON_Version, GET_TEXT_F(MSG_PID_P)); - drawFloat(thermalManager.temp_bed.pid.p(), row, false, 100); + Draw_Menu_Item(row, ICON_Version, F("Kp Value")); + Draw_Float(thermalManager.temp_bed.pid.p(), row, false, 100); + } + else { + Modify_Value(thermalManager.temp_bed.pid.Kp, 0, 5000, 100, thermalManager.updatePID); } - else - modifyValue(thermalManager.temp_bed.pid.Kp, 0, 5000, 100, []{ thermalManager.temp_bed.pid.reset(); }); break; case BEDPID_KI: if (draw) { - drawMenuItem(row, ICON_Version, GET_TEXT_F(MSG_PID_I)); - drawFloat(thermalManager.temp_bed.pid.i(), row, false, 100); + Draw_Menu_Item(row, ICON_Version, F("Ki Value")); + Draw_Float(thermalManager.temp_bed.pid.i(), row, false, 100); } else - modifyValue(thermalManager.temp_bed.pid.Ki, 0, 5000, 100, []{ thermalManager.temp_bed.pid.reset(); }); + Modify_Value(thermalManager.temp_bed.pid.Ki, 0, 5000, 100, thermalManager.updatePID); break; case BEDPID_KD: if (draw) { - drawMenuItem(row, ICON_Version, GET_TEXT_F(MSG_PID_D)); - drawFloat(thermalManager.temp_bed.pid.d(), row, false, 100); + Draw_Menu_Item(row, ICON_Version, F("Kd Value")); + Draw_Float(thermalManager.temp_bed.pid.d(), row, false, 100); } else - modifyValue(thermalManager.temp_bed.pid.Kd, 0, 5000, 100, []{ thermalManager.temp_bed.pid.reset(); }); + Modify_Value(thermalManager.temp_bed.pid.Kd, 0, 5000, 100, thermalManager.updatePID); break; } break; - #endif // PIDTEMPBED - - #if ANY(MPC_EDIT_MENU, MPC_AUTOTUNE_MENU) - case ID_MPC: - - #define MPCMENU_BACK 0 - #define MPCMENU_AUTOTUNE (MPCMENU_BACK + ENABLED(MPC_AUTOTUNE_MENU)) - #define MPCMENU_HEATER_POWER (MPCMENU_AUTOTUNE + ENABLED(MPC_EDIT_MENU)) - #define MPCMENU_BLOCK_HEAT_CAPACITY (MPCMENU_HEATER_POWER + ENABLED(MPC_EDIT_MENU)) - #define MPCMENU_SENSOR_RESPONSIVENESS (MPCMENU_BLOCK_HEAT_CAPACITY + ENABLED(MPC_EDIT_MENU)) - #define MPCMENU_AMBIENT_XFER_COEFF (MPCMENU_SENSOR_RESPONSIVENESS + ENABLED(MPC_EDIT_MENU)) - #define MPCMENU_AMBIENT_XFER_COEFF_FAN (MPCMENU_AMBIENT_XFER_COEFF + ALL(MPC_EDIT_MENU, MPC_INCLUDE_FAN)) - #define MPCMENU_TOTAL MPCMENU_AMBIENT_XFER_COEFF_FAN - - switch (item) { - case MPCMENU_BACK: - if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); - else - drawMenu(ID_TempMenu, TEMP_MPC); - break; - - #if ENABLED(MPC_AUTOTUNE_MENU) - case MPCMENU_AUTOTUNE: - if (draw) - drawMenuItem(row, ICON_HotendTemp, GET_TEXT_F(MSG_PID_AUTOTUNE)); - else { - popupHandler(Popup_MPCWait); - thermalManager.MPC_autotune(active_extruder, Temperature::MPCTuningType::AUTO); - redrawMenu(); - } - break; - #endif - - #if ENABLED(MPC_EDIT_MENU) - case MPCMENU_HEATER_POWER: - if (draw) { - drawMenuItem(row, ICON_Version, GET_TEXT_F(MSG_MPC_POWER)); - drawFloat(thermalManager.temp_hotend[0].mpc.heater_power, row, false, 1); - } - else - modifyValue(thermalManager.temp_hotend[0].mpc.heater_power, 1, 200, 1); - break; - - case MPCMENU_BLOCK_HEAT_CAPACITY: - if (draw) { - drawMenuItem(row, ICON_Version, GET_TEXT_F(MSG_MPC_BLOCK_HEAT_CAPACITY)); - drawFloat(thermalManager.temp_hotend[0].mpc.block_heat_capacity, row, false, 100); - } - else - modifyValue(thermalManager.temp_hotend[0].mpc.block_heat_capacity, 0, 40, 100); - break; - - case MPCMENU_SENSOR_RESPONSIVENESS: - if (draw) { - drawMenuItem(row, ICON_Version, GET_TEXT_F(MSG_SENSOR_RESPONSIVENESS)); - drawFloat(thermalManager.temp_hotend[0].mpc.sensor_responsiveness, row, false, 10000); - } - else - modifyValue(thermalManager.temp_hotend[0].mpc.sensor_responsiveness, 0, 1, 10000); - break; - - case MPCMENU_AMBIENT_XFER_COEFF: - if (draw) { - drawMenuItem(row, ICON_Version, GET_TEXT_F(MSG_MPC_AMBIENT_XFER_COEFF)); - drawFloat(thermalManager.temp_hotend[0].mpc.ambient_xfer_coeff_fan0, row, false, 10000); - } - else - modifyValue(thermalManager.temp_hotend[0].mpc.ambient_xfer_coeff_fan0, 0, 1, 10000); - break; - - #if ENABLED(MPC_INCLUDE_FAN) - case MPCMENU_AMBIENT_XFER_COEFF_FAN: { - static float fan255_adjustment; - if (draw) { - drawMenuItem(row, ICON_Version, GET_TEXT_F(MSG_MPC_AMBIENT_XFER_COEFF_FAN)); - fan255_adjustment = thermalManager.temp_hotend[0].fanCoefficient(); - drawFloat(fan255_adjustment, row, false, 10000); - } - else - modifyValue(fan255_adjustment, 0, 1, 10000, []{ thermalManager.temp_hotend[0].applyFanAdjustment(fan255_adjustment); }); - } break; - #endif - - #endif // MPC_EDIT_MENU - } - break; - - #endif // MPC_EDIT_MENU || MPC_AUTOTUNE_MENU + #endif // HAS_HEATED_BED #if HAS_PREHEAT - #define _PREHEAT_SUBMENU_CASE(N) case ID_Preheat##N: preheat_submenu((N) - 1, item, TEMP_PREHEAT##N); break; + #define _PREHEAT_SUBMENU_CASE(N) case Preheat##N: preheat_submenu((N) - 1, item, TEMP_PREHEAT##N); break; REPEAT_1(PREHEAT_COUNT, _PREHEAT_SUBMENU_CASE) #endif - case ID_Motion: + case Motion: #define MOTION_BACK 0 #define MOTION_HOMEOFFSETS (MOTION_BACK + 1) #define MOTION_SPEED (MOTION_HOMEOFFSETS + 1) #define MOTION_ACCEL (MOTION_SPEED + 1) - #define MOTION_JERK (MOTION_ACCEL + ENABLED(CLASSIC_JERK)) + #define MOTION_JERK (MOTION_ACCEL + ENABLED(HAS_CLASSIC_JERK)) #define MOTION_STEPS (MOTION_JERK + 1) #define MOTION_FLOW (MOTION_STEPS + ENABLED(HAS_HOTEND)) - #define MOTION_LA (MOTION_FLOW + ENABLED(LIN_ADVANCE)) - #define MOTION_TOTAL MOTION_LA + #define MOTION_TOTAL MOTION_FLOW switch (item) { case MOTION_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_Control, CONTROL_MOTION); + Draw_Menu(Control, CONTROL_MOTION); break; case MOTION_HOMEOFFSETS: if (draw) - drawMenuItem(row, ICON_SetHome, GET_TEXT_F(MSG_SET_HOME_OFFSETS), nullptr, true); + Draw_Menu_Item(row, ICON_SetHome, F("Home Offsets"), nullptr, true); else - drawMenu(ID_HomeOffsets); + Draw_Menu(HomeOffsets); break; case MOTION_SPEED: if (draw) - drawMenuItem(row, ICON_MaxSpeed, GET_TEXT_F(MSG_MAX_SPEED), nullptr, true); + Draw_Menu_Item(row, ICON_MaxSpeed, F("Max Speed"), nullptr, true); else - drawMenu(ID_MaxSpeed); + Draw_Menu(MaxSpeed); break; case MOTION_ACCEL: if (draw) - drawMenuItem(row, ICON_MaxAccelerated, GET_TEXT_F(MSG_ACCELERATION), nullptr, true); + Draw_Menu_Item(row, ICON_MaxAccelerated, F("Max Acceleration"), nullptr, true); else - drawMenu(ID_MaxAcceleration); + Draw_Menu(MaxAcceleration); break; - - #if ENABLED(CLASSIC_JERK) + #if HAS_CLASSIC_JERK case MOTION_JERK: if (draw) - drawMenuItem(row, ICON_MaxJerk, GET_TEXT_F(MSG_JERK), nullptr, true); + Draw_Menu_Item(row, ICON_MaxJerk, F("Max Jerk"), nullptr, true); else - drawMenu(ID_MaxJerk); + Draw_Menu(MaxJerk); break; #endif - - #if ENABLED(EDITABLE_STEPS_PER_UNIT) - case MOTION_STEPS: - if (draw) - drawMenuItem(row, ICON_Step, GET_TEXT_F(MSG_STEPS_PER_MM), nullptr, true); - else - drawMenu(ID_Steps); - break; - #endif - + case MOTION_STEPS: + if (draw) + Draw_Menu_Item(row, ICON_Step, F("Steps/mm"), nullptr, true); + else + Draw_Menu(Steps); + break; #if HAS_HOTEND case MOTION_FLOW: if (draw) { - drawMenuItem(row, ICON_Speed, GET_TEXT_F(MSG_FLOW)); - drawFloat(planner.flow_percentage[0], row, false, 1); + Draw_Menu_Item(row, ICON_Speed, F("Flow Rate")); + Draw_Float(planner.flow_percentage[0], row, false, 1); } else - modifyValue(planner.flow_percentage[0], MIN_FLOW_RATE, MAX_FLOW_RATE, 1, []{ planner.refresh_e_factor(0); }); - break; - #endif - - #if ENABLED(LIN_ADVANCE) - case MOTION_LA: - if (draw) { - drawMenuItem(row, ICON_MaxAccelerated, GET_TEXT_F(MSG_ADVANCE_K)); - drawFloat(planner.extruder_advance_K[0], row, false, 100); - } - else - modifyValue(planner.extruder_advance_K[0], 0, 10, 100); + Modify_Value(planner.flow_percentage[0], MIN_FLOW_RATE, MAX_FLOW_RATE, 1); break; #endif } break; - case ID_HomeOffsets: + case HomeOffsets: #define HOMEOFFSETS_BACK 0 #define HOMEOFFSETS_XOFFSET (HOMEOFFSETS_BACK + 1) @@ -2417,29 +2311,29 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case HOMEOFFSETS_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_Motion, MOTION_HOMEOFFSETS); + Draw_Menu(Motion, MOTION_HOMEOFFSETS); break; case HOMEOFFSETS_XOFFSET: if (draw) { - drawMenuItem(row, ICON_StepX, GET_TEXT_F(MSG_HOME_OFFSET_X)); - drawFloat(home_offset.x, row, false, 100); + Draw_Menu_Item(row, ICON_StepX, F("X Offset")); + Draw_Float(home_offset.x, row, false, 100); } else - modifyValue(home_offset.x, -MAX_XY_OFFSET, MAX_XY_OFFSET, 100); + Modify_Value(home_offset.x, -MAX_XY_OFFSET, MAX_XY_OFFSET, 100); break; case HOMEOFFSETS_YOFFSET: if (draw) { - drawMenuItem(row, ICON_StepY, GET_TEXT_F(MSG_HOME_OFFSET_Y)); - drawFloat(home_offset.y, row, false, 100); + Draw_Menu_Item(row, ICON_StepY, F("Y Offset")); + Draw_Float(home_offset.y, row, false, 100); } else - modifyValue(home_offset.y, -MAX_XY_OFFSET, MAX_XY_OFFSET, 100); + Modify_Value(home_offset.y, -MAX_XY_OFFSET, MAX_XY_OFFSET, 100); break; } break; - case ID_MaxSpeed: + case MaxSpeed: #define SPEED_BACK 0 #define SPEED_X (SPEED_BACK + 1) @@ -2451,239 +2345,214 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case SPEED_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_Motion, MOTION_SPEED); + Draw_Menu(Motion, MOTION_SPEED); + break; + case SPEED_X: + if (draw) { + Draw_Menu_Item(row, ICON_MaxSpeedX, F("X Axis")); + Draw_Float(planner.settings.max_feedrate_mm_s[X_AXIS], row, false, 1); + } + else + Modify_Value(planner.settings.max_feedrate_mm_s[X_AXIS], 0, default_max_feedrate[X_AXIS] * 2, 1); break; - #if HAS_X_AXIS - case SPEED_X: - if (draw) { - drawMenuItem(row, ICON_MaxSpeedX, GET_TEXT_F(MSG_VMAX_A)); - drawFloat(planner.settings.max_feedrate_mm_s[X_AXIS], row, false, FEEDRATE_UNIT); - } - else - modifyValue(planner.settings.max_feedrate_mm_s[X_AXIS], min_feedrate_edit_values.x, max_feedrate_edit_values.x, FEEDRATE_UNIT); - break; - #endif #if HAS_Y_AXIS case SPEED_Y: if (draw) { - drawMenuItem(row, ICON_MaxSpeedY, GET_TEXT_F(MSG_VMAX_B)); - drawFloat(planner.settings.max_feedrate_mm_s[Y_AXIS], row, false, FEEDRATE_UNIT); + Draw_Menu_Item(row, ICON_MaxSpeedY, F("Y Axis")); + Draw_Float(planner.settings.max_feedrate_mm_s[Y_AXIS], row, false, 1); } else - modifyValue(planner.settings.max_feedrate_mm_s[Y_AXIS], min_feedrate_edit_values.y, max_feedrate_edit_values.y, FEEDRATE_UNIT); + Modify_Value(planner.settings.max_feedrate_mm_s[Y_AXIS], 0, default_max_feedrate[Y_AXIS] * 2, 1); break; #endif #if HAS_Z_AXIS case SPEED_Z: if (draw) { - drawMenuItem(row, ICON_MaxSpeedZ, GET_TEXT_F(MSG_VMAX_C)); - drawFloat(planner.settings.max_feedrate_mm_s[Z_AXIS], row, false, FEEDRATE_UNIT); + Draw_Menu_Item(row, ICON_MaxSpeedZ, F("Z Axis")); + Draw_Float(planner.settings.max_feedrate_mm_s[Z_AXIS], row, false, 1); } else - modifyValue(planner.settings.max_feedrate_mm_s[Z_AXIS], min_feedrate_edit_values.z, max_feedrate_edit_values.z, FEEDRATE_UNIT); + Modify_Value(planner.settings.max_feedrate_mm_s[Z_AXIS], 0, default_max_feedrate[Z_AXIS] * 2, 1); break; #endif #if HAS_HOTEND case SPEED_E: if (draw) { - drawMenuItem(row, ICON_MaxSpeedE, GET_TEXT_F(MSG_VMAX_E)); - drawFloat(planner.settings.max_feedrate_mm_s[E_AXIS], row, false, FEEDRATE_UNIT); + Draw_Menu_Item(row, ICON_MaxSpeedE, F("Extruder")); + Draw_Float(planner.settings.max_feedrate_mm_s[E_AXIS], row, false, 1); } else - modifyValue(planner.settings.max_feedrate_mm_s[E_AXIS], min_feedrate_edit_values.e, max_feedrate_edit_values.e, FEEDRATE_UNIT); + Modify_Value(planner.settings.max_feedrate_mm_s[E_AXIS], 0, default_max_feedrate[E_AXIS] * 2, 1); break; #endif } break; - case ID_MaxAcceleration: + case MaxAcceleration: #define ACCEL_BACK 0 - #define ACCEL_X (ACCEL_BACK + ENABLED(HAS_X_AXIS)) - #define ACCEL_Y (ACCEL_X + ENABLED(HAS_Y_AXIS)) - #define ACCEL_Z (ACCEL_Y + ENABLED(HAS_Z_AXIS)) + #define ACCEL_X (ACCEL_BACK + 1) + #define ACCEL_Y (ACCEL_X + 1) + #define ACCEL_Z (ACCEL_Y + 1) #define ACCEL_E (ACCEL_Z + ENABLED(HAS_HOTEND)) #define ACCEL_TOTAL ACCEL_E switch (item) { case ACCEL_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_Motion, MOTION_ACCEL); + Draw_Menu(Motion, MOTION_ACCEL); + break; + case ACCEL_X: + if (draw) { + Draw_Menu_Item(row, ICON_MaxAccX, F("X Axis")); + Draw_Float(planner.settings.max_acceleration_mm_per_s2[X_AXIS], row, false, 1); + } + else + Modify_Value(planner.settings.max_acceleration_mm_per_s2[X_AXIS], 0, default_max_acceleration[X_AXIS] * 2, 1); + break; + case ACCEL_Y: + if (draw) { + Draw_Menu_Item(row, ICON_MaxAccY, F("Y Axis")); + Draw_Float(planner.settings.max_acceleration_mm_per_s2[Y_AXIS], row, false, 1); + } + else + Modify_Value(planner.settings.max_acceleration_mm_per_s2[Y_AXIS], 0, default_max_acceleration[Y_AXIS] * 2, 1); + break; + case ACCEL_Z: + if (draw) { + Draw_Menu_Item(row, ICON_MaxAccZ, F("Z Axis")); + Draw_Float(planner.settings.max_acceleration_mm_per_s2[Z_AXIS], row, false, 1); + } + else + Modify_Value(planner.settings.max_acceleration_mm_per_s2[Z_AXIS], 0, default_max_acceleration[Z_AXIS] * 2, 1); break; - #if HAS_X_AXIS - case ACCEL_X: - if (draw) { - drawMenuItem(row, ICON_MaxAccX, GET_TEXT_F(MSG_AMAX_A)); - drawFloat(planner.settings.max_acceleration_mm_per_s2[X_AXIS], row, false, ACCELERATION_UNIT); - } - else - modifyValue(planner.settings.max_acceleration_mm_per_s2[X_AXIS], min_acceleration_edit_values.x, max_acceleration_edit_values.x, ACCELERATION_UNIT); - break; - #endif - #if HAS_Y_AXIS - case ACCEL_Y: - if (draw) { - drawMenuItem(row, ICON_MaxAccY, GET_TEXT_F(MSG_AMAX_B)); - drawFloat(planner.settings.max_acceleration_mm_per_s2[Y_AXIS], row, false, ACCELERATION_UNIT); - } - else - modifyValue(planner.settings.max_acceleration_mm_per_s2[Y_AXIS], min_acceleration_edit_values.y, max_acceleration_edit_values.y, ACCELERATION_UNIT); - break; - #endif - #if HAS_Z_AXIS - case ACCEL_Z: - if (draw) { - drawMenuItem(row, ICON_MaxAccZ, GET_TEXT_F(MSG_AMAX_C)); - drawFloat(planner.settings.max_acceleration_mm_per_s2[Z_AXIS], row, false, ACCELERATION_UNIT); - } - else - modifyValue(planner.settings.max_acceleration_mm_per_s2[Z_AXIS], min_acceleration_edit_values.z, max_acceleration_edit_values.z, ACCELERATION_UNIT); - break; - #endif #if HAS_HOTEND case ACCEL_E: if (draw) { - drawMenuItem(row, ICON_MaxAccE, GET_TEXT_F(MSG_AMAX_E)); - drawFloat(planner.settings.max_acceleration_mm_per_s2[E_AXIS], row, false, ACCELERATION_UNIT); + Draw_Menu_Item(row, ICON_MaxAccE, F("Extruder")); + Draw_Float(planner.settings.max_acceleration_mm_per_s2[E_AXIS], row, false, 1); } else - modifyValue(planner.settings.max_acceleration_mm_per_s2[E_AXIS], min_acceleration_edit_values.e, max_acceleration_edit_values.e, ACCELERATION_UNIT); + Modify_Value(planner.settings.max_acceleration_mm_per_s2[E_AXIS], 0, default_max_acceleration[E_AXIS] * 2, 1); break; #endif } break; - #if ENABLED(CLASSIC_JERK) - case ID_MaxJerk: + #if HAS_CLASSIC_JERK + case MaxJerk: #define JERK_BACK 0 - #define JERK_X (JERK_BACK + ENABLED(HAS_X_AXIS)) - #define JERK_Y (JERK_X + ENABLED(HAS_Y_AXIS)) - #define JERK_Z (JERK_Y + ENABLED(HAS_Z_AXIS)) + #define JERK_X (JERK_BACK + 1) + #define JERK_Y (JERK_X + 1) + #define JERK_Z (JERK_Y + 1) #define JERK_E (JERK_Z + ENABLED(HAS_HOTEND)) #define JERK_TOTAL JERK_E switch (item) { case JERK_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_Motion, MOTION_JERK); + Draw_Menu(Motion, MOTION_JERK); + break; + case JERK_X: + if (draw) { + Draw_Menu_Item(row, ICON_MaxSpeedJerkX, F("X Axis")); + Draw_Float(planner.max_jerk[X_AXIS], row, false, 10); + } + else + Modify_Value(planner.max_jerk[X_AXIS], 0, default_max_jerk[X_AXIS] * 2, 10); + break; + case JERK_Y: + if (draw) { + Draw_Menu_Item(row, ICON_MaxSpeedJerkY, F("Y Axis")); + Draw_Float(planner.max_jerk[Y_AXIS], row, false, 10); + } + else + Modify_Value(planner.max_jerk[Y_AXIS], 0, default_max_jerk[Y_AXIS] * 2, 10); + break; + case JERK_Z: + if (draw) { + Draw_Menu_Item(row, ICON_MaxSpeedJerkZ, F("Z Axis")); + Draw_Float(planner.max_jerk[Z_AXIS], row, false, 10); + } + else + Modify_Value(planner.max_jerk[Z_AXIS], 0, default_max_jerk[Z_AXIS] * 2, 10); break; - #if HAS_X_AXIS - case JERK_X: - if (draw) { - drawMenuItem(row, ICON_MaxSpeedJerkX, GET_TEXT_F(MSG_VA_JERK)); - drawFloat(planner.max_jerk.x, row, false, JERK_UNIT); - } - else - modifyValue(planner.max_jerk.x, min_jerk_edit_values.x, max_jerk_edit_values.x, JERK_UNIT); - break; - #endif - #if HAS_Y_AXIS - case JERK_Y: - if (draw) { - drawMenuItem(row, ICON_MaxSpeedJerkY, GET_TEXT_F(MSG_VB_JERK)); - drawFloat(planner.max_jerk.y, row, false, JERK_UNIT); - } - else - modifyValue(planner.max_jerk.y, min_jerk_edit_values.y, max_jerk_edit_values.y, JERK_UNIT); - break; - #endif - #if HAS_Z_AXIS - case JERK_Z: - if (draw) { - drawMenuItem(row, ICON_MaxSpeedJerkZ, GET_TEXT_F(MSG_VC_JERK)); - drawFloat(planner.max_jerk.z, row, false, JERK_UNIT); - } - else - modifyValue(planner.max_jerk.z, min_jerk_edit_values.z, max_jerk_edit_values.z, JERK_UNIT); - break; - #endif #if HAS_HOTEND case JERK_E: if (draw) { - drawMenuItem(row, ICON_MaxSpeedJerkE, GET_TEXT_F(MSG_VE_JERK)); - drawFloat(planner.max_jerk.e, row, false, JERK_UNIT); + Draw_Menu_Item(row, ICON_MaxSpeedJerkE, F("Extruder")); + Draw_Float(planner.max_jerk[E_AXIS], row, false, 10); } else - modifyValue(planner.max_jerk.e, min_jerk_edit_values.e, max_jerk_edit_values.e, JERK_UNIT); + Modify_Value(planner.max_jerk[E_AXIS], 0, default_max_jerk[E_AXIS] * 2, 10); break; #endif } break; #endif + case Steps: - #if ENABLED(EDITABLE_STEPS_PER_UNIT) + #define STEPS_BACK 0 + #define STEPS_X (STEPS_BACK + 1) + #define STEPS_Y (STEPS_X + 1) + #define STEPS_Z (STEPS_Y + 1) + #define STEPS_E (STEPS_Z + ENABLED(HAS_HOTEND)) + #define STEPS_TOTAL STEPS_E - case ID_Steps: - - #define STEPS_BACK 0 - #define STEPS_X (STEPS_BACK + ENABLED(HAS_X_AXIS)) - #define STEPS_Y (STEPS_X + ENABLED(HAS_Y_AXIS)) - #define STEPS_Z (STEPS_Y + ENABLED(HAS_Z_AXIS)) - #define STEPS_E (STEPS_Z + ENABLED(HAS_HOTEND)) - #define STEPS_TOTAL STEPS_E - - switch (item) { - case STEPS_BACK: - if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + switch (item) { + case STEPS_BACK: + if (draw) + Draw_Menu_Item(row, ICON_Back, F("Back")); + else + Draw_Menu(Motion, MOTION_STEPS); + break; + case STEPS_X: + if (draw) { + Draw_Menu_Item(row, ICON_StepX, F("X Axis")); + Draw_Float(planner.settings.axis_steps_per_mm[X_AXIS], row, false, 10); + } + else + Modify_Value(planner.settings.axis_steps_per_mm[X_AXIS], 0, default_steps[X_AXIS] * 2, 10); + break; + case STEPS_Y: + if (draw) { + Draw_Menu_Item(row, ICON_StepY, F("Y Axis")); + Draw_Float(planner.settings.axis_steps_per_mm[Y_AXIS], row, false, 10); + } + else + Modify_Value(planner.settings.axis_steps_per_mm[Y_AXIS], 0, default_steps[Y_AXIS] * 2, 10); + break; + case STEPS_Z: + if (draw) { + Draw_Menu_Item(row, ICON_StepZ, F("Z Axis")); + Draw_Float(planner.settings.axis_steps_per_mm[Z_AXIS], row, false, 10); + } + else + Modify_Value(planner.settings.axis_steps_per_mm[Z_AXIS], 0, default_steps[Z_AXIS] * 2, 10); + break; + #if HAS_HOTEND + case STEPS_E: + if (draw) { + Draw_Menu_Item(row, ICON_StepE, F("Extruder")); + Draw_Float(planner.settings.axis_steps_per_mm[E_AXIS], row, false, 10); + } else - drawMenu(ID_Motion, MOTION_STEPS); + Modify_Value(planner.settings.axis_steps_per_mm[E_AXIS], 0, 1000, 10); break; - #if HAS_X_AXIS - case STEPS_X: - if (draw) { - drawMenuItem(row, ICON_StepX, GET_TEXT_F(MSG_A_STEPS)); - drawFloat(planner.settings.axis_steps_per_mm[X_AXIS], row, false, STEPS_UNIT); - } - else - modifyValue(planner.settings.axis_steps_per_mm[X_AXIS], min_steps_edit_values.x, max_steps_edit_values.x, STEPS_UNIT); - break; - #endif - #if HAS_Y_AXIS - case STEPS_Y: - if (draw) { - drawMenuItem(row, ICON_StepY, GET_TEXT_F(MSG_B_STEPS)); - drawFloat(planner.settings.axis_steps_per_mm[Y_AXIS], row, false, STEPS_UNIT); - } - else - modifyValue(planner.settings.axis_steps_per_mm[Y_AXIS], min_steps_edit_values.y, max_steps_edit_values.y, STEPS_UNIT); - break; - #endif - #if HAS_Z_AXIS - case STEPS_Z: - if (draw) { - drawMenuItem(row, ICON_StepZ, GET_TEXT_F(MSG_C_STEPS)); - drawFloat(planner.settings.axis_steps_per_mm[Z_AXIS], row, false, STEPS_UNIT); - } - else - modifyValue(planner.settings.axis_steps_per_mm[Z_AXIS], min_steps_edit_values.z, max_steps_edit_values.z, STEPS_UNIT); - break; - #endif - #if HAS_HOTEND - case STEPS_E: - if (draw) { - drawMenuItem(row, ICON_StepE, GET_TEXT_F(MSG_E_STEPS)); - drawFloat(planner.settings.axis_steps_per_mm[E_AXIS], row, false, STEPS_UNIT); - } - else - modifyValue(planner.settings.axis_steps_per_mm[E_AXIS], min_steps_edit_values.e, max_steps_edit_values.e, STEPS_UNIT); - break; - #endif - } - break; + #endif + } + break; - #endif // EDITABLE_STEPS_PER_UNIT - - case ID_Visual: + case Visual: #define VISUAL_BACK 0 #define VISUAL_BACKLIGHT (VISUAL_BACK + 1) @@ -2695,44 +2564,44 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case VISUAL_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_Control, CONTROL_VISUAL); + Draw_Menu(Control, CONTROL_VISUAL); break; case VISUAL_BACKLIGHT: if (draw) - drawMenuItem(row, ICON_Brightness, GET_TEXT_F(MSG_BRIGHTNESS_OFF)); + Draw_Menu_Item(row, ICON_Brightness, F("Display Off")); else ui.set_brightness(0); break; case VISUAL_BRIGHTNESS: if (draw) { - drawMenuItem(row, ICON_Brightness, GET_TEXT_F(MSG_BRIGHTNESS)); - drawFloat(ui.brightness, row, false, 1); + Draw_Menu_Item(row, ICON_Brightness, F("LCD Brightness")); + Draw_Float(ui.brightness, row, false, 1); } else - modifyValue(ui.brightness, LCD_BRIGHTNESS_MIN, LCD_BRIGHTNESS_MAX, 1, ui.refresh_brightness); + Modify_Value(ui.brightness, LCD_BRIGHTNESS_MIN, LCD_BRIGHTNESS_MAX, 1, ui.refresh_brightness); break; case VISUAL_TIME_FORMAT: if (draw) { - drawMenuItem(row, ICON_PrintTime, F("Progress as __h__m")); - drawCheckbox(row, eeprom_settings.time_format_textual); + Draw_Menu_Item(row, ICON_PrintTime, F("Progress as __h__m")); + Draw_Checkbox(row, eeprom_settings.time_format_textual); } else { - eeprom_settings.time_format_textual ^= true; - drawCheckbox(row, eeprom_settings.time_format_textual); + eeprom_settings.time_format_textual = !eeprom_settings.time_format_textual; + Draw_Checkbox(row, eeprom_settings.time_format_textual); } break; case VISUAL_COLOR_THEMES: if (draw) - drawMenuItem(row, ICON_MaxSpeed, F("UI Color Settings"), nullptr, true); + Draw_Menu_Item(row, ICON_MaxSpeed, F("UI Color Settings"), nullptr, true); else - drawMenu(ID_ColorSettings); + Draw_Menu(ColorSettings); break; } break; - case ID_ColorSettings: + case ColorSettings: #define COLORSETTINGS_BACK 0 #define COLORSETTINGS_CURSOR (COLORSETTINGS_BACK + 1) @@ -2751,134 +2620,133 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case COLORSETTINGS_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_Visual, VISUAL_COLOR_THEMES); + Draw_Menu(Visual, VISUAL_COLOR_THEMES); break; case COLORSETTINGS_CURSOR: if (draw) { - drawMenuItem(row, ICON_MaxSpeed, F("Cursor")); - drawOption(eeprom_settings.cursor_color, color_names, row, false, true); + Draw_Menu_Item(row, ICON_MaxSpeed, F("Cursor")); + Draw_Option(eeprom_settings.cursor_color, color_names, row, false, true); } else - modifyOption(eeprom_settings.cursor_color, color_names, Custom_Colors); + Modify_Option(eeprom_settings.cursor_color, color_names, Custom_Colors); break; case COLORSETTINGS_SPLIT_LINE: if (draw) { - drawMenuItem(row, ICON_MaxSpeed, F("Menu Split Line")); - drawOption(eeprom_settings.menu_split_line, color_names, row, false, true); + Draw_Menu_Item(row, ICON_MaxSpeed, F("Menu Split Line")); + Draw_Option(eeprom_settings.menu_split_line, color_names, row, false, true); } else - modifyOption(eeprom_settings.menu_split_line, color_names, Custom_Colors); + Modify_Option(eeprom_settings.menu_split_line, color_names, Custom_Colors); break; case COLORSETTINGS_MENU_TOP_TXT: if (draw) { - drawMenuItem(row, ICON_MaxSpeed, F("Menu Header Text")); - drawOption(eeprom_settings.menu_top_txt, color_names, row, false, true); + Draw_Menu_Item(row, ICON_MaxSpeed, F("Menu Header Text")); + Draw_Option(eeprom_settings.menu_top_txt, color_names, row, false, true); } else - modifyOption(eeprom_settings.menu_top_txt, color_names, Custom_Colors); + Modify_Option(eeprom_settings.menu_top_txt, color_names, Custom_Colors); break; case COLORSETTINGS_MENU_TOP_BG: if (draw) { - drawMenuItem(row, ICON_MaxSpeed, F("Menu Header Bg")); - drawOption(eeprom_settings.menu_top_bg, color_names, row, false, true); + Draw_Menu_Item(row, ICON_MaxSpeed, F("Menu Header Bg")); + Draw_Option(eeprom_settings.menu_top_bg, color_names, row, false, true); } else - modifyOption(eeprom_settings.menu_top_bg, color_names, Custom_Colors); + Modify_Option(eeprom_settings.menu_top_bg, color_names, Custom_Colors); break; case COLORSETTINGS_HIGHLIGHT_BORDER: if (draw) { - drawMenuItem(row, ICON_MaxSpeed, F("Highlight Box")); - drawOption(eeprom_settings.highlight_box, color_names, row, false, true); + Draw_Menu_Item(row, ICON_MaxSpeed, F("Highlight Box")); + Draw_Option(eeprom_settings.highlight_box, color_names, row, false, true); } else - modifyOption(eeprom_settings.highlight_box, color_names, Custom_Colors); + Modify_Option(eeprom_settings.highlight_box, color_names, Custom_Colors); break; case COLORSETTINGS_PROGRESS_PERCENT: if (draw) { - drawMenuItem(row, ICON_MaxSpeed, F("Progress Percent")); - drawOption(eeprom_settings.progress_percent, color_names, row, false, true); + Draw_Menu_Item(row, ICON_MaxSpeed, F("Progress Percent")); + Draw_Option(eeprom_settings.progress_percent, color_names, row, false, true); } else - modifyOption(eeprom_settings.progress_percent, color_names, Custom_Colors); + Modify_Option(eeprom_settings.progress_percent, color_names, Custom_Colors); break; case COLORSETTINGS_PROGRESS_TIME: if (draw) { - drawMenuItem(row, ICON_MaxSpeed, F("Progress Time")); - drawOption(eeprom_settings.progress_time, color_names, row, false, true); + Draw_Menu_Item(row, ICON_MaxSpeed, F("Progress Time")); + Draw_Option(eeprom_settings.progress_time, color_names, row, false, true); } else - modifyOption(eeprom_settings.progress_time, color_names, Custom_Colors); + Modify_Option(eeprom_settings.progress_time, color_names, Custom_Colors); break; case COLORSETTINGS_PROGRESS_STATUS_BAR: if (draw) { - drawMenuItem(row, ICON_MaxSpeed, F("Status Bar Text")); - drawOption(eeprom_settings.status_bar_text, color_names, row, false, true); + Draw_Menu_Item(row, ICON_MaxSpeed, F("Status Bar Text")); + Draw_Option(eeprom_settings.status_bar_text, color_names, row, false, true); } else - modifyOption(eeprom_settings.status_bar_text, color_names, Custom_Colors); + Modify_Option(eeprom_settings.status_bar_text, color_names, Custom_Colors); break; case COLORSETTINGS_PROGRESS_STATUS_AREA: if (draw) { - drawMenuItem(row, ICON_MaxSpeed, F("Status Area Text")); - drawOption(eeprom_settings.status_area_text, color_names, row, false, true); + Draw_Menu_Item(row, ICON_MaxSpeed, F("Status Area Text")); + Draw_Option(eeprom_settings.status_area_text, color_names, row, false, true); } else - modifyOption(eeprom_settings.status_area_text, color_names, Custom_Colors); + Modify_Option(eeprom_settings.status_area_text, color_names, Custom_Colors); break; case COLORSETTINGS_PROGRESS_COORDINATES: if (draw) { - drawMenuItem(row, ICON_MaxSpeed, F("Coordinates Text")); - drawOption(eeprom_settings.coordinates_text, color_names, row, false, true); + Draw_Menu_Item(row, ICON_MaxSpeed, F("Coordinates Text")); + Draw_Option(eeprom_settings.coordinates_text, color_names, row, false, true); } else - modifyOption(eeprom_settings.coordinates_text, color_names, Custom_Colors); + Modify_Option(eeprom_settings.coordinates_text, color_names, Custom_Colors); break; case COLORSETTINGS_PROGRESS_COORDINATES_LINE: if (draw) { - drawMenuItem(row, ICON_MaxSpeed, F("Coordinates Line")); - drawOption(eeprom_settings.coordinates_split_line, color_names, row, false, true); + Draw_Menu_Item(row, ICON_MaxSpeed, F("Coordinates Line")); + Draw_Option(eeprom_settings.coordinates_split_line, color_names, row, false, true); } else - modifyOption(eeprom_settings.coordinates_split_line, color_names, Custom_Colors); + Modify_Option(eeprom_settings.coordinates_split_line, color_names, Custom_Colors); break; } // switch (item) break; - case ID_Advanced: + case Advanced: #define ADVANCED_BACK 0 #define ADVANCED_BEEPER (ADVANCED_BACK + ENABLED(SOUND_MENU_ITEM)) #define ADVANCED_PROBE (ADVANCED_BEEPER + ENABLED(HAS_BED_PROBE)) - #define ADVANCED_TMC (ADVANCED_PROBE + ENABLED(HAS_TRINAMIC_CONFIG)) - #define ADVANCED_CORNER (ADVANCED_TMC + 1) + #define ADVANCED_CORNER (ADVANCED_PROBE + 1) #define ADVANCED_LA (ADVANCED_CORNER + ENABLED(LIN_ADVANCE)) #define ADVANCED_LOAD (ADVANCED_LA + ENABLED(ADVANCED_PAUSE_FEATURE)) #define ADVANCED_UNLOAD (ADVANCED_LOAD + ENABLED(ADVANCED_PAUSE_FEATURE)) #define ADVANCED_COLD_EXTRUDE (ADVANCED_UNLOAD + ENABLED(PREVENT_COLD_EXTRUSION)) #define ADVANCED_FILSENSORENABLED (ADVANCED_COLD_EXTRUDE + ENABLED(FILAMENT_RUNOUT_SENSOR)) - #define ADVANCED_FILSENSORDISTANCE (ADVANCED_FILSENSORENABLED + ENABLED(HAS_FILAMENT_RUNOUT_DISTANCE)) + #define ADVANCED_FILSENSORDISTANCE (ADVANCED_FILSENSORENABLED + 1) #define ADVANCED_POWER_LOSS (ADVANCED_FILSENSORDISTANCE + ENABLED(POWER_LOSS_RECOVERY)) #define ADVANCED_TOTAL ADVANCED_POWER_LOSS switch (item) { case ADVANCED_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_Control, CONTROL_ADVANCED); + Draw_Menu(Control, CONTROL_ADVANCED); break; #if ENABLED(SOUND_MENU_ITEM) case ADVANCED_BEEPER: if (draw) { - drawMenuItem(row, ICON_Version, GET_TEXT_F(MSG_SOUND)); - drawCheckbox(row, ui.sound_on); + Draw_Menu_Item(row, ICON_Version, F("LCD Beeper")); + Draw_Checkbox(row, ui.sound_on); } else { - ui.sound_on ^= true; - drawCheckbox(row, ui.sound_on); + ui.sound_on = !ui.sound_on; + Draw_Checkbox(row, ui.sound_on); } break; #endif @@ -2886,68 +2754,59 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra #if HAS_BED_PROBE case ADVANCED_PROBE: if (draw) - drawMenuItem(row, ICON_StepX, F("Probe"), nullptr, true); + Draw_Menu_Item(row, ICON_StepX, F("Probe"), nullptr, true); else - drawMenu(ID_ProbeMenu); - break; - #endif - - #if HAS_TRINAMIC_CONFIG - case ADVANCED_TMC: - if (draw) - drawMenuItem(row, ICON_Motion, F("TMC Drivers"), nullptr, true); - else - drawMenu(ID_TMCMenu); + Draw_Menu(ProbeMenu); break; #endif case ADVANCED_CORNER: if (draw) { - drawMenuItem(row, ICON_MaxAccelerated, F("Bed Screw Inset")); - drawFloat(corner_pos, row, false, 10); + Draw_Menu_Item(row, ICON_MaxAccelerated, F("Bed Screw Inset")); + Draw_Float(corner_pos, row, false, 10); } else - modifyValue(corner_pos, 1, 100, 10); + Modify_Value(corner_pos, 1, 100, 10); break; #if ENABLED(LIN_ADVANCE) case ADVANCED_LA: if (draw) { - drawMenuItem(row, ICON_MaxAccelerated, GET_TEXT_F(MSG_ADVANCE_K)); - drawFloat(planner.extruder_advance_K[0], row, false, 100); + Draw_Menu_Item(row, ICON_MaxAccelerated, F("Lin Advance K")); + Draw_Float(planner.extruder_advance_K[0], row, false, 100); } else - modifyValue(planner.extruder_advance_K[0], 0, 10, 100); + Modify_Value(planner.extruder_advance_K[0], 0, 10, 100); break; #endif - #if ENABLED(CONFIGURE_FILAMENT_CHANGE) + #if ENABLED(ADVANCED_PAUSE_FEATURE) case ADVANCED_LOAD: if (draw) { - drawMenuItem(row, ICON_WriteEEPROM, F("Load Length")); - drawFloat(fc_settings[0].load_length, row, false, 1); + Draw_Menu_Item(row, ICON_WriteEEPROM, F("Load Length")); + Draw_Float(fc_settings[0].load_length, row, false, 1); } else - modifyValue(fc_settings[0].load_length, 0, EXTRUDE_MAXLENGTH, 1); + Modify_Value(fc_settings[0].load_length, 0, EXTRUDE_MAXLENGTH, 1); break; case ADVANCED_UNLOAD: if (draw) { - drawMenuItem(row, ICON_ReadEEPROM, F("Unload Length")); - drawFloat(fc_settings[0].unload_length, row, false, 1); + Draw_Menu_Item(row, ICON_ReadEEPROM, F("Unload Length")); + Draw_Float(fc_settings[0].unload_length, row, false, 1); } else - modifyValue(fc_settings[0].unload_length, 0, EXTRUDE_MAXLENGTH, 1); + Modify_Value(fc_settings[0].unload_length, 0, EXTRUDE_MAXLENGTH, 1); break; - #endif // CONFIGURE_FILAMENT_CHANGE + #endif // ADVANCED_PAUSE_FEATURE #if ENABLED(PREVENT_COLD_EXTRUSION) case ADVANCED_COLD_EXTRUDE: if (draw) { - drawMenuItem(row, ICON_Cool, F("Min Extrusion T")); - drawFloat(thermalManager.extrude_min_temp, row, false, 1); + Draw_Menu_Item(row, ICON_Cool, F("Min Extrusion T")); + Draw_Float(thermalManager.extrude_min_temp, row, false, 1); } else { - modifyValue(thermalManager.extrude_min_temp, 0, MAX_E_TEMP, 1); + Modify_Value(thermalManager.extrude_min_temp, 0, MAX_E_TEMP, 1); thermalManager.allow_cold_extrude = (thermalManager.extrude_min_temp == 0); } break; @@ -2956,36 +2815,34 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra #if ENABLED(FILAMENT_RUNOUT_SENSOR) case ADVANCED_FILSENSORENABLED: if (draw) { - drawMenuItem(row, ICON_Extruder, GET_TEXT_F(MSG_RUNOUT_SENSOR)); - drawCheckbox(row, runout.enabled); + Draw_Menu_Item(row, ICON_Extruder, F("Filament Sensor")); + Draw_Checkbox(row, runout.enabled[0]); } else { - runout.enabled ^= true; - drawCheckbox(row, runout.enabled); + runout.enabled = !runout.enabled[0]; + Draw_Checkbox(row, runout.enabled[0]); } break; - #if ENABLED(HAS_FILAMENT_RUNOUT_DISTANCE) - case ADVANCED_FILSENSORDISTANCE: - if (draw) { - drawMenuItem(row, ICON_MaxAccE, GET_TEXT_F(MSG_RUNOUT_DISTANCE_MM)); - drawFloat(runout.runout_distance(), row, false, 10); - } - else - modifyValue(runout.runout_distance(), 0, 999, 10); - break; - #endif + case ADVANCED_FILSENSORDISTANCE: + if (draw) { + Draw_Menu_Item(row, ICON_MaxAccE, F("Runout Distance")); + Draw_Float(runout.runout_distance(), row, false, 10); + } + else + Modify_Value(runout.runout_distance(), 0, 999, 10); + break; #endif // FILAMENT_RUNOUT_SENSOR #if ENABLED(POWER_LOSS_RECOVERY) case ADVANCED_POWER_LOSS: if (draw) { - drawMenuItem(row, ICON_Motion, GET_TEXT_F(MSG_OUTAGE_RECOVERY)); - drawCheckbox(row, recovery.enabled); + Draw_Menu_Item(row, ICON_Motion, F("Power-loss recovery")); + Draw_Checkbox(row, recovery.enabled); } else { recovery.enable(!recovery.enabled); - drawCheckbox(row, recovery.enabled); + Draw_Checkbox(row, recovery.enabled); } break; #endif @@ -2993,7 +2850,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra break; #if HAS_BED_PROBE - case ID_ProbeMenu: + case ProbeMenu: #define PROBE_BACK 0 #define PROBE_XOFFSET (PROBE_BACK + 1) @@ -3007,129 +2864,49 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case PROBE_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_Advanced, ADVANCED_PROBE); + Draw_Menu(Advanced, ADVANCED_PROBE); break; case PROBE_XOFFSET: if (draw) { - drawMenuItem(row, ICON_StepX, F("Probe X Offset")); - drawFloat(probe.offset.x, row, false, 10); + Draw_Menu_Item(row, ICON_StepX, F("Probe X Offset")); + Draw_Float(probe.offset.x, row, false, 10); } else - modifyValue(probe.offset.x, -MAX_XY_OFFSET, MAX_XY_OFFSET, 10); + Modify_Value(probe.offset.x, -MAX_XY_OFFSET, MAX_XY_OFFSET, 10); break; case PROBE_YOFFSET: if (draw) { - drawMenuItem(row, ICON_StepY, F("Probe Y Offset")); - drawFloat(probe.offset.y, row, false, 10); + Draw_Menu_Item(row, ICON_StepY, F("Probe Y Offset")); + Draw_Float(probe.offset.y, row, false, 10); } else - modifyValue(probe.offset.y, -MAX_XY_OFFSET, MAX_XY_OFFSET, 10); + Modify_Value(probe.offset.y, -MAX_XY_OFFSET, MAX_XY_OFFSET, 10); break; case PROBE_TEST: if (draw) - drawMenuItem(row, ICON_StepY, F("M48 Probe Test")); + Draw_Menu_Item(row, ICON_StepY, F("M48 Probe Test")); else { - gcode.process_subcommands_now( - TS(F("G28O\nM48X") , p_float_t((X_BED_SIZE + X_MIN_POS) / 2.0f, 3), 'Y', p_float_t((Y_BED_SIZE + Y_MIN_POS) / 2.0f, 3), 'P', testcount) - ); + sprintf_P(cmd, PSTR("G28O\nM48 X%s Y%s P%i"), dtostrf((X_BED_SIZE + X_MIN_POS) / 2.0f, 1, 3, str_1), dtostrf((Y_BED_SIZE + Y_MIN_POS) / 2.0f, 1, 3, str_2), testcount); + gcode.process_subcommands_now(cmd); } break; case PROBE_TEST_COUNT: if (draw) { - drawMenuItem(row, ICON_StepY, F("Probe Test Count")); - drawFloat(testcount, row, false, 1); + Draw_Menu_Item(row, ICON_StepY, F("Probe Test Count")); + Draw_Float(testcount, row, false, 1); } else - modifyValue(testcount, 4, 50, 1); + Modify_Value(testcount, 4, 50, 1); break; } break; - #endif // HAS_PROBE_MENU + #endif - #if HAS_TRINAMIC_CONFIG - case ID_TMCMenu: - - #define TMC_BACK 0 - #define TMC_STEPPER_CURRENT_X (TMC_BACK + AXIS_IS_TMC(X)) - #define TMC_STEPPER_CURRENT_Y (TMC_STEPPER_CURRENT_X + AXIS_IS_TMC(Y)) - #define TMC_STEPPER_CURRENT_Z (TMC_STEPPER_CURRENT_Y + AXIS_IS_TMC(Z)) - #define TMC_STEPPER_CURRENT_E (TMC_STEPPER_CURRENT_Z + AXIS_IS_TMC(E0)) - #define TMC_TOTAL TMC_STEPPER_CURRENT_E - - switch (item) { - - case TMC_BACK: - if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); - else - drawMenu(ID_Advanced, ADVANCED_TMC); - break; - - #if AXIS_IS_TMC(X) - case TMC_STEPPER_CURRENT_X: - - static float stepper_current_x; - - if (draw) { - drawMenuItem(row, ICON_StepX, GET_TEXT_F(MSG_TMC_ACURRENT)); - stepper_current_x = stepperX.getMilliamps(); - drawFloat(stepper_current_x, row, false, 1); - } - else { - modifyValue(stepper_current_x, TMC_MIN_CURRENT, TMC_MAX_CURRENT, 1, []{ stepperX.rms_current(stepper_current_x); }); - } - break; - #endif - - #if AXIS_IS_TMC(Y) - case TMC_STEPPER_CURRENT_Y: - static float stepper_current_y; - if (draw) { - drawMenuItem(row, ICON_StepY, GET_TEXT_F(MSG_TMC_BCURRENT)); - stepper_current_y = stepperY.getMilliamps(); - drawFloat(stepper_current_y, row, false, 1); - } - else { - modifyValue(stepper_current_y, TMC_MIN_CURRENT, TMC_MAX_CURRENT, 1, []{ stepperY.rms_current(stepper_current_y); }); - } - break; - #endif - - #if AXIS_IS_TMC(Z) - case TMC_STEPPER_CURRENT_Z: - static float stepper_current_z; - if (draw) { - drawMenuItem(row, ICON_StepZ, GET_TEXT_F(MSG_TMC_CCURRENT)); - stepper_current_z = stepperZ.getMilliamps(); - drawFloat(stepper_current_z, row, false, 1); - } - else { - modifyValue(stepper_current_z, TMC_MIN_CURRENT, TMC_MAX_CURRENT, 1, []{ stepperZ.rms_current(stepper_current_z); }); - } - break; - #endif - - #if AXIS_IS_TMC(E0) - case TMC_STEPPER_CURRENT_E: - static float stepper_current_e; - if (draw) { - drawMenuItem(row, ICON_StepE, GET_TEXT_F(MSG_TMC_ECURRENT)); - stepper_current_e = stepperE0.getMilliamps(); - drawFloat(stepper_current_e, row, false, 1); - } - else - modifyValue(stepper_current_e, TMC_MIN_CURRENT, TMC_MAX_CURRENT, 1, []{ stepperE0.rms_current(stepper_current_e); }); - break; - #endif - }; - break; - #endif // HAS_TRINAMIC_CONFIG - - case ID_InfoMain: - case ID_Info: + case InfoMain: + case Info: #define INFO_BACK 0 #define INFO_PRINTCOUNT (INFO_BACK + ENABLED(PRINTCOUNTER)) @@ -3142,46 +2919,43 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case INFO_BACK: if (draw) { - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); #if ENABLED(PRINTCOUNTER) - + char row1[50], row2[50], buf[32]; printStatistics ps = print_job_timer.getStats(); - drawMenuItem(INFO_PRINTCOUNT, ICON_HotendTemp, - TS(ps.totalPrints, F(" prints, "), ps.finishedPrints, F(" finished")), - TS(p_float_t(ps.filamentUsed / 1000, 2), F(" m filament used")), - false, true - ); - char buf[32]; - drawMenuItem(INFO_PRINTTIME, ICON_PrintTime, - MString<50>(F("Printed: "), duration_t(print_job_timer.getStats().printTime).toString(buf)), - MString<50>(F("Longest: "), duration_t(print_job_timer.getStats().longestPrint).toString(buf)), - false, true - ); + sprintf_P(row1, PSTR("%i prints, %i finished"), ps.totalPrints, ps.finishedPrints); + sprintf_P(row2, PSTR("%s m filament used"), dtostrf(ps.filamentUsed / 1000, 1, 2, str_1)); + Draw_Menu_Item(INFO_PRINTCOUNT, ICON_HotendTemp, row1, row2, false, true); + duration_t(print_job_timer.getStats().printTime).toString(buf); + sprintf_P(row1, PSTR("Printed: %s"), buf); + duration_t(print_job_timer.getStats().longestPrint).toString(buf); + sprintf_P(row2, PSTR("Longest: %s"), buf); + Draw_Menu_Item(INFO_PRINTTIME, ICON_PrintTime, row1, row2, false, true); #endif - drawMenuItem(INFO_SIZE, ICON_PrintSize, F(MACHINE_SIZE), nullptr, false, true); - drawMenuItem(INFO_VERSION, ICON_Version, F(SHORT_BUILD_VERSION), nullptr, false, true); - drawMenuItem(INFO_CONTACT, ICON_Contact, F(CORP_WEBSITE), nullptr, false, true); + Draw_Menu_Item(INFO_SIZE, ICON_PrintSize, F(MACHINE_SIZE), nullptr, false, true); + Draw_Menu_Item(INFO_VERSION, ICON_Version, F(SHORT_BUILD_VERSION), nullptr, false, true); + Draw_Menu_Item(INFO_CONTACT, ICON_Contact, F(CORP_WEBSITE), nullptr, false, true); } else { - if (menu == ID_Info) - drawMenu(ID_Control, CONTROL_INFO); + if (menu == Info) + Draw_Menu(Control, CONTROL_INFO); else - drawMainMenu(3); + Draw_Main_Menu(3); } break; } break; #if HAS_MESH - case ID_Leveling: + case Leveling: #define LEVELING_BACK 0 #define LEVELING_ACTIVE (LEVELING_BACK + 1) - #define LEVELING_GET_TILT (LEVELING_ACTIVE + ALL(HAS_BED_PROBE, AUTO_BED_LEVELING_UBL)) + #define LEVELING_GET_TILT (LEVELING_ACTIVE + BOTH(HAS_BED_PROBE, AUTO_BED_LEVELING_UBL)) #define LEVELING_GET_MESH (LEVELING_GET_TILT + 1) #define LEVELING_MANUAL (LEVELING_GET_MESH + 1) #define LEVELING_VIEW (LEVELING_MANUAL + 1) @@ -3194,114 +2968,119 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case LEVELING_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMainMenu(3); + Draw_Main_Menu(3); break; case LEVELING_ACTIVE: if (draw) { - drawMenuItem(row, ICON_StockConfiguration, GET_TEXT_F(MSG_BED_LEVELING)); - drawCheckbox(row, planner.leveling_active); + Draw_Menu_Item(row, ICON_StockConfiguration, F("Leveling Active")); + Draw_Checkbox(row, planner.leveling_active); } else { if (!planner.leveling_active) { set_bed_leveling_enabled(!planner.leveling_active); if (!planner.leveling_active) { - confirmHandler(Popup_LevelError); + Confirm_Handler(LevelError); break; } } else set_bed_leveling_enabled(!planner.leveling_active); - drawCheckbox(row, planner.leveling_active); + Draw_Checkbox(row, planner.leveling_active); } break; - #if ALL(HAS_BED_PROBE, AUTO_BED_LEVELING_UBL) + #if BOTH(HAS_BED_PROBE, AUTO_BED_LEVELING_UBL) case LEVELING_GET_TILT: if (draw) - drawMenuItem(row, ICON_Tilt, GET_TEXT_F(MSG_UBL_TILT_MESH)); + Draw_Menu_Item(row, ICON_Tilt, F("Autotilt Current Mesh")); else { - if (bedlevel.storage_slot < 0) { popupHandler(Popup_MeshSlot); break; } - popupHandler(Popup_Home); + if (bedlevel.storage_slot < 0) { + Popup_Handler(MeshSlot); + break; + } + Popup_Handler(Home); gcode.home_all_axes(true); - popupHandler(Popup_Level); - if (mesh_conf.tilt_grid > 1) - gcode.process_subcommands_now(TS(F("G29J"), mesh_conf.tilt_grid)); + Popup_Handler(Level); + if (mesh_conf.tilt_grid > 1) { + sprintf_P(cmd, PSTR("G29 J%i"), mesh_conf.tilt_grid); + gcode.process_subcommands_now(cmd); + } else - gcode.process_subcommands_now(F("G29J")); + gcode.process_subcommands_now(F("G29 J")); planner.synchronize(); - redrawMenu(); + Redraw_Menu(); } break; #endif case LEVELING_GET_MESH: if (draw) - drawMenuItem(row, ICON_Mesh, F("Create New Mesh")); + Draw_Menu_Item(row, ICON_Mesh, F("Create New Mesh")); else { - popupHandler(Popup_Home); + Popup_Handler(Home); gcode.home_all_axes(true); #if ENABLED(AUTO_BED_LEVELING_UBL) #if ENABLED(PREHEAT_BEFORE_LEVELING) - popupHandler(Popup_Heating); + Popup_Handler(Heating); probe.preheat_for_probing(LEVELING_NOZZLE_TEMP, LEVELING_BED_TEMP); #endif #if HAS_BED_PROBE - popupHandler(Popup_Level); - gcode.process_subcommands_now(F("G29P0\nG29P1")); - gcode.process_subcommands_now(F("G29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nG29P3\nM420S1")); + Popup_Handler(Level); + gcode.process_subcommands_now(F("G29 P0\nG29 P1")); + gcode.process_subcommands_now(F("G29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nG29 P3\nM420 S1")); planner.synchronize(); - updateStatus("Probed all reachable points"); - popupHandler(Popup_SaveLevel); + Update_Status("Probed all reachable points"); + Popup_Handler(SaveLevel); #else level_state = planner.leveling_active; set_bed_leveling_enabled(false); mesh_conf.goto_mesh_value = true; mesh_conf.mesh_x = mesh_conf.mesh_y = 0; - popupHandler(Popup_MoveWait); + Popup_Handler(MoveWait); mesh_conf.manual_mesh_move(); - drawMenu(ID_UBLMesh); + Draw_Menu(UBLMesh); #endif #elif HAS_BED_PROBE - popupHandler(Popup_Level); + Popup_Handler(Level); gcode.process_subcommands_now(F("G29")); planner.synchronize(); - popupHandler(Popup_SaveLevel); + Popup_Handler(SaveLevel); #else level_state = planner.leveling_active; set_bed_leveling_enabled(false); gridpoint = 1; - popupHandler(Popup_MoveWait); + Popup_Handler(MoveWait); gcode.process_subcommands_now(F("G29")); planner.synchronize(); - drawMenu(ID_ManualMesh); + Draw_Menu(ManualMesh); #endif } break; case LEVELING_MANUAL: if (draw) - drawMenuItem(row, ICON_Mesh, F("Manual Tuning"), nullptr, true); + Draw_Menu_Item(row, ICON_Mesh, F("Manual Tuning"), nullptr, true); else { #if ENABLED(AUTO_BED_LEVELING_BILINEAR) if (!leveling_is_valid()) { - confirmHandler(Popup_InvalidMesh); + Confirm_Handler(InvalidMesh); break; } #endif #if ENABLED(AUTO_BED_LEVELING_UBL) if (bedlevel.storage_slot < 0) { - popupHandler(Popup_MeshSlot); + Popup_Handler(MeshSlot); break; } #endif if (axes_should_home()) { - popupHandler(Popup_Home); + Popup_Handler(Home); gcode.home_all_axes(true); } level_state = planner.leveling_active; set_bed_leveling_enabled(false); mesh_conf.goto_mesh_value = false; #if ENABLED(PREHEAT_BEFORE_LEVELING) - popupHandler(Popup_Heating); + Popup_Handler(Heating); #if HAS_HOTEND if (thermalManager.degTargetHotend(0) < LEVELING_NOZZLE_TEMP) thermalManager.setTargetHotend(LEVELING_NOZZLE_TEMP, 0); @@ -3313,70 +3092,70 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra TERN_(HAS_HOTEND, thermalManager.wait_for_hotend(0)); TERN_(HAS_HEATED_BED, thermalManager.wait_for_bed_heating()); #endif - popupHandler(Popup_MoveWait); + Popup_Handler(MoveWait); mesh_conf.manual_mesh_move(); - drawMenu(ID_LevelManual); + Draw_Menu(LevelManual); } break; case LEVELING_VIEW: if (draw) - drawMenuItem(row, ICON_Mesh, GET_TEXT_F(MSG_MESH_VIEW), nullptr, true); + Draw_Menu_Item(row, ICON_Mesh, GET_TEXT_F(MSG_MESH_VIEW), nullptr, true); else { #if ENABLED(AUTO_BED_LEVELING_UBL) if (bedlevel.storage_slot < 0) { - popupHandler(Popup_MeshSlot); + Popup_Handler(MeshSlot); break; } #endif - drawMenu(ID_LevelView); + Draw_Menu(LevelView); } break; case LEVELING_SETTINGS: if (draw) - drawMenuItem(row, ICON_Step, F("Leveling Settings"), nullptr, true); + Draw_Menu_Item(row, ICON_Step, F("Leveling Settings"), nullptr, true); else - drawMenu(ID_LevelSettings); + Draw_Menu(LevelSettings); break; #if ENABLED(AUTO_BED_LEVELING_UBL) - case LEVELING_SLOT: - if (draw) { - drawMenuItem(row, ICON_PrintSize, GET_TEXT_F(MSG_UBL_STORAGE_SLOT)); - drawFloat(bedlevel.storage_slot, row, false, 1); + case LEVELING_SLOT: + if (draw) { + Draw_Menu_Item(row, ICON_PrintSize, F("Mesh Slot")); + Draw_Float(bedlevel.storage_slot, row, false, 1); + } + else + Modify_Value(bedlevel.storage_slot, 0, settings.calc_num_meshes() - 1, 1); + break; + case LEVELING_LOAD: + if (draw) + Draw_Menu_Item(row, ICON_ReadEEPROM, F("Load Mesh")); + else { + if (bedlevel.storage_slot < 0) { + Popup_Handler(MeshSlot); + break; } - else - modifyValue(bedlevel.storage_slot, 0, settings.calc_num_meshes() - 1, 1); - break; - case LEVELING_LOAD: - if (draw) - drawMenuItem(row, ICON_ReadEEPROM, GET_TEXT_F(MSG_UBL_LOAD_MESH)); - else { - if (bedlevel.storage_slot < 0) { - popupHandler(Popup_MeshSlot); - break; - } - gcode.process_subcommands_now(F("G29 L")); - planner.synchronize(); - audioFeedback(true); + gcode.process_subcommands_now(F("G29 L")); + planner.synchronize(); + AudioFeedback(true); + } + break; + case LEVELING_SAVE: + if (draw) + Draw_Menu_Item(row, ICON_WriteEEPROM, F("Save Mesh")); + else { + if (bedlevel.storage_slot < 0) { + Popup_Handler(MeshSlot); + break; } - break; - case LEVELING_SAVE: - if (draw) - drawMenuItem(row, ICON_WriteEEPROM, GET_TEXT_F(MSG_UBL_SAVE_MESH)); - else { - if (bedlevel.storage_slot < 0) { - popupHandler(Popup_MeshSlot); - break; - } - gcode.process_subcommands_now(F("G29 S")); - planner.synchronize(); - audioFeedback(true); - } - break; - #endif // AUTO_BED_LEVELING_UBL + gcode.process_subcommands_now(F("G29 S")); + planner.synchronize(); + AudioFeedback(true); + } + break; + #endif } break; - case ID_LevelView: + case LevelView: #define LEVELING_VIEW_BACK 0 #define LEVELING_VIEW_MESH (LEVELING_VIEW_BACK + 1) @@ -3387,40 +3166,40 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case LEVELING_VIEW_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_Leveling, LEVELING_VIEW); + Draw_Menu(Leveling, LEVELING_VIEW); break; case LEVELING_VIEW_MESH: if (draw) - drawMenuItem(row, ICON_PrintSize, GET_TEXT_F(MSG_MESH_VIEW), nullptr, true); + Draw_Menu_Item(row, ICON_PrintSize, GET_TEXT_F(MSG_MESH_VIEW), nullptr, true); else - drawMenu(ID_MeshViewer); + Draw_Menu(MeshViewer); break; case LEVELING_VIEW_TEXT: if (draw) { - drawMenuItem(row, ICON_Contact, F("Viewer Show Values")); - drawCheckbox(row, mesh_conf.viewer_print_value); + Draw_Menu_Item(row, ICON_Contact, F("Viewer Show Values")); + Draw_Checkbox(row, mesh_conf.viewer_print_value); } else { - mesh_conf.viewer_print_value ^= true; - drawCheckbox(row, mesh_conf.viewer_print_value); + mesh_conf.viewer_print_value = !mesh_conf.viewer_print_value; + Draw_Checkbox(row, mesh_conf.viewer_print_value); } break; case LEVELING_VIEW_ASYMMETRIC: if (draw) { - drawMenuItem(row, ICON_Axis, F("Viewer Asymmetric")); - drawCheckbox(row, mesh_conf.viewer_asymmetric_range); + Draw_Menu_Item(row, ICON_Axis, F("Viewer Asymmetric")); + Draw_Checkbox(row, mesh_conf.viewer_asymmetric_range); } else { - mesh_conf.viewer_asymmetric_range ^= true; - drawCheckbox(row, mesh_conf.viewer_asymmetric_range); + mesh_conf.viewer_asymmetric_range = !mesh_conf.viewer_asymmetric_range; + Draw_Checkbox(row, mesh_conf.viewer_asymmetric_range); } break; } break; - case ID_LevelSettings: + case LevelSettings: #define LEVELING_SETTINGS_BACK 0 #define LEVELING_SETTINGS_FADE (LEVELING_SETTINGS_BACK + 1) @@ -3433,17 +3212,17 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case LEVELING_SETTINGS_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawMenu(ID_Leveling, LEVELING_SETTINGS); + Draw_Menu(Leveling, LEVELING_SETTINGS); break; case LEVELING_SETTINGS_FADE: if (draw) { - drawMenuItem(row, ICON_Fade, GET_TEXT_F(MSG_Z_FADE_HEIGHT)); - drawFloat(planner.z_fade_height, row, false, 1); + Draw_Menu_Item(row, ICON_Fade, F("Fade Mesh within")); + Draw_Float(planner.z_fade_height, row, false, 1); } else { - modifyValue(planner.z_fade_height, 0, Z_MAX_POS, 1); + Modify_Value(planner.z_fade_height, 0, Z_MAX_POS, 1); planner.z_fade_height = -1; set_z_fade_height(planner.z_fade_height); } @@ -3452,31 +3231,31 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra #if ENABLED(AUTO_BED_LEVELING_UBL) case LEVELING_SETTINGS_TILT: if (draw) { - drawMenuItem(row, ICON_Tilt, F("Tilting Grid Size")); - drawFloat(mesh_conf.tilt_grid, row, false, 1); + Draw_Menu_Item(row, ICON_Tilt, F("Tilting Grid Size")); + Draw_Float(mesh_conf.tilt_grid, row, false, 1); } else - modifyValue(mesh_conf.tilt_grid, 1, 8, 1); + Modify_Value(mesh_conf.tilt_grid, 1, 8, 1); break; case LEVELING_SETTINGS_PLANE: if (draw) - drawMenuItem(row, ICON_ResetEEPROM, F("Convert Mesh to Plane")); + Draw_Menu_Item(row, ICON_ResumeEEPROM, F("Convert Mesh to Plane")); else { - if (mesh_conf.createPlaneFromMesh()) break; + if (mesh_conf.create_plane_from_mesh()) break; gcode.process_subcommands_now(F("M420 S1")); planner.synchronize(); - audioFeedback(true); + AudioFeedback(true); } break; case LEVELING_SETTINGS_ZERO: if (draw) - drawMenuItem(row, ICON_Mesh, F("Mesh Zero")); + Draw_Menu_Item(row, ICON_Mesh, F("Zero Current Mesh")); else ZERO(bedlevel.z_values); break; case LEVELING_SETTINGS_UNDEF: if (draw) - drawMenuItem(row, ICON_Mesh, GET_TEXT_F(MSG_MESH_RESET)); + Draw_Menu_Item(row, ICON_Mesh, F("Clear Current Mesh")); else bedlevel.invalidate(); break; @@ -3484,24 +3263,24 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra } break; - case ID_MeshViewer: + case MeshViewer: #define MESHVIEW_BACK 0 #define MESHVIEW_TOTAL MESHVIEW_BACK if (item == MESHVIEW_BACK) { if (draw) { - drawMenuItem(0, ICON_Back, GET_TEXT_F(MSG_BACK)); - mesh_conf.drawBedMesh(); - mesh_conf.setMeshViewerStatus(); + Draw_Menu_Item(0, ICON_Back, F("Back")); + mesh_conf.Draw_Bed_Mesh(); + mesh_conf.Set_Mesh_Viewer_Status(); } else if (!mesh_conf.drawing_mesh) { - drawMenu(ID_LevelView, LEVELING_VIEW_MESH); - updateStatus(""); + Draw_Menu(LevelView, LEVELING_VIEW_MESH); + Update_Status(""); } } break; - case ID_LevelManual: + case LevelManual: #define LEVELING_M_BACK 0 #define LEVELING_M_X (LEVELING_M_BACK + 1) @@ -3517,32 +3296,32 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case LEVELING_M_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else { set_bed_leveling_enabled(level_state); TERN_(AUTO_BED_LEVELING_BILINEAR, bedlevel.refresh_bed_level()); - drawMenu(ID_Leveling, LEVELING_MANUAL); + Draw_Menu(Leveling, LEVELING_MANUAL); } break; case LEVELING_M_X: if (draw) { - drawMenuItem(row, ICON_MoveX, GET_TEXT_F(MSG_MESH_X)); - drawFloat(mesh_conf.mesh_x, row, 0, 1); + Draw_Menu_Item(row, ICON_MoveX, F("Mesh Point X")); + Draw_Float(mesh_conf.mesh_x, row, 0, 1); } else - modifyValue(mesh_conf.mesh_x, 0, GRID_MAX_POINTS_X - 1, 1); + Modify_Value(mesh_conf.mesh_x, 0, GRID_MAX_POINTS_X - 1, 1); break; case LEVELING_M_Y: if (draw) { - drawMenuItem(row, ICON_MoveY, GET_TEXT_F(MSG_MESH_Y)); - drawFloat(mesh_conf.mesh_y, row, 0, 1); + Draw_Menu_Item(row, ICON_MoveY, F("Mesh Point Y")); + Draw_Float(mesh_conf.mesh_y, row, 0, 1); } else - modifyValue(mesh_conf.mesh_y, 0, GRID_MAX_POINTS_Y - 1, 1); + Modify_Value(mesh_conf.mesh_y, 0, GRID_MAX_POINTS_Y - 1, 1); break; case LEVELING_M_NEXT: if (draw) - drawMenuItem(row, ICON_More, GET_TEXT_F(MSG_LEVEL_BED_NEXT_POINT)); + Draw_Menu_Item(row, ICON_More, F("Next Point")); else { if (mesh_conf.mesh_x != (GRID_MAX_POINTS_X - 1) || mesh_conf.mesh_y != (GRID_MAX_POINTS_Y - 1)) { if ((mesh_conf.mesh_x == (GRID_MAX_POINTS_X - 1) && mesh_conf.mesh_y % 2 == 0) || (mesh_conf.mesh_x == 0 && mesh_conf.mesh_y % 2 == 1)) @@ -3557,67 +3336,67 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra break; case LEVELING_M_OFFSET: if (draw) { - drawMenuItem(row, ICON_SetZOffset, GET_TEXT_F(MSG_MESH_EDIT_Z)); - drawFloat(bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y], row, false, 100); + Draw_Menu_Item(row, ICON_SetZOffset, F("Point Z Offset")); + Draw_Float(bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y], row, false, 100); } else { if (isnan(bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y])) bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y] = 0; - modifyValue(bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y], MIN_Z_OFFSET, MAX_Z_OFFSET, 100); + Modify_Value(bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y], MIN_Z_OFFSET, MAX_Z_OFFSET, 100); } break; case LEVELING_M_UP: if (draw) - drawMenuItem(row, ICON_Axis, F("+0.01mm Up")); + Draw_Menu_Item(row, ICON_Axis, F("Microstep Up")); else if (bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y] < MAX_Z_OFFSET) { bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y] += 0.01; gcode.process_subcommands_now(F("M290 Z0.01")); planner.synchronize(); current_position.z += 0.01f; sync_plan_position(); - drawFloat(bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y], row - 1, false, 100); + Draw_Float(bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y], row - 1, false, 100); } break; case LEVELING_M_DOWN: if (draw) - drawMenuItem(row, ICON_AxisD, F("-0.01mm Down")); + Draw_Menu_Item(row, ICON_AxisD, F("Microstep Down")); else if (bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y] > MIN_Z_OFFSET) { bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y] -= 0.01; gcode.process_subcommands_now(F("M290 Z-0.01")); planner.synchronize(); current_position.z -= 0.01f; sync_plan_position(); - drawFloat(bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y], row - 2, false, 100); + Draw_Float(bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y], row - 2, false, 100); } break; case LEVELING_M_GOTO_VALUE: if (draw) { - drawMenuItem(row, ICON_StockConfiguration, F("Go to Mesh Z Value")); - drawCheckbox(row, mesh_conf.goto_mesh_value); + Draw_Menu_Item(row, ICON_StockConfiguration, F("Go to Mesh Z Value")); + Draw_Checkbox(row, mesh_conf.goto_mesh_value); } else { - mesh_conf.goto_mesh_value ^= true; + mesh_conf.goto_mesh_value = !mesh_conf.goto_mesh_value; current_position.z = 0; mesh_conf.manual_mesh_move(true); - drawCheckbox(row, mesh_conf.goto_mesh_value); + Draw_Checkbox(row, mesh_conf.goto_mesh_value); } break; #if ENABLED(AUTO_BED_LEVELING_UBL) - case LEVELING_M_UNDEF: - if (draw) - drawMenuItem(row, ICON_ResetEEPROM, F("Clear Point Value")); - else { - mesh_conf.manualValueUpdate(true); - redrawMenu(false); - } - break; + case LEVELING_M_UNDEF: + if (draw) + Draw_Menu_Item(row, ICON_ResumeEEPROM, F("Clear Point Value")); + else { + mesh_conf.manual_value_update(true); + Redraw_Menu(false); + } + break; #endif } break; #endif // HAS_MESH #if ENABLED(AUTO_BED_LEVELING_UBL) && !HAS_BED_PROBE - case ID_UBLMesh: + case UBLMesh: #define UBL_M_BACK 0 #define UBL_M_NEXT (UBL_M_BACK + 1) @@ -3630,18 +3409,18 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case UBL_M_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else { set_bed_leveling_enabled(level_state); - drawMenu(ID_Leveling, LEVELING_GET_MESH); + Draw_Menu(Leveling, LEVELING_GET_MESH); } break; case UBL_M_NEXT: if (draw) { if (mesh_conf.mesh_x != (GRID_MAX_POINTS_X - 1) || mesh_conf.mesh_y != (GRID_MAX_POINTS_Y - 1)) - drawMenuItem(row, ICON_More, GET_TEXT_F(MSG_LEVEL_BED_NEXT_POINT)); + Draw_Menu_Item(row, ICON_More, F("Next Point")); else - drawMenuItem(row, ICON_More, GET_TEXT_F(MSG_UBL_SAVE_MESH)); + Draw_Menu_Item(row, ICON_More, F("Save Mesh")); } else { if (mesh_conf.mesh_x != (GRID_MAX_POINTS_X - 1) || mesh_conf.mesh_y != (GRID_MAX_POINTS_Y - 1)) { @@ -3656,14 +3435,14 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra else { gcode.process_subcommands_now(F("G29 S")); planner.synchronize(); - audioFeedback(true); - drawMenu(ID_Leveling, LEVELING_GET_MESH); + AudioFeedback(true); + Draw_Menu(Leveling, LEVELING_GET_MESH); } } break; case UBL_M_PREV: if (draw) - drawMenuItem(row, ICON_More, F("Previous Point")); + Draw_Menu_Item(row, ICON_More, F("Previous Point")); else { if (mesh_conf.mesh_x != 0 || mesh_conf.mesh_y != 0) { if ((mesh_conf.mesh_x == (GRID_MAX_POINTS_X - 1) && mesh_conf.mesh_y % 2 == 1) || (mesh_conf.mesh_x == 0 && mesh_conf.mesh_y % 2 == 0)) @@ -3678,37 +3457,37 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra break; case UBL_M_OFFSET: if (draw) { - drawMenuItem(row, ICON_SetZOffset, GET_TEXT_F(MSG_MESH_EDIT_Z)); - drawFloat(bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y], row, false, 100); + Draw_Menu_Item(row, ICON_SetZOffset, F("Point Z Offset")); + Draw_Float(bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y], row, false, 100); } else { if (isnan(bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y])) bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y] = 0; - modifyValue(bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y], MIN_Z_OFFSET, MAX_Z_OFFSET, 100); + Modify_Value(bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y], MIN_Z_OFFSET, MAX_Z_OFFSET, 100); } break; case UBL_M_UP: if (draw) - drawMenuItem(row, ICON_Axis, F("+0.01mm Up")); + Draw_Menu_Item(row, ICON_Axis, F("Microstep Up")); else if (bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y] < MAX_Z_OFFSET) { bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y] += 0.01; gcode.process_subcommands_now(F("M290 Z0.01")); planner.synchronize(); current_position.z += 0.01f; sync_plan_position(); - drawFloat(bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y], row - 1, false, 100); + Draw_Float(bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y], row - 1, false, 100); } break; case UBL_M_DOWN: if (draw) - drawMenuItem(row, ICON_Axis, F("-0.01mm Down")); + Draw_Menu_Item(row, ICON_Axis, F("Microstep Down")); else if (bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y] > MIN_Z_OFFSET) { bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y] -= 0.01; gcode.process_subcommands_now(F("M290 Z-0.01")); planner.synchronize(); current_position.z -= 0.01f; sync_plan_position(); - drawFloat(bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y], row - 2, false, 100); + Draw_Float(bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y], row - 2, false, 100); } break; } @@ -3716,7 +3495,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra #endif // AUTO_BED_LEVELING_UBL && !HAS_BED_PROBE #if ENABLED(PROBE_MANUALLY) - case ID_ManualMesh: + case ManualMesh: #define MMESH_BACK 0 #define MMESH_NEXT (MMESH_BACK + 1) @@ -3729,64 +3508,64 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case MMESH_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BUTTON_CANCEL)); + Draw_Menu_Item(row, ICON_Back, F("Cancel")); else { gcode.process_subcommands_now(F("G29 A")); planner.synchronize(); set_bed_leveling_enabled(level_state); - drawMenu(ID_Leveling, LEVELING_GET_MESH); + Draw_Menu(Leveling, LEVELING_GET_MESH); } break; case MMESH_NEXT: if (draw) { if (gridpoint < GRID_MAX_POINTS) - drawMenuItem(row, ICON_More, GET_TEXT_F(MSG_LEVEL_BED_NEXT_POINT)); + Draw_Menu_Item(row, ICON_More, F("Next Point")); else - drawMenuItem(row, ICON_More, GET_TEXT_F(MSG_UBL_SAVE_MESH)); + Draw_Menu_Item(row, ICON_More, F("Save Mesh")); } else if (gridpoint < GRID_MAX_POINTS) { - popupHandler(Popup_MoveWait); + Popup_Handler(MoveWait); gcode.process_subcommands_now(F("G29")); planner.synchronize(); gridpoint++; - redrawMenu(); + Redraw_Menu(); } else { gcode.process_subcommands_now(F("G29")); planner.synchronize(); - audioFeedback(settings.save()); - drawMenu(ID_Leveling, LEVELING_GET_MESH); + AudioFeedback(settings.save()); + Draw_Menu(Leveling, LEVELING_GET_MESH); } break; case MMESH_OFFSET: if (draw) { - drawMenuItem(row, ICON_SetZOffset, F("Z Position")); + Draw_Menu_Item(row, ICON_SetZOffset, F("Z Position")); current_position.z = MANUAL_PROBE_START_Z; - drawFloat(current_position.z, row, false, 100); + Draw_Float(current_position.z, row, false, 100); } else - modifyValue(current_position.z, MIN_Z_OFFSET, MAX_Z_OFFSET, 100); + Modify_Value(current_position.z, MIN_Z_OFFSET, MAX_Z_OFFSET, 100); break; case MMESH_UP: if (draw) - drawMenuItem(row, ICON_Axis, F("+0.01mm Up")); + Draw_Menu_Item(row, ICON_Axis, F("Microstep Up")); else if (current_position.z < MAX_Z_OFFSET) { gcode.process_subcommands_now(F("M290 Z0.01")); planner.synchronize(); current_position.z += 0.01f; sync_plan_position(); - drawFloat(current_position.z, row - 1, false, 100); + Draw_Float(current_position.z, row - 1, false, 100); } break; case MMESH_DOWN: if (draw) - drawMenuItem(row, ICON_AxisD, F("-0.01mm Down")); + Draw_Menu_Item(row, ICON_AxisD, F("Microstep Down")); else if (current_position.z > MIN_Z_OFFSET) { gcode.process_subcommands_now(F("M290 Z-0.01")); planner.synchronize(); current_position.z -= 0.01f; sync_plan_position(); - drawFloat(current_position.z, row - 2, false, 100); + Draw_Float(current_position.z, row - 2, false, 100); } break; case MMESH_OLD: @@ -3801,22 +3580,22 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra const float currval = bedlevel.z_values[mesh_x][mesh_y]; if (draw) { - drawMenuItem(row, ICON_Zoffset, F("Goto Mesh Value")); - drawFloat(currval, row, false, 100); + Draw_Menu_Item(row, ICON_Zoffset, F("Goto Mesh Value")); + Draw_Float(currval, row, false, 100); } else if (!isnan(currval)) { current_position.z = currval; planner.synchronize(); planner.buffer_line(current_position, homing_feedrate(Z_AXIS), active_extruder); planner.synchronize(); - drawFloat(current_position.z, row - 3, false, 100); + Draw_Float(current_position.z, row - 3, false, 100); } break; } break; #endif // PROBE_MANUALLY - case ID_Tune: + case Tune: #define TUNE_BACK 0 #define TUNE_SPEED (TUNE_BACK + 1) @@ -3827,10 +3606,8 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra #define TUNE_ZOFFSET (TUNE_FAN + ENABLED(HAS_ZOFFSET_ITEM)) #define TUNE_ZUP (TUNE_ZOFFSET + ENABLED(HAS_ZOFFSET_ITEM)) #define TUNE_ZDOWN (TUNE_ZUP + ENABLED(HAS_ZOFFSET_ITEM)) - #define TUNE_LA (TUNE_ZDOWN + ENABLED(LIN_ADVANCE)) - #define TUNE_CHANGEFIL (TUNE_LA + ENABLED(FILAMENT_LOAD_UNLOAD_GCODES)) - #define TUNE_FWRETRACT (TUNE_CHANGEFIL + ENABLED(FWRETRACT)) - #define TUNE_FILSENSORENABLED (TUNE_FWRETRACT + ENABLED(FILAMENT_RUNOUT_SENSOR)) + #define TUNE_CHANGEFIL (TUNE_ZDOWN + ENABLED(FILAMENT_LOAD_UNLOAD_GCODES)) + #define TUNE_FILSENSORENABLED (TUNE_CHANGEFIL + ENABLED(FILAMENT_RUNOUT_SENSOR)) #define TUNE_BACKLIGHT_OFF (TUNE_FILSENSORENABLED + 1) #define TUNE_BACKLIGHT (TUNE_BACKLIGHT_OFF + 1) #define TUNE_TOTAL TUNE_BACKLIGHT @@ -3838,151 +3615,131 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case TUNE_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK)); + Draw_Menu_Item(row, ICON_Back, F("Back")); else - drawPrintScreen(); + Draw_Print_Screen(); break; case TUNE_SPEED: if (draw) { - drawMenuItem(row, ICON_Speed, GET_TEXT_F(MSG_SPEED)); - drawFloat(feedrate_percentage, row, false, 1); + Draw_Menu_Item(row, ICON_Speed, F("Print Speed")); + Draw_Float(feedrate_percentage, row, false, 1); } else - modifyValue(feedrate_percentage, MIN_PRINT_SPEED, MAX_PRINT_SPEED, 1); + Modify_Value(feedrate_percentage, MIN_PRINT_SPEED, MAX_PRINT_SPEED, 1); break; #if HAS_HOTEND case TUNE_FLOW: if (draw) { - drawMenuItem(row, ICON_Speed, GET_TEXT_F(MSG_FLOW)); - drawFloat(planner.flow_percentage[0], row, false, 1); + Draw_Menu_Item(row, ICON_Speed, F("Flow Rate")); + Draw_Float(planner.flow_percentage[0], row, false, 1); } else - modifyValue(planner.flow_percentage[0], MIN_FLOW_RATE, MAX_FLOW_RATE, 1, []{ planner.refresh_e_factor(0); }); + Modify_Value(planner.flow_percentage[0], MIN_FLOW_RATE, MAX_FLOW_RATE, 1); break; case TUNE_HOTEND: if (draw) { - drawMenuItem(row, ICON_SetEndTemp, GET_TEXT_F(MSG_NOZZLE)); - drawFloat(thermalManager.degTargetHotend(0), row, false, 1); + Draw_Menu_Item(row, ICON_SetEndTemp, F("Hotend")); + Draw_Float(thermalManager.temp_hotend[0].target, row, false, 1); } else - modifyValue(thermalManager.temp_hotend[0].target, MIN_E_TEMP, MAX_E_TEMP, 1); + Modify_Value(thermalManager.temp_hotend[0].target, MIN_E_TEMP, MAX_E_TEMP, 1); break; #endif #if HAS_HEATED_BED case TUNE_BED: if (draw) { - drawMenuItem(row, ICON_SetBedTemp, GET_TEXT_F(MSG_BED)); - drawFloat(thermalManager.degTargetBed(), row, false, 1); + Draw_Menu_Item(row, ICON_SetBedTemp, F("Bed")); + Draw_Float(thermalManager.temp_bed.target, row, false, 1); } else - modifyValue(thermalManager.temp_bed.target, MIN_BED_TEMP, MAX_BED_TEMP, 1); + Modify_Value(thermalManager.temp_bed.target, MIN_BED_TEMP, MAX_BED_TEMP, 1); break; #endif #if HAS_FAN case TUNE_FAN: if (draw) { - drawMenuItem(row, ICON_FanSpeed, GET_TEXT_F(MSG_FAN_SPEED)); - drawFloat(thermalManager.fan_speed[0], row, false, 1); + Draw_Menu_Item(row, ICON_FanSpeed, F("Fan")); + Draw_Float(thermalManager.fan_speed[0], row, false, 1); } else - modifyValue(thermalManager.fan_speed[0], MIN_FAN_SPEED, MAX_FAN_SPEED, 1); + Modify_Value(thermalManager.fan_speed[0], MIN_FAN_SPEED, MAX_FAN_SPEED, 1); break; #endif #if HAS_ZOFFSET_ITEM case TUNE_ZOFFSET: if (draw) { - drawMenuItem(row, ICON_FanSpeed, F("Z-Offset")); - drawFloat(zoffsetvalue, row, false, 100); + Draw_Menu_Item(row, ICON_FanSpeed, F("Z-Offset")); + Draw_Float(zoffsetvalue, row, false, 100); } else - modifyValue(zoffsetvalue, MIN_Z_OFFSET, MAX_Z_OFFSET, 100); + Modify_Value(zoffsetvalue, MIN_Z_OFFSET, MAX_Z_OFFSET, 100); break; case TUNE_ZUP: if (draw) - drawMenuItem(row, ICON_Axis, F("Z-Offset +0.01mm Up")); + Draw_Menu_Item(row, ICON_Axis, F("Z-Offset Up")); else if (zoffsetvalue < MAX_Z_OFFSET) { gcode.process_subcommands_now(F("M290 Z0.01")); zoffsetvalue += 0.01; - drawFloat(zoffsetvalue, row - 1, false, 100); + Draw_Float(zoffsetvalue, row - 1, false, 100); } break; case TUNE_ZDOWN: if (draw) - drawMenuItem(row, ICON_AxisD, F("Z-Offset -0.01mm Down")); + Draw_Menu_Item(row, ICON_AxisD, F("Z-Offset Down")); else if (zoffsetvalue > MIN_Z_OFFSET) { gcode.process_subcommands_now(F("M290 Z-0.01")); zoffsetvalue -= 0.01; - drawFloat(zoffsetvalue, row - 2, false, 100); + Draw_Float(zoffsetvalue, row - 2, false, 100); } break; #endif - #if ENABLED(LIN_ADVANCE) - case TUNE_LA: - if (draw) { - drawMenuItem(row, ICON_MaxAccelerated, GET_TEXT_F(MSG_ADVANCE_K)); - drawFloat(planner.extruder_advance_K[0], row, false, 100); - } - else - modifyValue(planner.extruder_advance_K[0], 0, 10, 100); - break; - #endif - #if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES) case TUNE_CHANGEFIL: if (draw) - drawMenuItem(row, ICON_ResetEEPROM, GET_TEXT_F(MSG_FILAMENTCHANGE)); + Draw_Menu_Item(row, ICON_ResumeEEPROM, F("Change Filament")); else - popupHandler(Popup_ConfFilChange); - break; - #endif - - #if ENABLED(FWRETRACT) - case TUNE_FWRETRACT: - if (draw) - drawMenuItem(row, ICON_SetHome, GET_TEXT_F(MSG_FWRETRACT), nullptr, true); - else - drawMenu(ID_FWMenu); + Popup_Handler(ConfFilChange); break; #endif #if ENABLED(FILAMENT_RUNOUT_SENSOR) case TUNE_FILSENSORENABLED: if (draw) { - drawMenuItem(row, ICON_Extruder, GET_TEXT_F(MSG_RUNOUT_SENSOR)); - drawCheckbox(row, runout.enabled); + Draw_Menu_Item(row, ICON_Extruder, F("Filament Sensor")); + Draw_Checkbox(row, runout.enabled[0]); } else { - runout.enabled ^= true; - drawCheckbox(row, runout.enabled); + runout.enabled = !runout.enabled[0]; + Draw_Checkbox(row, runout.enabled[0]); } break; #endif case TUNE_BACKLIGHT_OFF: if (draw) - drawMenuItem(row, ICON_Brightness, GET_TEXT_F(MSG_BRIGHTNESS_OFF)); + Draw_Menu_Item(row, ICON_Brightness, F("Display Off")); else ui.set_brightness(0); break; case TUNE_BACKLIGHT: if (draw) { - drawMenuItem(row, ICON_Brightness, GET_TEXT_F(MSG_BRIGHTNESS)); - drawFloat(ui.brightness, row, false, 1); + Draw_Menu_Item(row, ICON_Brightness, F("LCD Brightness")); + Draw_Float(ui.brightness, row, false, 1); } else - modifyValue(ui.brightness, LCD_BRIGHTNESS_MIN, LCD_BRIGHTNESS_MAX, 1, ui.refresh_brightness); + Modify_Value(ui.brightness, LCD_BRIGHTNESS_MIN, LCD_BRIGHTNESS_MAX, 1, ui.refresh_brightness); break; } break; #if HAS_PREHEAT && HAS_HOTEND - case ID_PreheatHotend: + case PreheatHotend: #define PREHEATHOTEND_BACK 0 #define PREHEATHOTEND_CONTINUE (PREHEATHOTEND_BACK + 1) @@ -3997,56 +3754,59 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra switch (item) { case PREHEATHOTEND_BACK: if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BUTTON_CANCEL)); + Draw_Menu_Item(row, ICON_Back, F("Cancel")); else { thermalManager.setTargetHotend(0, 0); - TERN_(HAS_FAN, thermalManager.set_fan_speed(0, 0)); - redrawMenu(false, true, true); + thermalManager.set_fan_speed(0, 0); + Redraw_Menu(false, true, true); } break; case PREHEATHOTEND_CONTINUE: if (draw) - drawMenuItem(row, ICON_SetEndTemp, GET_TEXT_F(MSG_BUTTON_CONTINUE)); + Draw_Menu_Item(row, ICON_SetEndTemp, F("Continue")); else { - popupHandler(Popup_Heating); + Popup_Handler(Heating); thermalManager.wait_for_hotend(0); switch (last_menu) { - case ID_Prepare: - popupHandler(Popup_FilChange); - gcode.process_subcommands_now(TS(F("M600 B1 R"), thermalManager.degTargetHotend(0))); + case Prepare: + Popup_Handler(FilChange); + sprintf_P(cmd, PSTR("M600 B1 R%i"), thermalManager.temp_hotend[0].target); + gcode.process_subcommands_now(cmd); break; #if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES) - case ID_ChangeFilament: + case ChangeFilament: switch (last_selection) { case CHANGEFIL_LOAD: - popupHandler(Popup_FilLoad); + Popup_Handler(FilLoad); gcode.process_subcommands_now(F("M701")); planner.synchronize(); - redrawMenu(true, true, true); + Redraw_Menu(true, true, true); break; case CHANGEFIL_UNLOAD: - popupHandler(Popup_FilLoad, true); + Popup_Handler(FilLoad, true); gcode.process_subcommands_now(F("M702")); planner.synchronize(); - redrawMenu(true, true, true); + Redraw_Menu(true, true, true); break; case CHANGEFIL_CHANGE: - popupHandler(Popup_FilChange); - gcode.process_subcommands_now(TS(F("M600 B1 R"), thermalManager.degTargetHotend(0))); + Popup_Handler(FilChange); + sprintf_P(cmd, PSTR("M600 B1 R%i"), thermalManager.temp_hotend[0].target); + gcode.process_subcommands_now(cmd); break; } break; #endif default: - redrawMenu(true, true, true); + Redraw_Menu(true, true, true); break; } } break; + #define _PREHEAT_HOTEND_CASE(N) \ case PREHEATHOTEND_##N: \ - if (draw) drawMenuItem(row, ICON_Temperature, F(PREHEAT_## N ##_LABEL)); \ + if (draw) Draw_Menu_Item(row, ICON_Temperature, F(PREHEAT_## N ##_LABEL)); \ else ui.preheat_hotend_and_fan((N) - 1); \ break; @@ -4054,383 +3814,283 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra case PREHEATHOTEND_CUSTOM: if (draw) { - drawMenuItem(row, ICON_Temperature, F("Custom")); - drawFloat(thermalManager.degTargetHotend(0), row, false, 1); + Draw_Menu_Item(row, ICON_Temperature, F("Custom")); + Draw_Float(thermalManager.temp_hotend[0].target, row, false, 1); } else - modifyValue(thermalManager.temp_hotend[0].target, EXTRUDE_MINTEMP, MAX_E_TEMP, 1); + Modify_Value(thermalManager.temp_hotend[0].target, EXTRUDE_MINTEMP, MAX_E_TEMP, 1); break; } break; #endif // HAS_PREHEAT && HAS_HOTEND - - #if ENABLED(FWRETRACT) - case ID_FWMenu: - #define FWRETRACT_BACK 0 - #define FWRETRACT_RETLEN (FWRETRACT_BACK + 1) - #define FWRETRACT_RETSPD (FWRETRACT_RETLEN + 1) - #define FWRETRACT_RETZHOP (FWRETRACT_RETSPD + 1) - #define FWRETRACT_RECSPD (FWRETRACT_RETZHOP + 1) - #define FWRETRACT_RECLEN (FWRETRACT_RECSPD + 1) - #define FWRETRACT_TOTAL (FWRETRACT_RECLEN + 1) - - switch (item) { - case FWRETRACT_BACK: - if (draw) - drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BUTTON_BACK)); - else { - if (last_menu == ID_Prepare) - drawMenu(ID_Prepare, PREPARE_FWRETRACT); - else if (last_menu == ID_Tune) - drawMenu(ID_Tune, TUNE_FWRETRACT); - } - break; - case FWRETRACT_RETLEN: - if (draw) { - drawMenuItem(row, ICON_FWRetLength, GET_TEXT_F(MSG_CONTROL_RETRACT)); - drawFloat(fwretract.settings.retract_length, row, false, 10); - } - else - modifyValue(fwretract.settings.retract_length, 0, 10, 10); - break; - case FWRETRACT_RETSPD: - if (draw) { - drawMenuItem(row, ICON_FWRetLength, GET_TEXT_F(MSG_SINGLENOZZLE_RETRACT_SPEED)); - drawFloat(fwretract.settings.retract_feedrate_mm_s, row, false, 1); - } - else - modifyValue(fwretract.settings.retract_feedrate_mm_s, 1, 90, 1); - break; - case FWRETRACT_RETZHOP: - if (draw) { - drawMenuItem(row, ICON_FWRetLength, GET_TEXT_F(MSG_CONTROL_RETRACT_ZHOP)); - drawFloat(fwretract.settings.retract_zraise, row, false, 100); - } - else - modifyValue(fwretract.settings.retract_zraise, 0, 2, 100); - break; - case FWRETRACT_RECSPD: - if (draw) { - drawMenuItem(row, ICON_FWRetLength, GET_TEXT_F(MSG_SINGLENOZZLE_UNRETRACT_SPEED)); - drawFloat(fwretract.settings.retract_recover_feedrate_mm_s, row, false, 1); - } - else - modifyValue(fwretract.settings.retract_recover_feedrate_mm_s, 1, 90, 1); - break; - case FWRETRACT_RECLEN: - if (draw) { - drawMenuItem(row, ICON_FWRetLength, GET_TEXT_F(MSG_CONTROL_RETRACT_RECOVER)); - drawFloat(fwretract.settings.retract_recover_extra, row, false, 10); - } - else - modifyValue(fwretract.settings.retract_recover_extra, -5, 5, 10); - break; - } - break; - #endif } } -FSTR_P JyersDWIN::getMenuTitle(const uint8_t menu) { +FSTR_P CrealityDWINClass::Get_Menu_Title(uint8_t menu) { switch (menu) { - case ID_MainMenu: return GET_TEXT_F(MSG_MAIN_MENU); - case ID_Prepare: return GET_TEXT_F(MSG_PREPARE); - case ID_HomeMenu: return F("Homing Menu"); - case ID_Move: return GET_TEXT_F(MSG_MOVE_AXIS); - case ID_ManualLevel: return GET_TEXT_F(MSG_BED_TRAMMING_MANUAL); + case MainMenu: return F("Main Menu"); + case Prepare: return F("Prepare"); + case HomeMenu: return F("Homing Menu"); + case Move: return F("Move"); + case ManualLevel: return F("Manual Leveling"); #if HAS_ZOFFSET_ITEM - case ID_ZOffset: return GET_TEXT_F(MSG_ZPROBE_ZOFFSET); + case ZOffset: return F("Z Offset"); #endif #if HAS_PREHEAT - case ID_Preheat: return F("Preheat"); + case Preheat: return F("Preheat"); #endif #if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES) - case ID_ChangeFilament: return GET_TEXT_F(MSG_FILAMENTCHANGE); + case ChangeFilament: return F("Change Filament"); #endif #if HAS_CUSTOM_MENU - case ID_MenuCustom: + case MenuCustom: #ifdef CUSTOM_MENU_CONFIG_TITLE return F(CUSTOM_MENU_CONFIG_TITLE); #else - return GET_TEXT_F(MSG_CUSTOM_COMMANDS); + return F("Custom Commands"); #endif #endif - #if ENABLED(FWRETRACT) - case ID_FWMenu: return GET_TEXT_F(MSG_FWRETRACT); + case Control: return F("Control"); + case TempMenu: return F("Temperature"); + #if HAS_HOTEND || HAS_HEATED_BED + case PID: return F("PID Menu"); #endif - case ID_Control: return GET_TEXT_F(MSG_CONTROL); - case ID_TempMenu: return GET_TEXT_F(MSG_TEMPERATURE); - #if ANY(PIDTEMP, PIDTEMPBED) - case ID_PID: return F("PID Menu"); + #if HAS_HOTEND + case HotendPID: return F("Hotend PID Settings"); #endif - #if ENABLED(PIDTEMP) - case ID_HotendPID: return F("Hotend PID Settings"); - #endif - #if ENABLED(PIDTEMPBED) - case ID_BedPID: return F("Bed PID Settings"); - #endif - #if ANY(MPC_EDIT_MENU, MPC_AUTOTUNE_MENU) - case ID_MPC: return F("MPC Menu"); + #if HAS_HEATED_BED + case BedPID: return F("Bed PID Settings"); #endif #if HAS_PREHEAT - #define _PREHEAT_TITLE_CASE(N) case ID_Preheat##N: return F(PREHEAT_## N ##_LABEL " Settings"); + #define _PREHEAT_TITLE_CASE(N) case Preheat##N: return F(PREHEAT_## N ##_LABEL " Settings"); REPEAT_1(PREHEAT_COUNT, _PREHEAT_TITLE_CASE) #endif - case ID_Motion: return GET_TEXT_F(MSG_MOTION); - case ID_HomeOffsets: return GET_TEXT_F(MSG_SET_HOME_OFFSETS); - case ID_MaxSpeed: return GET_TEXT_F(MSG_MAX_SPEED); - case ID_MaxAcceleration: return F("Max Acceleration"); - #if ENABLED(CLASSIC_JERK) - case ID_MaxJerk: return F("Max Jerk"); + case Motion: return F("Motion Settings"); + case HomeOffsets: return F("Home Offsets"); + case MaxSpeed: return F("Max Speed"); + case MaxAcceleration: return F("Max Acceleration"); + #if HAS_CLASSIC_JERK + case MaxJerk: return F("Max Jerk"); #endif - #if ENABLED(EDITABLE_STEPS_PER_UNIT) - case ID_Steps: return GET_TEXT_F(MSG_STEPS_PER_MM); - #endif - case ID_Visual: return F("Visual Settings"); - case ID_Advanced: return GET_TEXT_F(MSG_ADVANCED_SETTINGS); + case Steps: return F("Steps/mm"); + case Visual: return F("Visual Settings"); + case Advanced: return F("Advanced Settings"); #if HAS_BED_PROBE - case ID_ProbeMenu: return F("Bed Probe"); + case ProbeMenu: return F("Probe Menu"); #endif - #if HAS_TRINAMIC_CONFIG - case ID_TMCMenu: return GET_TEXT_F(MSG_TMC_DRIVERS); - #endif - case ID_ColorSettings: return F("UI Color Settings"); - case ID_Info: return GET_TEXT_F(MSG_BUTTON_INFO); - case ID_InfoMain: return GET_TEXT_F(MSG_BUTTON_INFO); + case ColorSettings: return F("UI Color Settings"); + case Info: return F("Info"); + case InfoMain: return F("Info"); #if HAS_MESH - case ID_Leveling: return GET_TEXT_F(MSG_BED_LEVELING); - case ID_LevelView: return GET_TEXT_F(MSG_MESH_VIEW); - case ID_LevelSettings: return F("Leveling Settings"); - case ID_MeshViewer: return GET_TEXT_F(MSG_MESH_VIEW); - case ID_LevelManual: return F("Manual Tuning"); + case Leveling: return F("Leveling"); + case LevelView: return GET_TEXT_F(MSG_MESH_VIEW); + case LevelSettings: return F("Leveling Settings"); + case MeshViewer: return GET_TEXT_F(MSG_MESH_VIEW); + case LevelManual: return F("Manual Tuning"); #endif #if ENABLED(AUTO_BED_LEVELING_UBL) && !HAS_BED_PROBE - case ID_UBLMesh: return F("UBL Bed Leveling"); + case UBLMesh: return F("UBL Bed Leveling"); #endif #if ENABLED(PROBE_MANUALLY) - case ID_ManualMesh: return GET_TEXT_F(MSG_MANUAL_LEVELING); + case ManualMesh: return F("Mesh Bed Leveling"); #endif - case ID_Tune: return GET_TEXT_F(MSG_TUNE); - case ID_PreheatHotend: return GET_TEXT_F(MSG_PREHEAT_HOTEND); + case Tune: return F("Tune"); + case PreheatHotend: return F("Preheat Hotend"); } return F(""); } -uint8_t JyersDWIN::getMenuSize(const uint8_t menu) { +uint8_t CrealityDWINClass::Get_Menu_Size(uint8_t menu) { switch (menu) { - case ID_Prepare: return PREPARE_TOTAL; - case ID_HomeMenu: return HOME_TOTAL; - case ID_Move: return MOVE_TOTAL; - case ID_ManualLevel: return MLEVEL_TOTAL; + case Prepare: return PREPARE_TOTAL; + case HomeMenu: return HOME_TOTAL; + case Move: return MOVE_TOTAL; + case ManualLevel: return MLEVEL_TOTAL; #if HAS_ZOFFSET_ITEM - case ID_ZOffset: return ZOFFSET_TOTAL; + case ZOffset: return ZOFFSET_TOTAL; #endif #if HAS_PREHEAT - case ID_Preheat: return PREHEAT_TOTAL; + case Preheat: return PREHEAT_TOTAL; #endif #if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES) - case ID_ChangeFilament: return CHANGEFIL_TOTAL; + case ChangeFilament: return CHANGEFIL_TOTAL; #endif #if HAS_CUSTOM_MENU - case ID_MenuCustom: return CUSTOM_MENU_TOTAL; + case MenuCustom: return CUSTOM_MENU_TOTAL; #endif - #if ENABLED(FWRETRACT) - case ID_FWMenu: return FWRETRACT_TOTAL; + case Control: return CONTROL_TOTAL; + case TempMenu: return TEMP_TOTAL; + #if HAS_HOTEND || HAS_HEATED_BED + case PID: return PID_TOTAL; #endif - case ID_Control: return CONTROL_TOTAL; - case ID_TempMenu: return TEMP_TOTAL; - #if ANY(PIDTEMP, PIDTEMPBED) - case ID_PID: return PID_TOTAL; + #if HAS_HOTEND + case HotendPID: return HOTENDPID_TOTAL; #endif - #if ENABLED(PIDTEMP) - case ID_HotendPID: return HOTENDPID_TOTAL; - #endif - #if ENABLED(PIDTEMPBED) - case ID_BedPID: return BEDPID_TOTAL; - #endif - #if ANY(MPC_EDIT_MENU, MPC_AUTOTUNE_MENU) - case ID_MPC: return MPCMENU_TOTAL; + #if HAS_HEATED_BED + case BedPID: return BEDPID_TOTAL; #endif #if HAS_PREHEAT - case ID_Preheat1 ... CAT(ID_Preheat, PREHEAT_COUNT): + case Preheat1 ... CAT(Preheat, PREHEAT_COUNT): return PREHEAT_SUBMENU_TOTAL; #endif - case ID_Motion: return MOTION_TOTAL; - case ID_HomeOffsets: return HOMEOFFSETS_TOTAL; - case ID_MaxSpeed: return SPEED_TOTAL; - case ID_MaxAcceleration: return ACCEL_TOTAL; - #if ENABLED(CLASSIC_JERK) - case ID_MaxJerk: return JERK_TOTAL; + case Motion: return MOTION_TOTAL; + case HomeOffsets: return HOMEOFFSETS_TOTAL; + case MaxSpeed: return SPEED_TOTAL; + case MaxAcceleration: return ACCEL_TOTAL; + #if HAS_CLASSIC_JERK + case MaxJerk: return JERK_TOTAL; #endif - #if ENABLED(EDITABLE_STEPS_PER_UNIT) - case ID_Steps: return STEPS_TOTAL; - #endif - case ID_Visual: return VISUAL_TOTAL; - case ID_Advanced: return ADVANCED_TOTAL; + case Steps: return STEPS_TOTAL; + case Visual: return VISUAL_TOTAL; + case Advanced: return ADVANCED_TOTAL; #if HAS_BED_PROBE - case ID_ProbeMenu: return PROBE_TOTAL; + case ProbeMenu: return PROBE_TOTAL; #endif - #if HAS_TRINAMIC_CONFIG - case ID_TMCMenu: return TMC_TOTAL; - #endif - case ID_Info: return INFO_TOTAL; - case ID_InfoMain: return INFO_TOTAL; + case Info: return INFO_TOTAL; + case InfoMain: return INFO_TOTAL; #if ENABLED(AUTO_BED_LEVELING_UBL) && !HAS_BED_PROBE - case ID_UBLMesh: return UBL_M_TOTAL; + case UBLMesh: return UBL_M_TOTAL; #endif #if ENABLED(PROBE_MANUALLY) - case ID_ManualMesh: return MMESH_TOTAL; + case ManualMesh: return MMESH_TOTAL; #endif #if HAS_MESH - case ID_Leveling: return LEVELING_TOTAL; - case ID_LevelView: return LEVELING_VIEW_TOTAL; - case ID_LevelSettings: return LEVELING_SETTINGS_TOTAL; - case ID_MeshViewer: return MESHVIEW_TOTAL; - case ID_LevelManual: return LEVELING_M_TOTAL; + case Leveling: return LEVELING_TOTAL; + case LevelView: return LEVELING_VIEW_TOTAL; + case LevelSettings: return LEVELING_SETTINGS_TOTAL; + case MeshViewer: return MESHVIEW_TOTAL; + case LevelManual: return LEVELING_M_TOTAL; #endif - case ID_Tune: return TUNE_TOTAL; + case Tune: return TUNE_TOTAL; #if HAS_PREHEAT && HAS_HOTEND - case ID_PreheatHotend: return PREHEATHOTEND_TOTAL; + case PreheatHotend: return PREHEATHOTEND_TOTAL; #endif - case ID_ColorSettings: return COLORSETTINGS_TOTAL; + case ColorSettings: return COLORSETTINGS_TOTAL; } return 0; } -// -// Popup Config -// +/* Popup Config */ -void JyersDWIN::popupHandler(const PopupID popupid, const bool option/*=false*/) { +void CrealityDWINClass::Popup_Handler(PopupID popupid, bool option/*=false*/) { popup = last_popup = popupid; - FSTR_P const PWID = F("Please wait until done."); switch (popupid) { - case Popup_Pause: drawPopup(GET_TEXT_F(MSG_PAUSE_PRINT), F(""), F(""), Proc_Popup); break; - case Popup_Stop: drawPopup(GET_TEXT_F(MSG_STOP_PRINT), F(""), F(""), Proc_Popup); break; - case Popup_Resume: drawPopup(F("Resume Print?"), F("Looks Like the last"), F("print was interrupted."), Proc_Popup); break; - case Popup_ConfFilChange: drawPopup(F("Confirm Filament Change"), F(""), F(""), Proc_Popup); break; - case Popup_PurgeMore: drawPopup(F("Purge more filament?"), F("(Cancel to finish process)"), F(""), Proc_Popup); break; - #if ENABLED(AUTO_BED_LEVELING_UBL) - case Popup_SaveLevel: drawPopup(GET_TEXT_F(MSG_LEVEL_BED_DONE), F("Save to EEPROM?"), F(""), Proc_Popup); break; - case Popup_MeshSlot: drawPopup(F("Mesh slot not selected"), F("(Confirm to select slot 0)"), F(""), Proc_Popup); break; - #endif - case Popup_ETemp: drawPopup(GET_TEXT_F(MSG_HOTEND_TOO_COLD), F("Open Preheat Menu?"), F(""), Proc_Popup); break; - case Popup_ManualProbing: drawPopup(F("Manual Probing"), F("(Confirm to probe)"), F("(cancel to exit)"), Proc_Popup); break; - case Popup_Level: drawPopup(GET_TEXT_F(MSG_BED_LEVELING), PWID, F(""), Proc_Wait, ICON_AutoLeveling); break; - case Popup_Home: drawPopup(option ? F("Parking") : GET_TEXT_F(MSG_HOMING), PWID, F(""), Proc_Wait, ICON_BLTouch); break; - case Popup_MoveWait: drawPopup(GET_TEXT_F(MSG_UBL_MOVING_TO_NEXT), PWID, F(""), Proc_Wait, ICON_BLTouch); break; - case Popup_Heating: drawPopup(GET_TEXT_F(MSG_HEATING), PWID, F(""), Proc_Wait, ICON_BLTouch); break; - case Popup_FilLoad: drawPopup(option ? F("Unloading Filament") : F("Loading Filament"), PWID, F(""), Proc_Wait, ICON_BLTouch); break; - case Popup_FilChange: drawPopup(F("Filament Change"), F("Please wait for prompt."), F(""), Proc_Wait, ICON_BLTouch); break; - case Popup_TempWarn: drawPopup(option ? F("Nozzle temp too low!") : F("Nozzle temp too high!"), F(""), F(""), Proc_Wait, option ? ICON_TempTooLow : ICON_TempTooHigh); break; - #if ENABLED(FILAMENT_RUNOUT_SENSOR) - case Popup_Runout: drawPopup(F("Filament Runout"), F(""), F(""), Proc_Wait, ICON_BLTouch); break; - #endif - #if ANY(PIDTEMP, PIDTEMPBED) - case Popup_PIDWait: drawPopup(GET_TEXT_F(MSG_PID_AUTOTUNE), F("in progress"), PWID, Proc_Wait, ICON_BLTouch); break; - #endif - #if ENABLED(MPC_AUTOTUNE_MENU) - case Popup_MPCWait: drawPopup(GET_TEXT_F(MSG_MPC_AUTOTUNE), F("in progress"), PWID, Proc_Wait, ICON_BLTouch); break; - #endif - case Popup_Resuming: drawPopup(F("Resuming Print"), PWID, F(""), Proc_Wait, ICON_BLTouch); break; - case Popup_Custom: drawPopup(F("Running Custom G-Code"), PWID, F(""), Proc_Wait, ICON_BLTouch); break; + case Pause: Draw_Popup(F("Pause Print"), F(""), F(""), Popup); break; + case Stop: Draw_Popup(F("Stop Print"), F(""), F(""), Popup); break; + case Resume: Draw_Popup(F("Resume Print?"), F("Looks Like the last"), F("print was interrupted."), Popup); break; + case ConfFilChange: Draw_Popup(F("Confirm Filament Change"), F(""), F(""), Popup); break; + case PurgeMore: Draw_Popup(F("Purge more filament?"), F("(Cancel to finish process)"), F(""), Popup); break; + case SaveLevel: Draw_Popup(F("Leveling Complete"), F("Save to EEPROM?"), F(""), Popup); break; + case MeshSlot: Draw_Popup(F("Mesh slot not selected"), F("(Confirm to select slot 0)"), F(""), Popup); break; + case ETemp: Draw_Popup(F("Nozzle is too cold"), F("Open Preheat Menu?"), F(""), Popup); break; + case ManualProbing: Draw_Popup(F("Manual Probing"), F("(Confirm to probe)"), F("(cancel to exit)"), Popup); break; + case Level: Draw_Popup(F("Auto Bed Leveling"), F("Please wait until done."), F(""), Wait, ICON_AutoLeveling); break; + case Home: Draw_Popup(option ? F("Parking") : F("Homing"), F("Please wait until done."), F(""), Wait, ICON_BLTouch); break; + case MoveWait: Draw_Popup(F("Moving to Point"), F("Please wait until done."), F(""), Wait, ICON_BLTouch); break; + case Heating: Draw_Popup(F("Heating"), F("Please wait until done."), F(""), Wait, ICON_BLTouch); break; + case FilLoad: Draw_Popup(option ? F("Unloading Filament") : F("Loading Filament"), F("Please wait until done."), F(""), Wait, ICON_BLTouch); break; + case FilChange: Draw_Popup(F("Filament Change"), F("Please wait for prompt."), F(""), Wait, ICON_BLTouch); break; + case TempWarn: Draw_Popup(option ? F("Nozzle temp too low!") : F("Nozzle temp too high!"), F(""), F(""), Wait, option ? ICON_TempTooLow : ICON_TempTooHigh); break; + case Runout: Draw_Popup(F("Filament Runout"), F(""), F(""), Wait, ICON_BLTouch); break; + case PIDWait: Draw_Popup(F("PID Autotune"), F("in process"), F("Please wait until done."), Wait, ICON_BLTouch); break; + case Resuming: Draw_Popup(F("Resuming Print"), F("Please wait until done."), F(""), Wait, ICON_BLTouch); break; + case Custom: Draw_Popup(F("Running Custom GCode"), F("Please wait until done."), F(""), Wait, ICON_BLTouch); break; default: break; } } -void JyersDWIN::confirmHandler(PopupID popupid) { +void CrealityDWINClass::Confirm_Handler(PopupID popupid) { popup = popupid; switch (popupid) { - case Popup_FilInsert: drawPopup(F("Insert Filament"), F("Press to Continue"), F(""), Proc_Confirm); break; - case Popup_HeaterTime: drawPopup(F("Heater Timed Out"), F("Press to Reheat"), F(""), Proc_Confirm); break; - case Popup_UserInput: drawPopup(F("Waiting for Input"), F("Press to Continue"), F(""), Proc_Confirm); break; - case Popup_LevelError: drawPopup(F("Couldn't enable Leveling"), F("(Valid mesh must exist)"), F(""), Proc_Confirm); break; - case Popup_InvalidMesh: drawPopup(F("Valid mesh must exist"), F("before tuning can be"), F("performed"), Proc_Confirm); break; + case FilInsert: Draw_Popup(F("Insert Filament"), F("Press to Continue"), F(""), Confirm); break; + case HeaterTime: Draw_Popup(F("Heater Timed Out"), F("Press to Reheat"), F(""), Confirm); break; + case UserInput: Draw_Popup(F("Waiting for Input"), F("Press to Continue"), F(""), Confirm); break; + case LevelError: Draw_Popup(F("Couldn't enable Leveling"), F("(Valid mesh must exist)"), F(""), Confirm); break; + case InvalidMesh: Draw_Popup(F("Valid mesh must exist"), F("before tuning can be"), F("performed"), Confirm); break; default: break; } } -// -// Navigation and Control -// +/* Navigation and Control */ -void JyersDWIN::mainMenuControl() { - EncoderState encoder_diffState = encoderReceiveAnalyze(); +void CrealityDWINClass::Main_Menu_Control() { + EncoderState encoder_diffState = Encoder_ReceiveAnalyze(); if (encoder_diffState == ENCODER_DIFF_NO) return; if (encoder_diffState == ENCODER_DIFF_CW && selection < PAGE_COUNT - 1) { selection++; // Select Down - mainMenuIcons(); + Main_Menu_Icons(); } else if (encoder_diffState == ENCODER_DIFF_CCW && selection > 0) { selection--; // Select Up - mainMenuIcons(); + Main_Menu_Icons(); } else if (encoder_diffState == ENCODER_DIFF_ENTER) switch (selection) { - case PAGE_PRINT: card.mount(); drawSDList(); break; - case PAGE_PREPARE: drawMenu(ID_Prepare); break; - case PAGE_CONTROL: drawMenu(ID_Control); break; - case PAGE_INFO_LEVELING: drawMenu(TERN(HAS_MESH, ID_Leveling, ID_InfoMain)); break; + case PAGE_PRINT: card.mount(); Draw_SD_List(); break; + case PAGE_PREPARE: Draw_Menu(Prepare); break; + case PAGE_CONTROL: Draw_Menu(Control); break; + case PAGE_INFO_LEVELING: Draw_Menu(TERN(HAS_MESH, Leveling, InfoMain)); break; } - dwinUpdateLCD(); + DWIN_UpdateLCD(); } -void JyersDWIN::menuControl() { - EncoderState encoder_diffState = encoderReceiveAnalyze(); +void CrealityDWINClass::Menu_Control() { + EncoderState encoder_diffState = Encoder_ReceiveAnalyze(); if (encoder_diffState == ENCODER_DIFF_NO) return; - if (encoder_diffState == ENCODER_DIFF_CW && selection < getMenuSize(active_menu)) { - dwinDrawRectangle(1, COLOR_BG_BLACK, 0, MBASE(selection - scrollpos) - 18, 14, MBASE(selection - scrollpos) + 33); + if (encoder_diffState == ENCODER_DIFF_CW && selection < Get_Menu_Size(active_menu)) { + DWIN_Draw_Rectangle(1, Color_Bg_Black, 0, MBASE(selection - scrollpos) - 18, 14, MBASE(selection - scrollpos) + 33); selection++; // Select Down - if (selection > scrollpos + MROWS) { + if (selection > scrollpos+MROWS) { scrollpos++; - dwinFrameAreaMove(1, 2, MLINE, COLOR_BG_BLACK, 0, 31, DWIN_WIDTH, 349); - menuItemHandler(active_menu, selection); + DWIN_Frame_AreaMove(1, 2, MLINE, Color_Bg_Black, 0, 31, DWIN_WIDTH, 349); + Menu_Item_Handler(active_menu, selection); } - dwinDrawRectangle(1, getColor(eeprom_settings.cursor_color, COLOR_RECTANGLE), 0, MBASE(selection - scrollpos) - 18, 14, MBASE(selection - scrollpos) + 33); + DWIN_Draw_Rectangle(1, GetColor(eeprom_settings.cursor_color, Rectangle_Color), 0, MBASE(selection - scrollpos) - 18, 14, MBASE(selection - scrollpos) + 33); } else if (encoder_diffState == ENCODER_DIFF_CCW && selection > 0) { - dwinDrawRectangle(1, COLOR_BG_BLACK, 0, MBASE(selection - scrollpos) - 18, 14, MBASE(selection - scrollpos) + 33); + DWIN_Draw_Rectangle(1, Color_Bg_Black, 0, MBASE(selection - scrollpos) - 18, 14, MBASE(selection - scrollpos) + 33); selection--; // Select Up if (selection < scrollpos) { scrollpos--; - dwinFrameAreaMove(1, 3, MLINE, COLOR_BG_BLACK, 0, 31, DWIN_WIDTH, 349); - menuItemHandler(active_menu, selection); + DWIN_Frame_AreaMove(1, 3, MLINE, Color_Bg_Black, 0, 31, DWIN_WIDTH, 349); + Menu_Item_Handler(active_menu, selection); } - dwinDrawRectangle(1, getColor(eeprom_settings.cursor_color, COLOR_RECTANGLE), 0, MBASE(selection - scrollpos) - 18, 14, MBASE(selection - scrollpos) + 33); + DWIN_Draw_Rectangle(1, GetColor(eeprom_settings.cursor_color, Rectangle_Color), 0, MBASE(selection - scrollpos) - 18, 14, MBASE(selection - scrollpos) + 33); } else if (encoder_diffState == ENCODER_DIFF_ENTER) - menuItemHandler(active_menu, selection, false); - dwinUpdateLCD(); + Menu_Item_Handler(active_menu, selection, false); + DWIN_UpdateLCD(); } -void JyersDWIN::valueControl() { - EncoderState encoder_diffState = encoderReceiveAnalyze(); +void CrealityDWINClass::Value_Control() { + EncoderState encoder_diffState = Encoder_ReceiveAnalyze(); if (encoder_diffState == ENCODER_DIFF_NO) return; if (encoder_diffState == ENCODER_DIFF_CW) - tempvalue += encoderRate.encoderMoveValue; + tempvalue += EncoderRate.encoderMoveValue; else if (encoder_diffState == ENCODER_DIFF_CCW) - tempvalue -= encoderRate.encoderMoveValue; + tempvalue -= EncoderRate.encoderMoveValue; else if (encoder_diffState == ENCODER_DIFF_ENTER) { - process = Proc_Menu; - encoderRate.enabled = false; - drawFloat(tempvalue / valueunit, selection - scrollpos, false, valueunit); - dwinUpdateLCD(); - if (active_menu == ID_ZOffset && liveadjust) { + process = Menu; + EncoderRate.enabled = false; + Draw_Float(tempvalue / valueunit, selection - scrollpos, false, valueunit); + DWIN_UpdateLCD(); + if (active_menu == ZOffset && liveadjust) { planner.synchronize(); current_position.z += (tempvalue / valueunit - zoffsetvalue); planner.buffer_line(current_position, homing_feedrate(Z_AXIS), active_extruder); current_position.z = 0; sync_plan_position(); } - else if (active_menu == ID_Tune && selection == TUNE_ZOFFSET) { - gcode.process_subcommands_now(TS(F("M290Z"), p_float_t((tempvalue / valueunit - zoffsetvalue), 3))); + else if (active_menu == Tune && selection == TUNE_ZOFFSET) { + sprintf_P(cmd, PSTR("M290 Z%s"), dtostrf((tempvalue / valueunit - zoffsetvalue), 1, 3, str_1)); + gcode.process_subcommands_now(cmd); } - if (TERN0(PIDTEMP, valuepointer == &thermalManager.temp_hotend[0].pid.Ki) || TERN0(PIDTEMPBED, valuepointer == &thermalManager.temp_bed.pid.Ki)) + if (TERN0(HAS_HOTEND, valuepointer == &thermalManager.temp_hotend[0].pid.Ki) || TERN0(HAS_HEATED_BED, valuepointer == &thermalManager.temp_bed.pid.Ki)) tempvalue = scalePID_i(tempvalue); - if (TERN0(PIDTEMP, valuepointer == &thermalManager.temp_hotend[0].pid.Kd) || TERN0(PIDTEMPBED, valuepointer == &thermalManager.temp_bed.pid.Kd)) + if (TERN0(HAS_HOTEND, valuepointer == &thermalManager.temp_hotend[0].pid.Kd) || TERN0(HAS_HEATED_BED, valuepointer == &thermalManager.temp_bed.pid.Kd)) tempvalue = scalePID_d(tempvalue); switch (valuetype) { case 0: *(float*)valuepointer = tempvalue / valueunit; break; @@ -4441,42 +4101,45 @@ void JyersDWIN::valueControl() { case 5: *(int8_t*)valuepointer = tempvalue / valueunit; break; } switch (active_menu) { - case ID_Move: + case Move: planner.synchronize(); planner.buffer_line(current_position, manual_feedrate_mm_s[selection - 1], active_extruder); break; #if HAS_MESH - case ID_ManualMesh: + case ManualMesh: planner.synchronize(); planner.buffer_line(current_position, homing_feedrate(Z_AXIS), active_extruder); planner.synchronize(); break; - case ID_UBLMesh: mesh_conf.manual_mesh_move(true); break; - case ID_LevelManual: mesh_conf.manual_mesh_move(selection == LEVELING_M_OFFSET); break; + case UBLMesh: mesh_conf.manual_mesh_move(true); break; + case LevelManual: mesh_conf.manual_mesh_move(selection == LEVELING_M_OFFSET); break; #endif } + if (valuepointer == &planner.flow_percentage[0]) + planner.refresh_e_factor(0); if (funcpointer) funcpointer(); return; } - LIMIT(tempvalue, valuemin * valueunit, valuemax * valueunit); - drawFloat(tempvalue / valueunit, selection - scrollpos, true, valueunit); - dwinUpdateLCD(); - if (active_menu == ID_Move && livemove) { + NOLESS(tempvalue, (valuemin * valueunit)); + NOMORE(tempvalue, (valuemax * valueunit)); + Draw_Float(tempvalue / valueunit, selection - scrollpos, true, valueunit); + DWIN_UpdateLCD(); + if (active_menu == Move && livemove) { *(float*)valuepointer = tempvalue / valueunit; planner.buffer_line(current_position, manual_feedrate_mm_s[selection - 1], active_extruder); } } -void JyersDWIN::optionControl() { - EncoderState encoder_diffState = encoderReceiveAnalyze(); +void CrealityDWINClass::Option_Control() { + EncoderState encoder_diffState = Encoder_ReceiveAnalyze(); if (encoder_diffState == ENCODER_DIFF_NO) return; if (encoder_diffState == ENCODER_DIFF_CW) - tempvalue += encoderRate.encoderMoveValue; + tempvalue += EncoderRate.encoderMoveValue; else if (encoder_diffState == ENCODER_DIFF_CCW) - tempvalue -= encoderRate.encoderMoveValue; + tempvalue -= EncoderRate.encoderMoveValue; else if (encoder_diffState == ENCODER_DIFF_ENTER) { - process = Proc_Menu; - encoderRate.enabled = false; + process = Menu; + EncoderRate.enabled = false; if (valuepointer == &color_names) { switch (selection) { case COLORSETTINGS_CURSOR: eeprom_settings.cursor_color = tempvalue; break; @@ -4491,29 +4154,31 @@ void JyersDWIN::optionControl() { case COLORSETTINGS_PROGRESS_COORDINATES: eeprom_settings.coordinates_text = tempvalue; break; case COLORSETTINGS_PROGRESS_COORDINATES_LINE: eeprom_settings.coordinates_split_line = tempvalue; break; } - redrawScreen(); + Redraw_Screen(); } else if (valuepointer == &preheat_modes) preheatmode = tempvalue; - drawOption(tempvalue, static_cast(valuepointer), selection - scrollpos, false, (valuepointer == &color_names)); - dwinUpdateLCD(); + Draw_Option(tempvalue, static_cast(valuepointer), selection - scrollpos, false, (valuepointer == &color_names)); + DWIN_UpdateLCD(); return; } - LIMIT(tempvalue, valuemin, valuemax); - drawOption(tempvalue, static_cast(valuepointer), selection - scrollpos, true); - dwinUpdateLCD(); + NOLESS(tempvalue, valuemin); + NOMORE(tempvalue, valuemax); + Draw_Option(tempvalue, static_cast(valuepointer), selection - scrollpos, true); + DWIN_UpdateLCD(); } -void JyersDWIN::fileControl() { +void CrealityDWINClass::File_Control() { typedef TextScroller Scroller; static Scroller scroller; - EncoderState encoder_diffState = encoderReceiveAnalyze(); + EncoderState encoder_diffState = Encoder_ReceiveAnalyze(); if (encoder_diffState == ENCODER_DIFF_NO) { if (selection > 0) { - card.selectFileByIndexSorted(selection - 1); + card.getfilename_sorted(SD_ORDER(selection - 1, card.get_num_Files())); char * const filename = card.longest_filename(); - size_t len = strlen(filename), pos = len; + size_t len = strlen(filename); + size_t pos = len; if (!card.flag.filenameIsDir) while (pos && filename[pos] != '.') pos--; if (pos > MENU_CHAR_LIMIT) { @@ -4522,81 +4187,82 @@ void JyersDWIN::fileControl() { time = millis() + 200; Scroller::Buffer buf; const char* const name = scroller.scroll(pos, buf, filename); - dwinDrawRectangle(1, COLOR_BG_BLACK, LBLX, MBASE(selection - scrollpos) - 14, 271, MBASE(selection - scrollpos) + 28); - drawMenuItem(selection - scrollpos, card.flag.filenameIsDir ? ICON_More : ICON_File, name); - dwinUpdateLCD(); + DWIN_Draw_Rectangle(1, Color_Bg_Black, LBLX, MBASE(selection - scrollpos) - 14, 271, MBASE(selection - scrollpos) + 28); + Draw_Menu_Item(selection - scrollpos, card.flag.filenameIsDir ? ICON_More : ICON_File, name); + DWIN_UpdateLCD(); } } return; } - if (encoder_diffState == ENCODER_DIFF_CW && selection < card.get_num_items()) { - dwinDrawRectangle(1, COLOR_BG_BLACK, 0, MBASE(selection - scrollpos) - 18, 14, MBASE(selection - scrollpos) + 33); + if (encoder_diffState == ENCODER_DIFF_CW && selection < card.get_num_Files()) { + DWIN_Draw_Rectangle(1, Color_Bg_Black, 0, MBASE(selection - scrollpos) - 18, 14, MBASE(selection - scrollpos) + 33); if (selection > 0) { - dwinDrawRectangle(1, COLOR_BG_BLACK, LBLX, MBASE(selection - scrollpos) - 14, 271, MBASE(selection - scrollpos) + 28); - drawSDItem(selection, selection - scrollpos); + DWIN_Draw_Rectangle(1, Color_Bg_Black, LBLX, MBASE(selection - scrollpos) - 14, 271, MBASE(selection - scrollpos) + 28); + Draw_SD_Item(selection, selection - scrollpos); } scroller.reset(); selection++; // Select Down if (selection > scrollpos + MROWS) { scrollpos++; - dwinFrameAreaMove(1, 2, MLINE, COLOR_BG_BLACK, 0, 31, DWIN_WIDTH, 349); - drawSDItem(selection, selection - scrollpos); + DWIN_Frame_AreaMove(1, 2, MLINE, Color_Bg_Black, 0, 31, DWIN_WIDTH, 349); + Draw_SD_Item(selection, selection - scrollpos); } - dwinDrawRectangle(1, getColor(eeprom_settings.cursor_color, COLOR_RECTANGLE), 0, MBASE(selection - scrollpos) - 18, 14, MBASE(selection - scrollpos) + 33); + DWIN_Draw_Rectangle(1, GetColor(eeprom_settings.cursor_color, Rectangle_Color), 0, MBASE(selection - scrollpos) - 18, 14, MBASE(selection - scrollpos) + 33); } else if (encoder_diffState == ENCODER_DIFF_CCW && selection > 0) { - dwinDrawRectangle(1, COLOR_BG_BLACK, 0, MBASE(selection - scrollpos) - 18, 14, MBASE(selection - scrollpos) + 33); - dwinDrawRectangle(1, COLOR_BG_BLACK, LBLX, MBASE(selection - scrollpos) - 14, 271, MBASE(selection - scrollpos) + 28); - drawSDItem(selection, selection - scrollpos); + DWIN_Draw_Rectangle(1, Color_Bg_Black, 0, MBASE(selection - scrollpos) - 18, 14, MBASE(selection - scrollpos) + 33); + DWIN_Draw_Rectangle(1, Color_Bg_Black, LBLX, MBASE(selection - scrollpos) - 14, 271, MBASE(selection - scrollpos) + 28); + Draw_SD_Item(selection, selection - scrollpos); scroller.reset(); selection--; // Select Up if (selection < scrollpos) { scrollpos--; - dwinFrameAreaMove(1, 3, MLINE, COLOR_BG_BLACK, 0, 31, DWIN_WIDTH, 349); - drawSDItem(selection, selection - scrollpos); + DWIN_Frame_AreaMove(1, 3, MLINE, Color_Bg_Black, 0, 31, DWIN_WIDTH, 349); + Draw_SD_Item(selection, selection - scrollpos); } - dwinDrawRectangle(1, getColor(eeprom_settings.cursor_color, COLOR_RECTANGLE), 0, MBASE(selection - scrollpos) - 18, 14, MBASE(selection - scrollpos) + 33); + DWIN_Draw_Rectangle(1, GetColor(eeprom_settings.cursor_color, Rectangle_Color), 0, MBASE(selection - scrollpos) - 18, 14, MBASE(selection - scrollpos) + 33); } else if (encoder_diffState == ENCODER_DIFF_ENTER) { if (selection == 0) { if (card.flag.workDirIsRoot) { - process = Proc_Main; - drawMainMenu(); + process = Main; + Draw_Main_Menu(); } else { card.cdup(); - drawSDList(); + Draw_SD_List(); } } else { - card.selectFileByIndexSorted(selection - 1); + card.getfilename_sorted(SD_ORDER(selection - 1, card.get_num_Files())); if (card.flag.filenameIsDir) { card.cd(card.filename); - drawSDList(); + Draw_SD_List(); } - else + else { card.openAndPrintFile(card.filename); + } } } - dwinUpdateLCD(); + DWIN_UpdateLCD(); } -void JyersDWIN::printScreenControl() { - EncoderState encoder_diffState = encoderReceiveAnalyze(); +void CrealityDWINClass::Print_Screen_Control() { + EncoderState encoder_diffState = Encoder_ReceiveAnalyze(); if (encoder_diffState == ENCODER_DIFF_NO) return; if (encoder_diffState == ENCODER_DIFF_CW && selection < PRINT_COUNT - 1) { selection++; // Select Down - printScreenIcons(); + Print_Screen_Icons(); } else if (encoder_diffState == ENCODER_DIFF_CCW && selection > 0) { selection--; // Select Up - printScreenIcons(); + Print_Screen_Icons(); } else if (encoder_diffState == ENCODER_DIFF_ENTER) { switch (selection) { case PRINT_SETUP: - drawMenu(ID_Tune); - updateStatusBar(true); + Draw_Menu(Tune); + Update_Status_Bar(true); break; case PRINT_PAUSE_RESUME: if (paused) { @@ -4606,53 +4272,56 @@ void JyersDWIN::printScreenControl() { card.startOrResumeFilePrinting(); TERN_(POWER_LOSS_RECOVERY, recovery.prepare()); #else + char cmd[20]; #if HAS_HEATED_BED - gcode.process_subcommands_now(TS(F("M140 S"), pausebed)); + sprintf_P(cmd, PSTR("M140 S%i"), pausebed); + gcode.process_subcommands_now(cmd); #endif #if HAS_EXTRUDERS - gcode.process_subcommands_now(TS(F("M109 S"), pausetemp)); + sprintf_P(cmd, PSTR("M109 S%i"), pausetemp); + gcode.process_subcommands_now(cmd); #endif TERN_(HAS_FAN, thermalManager.fan_speed[0] = pausefan); planner.synchronize(); - TERN_(HAS_MEDIA, queue.inject(FPSTR(M24_STR))); + TERN_(SDSUPPORT, queue.inject(F("M24"))); #endif } else { TERN_(HOST_ACTION_COMMANDS, hostui.resume()); } - drawPrintScreen(); + Draw_Print_Screen(); } else - popupHandler(Popup_Pause); + Popup_Handler(Pause); break; - case PRINT_STOP: popupHandler(Popup_Stop); break; + case PRINT_STOP: Popup_Handler(Stop); break; } } - dwinUpdateLCD(); + DWIN_UpdateLCD(); } -void JyersDWIN::popupControl() { - EncoderState encoder_diffState = encoderReceiveAnalyze(); +void CrealityDWINClass::Popup_Control() { + EncoderState encoder_diffState = Encoder_ReceiveAnalyze(); if (encoder_diffState == ENCODER_DIFF_NO) return; if (encoder_diffState == ENCODER_DIFF_CW && selection < 1) { selection++; - popupSelect(); + Popup_Select(); } else if (encoder_diffState == ENCODER_DIFF_CCW && selection > 0) { selection--; - popupSelect(); + Popup_Select(); } else if (encoder_diffState == ENCODER_DIFF_ENTER) { switch (popup) { - case Popup_Pause: + case Pause: if (selection == 0) { if (sdprint) { #if ENABLED(POWER_LOSS_RECOVERY) if (recovery.enabled) recovery.save(true); #endif #if ENABLED(PARK_HEAD_ON_PAUSE) - popupHandler(Popup_Home, true); - #if HAS_MEDIA + Popup_Handler(Home, true); + #if ENABLED(SDSUPPORT) if (IS_SD_PRINTING()) card.pauseSDPrint(); #endif planner.synchronize(); @@ -4660,8 +4329,8 @@ void JyersDWIN::popupControl() { planner.synchronize(); #else queue.inject(F("M25")); - TERN_(HAS_HOTEND, pausetemp = thermalManager.degTargetHotend(0)); - TERN_(HAS_HEATED_BED, pausebed = thermalManager.degTargetBed()); + TERN_(HAS_HOTEND, pausetemp = thermalManager.temp_hotend[0].target); + TERN_(HAS_HEATED_BED, pausebed = thermalManager.temp_bed.target); TERN_(HAS_FAN, pausefan = thermalManager.fan_speed[0]); thermalManager.cooldown(); #endif @@ -4670,9 +4339,9 @@ void JyersDWIN::popupControl() { TERN_(HOST_ACTION_COMMANDS, hostui.pause()); } } - drawPrintScreen(); + Draw_Print_Screen(); break; - case Popup_Stop: + case Stop: if (selection == 0) { if (sdprint) { ui.abort_print(); @@ -4683,132 +4352,133 @@ void JyersDWIN::popupControl() { } } else - drawPrintScreen(); + Draw_Print_Screen(); break; - case Popup_Resume: + case Resume: if (selection == 0) queue.inject(F("M1000")); else { queue.inject(F("M1000 C")); - drawMainMenu(); + Draw_Main_Menu(); } break; #if HAS_HOTEND - case Popup_ETemp: + case ETemp: if (selection == 0) { thermalManager.setTargetHotend(EXTRUDE_MINTEMP, 0); - TERN_(HAS_FAN, thermalManager.set_fan_speed(0, MAX_FAN_SPEED)); - drawMenu(ID_PreheatHotend); + thermalManager.set_fan_speed(0, MAX_FAN_SPEED); + Draw_Menu(PreheatHotend); } else - redrawMenu(true, true, false); + Redraw_Menu(true, true, false); break; #endif #if HAS_BED_PROBE - case Popup_ManualProbing: + case ManualProbing: if (selection == 0) { + char buf[80]; const float dif = probe.probe_at_point(current_position.x, current_position.y, PROBE_PT_STOW, 0, false) - corner_avg; - updateStatus(TS(F("Corner is "), p_float_t(abs(dif), 3), "mm ", dif > 0 ? F("high") : F("low"))); + sprintf_P(buf, dif > 0 ? PSTR("Corner is %smm high") : PSTR("Corner is %smm low"), dtostrf(abs(dif), 1, 3, str_1)); + Update_Status(buf); } else { - redrawMenu(true, true, false); - updateStatus(""); + Redraw_Menu(true, true, false); + Update_Status(""); } break; #endif #if ENABLED(ADVANCED_PAUSE_FEATURE) - case Popup_ConfFilChange: + case ConfFilChange: if (selection == 0) { - if (thermalManager.targetTooColdToExtrude(0)) - popupHandler(Popup_ETemp); + if (thermalManager.temp_hotend[0].target < thermalManager.extrude_min_temp) + Popup_Handler(ETemp); else { - if (thermalManager.temp_hotend[0].is_below_target(2)) { - popupHandler(Popup_Heating); + if (thermalManager.temp_hotend[0].is_below_target(-2)) { + Popup_Handler(Heating); thermalManager.wait_for_hotend(0); } - popupHandler(Popup_FilChange); - gcode.process_subcommands_now(TS(F("M600B1R"), thermalManager.degTargetHotend(0))); + Popup_Handler(FilChange); + sprintf_P(cmd, PSTR("M600 B1 R%i"), thermalManager.temp_hotend[0].target); + gcode.process_subcommands_now(cmd); } } else - redrawMenu(true, true, false); + Redraw_Menu(true, true, false); break; - case Popup_PurgeMore: + case PurgeMore: if (selection == 0) { pause_menu_response = PAUSE_RESPONSE_EXTRUDE_MORE; - popupHandler(Popup_FilChange); + Popup_Handler(FilChange); } else { pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT; - if (printing) popupHandler(Popup_Resuming); - else redrawMenu(true, true, active_menu == ID_PreheatHotend); + if (printing) Popup_Handler(Resuming); + else Redraw_Menu(true, true, (active_menu==PreheatHotend)); } break; #endif // ADVANCED_PAUSE_FEATURE #if HAS_MESH - case Popup_SaveLevel: + case SaveLevel: if (selection == 0) { #if ENABLED(AUTO_BED_LEVELING_UBL) gcode.process_subcommands_now(F("G29 S")); planner.synchronize(); - audioFeedback(true); + AudioFeedback(true); #else - audioFeedback(settings.save()); + AudioFeedback(settings.save()); #endif } - drawMenu(ID_Leveling, LEVELING_GET_MESH); + Draw_Menu(Leveling, LEVELING_GET_MESH); break; #endif #if ENABLED(AUTO_BED_LEVELING_UBL) - case Popup_MeshSlot: + case MeshSlot: if (selection == 0) bedlevel.storage_slot = 0; - redrawMenu(true, true); + Redraw_Menu(true, true); break; #endif default: break; } } - dwinUpdateLCD(); + DWIN_UpdateLCD(); } -void JyersDWIN::confirmControl() { - EncoderState encoder_diffState = encoderReceiveAnalyze(); +void CrealityDWINClass::Confirm_Control() { + EncoderState encoder_diffState = Encoder_ReceiveAnalyze(); if (encoder_diffState == ENCODER_DIFF_NO) return; if (encoder_diffState == ENCODER_DIFF_ENTER) { switch (popup) { - case Popup_Complete: - drawMainMenu(); + case Complete: + Draw_Main_Menu(); break; - case Popup_FilInsert: - popupHandler(Popup_FilChange); + case FilInsert: + Popup_Handler(FilChange); wait_for_user = false; break; - case Popup_HeaterTime: - popupHandler(Popup_Heating); + case HeaterTime: + Popup_Handler(Heating); wait_for_user = false; break; default: - redrawMenu(true, true, false); + Redraw_Menu(true, true, false); wait_for_user = false; break; } } - dwinUpdateLCD(); + DWIN_UpdateLCD(); } -// -// In-Menu Value Modification -// +/* In-Menu Value Modification */ -void JyersDWIN::setupValue(const_float_t value, const_float_t min, const_float_t max, const_float_t unit, const uint8_t type) { - if (TERN0(PIDTEMP, valuepointer == &thermalManager.temp_hotend[0].pid.Ki) || TERN0(PIDTEMPBED, valuepointer == &thermalManager.temp_bed.pid.Ki)) +void CrealityDWINClass::Setup_Value(float value, float min, float max, float unit, uint8_t type) { + if (TERN0(HAS_HOTEND, valuepointer == &thermalManager.temp_hotend[0].pid.Ki) || TERN0(HAS_HEATED_BED, valuepointer == &thermalManager.temp_bed.pid.Ki)) tempvalue = unscalePID_i(value) * unit; - else if (TERN0(PIDTEMP, valuepointer == &thermalManager.temp_hotend[0].pid.Kd) || TERN0(PIDTEMPBED, valuepointer == &thermalManager.temp_bed.pid.Kd)) + else if (TERN0(HAS_HOTEND, valuepointer == &thermalManager.temp_hotend[0].pid.Kd) || TERN0(HAS_HEATED_BED, valuepointer == &thermalManager.temp_bed.pid.Kd)) tempvalue = unscalePID_d(value) * unit; else tempvalue = value * unit; @@ -4816,69 +4486,67 @@ void JyersDWIN::setupValue(const_float_t value, const_float_t min, const_float_t valuemax = max; valueunit = unit; valuetype = type; - process = Proc_Value; - encoderRate.enabled = true; - drawFloat(tempvalue / unit, selection - scrollpos, true, valueunit); + process = Value; + EncoderRate.enabled = true; + Draw_Float(tempvalue / unit, selection - scrollpos, true, valueunit); } -void JyersDWIN::modifyValue(float &value, const_float_t min, const_float_t max, const_float_t unit, void (*f)()/*=nullptr*/) { +void CrealityDWINClass::Modify_Value(float &value, float min, float max, float unit, void (*f)()/*=nullptr*/) { valuepointer = &value; funcpointer = f; - setupValue((float)value, min, max, unit, 0); + Setup_Value((float)value, min, max, unit, 0); } -void JyersDWIN::modifyValue(uint8_t &value, const_float_t min, const_float_t max, const_float_t unit, void (*f)()/*=nullptr*/) { +void CrealityDWINClass::Modify_Value(uint8_t &value, float min, float max, float unit, void (*f)()/*=nullptr*/) { valuepointer = &value; funcpointer = f; - setupValue((float)value, min, max, unit, 1); + Setup_Value((float)value, min, max, unit, 1); } -void JyersDWIN::modifyValue(uint16_t &value, const_float_t min, const_float_t max, const_float_t unit, void (*f)()/*=nullptr*/) { +void CrealityDWINClass::Modify_Value(uint16_t &value, float min, float max, float unit, void (*f)()/*=nullptr*/) { valuepointer = &value; funcpointer = f; - setupValue((float)value, min, max, unit, 2); + Setup_Value((float)value, min, max, unit, 2); } -void JyersDWIN::modifyValue(int16_t &value, const_float_t min, const_float_t max, const_float_t unit, void (*f)()/*=nullptr*/) { +void CrealityDWINClass::Modify_Value(int16_t &value, float min, float max, float unit, void (*f)()/*=nullptr*/) { valuepointer = &value; funcpointer = f; - setupValue((float)value, min, max, unit, 3); + Setup_Value((float)value, min, max, unit, 3); } -void JyersDWIN::modifyValue(uint32_t &value, const_float_t min, const_float_t max, const_float_t unit, void (*f)()/*=nullptr*/) { +void CrealityDWINClass::Modify_Value(uint32_t &value, float min, float max, float unit, void (*f)()/*=nullptr*/) { valuepointer = &value; funcpointer = f; - setupValue((float)value, min, max, unit, 4); + Setup_Value((float)value, min, max, unit, 4); } -void JyersDWIN::modifyValue(int8_t &value, const_float_t min, const_float_t max, const_float_t unit, void (*f)()/*=nullptr*/) { +void CrealityDWINClass::Modify_Value(int8_t &value, float min, float max, float unit, void (*f)()/*=nullptr*/) { valuepointer = &value; funcpointer = f; - setupValue((float)value, min, max, unit, 5); + Setup_Value((float)value, min, max, unit, 5); } -void JyersDWIN::modifyOption(const uint8_t value, const char * const * options, const uint8_t max) { +void CrealityDWINClass::Modify_Option(uint8_t value, const char * const * options, uint8_t max) { tempvalue = value; valuepointer = const_cast(options); valuemin = 0; valuemax = max; - process = Proc_Option; - encoderRate.enabled = true; - drawOption(value, options, selection - scrollpos, true); + process = Option; + EncoderRate.enabled = true; + Draw_Option(value, options, selection - scrollpos, true); } -// -// Main Functions -// +/* Main Functions */ -void JyersDWIN::updateStatus(const char * const text) { +void CrealityDWINClass::Update_Status(const char * const text) { if (strncmp_P(text, PSTR(""), 3) == 0) { - for (uint8_t i = 0; i < _MIN((size_t)LONG_FILENAME_LENGTH, strlen(text)); ++i) filename[i] = text[i + 3]; + LOOP_L_N(i, _MIN((size_t)LONG_FILENAME_LENGTH, strlen(text))) filename[i] = text[i + 3]; filename[_MIN((size_t)LONG_FILENAME_LENGTH - 1, strlen(text))] = '\0'; - drawPrintFilename(true); + Draw_Print_Filename(true); } else { - for (uint8_t i = 0; i < _MIN((size_t)64, strlen(text)); ++i) statusmsg[i] = text[i]; + LOOP_L_N(i, _MIN((size_t)64, strlen(text))) statusmsg[i] = text[i]; statusmsg[_MIN((size_t)64, strlen(text))] = '\0'; } } -void JyersDWIN::startPrint(const bool sd) { +void CrealityDWINClass::Start_Print(bool sd) { sdprint = sd; if (!printing) { printing = true; @@ -4886,7 +4554,7 @@ void JyersDWIN::startPrint(const bool sd) { if (sd) { #if ENABLED(POWER_LOSS_RECOVERY) if (recovery.valid()) { - MediaFile *diveDir = nullptr; + SdFile *diveDir = nullptr; const char * const fname = card.diveToFile(true, diveDir, recovery.info.sd_filename); card.selectFileByName(fname); } @@ -4897,59 +4565,59 @@ void JyersDWIN::startPrint(const bool sd) { strcpy_P(filename, PSTR("Host Print")); TERN_(SET_PROGRESS_PERCENT, ui.set_progress(0)); TERN_(SET_REMAINING_TIME, ui.set_remaining_time(0)); - drawPrintScreen(); + Draw_Print_Screen(); } } -void JyersDWIN::stopPrint() { +void CrealityDWINClass::Stop_Print() { printing = false; sdprint = false; thermalManager.cooldown(); TERN_(SET_PROGRESS_PERCENT, ui.set_progress(100 * (PROGRESS_SCALE))); TERN_(SET_REMAINING_TIME, ui.set_remaining_time(0)); - drawPrintConfirm(); + Draw_Print_confirm(); } -void JyersDWIN::update() { - stateUpdate(); - screenUpdate(); +void CrealityDWINClass::Update() { + State_Update(); + Screen_Update(); switch (process) { - case Proc_Main: mainMenuControl(); break; - case Proc_Menu: menuControl(); break; - case Proc_Value: valueControl(); break; - case Proc_Option: optionControl(); break; - case Proc_File: fileControl(); break; - case Proc_Print: printScreenControl(); break; - case Proc_Popup: popupControl(); break; - case Proc_Confirm: confirmControl(); break; + case Main: Main_Menu_Control(); break; + case Menu: Menu_Control(); break; + case Value: Value_Control(); break; + case Option: Option_Control(); break; + case File: File_Control(); break; + case Print: Print_Screen_Control(); break; + case Popup: Popup_Control(); break; + case Confirm: Confirm_Control(); break; } } -void MarlinUI::update() { jyersDWIN.update(); } +void MarlinUI::update() { CrealityDWIN.Update(); } #if HAS_LCD_BRIGHTNESS - void MarlinUI::_set_brightness() { dwinLCDBrightness(backlight ? brightness : 0); } + void MarlinUI::_set_brightness() { DWIN_LCD_Brightness(backlight ? brightness : 0); } #endif -void JyersDWIN::stateUpdate() { +void CrealityDWINClass::State_Update() { if ((print_job_timer.isRunning() || print_job_timer.isPaused()) != printing) { - if (!printing) startPrint(card.isFileOpen() || TERN0(POWER_LOSS_RECOVERY, recovery.valid())); - else stopPrint(); + if (!printing) Start_Print(card.isFileOpen() || TERN0(POWER_LOSS_RECOVERY, recovery.valid())); + else Stop_Print(); } if (print_job_timer.isPaused() != paused) { paused = print_job_timer.isPaused(); - if (process == Proc_Print) printScreenIcons(); - if (process == Proc_Wait && !paused) redrawMenu(true, true); + if (process == Print) Print_Screen_Icons(); + if (process == Wait && !paused) Redraw_Menu(true, true); } - if (wait_for_user && !(process == Proc_Confirm) && !print_job_timer.isPaused()) - confirmHandler(Popup_UserInput); + if (wait_for_user && !(process == Confirm) && !print_job_timer.isPaused()) + Confirm_Handler(UserInput); #if ENABLED(ADVANCED_PAUSE_FEATURE) - if (process == Proc_Popup && popup == Popup_PurgeMore) { + if (process == Popup && popup == PurgeMore) { if (pause_menu_response == PAUSE_RESPONSE_EXTRUDE_MORE) - popupHandler(Popup_FilChange); + Popup_Handler(FilChange); else if (pause_menu_response == PAUSE_RESPONSE_RESUME_PRINT) { - if (printing) popupHandler(Popup_Resuming); - else redrawMenu(true, true, active_menu == ID_PreheatHotend); + if (printing) Popup_Handler(Resuming); + else Redraw_Menu(true, true, (active_menu==PreheatHotend)); } } #endif @@ -4957,41 +4625,41 @@ void JyersDWIN::stateUpdate() { static bool ranout = false; if (runout.filament_ran_out != ranout) { ranout = runout.filament_ran_out; - if (ranout) popupHandler(Popup_Runout); + if (ranout) Popup_Handler(Runout); } #endif } -void JyersDWIN::screenUpdate() { +void CrealityDWINClass::Screen_Update() { const millis_t ms = millis(); static millis_t scrltime = 0; if (ELAPSED(ms, scrltime)) { scrltime = ms + 200; - updateStatusBar(); - if (process == Proc_Print) drawPrintFilename(); + Update_Status_Bar(); + if (process == Print) Draw_Print_Filename(); } static millis_t statustime = 0; if (ELAPSED(ms, statustime)) { statustime = ms + 500; - drawStatusArea(); + Draw_Status_Area(); } static millis_t printtime = 0; if (ELAPSED(ms, printtime)) { printtime = ms + 1000; - if (process == Proc_Print) { - drawPrintProgressBar(); - drawPrintProgressElapsed(); - TERN_(SET_REMAINING_TIME, drawPrintProgressRemain()); + if (process == Print) { + Draw_Print_ProgressBar(); + Draw_Print_ProgressElapsed(); + TERN_(SET_REMAINING_TIME, Draw_Print_ProgressRemain()); } } static bool mounted = card.isMounted(); if (mounted != card.isMounted()) { mounted = card.isMounted(); - if (process == Proc_File) - drawSDList(); + if (process == File) + Draw_SD_List(); } #if HAS_HOTEND @@ -5024,24 +4692,24 @@ void JyersDWIN::screenUpdate() { #endif #endif // HAS_ZOFFSET_ITEM - if (process == Proc_Menu || process == Proc_Value) { + if (process == Menu || process == Value) { switch (active_menu) { - case ID_TempMenu: + case TempMenu: #if HAS_HOTEND - if (thermalManager.degTargetHotend(0) != hotendtarget) { - hotendtarget = thermalManager.degTargetHotend(0); + if (thermalManager.temp_hotend[0].target != hotendtarget) { + hotendtarget = thermalManager.temp_hotend[0].target; if (scrollpos <= TEMP_HOTEND && TEMP_HOTEND <= scrollpos + MROWS) { - if (process != Proc_Value || selection != TEMP_HOTEND - scrollpos) - drawFloat(hotendtarget, TEMP_HOTEND - scrollpos, false, 1); + if (process != Value || selection != TEMP_HOTEND - scrollpos) + Draw_Float(thermalManager.temp_hotend[0].target, TEMP_HOTEND - scrollpos, false, 1); } } #endif #if HAS_HEATED_BED - if (thermalManager.degTargetBed() != bedtarget) { - bedtarget = thermalManager.degTargetBed(); + if (thermalManager.temp_bed.target != bedtarget) { + bedtarget = thermalManager.temp_bed.target; if (scrollpos <= TEMP_BED && TEMP_BED <= scrollpos + MROWS) { - if (process != Proc_Value || selection != TEMP_HOTEND - scrollpos) - drawFloat(bedtarget, TEMP_BED - scrollpos, false, 1); + if (process != Value || selection != TEMP_HOTEND - scrollpos) + Draw_Float(thermalManager.temp_bed.target, TEMP_BED - scrollpos, false, 1); } } #endif @@ -5049,28 +4717,28 @@ void JyersDWIN::screenUpdate() { if (thermalManager.fan_speed[0] != fanspeed) { fanspeed = thermalManager.fan_speed[0]; if (scrollpos <= TEMP_FAN && TEMP_FAN <= scrollpos + MROWS) { - if (process != Proc_Value || selection != TEMP_HOTEND - scrollpos) - drawFloat(fanspeed, TEMP_FAN - scrollpos, false, 1); + if (process != Value || selection != TEMP_HOTEND - scrollpos) + Draw_Float(thermalManager.fan_speed[0], TEMP_FAN - scrollpos, false, 1); } } #endif break; - case ID_Tune: + case Tune: #if HAS_HOTEND - if (thermalManager.degTargetHotend(0) != hotendtarget) { - hotendtarget = thermalManager.degTargetHotend(0); + if (thermalManager.temp_hotend[0].target != hotendtarget) { + hotendtarget = thermalManager.temp_hotend[0].target; if (scrollpos <= TUNE_HOTEND && TUNE_HOTEND <= scrollpos + MROWS) { - if (process != Proc_Value || selection != TEMP_HOTEND - scrollpos) - drawFloat(hotendtarget, TUNE_HOTEND - scrollpos, false, 1); + if (process != Value || selection != TEMP_HOTEND - scrollpos) + Draw_Float(thermalManager.temp_hotend[0].target, TUNE_HOTEND - scrollpos, false, 1); } } #endif #if HAS_HEATED_BED - if (thermalManager.degTargetBed() != bedtarget) { - bedtarget = thermalManager.degTargetBed(); + if (thermalManager.temp_bed.target != bedtarget) { + bedtarget = thermalManager.temp_bed.target; if (scrollpos <= TUNE_BED && TUNE_BED <= scrollpos + MROWS) { - if (process != Proc_Value || selection != TEMP_HOTEND - scrollpos) - drawFloat(bedtarget, TUNE_BED - scrollpos, false, 1); + if (process != Value || selection != TEMP_HOTEND - scrollpos) + Draw_Float(thermalManager.temp_bed.target, TUNE_BED - scrollpos, false, 1); } } #endif @@ -5078,8 +4746,8 @@ void JyersDWIN::screenUpdate() { if (thermalManager.fan_speed[0] != fanspeed) { fanspeed = thermalManager.fan_speed[0]; if (scrollpos <= TUNE_FAN && TUNE_FAN <= scrollpos + MROWS) { - if (process != Proc_Value || selection != TEMP_HOTEND - scrollpos) - drawFloat(fanspeed, TUNE_FAN - scrollpos, false, 1); + if (process != Value || selection != TEMP_HOTEND - scrollpos) + Draw_Float(thermalManager.fan_speed[0], TUNE_FAN - scrollpos, false, 1); } } #endif @@ -5088,25 +4756,25 @@ void JyersDWIN::screenUpdate() { } } -void JyersDWIN::audioFeedback(const bool success/*=true*/) { +void CrealityDWINClass::AudioFeedback(const bool success/*=true*/) { if (ui.sound_on) DONE_BUZZ(success); else - updateStatus(success ? "Success" : "Failed"); + Update_Status(success ? "Success" : "Failed"); } -void JyersDWIN::saveSettings(char * const buff) { +void CrealityDWINClass::Save_Settings(char *buff) { TERN_(AUTO_BED_LEVELING_UBL, eeprom_settings.tilt_grid_size = mesh_conf.tilt_grid - 1); eeprom_settings.corner_pos = corner_pos * 10; memcpy(buff, &eeprom_settings, _MIN(sizeof(eeprom_settings), eeprom_data_size)); } -void JyersDWIN::loadSettings(const char * const buff) { +void CrealityDWINClass::Load_Settings(const char *buff) { memcpy(&eeprom_settings, buff, _MIN(sizeof(eeprom_settings), eeprom_data_size)); TERN_(AUTO_BED_LEVELING_UBL, mesh_conf.tilt_grid = eeprom_settings.tilt_grid_size + 1); if (eeprom_settings.corner_pos == 0) eeprom_settings.corner_pos = 325; corner_pos = eeprom_settings.corner_pos / 10.0f; - redrawScreen(); + Redraw_Screen(); #if ENABLED(POWER_LOSS_RECOVERY) static bool init = true; if (init) { @@ -5116,7 +4784,7 @@ void JyersDWIN::loadSettings(const char * const buff) { #endif } -void JyersDWIN::resetSettings() { +void CrealityDWINClass::Reset_Settings() { eeprom_settings.time_format_textual = false; TERN_(AUTO_BED_LEVELING_UBL, eeprom_settings.tilt_grid_size = 0); eeprom_settings.corner_pos = 325; @@ -5134,37 +4802,36 @@ void JyersDWIN::resetSettings() { TERN_(AUTO_BED_LEVELING_UBL, mesh_conf.tilt_grid = eeprom_settings.tilt_grid_size + 1); corner_pos = eeprom_settings.corner_pos / 10.0f; TERN_(SOUND_MENU_ITEM, ui.sound_on = ENABLED(SOUND_ON_DEFAULT)); - redrawScreen(); + Redraw_Screen(); } void MarlinUI::init_lcd() { delay(800); SERIAL_ECHOPGM("\nDWIN handshake "); - if (dwinHandshake()) SERIAL_ECHOLNPGM("ok."); else SERIAL_ECHOLNPGM("error."); - dwinFrameSetDir(1); // Orientation 90° - dwinUpdateLCD(); // Show bootscreen (first image) - encoderConfiguration(); + if (DWIN_Handshake()) SERIAL_ECHOLNPGM("ok."); else SERIAL_ECHOLNPGM("error."); + DWIN_Frame_SetDir(1); // Orientation 90° + DWIN_UpdateLCD(); // Show bootscreen (first image) + Encoder_Configuration(); for (uint16_t t = 0; t <= 100; t += 2) { - dwinIconShow(ICON, ICON_Bar, 15, 260); - dwinDrawRectangle(1, COLOR_BG_BLACK, 15 + t * 242 / 100, 260, 257, 280); - dwinUpdateLCD(); + DWIN_ICON_Show(ICON, ICON_Bar, 15, 260); + DWIN_Draw_Rectangle(1, Color_Bg_Black, 15 + t * 242 / 100, 260, 257, 280); + DWIN_UpdateLCD(); delay(20); } - dwinJPGShowAndCache(3); - dwinJPGCacheTo1(Language_English); - jyersDWIN.redrawScreen(); + DWIN_JPG_ShowAndCache(3); + DWIN_JPG_CacheTo1(Language_English); + CrealityDWIN.Redraw_Screen(); } #if ENABLED(ADVANCED_PAUSE_FEATURE) void MarlinUI::pause_show_message(const PauseMessage message, const PauseMode mode/*=PAUSE_MODE_SAME*/, const uint8_t extruder/*=active_extruder*/) { - if (mode != PAUSE_MODE_SAME) pause_mode = mode; switch (message) { - case PAUSE_MESSAGE_INSERT: jyersDWIN.confirmHandler(Popup_FilInsert); break; + case PAUSE_MESSAGE_INSERT: CrealityDWIN.Confirm_Handler(FilInsert); break; case PAUSE_MESSAGE_PURGE: - case PAUSE_MESSAGE_OPTION: jyersDWIN.popupHandler(Popup_PurgeMore); break; - case PAUSE_MESSAGE_HEAT: jyersDWIN.confirmHandler(Popup_HeaterTime); break; - case PAUSE_MESSAGE_WAITING: jyersDWIN.drawPrintScreen(); break; + case PAUSE_MESSAGE_OPTION: CrealityDWIN.Popup_Handler(PurgeMore); break; + case PAUSE_MESSAGE_HEAT: CrealityDWIN.Confirm_Handler(HeaterTime); break; + case PAUSE_MESSAGE_WAITING: CrealityDWIN.Draw_Print_Screen(); break; default: break; } } diff --git a/Marlin/src/lcd/e3v2/proui/endstop_diag.cpp b/Marlin/src/lcd/e3v2/proui/endstop_diag.cpp index 21c83dc8fa..4d78677281 100644 --- a/Marlin/src/lcd/e3v2/proui/endstop_diag.cpp +++ b/Marlin/src/lcd/e3v2/proui/endstop_diag.cpp @@ -23,8 +23,8 @@ /** * DWIN Endstops diagnostic page for PRO UI * Author: Miguel A. Risco-Castillo (MRISCOC) - * Version: 1.4.3 - * Date: 2023/05/10 + * Version: 1.2.2 + * Date: 2022/02/24 */ #include "../../../inc/MarlinConfigPre.h" @@ -36,9 +36,13 @@ #if HAS_ESDIAG #include "endstop_diag.h" + +#include "../../../core/types.h" #include "../../marlinui.h" -#include "dwin.h" +#include "dwin_lcd.h" +#include "dwinui.h" #include "dwin_popup.h" +#include "dwin.h" #if HAS_FILAMENT_SENSOR #include "../../../feature/runout.h" @@ -48,45 +52,61 @@ #include "../../../module/probe.h" #endif -ESDiag esDiag; +ESDiagClass ESDiag; void draw_es_label(FSTR_P const flabel=nullptr) { DWINUI::cursor.x = 40; - if (flabel) DWINUI::drawString(F(flabel)); - DWINUI::drawString(F(": ")); - DWINUI::moveBy(0, 25); + if (flabel) DWINUI::Draw_String(F(flabel)); + DWINUI::Draw_String(F(": ")); + DWINUI::MoveBy(0, 25); } void draw_es_state(const bool is_hit) { const uint8_t LM = 130; DWINUI::cursor.x = LM; - dwinDrawRectangle(1, hmiData.colorPopupBg, LM, DWINUI::cursor.y, LM + 100, DWINUI::cursor.y + 20); - is_hit ? DWINUI::drawString(RGB(31,31,16), F(STR_ENDSTOP_HIT)) : DWINUI::drawString(RGB(16,63,16), F(STR_ENDSTOP_OPEN)); - DWINUI::moveBy(0, 25); + DWIN_Draw_Rectangle(1, HMI_data.PopupBg_color, LM, DWINUI::cursor.y, LM + 100, DWINUI::cursor.y + 20); + is_hit ? DWINUI::Draw_String(RGB(31,31,16), F(STR_ENDSTOP_HIT)) : DWINUI::Draw_String(RGB(16,63,16), F(STR_ENDSTOP_OPEN)); + DWINUI::MoveBy(0, 25); } -void ESDiag::draw() { - title.showCaption(GET_TEXT_F(MSG_ENDSTOP_TEST)); - DWINUI::clearMainArea(); - drawPopupBkgd(); - DWINUI::drawButton(BTN_Continue, 86, 250); +void ESDiagClass::Draw() { + Title.ShowCaption(F("End-stops Diagnostic")); + DWINUI::ClearMainArea(); + Draw_Popup_Bkgd(); + DWINUI::Draw_Button(BTN_Continue, 86, 250); DWINUI::cursor.y = 80; #define ES_LABEL(S) draw_es_label(F(STR_##S)) - TERN_(USE_X_MIN, ES_LABEL(X_MIN)); TERN_(USE_X_MAX, ES_LABEL(X_MAX)); - TERN_(USE_Y_MIN, ES_LABEL(Y_MIN)); TERN_(USE_Y_MAX, ES_LABEL(Y_MAX)); - TERN_(USE_Z_MIN, ES_LABEL(Z_MIN)); TERN_(USE_Z_MAX, ES_LABEL(Z_MAX)); - TERN_(HAS_FILAMENT_SENSOR, draw_es_label(F(STR_FILAMENT))); - update(); + #if HAS_X_MIN + ES_LABEL(X_MIN); + #endif + #if HAS_Y_MIN + ES_LABEL(Y_MIN); + #endif + #if HAS_Z_MIN + ES_LABEL(Z_MIN); + #endif + #if HAS_FILAMENT_SENSOR + draw_es_label(F(STR_FILAMENT)); + #endif + Update(); } -void ESDiag::update() { +void ESDiagClass::Update() { DWINUI::cursor.y = 80; - #define ES_REPORT(S) draw_es_state(READ(S##_PIN) == S##_ENDSTOP_HIT_STATE) - TERN_(USE_X_MIN, ES_REPORT(X_MIN)); TERN_(USE_X_MAX, ES_REPORT(X_MAX)); - TERN_(USE_Y_MIN, ES_REPORT(Y_MIN)); TERN_(USE_Y_MAX, ES_REPORT(Y_MAX)); - TERN_(USE_Z_MIN, ES_REPORT(Z_MIN)); TERN_(USE_Z_MAX, ES_REPORT(Z_MAX)); - TERN_(HAS_FILAMENT_SENSOR, draw_es_state(READ(FIL_RUNOUT1_PIN) != FIL_RUNOUT1_STATE)); - dwinUpdateLCD(); + #define ES_REPORT(S) draw_es_state(READ(S##_PIN) != S##_ENDSTOP_INVERTING) + #if HAS_X_MIN + ES_REPORT(X_MIN); + #endif + #if HAS_Y_MIN + ES_REPORT(Y_MIN); + #endif + #if HAS_Z_MIN + ES_REPORT(Z_MIN); + #endif + #if HAS_FILAMENT_SENSOR + draw_es_state(READ(FIL_RUNOUT1_PIN) != runout.out_state()); + #endif + DWIN_UpdateLCD(); } #endif // HAS_ESDIAG diff --git a/Marlin/src/lcd/extui/anycubic_chiron/chiron_tft.cpp b/Marlin/src/lcd/extui/anycubic_chiron/chiron_tft.cpp index 63b1ef9c19..4b046c34f3 100644 --- a/Marlin/src/lcd/extui/anycubic_chiron/chiron_tft.cpp +++ b/Marlin/src/lcd/extui/anycubic_chiron/chiron_tft.cpp @@ -33,7 +33,7 @@ #if ENABLED(ANYCUBIC_LCD_CHIRON) #include "chiron_tft.h" -#include "../anycubic/Tunes.h" +#include "Tunes.h" #include "FileNavigator.h" #include "../../../gcode/queue.h" @@ -42,13 +42,9 @@ #include "../../../libs/numtostr.h" #include "../../../MarlinCore.h" -#define DEBUG_OUT ACDEBUGLEVEL -#include "../../../core/debug_out.h" - namespace Anycubic { -ChironTFT chiron; - +ChironTFT Chiron; #if AUTO_DETECT_CHIRON_TFT panel_type_t ChironTFT::panel_type = AC_panel_unknown; #endif @@ -64,7 +60,7 @@ uint8_t ChironTFT::command_len; float ChironTFT::live_Zoffset; file_menu_t ChironTFT::file_menu; -void ChironTFT::startup() { +void ChironTFT::Startup() { selectedfile[0] = '\0'; panel_command[0] = '\0'; command_len = 0; @@ -76,9 +72,14 @@ void ChironTFT::startup() { live_Zoffset = 0.0; file_menu = AC_menu_file; - // Filament runout is handled by Marlin settings in Configuration.h - // opt_set FIL_RUNOUT_STATE HIGH // Pin state indicating that filament is NOT present. - // opt_enable FIL_RUNOUT_PULLUP + // Setup pins for powerloss detection + // Two IO pins are connected on the Trigorilla Board + // On a power interruption the OUTAGECON_PIN goes low. + + #if ENABLED(POWER_LOSS_RECOVERY) + OUT_WRITE(OUTAGECON_PIN, HIGH); + #endif + TFTSer.begin(115200); // Wait for the TFT panel to initialize and finish the animation @@ -88,76 +89,81 @@ void ChironTFT::startup() { // So we need to know what we are working with. // Panel type can be defined otherwise detect it automatically switch (panel_type) { - case AC_panel_new: SERIAL_ECHOLN(AC_msg_new_panel_set); break; - case AC_panel_standard: SERIAL_ECHOLN(AC_msg_old_panel_set); break; - default: SERIAL_ECHOLN(AC_msg_auto_panel_detection); - detectPanelType(); + case AC_panel_new: + SERIAL_ECHOLNF(AC_msg_new_panel_set); + break; + case AC_panel_standard: + SERIAL_ECHOLNF(AC_msg_old_panel_set); + break; + default: + SERIAL_ECHOLNF(AC_msg_auto_panel_detection); + DetectPanelType(); break; } // Signal Board has reset - tftSendLn(AC_msg_main_board_has_reset); + SendtoTFTLN(AC_msg_main_board_has_reset); // Enable leveling and Disable end stops during print // as Z home places nozzle above the bed so we need to allow it past the end stops injectCommands(AC_cmnd_enable_leveling); - // startup tunes are defined in Tunes.h - playTune(TERN(AC_DEFAULT_STARTUP_TUNE, Anycubic_PowerOn, GB_PowerOn)); + // Startup tunes are defined in Tunes.h + PlayTune(BEEPER_PIN, TERN(AC_DEFAULT_STARTUP_TUNE, Anycubic_PowerOn, GB_PowerOn), 1); #if ACDEBUGLEVEL - DEBUG_ECHOLNPGM("AC Debug Level ", ACDEBUGLEVEL); + SERIAL_ECHOLNPGM("AC Debug Level ", ACDEBUGLEVEL); #endif - tftSendLn(AC_msg_ready); + SendtoTFTLN(AC_msg_ready); } -void ChironTFT::detectPanelType() { +void ChironTFT::DetectPanelType() { #if AUTO_DETECT_CHIRON_TFT // Send a query to the TFT - tftSendLn(AC_Test_for_OldPanel); // The panel will respond with 'SXY 480 320' - tftSendLn(AC_Test_for_NewPanel); // the panel will respond with '[0]=0 ' to '[19]=0 ' + SendtoTFTLN(AC_Test_for_OldPanel); // The panel will respond with 'SXY 480 320' + SendtoTFTLN(AC_Test_for_NewPanel); // the panel will respond with '[0]=0 ' to '[19]=0 ' #endif } -void ChironTFT::idleLoop() { - if (readTFTCommand()) { - processPanelRequest(); +void ChironTFT::IdleLoop() { + if (ReadTFTCommand()) { + ProcessPanelRequest(); command_len = 0; } - checkHeaters(); + CheckHeaters(); } -void ChironTFT::printerKilled(FSTR_P const error, FSTR_P const component) { - tftSendLn(AC_msg_kill_lcd); +void ChironTFT::PrinterKilled(FSTR_P const error, FSTR_P const component) { + SendtoTFTLN(AC_msg_kill_lcd); #if ACDEBUG(AC_MARLIN) - DEBUG_ECHOLNPGM("printerKilled()\nerror: ", error , "\ncomponent: ", component); + SERIAL_ECHOLNPGM("PrinterKilled()\nerror: ", error , "\ncomponent: ", component); #endif } -void ChironTFT::mediaEvent(media_event_t event) { +void ChironTFT::MediaEvent(media_event_t event) { #if ACDEBUG(AC_MARLIN) - DEBUG_ECHOLNPGM("ProcessMediaStatus() ", event); + SERIAL_ECHOLNPGM("ProcessMediaStatus() ", event); #endif switch (event) { case AC_media_inserted: - tftSendLn(AC_msg_sd_card_inserted); + SendtoTFTLN(AC_msg_sd_card_inserted); break; case AC_media_removed: - tftSendLn(AC_msg_sd_card_removed); + SendtoTFTLN(AC_msg_sd_card_removed); break; case AC_media_error: last_error = AC_error_noSD; - tftSendLn(AC_msg_no_sd_card); + SendtoTFTLN(AC_msg_no_sd_card); break; } } -void ChironTFT::timerEvent(timer_event_t event) { +void ChironTFT::TimerEvent(timer_event_t event) { #if ACDEBUG(AC_MARLIN) - DEBUG_ECHOLNPGM("timerEvent() ", event); - DEBUG_ECHOLNPGM("Printer State: ", printer_state); + SERIAL_ECHOLNPGM("TimerEvent() ", event); + SERIAL_ECHOLNPGM("Printer State: ", printer_state); #endif switch (event) { @@ -165,44 +171,44 @@ void ChironTFT::timerEvent(timer_event_t event) { live_Zoffset = 0.0; // reset print offset setSoftEndstopState(false); // disable endstops to print printer_state = AC_printer_printing; - tftSendLn(AC_msg_print_from_sd_card); + SendtoTFTLN(AC_msg_print_from_sd_card); } break; case AC_timer_paused: { printer_state = AC_printer_paused; pause_state = AC_paused_idle; - tftSendLn(AC_msg_paused); + SendtoTFTLN(AC_msg_paused); } break; case AC_timer_stopped: { if (printer_state != AC_printer_idle) { printer_state = AC_printer_stopping; - tftSendLn(AC_msg_print_complete); + SendtoTFTLN(AC_msg_print_complete); } setSoftEndstopState(true); // enable endstops } break; } } -void ChironTFT::filamentRunout() { +void ChironTFT::FilamentRunout() { #if ACDEBUG(AC_MARLIN) - DEBUG_ECHOLNPGM("filamentRunout() printer_state ", printer_state); + SERIAL_ECHOLNPGM("FilamentRunout() printer_state ", printer_state); #endif // 1 Signal filament out last_error = AC_error_filament_runout; - tftSendLn(isPrintingFromMedia() ? AC_msg_filament_out_alert : AC_msg_filament_out_block); - playTune(FilamentOut); + SendtoTFTLN(isPrintingFromMedia() ? AC_msg_filament_out_alert : AC_msg_filament_out_block); + PlayTune(BEEPER_PIN, FilamentOut, 1); } -void ChironTFT::confirmationRequest(const char * const msg) { +void ChironTFT::ConfirmationRequest(const char * const msg) { // M108 continue #if ACDEBUG(AC_MARLIN) - DEBUG_ECHOLNPGM("confirmationRequest() ", msg, " printer_state:", printer_state); + SERIAL_ECHOLNPGM("ConfirmationRequest() ", msg, " printer_state:", printer_state); #endif switch (printer_state) { case AC_printer_pausing: { if (strcmp_P(msg, MARLIN_msg_print_paused) == 0 || strcmp_P(msg, MARLIN_msg_nozzle_parked) == 0) { - tftSendLn(AC_msg_paused); // enable continue button + SendtoTFTLN(AC_msg_paused); // enable continue button printer_state = AC_printer_paused; } } break; @@ -213,18 +219,18 @@ void ChironTFT::confirmationRequest(const char * const msg) { // Heater timeout, send acknowledgement if (strcmp_P(msg, MARLIN_msg_heater_timeout) == 0) { pause_state = AC_paused_heater_timed_out; - tftSendLn(AC_msg_paused); // enable continue button - playTune(HeaterTimeout); + SendtoTFTLN(AC_msg_paused); // enable continue button + PlayTune(BEEPER_PIN,Heater_Timedout,1); } // Reheat finished, send acknowledgement else if (strcmp_P(msg, MARLIN_msg_reheat_done) == 0) { pause_state = AC_paused_idle; - tftSendLn(AC_msg_paused); // enable continue button + SendtoTFTLN(AC_msg_paused); // enable continue button } // Filament Purging, send acknowledgement enter run mode else if (strcmp_P(msg, MARLIN_msg_filament_purging) == 0) { pause_state = AC_paused_purging_filament; - tftSendLn(AC_msg_paused); // enable continue button + SendtoTFTLN(AC_msg_paused); // enable continue button } } break; default: @@ -232,10 +238,10 @@ void ChironTFT::confirmationRequest(const char * const msg) { } } -void ChironTFT::statusChange(const char * const msg) { +void ChironTFT::StatusChange(const char * const msg) { #if ACDEBUG(AC_MARLIN) - DEBUG_ECHOLNPGM("statusChange() ", msg); - DEBUG_ECHOLNPGM("printer_state:", printer_state); + SERIAL_ECHOLNPGM("StatusChange() ", msg); + SERIAL_ECHOLNPGM("printer_state:", printer_state); #endif bool msg_matched = false; // The only way to get printer status is to parse messages @@ -246,15 +252,15 @@ void ChironTFT::statusChange(const char * const msg) { // Ignore the custom machine name if (strcmp_P(msg + strlen(MACHINE_NAME), MARLIN_msg_ready) == 0) { injectCommands(F("M500\nG27")); - tftSendLn(AC_msg_probing_complete); + SendtoTFTLN(AC_msg_probing_complete); printer_state = AC_printer_idle; msg_matched = true; } // If probing fails don't save the mesh raise the probe above the bad point if (strcmp_P(msg, MARLIN_msg_probing_failed) == 0) { - playTune(BeepBeepBeeep); + PlayTune(BEEPER_PIN, BeepBeepBeeep, 1); injectCommands(F("G1 Z50 F500")); - tftSendLn(AC_msg_probing_complete); + SendtoTFTLN(AC_msg_probing_complete); printer_state = AC_printer_idle; msg_matched = true; } @@ -262,14 +268,14 @@ void ChironTFT::statusChange(const char * const msg) { case AC_printer_printing: { if (strcmp_P(msg, MARLIN_msg_reheating) == 0) { - tftSendLn(AC_msg_paused); // enable continue button + SendtoTFTLN(AC_msg_paused); // enable continue button msg_matched = true; } } break; case AC_printer_pausing: { if (strcmp_P(msg, MARLIN_msg_print_paused) == 0) { - tftSendLn(AC_msg_paused); + SendtoTFTLN(AC_msg_paused); printer_state = AC_printer_paused; pause_state = AC_paused_idle; msg_matched = true; @@ -278,7 +284,7 @@ void ChironTFT::statusChange(const char * const msg) { case AC_printer_stopping: { if (strcmp_P(msg, MARLIN_msg_print_aborted) == 0) { - tftSendLn(AC_msg_stop); + SendtoTFTLN(AC_msg_stop); printer_state = AC_printer_idle; msg_matched = true; } @@ -290,11 +296,11 @@ void ChironTFT::statusChange(const char * const msg) { // If not matched earlier see if this was a heater message if (!msg_matched) { if (strcmp_P(msg, MARLIN_msg_extruder_heating) == 0) { - tftSendLn(AC_msg_nozzle_heating); + SendtoTFTLN(AC_msg_nozzle_heating); hotend_state = AC_heater_temp_set; } else if (strcmp_P(msg, MARLIN_msg_bed_heating) == 0) { - tftSendLn(AC_msg_bed_heating); + SendtoTFTLN(AC_msg_bed_heating); hotbed_state = AC_heater_temp_set; } else if (strcmp_P(msg, MARLIN_msg_EEPROM_version) == 0) { @@ -303,33 +309,33 @@ void ChironTFT::statusChange(const char * const msg) { } } -void ChironTFT::powerLossRecovery() { +void ChironTFT::PowerLossRecovery() { printer_state = AC_printer_resuming_from_power_outage; // Play tune to notify user we can recover. last_error = AC_error_powerloss; - playTune(SOS); - SERIAL_ECHOLN(AC_msg_powerloss_recovery); + PlayTune(BEEPER_PIN, SOS, 1); + SERIAL_ECHOLNF(AC_msg_powerloss_recovery); } -void ChironTFT::printComplete() { - tftSend(AC_msg_print_complete); +void ChironTFT::PrintComplete() { + SendtoTFT(AC_msg_print_complete); printer_state = AC_printer_idle; setSoftEndstopState(true); // enable endstops } -void ChironTFT::tftSend(FSTR_P const fstr/*=nullptr*/) { // A helper to print PROGMEM string to the panel +void ChironTFT::SendtoTFT(FSTR_P const fstr/*=nullptr*/) { // A helper to print PROGMEM string to the panel #if ACDEBUG(AC_SOME) - DEBUG_ECHO(fstr); + SERIAL_ECHOF(fstr); #endif PGM_P str = FTOP(fstr); while (const char c = pgm_read_byte(str++)) TFTSer.write(c); } -void ChironTFT::tftSendLn(FSTR_P const fstr/*=nullptr*/) { +void ChironTFT::SendtoTFTLN(FSTR_P const fstr/*=nullptr*/) { if (fstr) { #if ACDEBUG(AC_SOME) - DEBUG_ECHOPGM("> "); + SERIAL_ECHOPGM("> "); #endif - tftSend(fstr); + SendtoTFT(fstr); #if ACDEBUG(AC_SOME) SERIAL_EOL(); #endif @@ -337,7 +343,7 @@ void ChironTFT::tftSendLn(FSTR_P const fstr/*=nullptr*/) { TFTSer.println(); } -bool ChironTFT::readTFTCommand() { +bool ChironTFT::ReadTFTCommand() { bool command_ready = false; while (TFTSer.available() > 0 && command_len < MAX_CMND_LEN) { panel_command[command_len] = TFTSer.read(); @@ -351,29 +357,29 @@ bool ChironTFT::readTFTCommand() { if (command_ready || command_len == MAX_CMND_LEN) { panel_command[command_len] = '\0'; #if ACDEBUG(AC_ALL) - DEBUG_ECHOLNPGM("len(",command_len,") < ", panel_command); + SERIAL_ECHOLNPGM("len(",command_len,") < ", panel_command); #endif command_ready = true; } return command_ready; } -int8_t ChironTFT::findToken(char c) { +int8_t ChironTFT::FindToken(char c) { for (int8_t pos = 0; pos < command_len; pos++) { if (panel_command[pos] == c) { #if ACDEBUG(AC_INFO) - DEBUG_ECHOLNPGM("Tpos:", pos, " ", c); + SERIAL_ECHOLNPGM("Tpos:", pos, " ", c); #endif return pos; } } #if ACDEBUG(AC_INFO) - DEBUG_ECHOLNPGM("Not found: ", c); + SERIAL_ECHOLNPGM("Not found: ", c); #endif return -1; } -void ChironTFT::checkHeaters() { +void ChironTFT::CheckHeaters() { uint8_t faultDuration = 0; // if the hotend temp is abnormal, confirm state before signalling panel @@ -381,7 +387,7 @@ void ChironTFT::checkHeaters() { while (!WITHIN(temp, HEATER_0_MINTEMP, HEATER_0_MAXTEMP)) { faultDuration++; if (faultDuration >= AC_HEATER_FAULT_VALIDATION_TIME) { - tftSendLn(AC_msg_nozzle_temp_abnormal); + SendtoTFTLN(AC_msg_nozzle_temp_abnormal); last_error = AC_error_abnormal_temp_t0; SERIAL_ECHOLNPGM("Extruder temp abnormal! : ", temp); break; @@ -396,7 +402,7 @@ void ChironTFT::checkHeaters() { while (!WITHIN(temp, BED_MINTEMP, BED_MAXTEMP)) { faultDuration++; if (faultDuration >= AC_HEATER_FAULT_VALIDATION_TIME) { - tftSendLn(AC_msg_nozzle_temp_abnormal); + SendtoTFTLN(AC_msg_nozzle_temp_abnormal); last_error = AC_error_abnormal_temp_bed; SERIAL_ECHOLNPGM("Bed temp abnormal! : ", temp); break; @@ -408,7 +414,7 @@ void ChironTFT::checkHeaters() { // Update panel with hotend heater status if (hotend_state != AC_heater_temp_reached) { if (WITHIN(getActualTemp_celsius(E0) - getTargetTemp_celsius(E0), -(TEMP_WINDOW), TEMP_WINDOW)) { - tftSendLn(AC_msg_nozzle_heating_done); + SendtoTFTLN(AC_msg_nozzle_heating_done); hotend_state = AC_heater_temp_reached; } } @@ -416,84 +422,90 @@ void ChironTFT::checkHeaters() { // Update panel with bed heater status if (hotbed_state != AC_heater_temp_reached) { if (WITHIN(getActualTemp_celsius(BED) - getTargetTemp_celsius(BED), -(TEMP_BED_WINDOW), TEMP_BED_WINDOW)) { - tftSendLn(AC_msg_bed_heating_done); + SendtoTFTLN(AC_msg_bed_heating_done); hotbed_state = AC_heater_temp_reached; } } } -void ChironTFT::sendFileList(int8_t startindex) { +void ChironTFT::SendFileList(int8_t startindex) { // Respond to panel request for 4 files starting at index #if ACDEBUG(AC_INFO) - DEBUG_ECHOLNPGM("## sendFileList ## ", startindex); + SERIAL_ECHOLNPGM("## SendFileList ## ", startindex); #endif - tftSendLn(F("FN ")); + SendtoTFTLN(F("FN ")); filenavigator.getFiles(startindex, panel_type, 4); - tftSendLn(F("END")); + SendtoTFTLN(F("END")); } -void ChironTFT::selectFile() { - const size_t fnlen = command_len - 4 + (panel_type <= AC_panel_new); - strlcpy(selectedfile, panel_command + 4, fnlen + 1); +void ChironTFT::SelectFile() { + if (panel_type <= AC_panel_new) { + strncpy(selectedfile, panel_command + 4, command_len - 3); + selectedfile[command_len - 4] = '\0'; + } + else { + strncpy(selectedfile, panel_command + 4, command_len - 4); + selectedfile[command_len - 5] = '\0'; + } #if ACDEBUG(AC_FILE) - DEBUG_ECHOLNPGM(" Selected File: ", selectedfile); + SERIAL_ECHOLNPGM(" Selected File: ",selectedfile); #endif - switch (selectedfile[0]) { case '/': // Valid file selected - tftSendLn(AC_msg_sd_file_open_success); + SendtoTFTLN(AC_msg_sd_file_open_success); break; case '<': // .. (go up folder level) filenavigator.upDIR(); - tftSendLn(AC_msg_sd_file_open_failed); - sendFileList( 0 ); + SendtoTFTLN(AC_msg_sd_file_open_failed); + SendFileList( 0 ); break; - default: // enter subfolder - // For new panel remove the '.GCO' tag that was added to the end of the path - if (panel_type <= AC_panel_new) selectedfile[fnlen - 4] = '\0'; + default: // enter sub folder + // for new panel remove the '.GCO' tag that was added to the end of the path + if (panel_type <= AC_panel_new) + selectedfile[strlen(selectedfile) - 4] = '\0'; filenavigator.changeDIR(selectedfile); - tftSendLn(AC_msg_sd_file_open_failed); - sendFileList( 0 ); + SendtoTFTLN(AC_msg_sd_file_open_failed); + SendFileList( 0 ); break; } } -void ChironTFT::processPanelRequest() { +void ChironTFT::ProcessPanelRequest() { // Break these up into logical blocks // as its easier to navigate than one huge switch case! - int8_t tpos = findToken('A'); + int8_t tpos = FindToken('A'); // Panel request are 'A0' - 'A36' if (tpos >= 0) { const int8_t req = atoi(&panel_command[tpos + 1]); // Information requests A0 - A8 and A33 - if (req <= 8 || req == 33) panelInfo(req); + if (req <= 8 || req == 33) PanelInfo(req); // Simple Actions A9 - A28 - else if (req <= 28) panelAction(req); + else if (req <= 28) PanelAction(req); // Process Initiation - else if (req <= 36) panelProcess(req); + else if (req <= 36) PanelProcess(req); } else { #if AUTO_DETECT_CHIRON_TFT // This may be a response to a panel type detection query if (panel_type == AC_panel_unknown) { - tpos = findToken('S'); // old panel will respond to 'SIZE' with 'SXY 480 320' + tpos = FindToken('S'); // old panel will respond to 'SIZE' with 'SXY 480 320' if (tpos >= 0) { if (panel_command[tpos + 1] == 'X' && panel_command[tpos + 2] =='Y') { panel_type = AC_panel_standard; - SERIAL_ECHOLN(AC_msg_old_panel_detected); + SERIAL_ECHOLNF(AC_msg_old_panel_detected); } } else { // new panel will respond to 'J200' with '[0]=0' // it seems only after a power cycle so detection assumes a new panel - tpos = findToken('['); + tpos = FindToken('['); if (tpos >= 0) { if (panel_command[tpos + 1] == '0' && panel_command[tpos + 2] ==']') { panel_type = AC_panel_new; - SERIAL_ECHOLN(AC_msg_new_panel_detected); + SERIAL_ECHOLNF(AC_msg_new_panel_detected); } } } @@ -501,94 +513,94 @@ void ChironTFT::processPanelRequest() { } #endif - tftSendLn(); // Ignore unknown requests + SendtoTFTLN(); // Ignore unknown requests } } -void ChironTFT::panelInfo(uint8_t req) { +void ChironTFT::PanelInfo(uint8_t req) { // information requests A0-A8 and A33 switch (req) { case 0: // A0 Get HOTEND Temp - tftSend(F("A0V ")); + SendtoTFT(F("A0V ")); TFTSer.println(getActualTemp_celsius(E0)); break; case 1: // A1 Get HOTEND Target Temp - tftSend(F("A1V ")); + SendtoTFT(F("A1V ")); TFTSer.println(getTargetTemp_celsius(E0)); break; case 2: // A2 Get BED Temp - tftSend(F("A2V ")); + SendtoTFT(F("A2V ")); TFTSer.println(getActualTemp_celsius(BED)); break; case 3: // A3 Get BED Target Temp - tftSend(F("A3V ")); + SendtoTFT(F("A3V ")); TFTSer.println(getTargetTemp_celsius(BED)); break; case 4: // A4 Get FAN Speed - tftSend(F("A4V ")); + SendtoTFT(F("A4V ")); TFTSer.println(getActualFan_percent(FAN0)); break; case 5: // A5 Get Current Coordinates - tftSend(F("A5V X: ")); + SendtoTFT(F("A5V X: ")); TFTSer.print(getAxisPosition_mm(X)); - tftSend(F(" Y: ")); + SendtoTFT(F(" Y: ")); TFTSer.print(getAxisPosition_mm(Y)); - tftSend(F(" Z: ")); + SendtoTFT(F(" Z: ")); TFTSer.println(getAxisPosition_mm(Z)); break; case 6: // A6 Get printing progress if (isPrintingFromMedia()) { - tftSend(F("A6V ")); + SendtoTFT(F("A6V ")); TFTSer.println(ui8tostr2(getProgress_percent())); } else - tftSendLn(F("A6V ---")); + SendtoTFTLN(F("A6V ---")); break; case 7: { // A7 Get Printing Time uint32_t time = getProgress_seconds_elapsed() / 60; - tftSend(F("A7V ")); + SendtoTFT(F("A7V ")); TFTSer.print(ui8tostr2(time / 60)); - tftSend(F(" H ")); + SendtoTFT(F(" H ")); TFTSer.print(ui8tostr2(time % 60)); - tftSend(F(" M")); + SendtoTFT(F(" M")); #if ACDEBUG(AC_ALL) - DEBUG_ECHOLNPGM("Print time ", ui8tostr2(time / 60), ":", ui8tostr2(time % 60)); + SERIAL_ECHOLNPGM("Print time ", ui8tostr2(time / 60), ":", ui8tostr2(time % 60)); #endif } break; case 8: // A8 Get SD Card list A8 S0 if (!isMediaInserted()) safe_delay(500); if (!isMediaInserted()) // Make sure the card is removed - tftSendLn(AC_msg_no_sd_card); + SendtoTFTLN(AC_msg_no_sd_card); else if (panel_command[3] == 'S') - sendFileList( atoi( &panel_command[4] ) ); + SendFileList( atoi( &panel_command[4] ) ); break; case 33: // A33 Get firmware info - tftSend(F("J33 ")); + SendtoTFT(F("J33 ")); // If there is an error recorded, show that instead of the FW version - if (!getLastError()) tftSendLn(F(SHORT_BUILD_VERSION)); + if (!GetLastError()) SendtoTFTLN(F(SHORT_BUILD_VERSION)); break; } } -void ChironTFT::panelAction(uint8_t req) { +void ChironTFT::PanelAction(uint8_t req) { switch (req) { case 9: // A9 Pause SD print if (isPrintingFromMedia()) { - tftSendLn(AC_msg_pause); + SendtoTFTLN(AC_msg_pause); pausePrint(); printer_state = AC_printer_pausing; } else - tftSendLn(AC_msg_stop); + SendtoTFTLN(AC_msg_stop); break; case 10: // A10 Resume SD Print @@ -606,7 +618,7 @@ void ChironTFT::panelAction(uint8_t req) { else { if (printer_state == AC_printer_resuming_from_power_outage) injectCommands(F("M1000 C")); // Cancel recovery - tftSendLn(AC_msg_stop); + SendtoTFTLN(AC_msg_stop); printer_state = AC_printer_idle; } break; @@ -616,7 +628,7 @@ void ChironTFT::panelAction(uint8_t req) { break; case 13: // A13 Select file - selectFile(); + SelectFile(); break; case 14: // A14 Start Printing @@ -625,9 +637,11 @@ void ChironTFT::panelAction(uint8_t req) { injectCommands(F("M1000 C")); // Cancel recovery printer_state = AC_printer_idle; } - DEBUG_ECHOLNPGM("Print: ", selectedfile); + #if ACDebugLevel >= 1 + SERIAL_ECHOLNPGM("Print: ", selectedfile); + #endif printFile(selectedfile); - tftSendLn(AC_msg_print_from_sd_card); + SendtoTFTLN(AC_msg_print_from_sd_card); break; case 15: // A15 Resuming from outage @@ -662,7 +676,7 @@ void ChironTFT::panelAction(uint8_t req) { case 19: // A19 Motors off if (!isPrinting()) { stepper.disable_all_steppers(); - tftSendLn(AC_msg_ready); + SendtoTFTLN(AC_msg_ready); } break; @@ -670,7 +684,7 @@ void ChironTFT::panelAction(uint8_t req) { if (panel_command[4] == 'S') setFeedrate_percent(atoi(&panel_command[5])); else { - tftSend(F("A20V ")); + SendtoTFT(F("A20V ")); TFTSer.println(getFeedrate_percent()); } break; @@ -698,7 +712,7 @@ void ChironTFT::panelAction(uint8_t req) { char MoveCmnd[30]; sprintf_P(MoveCmnd, PSTR("G91\nG0%s\nG90"), panel_command + 3); #if ACDEBUG(AC_ACTION) - DEBUG_ECHOLNPGM("Move: ", MoveCmnd); + SERIAL_ECHOLNPGM("Move: ", MoveCmnd); #endif setSoftEndstopState(true); // enable endstops injectCommands(MoveCmnd); @@ -711,7 +725,7 @@ void ChironTFT::panelAction(uint8_t req) { // Temps defined in configuration.h setTargetTemp_celsius(PREHEAT_1_TEMP_BED, BED); setTargetTemp_celsius(PREHEAT_1_TEMP_HOTEND, E0); - tftSendLn(); + SendtoTFTLN(); hotbed_state = AC_heater_temp_set; hotend_state = AC_heater_temp_set; } @@ -722,7 +736,7 @@ void ChironTFT::panelAction(uint8_t req) { if (!isPrinting()) { setTargetTemp_celsius(PREHEAT_2_TEMP_BED, BED); setTargetTemp_celsius(PREHEAT_2_TEMP_HOTEND, E0); - tftSendLn(); + SendtoTFTLN(); hotbed_state = AC_heater_temp_set; hotend_state = AC_heater_temp_set; } @@ -733,7 +747,7 @@ void ChironTFT::panelAction(uint8_t req) { if (!isPrinting()) { setTargetTemp_celsius(0, E0); setTargetTemp_celsius(0, BED); - tftSendLn(AC_msg_ready); + SendtoTFTLN(AC_msg_ready); hotbed_state = AC_heater_off; hotend_state = AC_heater_off; } @@ -752,21 +766,21 @@ void ChironTFT::panelAction(uint8_t req) { case 28: // A28 Filament set A28 O/C // Ignore request if printing if (isPrinting()) break; - tftSendLn(); + SendtoTFTLN(); break; } } -void ChironTFT::panelProcess(uint8_t req) { +void ChironTFT::PanelProcess(uint8_t req) { switch (req) { case 29: { // A29 Read Mesh Point A29 X1 Y1 xy_uint8_t pos; float pos_z; - pos.x = atoi(&panel_command[findToken('X')+1]); - pos.y = atoi(&panel_command[findToken('Y')+1]); + pos.x = atoi(&panel_command[FindToken('X')+1]); + pos.y = atoi(&panel_command[FindToken('Y')+1]); pos_z = getMeshPoint(pos); - tftSend(F("A29V ")); + SendtoTFT(F("A29V ")); TFTSer.println(pos_z * 100); if (!isPrinting()) { setSoftEndstopState(true); // disable endstops @@ -777,7 +791,7 @@ void ChironTFT::panelProcess(uint8_t req) { if (isPositionKnown()) { #if ACDEBUG(AC_INFO) - DEBUG_ECHOLNPGM("Moving to mesh point at x: ", pos.x, " y: ", pos.y, " z: ", pos_z); + SERIAL_ECHOLNPGM("Moving to mesh point at x: ", pos.x, " y: ", pos.y, " z: ", pos_z); #endif // Go up before moving setAxisPosition_mm(3.0,Z); @@ -786,7 +800,7 @@ void ChironTFT::panelProcess(uint8_t req) { setAxisPosition_mm(20 + (93 * pos.y), Y); setAxisPosition_mm(0.0, Z); #if ACDEBUG(AC_INFO) - DEBUG_ECHOLNPGM("Current Z: ", getAxisPosition_mm(Z)); + SERIAL_ECHOLNPGM("Current Z: ", getAxisPosition_mm(Z)); #endif } } @@ -796,42 +810,42 @@ void ChironTFT::panelProcess(uint8_t req) { } break; case 30: // A30 Auto leveling - if (findToken('S') >= 0) { // Start probing New panel adds spaces.. + if (FindToken('S') >= 0) { // Start probing New panel adds spaces.. // Ignore request if printing if (isPrinting()) - tftSendLn(AC_msg_probing_not_allowed); // forbid auto leveling + SendtoTFTLN(AC_msg_probing_not_allowed); // forbid auto leveling else { - tftSendLn(AC_msg_start_probing); + SendtoTFTLN(AC_msg_start_probing); injectCommands(F("G28\nG29")); printer_state = AC_printer_probing; } } else - tftSendLn(AC_msg_start_probing); // Just enter levelling menu + SendtoTFTLN(AC_msg_start_probing); // Just enter levelling menu break; case 31: // A31 Adjust all Probe Points // The tokens can occur in different places on the new panel so we need to find it. - if (findToken('C') >= 0) { // Restore and apply original offsets + if (FindToken('C') >= 0) { // Restore and apply original offsets if (!isPrinting()) { injectCommands(F("M501\nM420 S1")); selectedmeshpoint.x = selectedmeshpoint.y = 99; - SERIAL_ECHOLN(AC_msg_mesh_changes_abandoned); + SERIAL_ECHOLNF(AC_msg_mesh_changes_abandoned); } } - else if (findToken('D') >= 0) { // Save Z Offset tables and restore leveling state + else if (FindToken('D') >= 0) { // Save Z Offset tables and restore leveling state if (!isPrinting()) { setAxisPosition_mm(1.0,Z); // Lift nozzle before any further movements are made injectCommands(F("M500")); - SERIAL_ECHOLN(AC_msg_mesh_changes_saved); + SERIAL_ECHOLNF(AC_msg_mesh_changes_saved); selectedmeshpoint.x = selectedmeshpoint.y = 99; } } - else if (findToken('G') >= 0) { // Get current offset - tftSend(F("A31V ")); + else if (FindToken('G') >= 0) { // Get current offset + SendtoTFT(F("A31V ")); // When printing use the live z Offset position // we will use babystepping to move the print head if (isPrinting()) @@ -843,7 +857,7 @@ void ChironTFT::panelProcess(uint8_t req) { } else { - int8_t tokenpos = findToken('S'); + int8_t tokenpos = FindToken('S'); if (tokenpos >= 0) { // Set offset (adjusts all points by value) float Zshift = atof(&panel_command[tokenpos+1]); setSoftEndstopState(false); // disable endstops @@ -851,22 +865,22 @@ void ChironTFT::panelProcess(uint8_t req) { // From the leveling panel use the all points UI to adjust the print pos. if (isPrinting()) { #if ACDEBUG(AC_INFO) - DEBUG_ECHOLNPGM("Change Zoffset from:", live_Zoffset, " to ", live_Zoffset + Zshift); + SERIAL_ECHOLNPGM("Change Zoffset from:", live_Zoffset, " to ", live_Zoffset + Zshift); #endif if (isAxisPositionKnown(Z)) { #if ACDEBUG(AC_INFO) const float currZpos = getAxisPosition_mm(Z); - DEBUG_ECHOLNPGM("Nudge Z pos from ", currZpos, " to ", currZpos + constrain(Zshift, -0.05, 0.05)); + SERIAL_ECHOLNPGM("Nudge Z pos from ", currZpos, " to ", currZpos + constrain(Zshift, -0.05, 0.05)); #endif // Use babystepping to adjust the head position int16_t steps = mmToWholeSteps(constrain(Zshift,-0.05,0.05), Z); #if ACDEBUG(AC_INFO) - DEBUG_ECHOLNPGM("Steps to move Z: ", steps); + SERIAL_ECHOLNPGM("Steps to move Z: ", steps); #endif babystepAxis_steps(steps, Z); live_Zoffset += Zshift; } - tftSend(F("A31V ")); + SendtoTFT(F("A31V ")); TFTSer.println(live_Zoffset); } else { @@ -875,23 +889,23 @@ void ChironTFT::panelProcess(uint8_t req) { const float currval = getMeshPoint(pos); setMeshPoint(pos, constrain(currval + Zshift, AC_LOWEST_MESHPOINT_VAL, 2)); #if ACDEBUG(AC_INFO) - DEBUG_ECHOLNPGM("Change mesh point X", x," Y",y ," from ", currval, " to ", getMeshPoint(pos) ); + SERIAL_ECHOLNPGM("Change mesh point X", x," Y",y ," from ", currval, " to ", getMeshPoint(pos) ); #endif } const float currZOffset = getZOffset_mm(); #if ACDEBUG(AC_INFO) - DEBUG_ECHOLNPGM("Change probe offset from ", currZOffset, " to ", currZOffset + Zshift); + SERIAL_ECHOLNPGM("Change probe offset from ", currZOffset, " to ", currZOffset + Zshift); #endif setZOffset_mm(currZOffset + Zshift); - tftSend(F("A31V ")); + SendtoTFT(F("A31V ")); TFTSer.println(getZOffset_mm()); if (isAxisPositionKnown(Z)) { // Move Z axis const float currZpos = getAxisPosition_mm(Z); #if ACDEBUG(AC_INFO) - DEBUG_ECHOLNPGM("Move Z pos from ", currZpos, " to ", currZpos + constrain(Zshift, -0.05, 0.05)); + SERIAL_ECHOLNPGM("Move Z pos from ", currZpos, " to ", currZpos + constrain(Zshift, -0.05, 0.05)); #endif setAxisPosition_mm(currZpos+constrain(Zshift,-0.05,0.05),Z); } @@ -907,7 +921,7 @@ void ChironTFT::panelProcess(uint8_t req) { //TFTSer.println(); break; - // A33 firmware info request see panelInfo() + // A33 firmware info request see PanelInfo() case 34: // A34 Adjust single mesh point A34 C/S X1 Y1 V123 if (panel_command[3] == 'C') { // Restore original offsets @@ -923,8 +937,8 @@ void ChironTFT::panelProcess(uint8_t req) { float currmesh = getMeshPoint(pos); float newval = atof(&panel_command[11])/100; #if ACDEBUG(AC_INFO) - DEBUG_ECHOLNPGM("Change mesh point x:", pos.x, " y:", pos.y); - DEBUG_ECHOLNPGM("from ", currmesh, " to ", newval); + SERIAL_ECHOLNPGM("Change mesh point x:", pos.x, " y:", pos.y); + SERIAL_ECHOLNPGM("from ", currmesh, " to ", newval); #endif // Update Meshpoint setMeshPoint(pos,newval); @@ -935,7 +949,7 @@ void ChironTFT::panelProcess(uint8_t req) { setSoftEndstopState(false); float currZpos = getAxisPosition_mm(Z); #if ACDEBUG(AC_INFO) - DEBUG_ECHOLNPGM("Move Z pos from ", currZpos, " to ", currZpos + constrain(newval - currmesh, -0.05, 0.05)); + SERIAL_ECHOLNPGM("Move Z pos from ", currZpos, " to ", currZpos + constrain(newval - currmesh, -0.05, 0.05)); #endif setAxisPosition_mm(currZpos + constrain(newval - currmesh, -0.05, 0.05), Z); } @@ -944,19 +958,19 @@ void ChironTFT::panelProcess(uint8_t req) { break; case 36: // A36 Auto leveling for new TFT bet that was a typo in the panel code! - tftSendLn(AC_msg_start_probing); + SendtoTFTLN(AC_msg_start_probing); break; } } -bool ChironTFT::getLastError() { +bool ChironTFT::GetLastError() { switch (last_error) { - case AC_error_abnormal_temp_bed: tftSendLn(AC_msg_error_bed_temp); break; - case AC_error_abnormal_temp_t0: tftSendLn(AC_msg_error_hotend_temp); break; - case AC_error_noSD: tftSendLn(AC_msg_error_sd_card); break; - case AC_error_powerloss: tftSendLn(AC_msg_power_loss); break; - case AC_error_EEPROM: tftSendLn(AC_msg_eeprom_version); break; - case AC_error_filament_runout: tftSendLn(AC_msg_filament_out); break; + case AC_error_abnormal_temp_bed: SendtoTFTLN(AC_msg_error_bed_temp); break; + case AC_error_abnormal_temp_t0: SendtoTFTLN(AC_msg_error_hotend_temp); break; + case AC_error_noSD: SendtoTFTLN(AC_msg_error_sd_card); break; + case AC_error_powerloss: SendtoTFTLN(AC_msg_power_loss); break; + case AC_error_EEPROM: SendtoTFTLN(AC_msg_eeprom_version); break; + case AC_error_filament_runout: SendtoTFTLN(AC_msg_filament_out); break; default: return false; } last_error = AC_error_none; diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/filament_runout_screen.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/filament_runout_screen.cpp index 0569b90032..6ee1fedba4 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/filament_runout_screen.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/filament_runout_screen.cpp @@ -34,14 +34,13 @@ void FilamentRunoutScreen::onRedraw(draw_mode_t what) { w.heading( GET_TEXT_F(MSG_FILAMENT)); w.toggle( 2, GET_TEXT_F(MSG_RUNOUT_SENSOR), getFilamentRunoutEnabled()); - #if HAS_FILAMENT_RUNOUT_DISTANCE - w.heading(GET_TEXT_F(MSG_RUNOUT_DISTANCE_MM)); - w.units(GET_TEXT_F(MSG_UNITS_MM)); - w.precision(0); - w.color(e_axis); - w.adjuster( 10, FPSTR(NUL_STR), getFilamentRunoutDistance_mm(), getFilamentRunoutEnabled()); - w.increments(); - #endif + w.heading(GET_TEXT_F(MSG_RUNOUT_DISTANCE_MM)); + w.units(GET_TEXT_F(MSG_UNITS_MM)); + w.precision(0); + w.color(e_axis); + w.adjuster( 10, FPSTR(NUL_STR), getFilamentRunoutDistance_mm(), getFilamentRunoutEnabled()); + w.increments(); + } bool FilamentRunoutScreen::onTouchHeld(uint8_t tag) { @@ -51,10 +50,8 @@ bool FilamentRunoutScreen::onTouchHeld(uint8_t tag) { #endif switch (tag) { case 2: setFilamentRunoutEnabled(!getFilamentRunoutEnabled()); break; - #if HAS_FILAMENT_RUNOUT_DISTANCE - case 10: UI_DECREMENT(FilamentRunoutDistance_mm); break; - case 11: UI_INCREMENT(FilamentRunoutDistance_mm); break; - #endif + case 10: UI_DECREMENT(FilamentRunoutDistance_mm); break; + case 11: UI_INCREMENT(FilamentRunoutDistance_mm); break; default: return false; } diff --git a/Marlin/src/lcd/extui/ui_api.cpp b/Marlin/src/lcd/extui/ui_api.cpp index ec9b05318c..e96e601577 100644 --- a/Marlin/src/lcd/extui/ui_api.cpp +++ b/Marlin/src/lcd/extui/ui_api.cpp @@ -722,15 +722,12 @@ namespace ExtUI { } #if HAS_FILAMENT_SENSOR - bool getFilamentRunoutEnabled() { return runout.enabled; } - void setFilamentRunoutEnabled(const bool value) { runout.enabled = value; } + bool getFilamentRunoutEnabled(const extruder_t extruder/*=E0*/) { return runout.enabled[extruder]; } + void setFilamentRunoutEnabled(const bool value, const extruder_t extruder/*=E0*/) { runout.enabled[extruder] = value; } bool getFilamentRunoutState() { return runout.filament_ran_out; } void setFilamentRunoutState(const bool value) { runout.filament_ran_out = value; } - - #if HAS_FILAMENT_RUNOUT_DISTANCE - float getFilamentRunoutDistance_mm() { return runout.runout_distance(); } - void setFilamentRunoutDistance_mm(const_float_t value) { runout.set_runout_distance(constrain(value, 0, 999)); } - #endif + float getFilamentRunoutDistance_mm() { return runout.runout_distance(); } + void setFilamentRunoutDistance_mm(const_float_t value) { runout.set_runout_distance(constrain(value, 0, 999)); } #endif #if ENABLED(CASE_LIGHT_ENABLE) diff --git a/Marlin/src/lcd/extui/ui_api.h b/Marlin/src/lcd/extui/ui_api.h index 8202f7be8d..c53a72fb57 100644 --- a/Marlin/src/lcd/extui/ui_api.h +++ b/Marlin/src/lcd/extui/ui_api.h @@ -385,15 +385,12 @@ namespace ExtUI { // Filament Runout Sensor #if HAS_FILAMENT_SENSOR - bool getFilamentRunoutEnabled(); - void setFilamentRunoutEnabled(const bool); + bool getFilamentRunoutEnabled(const extruder_t extruder=E0); + void setFilamentRunoutEnabled(const bool, const extruder_t extruder=E0); bool getFilamentRunoutState(); void setFilamentRunoutState(const bool); - - #if HAS_FILAMENT_RUNOUT_DISTANCE - float getFilamentRunoutDistance_mm(); - void setFilamentRunoutDistance_mm(const_float_t); - #endif + float getFilamentRunoutDistance_mm(); + void setFilamentRunoutDistance_mm(const_float_t); #endif // Case Light Control diff --git a/Marlin/src/lcd/language/language_en.h b/Marlin/src/lcd/language/language_en.h index 1ecf65a57f..d2e527c78c 100644 --- a/Marlin/src/lcd/language/language_en.h +++ b/Marlin/src/lcd/language/language_en.h @@ -719,6 +719,11 @@ namespace LanguageNarrow_en { LSTR MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Nozzle: "); LSTR MSG_RUNOUT_SENSOR = _UxGT("Runout Sensor"); LSTR MSG_RUNOUT_DISTANCE_MM = _UxGT("Runout Dist mm"); + LSTR MSG_RUNOUT_MODE = _UxGT("Runout Mode"); + LSTR MSG_RUNOUT_MODE_HIGH = _UxGT("Sensor High"); + LSTR MSG_RUNOUT_MODE_LOW = _UxGT("Sensor Low"); + LSTR MSG_RUNOUT_MODE_MOTION = _UxGT("Motion Encoder"); + LSTR MSG_RUNOUT_MODE_NONE = _UxGT("No Sensor"); LSTR MSG_RUNOUT_ENABLE = _UxGT("Enable Runout"); LSTR MSG_RUNOUT_ACTIVE = _UxGT("Runout Active"); LSTR MSG_INVERT_EXTRUDER = _UxGT("Invert Extruder"); diff --git a/Marlin/src/lcd/menu/menu_advanced.cpp b/Marlin/src/lcd/menu/menu_advanced.cpp index 22c0823f26..a0eba750e4 100644 --- a/Marlin/src/lcd/menu/menu_advanced.cpp +++ b/Marlin/src/lcd/menu/menu_advanced.cpp @@ -45,7 +45,7 @@ #include "../../module/temperature.h" #endif -#if HAS_FILAMENT_RUNOUT_DISTANCE +#if HAS_FILAMENT_SENSOR #include "../../feature/runout.h" #endif @@ -99,6 +99,54 @@ void menu_backlash(); #endif +#if HAS_FILAMENT_SENSOR && DISABLED(SLIM_LCD_MENUS) + + void set_runout_mode_none(const uint8_t e) { runout.mode[e] = RM_NONE; runout.setup(); } + void set_runout_mode_high(const uint8_t e) { runout.mode[e] = RM_OUT_ON_HIGH; runout.setup(); } + void set_runout_mode_low(const uint8_t e) { runout.mode[e] = RM_OUT_ON_LOW; runout.setup(); } + void set_runout_mode_motion(const uint8_t e) { runout.mode[e] = RM_MOTION_SENSOR; runout.setup(); } + + #define RUNOUT_EDIT_ITEMS(F) do{ \ + EDIT_ITEM(bool, MSG_RUNOUT_SENSOR, &runout.enabled[F]); \ + ACTION_ITEM(MSG_RUNOUT_MODE_NONE, []{ set_runout_mode_none(F); }); \ + ACTION_ITEM(MSG_RUNOUT_MODE_HIGH, []{ set_runout_mode_high(F); }); \ + ACTION_ITEM(MSG_RUNOUT_MODE_LOW, []{ set_runout_mode_low(F); }); \ + ACTION_ITEM(MSG_RUNOUT_MODE_MOTION, []{ set_runout_mode_motion(F); }); \ + editable.decimal = runout.runout_distance(F); \ + EDIT_ITEM_FAST(float3, MSG_RUNOUT_DISTANCE_MM, &editable.decimal, 1, 999, \ + []{ runout.set_runout_distance(editable.decimal, F); }, true \ + ); \ + }while(0) + + void menu_runout_config() { + START_MENU(); + BACK_ITEM(MSG_CONFIGURATION); + RUNOUT_EDIT_ITEMS(0); + #if NUM_RUNOUT_SENSORS > 1 + RUNOUT_EDIT_ITEMS(1); + #endif + #if NUM_RUNOUT_SENSORS > 2 + RUNOUT_EDIT_ITEMS(2); + #endif + #if NUM_RUNOUT_SENSORS > 3 + RUNOUT_EDIT_ITEMS(3); + #endif + #if NUM_RUNOUT_SENSORS > 4 + RUNOUT_EDIT_ITEMS(4); + #endif + #if NUM_RUNOUT_SENSORS > 5 + RUNOUT_EDIT_ITEMS(5); + #endif + #if NUM_RUNOUT_SENSORS > 6 + RUNOUT_EDIT_ITEMS(6); + #endif + #if NUM_RUNOUT_SENSORS > 7 + RUNOUT_EDIT_ITEMS(7); + #endif + END_MENU(); + } +#endif + #if DISABLED(NO_VOLUMETRICS) || ENABLED(ADVANCED_PAUSE_FEATURE) // // Advanced Settings > Filament @@ -152,11 +200,8 @@ void menu_backlash(); #endif #endif - #if HAS_FILAMENT_RUNOUT_DISTANCE - editable.decimal = runout.runout_distance(); - EDIT_ITEM_FAST(float3, MSG_RUNOUT_DISTANCE_MM, &editable.decimal, 1, 999, - []{ runout.set_runout_distance(editable.decimal); }, true - ); + #if HAS_FILAMENT_SENSOR && DISABLED(SLIM_LCD_MENUS) + SUBMENU(MSG_RUNOUT_MODE, menu_runout_config); #endif END_MENU(); diff --git a/Marlin/src/lcd/menu/menu_configuration.cpp b/Marlin/src/lcd/menu/menu_configuration.cpp index bd5ed492a1..d5fca1f60a 100644 --- a/Marlin/src/lcd/menu/menu_configuration.cpp +++ b/Marlin/src/lcd/menu/menu_configuration.cpp @@ -634,7 +634,7 @@ void menu_configuration() { #endif #if HAS_FILAMENT_SENSOR - EDIT_ITEM(bool, MSG_RUNOUT_SENSOR, &runout.enabled, runout.reset); + EDIT_ITEM(bool, MSG_RUNOUT_SENSOR, &runout.enabled[active_extruder], runout.reset); #endif #if HAS_FANCHECK diff --git a/Marlin/src/lcd/menu/menu_filament.cpp b/Marlin/src/lcd/menu/menu_filament.cpp index 46ebf85ba4..c6436bafc3 100644 --- a/Marlin/src/lcd/menu/menu_filament.cpp +++ b/Marlin/src/lcd/menu/menu_filament.cpp @@ -26,7 +26,7 @@ #include "../../inc/MarlinConfigPre.h" -#if ALL(HAS_MARLINUI_MENU, ADVANCED_PAUSE_FEATURE) +#if BOTH(HAS_MARLINUI_MENU, ADVANCED_PAUSE_FEATURE) #include "menu_item.h" #include "../../module/temperature.h" @@ -96,7 +96,7 @@ void _menu_temp_filament_op(const PauseMode mode, const int8_t extruder) { if (LCD_HEIGHT >= 4) STATIC_ITEM_F(change_filament_header(mode), SS_DEFAULT|SS_INVERT); BACK_ITEM(MSG_BACK); #if HAS_PREHEAT - for (uint8_t m = 0; m < PREHEAT_COUNT; ++m) + LOOP_L_N(m, PREHEAT_COUNT) ACTION_ITEM_N_f(m, ui.get_preheat_label(m), MSG_PREHEAT_M, _change_filament_with_preset); #endif EDIT_ITEM_FAST_N(int3, extruder, MSG_PREHEAT_CUSTOM, &thermalManager.temp_hotend[extruder].target, @@ -130,7 +130,7 @@ void menu_change_filament() { #endif START_MENU(); - BACK_ITEM(MSG_MAIN_MENU); + BACK_ITEM(MSG_MAIN); // Change filament #if E_STEPPERS == 1 @@ -141,7 +141,7 @@ void menu_change_filament() { GCODES_ITEM_F(fmsg, F("M600 B0")); #else FSTR_P const fmsg = GET_TEXT_F(MSG_FILAMENTCHANGE_E); - for (uint8_t s = 0; s < E_STEPPERS; ++s) { + LOOP_L_N(s, E_STEPPERS) { if (thermalManager.targetTooColdToExtrude(s)) SUBMENU_N_F(s, fmsg, []{ _menu_temp_filament_op(PAUSE_MODE_CHANGE_FILAMENT, MenuItemBase::itemIndex); }); else { @@ -166,7 +166,7 @@ void menu_change_filament() { GCODES_ITEM_F(msg_load, F("M701")); #else FSTR_P const msg_load = GET_TEXT_F(MSG_FILAMENTLOAD_E); - for (uint8_t s = 0; s < E_STEPPERS; ++s) { + LOOP_L_N(s, E_STEPPERS) { if (thermalManager.targetTooColdToExtrude(s)) SUBMENU_N_F(s, msg_load, []{ _menu_temp_filament_op(PAUSE_MODE_LOAD_FILAMENT, MenuItemBase::itemIndex); }); else { @@ -194,7 +194,7 @@ void menu_change_filament() { GCODES_ITEM(MSG_FILAMENTUNLOAD_ALL, F("M702")); #endif FSTR_P const msg_unload = GET_TEXT_F(MSG_FILAMENTUNLOAD_E); - for (uint8_t s = 0; s < E_STEPPERS; ++s) { + LOOP_L_N(s, E_STEPPERS) { if (thermalManager.targetTooColdToExtrude(s)) SUBMENU_N_F(s, msg_unload, []{ _menu_temp_filament_op(PAUSE_MODE_UNLOAD_FILAMENT, MenuItemBase::itemIndex); }); else { @@ -250,12 +250,6 @@ static FSTR_P pause_header() { }while(0) void menu_pause_option() { - #if HAS_FILAMENT_SENSOR - const bool still_out = runout.filament_ran_out; - #else - constexpr bool still_out = false; - #endif - START_MENU(); #if LCD_HEIGHT > 2 STATIC_ITEM(MSG_FILAMENT_CHANGE_OPTION_HEADER); @@ -263,8 +257,11 @@ void menu_pause_option() { ACTION_ITEM(MSG_FILAMENT_CHANGE_OPTION_PURGE, []{ pause_menu_response = PAUSE_RESPONSE_EXTRUDE_MORE; }); #if HAS_FILAMENT_SENSOR + const bool still_out = runout.filament_ran_out; if (still_out) - EDIT_ITEM(bool, MSG_RUNOUT_SENSOR, &runout.enabled, runout.reset); + EDIT_ITEM(bool, MSG_RUNOUT_SENSOR, &runout.enabled[active_extruder], runout.reset); + #else + constexpr bool still_out = false; #endif if (!still_out) diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index 490d6bc2ce..f288252b5a 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -31,14 +31,14 @@ #include "temperature.h" #include "../lcd/marlinui.h" -#define DEBUG_OUT ALL(USE_SENSORLESS, DEBUG_LEVELING_FEATURE) +#define DEBUG_OUT BOTH(USE_SENSORLESS, DEBUG_LEVELING_FEATURE) #include "../core/debug_out.h" #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) - #include HAL_PATH(.., endstop_interrupts.h) + #include HAL_PATH(../HAL, endstop_interrupts.h) #endif -#if ENABLED(SD_ABORT_ON_ENDSTOP_HIT) +#if BOTH(SD_ABORT_ON_ENDSTOP_HIT, SDSUPPORT) #include "printcounter.h" // for print_job_timer #endif @@ -50,6 +50,10 @@ #include "../feature/joystick.h" #endif +#if HAS_FILAMENT_SENSOR + #include "../feature/runout.h" +#endif + #if HAS_BED_PROBE #include "probe.h" #endif @@ -65,11 +69,7 @@ Endstops::endstop_mask_t Endstops::live_state = 0; #if ENABLED(BD_SENSOR) bool Endstops::bdp_state; // = false - #if HOMING_Z_WITH_PROBE - #define READ_ENDSTOP(P) ((P == TERN(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, Z_MIN_PIN, Z_MIN_PROBE_PIN)) ? bdp_state : READ(P)) - #else - #define READ_ENDSTOP(P) READ(P) - #endif + #define READ_ENDSTOP(P) ((P == Z_MIN_PIN) ? bdp_state : READ(P)) #else #define READ_ENDSTOP(P) READ(P) #endif @@ -113,90 +113,284 @@ Endstops::endstop_mask_t Endstops::live_state = 0; void Endstops::init() { - #define _INIT_ENDSTOP(T,A,N) TERN(ENDSTOPPULLUP_##A##T, SET_INPUT_PULLUP, TERN(ENDSTOPPULLDOWN_##A##T, SET_INPUT_PULLDOWN, SET_INPUT))(A##N##_##T##_PIN) - #if USE_X_MIN - _INIT_ENDSTOP(MIN,X,); + #if HAS_X_MIN + #if ENABLED(ENDSTOPPULLUP_XMIN) + SET_INPUT_PULLUP(X_MIN_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_XMIN) + SET_INPUT_PULLDOWN(X_MIN_PIN); + #else + SET_INPUT(X_MIN_PIN); + #endif #endif - #if USE_X_MAX - _INIT_ENDSTOP(MAX,X,); + + #if HAS_X2_MIN + #if ENABLED(ENDSTOPPULLUP_XMIN) + SET_INPUT_PULLUP(X2_MIN_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_XMIN) + SET_INPUT_PULLDOWN(X2_MIN_PIN); + #else + SET_INPUT(X2_MIN_PIN); + #endif #endif - #if USE_X2_MIN - _INIT_ENDSTOP(MIN,X,2); + + #if HAS_Y_MIN + #if ENABLED(ENDSTOPPULLUP_YMIN) + SET_INPUT_PULLUP(Y_MIN_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_YMIN) + SET_INPUT_PULLDOWN(Y_MIN_PIN); + #else + SET_INPUT(Y_MIN_PIN); + #endif #endif - #if USE_X2_MAX - _INIT_ENDSTOP(MAX,X,2); + + #if HAS_Y2_MIN + #if ENABLED(ENDSTOPPULLUP_YMIN) + SET_INPUT_PULLUP(Y2_MIN_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_YMIN) + SET_INPUT_PULLDOWN(Y2_MIN_PIN); + #else + SET_INPUT(Y2_MIN_PIN); + #endif #endif - #if USE_Y_MIN - _INIT_ENDSTOP(MIN,Y,); + + #if HAS_Z_MIN + #if ENABLED(ENDSTOPPULLUP_ZMIN) + SET_INPUT_PULLUP(Z_MIN_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_ZMIN) + SET_INPUT_PULLDOWN(Z_MIN_PIN); + #else + SET_INPUT(Z_MIN_PIN); + #endif #endif - #if USE_Y_MAX - _INIT_ENDSTOP(MAX,Y,); + + #if HAS_Z2_MIN + #if ENABLED(ENDSTOPPULLUP_ZMIN) + SET_INPUT_PULLUP(Z2_MIN_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_ZMIN) + SET_INPUT_PULLDOWN(Z2_MIN_PIN); + #else + SET_INPUT(Z2_MIN_PIN); + #endif #endif - #if USE_Y2_MIN - _INIT_ENDSTOP(MIN,Y,2); + + #if HAS_Z3_MIN + #if ENABLED(ENDSTOPPULLUP_ZMIN) + SET_INPUT_PULLUP(Z3_MIN_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_ZMIN) + SET_INPUT_PULLDOWN(Z3_MIN_PIN); + #else + SET_INPUT(Z3_MIN_PIN); + #endif #endif - #if USE_Y2_MAX - _INIT_ENDSTOP(MAX,Y,2); + + #if HAS_Z4_MIN + #if ENABLED(ENDSTOPPULLUP_ZMIN) + SET_INPUT_PULLUP(Z4_MIN_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_ZMIN) + SET_INPUT_PULLDOWN(Z4_MIN_PIN); + #else + SET_INPUT(Z4_MIN_PIN); + #endif #endif - #if USE_Z_MIN - _INIT_ENDSTOP(MIN,Z,); + + #if HAS_X_MAX + #if ENABLED(ENDSTOPPULLUP_XMAX) + SET_INPUT_PULLUP(X_MAX_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_XMAX) + SET_INPUT_PULLDOWN(X_MAX_PIN); + #else + SET_INPUT(X_MAX_PIN); + #endif #endif - #if USE_Z_MAX - _INIT_ENDSTOP(MAX,Z,); + + #if HAS_X2_MAX + #if ENABLED(ENDSTOPPULLUP_XMAX) + SET_INPUT_PULLUP(X2_MAX_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_XMAX) + SET_INPUT_PULLDOWN(X2_MAX_PIN); + #else + SET_INPUT(X2_MAX_PIN); + #endif #endif - #if USE_Z2_MIN - _INIT_ENDSTOP(MIN,Z,2); + + #if HAS_Y_MAX + #if ENABLED(ENDSTOPPULLUP_YMAX) + SET_INPUT_PULLUP(Y_MAX_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_YMAX) + SET_INPUT_PULLDOWN(Y_MAX_PIN); + #else + SET_INPUT(Y_MAX_PIN); + #endif #endif - #if USE_Z2_MAX - _INIT_ENDSTOP(MAX,Z,2); + + #if HAS_Y2_MAX + #if ENABLED(ENDSTOPPULLUP_YMAX) + SET_INPUT_PULLUP(Y2_MAX_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_YMAX) + SET_INPUT_PULLDOWN(Y2_MAX_PIN); + #else + SET_INPUT(Y2_MAX_PIN); + #endif #endif - #if USE_Z3_MIN - _INIT_ENDSTOP(MIN,Z,3); + + #if HAS_Z_MAX + #if ENABLED(ENDSTOPPULLUP_ZMAX) + SET_INPUT_PULLUP(Z_MAX_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_ZMAX) + SET_INPUT_PULLDOWN(Z_MAX_PIN); + #else + SET_INPUT(Z_MAX_PIN); + #endif #endif - #if USE_Z3_MAX - _INIT_ENDSTOP(MAX,Z,3); + + #if HAS_Z2_MAX + #if ENABLED(ENDSTOPPULLUP_ZMAX) + SET_INPUT_PULLUP(Z2_MAX_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_ZMAX) + SET_INPUT_PULLDOWN(Z2_MAX_PIN); + #else + SET_INPUT(Z2_MAX_PIN); + #endif #endif - #if USE_Z4_MIN - _INIT_ENDSTOP(MIN,Z,4); + + #if HAS_Z3_MAX + #if ENABLED(ENDSTOPPULLUP_ZMAX) + SET_INPUT_PULLUP(Z3_MAX_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_ZMAX) + SET_INPUT_PULLDOWN(Z3_MAX_PIN); + #else + SET_INPUT(Z3_MAX_PIN); + #endif #endif - #if USE_Z4_MAX - _INIT_ENDSTOP(MAX,Z,4); + + #if HAS_Z4_MAX + #if ENABLED(ENDSTOPPULLUP_ZMAX) + SET_INPUT_PULLUP(Z4_MAX_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_ZMAX) + SET_INPUT_PULLDOWN(Z4_MAX_PIN); + #else + SET_INPUT(Z4_MAX_PIN); + #endif #endif - #if USE_I_MIN - _INIT_ENDSTOP(MIN,I,); + + #if HAS_I_MIN + #if ENABLED(ENDSTOPPULLUP_IMIN) + SET_INPUT_PULLUP(I_MIN_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_IMIN) + SET_INPUT_PULLDOWN(I_MIN_PIN); + #else + SET_INPUT(I_MIN_PIN); + #endif #endif - #if USE_I_MAX - _INIT_ENDSTOP(MAX,I,); + + #if HAS_I_MAX + #if ENABLED(ENDSTOPPULLUP_IMAX) + SET_INPUT_PULLUP(I_MAX_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_IMAX) + SET_INPUT_PULLDOWN(I_MAX_PIN); + #else + SET_INPUT(I_MAX_PIN); + #endif #endif - #if USE_J_MIN - _INIT_ENDSTOP(MIN,J,); + + #if HAS_J_MIN + #if ENABLED(ENDSTOPPULLUP_JMIN) + SET_INPUT_PULLUP(J_MIN_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_IMIN) + SET_INPUT_PULLDOWN(J_MIN_PIN); + #else + SET_INPUT(J_MIN_PIN); + #endif #endif - #if USE_J_MAX - _INIT_ENDSTOP(MAX,J,); + + #if HAS_J_MAX + #if ENABLED(ENDSTOPPULLUP_JMAX) + SET_INPUT_PULLUP(J_MAX_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_JMAX) + SET_INPUT_PULLDOWN(J_MAX_PIN); + #else + SET_INPUT(J_MAX_PIN); + #endif #endif - #if USE_K_MIN - _INIT_ENDSTOP(MIN,K,); + + #if HAS_K_MIN + #if ENABLED(ENDSTOPPULLUP_KMIN) + SET_INPUT_PULLUP(K_MIN_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_KMIN) + SET_INPUT_PULLDOWN(K_MIN_PIN); + #else + SET_INPUT(K_MIN_PIN); + #endif #endif - #if USE_K_MAX - _INIT_ENDSTOP(MAX,K,); + + #if HAS_K_MAX + #if ENABLED(ENDSTOPPULLUP_KMAX) + SET_INPUT_PULLUP(K_MAX_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_KMIN) + SET_INPUT_PULLDOWN(K_MAX_PIN); + #else + SET_INPUT(K_MAX_PIN); + #endif #endif - #if USE_U_MIN - _INIT_ENDSTOP(MIN,U,); + + #if HAS_U_MIN + #if ENABLED(ENDSTOPPULLUP_UMIN) + SET_INPUT_PULLUP(U_MIN_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_UMIN) + SET_INPUT_PULLDOWN(U_MIN_PIN); + #else + SET_INPUT(U_MIN_PIN); + #endif #endif - #if USE_U_MAX - _INIT_ENDSTOP(MAX,U,); + + #if HAS_U_MAX + #if ENABLED(ENDSTOPPULLUP_UMAX) + SET_INPUT_PULLUP(U_MAX_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_UMIN) + SET_INPUT_PULLDOWN(U_MAX_PIN); + #else + SET_INPUT(U_MAX_PIN); + #endif #endif - #if USE_V_MIN - _INIT_ENDSTOP(MIN,V,); + + #if HAS_V_MIN + #if ENABLED(ENDSTOPPULLUP_VMIN) + SET_INPUT_PULLUP(V_MIN_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_VMIN) + SET_INPUT_PULLDOWN(V_MIN_PIN); + #else + SET_INPUT(V_MIN_PIN); + #endif #endif - #if USE_V_MAX - _INIT_ENDSTOP(MAX,V,); + + #if HAS_V_MAX + #if ENABLED(ENDSTOPPULLUP_VMAX) + SET_INPUT_PULLUP(V_MAX_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_VMIN) + SET_INPUT_PULLDOWN(V_MAX_PIN); + #else + SET_INPUT(V_MAX_PIN); + #endif #endif - #if USE_W_MIN - _INIT_ENDSTOP(MIN,W,); + + #if HAS_W_MIN + #if ENABLED(ENDSTOPPULLUP_WMIN) + SET_INPUT_PULLUP(W_MIN_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_WMIN) + SET_INPUT_PULLDOWN(W_MIN_PIN); + #else + SET_INPUT(W_MIN_PIN); + #endif #endif - #if USE_W_MAX - _INIT_ENDSTOP(MAX,W,); + + #if HAS_W_MAX + #if ENABLED(ENDSTOPPULLUP_WMAX) + SET_INPUT_PULLUP(W_MAX_PIN); + #elif ENABLED(ENDSTOPPULLDOWN_WMIN) + SET_INPUT_PULLDOWN(W_MAX_PIN); + #else + SET_INPUT(W_MAX_PIN); + #endif #endif #if PIN_EXISTS(CALIBRATION) @@ -209,7 +403,7 @@ void Endstops::init() { #endif #endif - #if USE_Z_MIN_PROBE + #if USES_Z_MIN_PROBE_PIN #if ENABLED(ENDSTOPPULLUP_ZMIN_PROBE) SET_INPUT_PULLUP(Z_MIN_PROBE_PIN); #elif ENABLED(ENDSTOPPULLDOWN_ZMIN_PROBE) @@ -304,7 +498,7 @@ void Endstops::event_handler() { prev_hit_state = hit_state; if (hit_state) { #if HAS_STATUS_MESSAGE - char NUM_AXIS_LIST_(chrX = ' ', chrY = ' ', chrZ = ' ', chrI = ' ', chrJ = ' ', chrK = ' ', chrU = ' ', chrV = ' ', chrW = ' ') + char NUM_AXIS_LIST(chrX = ' ', chrY = ' ', chrZ = ' ', chrI = ' ', chrJ = ' ', chrK = ' ', chrU = ' ', chrV = ' ', chrW = ' '), chrP = ' '; #define _SET_STOP_CHAR(A,C) (chr## A = C) #else @@ -315,7 +509,7 @@ void Endstops::event_handler() { SERIAL_ECHOPGM(" " STRINGIFY(A) ":", planner.triggered_position_mm(_AXIS(A))); _SET_STOP_CHAR(A,C); }while(0) #define _ENDSTOP_HIT_TEST(A,C) \ - if (TERN0(HAS_##A##_MIN_STATE, TEST(hit_state, ES_ENUM(A,MIN))) || TERN0(HAS_##A##_MAX_STATE, TEST(hit_state, ES_ENUM(A,MAX)))) \ + if (TERN0(HAS_##A##_MIN, TEST(hit_state, A##_MIN)) || TERN0(HAS_##A##_MAX, TEST(hit_state, A##_MAX))) \ _ENDSTOP_HIT_ECHO(A,C) #define ENDSTOP_HIT_TEST_X() _ENDSTOP_HIT_TEST(X,'X') @@ -342,7 +536,7 @@ void Endstops::event_handler() { _ENDSTOP_HIT_TEST(W,'W') ); - #if USE_Z_MIN_PROBE + #if USES_Z_MIN_PROBE_PIN #define P_AXIS Z_AXIS if (TEST(hit_state, Z_MIN_PROBE)) _ENDSTOP_HIT_ECHO(P, 'P'); #endif @@ -352,11 +546,11 @@ void Endstops::event_handler() { ui.status_printf(0, F(S_FMT GANG_N_1(NUM_AXES, " %c") " %c"), GET_TEXT(MSG_LCD_ENDSTOPS), - NUM_AXIS_LIST_(chrX, chrY, chrZ, chrI, chrJ, chrK, chrU, chrV, chrW) chrP + NUM_AXIS_LIST(chrX, chrY, chrZ, chrI, chrJ, chrK, chrU, chrV, chrW), chrP ) ); - #if ENABLED(SD_ABORT_ON_ENDSTOP_HIT) + #if BOTH(SD_ABORT_ON_ENDSTOP_HIT, SDSUPPORT) if (planner.abort_on_endstop_hit) { card.abortFilePrintNow(); quickstop_stepper(); @@ -371,132 +565,142 @@ void Endstops::event_handler() { } } -#if NUM_AXES - - #pragma GCC diagnostic push - #if GCC_VERSION <= 50000 - #pragma GCC diagnostic ignored "-Wunused-function" - #endif - - static void print_es_state(const bool is_hit, FSTR_P const flabel=nullptr) { - if (flabel) SERIAL_ECHO(flabel); - SERIAL_ECHOLN(F(": "), is_hit ? F(STR_ENDSTOP_HIT) : F(STR_ENDSTOP_OPEN)); - } - - #pragma GCC diagnostic pop - +#pragma GCC diagnostic push +#if GCC_VERSION <= 50000 + #pragma GCC diagnostic ignored "-Wunused-function" #endif +static void print_es_state(const bool is_hit, FSTR_P const flabel=nullptr) { + if (flabel) SERIAL_ECHOF(flabel); + SERIAL_ECHOPGM(": "); + SERIAL_ECHOLNF(is_hit ? F(STR_ENDSTOP_HIT) : F(STR_ENDSTOP_OPEN)); +} + +#pragma GCC diagnostic pop + void __O2 Endstops::report_states() { TERN_(BLTOUCH, bltouch._set_SW_mode()); SERIAL_ECHOLNPGM(STR_M119_REPORT); - #define ES_REPORT(S) print_es_state(READ_ENDSTOP(S##_PIN) == S##_ENDSTOP_HIT_STATE, F(STR_##S)) - #if USE_X_MIN + #define ES_REPORT(S) print_es_state(READ_ENDSTOP(S##_PIN) != S##_ENDSTOP_INVERTING, F(STR_##S)) + #if HAS_X_MIN ES_REPORT(X_MIN); #endif - #if USE_X2_MIN + #if HAS_X2_MIN ES_REPORT(X2_MIN); #endif - #if USE_X_MAX + #if HAS_X_MAX ES_REPORT(X_MAX); #endif - #if USE_X2_MAX + #if HAS_X2_MAX ES_REPORT(X2_MAX); #endif - #if USE_Y_MIN + #if HAS_Y_MIN ES_REPORT(Y_MIN); #endif - #if USE_Y2_MIN + #if HAS_Y2_MIN ES_REPORT(Y2_MIN); #endif - #if USE_Y_MAX + #if HAS_Y_MAX ES_REPORT(Y_MAX); #endif - #if USE_Y2_MAX + #if HAS_Y2_MAX ES_REPORT(Y2_MAX); #endif - #if USE_Z_MIN + #if HAS_Z_MIN ES_REPORT(Z_MIN); #endif - #if USE_Z2_MIN + #if HAS_Z2_MIN ES_REPORT(Z2_MIN); #endif - #if USE_Z3_MIN + #if HAS_Z3_MIN ES_REPORT(Z3_MIN); #endif - #if USE_Z4_MIN + #if HAS_Z4_MIN ES_REPORT(Z4_MIN); #endif - #if USE_Z_MAX + #if HAS_Z_MAX ES_REPORT(Z_MAX); #endif - #if USE_Z2_MAX + #if HAS_Z2_MAX ES_REPORT(Z2_MAX); #endif - #if USE_Z3_MAX + #if HAS_Z3_MAX ES_REPORT(Z3_MAX); #endif - #if USE_Z4_MAX + #if HAS_Z4_MAX ES_REPORT(Z4_MAX); #endif - #if USE_I_MIN + #if HAS_I_MIN ES_REPORT(I_MIN); #endif - #if USE_I_MAX + #if HAS_I_MAX ES_REPORT(I_MAX); #endif - #if USE_J_MIN + #if HAS_J_MIN ES_REPORT(J_MIN); #endif - #if USE_J_MAX + #if HAS_J_MAX ES_REPORT(J_MAX); #endif - #if USE_K_MIN + #if HAS_K_MIN ES_REPORT(K_MIN); #endif - #if USE_K_MAX + #if HAS_K_MAX ES_REPORT(K_MAX); #endif - #if USE_U_MIN + #if HAS_U_MIN ES_REPORT(U_MIN); #endif - #if USE_U_MAX + #if HAS_U_MAX ES_REPORT(U_MAX); #endif - #if USE_V_MIN + #if HAS_V_MIN ES_REPORT(V_MIN); #endif - #if USE_V_MAX + #if HAS_V_MAX ES_REPORT(V_MAX); #endif - #if USE_W_MIN + #if HAS_W_MIN ES_REPORT(W_MIN); #endif - #if USE_W_MAX + #if HAS_W_MAX ES_REPORT(W_MAX); #endif #if ENABLED(PROBE_ACTIVATION_SWITCH) print_es_state(probe_switch_activated(), F(STR_PROBE_EN)); #endif - #if USE_Z_MIN_PROBE + #if USES_Z_MIN_PROBE_PIN print_es_state(PROBE_TRIGGERED(), F(STR_Z_PROBE)); #endif - #if MULTI_FILAMENT_SENSOR - #define _CASE_RUNOUT(N) case N: pin = FIL_RUNOUT##N##_PIN; state = FIL_RUNOUT##N##_STATE; break; - for (uint8_t i = 1; i <= NUM_RUNOUT_SENSORS; ++i) { + #if HAS_FILAMENT_SENSOR + LOOP_S_LE_N(i, 1, NUM_RUNOUT_SENSORS) { pin_t pin; - uint8_t state; switch (i) { default: continue; + #define _CASE_RUNOUT(N) case N: pin = FIL_RUNOUT##N##_PIN; break; REPEAT_1(NUM_RUNOUT_SENSORS, _CASE_RUNOUT) + #undef _CASE_RUNOUT } - SERIAL_ECHOPGM(STR_FILAMENT); - if (i > 1) SERIAL_CHAR(' ', '0' + i); - print_es_state(extDigitalRead(pin) != state); + const RunoutMode rm = runout.mode[i - 1]; + const uint8_t outval = runout.out_state(i - 1); + + #if DISABLED(SLIM_LCD_MENUS) + SERIAL_ECHOPGM(STR_FILAMENT); + if (i > 1) SERIAL_CHAR(' ', '0' + i); + SERIAL_ECHOPGM(": "); + if (rm == RM_NONE) + SERIAL_ECHOLNPGM(STR_OFF); + else if (rm == RM_MOTION_SENSOR) { + SERIAL_ECHOPGM("MOTION : "); + print_es_state(extDigitalRead(pin) == outval); + } + else + SERIAL_ECHOLNPGM_P(extDigitalRead(pin) == outval ? PSTR("OUT") : PSTR("PRESENT")); + #else + print_es_state(extDigitalRead(pin) == outval, F(STR_FILAMENT)); + #endif } - #undef _CASE_RUNOUT - #elif HAS_FILAMENT_SENSOR - print_es_state(READ(FIL_RUNOUT1_PIN) != FIL_RUNOUT1_STATE, F(STR_FILAMENT)); + #endif TERN_(BLTOUCH, bltouch._reset_SW_mode()); @@ -504,6 +708,17 @@ void __O2 Endstops::report_states() { } // Endstops::report_states +#if HAS_DELTA_SENSORLESS_PROBING + #define __ENDSTOP(AXIS, ...) AXIS ##_MAX + #define _ENDSTOP_PIN(AXIS, ...) AXIS ##_MAX_PIN + #define _ENDSTOP_INVERTING(AXIS, ...) AXIS ##_MAX_ENDSTOP_INVERTING +#else + #define __ENDSTOP(AXIS, MINMAX) AXIS ##_## MINMAX + #define _ENDSTOP_PIN(AXIS, MINMAX) AXIS ##_## MINMAX ##_PIN + #define _ENDSTOP_INVERTING(AXIS, MINMAX) AXIS ##_## MINMAX ##_ENDSTOP_INVERTING +#endif +#define _ENDSTOP(AXIS, MINMAX) __ENDSTOP(AXIS, MINMAX) + /** * Called from interrupt context by the Endstop ISR or Stepper ISR! * Read endstops to get their current states, register hits for all @@ -516,19 +731,18 @@ void Endstops::update() { #endif // Macros to update / copy the live_state - #define _ES_PIN(A,M) A##_##M##_PIN - #define _ES_HIT(A,M) A##_##M##_ENDSTOP_HIT_STATE - #define UPDATE_LIVE_STATE(AXIS, MINMAX) SET_BIT_TO(live_state, ES_ENUM(AXIS, MINMAX), (READ_ENDSTOP(_ES_PIN(AXIS, MINMAX)) == _ES_HIT(AXIS, MINMAX))) + #define UPDATE_ENDSTOP_BIT(AXIS, MINMAX) SET_BIT_TO(live_state, _ENDSTOP(AXIS, MINMAX), (READ_ENDSTOP(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX))) #define COPY_LIVE_STATE(SRC_BIT, DST_BIT) SET_BIT_TO(live_state, DST_BIT, TEST(live_state, SRC_BIT)) - #if ENABLED(G38_PROBE_TARGET) + #if ENABLED(G38_PROBE_TARGET) && NONE(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY, MARKFORGED_YX) + #define HAS_G38_PROBE 1 // For G38 moves check the probe's pin for ALL movement - if (G38_move) UPDATE_LIVE_STATE(Z, TERN(USE_Z_MIN_PROBE, MIN_PROBE, MIN)); + if (G38_move) UPDATE_ENDSTOP_BIT(Z, TERN(USES_Z_MIN_PROBE_PIN, MIN_PROBE, MIN)); #endif // With Dual X, endstops are only checked in the homing direction for the active extruder - #define X_MIN_TEST() TERN1(DUAL_X_CARRIAGE, stepper.last_moved_extruder == 0) // Check min for the left carriage - #define X_MAX_TEST() TERN1(DUAL_X_CARRIAGE, stepper.last_moved_extruder != 0) // Check max for the right carriage + #define X_MIN_TEST() TERN1(DUAL_X_CARRIAGE, TERN0(X_HOME_TO_MIN, stepper.last_moved_extruder == 0) || TERN0(X2_HOME_TO_MIN, stepper.last_moved_extruder != 0)) + #define X_MAX_TEST() TERN1(DUAL_X_CARRIAGE, TERN0(X_HOME_TO_MAX, stepper.last_moved_extruder == 0) || TERN0(X2_HOME_TO_MAX, stepper.last_moved_extruder != 0)) // Use HEAD for core axes, AXIS for others #if ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY, MARKFORGED_YX) @@ -557,129 +771,262 @@ void Endstops::update() { /** * Check and update endstops */ - #if USE_X_MIN - UPDATE_LIVE_STATE(X, MIN); + #if HAS_X_MIN && !X_SPI_SENSORLESS + UPDATE_ENDSTOP_BIT(X, MIN); #if ENABLED(X_DUAL_ENDSTOPS) - #if USE_X2_MIN - UPDATE_LIVE_STATE(X2, MIN); + #if HAS_X2_MIN + UPDATE_ENDSTOP_BIT(X2, MIN); #else COPY_LIVE_STATE(X_MIN, X2_MIN); #endif #endif #endif - #if USE_X_MAX - UPDATE_LIVE_STATE(X, MAX); + #if HAS_X_MAX && !X_SPI_SENSORLESS + UPDATE_ENDSTOP_BIT(X, MAX); #if ENABLED(X_DUAL_ENDSTOPS) - #if USE_X2_MAX - UPDATE_LIVE_STATE(X2, MAX); + #if HAS_X2_MAX + UPDATE_ENDSTOP_BIT(X2, MAX); #else COPY_LIVE_STATE(X_MAX, X2_MAX); #endif #endif #endif - #if USE_Y_MIN - UPDATE_LIVE_STATE(Y, MIN); + #if HAS_Y_MIN && !Y_SPI_SENSORLESS + UPDATE_ENDSTOP_BIT(Y, MIN); #if ENABLED(Y_DUAL_ENDSTOPS) - #if USE_Y2_MIN - UPDATE_LIVE_STATE(Y2, MIN); + #if HAS_Y2_MIN + UPDATE_ENDSTOP_BIT(Y2, MIN); #else COPY_LIVE_STATE(Y_MIN, Y2_MIN); #endif #endif #endif - #if USE_Y_MAX - UPDATE_LIVE_STATE(Y, MAX); + #if HAS_Y_MAX && !Y_SPI_SENSORLESS + UPDATE_ENDSTOP_BIT(Y, MAX); #if ENABLED(Y_DUAL_ENDSTOPS) - #if USE_Y2_MAX - UPDATE_LIVE_STATE(Y2, MAX); + #if HAS_Y2_MAX + UPDATE_ENDSTOP_BIT(Y2, MAX); #else COPY_LIVE_STATE(Y_MAX, Y2_MAX); #endif #endif #endif - #if USE_Z_MIN && NONE(Z_SPI_SENSORLESS, Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) - UPDATE_LIVE_STATE(Z, MIN); - #endif - #if USE_Z2_MIN - UPDATE_LIVE_STATE(Z2, MIN); - #elif HAS_Z2_MIN_STATE - COPY_LIVE_STATE(Z_MIN, Z2_MIN); - #endif - #if USE_Z3_MIN - UPDATE_LIVE_STATE(Z3, MIN); - #elif HAS_Z3_MIN_STATE - COPY_LIVE_STATE(Z_MIN, Z3_MIN); - #endif - #if USE_Z4_MIN - UPDATE_LIVE_STATE(Z4, MIN); - #elif HAS_Z4_MIN_STATE - COPY_LIVE_STATE(Z_MIN, Z4_MIN); + #if HAS_Z_MIN && NONE(Z_SPI_SENSORLESS, Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) + UPDATE_ENDSTOP_BIT(Z, MIN); + #if ENABLED(Z_MULTI_ENDSTOPS) + #if HAS_Z2_MIN + UPDATE_ENDSTOP_BIT(Z2, MIN); + #else + COPY_LIVE_STATE(Z_MIN, Z2_MIN); + #endif + #if NUM_Z_STEPPERS >= 3 + #if HAS_Z3_MIN + UPDATE_ENDSTOP_BIT(Z3, MIN); + #else + COPY_LIVE_STATE(Z_MIN, Z3_MIN); + #endif + #endif + #if NUM_Z_STEPPERS >= 4 + #if HAS_Z4_MIN + UPDATE_ENDSTOP_BIT(Z4, MIN); + #else + COPY_LIVE_STATE(Z_MIN, Z4_MIN); + #endif + #endif + #endif #endif - #if HAS_REAL_BED_PROBE + #if HAS_BED_PROBE // When closing the gap check the enabled probe if (probe_switch_activated()) - UPDATE_LIVE_STATE(Z, TERN(USE_Z_MIN_PROBE, MIN_PROBE, MIN)); + UPDATE_ENDSTOP_BIT(Z, TERN(USES_Z_MIN_PROBE_PIN, MIN_PROBE, MIN)); #endif - #if USE_Z_MAX - UPDATE_LIVE_STATE(Z, MAX); - #endif - #if USE_Z2_MAX - UPDATE_LIVE_STATE(Z2, MAX); - #elif HAS_Z2_MAX_STATE - COPY_LIVE_STATE(Z_MAX, Z2_MAX); - #endif - #if USE_Z3_MAX - UPDATE_LIVE_STATE(Z3, MAX); - #elif HAS_Z3_MAX_STATE - COPY_LIVE_STATE(Z_MAX, Z3_MAX); - #endif - #if USE_Z4_MAX - UPDATE_LIVE_STATE(Z4, MAX); - #elif HAS_Z4_MAX_STATE - COPY_LIVE_STATE(Z_MAX, Z4_MAX); + #if HAS_Z_MAX && !Z_SPI_SENSORLESS + // Check both Z dual endstops + #if ENABLED(Z_MULTI_ENDSTOPS) + UPDATE_ENDSTOP_BIT(Z, MAX); + #if HAS_Z2_MAX + UPDATE_ENDSTOP_BIT(Z2, MAX); + #else + COPY_LIVE_STATE(Z_MAX, Z2_MAX); + #endif + #if NUM_Z_STEPPERS >= 3 + #if HAS_Z3_MAX + UPDATE_ENDSTOP_BIT(Z3, MAX); + #else + COPY_LIVE_STATE(Z_MAX, Z3_MAX); + #endif + #endif + #if NUM_Z_STEPPERS >= 4 + #if HAS_Z4_MAX + UPDATE_ENDSTOP_BIT(Z4, MAX); + #else + COPY_LIVE_STATE(Z_MAX, Z4_MAX); + #endif + #endif + #elif TERN1(USES_Z_MIN_PROBE_PIN, Z_MAX_PIN != Z_MIN_PROBE_PIN) + // If this pin isn't the bed probe it's the Z endstop + UPDATE_ENDSTOP_BIT(Z, MAX); + #endif #endif - #if USE_I_MIN - UPDATE_LIVE_STATE(I, MIN); + #if HAS_I_MIN && !I_SPI_SENSORLESS + #if ENABLED(I_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(I, MIN); + #if HAS_I2_MIN + UPDATE_ENDSTOP_BIT(I2, MAX); + #else + COPY_LIVE_STATE(I_MIN, I2_MIN); + #endif + #else + UPDATE_ENDSTOP_BIT(I, MIN); + #endif #endif - #if USE_I_MAX - UPDATE_LIVE_STATE(I, MAX); + + #if HAS_I_MAX && !I_SPI_SENSORLESS + #if ENABLED(I_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(I, MAX); + #if HAS_I2_MAX + UPDATE_ENDSTOP_BIT(I2, MAX); + #else + COPY_LIVE_STATE(I_MAX, I2_MAX); + #endif + #else + UPDATE_ENDSTOP_BIT(I, MAX); + #endif #endif - #if USE_J_MIN - UPDATE_LIVE_STATE(J, MIN); + + #if HAS_J_MIN && !J_SPI_SENSORLESS + #if ENABLED(J_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(J, MIN); + #if HAS_J2_MIN + UPDATE_ENDSTOP_BIT(J2, MIN); + #else + COPY_LIVE_STATE(J_MIN, J2_MIN); + #endif + #else + UPDATE_ENDSTOP_BIT(J, MIN); + #endif #endif - #if USE_J_MAX - UPDATE_LIVE_STATE(J, MAX); + + #if HAS_J_MAX && !J_SPI_SENSORLESS + #if ENABLED(J_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(J, MAX); + #if HAS_J2_MAX + UPDATE_ENDSTOP_BIT(J2, MAX); + #else + COPY_LIVE_STATE(J_MAX, J2_MAX); + #endif + #else + UPDATE_ENDSTOP_BIT(J, MAX); + #endif #endif - #if USE_K_MIN - UPDATE_LIVE_STATE(K, MIN); + + #if HAS_K_MIN && !K_SPI_SENSORLESS + #if ENABLED(K_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(K, MIN); + #if HAS_K2_MIN + UPDATE_ENDSTOP_BIT(K2, MIN); + #else + COPY_LIVE_STATE(K_MIN, K2_MIN); + #endif + #else + UPDATE_ENDSTOP_BIT(K, MIN); + #endif #endif - #if USE_K_MAX - UPDATE_LIVE_STATE(K, MAX); + + #if HAS_K_MAX && !K_SPI_SENSORLESS + #if ENABLED(K_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(K, MAX); + #if HAS_K2_MAX + UPDATE_ENDSTOP_BIT(K2, MAX); + #else + COPY_LIVE_STATE(K_MAX, K2_MAX); + #endif + #else + UPDATE_ENDSTOP_BIT(K, MAX); + #endif #endif - #if USE_U_MIN - UPDATE_LIVE_STATE(U, MIN); + + #if HAS_U_MIN && !U_SPI_SENSORLESS + #if ENABLED(U_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(U, MIN); + #if HAS_U2_MIN + UPDATE_ENDSTOP_BIT(U2, MIN); + #else + COPY_LIVE_STATE(U_MIN, U2_MIN); + #endif + #else + UPDATE_ENDSTOP_BIT(U, MIN); + #endif #endif - #if USE_U_MAX - UPDATE_LIVE_STATE(U, MAX); + + #if HAS_U_MAX && !U_SPI_SENSORLESS + #if ENABLED(U_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(U, MAX); + #if HAS_U2_MAX + UPDATE_ENDSTOP_BIT(U2, MAX); + #else + COPY_LIVE_STATE(U_MAX, U2_MAX); + #endif + #else + UPDATE_ENDSTOP_BIT(U, MAX); + #endif #endif - #if USE_V_MIN - UPDATE_LIVE_STATE(V, MIN); + + #if HAS_V_MIN && !V_SPI_SENSORLESS + #if ENABLED(V_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(V, MIN); + #if HAS_V2_MIN + UPDATE_ENDSTOP_BIT(V2, MIN); + #else + COPY_LIVE_STATE(V_MIN, V2_MIN); + #endif + #else + UPDATE_ENDSTOP_BIT(V, MIN); + #endif #endif - #if USE_V_MAX - UPDATE_LIVE_STATE(V, MAX); + #if HAS_V_MAX && !V_SPI_SENSORLESS + #if ENABLED(O_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(V, MAX); + #if HAS_V2_MAX + UPDATE_ENDSTOP_BIT(V2, MAX); + #else + COPY_LIVE_STATE(V_MAX, V2_MAX); + #endif + #else + UPDATE_ENDSTOP_BIT(V, MAX); + #endif #endif - #if USE_W_MIN - UPDATE_LIVE_STATE(W, MIN); + + #if HAS_W_MIN && !W_SPI_SENSORLESS + #if ENABLED(W_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(W, MIN); + #if HAS_W2_MIN + UPDATE_ENDSTOP_BIT(W2, MIN); + #else + COPY_LIVE_STATE(W_MIN, W2_MIN); + #endif + #else + UPDATE_ENDSTOP_BIT(W, MIN); + #endif #endif - #if USE_W_MAX - UPDATE_LIVE_STATE(W, MAX); + #if HAS_W_MAX && !W_SPI_SENSORLESS + #if ENABLED(W_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(W, MAX); + #if HAS_W2_MAX + UPDATE_ENDSTOP_BIT(W2, MAX); + #else + COPY_LIVE_STATE(W_MAX, W2_MAX); + #endif + #else + UPDATE_ENDSTOP_BIT(W, MAX); + #endif #endif #if ENDSTOP_NOISE_THRESHOLD @@ -710,20 +1057,20 @@ void Endstops::update() { #define TEST_ENDSTOP(ENDSTOP) (TEST(state(), ENDSTOP)) // Record endstop was hit - #define _ENDSTOP_HIT(AXIS, MINMAX) SBI(hit_state, ES_ENUM(AXIS, MINMAX)) + #define _ENDSTOP_HIT(AXIS, MINMAX) SBI(hit_state, _ENDSTOP(AXIS, MINMAX)) // Call the endstop triggered routine for single endstops #define PROCESS_ENDSTOP(AXIS, MINMAX) do { \ - if (TEST_ENDSTOP(ES_ENUM(AXIS, MINMAX))) { \ + if (TEST_ENDSTOP(_ENDSTOP(AXIS, MINMAX))) { \ _ENDSTOP_HIT(AXIS, MINMAX); \ planner.endstop_triggered(_AXIS(AXIS)); \ } \ }while(0) // Core Sensorless Homing needs to test an Extra Pin - #define CORE_DIAG(QQ,A,MM) (CORE_IS_##QQ && A##_SENSORLESS && !A##_SPI_SENSORLESS && USE_##A##_##MM) + #define CORE_DIAG(QQ,A,MM) (CORE_IS_##QQ && A##_SENSORLESS && !A##_SPI_SENSORLESS && HAS_##A##_##MM) #define PROCESS_CORE_ENDSTOP(A1,M1,A2,M2) do { \ - if (TEST_ENDSTOP(ES_ENUM(A1,M1))) { \ + if (TEST_ENDSTOP(_ENDSTOP(A1,M1))) { \ _ENDSTOP_HIT(A2,M2); \ planner.endstop_triggered(_AXIS(A2)); \ } \ @@ -731,7 +1078,7 @@ void Endstops::update() { // Call the endstop triggered routine for dual endstops #define PROCESS_DUAL_ENDSTOP(A, MINMAX) do { \ - const byte dual_hit = TEST_ENDSTOP(ES_ENUM(A, MINMAX)) | (TEST_ENDSTOP(ES_ENUM(A##2, MINMAX)) << 1); \ + const byte dual_hit = TEST_ENDSTOP(_ENDSTOP(A, MINMAX)) | (TEST_ENDSTOP(_ENDSTOP(A##2, MINMAX)) << 1); \ if (dual_hit) { \ _ENDSTOP_HIT(A, MINMAX); \ /* if not performing home or if both endstops were triggered during homing... */ \ @@ -741,7 +1088,7 @@ void Endstops::update() { }while(0) #define PROCESS_TRIPLE_ENDSTOP(A, MINMAX) do { \ - const byte triple_hit = TEST_ENDSTOP(ES_ENUM(A, MINMAX)) | (TEST_ENDSTOP(ES_ENUM(A##2, MINMAX)) << 1) | (TEST_ENDSTOP(ES_ENUM(A##3, MINMAX)) << 2); \ + const byte triple_hit = TEST_ENDSTOP(_ENDSTOP(A, MINMAX)) | (TEST_ENDSTOP(_ENDSTOP(A##2, MINMAX)) << 1) | (TEST_ENDSTOP(_ENDSTOP(A##3, MINMAX)) << 2); \ if (triple_hit) { \ _ENDSTOP_HIT(A, MINMAX); \ /* if not performing home or if both endstops were triggered during homing... */ \ @@ -751,7 +1098,7 @@ void Endstops::update() { }while(0) #define PROCESS_QUAD_ENDSTOP(A, MINMAX) do { \ - const byte quad_hit = TEST_ENDSTOP(ES_ENUM(A, MINMAX)) | (TEST_ENDSTOP(ES_ENUM(A##2, MINMAX)) << 1) | (TEST_ENDSTOP(ES_ENUM(A##3, MINMAX)) << 2) | (TEST_ENDSTOP(ES_ENUM(A##4, MINMAX)) << 3); \ + const byte quad_hit = TEST_ENDSTOP(_ENDSTOP(A, MINMAX)) | (TEST_ENDSTOP(_ENDSTOP(A##2, MINMAX)) << 1) | (TEST_ENDSTOP(_ENDSTOP(A##3, MINMAX)) << 2) | (TEST_ENDSTOP(_ENDSTOP(A##4, MINMAX)) << 3); \ if (quad_hit) { \ _ENDSTOP_HIT(A, MINMAX); \ /* if not performing home or if both endstops were triggered during homing... */ \ @@ -782,56 +1129,58 @@ void Endstops::update() { #define PROCESS_ENDSTOP_Z(MINMAX) PROCESS_DUAL_ENDSTOP(Z, MINMAX) #endif - #if ENABLED(G38_PROBE_TARGET) + #if HAS_G38_PROBE // TODO (DerAndere): Add support for HAS_I_AXIS + #define _G38_OPEN_STATE TERN(G38_PROBE_AWAY, (G38_move >= 4), LOW) // For G38 moves check the probe's pin for ALL movement - if (G38_move && TEST_ENDSTOP(Z_MIN_PROBE) == TERN1(G38_PROBE_AWAY, (G38_move < 4))) { + if (G38_move && TEST_ENDSTOP(_ENDSTOP(Z, TERN(USES_Z_MIN_PROBE_PIN, MIN_PROBE, MIN))) != _G38_OPEN_STATE) { + if (stepper.axis_is_moving(X_AXIS)) { _ENDSTOP_HIT(X, TERN(X_HOME_TO_MIN, MIN, MAX)); planner.endstop_triggered(X_AXIS); } + #if HAS_Y_AXIS + else if (stepper.axis_is_moving(Y_AXIS)) { _ENDSTOP_HIT(Y, TERN(Y_HOME_TO_MIN, MIN, MAX)); planner.endstop_triggered(Y_AXIS); } + #endif + #if HAS_Z_AXIS + else if (stepper.axis_is_moving(Z_AXIS)) { _ENDSTOP_HIT(Z, TERN(Z_HOME_TO_MIN, MIN, MAX)); planner.endstop_triggered(Z_AXIS); } + #endif G38_did_trigger = true; - #define _G38_SET(Q) | (stepper.axis_is_moving(_AXIS(Q)) << _AXIS(Q)) - #define _G38_RESP(Q) if (moving[_AXIS(Q)]) { _ENDSTOP_HIT(Q, ENDSTOP); planner.endstop_triggered(_AXIS(Q)); } - const Flags moving = { uvalue_t(NUM_AXES)(0 MAIN_AXIS_MAP(_G38_SET)) }; - MAIN_AXIS_MAP(_G38_RESP); } #endif // Signal, after validation, if an endstop limit is pressed or not - #if HAS_X_AXIS - if (stepper.axis_is_moving(X_AXIS)) { - if (!stepper.motor_direction(X_AXIS_HEAD)) { // -direction - #if HAS_X_MIN_STATE - PROCESS_ENDSTOP_X(MIN); - #if CORE_DIAG(XY, Y, MIN) - PROCESS_CORE_ENDSTOP(Y,MIN,X,MIN); - #elif CORE_DIAG(XY, Y, MAX) - PROCESS_CORE_ENDSTOP(Y,MAX,X,MIN); - #elif CORE_DIAG(XZ, Z, MIN) - PROCESS_CORE_ENDSTOP(Z,MIN,X,MIN); - #elif CORE_DIAG(XZ, Z, MAX) - PROCESS_CORE_ENDSTOP(Z,MAX,X,MIN); - #endif + if (stepper.axis_is_moving(X_AXIS)) { + if (stepper.motor_direction(X_AXIS_HEAD)) { // -direction + #if HAS_X_MIN || (X_SPI_SENSORLESS && X_HOME_TO_MIN) + PROCESS_ENDSTOP_X(MIN); + #if CORE_DIAG(XY, Y, MIN) + PROCESS_CORE_ENDSTOP(Y,MIN,X,MIN); + #elif CORE_DIAG(XY, Y, MAX) + PROCESS_CORE_ENDSTOP(Y,MAX,X,MIN); + #elif CORE_DIAG(XZ, Z, MIN) + PROCESS_CORE_ENDSTOP(Z,MIN,X,MIN); + #elif CORE_DIAG(XZ, Z, MAX) + PROCESS_CORE_ENDSTOP(Z,MAX,X,MIN); #endif - } - else { // +direction - #if HAS_X_MAX_STATE - PROCESS_ENDSTOP_X(MAX); - #if CORE_DIAG(XY, Y, MIN) - PROCESS_CORE_ENDSTOP(Y,MIN,X,MAX); - #elif CORE_DIAG(XY, Y, MAX) - PROCESS_CORE_ENDSTOP(Y,MAX,X,MAX); - #elif CORE_DIAG(XZ, Z, MIN) - PROCESS_CORE_ENDSTOP(Z,MIN,X,MAX); - #elif CORE_DIAG(XZ, Z, MAX) - PROCESS_CORE_ENDSTOP(Z,MAX,X,MAX); - #endif - #endif - } + #endif } - #endif // HAS_X_AXIS + else { // +direction + #if HAS_X_MAX || (X_SPI_SENSORLESS && X_HOME_TO_MAX) + PROCESS_ENDSTOP_X(MAX); + #if CORE_DIAG(XY, Y, MIN) + PROCESS_CORE_ENDSTOP(Y,MIN,X,MAX); + #elif CORE_DIAG(XY, Y, MAX) + PROCESS_CORE_ENDSTOP(Y,MAX,X,MAX); + #elif CORE_DIAG(XZ, Z, MIN) + PROCESS_CORE_ENDSTOP(Z,MIN,X,MAX); + #elif CORE_DIAG(XZ, Z, MAX) + PROCESS_CORE_ENDSTOP(Z,MAX,X,MAX); + #endif + #endif + } + } #if HAS_Y_AXIS if (stepper.axis_is_moving(Y_AXIS)) { - if (!stepper.motor_direction(Y_AXIS_HEAD)) { // -direction - #if HAS_Y_MIN_STATE + if (stepper.motor_direction(Y_AXIS_HEAD)) { // -direction + #if HAS_Y_MIN || (Y_SPI_SENSORLESS && Y_HOME_TO_MIN) PROCESS_ENDSTOP_Y(MIN); #if CORE_DIAG(XY, X, MIN) PROCESS_CORE_ENDSTOP(X,MIN,Y,MIN); @@ -845,7 +1194,7 @@ void Endstops::update() { #endif } else { // +direction - #if HAS_Y_MAX_STATE + #if HAS_Y_MAX || (Y_SPI_SENSORLESS && Y_HOME_TO_MAX) PROCESS_ENDSTOP_Y(MAX); #if CORE_DIAG(XY, X, MIN) PROCESS_CORE_ENDSTOP(X,MIN,Y,MAX); @@ -859,39 +1208,39 @@ void Endstops::update() { #endif } } - #endif // HAS_Y_AXIS + #endif #if HAS_Z_AXIS if (stepper.axis_is_moving(Z_AXIS)) { - if (!stepper.motor_direction(Z_AXIS_HEAD)) { // Z -direction. Gantry down, bed up. - #if HAS_Z_MIN_STATE - // If the Z_MIN_PIN is being used for the probe there's no - // separate Z_MIN endstop. But a Z endstop could be wired - // in series, so someone might find this useful. - if ( TERN1(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, z_probe_enabled) // When Z_MIN is the probe, the probe must be enabled - && TERN1(USE_Z_MIN_PROBE, !z_probe_enabled) // When Z_MIN isn't the probe, Z MIN is ignored while probing - ) { - PROCESS_ENDSTOP_Z(MIN); - #if CORE_DIAG(XZ, X, MIN) - PROCESS_CORE_ENDSTOP(X,MIN,Z,MIN); - #elif CORE_DIAG(XZ, X, MAX) - PROCESS_CORE_ENDSTOP(X,MAX,Z,MIN); - #elif CORE_DIAG(YZ, Y, MIN) - PROCESS_CORE_ENDSTOP(Y,MIN,Z,MIN); - #elif CORE_DIAG(YZ, Y, MAX) - PROCESS_CORE_ENDSTOP(Y,MAX,Z,MIN); - #endif - } + if (stepper.motor_direction(Z_AXIS_HEAD)) { // Z -direction. Gantry down, bed up. + + #if HAS_Z_MIN || (Z_SPI_SENSORLESS && Z_HOME_TO_MIN) + if ( TERN1(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, z_probe_enabled) + && TERN1(USES_Z_MIN_PROBE_PIN, !z_probe_enabled) + ) PROCESS_ENDSTOP_Z(MIN); + #if CORE_DIAG(XZ, X, MIN) + PROCESS_CORE_ENDSTOP(X,MIN,Z,MIN); + #elif CORE_DIAG(XZ, X, MAX) + PROCESS_CORE_ENDSTOP(X,MAX,Z,MIN); + #elif CORE_DIAG(YZ, Y, MIN) + PROCESS_CORE_ENDSTOP(Y,MIN,Z,MIN); + #elif CORE_DIAG(YZ, Y, MAX) + PROCESS_CORE_ENDSTOP(Y,MAX,Z,MIN); + #endif #endif - // When closing the gap use the probe trigger state - #if USE_Z_MIN_PROBE + // When closing the gap check the enabled probe + #if USES_Z_MIN_PROBE_PIN if (z_probe_enabled) PROCESS_ENDSTOP(Z, MIN_PROBE); #endif } else { // Z +direction. Gantry up, bed down. - #if HAS_Z_MAX_STATE - PROCESS_ENDSTOP_Z(MAX); + #if HAS_Z_MAX || (Z_SPI_SENSORLESS && Z_HOME_TO_MAX) + #if ENABLED(Z_MULTI_ENDSTOPS) + PROCESS_ENDSTOP_Z(MAX); + #elif TERN1(USES_Z_MIN_PROBE_PIN, Z_MAX_PIN != Z_MIN_PROBE_PIN) // No probe or probe is Z_MIN || Probe is not Z_MAX + PROCESS_ENDSTOP(Z, MAX); + #endif #if CORE_DIAG(XZ, X, MIN) PROCESS_CORE_ENDSTOP(X,MIN,Z,MAX); #elif CORE_DIAG(XZ, X, MAX) @@ -904,98 +1253,97 @@ void Endstops::update() { #endif } } - #endif // HAS_Z_AXIS + #endif #if HAS_I_AXIS if (stepper.axis_is_moving(I_AXIS)) { - if (!stepper.motor_direction(I_AXIS_HEAD)) { // -direction - #if HAS_I_MIN_STATE + if (stepper.motor_direction(I_AXIS_HEAD)) { // -direction + #if HAS_I_MIN || (I_SPI_SENSORLESS && I_HOME_TO_MIN) PROCESS_ENDSTOP(I, MIN); #endif } else { // +direction - #if HAS_I_MAX_STATE + #if HAS_I_MAX || (I_SPI_SENSORLESS && I_HOME_TO_MAX) PROCESS_ENDSTOP(I, MAX); #endif } } - #endif // HAS_I_AXIS + #endif #if HAS_J_AXIS if (stepper.axis_is_moving(J_AXIS)) { - if (!stepper.motor_direction(J_AXIS_HEAD)) { // -direction - #if HAS_J_MIN_STATE + if (stepper.motor_direction(J_AXIS_HEAD)) { // -direction + #if HAS_J_MIN || (J_SPI_SENSORLESS && J_HOME_TO_MIN) PROCESS_ENDSTOP(J, MIN); #endif } else { // +direction - #if HAS_J_MAX_STATE + #if HAS_J_MAX || (J_SPI_SENSORLESS && J_HOME_TO_MAX) PROCESS_ENDSTOP(J, MAX); #endif } } - #endif // HAS_J_AXIS + #endif #if HAS_K_AXIS if (stepper.axis_is_moving(K_AXIS)) { - if (!stepper.motor_direction(K_AXIS_HEAD)) { // -direction - #if HAS_K_MIN_STATE + if (stepper.motor_direction(K_AXIS_HEAD)) { // -direction + #if HAS_K_MIN || (K_SPI_SENSORLESS && K_HOME_TO_MIN) PROCESS_ENDSTOP(K, MIN); #endif } else { // +direction - #if HAS_K_MAX_STATE + #if HAS_K_MAX || (K_SPI_SENSORLESS && K_HOME_TO_MAX) PROCESS_ENDSTOP(K, MAX); #endif } } - #endif // HAS_K_AXIS + #endif #if HAS_U_AXIS if (stepper.axis_is_moving(U_AXIS)) { - if (!stepper.motor_direction(U_AXIS_HEAD)) { // -direction - #if HAS_U_MIN_STATE + if (stepper.motor_direction(U_AXIS_HEAD)) { // -direction + #if HAS_U_MIN || (U_SPI_SENSORLESS && U_HOME_TO_MIN) PROCESS_ENDSTOP(U, MIN); #endif } else { // +direction - #if HAS_U_MAX_STATE + #if HAS_U_MAX || (U_SPI_SENSORLESS && U_HOME_TO_MAX) PROCESS_ENDSTOP(U, MAX); #endif } } - #endif // HAS_U_AXIS + #endif #if HAS_V_AXIS if (stepper.axis_is_moving(V_AXIS)) { - if (!stepper.motor_direction(V_AXIS_HEAD)) { // -direction - #if HAS_V_MIN_STATE + if (stepper.motor_direction(V_AXIS_HEAD)) { // -direction + #if HAS_V_MIN || (V_SPI_SENSORLESS && V_HOME_TO_MIN) PROCESS_ENDSTOP(V, MIN); #endif } else { // +direction - #if HAS_V_MAX_STATE + #if HAS_V_MAX || (V_SPI_SENSORLESS && V_HOME_TO_MAX) PROCESS_ENDSTOP(V, MAX); #endif } } - #endif // HAS_V_AXIS + #endif #if HAS_W_AXIS if (stepper.axis_is_moving(W_AXIS)) { - if (!stepper.motor_direction(W_AXIS_HEAD)) { // -direction - #if HAS_W_MIN_STATE + if (stepper.motor_direction(W_AXIS_HEAD)) { // -direction + #if HAS_W_MIN || (W_SPI_SENSORLESS && W_HOME_TO_MIN) PROCESS_ENDSTOP(W, MIN); #endif } else { // +direction - #if HAS_W_MAX_STATE + #if HAS_W_MAX || (W_SPI_SENSORLESS && W_HOME_TO_MAX) PROCESS_ENDSTOP(W, MAX); #endif } } - #endif // HAS_W_AXIS - + #endif } // Endstops::update() #if ENABLED(SPI_ENDSTOPS) @@ -1003,84 +1351,77 @@ void Endstops::update() { // Called from idle() to read Trinamic stall states bool Endstops::tmc_spi_homing_check() { bool hit = false; - #if X_SPI_SENSORLESS - if (tmc_spi_homing.x) { - #if ENABLED(DUAL_X_CARRIAGE) - const bool ismin = X_MIN_TEST(); - #endif - const bool xhit = ( - #if ENABLED(DUAL_X_CARRIAGE) - ismin ? stepperX.test_stall_status() : stepperX2.test_stall_status() - #else - stepperX.test_stall_status() - #if Y_SPI_SENSORLESS && ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) - || stepperY.test_stall_status() - #elif Z_SPI_SENSORLESS && CORE_IS_XZ - || stepperZ.test_stall_status() - #endif - #endif - ); - if (xhit) { SBI(live_state, TERN(DUAL_X_CARRIAGE, ismin ? X_MIN : X_MAX, X_ENDSTOP)); hit = true; } - #if ENABLED(X_DUAL_ENDSTOPS) - if (stepperX2.test_stall_status()) { SBI(live_state, X2_ENDSTOP); hit = true; } + if (tmc_spi_homing.x && (stepperX.test_stall_status() + #if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) && Y_SPI_SENSORLESS + || stepperY.test_stall_status() + #elif CORE_IS_XZ && Z_SPI_SENSORLESS + || stepperZ.test_stall_status() #endif + )) { + SBI(live_state, X_ENDSTOP); + hit = true; } #endif - #if Y_SPI_SENSORLESS - if (tmc_spi_homing.y) { - if (stepperY.test_stall_status() - #if X_SPI_SENSORLESS && ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) - || stepperX.test_stall_status() - #elif Z_SPI_SENSORLESS && CORE_IS_YZ - || stepperZ.test_stall_status() - #endif - ) { SBI(live_state, Y_ENDSTOP); hit = true; } - #if ENABLED(Y_DUAL_ENDSTOPS) - if (stepperY2.test_stall_status()) { SBI(live_state, Y2_ENDSTOP); hit = true; } + if (tmc_spi_homing.y && (stepperY.test_stall_status() + #if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) && X_SPI_SENSORLESS + || stepperX.test_stall_status() + #elif CORE_IS_YZ && Z_SPI_SENSORLESS + || stepperZ.test_stall_status() #endif + )) { + SBI(live_state, Y_ENDSTOP); + hit = true; } #endif - #if Z_SPI_SENSORLESS - if (tmc_spi_homing.z) { - if (stepperZ.test_stall_status() - #if X_SPI_SENSORLESS && CORE_IS_XZ - || stepperX.test_stall_status() - #elif Y_SPI_SENSORLESS && CORE_IS_YZ - || stepperY.test_stall_status() - #endif - ) { SBI(live_state, Z_ENDSTOP); hit = true; } - #if ENABLED(Z_MULTI_ENDSTOPS) - if (stepperZ2.test_stall_status()) { SBI(live_state, Z2_ENDSTOP); hit = true; } - #if NUM_Z_STEPPERS >= 3 - if (stepperZ3.test_stall_status()) { SBI(live_state, Z3_ENDSTOP); hit = true; } - #if NUM_Z_STEPPERS >= 4 - if (stepperZ4.test_stall_status()) { SBI(live_state, Z4_ENDSTOP); hit = true; } - #endif - #endif + if (tmc_spi_homing.z && (stepperZ.test_stall_status() + #if CORE_IS_XZ && X_SPI_SENSORLESS + || stepperX.test_stall_status() + #elif CORE_IS_YZ && Y_SPI_SENSORLESS + || stepperY.test_stall_status() #endif + )) { + SBI(live_state, Z_ENDSTOP); + hit = true; } #endif - #if I_SPI_SENSORLESS - if (tmc_spi_homing.i && stepperI.test_stall_status()) { SBI(live_state, I_ENDSTOP); hit = true; } + if (tmc_spi_homing.i && stepperI.test_stall_status()) { + SBI(live_state, I_ENDSTOP); + hit = true; + } #endif #if J_SPI_SENSORLESS - if (tmc_spi_homing.j && stepperJ.test_stall_status()) { SBI(live_state, J_ENDSTOP); hit = true; } + if (tmc_spi_homing.j && stepperJ.test_stall_status()) { + SBI(live_state, J_ENDSTOP); + hit = true; + } #endif #if K_SPI_SENSORLESS - if (tmc_spi_homing.k && stepperK.test_stall_status()) { SBI(live_state, K_ENDSTOP); hit = true; } + if (tmc_spi_homing.k && stepperK.test_stall_status()) { + SBI(live_state, K_ENDSTOP); + hit = true; + } #endif #if U_SPI_SENSORLESS - if (tmc_spi_homing.u && stepperU.test_stall_status()) { SBI(live_state, U_ENDSTOP); hit = true; } + if (tmc_spi_homing.u && stepperU.test_stall_status()) { + SBI(live_state, U_ENDSTOP); + hit = true; + } #endif #if V_SPI_SENSORLESS - if (tmc_spi_homing.v && stepperV.test_stall_status()) { SBI(live_state, V_ENDSTOP); hit = true; } + if (tmc_spi_homing.v && stepperV.test_stall_status()) { + SBI(live_state, V_ENDSTOP); + hit = true; + } #endif #if W_SPI_SENSORLESS - if (tmc_spi_homing.w && stepperW.test_stall_status()) { SBI(live_state, W_ENDSTOP); hit = true; } + if (tmc_spi_homing.w && stepperW.test_stall_status()) { + SBI(live_state, W_ENDSTOP); + hit = true; + } #endif if (TERN0(ENDSTOP_INTERRUPTS_FEATURE, hit)) update(); @@ -1090,23 +1431,8 @@ void Endstops::update() { void Endstops::clear_endstop_state() { TERN_(X_SPI_SENSORLESS, CBI(live_state, X_ENDSTOP)); - #if ALL(X_SPI_SENSORLESS, X_DUAL_ENDSTOPS) - CBI(live_state, X2_ENDSTOP); - #endif TERN_(Y_SPI_SENSORLESS, CBI(live_state, Y_ENDSTOP)); - #if ALL(Y_SPI_SENSORLESS, Y_DUAL_ENDSTOPS) - CBI(live_state, Y2_ENDSTOP); - #endif TERN_(Z_SPI_SENSORLESS, CBI(live_state, Z_ENDSTOP)); - #if ALL(Z_SPI_SENSORLESS, Z_MULTI_ENDSTOPS) - CBI(live_state, Z2_ENDSTOP); - #if NUM_Z_STEPPERS >= 3 - CBI(live_state, Z3_ENDSTOP); - #if NUM_Z_STEPPERS >= 4 - CBI(live_state, Z4_ENDSTOP); - #endif - #endif - #endif TERN_(I_SPI_SENSORLESS, CBI(live_state, I_ENDSTOP)); TERN_(J_SPI_SENSORLESS, CBI(live_state, J_ENDSTOP)); TERN_(K_SPI_SENSORLESS, CBI(live_state, K_ENDSTOP)); @@ -1138,183 +1464,183 @@ void Endstops::update() { #define ES_GET_STATE(S) if (READ_ENDSTOP(S##_PIN)) SBI(live_state_local, S) - #if USE_X_MIN + #if HAS_X_MIN ES_GET_STATE(X_MIN); #endif - #if USE_X_MAX + #if HAS_X_MAX ES_GET_STATE(X_MAX); #endif - #if USE_Y_MIN + #if HAS_Y_MIN ES_GET_STATE(Y_MIN); #endif - #if USE_Y_MAX + #if HAS_Y_MAX ES_GET_STATE(Y_MAX); #endif - #if USE_Z_MIN + #if HAS_Z_MIN ES_GET_STATE(Z_MIN); #endif - #if USE_Z_MAX + #if HAS_Z_MAX ES_GET_STATE(Z_MAX); #endif - #if USE_Z_MIN_PROBE + #if HAS_Z_MIN_PROBE_PIN ES_GET_STATE(Z_MIN_PROBE); #endif - #if USE_X2_MIN + #if HAS_X2_MIN ES_GET_STATE(X2_MIN); #endif - #if USE_X2_MAX + #if HAS_X2_MAX ES_GET_STATE(X2_MAX); #endif - #if USE_Y2_MIN + #if HAS_Y2_MIN ES_GET_STATE(Y2_MIN); #endif - #if USE_Y2_MAX + #if HAS_Y2_MAX ES_GET_STATE(Y2_MAX); #endif - #if USE_Z2_MIN + #if HAS_Z2_MIN ES_GET_STATE(Z2_MIN); #endif - #if USE_Z2_MAX + #if HAS_Z2_MAX ES_GET_STATE(Z2_MAX); #endif - #if USE_Z3_MIN + #if HAS_Z3_MIN ES_GET_STATE(Z3_MIN); #endif - #if USE_Z3_MAX + #if HAS_Z3_MAX ES_GET_STATE(Z3_MAX); #endif - #if USE_Z4_MIN + #if HAS_Z4_MIN ES_GET_STATE(Z4_MIN); #endif - #if USE_Z4_MAX + #if HAS_Z4_MAX ES_GET_STATE(Z4_MAX); #endif - #if USE_I_MAX + #if HAS_I_MAX ES_GET_STATE(I_MAX); #endif - #if USE_I_MIN + #if HAS_I_MIN ES_GET_STATE(I_MIN); #endif - #if USE_J_MAX + #if HAS_J_MAX ES_GET_STATE(J_MAX); #endif - #if USE_J_MIN + #if HAS_J_MIN ES_GET_STATE(J_MIN); #endif - #if USE_K_MAX + #if HAS_K_MAX ES_GET_STATE(K_MAX); #endif - #if USE_K_MIN + #if HAS_K_MIN ES_GET_STATE(K_MIN); #endif - #if USE_U_MAX + #if HAS_U_MAX ES_GET_STATE(U_MAX); #endif - #if USE_U_MIN + #if HAS_U_MIN ES_GET_STATE(U_MIN); #endif - #if USE_V_MAX + #if HAS_V_MAX ES_GET_STATE(V_MAX); #endif - #if USE_V_MIN + #if HAS_V_MIN ES_GET_STATE(V_MIN); #endif - #if USE_W_MAX + #if HAS_W_MAX ES_GET_STATE(W_MAX); #endif - #if USE_W_MIN + #if HAS_W_MIN ES_GET_STATE(W_MIN); #endif - const uint16_t endstop_change = live_state_local ^ old_live_state_local; + uint16_t endstop_change = live_state_local ^ old_live_state_local; #define ES_REPORT_CHANGE(S) if (TEST(endstop_change, S)) SERIAL_ECHOPGM(" " STRINGIFY(S) ":", TEST(live_state_local, S)) if (endstop_change) { - #if USE_X_MIN + #if HAS_X_MIN ES_REPORT_CHANGE(X_MIN); #endif - #if USE_X_MAX + #if HAS_X_MAX ES_REPORT_CHANGE(X_MAX); #endif - #if USE_Y_MIN + #if HAS_Y_MIN ES_REPORT_CHANGE(Y_MIN); #endif - #if USE_Y_MAX + #if HAS_Y_MAX ES_REPORT_CHANGE(Y_MAX); #endif - #if USE_Z_MIN + #if HAS_Z_MIN ES_REPORT_CHANGE(Z_MIN); #endif - #if USE_Z_MAX + #if HAS_Z_MAX ES_REPORT_CHANGE(Z_MAX); #endif - #if USE_Z_MIN_PROBE + #if HAS_Z_MIN_PROBE_PIN ES_REPORT_CHANGE(Z_MIN_PROBE); #endif - #if USE_X2_MIN + #if HAS_X2_MIN ES_REPORT_CHANGE(X2_MIN); #endif - #if USE_X2_MAX + #if HAS_X2_MAX ES_REPORT_CHANGE(X2_MAX); #endif - #if USE_Y2_MIN + #if HAS_Y2_MIN ES_REPORT_CHANGE(Y2_MIN); #endif - #if USE_Y2_MAX + #if HAS_Y2_MAX ES_REPORT_CHANGE(Y2_MAX); #endif - #if USE_Z2_MIN + #if HAS_Z2_MIN ES_REPORT_CHANGE(Z2_MIN); #endif - #if USE_Z2_MAX + #if HAS_Z2_MAX ES_REPORT_CHANGE(Z2_MAX); #endif - #if USE_Z3_MIN + #if HAS_Z3_MIN ES_REPORT_CHANGE(Z3_MIN); #endif - #if USE_Z3_MAX + #if HAS_Z3_MAX ES_REPORT_CHANGE(Z3_MAX); #endif - #if USE_Z4_MIN + #if HAS_Z4_MIN ES_REPORT_CHANGE(Z4_MIN); #endif - #if USE_Z4_MAX + #if HAS_Z4_MAX ES_REPORT_CHANGE(Z4_MAX); #endif - #if USE_I_MIN + #if HAS_I_MIN ES_REPORT_CHANGE(I_MIN); #endif - #if USE_I_MAX + #if HAS_I_MAX ES_REPORT_CHANGE(I_MAX); #endif - #if USE_J_MIN + #if HAS_J_MIN ES_REPORT_CHANGE(J_MIN); #endif - #if USE_J_MAX + #if HAS_J_MAX ES_REPORT_CHANGE(J_MAX); #endif - #if USE_K_MIN + #if HAS_K_MIN ES_REPORT_CHANGE(K_MIN); #endif - #if USE_K_MAX + #if HAS_K_MAX ES_REPORT_CHANGE(K_MAX); #endif - #if USE_U_MIN + #if HAS_U_MIN ES_REPORT_CHANGE(U_MIN); #endif - #if USE_U_MAX + #if HAS_U_MAX ES_REPORT_CHANGE(U_MAX); #endif - #if USE_V_MIN + #if HAS_V_MIN ES_REPORT_CHANGE(V_MIN); #endif - #if USE_V_MAX + #if HAS_V_MAX ES_REPORT_CHANGE(V_MAX); #endif - #if USE_W_MIN + #if HAS_W_MIN ES_REPORT_CHANGE(W_MIN); #endif - #if USE_W_MAX + #if HAS_W_MAX ES_REPORT_CHANGE(W_MAX); #endif @@ -1331,80 +1657,52 @@ void Endstops::update() { /** * Change TMC driver currents to N##_CURRENT_HOME, saving the current configuration of each. */ - void Endstops::set_z_sensorless_current(const bool onoff) { - #if ENABLED(DELTA) && HAS_CURRENT_HOME(X) - #define HAS_DELTA_X_CURRENT 1 - #endif - #if ENABLED(DELTA) && HAS_CURRENT_HOME(Y) - #define HAS_DELTA_Y_CURRENT 1 - #endif - #if HAS_DELTA_X_CURRENT || HAS_DELTA_Y_CURRENT || HAS_CURRENT_HOME(Z) || HAS_CURRENT_HOME(Z2) || HAS_CURRENT_HOME(Z3) || HAS_CURRENT_HOME(Z4) + void Endstops::set_homing_current(const bool onoff) { + #define HAS_CURRENT_HOME(N) (defined(N##_CURRENT_HOME) && N##_CURRENT_HOME != N##_CURRENT) + #define HAS_DELTA_X_CURRENT (ENABLED(DELTA) && HAS_CURRENT_HOME(X)) + #define HAS_DELTA_Y_CURRENT (ENABLED(DELTA) && HAS_CURRENT_HOME(Y)) + #if HAS_DELTA_X_CURRENT || HAS_DELTA_Y_CURRENT || HAS_CURRENT_HOME(Z) #if HAS_DELTA_X_CURRENT - static int16_t saved_current_X; + static int16_t saved_current_x; #endif #if HAS_DELTA_Y_CURRENT - static int16_t saved_current_Y; + static int16_t saved_current_y; #endif #if HAS_CURRENT_HOME(Z) - static int16_t saved_current_Z; + static int16_t saved_current_z; #endif - #if HAS_CURRENT_HOME(Z2) - static int16_t saved_current_Z2; - #endif - #if HAS_CURRENT_HOME(Z3) - static int16_t saved_current_Z3; - #endif - #if HAS_CURRENT_HOME(Z4) - static int16_t saved_current_Z4; - #endif - - #if ENABLED(DEBUG_LEVELING_FEATURE) - auto debug_current = [](FSTR_P const s, const int16_t a, const int16_t b) { - if (DEBUGGING(LEVELING)) { DEBUG_ECHOLN(s, F(" current: "), a, F(" -> "), b); } - }; - #else - #define debug_current(...) - #endif - - #define _SAVE_SET_CURRENT(A) \ - saved_current_##A = stepper##A.getMilliamps(); \ - stepper##A.rms_current(A##_CURRENT_HOME); \ - debug_current(F(STR_##A), saved_current_##A, A##_CURRENT_HOME) - - #define _RESTORE_CURRENT(A) \ - stepper##A.rms_current(saved_current_##A); \ - debug_current(F(STR_##A), saved_current_##A, A##_CURRENT_HOME) - + auto debug_current_on = [](PGM_P const s, const int16_t a, const int16_t b) { + if (DEBUGGING(LEVELING)) { DEBUG_ECHOPGM_P(s); DEBUG_ECHOLNPGM(" current: ", a, " -> ", b); } + }; if (onoff) { - TERN_(HAS_DELTA_X_CURRENT, _SAVE_SET_CURRENT(X)); - TERN_(HAS_DELTA_Y_CURRENT, _SAVE_SET_CURRENT(Y)); + #if HAS_DELTA_X_CURRENT + saved_current_x = stepperX.getMilliamps(); + stepperX.rms_current(X_CURRENT_HOME); + debug_current_on(PSTR("X"), saved_current_x, X_CURRENT_HOME); + #endif + #if HAS_DELTA_Y_CURRENT + saved_current_y = stepperY.getMilliamps(); + stepperY.rms_current(Y_CURRENT_HOME); + debug_current_on(PSTR("Y"), saved_current_y, Y_CURRENT_HOME); + #endif #if HAS_CURRENT_HOME(Z) - _SAVE_SET_CURRENT(Z); - #endif - #if HAS_CURRENT_HOME(Z2) - _SAVE_SET_CURRENT(Z2); - #endif - #if HAS_CURRENT_HOME(Z3) - _SAVE_SET_CURRENT(Z3); - #endif - #if HAS_CURRENT_HOME(Z4) - _SAVE_SET_CURRENT(Z4); + saved_current_z = stepperZ.getMilliamps(); + stepperZ.rms_current(Z_CURRENT_HOME); + debug_current_on(PSTR("Z"), saved_current_z, Z_CURRENT_HOME); #endif } else { - TERN_(HAS_DELTA_X_CURRENT, _RESTORE_CURRENT(X)); - TERN_(HAS_DELTA_Y_CURRENT, _RESTORE_CURRENT(Y)); + #if HAS_DELTA_X_CURRENT + stepperX.rms_current(saved_current_x); + debug_current_on(PSTR("X"), X_CURRENT_HOME, saved_current_x); + #endif + #if HAS_DELTA_Y_CURRENT + stepperY.rms_current(saved_current_y); + debug_current_on(PSTR("Y"), Y_CURRENT_HOME, saved_current_y); + #endif #if HAS_CURRENT_HOME(Z) - _RESTORE_CURRENT(Z); - #endif - #if HAS_CURRENT_HOME(Z2) - _RESTORE_CURRENT(Z2); - #endif - #if HAS_CURRENT_HOME(Z3) - _RESTORE_CURRENT(Z3); - #endif - #if HAS_CURRENT_HOME(Z4) - _RESTORE_CURRENT(Z4); + stepperZ.rms_current(saved_current_z); + debug_current_on(PSTR("Z"), Z_CURRENT_HOME, saved_current_z); #endif } @@ -1414,6 +1712,6 @@ void Endstops::update() { safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle #endif - #endif + #endif // XYZ } -#endif // USE_SENSORLESS +#endif diff --git a/Marlin/src/module/settings.cpp b/Marlin/src/module/settings.cpp index 17b8ae4d72..d164054d97 100644 --- a/Marlin/src/module/settings.cpp +++ b/Marlin/src/module/settings.cpp @@ -36,13 +36,12 @@ */ // Change EEPROM version if the structure changes -#define EEPROM_VERSION "V90" +#define EEPROM_VERSION "V87" #define EEPROM_OFFSET 100 // Check the integrity of data offsets. // Can be disabled for production build. //#define DEBUG_EEPROM_READWRITE -//#define DEBUG_EEPROM_OBSERVE #include "settings.h" @@ -56,13 +55,11 @@ #include "../gcode/gcode.h" #include "../MarlinCore.h" -#if ANY(EEPROM_SETTINGS, SD_FIRMWARE_UPDATE) +#if EITHER(EEPROM_SETTINGS, SD_FIRMWARE_UPDATE) #include "../HAL/shared/eeprom_api.h" #endif -#if HAS_BED_PROBE - #include "probe.h" -#endif +#include "probe.h" #if HAS_LEVELING #include "../feature/bedlevel/bedlevel.h" @@ -75,13 +72,11 @@ #include "../feature/z_stepper_align.h" #endif -#if ENABLED(DWIN_LCD_PROUI) - #include "../lcd/e3v2/proui/dwin.h" - #include "../lcd/e3v2/proui/bedlevel_tools.h" -#endif - #if ENABLED(EXTENSIBLE_UI) #include "../lcd/extui/ui_api.h" +#elif ENABLED(DWIN_LCD_PROUI) + #include "../lcd/e3v2/proui/dwin.h" + #include "../lcd/e3v2/proui/bedlevel_tools.h" #elif ENABLED(DWIN_CREALITY_LCD_JYERSUI) #include "../lcd/e3v2/jyersui/dwin.h" #endif @@ -94,6 +89,12 @@ #include "servo.h" #endif +#if HAS_SERVOS && HAS_SERVO_ANGLES + #define EEPROM_NUM_SERVOS NUM_SERVOS +#else + #define EEPROM_NUM_SERVOS NUM_SERVO_PLUGS +#endif + #include "../feature/fwretract.h" #if ENABLED(POWER_LOSS_RECOVERY) @@ -110,15 +111,8 @@ #include "../feature/backlash.h" #endif -#if ENABLED(FT_MOTION) - #include "../module/ft_motion.h" -#endif - #if HAS_FILAMENT_SENSOR #include "../feature/runout.h" - #ifndef FIL_RUNOUT_ENABLED_DEFAULT - #define FIL_RUNOUT_ENABLED_DEFAULT true - #endif #endif #if ENABLED(ADVANCE_K_EXTRA) @@ -169,15 +163,11 @@ #include "../feature/fancheck.h" #endif -#if DGUS_LCD_UI_MKS +#if ENABLED(DGUS_LCD_UI_MKS) #include "../lcd/extui/dgus/DGUSScreenHandler.h" #include "../lcd/extui/dgus/DGUSDisplayDef.h" #endif -#if ENABLED(HOTEND_IDLE_TIMEOUT) - #include "../feature/hotend_idle.h" -#endif - #pragma pack(push, 1) // No padding between variables #if HAS_ETHERNET @@ -188,10 +178,10 @@ #define _EN_ITEM(N) , E##N #define _EN1_ITEM(N) , E##N:1 -typedef struct { uint16_t MAIN_AXIS_NAMES_ X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } per_stepper_uint16_t; -typedef struct { uint32_t MAIN_AXIS_NAMES_ X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } per_stepper_uint32_t; -typedef struct { int16_t MAIN_AXIS_NAMES_ X2, Y2, Z2, Z3, Z4; } mot_stepper_int16_t; -typedef struct { bool NUM_AXIS_LIST_(X:1, Y:1, Z:1, I:1, J:1, K:1, U:1, V:1, W:1) X2:1, Y2:1, Z2:1, Z3:1, Z4:1 REPEAT(E_STEPPERS, _EN1_ITEM); } per_stepper_bool_t; +typedef struct { uint16_t MAIN_AXIS_NAMES, X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } per_stepper_uint16_t; +typedef struct { uint32_t MAIN_AXIS_NAMES, X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } per_stepper_uint32_t; +typedef struct { int16_t MAIN_AXIS_NAMES, X2, Y2, Z2, Z3, Z4; } mot_stepper_int16_t; +typedef struct { bool NUM_AXIS_LIST(X:1, Y:1, Z:1, I:1, J:1, K:1, U:1, V:1, W:1), X2:1, Y2:1, Z2:1, Z3:1, Z4:1 REPEAT(E_STEPPERS, _EN1_ITEM); } per_stepper_bool_t; #undef _EN_ITEM @@ -200,10 +190,8 @@ typedef struct { bool NUM_AXIS_LIST_(X:1, Y:1, Z:1, I:1, J:1, K:1, U:1, V:1, // Defaults for reset / fill in on load static const uint32_t _DMA[] PROGMEM = DEFAULT_MAX_ACCELERATION; +static const float _DASU[] PROGMEM = DEFAULT_AXIS_STEPS_PER_UNIT; static const feedRate_t _DMF[] PROGMEM = DEFAULT_MAX_FEEDRATE; -#if ENABLED(EDITABLE_STEPS_PER_UNIT) - static const float _DASU[] PROGMEM = DEFAULT_AXIS_STEPS_PER_UNIT; -#endif /** * Current EEPROM Layout @@ -216,8 +204,7 @@ typedef struct SettingsDataStruct { #if ENABLED(EEPROM_INIT_NOW) uint32_t build_hash; // Unique build hash #endif - uint16_t crc; // Data Checksum for validation - uint16_t data_size; // Data Size for validation + uint16_t crc; // Data Checksum // // DISTINCT_E_FACTORS @@ -235,9 +222,7 @@ typedef struct SettingsDataStruct { // // Home Offset // - #if NUM_AXES - xyz_pos_t home_offset; // M206 XYZ / M665 TPZ - #endif + xyz_pos_t home_offset; // M206 XYZ / M665 TPZ // // Hotend Offset @@ -249,37 +234,30 @@ typedef struct SettingsDataStruct { // // FILAMENT_RUNOUT_SENSOR // - bool runout_sensor_enabled; // M412 S - float runout_distance_mm; // M412 D + #if HAS_FILAMENT_SENSOR + bool runout_enabled[NUM_RUNOUT_SENSORS]; // M591 S + float runout_distance_mm[NUM_RUNOUT_SENSORS]; // M591 D + uint8_t runout_mode[NUM_RUNOUT_SENSORS]; // M591 P + #endif // // ENABLE_LEVELING_FADE_HEIGHT // float planner_z_fade_height; // M420 Zn planner.z_fade_height - // - // AUTOTEMP - // - #if ENABLED(AUTOTEMP) - celsius_t planner_autotemp_max, planner_autotemp_min; - float planner_autotemp_factor; - #endif - // // MESH_BED_LEVELING // float mbl_z_offset; // bedlevel.z_offset uint8_t mesh_num_x, mesh_num_y; // GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y - uint16_t mesh_check; // Hash to check against X/Y float mbl_z_values[TERN(MESH_BED_LEVELING, GRID_MAX_POINTS_X, 3)] // bedlevel.z_values [TERN(MESH_BED_LEVELING, GRID_MAX_POINTS_Y, 3)]; // // HAS_BED_PROBE // - #if NUM_AXES - xyz_pos_t probe_offset; // M851 X Y Z - #endif + + xyz_pos_t probe_offset; // M851 X Y Z // // ABL_PLANAR @@ -290,7 +268,6 @@ typedef struct SettingsDataStruct { // AUTO_BED_LEVELING_BILINEAR // uint8_t grid_max_x, grid_max_y; // GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y - uint16_t grid_check; // Hash to check against X/Y xy_pos_t bilinear_grid_spacing, bilinear_start; // G29 L F #if ENABLED(AUTO_BED_LEVELING_BILINEAR) bed_mesh_t z_values; // G29 @@ -316,9 +293,7 @@ typedef struct SettingsDataStruct { // // SERVO_ANGLES // - #if HAS_SERVO_ANGLES - uint16_t servo_angles[NUM_SERVOS][2]; // M281 P L U - #endif + uint16_t servo_angles[EEPROM_NUM_SERVOS][2]; // M281 P L U // // Temperature first layer compensation values @@ -339,7 +314,7 @@ typedef struct SettingsDataStruct { // BLTOUCH // bool bltouch_od_5v_mode; - #if HAS_BLTOUCH_HS_MODE + #ifdef BLTOUCH_HS_MODE bool bltouch_high_speed_mode; // M401 S #endif @@ -431,12 +406,10 @@ typedef struct SettingsDataStruct { // // Display Sleep // - #if ENABLED(EDITABLE_DISPLAY_TIMEOUT) - #if HAS_BACKLIGHT_TIMEOUT - uint8_t backlight_timeout_minutes; // M255 S - #elif HAS_DISPLAY_SLEEP - uint8_t sleep_timeout_minutes; // M255 S - #endif + #if LCD_BACKLIGHT_TIMEOUT_MINS + uint8_t backlight_timeout_minutes; // M255 S + #elif HAS_DISPLAY_SLEEP + uint8_t sleep_timeout_minutes; // M255 S #endif // @@ -448,7 +421,6 @@ typedef struct SettingsDataStruct { // POWER_LOSS_RECOVERY // bool recovery_enabled; // M413 S - celsius_t bed_temp_threshold; // M413 B // // FWRETRACT @@ -492,31 +464,20 @@ typedef struct SettingsDataStruct { #endif uint32_t motor_current_setting[MOTOR_CURRENT_COUNT]; // M907 X Z E ... - // - // Adaptive Step Smoothing state - // - #if ENABLED(ADAPTIVE_STEP_SMOOTHING_TOGGLE) - bool adaptive_step_smoothing_enabled; // G-code pending - #endif - // // CNC_COORDINATE_SYSTEMS // - #if NUM_AXES - xyz_pos_t coordinate_system[MAX_COORDINATE_SYSTEMS]; // G54-G59.3 - #endif + xyz_pos_t coordinate_system[MAX_COORDINATE_SYSTEMS]; // G54-G59.3 // // SKEW_CORRECTION // - #if ENABLED(SKEW_CORRECTION) - skew_factor_t planner_skew_factor; // M852 I J K - #endif + skew_factor_t planner_skew_factor; // M852 I J K // // ADVANCED_PAUSE_FEATURE // - #if ENABLED(CONFIGURE_FILAMENT_CHANGE) + #if HAS_EXTRUDERS fil_change_settings_t fc_settings[EXTRUDERS]; // M603 T U L #endif @@ -530,11 +491,9 @@ typedef struct SettingsDataStruct { // // BACKLASH_COMPENSATION // - #if NUM_AXES - xyz_float_t backlash_distance_mm; // M425 X Y Z - uint8_t backlash_correction; // M425 F - float backlash_smoothing_mm; // M425 S - #endif + xyz_float_t backlash_distance_mm; // M425 X Y Z + uint8_t backlash_correction; // M425 F + float backlash_smoothing_mm; // M425 S // // EXTENSIBLE_UI @@ -546,8 +505,10 @@ typedef struct SettingsDataStruct { // // Ender-3 V2 DWIN // - #if ENABLED(DWIN_CREALITY_LCD_JYERSUI) - uint8_t dwin_settings[jyersDWIN.eeprom_data_size]; + #if ENABLED(DWIN_LCD_PROUI) + uint8_t dwin_data[eeprom_data_size]; + #elif ENABLED(DWIN_CREALITY_LCD_JYERSUI) + uint8_t dwin_settings[CrealityDWIN.eeprom_data_size]; #endif // @@ -598,7 +559,7 @@ typedef struct SettingsDataStruct { // // MKS UI controller // - #if DGUS_LCD_UI_MKS + #if ENABLED(DGUS_LCD_UI_MKS) MKS_Language mks_language_index; // Display Language xy_int_t mks_corner_offsets[5]; // Bed Tramming xyz_int_t mks_park_pos; // Custom Parking (without NOZZLE_PARK) @@ -616,39 +577,6 @@ typedef struct SettingsDataStruct { MPC_t mpc_constants[HOTENDS]; // M306 #endif - // - // Fixed-Time Motion - // - #if ENABLED(FT_MOTION) - ft_config_t ftMotion_cfg; // M493 - #endif - - // - // Input Shaping - // - #if ENABLED(INPUT_SHAPING_X) - float shaping_x_frequency, // M593 X F - shaping_x_zeta; // M593 X D - #endif - #if ENABLED(INPUT_SHAPING_Y) - float shaping_y_frequency, // M593 Y F - shaping_y_zeta; // M593 Y D - #endif - - // - // HOTEND_IDLE_TIMEOUT - // - #if ENABLED(HOTEND_IDLE_TIMEOUT) - hotend_idle_settings_t hotend_idle_config; // M86 S T E B - #endif - - // - // Nonlinear Extrusion - // - #if ENABLED(NONLINEAR_EXTRUSION) - ne_coeff_t stepper_ne; // M592 A B C - #endif - } SettingsData; //static_assert(sizeof(SettingsData) <= MARLIN_EEPROM_SIZE, "EEPROM too small to contain SettingsData!"); @@ -685,7 +613,10 @@ void MarlinSettings::postprocess() { #endif // Software endstops depend on home_offset - LOOP_NUM_AXES(i) update_software_endstops((AxisEnum)i); + LOOP_NUM_AXES(i) { + update_workspace_offset((AxisEnum)i); + update_software_endstops((AxisEnum)i); + } TERN_(ENABLE_LEVELING_FADE_HEIGHT, set_z_fade_height(new_z_fade_height, false)); // false = no report @@ -709,14 +640,18 @@ void MarlinSettings::postprocess() { if (oldpos != current_position) report_current_position(); - // Moved as last update due to interference with NeoPixel init + // Moved as last update due to interference with Neopixel init TERN_(HAS_LCD_CONTRAST, ui.refresh_contrast()); TERN_(HAS_LCD_BRIGHTNESS, ui.refresh_brightness()); - TERN_(HAS_BACKLIGHT_TIMEOUT, ui.refresh_backlight_timeout()); - TERN_(HAS_DISPLAY_SLEEP, ui.refresh_screen_timeout()); + + #if LCD_BACKLIGHT_TIMEOUT_MINS + ui.refresh_backlight_timeout(); + #elif HAS_DISPLAY_SLEEP && DISABLED(TFT_COLOR_UI) + ui.refresh_screen_timeout(); + #endif } -#if ALL(PRINTCOUNTER, EEPROM_SETTINGS) +#if BOTH(PRINTCOUNTER, EEPROM_SETTINGS) #include "printcounter.h" static_assert( !WITHIN(STATS_EEPROM_ADDRESS, EEPROM_OFFSET, EEPROM_OFFSET + sizeof(SettingsData)) && @@ -736,8 +671,7 @@ void MarlinSettings::postprocess() { bool MarlinSettings::sd_update_status() { uint8_t val; - int pos = SD_FIRMWARE_UPDATE_EEPROM_ADDR; - persistentStore.read_data(pos, &val); + persistentStore.read_data(SD_FIRMWARE_UPDATE_EEPROM_ADDR, &val); return (val == SD_FIRMWARE_UPDATE_ACTIVE_VALUE); } @@ -761,22 +695,19 @@ void MarlinSettings::postprocess() { // This file simply uses the DEBUG_ECHO macros to implement EEPROM_CHITCHAT. // For deeper debugging of EEPROM issues enable DEBUG_EEPROM_READWRITE. // -#define DEBUG_OUT ANY(EEPROM_CHITCHAT, DEBUG_LEVELING_FEATURE) +#define DEBUG_OUT EITHER(EEPROM_CHITCHAT, DEBUG_LEVELING_FEATURE) #include "../core/debug_out.h" -#if ALL(EEPROM_CHITCHAT, HOST_PROMPT_SUPPORT) +#if BOTH(EEPROM_CHITCHAT, HOST_PROMPT_SUPPORT) #define HOST_EEPROM_CHITCHAT 1 #endif #if ENABLED(EEPROM_SETTINGS) - #define EEPROM_ASSERT(TST,ERR) do{ if (!(TST)) { SERIAL_WARN_MSG(ERR); eeprom_error = ERR_EEPROM_SIZE; } }while(0) - - #define TWO_BYTE_HASH(A,B) uint16_t((uint16_t(A ^ 0xC3) << 4) ^ (uint16_t(B ^ 0xC3) << 12)) + #define EEPROM_ASSERT(TST,ERR) do{ if (!(TST)) { SERIAL_ERROR_MSG(ERR); eeprom_error = true; } }while(0) #if ENABLED(DEBUG_EEPROM_READWRITE) #define _FIELD_TEST(FIELD) \ - SERIAL_ECHOLNPGM("Field: " STRINGIFY(FIELD)); \ EEPROM_ASSERT( \ eeprom_error || eeprom_index == offsetof(SettingsData, FIELD) + EEPROM_OFFSET, \ "Field " STRINGIFY(FIELD) " mismatch." \ @@ -785,14 +716,6 @@ void MarlinSettings::postprocess() { #define _FIELD_TEST(FIELD) NOOP #endif - #if ENABLED(DEBUG_EEPROM_OBSERVE) - #define EEPROM_READ(V...) do{ SERIAL_ECHOLNPGM("READ: ", F(STRINGIFY(FIRST(V)))); EEPROM_READ_(V); }while(0) - #define EEPROM_READ_ALWAYS(V...) do{ SERIAL_ECHOLNPGM("READ: ", F(STRINGIFY(FIRST(V)))); EEPROM_READ_ALWAYS_(V); }while(0) - #else - #define EEPROM_READ(V...) EEPROM_READ_(V) - #define EEPROM_READ_ALWAYS(V...) EEPROM_READ_ALWAYS_(V) - #endif - const char version[4] = EEPROM_VERSION; #if ENABLED(EEPROM_INIT_NOW) @@ -802,20 +725,20 @@ void MarlinSettings::postprocess() { constexpr uint32_t build_hash = strhash32(__DATE__ __TIME__); #endif - bool MarlinSettings::validating; + bool MarlinSettings::eeprom_error, MarlinSettings::validating; int MarlinSettings::eeprom_index; uint16_t MarlinSettings::working_crc; - EEPROM_Error MarlinSettings::size_error(const uint16_t size) { + bool MarlinSettings::size_error(const uint16_t size) { if (size != datasize()) { - DEBUG_WARN_MSG("EEPROM datasize error." + DEBUG_ERROR_MSG("EEPROM datasize error." #if ENABLED(MARLIN_DEV_MODE) " (Actual:", size, " Expected:", datasize(), ")" #endif ); - return ERR_EEPROM_SIZE; + return true; } - return ERR_EEPROM_NOERR; + return false; } /** @@ -823,29 +746,22 @@ void MarlinSettings::postprocess() { */ bool MarlinSettings::save() { float dummyf = 0; - MString<3> ver(F("ERR")); + char ver[4] = "ERR"; if (!EEPROM_START(EEPROM_OFFSET)) return false; - EEPROM_Error eeprom_error = ERR_EEPROM_NOERR; + eeprom_error = false; // Write or Skip version. (Flash doesn't allow rewrite without erase.) TERN(FLASH_EEPROM_EMULATION, EEPROM_SKIP, EEPROM_WRITE)(ver); #if ENABLED(EEPROM_INIT_NOW) - EEPROM_SKIP(build_hash); // Skip the hash slot which will be written later + EEPROM_SKIP(build_hash); // Skip the hash slot #endif EEPROM_SKIP(working_crc); // Skip the checksum slot - // - // Clear after skipping CRC and before writing the CRC'ed data - // - working_crc = 0; - - // Write the size of the data structure for use in validation - const uint16_t data_size = datasize(); - EEPROM_WRITE(data_size); + working_crc = 0; // clear before first "real data" const uint8_t e_factors = DISTINCT_AXES - (NUM_AXES); _FIELD_TEST(e_factors); @@ -857,14 +773,14 @@ void MarlinSettings::postprocess() { { EEPROM_WRITE(planner.settings); - #if ENABLED(CLASSIC_JERK) + #if HAS_CLASSIC_JERK EEPROM_WRITE(planner.max_jerk); #if HAS_LINEAR_E_JERK dummyf = float(DEFAULT_EJERK); EEPROM_WRITE(dummyf); #endif #else - const xyze_pos_t planner_max_jerk = LOGICAL_AXIS_ARRAY(5, 10, 10, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4); + const xyze_pos_t planner_max_jerk = LOGICAL_AXIS_ARRAY(float(DEFAULT_EJERK), 10, 10, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4); EEPROM_WRITE(planner_max_jerk); #endif @@ -875,7 +791,6 @@ void MarlinSettings::postprocess() { // // Home Offset // - #if NUM_AXES { _FIELD_TEST(home_offset); @@ -888,38 +803,27 @@ void MarlinSettings::postprocess() { EEPROM_WRITE(home_offset); #endif } - #endif // NUM_AXES // // Hotend Offsets, if any // - { - #if HAS_HOTEND_OFFSET - // Skip hotend 0 which must be 0 - for (uint8_t e = 1; e < HOTENDS; ++e) - EEPROM_WRITE(hotend_offset[e]); - #endif - } + #if HAS_HOTEND_OFFSET + // Skip hotend 0 which must be 0 + LOOP_S_L_N(e, 1, HOTENDS) + EEPROM_WRITE(hotend_offset[e]); + #endif // // Filament Runout Sensor // + #if HAS_FILAMENT_SENSOR { - #if HAS_FILAMENT_SENSOR - const bool &runout_sensor_enabled = runout.enabled; - #else - constexpr int8_t runout_sensor_enabled = -1; - #endif - _FIELD_TEST(runout_sensor_enabled); - EEPROM_WRITE(runout_sensor_enabled); - - #if HAS_FILAMENT_RUNOUT_DISTANCE - const float &runout_distance_mm = runout.runout_distance(); - #else - constexpr float runout_distance_mm = 0; - #endif - EEPROM_WRITE(runout_distance_mm); + _FIELD_TEST(runout_enabled); + LOOP_L_N(e, NUM_RUNOUT_SENSORS) EEPROM_WRITE(runout.enabled[e]); + LOOP_L_N(e, NUM_RUNOUT_SENSORS) EEPROM_WRITE(runout.runout_distance(e)); + LOOP_L_N(e, NUM_RUNOUT_SENSORS) EEPROM_WRITE(runout.mode[e]); } + #endif // // Global Leveling @@ -929,23 +833,13 @@ void MarlinSettings::postprocess() { EEPROM_WRITE(zfh); } - // - // AUTOTEMP - // - #if ENABLED(AUTOTEMP) - _FIELD_TEST(planner_autotemp_max); - EEPROM_WRITE(planner.autotemp.max); - EEPROM_WRITE(planner.autotemp.min); - EEPROM_WRITE(planner.autotemp.factor); - #endif - // // Mesh Bed Leveling // { #if ENABLED(MESH_BED_LEVELING) static_assert( - sizeof(bedlevel.z_values) == GRID_MAX_POINTS * sizeof(bedlevel.z_values[0][0]), + sizeof(bedlevel.z_values) == (GRID_MAX_POINTS) * sizeof(bedlevel.z_values[0][0]), "MBL Z array is the wrong size." ); #else @@ -959,10 +853,6 @@ void MarlinSettings::postprocess() { EEPROM_WRITE(mesh_num_x); EEPROM_WRITE(mesh_num_y); - // Check value for the X/Y values - const uint16_t mesh_check = TWO_BYTE_HASH(mesh_num_x, mesh_num_y); - EEPROM_WRITE(mesh_check); - #if ENABLED(MESH_BED_LEVELING) EEPROM_WRITE(bedlevel.z_values); #else @@ -973,7 +863,6 @@ void MarlinSettings::postprocess() { // // Probe XYZ Offsets // - #if NUM_AXES { _FIELD_TEST(probe_offset); #if HAS_BED_PROBE @@ -983,7 +872,6 @@ void MarlinSettings::postprocess() { #endif EEPROM_WRITE(zpo); } - #endif // // Planar Bed Leveling matrix @@ -1003,7 +891,7 @@ void MarlinSettings::postprocess() { { #if ENABLED(AUTO_BED_LEVELING_BILINEAR) static_assert( - sizeof(bedlevel.z_values) == GRID_MAX_POINTS * sizeof(bedlevel.z_values[0][0]), + sizeof(bedlevel.z_values) == (GRID_MAX_POINTS) * sizeof(bedlevel.z_values[0][0]), "Bilinear Z array is the wrong size." ); #endif @@ -1012,11 +900,6 @@ void MarlinSettings::postprocess() { grid_max_y = TERN(AUTO_BED_LEVELING_BILINEAR, GRID_MAX_POINTS_Y, 3); EEPROM_WRITE(grid_max_x); EEPROM_WRITE(grid_max_y); - - // Check value for the X/Y values - const uint16_t grid_check = TWO_BYTE_HASH(grid_max_x, grid_max_y); - EEPROM_WRITE(grid_check); - #if ENABLED(AUTO_BED_LEVELING_BILINEAR) EEPROM_WRITE(bedlevel.grid_spacing); EEPROM_WRITE(bedlevel.grid_start); @@ -1058,12 +941,13 @@ void MarlinSettings::postprocess() { // // Servo Angles // - #if HAS_SERVO_ANGLES { _FIELD_TEST(servo_angles); + #if !HAS_SERVO_ANGLES + uint16_t servo_angles[EEPROM_NUM_SERVOS][2] = { { 0, 0 } }; + #endif EEPROM_WRITE(servo_angles); } - #endif // // Thermal first layer compensation values @@ -1090,7 +974,7 @@ void MarlinSettings::postprocess() { const bool bltouch_od_5v_mode = TERN0(BLTOUCH, bltouch.od_5v_mode); EEPROM_WRITE(bltouch_od_5v_mode); - #if HAS_BLTOUCH_HS_MODE + #ifdef BLTOUCH_HS_MODE _FIELD_TEST(bltouch_high_speed_mode); const bool bltouch_high_speed_mode = TERN0(BLTOUCH, bltouch.high_speed_mode); EEPROM_WRITE(bltouch_high_speed_mode); @@ -1189,7 +1073,7 @@ void MarlinSettings::postprocess() { { _FIELD_TEST(bedPID); #if ENABLED(PIDTEMPBED) - const auto &pid = thermalManager.temp_bed.pid; + const PID_t &pid = thermalManager.temp_bed.pid; const raw_pid_t bed_pid = { pid.p(), pid.i(), pid.d() }; #else const raw_pid_t bed_pid = { NAN, NAN, NAN }; @@ -1203,7 +1087,7 @@ void MarlinSettings::postprocess() { { _FIELD_TEST(chamberPID); #if ENABLED(PIDTEMPCHAMBER) - const auto &pid = thermalManager.temp_chamber.pid; + const PID_t &pid = thermalManager.temp_chamber.pid; const raw_pid_t chamber_pid = { pid.p(), pid.i(), pid.d() }; #else const raw_pid_t chamber_pid = { NAN, NAN, NAN }; @@ -1253,12 +1137,10 @@ void MarlinSettings::postprocess() { // // LCD Backlight / Sleep Timeout // - #if ENABLED(EDITABLE_DISPLAY_TIMEOUT) - #if HAS_BACKLIGHT_TIMEOUT - EEPROM_WRITE(ui.backlight_timeout_minutes); - #elif HAS_DISPLAY_SLEEP - EEPROM_WRITE(ui.sleep_timeout_minutes); - #endif + #if LCD_BACKLIGHT_TIMEOUT_MINS + EEPROM_WRITE(ui.backlight_timeout_minutes); + #elif HAS_DISPLAY_SLEEP + EEPROM_WRITE(ui.sleep_timeout_minutes); #endif // @@ -1279,10 +1161,8 @@ void MarlinSettings::postprocess() { // { _FIELD_TEST(recovery_enabled); - const bool recovery_enabled = TERN0(POWER_LOSS_RECOVERY, recovery.enabled); - const celsius_t bed_temp_threshold = TERN0(HAS_PLR_BED_THRESHOLD, recovery.bed_temp_threshold); + const bool recovery_enabled = TERN(POWER_LOSS_RECOVERY, recovery.enabled, ENABLED(PLR_ENABLED_DEFAULT)); EEPROM_WRITE(recovery_enabled); - EEPROM_WRITE(bed_temp_threshold); } // @@ -1442,7 +1322,7 @@ void MarlinSettings::postprocess() { #else #define _EN_ITEM(N) , .E##N = 30 const per_stepper_uint32_t tmc_hybrid_threshold = { - NUM_AXIS_LIST_(.X = 100, .Y = 100, .Z = 3, .I = 3, .J = 3, .K = 3, .U = 3, .V = 3, .W = 3) + NUM_AXIS_LIST(.X = 100, .Y = 100, .Z = 3, .I = 3, .J = 3, .K = 3, .U = 3, .V = 3, .W = 3), .X2 = 100, .Y2 = 100, .Z2 = 3, .Z3 = 3, .Z4 = 3 REPEAT(E_STEPPERS, _EN_ITEM) }; @@ -1519,7 +1399,7 @@ void MarlinSettings::postprocess() { EEPROM_WRITE(planner.extruder_advance_K); #else dummyf = 0; - for (uint8_t q = DISTINCT_E; q--;) EEPROM_WRITE(dummyf); + for (uint8_t q = _MAX(EXTRUDERS, 1); q--;) EEPROM_WRITE(dummyf); #endif } @@ -1537,38 +1417,31 @@ void MarlinSettings::postprocess() { #endif } - // - // Adaptive Step Smoothing state - // - #if ENABLED(ADAPTIVE_STEP_SMOOTHING_TOGGLE) - _FIELD_TEST(adaptive_step_smoothing_enabled); - EEPROM_WRITE(stepper.adaptive_step_smoothing_enabled); - #endif - // // CNC Coordinate Systems // - #if NUM_AXES - _FIELD_TEST(coordinate_system); - #if DISABLED(CNC_COORDINATE_SYSTEMS) - const xyz_pos_t coordinate_system[MAX_COORDINATE_SYSTEMS] = { { 0 } }; - #endif - EEPROM_WRITE(TERN(CNC_COORDINATE_SYSTEMS, gcode.coordinate_system, coordinate_system)); + + _FIELD_TEST(coordinate_system); + + #if DISABLED(CNC_COORDINATE_SYSTEMS) + const xyz_pos_t coordinate_system[MAX_COORDINATE_SYSTEMS] = { { 0 } }; #endif + EEPROM_WRITE(TERN(CNC_COORDINATE_SYSTEMS, gcode.coordinate_system, coordinate_system)); // // Skew correction factors // - #if ENABLED(SKEW_CORRECTION) - _FIELD_TEST(planner_skew_factor); - EEPROM_WRITE(planner.skew_factor); - #endif + _FIELD_TEST(planner_skew_factor); + EEPROM_WRITE(planner.skew_factor); // // Advanced Pause filament load & unload lengths // - #if ENABLED(CONFIGURE_FILAMENT_CHANGE) + #if HAS_EXTRUDERS { + #if DISABLED(ADVANCED_PAUSE_FEATURE) + const fil_change_settings_t fc_settings[EXTRUDERS] = { 0, 0 }; + #endif _FIELD_TEST(fc_settings); EEPROM_WRITE(fc_settings); } @@ -1586,7 +1459,6 @@ void MarlinSettings::postprocess() { // // Backlash Compensation // - #if NUM_AXES { #if ENABLED(BACKLASH_GCODE) xyz_float_t backlash_distance_mm; @@ -1606,7 +1478,6 @@ void MarlinSettings::postprocess() { EEPROM_WRITE(backlash_correction); EEPROM_WRITE(backlash_smoothing_mm); } - #endif // NUM_AXES // // Extensible UI User Data @@ -1621,13 +1492,22 @@ void MarlinSettings::postprocess() { #endif // - // JyersUI DWIN User Data + // Creality DWIN User Data // + #if ENABLED(DWIN_LCD_PROUI) + { + _FIELD_TEST(dwin_data); + char dwin_data[eeprom_data_size] = { 0 }; + DWIN_CopySettingsTo(dwin_data); + EEPROM_WRITE(dwin_data); + } + #endif + #if ENABLED(DWIN_CREALITY_LCD_JYERSUI) { _FIELD_TEST(dwin_settings); - char dwin_settings[jyersDWIN.eeprom_data_size] = { 0 }; - jyersDWIN.saveSettings(dwin_settings); + char dwin_settings[CrealityDWIN.eeprom_data_size] = { 0 }; + CrealityDWIN.Save_Settings(dwin_settings); EEPROM_WRITE(dwin_settings); } #endif @@ -1690,7 +1570,7 @@ void MarlinSettings::postprocess() { // // MKS UI controller // - #if DGUS_LCD_UI_MKS + #if ENABLED(DGUS_LCD_UI_MKS) EEPROM_WRITE(mks_language_index); EEPROM_WRITE(mks_corner_offsets); EEPROM_WRITE(mks_park_pos); @@ -1708,49 +1588,14 @@ void MarlinSettings::postprocess() { // Model predictive control // #if ENABLED(MPCTEMP) - HOTEND_LOOP() EEPROM_WRITE(thermalManager.temp_hotend[e].mpc); - #endif - - // - // Fixed-Time Motion - // - #if ENABLED(FT_MOTION) - _FIELD_TEST(ftMotion_cfg); - EEPROM_WRITE(ftMotion.cfg); - #endif - - // - // Input Shaping - // - #if HAS_ZV_SHAPING - #if ENABLED(INPUT_SHAPING_X) - EEPROM_WRITE(stepper.get_shaping_frequency(X_AXIS)); - EEPROM_WRITE(stepper.get_shaping_damping_ratio(X_AXIS)); - #endif - #if ENABLED(INPUT_SHAPING_Y) - EEPROM_WRITE(stepper.get_shaping_frequency(Y_AXIS)); - EEPROM_WRITE(stepper.get_shaping_damping_ratio(Y_AXIS)); - #endif - #endif - - // - // HOTEND_IDLE_TIMEOUT - // - #if ENABLED(HOTEND_IDLE_TIMEOUT) - EEPROM_WRITE(hotend_idle.cfg); - #endif - - // - // Nonlinear Extrusion - // - #if ENABLED(NONLINEAR_EXTRUSION) - EEPROM_WRITE(stepper.ne); + HOTEND_LOOP() + EEPROM_WRITE(thermalManager.temp_hotend[e].constants); #endif // // Report final CRC and Data Size // - if (eeprom_error == ERR_EEPROM_NOERR) { + if (!eeprom_error) { const uint16_t eeprom_size = eeprom_index - (EEPROM_OFFSET), final_crc = working_crc; @@ -1766,7 +1611,7 @@ void MarlinSettings::postprocess() { // Report storage size DEBUG_ECHO_MSG("Settings Stored (", eeprom_size, " bytes; crc ", (uint32_t)final_crc, ")"); - eeprom_error = size_error(eeprom_size); + eeprom_error |= size_error(eeprom_size); } EEPROM_FINISH(); @@ -1778,82 +1623,56 @@ void MarlinSettings::postprocess() { store_mesh(bedlevel.storage_slot); #endif - const bool success = (eeprom_error == ERR_EEPROM_NOERR); - if (success) { + if (!eeprom_error) { LCD_MESSAGE(MSG_SETTINGS_STORED); TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_SETTINGS_STORED))); } - TERN_(EXTENSIBLE_UI, ExtUI::onSettingsStored(success)); + TERN_(EXTENSIBLE_UI, ExtUI::onSettingsStored(!eeprom_error)); - return success; + return !eeprom_error; } /** * M501 - Retrieve Configuration */ - EEPROM_Error MarlinSettings::_load() { - EEPROM_Error eeprom_error = ERR_EEPROM_NOERR; - - if (!EEPROM_START(EEPROM_OFFSET)) return eeprom_error; + bool MarlinSettings::_load() { + if (!EEPROM_START(EEPROM_OFFSET)) return false; char stored_ver[4]; EEPROM_READ_ALWAYS(stored_ver); - uint16_t stored_crc; - - do { // A block to break out of on error - - // Version has to match or defaults are used - if (strncmp(version, stored_ver, 3) != 0) { - if (stored_ver[3] != '\0') { - stored_ver[0] = '?'; - stored_ver[1] = '\0'; - } - DEBUG_ECHO_MSG("EEPROM version mismatch (EEPROM=", stored_ver, " Marlin=" EEPROM_VERSION ")"); - eeprom_error = ERR_EEPROM_VERSION; - break; + // Version has to match or defaults are used + if (strncmp(version, stored_ver, 3) != 0) { + if (stored_ver[3] != '\0') { + stored_ver[0] = '?'; + stored_ver[1] = '\0'; } + DEBUG_ECHO_MSG("EEPROM version mismatch (EEPROM=", stored_ver, " Marlin=" EEPROM_VERSION ")"); + TERN_(DWIN_LCD_PROUI, LCD_MESSAGE(MSG_ERR_EEPROM_VERSION)); + TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_ERR_EEPROM_VERSION))); - // - // Optionally reset on first boot after flashing - // + IF_DISABLED(EEPROM_AUTO_INIT, ui.eeprom_alert_version()); + eeprom_error = true; + } + else { + + // Optionally reset on the first boot after flashing #if ENABLED(EEPROM_INIT_NOW) uint32_t stored_hash; EEPROM_READ_ALWAYS(stored_hash); - if (stored_hash != build_hash) { - eeprom_error = ERR_EEPROM_CORRUPT; - break; - } + if (stored_hash != build_hash) { EEPROM_FINISH(); return false; } #endif - // - // Get the stored CRC to compare at the end - // + uint16_t stored_crc; EEPROM_READ_ALWAYS(stored_crc); - // - // A temporary float for safe storage - // float dummyf = 0; + working_crc = 0; // Init to 0. Accumulated by EEPROM_READ - // - // Init to 0. Accumulated by EEPROM_READ - // - working_crc = 0; - - // - // Validate the stored size against the current data structure size - // - uint16_t stored_size; - EEPROM_READ_ALWAYS(stored_size); - if ((eeprom_error = size_error(stored_size))) break; - - // - // Extruder Parameter Count - // Number of e_factors may change - // _FIELD_TEST(e_factors); + + // Number of e_factors may change uint8_t e_factors; EEPROM_READ_ALWAYS(e_factors); @@ -1864,24 +1683,17 @@ void MarlinSettings::postprocess() { // Get only the number of E stepper parameters previously stored // Any steppers added later are set to their defaults uint32_t tmp1[NUM_AXES + e_factors]; - EEPROM_READ((uint8_t *)tmp1, sizeof(tmp1)); // max_acceleration_mm_per_s2 - - EEPROM_READ(planner.settings.min_segment_time_us); - - #if ENABLED(EDITABLE_STEPS_PER_UNIT) - float tmp2[NUM_AXES + e_factors]; - EEPROM_READ((uint8_t *)tmp2, sizeof(tmp2)); // axis_steps_per_mm - #endif - + float tmp2[NUM_AXES + e_factors]; feedRate_t tmp3[NUM_AXES + e_factors]; + EEPROM_READ((uint8_t *)tmp1, sizeof(tmp1)); // max_acceleration_mm_per_s2 + EEPROM_READ(planner.settings.min_segment_time_us); + EEPROM_READ((uint8_t *)tmp2, sizeof(tmp2)); // axis_steps_per_mm EEPROM_READ((uint8_t *)tmp3, sizeof(tmp3)); // max_feedrate_mm_s if (!validating) LOOP_DISTINCT_AXES(i) { const bool in = (i < e_factors + NUM_AXES); planner.settings.max_acceleration_mm_per_s2[i] = in ? tmp1[i] : pgm_read_dword(&_DMA[ALIM(i, _DMA)]); - #if ENABLED(EDITABLE_STEPS_PER_UNIT) - planner.settings.axis_steps_per_mm[i] = in ? tmp2[i] : pgm_read_float(&_DASU[ALIM(i, _DASU)]); - #endif + planner.settings.axis_steps_per_mm[i] = in ? tmp2[i] : pgm_read_float(&_DASU[ALIM(i, _DASU)]); planner.settings.max_feedrate_mm_s[i] = in ? tmp3[i] : pgm_read_float(&_DMF[ALIM(i, _DMF)]); } @@ -1891,7 +1703,7 @@ void MarlinSettings::postprocess() { EEPROM_READ(planner.settings.min_feedrate_mm_s); EEPROM_READ(planner.settings.min_travel_feedrate_mm_s); - #if ENABLED(CLASSIC_JERK) + #if HAS_CLASSIC_JERK EEPROM_READ(planner.max_jerk); #if HAS_LINEAR_E_JERK EEPROM_READ(dummyf); @@ -1906,7 +1718,6 @@ void MarlinSettings::postprocess() { // // Home Offset (M206 / M665) // - #if NUM_AXES { _FIELD_TEST(home_offset); @@ -1919,7 +1730,6 @@ void MarlinSettings::postprocess() { EEPROM_READ(home_offset); #endif } - #endif // NUM_AXES // // Hotend Offsets, if any @@ -1927,7 +1737,7 @@ void MarlinSettings::postprocess() { { #if HAS_HOTEND_OFFSET // Skip hotend 0 which must be 0 - for (uint8_t e = 1; e < HOTENDS; ++e) + LOOP_S_L_N(e, 1, HOTENDS) EEPROM_READ(hotend_offset[e]); #endif } @@ -1935,64 +1745,49 @@ void MarlinSettings::postprocess() { // // Filament Runout Sensor // + #if HAS_FILAMENT_SENSOR { - int8_t runout_sensor_enabled; - _FIELD_TEST(runout_sensor_enabled); - EEPROM_READ(runout_sensor_enabled); - #if HAS_FILAMENT_SENSOR - if (!validating) runout.enabled = runout_sensor_enabled < 0 ? FIL_RUNOUT_ENABLED_DEFAULT : runout_sensor_enabled; - #endif + _FIELD_TEST(runout_enabled); - TERN_(HAS_FILAMENT_SENSOR, if (runout.enabled) runout.reset()); + bool runout_enabled[NUM_RUNOUT_SENSORS]; + float runout_distance_mm[NUM_RUNOUT_SENSORS]; + RunoutMode runout_mode[NUM_RUNOUT_SENSORS]; - float runout_distance_mm; + EEPROM_READ(runout_enabled); EEPROM_READ(runout_distance_mm); - #if HAS_FILAMENT_RUNOUT_DISTANCE - if (!validating) runout.set_runout_distance(runout_distance_mm); - #endif + EEPROM_READ(runout_mode); + + if (!validating) { + LOOP_S_L_N(e, 0, NUM_RUNOUT_SENSORS) { + runout.enabled[e] = runout_enabled[e]; + runout.set_runout_distance(runout_distance_mm[e], e); + runout.mode[e] = runout_mode[e]; + } + runout.reset(); + } } + #endif // // Global Leveling // EEPROM_READ(TERN(ENABLE_LEVELING_FADE_HEIGHT, new_z_fade_height, dummyf)); - // - // AUTOTEMP - // - #if ENABLED(AUTOTEMP) - EEPROM_READ(planner.autotemp.max); - EEPROM_READ(planner.autotemp.min); - EEPROM_READ(planner.autotemp.factor); - #endif - // // Mesh (Manual) Bed Leveling // { uint8_t mesh_num_x, mesh_num_y; - uint16_t mesh_check; EEPROM_READ(dummyf); EEPROM_READ_ALWAYS(mesh_num_x); EEPROM_READ_ALWAYS(mesh_num_y); - // Check value must correspond to the X/Y values - EEPROM_READ_ALWAYS(mesh_check); - if (mesh_check != TWO_BYTE_HASH(mesh_num_x, mesh_num_y)) { - eeprom_error = ERR_EEPROM_CORRUPT; - break; - } - #if ENABLED(MESH_BED_LEVELING) if (!validating) bedlevel.z_offset = dummyf; if (mesh_num_x == (GRID_MAX_POINTS_X) && mesh_num_y == (GRID_MAX_POINTS_Y)) { // EEPROM data fits the current mesh EEPROM_READ(bedlevel.z_values); } - else if (mesh_num_x > (GRID_MAX_POINTS_X) || mesh_num_y > (GRID_MAX_POINTS_Y)) { - eeprom_error = ERR_EEPROM_CORRUPT; - break; - } else { // EEPROM data is stale if (!validating) bedlevel.reset(); @@ -2007,7 +1802,6 @@ void MarlinSettings::postprocess() { // // Probe Z Offset // - #if NUM_AXES { _FIELD_TEST(probe_offset); #if HAS_BED_PROBE @@ -2017,7 +1811,6 @@ void MarlinSettings::postprocess() { #endif EEPROM_READ(zpo); } - #endif // // Planar Bed Leveling matrix @@ -2037,15 +1830,6 @@ void MarlinSettings::postprocess() { uint8_t grid_max_x, grid_max_y; EEPROM_READ_ALWAYS(grid_max_x); // 1 byte EEPROM_READ_ALWAYS(grid_max_y); // 1 byte - - // Check value must correspond to the X/Y values - uint16_t grid_check; - EEPROM_READ_ALWAYS(grid_check); - if (grid_check != TWO_BYTE_HASH(grid_max_x, grid_max_y)) { - eeprom_error = ERR_EEPROM_CORRUPT; - break; - } - xy_pos_t spacing, start; EEPROM_READ(spacing); // 2 ints EEPROM_READ(start); // 2 ints @@ -2053,11 +1837,7 @@ void MarlinSettings::postprocess() { if (grid_max_x == (GRID_MAX_POINTS_X) && grid_max_y == (GRID_MAX_POINTS_Y)) { if (!validating) set_bed_leveling_enabled(false); bedlevel.set_grid(spacing, start); - EEPROM_READ(bedlevel.z_values); // 9 to 256 floats - } - else if (grid_max_x > (GRID_MAX_POINTS_X) || grid_max_y > (GRID_MAX_POINTS_Y)) { - eeprom_error = ERR_EEPROM_CORRUPT; - break; + EEPROM_READ(bedlevel.z_values); // 9 to 256 floats } else // EEPROM data is stale #endif // AUTO_BED_LEVELING_BILINEAR @@ -2096,17 +1876,15 @@ void MarlinSettings::postprocess() { // // SERVO_ANGLES // - #if HAS_SERVO_ANGLES { _FIELD_TEST(servo_angles); #if ENABLED(EDITABLE_SERVO_ANGLES) - uint16_t (&servo_angles_arr)[NUM_SERVOS][2] = servo_angles; + uint16_t (&servo_angles_arr)[EEPROM_NUM_SERVOS][2] = servo_angles; #else - uint16_t servo_angles_arr[NUM_SERVOS][2]; + uint16_t servo_angles_arr[EEPROM_NUM_SERVOS][2]; #endif EEPROM_READ(servo_angles_arr); } - #endif // // Thermal first layer compensation values @@ -2121,7 +1899,7 @@ void MarlinSettings::postprocess() { #if ENABLED(PTC_HOTEND) EEPROM_READ(ptc.z_offsets_hotend); #endif - if (!validating) ptc.reset_index(); + ptc.reset_index(); #else // No placeholder data for this feature #endif @@ -2138,7 +1916,7 @@ void MarlinSettings::postprocess() { #endif EEPROM_READ(bltouch_od_5v_mode); - #if HAS_BLTOUCH_HS_MODE + #ifdef BLTOUCH_HS_MODE _FIELD_TEST(bltouch_high_speed_mode); #if ENABLED(BLTOUCH) const bool &bltouch_high_speed_mode = bltouch.high_speed_mode; @@ -2307,12 +2085,10 @@ void MarlinSettings::postprocess() { // // LCD Backlight / Sleep Timeout // - #if ENABLED(EDITABLE_DISPLAY_TIMEOUT) - #if HAS_BACKLIGHT_TIMEOUT - EEPROM_READ(ui.backlight_timeout_minutes); - #elif HAS_DISPLAY_SLEEP - EEPROM_READ(ui.sleep_timeout_minutes); - #endif + #if LCD_BACKLIGHT_TIMEOUT_MINS + EEPROM_READ(ui.backlight_timeout_minutes); + #elif HAS_DISPLAY_SLEEP + EEPROM_READ(ui.sleep_timeout_minutes); #endif // @@ -2329,15 +2105,10 @@ void MarlinSettings::postprocess() { // Power-Loss Recovery // { - _FIELD_TEST(recovery_enabled); bool recovery_enabled; - celsius_t bed_temp_threshold; + _FIELD_TEST(recovery_enabled); EEPROM_READ(recovery_enabled); - EEPROM_READ(bed_temp_threshold); - if (!validating) { - TERN_(POWER_LOSS_RECOVERY, recovery.enabled = recovery_enabled); - TERN_(HAS_PLR_BED_THRESHOLD, recovery.bed_temp_threshold = bed_temp_threshold); - } + TERN_(POWER_LOSS_RECOVERY, if (!validating) recovery.enabled = recovery_enabled); } // @@ -2605,17 +2376,9 @@ void MarlinSettings::postprocess() { #endif } - // - // Adaptive Step Smoothing state - // - #if ENABLED(ADAPTIVE_STEP_SMOOTHING_TOGGLE) - EEPROM_READ(stepper.adaptive_step_smoothing_enabled); - #endif - // // CNC Coordinate System // - #if NUM_AXES { _FIELD_TEST(coordinate_system); #if ENABLED(CNC_COORDINATE_SYSTEMS) @@ -2626,12 +2389,10 @@ void MarlinSettings::postprocess() { EEPROM_READ(coordinate_system); #endif } - #endif // // Skew correction factors // - #if ENABLED(SKEW_CORRECTION) { skew_factor_t skew_factor; _FIELD_TEST(planner_skew_factor); @@ -2646,13 +2407,15 @@ void MarlinSettings::postprocess() { } #endif } - #endif // // Advanced Pause filament load & unload lengths // - #if ENABLED(CONFIGURE_FILAMENT_CHANGE) + #if HAS_EXTRUDERS { + #if DISABLED(ADVANCED_PAUSE_FEATURE) + fil_change_settings_t fc_settings[EXTRUDERS]; + #endif _FIELD_TEST(fc_settings); EEPROM_READ(fc_settings); } @@ -2669,7 +2432,6 @@ void MarlinSettings::postprocess() { // // Backlash Compensation // - #if NUM_AXES { xyz_float_t backlash_distance_mm; uint8_t backlash_correction; @@ -2681,16 +2443,13 @@ void MarlinSettings::postprocess() { EEPROM_READ(backlash_smoothing_mm); #if ENABLED(BACKLASH_GCODE) - if (!validating) { LOOP_NUM_AXES(axis) backlash.set_distance_mm((AxisEnum)axis, backlash_distance_mm[axis]); backlash.set_correction_uint8(backlash_correction); #ifdef BACKLASH_SMOOTHING_MM backlash.set_smoothing_mm(backlash_smoothing_mm); #endif - } #endif } - #endif // NUM_AXES // // Extensible UI User Data @@ -2705,14 +2464,21 @@ void MarlinSettings::postprocess() { #endif // - // JyersUI User Data + // Creality DWIN User Data // - #if ENABLED(DWIN_CREALITY_LCD_JYERSUI) + #if ENABLED(DWIN_LCD_PROUI) { - const char dwin_settings[jyersDWIN.eeprom_data_size] = { 0 }; + const char dwin_data[eeprom_data_size] = { 0 }; + _FIELD_TEST(dwin_data); + EEPROM_READ(dwin_data); + if (!validating) DWIN_CopySettingsFrom(dwin_data); + } + #elif ENABLED(DWIN_CREALITY_LCD_JYERSUI) + { + const char dwin_settings[CrealityDWIN.eeprom_data_size] = { 0 }; _FIELD_TEST(dwin_settings); EEPROM_READ(dwin_settings); - if (!validating) jyersDWIN.loadSettings(dwin_settings); + if (!validating) CrealityDWIN.Load_Settings(dwin_settings); } #endif @@ -2773,7 +2539,7 @@ void MarlinSettings::postprocess() { // // MKS UI controller // - #if DGUS_LCD_UI_MKS + #if ENABLED(DGUS_LCD_UI_MKS) _FIELD_TEST(mks_language_index); EEPROM_READ(mks_language_index); EEPROM_READ(mks_corner_offsets); @@ -2789,7 +2555,7 @@ void MarlinSettings::postprocess() { uint8_t ui_language; EEPROM_READ(ui_language); if (ui_language >= NUM_LANGUAGES) ui_language = 0; - if (!validating) ui.set_language(ui_language); + ui.set_language(ui_language); } #endif @@ -2797,88 +2563,49 @@ void MarlinSettings::postprocess() { // Model predictive control // #if ENABLED(MPCTEMP) - HOTEND_LOOP() EEPROM_READ(thermalManager.temp_hotend[e].mpc); - #endif - - // - // Fixed-Time Motion - // - #if ENABLED(FT_MOTION) - _FIELD_TEST(ftMotion_cfg); - EEPROM_READ(ftMotion.cfg); - #endif - - // - // Input Shaping - // - #if ENABLED(INPUT_SHAPING_X) { - float _data[2]; - EEPROM_READ(_data); - if (!validating) { - stepper.set_shaping_frequency(X_AXIS, _data[0]); - stepper.set_shaping_damping_ratio(X_AXIS, _data[1]); - } + HOTEND_LOOP() + EEPROM_READ(thermalManager.temp_hotend[e].constants); } #endif - #if ENABLED(INPUT_SHAPING_Y) - { - float _data[2]; - EEPROM_READ(_data); - if (!validating) { - stepper.set_shaping_frequency(Y_AXIS, _data[0]); - stepper.set_shaping_damping_ratio(Y_AXIS, _data[1]); - } - } - #endif - - // - // HOTEND_IDLE_TIMEOUT - // - #if ENABLED(HOTEND_IDLE_TIMEOUT) - EEPROM_READ(hotend_idle.cfg); - #endif - - // - // Nonlinear Extrusion - // - #if ENABLED(NONLINEAR_EXTRUSION) - EEPROM_READ(stepper.ne); - #endif - // // Validate Final Size and CRC // - const uint16_t eeprom_total = eeprom_index - (EEPROM_OFFSET); - if ((eeprom_error = size_error(eeprom_total))) { - // Handle below and on return - break; + eeprom_error = size_error(eeprom_index - (EEPROM_OFFSET)); + if (eeprom_error) { + DEBUG_ECHO_MSG("Index: ", eeprom_index - (EEPROM_OFFSET), " Size: ", datasize()); + IF_DISABLED(EEPROM_AUTO_INIT, ui.eeprom_alert_index()); } else if (working_crc != stored_crc) { - eeprom_error = ERR_EEPROM_CRC; - break; + eeprom_error = true; + DEBUG_ERROR_MSG("EEPROM CRC mismatch - (stored) ", stored_crc, " != ", working_crc, " (calculated)!"); + TERN_(DWIN_LCD_PROUI, LCD_MESSAGE(MSG_ERR_EEPROM_CRC)); + TERN_(HOST_EEPROM_CHITCHAT, hostui.notify(GET_TEXT_F(MSG_ERR_EEPROM_CRC))); + IF_DISABLED(EEPROM_AUTO_INIT, ui.eeprom_alert_crc()); } else if (!validating) { DEBUG_ECHO_START(); DEBUG_ECHO(version); - DEBUG_ECHOLNPGM(" stored settings retrieved (", eeprom_total, " bytes; crc ", working_crc, ")"); + DEBUG_ECHOLNPGM(" stored settings retrieved (", eeprom_index - (EEPROM_OFFSET), " bytes; crc ", (uint32_t)working_crc, ")"); TERN_(HOST_EEPROM_CHITCHAT, hostui.notify(F("Stored settings retrieved"))); } + if (!validating && !eeprom_error) postprocess(); + #if ENABLED(AUTO_BED_LEVELING_UBL) if (!validating) { bedlevel.report_state(); if (!bedlevel.sanity_check()) { - #if ALL(EEPROM_CHITCHAT, DEBUG_LEVELING_FEATURE) + #if BOTH(EEPROM_CHITCHAT, DEBUG_LEVELING_FEATURE) bedlevel.echo_name(); DEBUG_ECHOLNPGM(" initialized.\n"); #endif } else { - eeprom_error = ERR_EEPROM_CORRUPT; - #if ALL(EEPROM_CHITCHAT, DEBUG_LEVELING_FEATURE) + eeprom_error = true; + #if BOTH(EEPROM_CHITCHAT, DEBUG_LEVELING_FEATURE) DEBUG_ECHOPGM("?Can't enable "); bedlevel.echo_name(); DEBUG_ECHOLNPGM("."); @@ -2896,26 +2623,6 @@ void MarlinSettings::postprocess() { } } #endif - - } while(0); - - EEPROM_FINISH(); - - switch (eeprom_error) { - case ERR_EEPROM_NOERR: - if (!validating) postprocess(); - break; - case ERR_EEPROM_SIZE: - DEBUG_ECHO_MSG("Index: ", eeprom_index - (EEPROM_OFFSET), " Size: ", datasize()); - break; - case ERR_EEPROM_CORRUPT: - DEBUG_WARN_MSG(STR_ERR_EEPROM_CORRUPT); - break; - case ERR_EEPROM_CRC: - DEBUG_WARN_MSG("EEPROM CRC mismatch - (stored) ", stored_crc, " != ", working_crc, " (calculated)!"); - TERN_(HOST_EEPROM_CHITCHAT, hostui.notify(GET_TEXT_F(MSG_ERR_EEPROM_CRC))); - break; - default: break; } #if ENABLED(EEPROM_CHITCHAT) && DISABLED(DISABLE_M503) @@ -2923,7 +2630,9 @@ void MarlinSettings::postprocess() { if (!validating && TERN1(EEPROM_BOOT_SILENT, IsRunning())) report(); #endif - return eeprom_error; + EEPROM_FINISH(); + + return !eeprom_error; } #ifdef ARCHIM2_SPI_FLASH_EEPROM_BACKUP_SIZE @@ -2933,30 +2642,26 @@ void MarlinSettings::postprocess() { bool MarlinSettings::validate() { validating = true; #ifdef ARCHIM2_SPI_FLASH_EEPROM_BACKUP_SIZE - EEPROM_Error err = _load(); - if (err != ERR_EEPROM_NOERR && restoreEEPROM()) { + bool success = _load(); + if (!success && restoreEEPROM()) { SERIAL_ECHOLNPGM("Recovered backup EEPROM settings from SPI Flash"); - err = _load(); + success = _load(); } #else - const EEPROM_Error err = _load(); + const bool success = _load(); #endif validating = false; - - if (err) ui.eeprom_alert(err); - - return (err == ERR_EEPROM_NOERR); + return success; } bool MarlinSettings::load() { if (validate()) { - const EEPROM_Error err = _load(); - const bool success = (err == ERR_EEPROM_NOERR); + const bool success = _load(); TERN_(EXTENSIBLE_UI, ExtUI::onSettingsLoaded(success)); return success; } reset(); - #if ANY(EEPROM_AUTO_INIT, EEPROM_INIT_NOW) + #if EITHER(EEPROM_AUTO_INIT, EEPROM_INIT_NOW) (void)save(); SERIAL_ECHO_MSG("EEPROM Initialized"); #endif @@ -3063,7 +2768,7 @@ void MarlinSettings::postprocess() { #endif #if ENABLED(DWIN_LCD_PROUI) - status = !bedLevelTools.meshValidate(); + status = !BedLevelTools.meshvalidate(); if (status) { bedlevel.invalidate(); LCD_MESSAGE(MSG_UBL_MESH_INVALID); @@ -3092,7 +2797,7 @@ void MarlinSettings::postprocess() { #else // !EEPROM_SETTINGS bool MarlinSettings::save() { - DEBUG_WARN_MSG("EEPROM disabled"); + DEBUG_ERROR_MSG("EEPROM disabled"); return false; } @@ -3104,9 +2809,7 @@ void MarlinSettings::postprocess() { void MarlinSettings::reset() { LOOP_DISTINCT_AXES(i) { planner.settings.max_acceleration_mm_per_s2[i] = pgm_read_dword(&_DMA[ALIM(i, _DMA)]); - #if ENABLED(EDITABLE_STEPS_PER_UNIT) - planner.settings.axis_steps_per_mm[i] = pgm_read_float(&_DASU[ALIM(i, _DASU)]); - #endif + planner.settings.axis_steps_per_mm[i] = pgm_read_float(&_DASU[ALIM(i, _DASU)]); planner.settings.max_feedrate_mm_s[i] = pgm_read_float(&_DMF[ALIM(i, _DMF)]); } @@ -3117,8 +2820,8 @@ void MarlinSettings::reset() { planner.settings.min_feedrate_mm_s = feedRate_t(DEFAULT_MINIMUMFEEDRATE); planner.settings.min_travel_feedrate_mm_s = feedRate_t(DEFAULT_MINTRAVELFEEDRATE); - #if ENABLED(CLASSIC_JERK) - #if HAS_X_AXIS && !defined(DEFAULT_XJERK) + #if HAS_CLASSIC_JERK + #ifndef DEFAULT_XJERK #define DEFAULT_XJERK 0 #endif #if HAS_Y_AXIS && !defined(DEFAULT_YJERK) @@ -3166,9 +2869,16 @@ void MarlinSettings::reset() { // #if HAS_FILAMENT_SENSOR - runout.enabled = FIL_RUNOUT_ENABLED_DEFAULT; + constexpr bool fred[] = FIL_RUNOUT_ENABLED; + constexpr uint8_t frm[] = FIL_RUNOUT_MODE; + constexpr float frd[] = FIL_RUNOUT_DISTANCE_MM; + static_assert(COUNT(fred) == NUM_RUNOUT_SENSORS, "FIL_RUNOUT_ENABLED must have NUM_RUNOUT_SENSORS values."); + static_assert(COUNT(frm) == NUM_RUNOUT_SENSORS, "FIL_RUNOUT_MODE must have NUM_RUNOUT_SENSORS values."); + static_assert(COUNT(frd) == NUM_RUNOUT_SENSORS, "FIL_RUNOUT_DISTANCE_MM must have NUM_RUNOUT_SENSORS values."); + COPY(runout.enabled, fred); + COPY(runout.mode, frm); + LOOP_L_N(e, NUM_RUNOUT_SENSORS) runout.set_runout_distance(frd[e], e); runout.reset(); - TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, runout.set_runout_distance(FILAMENT_RUNOUT_DISTANCE_MM)); #endif // @@ -3215,7 +2925,7 @@ void MarlinSettings::reset() { #endif #endif - TERN_(DWIN_CREALITY_LCD_JYERSUI, jyersDWIN.resetSettings()); + TERN_(DWIN_CREALITY_LCD_JYERSUI, CrealityDWIN.Reset_Settings()); // // Case Light Brightness @@ -3245,15 +2955,6 @@ void MarlinSettings::reset() { TERN_(ENABLE_LEVELING_FADE_HEIGHT, new_z_fade_height = (DEFAULT_LEVELING_FADE_HEIGHT)); TERN_(HAS_LEVELING, reset_bed_level()); - // - // AUTOTEMP - // - #if ENABLED(AUTOTEMP) - planner.autotemp.max = AUTOTEMP_MAX; - planner.autotemp.min = AUTOTEMP_MIN; - planner.autotemp.factor = AUTOTEMP_FACTOR; - #endif - // // X Axis Twist Compensation // @@ -3290,14 +2991,20 @@ void MarlinSettings::reset() { // // BLTouch // - TERN_(HAS_BLTOUCH_HS_MODE, bltouch.high_speed_mode = BLTOUCH_HS_MODE); + #ifdef BLTOUCH_HS_MODE + bltouch.high_speed_mode = ENABLED(BLTOUCH_HS_MODE); + #endif // // Kinematic Settings (Delta, SCARA, TPARA, Polargraph...) // #if IS_KINEMATIC - segments_per_second = DEFAULT_SEGMENTS_PER_SECOND; + segments_per_second = ( + TERN_(DELTA, DELTA_SEGMENTS_PER_SECOND) + TERN_(IS_SCARA, SCARA_SEGMENTS_PER_SECOND) + TERN_(POLARGRAPH, POLAR_SEGMENTS_PER_SECOND) + ); #if ENABLED(DELTA) const abc_float_t adj = DELTA_ENDSTOP_ADJ, dta = DELTA_TOWER_ANGLE_TRIM, ddr = DELTA_DIAGONAL_ROD_TRIM_TOWER; delta_height = DELTA_HEIGHT; @@ -3364,7 +3071,7 @@ void MarlinSettings::reset() { #if HAS_FAN constexpr uint8_t fpre[] = { REPEAT2_S(1, INCREMENT(PREHEAT_COUNT), _PITEM, FAN_SPEED) }; #endif - for (uint8_t i = 0; i < PREHEAT_COUNT; ++i) { + LOOP_L_N(i, PREHEAT_COUNT) { TERN_(HAS_HOTEND, ui.material_preset[i].hotend_temp = hpre[i]); TERN_(HAS_HEATED_BED, ui.material_preset[i].bed_temp = bpre[i]); TERN_(HAS_FAN, ui.material_preset[i].fan_speed = fpre[i]); @@ -3442,6 +3149,7 @@ void MarlinSettings::reset() { // // Heated Bed PID // + #if ENABLED(PIDTEMPBED) thermalManager.temp_bed.pid.set(DEFAULT_bedKp, DEFAULT_bedKi, DEFAULT_bedKd); #endif @@ -3449,6 +3157,7 @@ void MarlinSettings::reset() { // // Heated Chamber PID // + #if ENABLED(PIDTEMPCHAMBER) thermalManager.temp_chamber.pid.set(DEFAULT_chamberKp, DEFAULT_chamberKi, DEFAULT_chamberKd); #endif @@ -3476,12 +3185,10 @@ void MarlinSettings::reset() { // // LCD Backlight / Sleep Timeout // - #if ENABLED(EDITABLE_DISPLAY_TIMEOUT) - #if HAS_BACKLIGHT_TIMEOUT - ui.backlight_timeout_minutes = LCD_BACKLIGHT_TIMEOUT_MINS; - #elif HAS_DISPLAY_SLEEP - ui.sleep_timeout_minutes = DISPLAY_SLEEP_MINUTES; - #endif + #if LCD_BACKLIGHT_TIMEOUT_MINS + ui.backlight_timeout_minutes = LCD_BACKLIGHT_TIMEOUT_MINS; + #elif HAS_DISPLAY_SLEEP + ui.sleep_timeout_minutes = TERN(TOUCH_SCREEN, TOUCH_IDLE_SLEEP_MINS, DISPLAY_SLEEP_MINUTES); #endif // @@ -3492,10 +3199,7 @@ void MarlinSettings::reset() { // // Power-Loss Recovery // - #if ENABLED(POWER_LOSS_RECOVERY) - recovery.enable(ENABLED(PLR_ENABLED_DEFAULT)); - TERN_(HAS_PLR_BED_THRESHOLD, recovery.bed_temp_threshold = PLR_BED_THRESHOLD); - #endif + TERN_(POWER_LOSS_RECOVERY, recovery.enable(ENABLED(PLR_ENABLED_DEFAULT))); // // Firmware Retraction @@ -3505,12 +3209,13 @@ void MarlinSettings::reset() { // // Volumetric & Filament Size // + #if DISABLED(NO_VOLUMETRICS) parser.volumetric_enabled = ENABLED(VOLUMETRIC_DEFAULT_ON); - for (uint8_t q = 0; q < COUNT(planner.filament_size); ++q) + LOOP_L_N(q, COUNT(planner.filament_size)) planner.filament_size[q] = DEFAULT_NOMINAL_FILAMENT_DIA; #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) - for (uint8_t q = 0; q < COUNT(planner.volumetric_extruder_limit); ++q) + LOOP_L_N(q, COUNT(planner.volumetric_extruder_limit)) planner.volumetric_extruder_limit[q] = DEFAULT_VOLUMETRIC_EXTRUDER_LIMIT; #endif #endif @@ -3526,7 +3231,7 @@ void MarlinSettings::reset() { #if ENABLED(DISTINCT_E_FACTORS) constexpr float linAdvanceK[] = ADVANCE_K; EXTRUDER_LOOP() { - const float a = linAdvanceK[_MAX(uint8_t(e), COUNT(linAdvanceK) - 1)]; + const float a = linAdvanceK[_MAX(e, (int8_t)COUNT(linAdvanceK) - 1)]; planner.extruder_advance_K[e] = a; TERN_(ADVANCE_K_EXTRA, other_extruder_advance_K[e] = a); } @@ -3541,7 +3246,7 @@ void MarlinSettings::reset() { #if HAS_MOTOR_CURRENT_PWM constexpr uint32_t tmp_motor_current_setting[MOTOR_CURRENT_COUNT] = PWM_MOTOR_CURRENT; - for (uint8_t q = 0; q < MOTOR_CURRENT_COUNT; ++q) + LOOP_L_N(q, MOTOR_CURRENT_COUNT) stepper.set_digipot_current(q, (stepper.motor_current_setting[q] = tmp_motor_current_setting[q])); #endif @@ -3551,18 +3256,11 @@ void MarlinSettings::reset() { #if HAS_MOTOR_CURRENT_SPI static constexpr uint32_t tmp_motor_current_setting[] = DIGIPOT_MOTOR_CURRENT; DEBUG_ECHOLNPGM("Writing Digipot"); - for (uint8_t q = 0; q < COUNT(tmp_motor_current_setting); ++q) + LOOP_L_N(q, COUNT(tmp_motor_current_setting)) stepper.set_digipot_current(q, tmp_motor_current_setting[q]); DEBUG_ECHOLNPGM("Digipot Written"); #endif - // - // Adaptive Step Smoothing state - // - #if ENABLED(ADAPTIVE_STEP_SMOOTHING_TOGGLE) - stepper.adaptive_step_smoothing_enabled = true; - #endif - // // CNC Coordinate System // @@ -3582,7 +3280,7 @@ void MarlinSettings::reset() { // // Advanced Pause filament load & unload lengths // - #if ENABLED(CONFIGURE_FILAMENT_CHANGE) + #if ENABLED(ADVANCED_PAUSE_FEATURE) EXTRUDER_LOOP() { fc_settings[e].unload_length = FILAMENT_CHANGE_UNLOAD_LENGTH; fc_settings[e].load_length = FILAMENT_CHANGE_FAST_LOAD_LENGTH; @@ -3608,6 +3306,11 @@ void MarlinSettings::reset() { // TERN_(DGUS_LCD_UI_MKS, MKS_reset_settings()); + // + // Ender-3 V2 with ProUI + // + TERN_(DWIN_LCD_PROUI, DWIN_SetDataDefaults()); + // // Model predictive control // @@ -3631,53 +3334,24 @@ void MarlinSettings::reset() { static_assert(COUNT(_filament_heat_capacity_permm) == HOTENDS, "FILAMENT_HEAT_CAPACITY_PERMM must have HOTENDS items."); HOTEND_LOOP() { - MPC_t &mpc = thermalManager.temp_hotend[e].mpc; - mpc.heater_power = _mpc_heater_power[e]; - mpc.block_heat_capacity = _mpc_block_heat_capacity[e]; - mpc.sensor_responsiveness = _mpc_sensor_responsiveness[e]; - mpc.ambient_xfer_coeff_fan0 = _mpc_ambient_xfer_coeff[e]; + MPC_t &constants = thermalManager.temp_hotend[e].constants; + constants.heater_power = _mpc_heater_power[e]; + constants.block_heat_capacity = _mpc_block_heat_capacity[e]; + constants.sensor_responsiveness = _mpc_sensor_responsiveness[e]; + constants.ambient_xfer_coeff_fan0 = _mpc_ambient_xfer_coeff[e]; #if ENABLED(MPC_INCLUDE_FAN) - mpc.fan255_adjustment = _mpc_ambient_xfer_coeff_fan255[e] - _mpc_ambient_xfer_coeff[e]; + constants.fan255_adjustment = _mpc_ambient_xfer_coeff_fan255[e] - _mpc_ambient_xfer_coeff[e]; #endif - mpc.filament_heat_capacity_permm = _filament_heat_capacity_permm[e]; + constants.filament_heat_capacity_permm = _filament_heat_capacity_permm[e]; } #endif - // - // Fixed-Time Motion - // - TERN_(FT_MOTION, ftMotion.set_defaults()); - - // - // Nonlinear Extrusion - // - TERN_(NONLINEAR_EXTRUSION, stepper.ne.reset()); - - // - // Input Shaping - // - #if HAS_ZV_SHAPING - #if ENABLED(INPUT_SHAPING_X) - stepper.set_shaping_frequency(X_AXIS, SHAPING_FREQ_X); - stepper.set_shaping_damping_ratio(X_AXIS, SHAPING_ZETA_X); - #endif - #if ENABLED(INPUT_SHAPING_Y) - stepper.set_shaping_frequency(Y_AXIS, SHAPING_FREQ_Y); - stepper.set_shaping_damping_ratio(Y_AXIS, SHAPING_ZETA_Y); - #endif - #endif - - // - // Hotend Idle Timeout - // - TERN_(HOTEND_IDLE_TIMEOUT, hotend_idle.cfg.set_defaults()); - postprocess(); - #if ANY(EEPROM_CHITCHAT, DEBUG_LEVELING_FEATURE) + #if EITHER(EEPROM_CHITCHAT, DEBUG_LEVELING_FEATURE) FSTR_P const hdsl = F("Hardcoded Default Settings Loaded"); TERN_(HOST_EEPROM_CHITCHAT, hostui.notify(hdsl)); - DEBUG_ECHO_START(); DEBUG_ECHOLN(hdsl); + DEBUG_ECHO_START(); DEBUG_ECHOLNF(hdsl); #endif TERN_(EXTENSIBLE_UI, ExtUI::onFactoryReset()); @@ -3690,9 +3364,7 @@ void MarlinSettings::reset() { #define CONFIG_ECHO_MSG_P(V...) do{ CONFIG_ECHO_START(); SERIAL_ECHOLNPGM_P(V); }while(0) #define CONFIG_ECHO_HEADING(STR) gcode.report_heading(forReplay, F(STR)) - #if ENABLED(EDITABLE_STEPS_PER_UNIT) - void M92_report(const bool echo=true, const int8_t e=-1); - #endif + void M92_report(const bool echo=true, const int8_t e=-1); /** * M503 - Report current settings in RAM @@ -3730,7 +3402,7 @@ void MarlinSettings::reset() { // // M92 Steps per Unit // - TERN_(EDITABLE_STEPS_PER_UNIT, gcode.M92_report(forReplay)); + gcode.M92_report(forReplay); // // M203 Maximum feedrates (units/s) @@ -3755,7 +3427,7 @@ void MarlinSettings::reset() { // // M206 Home Offset // - TERN_(HAS_HOME_OFFSET, gcode.M206_report(forReplay)); + TERN_(HAS_M206_COMMAND, gcode.M206_report(forReplay)); // // M218 Hotend offsets @@ -3772,14 +3444,15 @@ void MarlinSettings::reset() { #if ENABLED(MESH_BED_LEVELING) if (leveling_is_valid()) { - for (uint8_t py = 0; py < GRID_MAX_POINTS_Y; ++py) { - for (uint8_t px = 0; px < GRID_MAX_POINTS_X; ++px) { + LOOP_L_N(py, GRID_MAX_POINTS_Y) { + LOOP_L_N(px, GRID_MAX_POINTS_X) { CONFIG_ECHO_START(); - SERIAL_ECHOLN(F(" G29 S3 I"), px, F(" J"), py, FPSTR(SP_Z_STR), p_float_t(LINEAR_UNIT(bedlevel.z_values[px][py]), 5)); + SERIAL_ECHOPGM(" G29 S3 I", px, " J", py); + SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, LINEAR_UNIT(bedlevel.z_values[px][py]), 5); } } CONFIG_ECHO_START(); - SERIAL_ECHOLNPGM(" G29 S4 Z", p_float_t(LINEAR_UNIT(bedlevel.z_offset), 5)); + SERIAL_ECHOLNPAIR_F(" G29 S4 Z", LINEAR_UNIT(bedlevel.z_offset), 5); } #elif ENABLED(AUTO_BED_LEVELING_UBL) @@ -3797,10 +3470,11 @@ void MarlinSettings::reset() { #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) if (leveling_is_valid()) { - for (uint8_t py = 0; py < GRID_MAX_POINTS_Y; ++py) { - for (uint8_t px = 0; px < GRID_MAX_POINTS_X; ++px) { + LOOP_L_N(py, GRID_MAX_POINTS_Y) { + LOOP_L_N(px, GRID_MAX_POINTS_X) { CONFIG_ECHO_START(); - SERIAL_ECHOLN(F(" G29 W I"), px, F(" J"), py, FPSTR(SP_Z_STR), p_float_t(LINEAR_UNIT(bedlevel.z_values[px][py]), 5)); + SERIAL_ECHOPGM(" G29 W I", px, " J", py); + SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, LINEAR_UNIT(bedlevel.z_values[px][py]), 5); } } } @@ -3827,7 +3501,7 @@ void MarlinSettings::reset() { // // M666 Endstops Adjustment // - #if ANY(DELTA, HAS_EXTRA_ENDSTOPS) + #if EITHER(DELTA, HAS_EXTRA_ENDSTOPS) gcode.M666_report(forReplay); #endif @@ -3849,7 +3523,7 @@ void MarlinSettings::reset() { TERN_(PIDTEMPCHAMBER, gcode.M309_report(forReplay)); #if HAS_USER_THERMISTORS - for (uint8_t i = 0; i < USER_THERMISTORS; ++i) + LOOP_L_N(i, USER_THERMISTORS) thermalManager.M305_report(i, forReplay); #endif @@ -3861,7 +3535,7 @@ void MarlinSettings::reset() { // // Display Sleep // - TERN_(EDITABLE_DISPLAY_TIMEOUT, gcode.M255_report(forReplay)); + TERN_(HAS_GCODE_M255, gcode.M255_report(forReplay)); // // LCD Brightness @@ -3919,26 +3593,6 @@ void MarlinSettings::reset() { // TERN_(HAS_STEALTHCHOP, gcode.M569_report(forReplay)); - // - // Fixed-Time Motion - // - TERN_(FT_MOTION, gcode.M493_report(forReplay)); - - // - // Nonlinear Extrusion - // - TERN_(NONLINEAR_EXTRUSION, gcode.M592_report(forReplay)); - - // - // Input Shaping - // - TERN_(HAS_ZV_SHAPING, gcode.M593_report(forReplay)); - - // - // Hotend Idle Timeout - // - TERN_(HOTEND_IDLE_TIMEOUT, gcode.M86_report(forReplay)); - // // Linear Advance // @@ -3954,7 +3608,7 @@ void MarlinSettings::reset() { // // Advanced Pause filament load & unload lengths // - TERN_(CONFIGURE_FILAMENT_CHANGE, gcode.M603_report(forReplay)); + TERN_(ADVANCED_PAUSE_FEATURE, gcode.M603_report(forReplay)); // // Tool-changing Parameters @@ -3969,7 +3623,7 @@ void MarlinSettings::reset() { // // Filament Runout Sensor // - TERN_(HAS_FILAMENT_SENSOR, gcode.M412_report(forReplay)); + TERN_(HAS_FILAMENT_SENSOR, gcode.M591_report(forReplay)); #if HAS_ETHERNET CONFIG_ECHO_HEADING("Ethernet"); diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index 6426c7f4a2..7306168262 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -122,7 +122,7 @@ Stepper stepper; // Singleton #include "../feature/mixing.h" #endif -#if HAS_FILAMENT_RUNOUT_DISTANCE +#if HAS_FILAMENT_SENSOR #include "../feature/runout.h" #endif @@ -2292,7 +2292,7 @@ hal_timer_t Stepper::block_phase_isr() { PAGE_SEGMENT_UPDATE_POS(E); } #endif - TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, runout.block_completed(current_block)); + TERN_(HAS_FILAMENT_SENSOR, runout.block_completed(current_block)); discard_current_block(); } else { diff --git a/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR2.h b/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR2.h index 65828fd4fb..5919aef682 100644 --- a/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR2.h +++ b/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR2.h @@ -69,7 +69,13 @@ #endif #if HAS_MARLINUI_U8GLIB - #define BOARD_ST7920_DELAY_1 125 - #define BOARD_ST7920_DELAY_2 125 - #define BOARD_ST7920_DELAY_3 125 + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 125 + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 125 + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 125 + #endif #endif diff --git a/Marlin/src/pins/ramps/pins_FORMBOT_TREX3.h b/Marlin/src/pins/ramps/pins_FORMBOT_TREX3.h index fd799e0d49..a2cb9a10d2 100644 --- a/Marlin/src/pins/ramps/pins_FORMBOT_TREX3.h +++ b/Marlin/src/pins/ramps/pins_FORMBOT_TREX3.h @@ -182,7 +182,14 @@ #endif #if HAS_MARLINUI_U8GLIB - #define BOARD_ST7920_DELAY_1 125 - #define BOARD_ST7920_DELAY_2 125 - #define BOARD_ST7920_DELAY_3 125 + #ifndef BOARD_ST7920_DELAY_1 + #define BOARD_ST7920_DELAY_1 125 + #endif + #ifndef BOARD_ST7920_DELAY_2 + #define BOARD_ST7920_DELAY_2 125 + #endif + #ifndef BOARD_ST7920_DELAY_3 + #define BOARD_ST7920_DELAY_3 125 + #endif #endif + diff --git a/buildroot/tests/BIGTREE_GTR_V1_0 b/buildroot/tests/BIGTREE_GTR_V1_0 index 9323175986..98406a70f4 100755 --- a/buildroot/tests/BIGTREE_GTR_V1_0 +++ b/buildroot/tests/BIGTREE_GTR_V1_0 @@ -12,8 +12,10 @@ opt_set MOTHERBOARD BOARD_BTT_GTR_V1_0 SERIAL_PORT -1 \ # Not necessary to enable auto-fan for all extruders to hit problematic code paths opt_set E0_AUTO_FAN_PIN PC10 E1_AUTO_FAN_PIN PC11 E2_AUTO_FAN_PIN PC12 NEOPIXEL_PIN PF13 \ X_DRIVER_TYPE TMC2208 Y_DRIVER_TYPE TMC2130 \ - NUM_RUNOUT_SENSORS 8 FIL_RUNOUT_PIN 3 FIL_RUNOUT2_PIN 4 FIL_RUNOUT3_PIN 5 FIL_RUNOUT4_PIN 6 FIL_RUNOUT5_PIN 7 \ - FIL_RUNOUT6_PIN 8 FIL_RUNOUT7_PIN 9 FIL_RUNOUT8_PIN 10 FIL_RUNOUT4_STATE HIGH FIL_RUNOUT8_STATE HIGH \ + FIL_RUNOUT_ENABLED '{ true, true, true, true, true, true, true, true }' \ + FIL_RUNOUT_MODE '{ 1, 1, 1, 1, 1, 1, 1, 1 }' \ + FIL_RUNOUT_DISTANCE_MM '{ 0, 1, 5, 10, 5, 5, 5, 5 }' \ + FIL_RUNOUT_PIN 3 FIL_RUNOUT2_PIN 4 FIL_RUNOUT3_PIN 5 FIL_RUNOUT4_PIN 6 FIL_RUNOUT5_PIN 7 FIL_RUNOUT6_PIN 8 FIL_RUNOUT7_PIN 9 FIL_RUNOUT8_PIN 10 \ FILAMENT_RUNOUT_SCRIPT '"M600 T%c"' opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER BLTOUCH NEOPIXEL_LED Z_SAFE_HOMING NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE \ FILAMENT_RUNOUT_SENSOR FIL_RUNOUT4_PULLUP FIL_RUNOUT8_PULLUP FILAMENT_CHANGE_RESUME_ON_INSERT PAUSE_REHEAT_FAST_RESUME \ diff --git a/buildroot/tests/BIGTREE_GTR_V1_0_usb_flash_drive b/buildroot/tests/BIGTREE_GTR_V1_0_usb_flash_drive index 78aec13295..46264e7db4 100755 --- a/buildroot/tests/BIGTREE_GTR_V1_0_usb_flash_drive +++ b/buildroot/tests/BIGTREE_GTR_V1_0_usb_flash_drive @@ -16,7 +16,7 @@ opt_enable SDSUPPORT USB_FLASH_DRIVE_SUPPORT USE_OTG_USB_HOST \ opt_set E0_AUTO_FAN_PIN PC10 E1_AUTO_FAN_PIN PC11 E2_AUTO_FAN_PIN PC12 NEOPIXEL_PIN PF13 \ X_DRIVER_TYPE TMC2208 Y_DRIVER_TYPE TMC2130 \ FIL_RUNOUT_PIN 3 FIL_RUNOUT2_PIN 4 FIL_RUNOUT3_PIN 5 FIL_RUNOUT4_PIN 6 FIL_RUNOUT5_PIN 7 FIL_RUNOUT6_PIN 8 FIL_RUNOUT7_PIN 9 FIL_RUNOUT8_PIN 10 \ - FIL_RUNOUT4_STATE HIGH FIL_RUNOUT8_STATE HIGH + FIL_RUNOUT_MODE '{ 2, 2, 2, 1, 2, 2, 2, 1 }' FIL_RUNOUT_DISTANCE_MM '{ 0, 1, 5, 10, 5, 5, 5, 5 }' opt_enable FIL_RUNOUT4_PULLUP FIL_RUNOUT8_PULLUP exec_test $1 $2 "GTT GTR | OTG USB Flash Drive | 8 Extruders | Auto-Fan | Mixed TMC Drivers | Runout Sensors (distinct)" "$3" diff --git a/buildroot/tests/DUE b/buildroot/tests/DUE index 590d76606c..695f320831 100755 --- a/buildroot/tests/DUE +++ b/buildroot/tests/DUE @@ -20,7 +20,7 @@ opt_enable S_CURVE_ACCELERATION EEPROM_SETTINGS GCODE_MACROS \ EEPROM_SETTINGS SDSUPPORT BINARY_FILE_TRANSFER \ BLINKM PCA9533 PCA9632 RGB_LED RGB_LED_R_PIN RGB_LED_G_PIN RGB_LED_B_PIN \ NEOPIXEL_LED NEOPIXEL_PIN CASE_LIGHT_ENABLE CASE_LIGHT_USE_NEOPIXEL CASE_LIGHT_USE_RGB_LED CASE_LIGHT_MENU \ - NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE FILAMENT_RUNOUT_DISTANCE_MM FILAMENT_RUNOUT_SENSOR \ + NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE FILAMENT_RUNOUT_SENSOR FIL_RUNOUT_DISTANCE_MM \ AUTO_BED_LEVELING_BILINEAR Z_MIN_PROBE_REPEATABILITY_TEST DEBUG_LEVELING_FEATURE \ SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE CALIBRATION_GCODE \ BACKLASH_COMPENSATION BACKLASH_GCODE BAUD_RATE_GCODE BEZIER_CURVE_SUPPORT \ diff --git a/buildroot/tests/mega2560 b/buildroot/tests/mega2560 index 97d12090c2..0f636621e9 100755 --- a/buildroot/tests/mega2560 +++ b/buildroot/tests/mega2560 @@ -26,14 +26,13 @@ ci_src_filter -y use_example_configs AnimationExample opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO LCD_LANGUAGE fr SAVED_POSITIONS 4 DEFAULT_EJERK 10 \ EXTRUDERS 5 TEMP_SENSOR_1 1 TEMP_SENSOR_2 5 TEMP_SENSOR_3 20 TEMP_SENSOR_4 1000 TEMP_SENSOR_BED 1 -opt_enable AUTO_BED_LEVELING_UBL AVOID_OBSTACLES RESTORE_LEVELING_AFTER_G28 DEBUG_LEVELING_FEATURE G26_MESH_VALIDATION ENABLE_LEVELING_FADE_HEIGHT SKEW_CORRECTION \ +opt_enable AUTO_BED_LEVELING_UBL RESTORE_LEVELING_AFTER_G28 DEBUG_LEVELING_FEATURE G26_MESH_VALIDATION ENABLE_LEVELING_FADE_HEIGHT SKEW_CORRECTION \ REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER LIGHTWEIGHT_UI STATUS_MESSAGE_SCROLLING SHOW_CUSTOM_BOOTSCREEN BOOT_MARLIN_LOGO_SMALL \ SDSUPPORT SDCARD_SORT_ALPHA USB_FLASH_DRIVE_SUPPORT AUTO_REPORT_SD_STATUS SCROLL_LONG_FILENAMES MEDIA_MENU_AT_TOP \ EEPROM_SETTINGS EEPROM_CHITCHAT GCODE_MACROS CUSTOM_MENU_MAIN FREEZE_FEATURE CANCEL_OBJECTS SOUND_MENU_ITEM \ - EMERGENCY_PARSER MULTI_NOZZLE_DUPLICATION CLASSIC_JERK LIN_ADVANCE ADVANCE_K_EXTRA QUICK_HOME \ + MULTI_NOZZLE_DUPLICATION CLASSIC_JERK LIN_ADVANCE ADVANCE_K_EXTRA QUICK_HOME \ SET_PROGRESS_MANUALLY SET_PROGRESS_PERCENT PRINT_PROGRESS_SHOW_DECIMALS SHOW_REMAINING_TIME \ ENCODER_NOISE_FILTER BABYSTEPPING BABYSTEP_XY NANODLP_Z_SYNC I2C_POSITION_ENCODERS M114_DETAIL -opt_disable ENCODER_RATE_MULTIPLIER exec_test $1 $2 "Azteeg X3 Pro | EXTRUDERS 5 | RRDFGSC | UBL | LIN_ADVANCE ..." "$3" # @@ -45,8 +44,7 @@ opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO LCD_LANGUAGE jp_kana DEFAULT_EJERK 10 \ opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER LIGHTWEIGHT_UI SHOW_CUSTOM_BOOTSCREEN BOOT_MARLIN_LOGO_SMALL \ SET_PROGRESS_MANUALLY SET_PROGRESS_PERCENT PRINT_PROGRESS_SHOW_DECIMALS SHOW_REMAINING_TIME STATUS_MESSAGE_SCROLLING SCROLL_LONG_FILENAMES \ SDSUPPORT LONG_FILENAME_WRITE_SUPPORT SDCARD_SORT_ALPHA NO_SD_AUTOSTART USB_FLASH_DRIVE_SUPPORT CANCEL_OBJECTS \ - Z_PROBE_SLED AUTO_BED_LEVELING_UBL UBL_HILBERT_CURVE UBL_TILT_ON_MESH_POINTS UBL_TILT_ON_MESH_POINTS_3POINT \ - RESTORE_LEVELING_AFTER_G28 DEBUG_LEVELING_FEATURE G26_MESH_VALIDATION ENABLE_LEVELING_FADE_HEIGHT \ + Z_PROBE_SLED AUTO_BED_LEVELING_UBL UBL_HILBERT_CURVE RESTORE_LEVELING_AFTER_G28 DEBUG_LEVELING_FEATURE G26_MESH_VALIDATION ENABLE_LEVELING_FADE_HEIGHT \ EEPROM_SETTINGS EEPROM_CHITCHAT GCODE_MACROS CUSTOM_MENU_MAIN \ MULTI_NOZZLE_DUPLICATION CLASSIC_JERK LIN_ADVANCE QUICK_HOME \ NANODLP_Z_SYNC I2C_POSITION_ENCODERS M114_DETAIL \ @@ -55,50 +53,36 @@ opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER LIGHTWEIGHT_UI SHOW_CUS opt_disable SEGMENT_LEVELED_MOVES exec_test $1 $2 "Azteeg X3 Pro | EXTRUDERS 5 | RRDFGSC | UBL | LIN_ADVANCE | Sled Probe | Skew | JP-Kana | Babystep offsets ..." "$3" + # # 5 runout sensors with distinct states # restore_configs opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO NUM_SERVOS 1 \ - EXTRUDERS 4 TEMP_SENSOR_1 1 TEMP_SENSOR_2 1 TEMP_SENSOR_3 1 TEMP_SENSOR_4 1 FAN_KICKSTART_TIME 500 \ - NUM_RUNOUT_SENSORS 4 FIL_RUNOUT2_PIN 44 FIL_RUNOUT3_PIN 45 FIL_RUNOUT4_PIN 46 FIL_RUNOUT5_PIN 47 \ - FIL_RUNOUT3_STATE HIGH FILAMENT_RUNOUT_SCRIPT '"M600 T%c"' + EXTRUDERS 5 TEMP_SENSOR_1 1 TEMP_SENSOR_2 1 TEMP_SENSOR_3 1 TEMP_SENSOR_4 1 \ + NUM_RUNOUT_SENSORS 5 FIL_RUNOUT2_PIN 44 FIL_RUNOUT3_PIN 45 FIL_RUNOUT4_PIN 46 FIL_RUNOUT5_PIN 47 \ + FIL_RUNOUT_ENABLED '{ true, true, true, true, true }' FIL_RUNOUT_MODE '{ 1, 2, 7, 0, 1 }' FIL_RUNOUT_DISTANCE_MM '{ 15, 15, 15, 15, 15 }' opt_enable VIKI2 BOOT_MARLIN_LOGO_ANIMATED SDSUPPORT AUTO_REPORT_SD_STATUS \ - Z_PROBE_SERVO_NR Z_SERVO_ANGLES Z_SERVO_MEASURE_ANGLE DEACTIVATE_SERVOS_AFTER_MOVE Z_SERVO_DEACTIVATE_AFTER_STOW \ - AUTO_BED_LEVELING_3POINT DEBUG_LEVELING_FEATURE PROBE_PT_1 PROBE_PT_2 PROBE_PT_3 \ + Z_PROBE_SERVO_NR Z_SERVO_ANGLES DEACTIVATE_SERVOS_AFTER_MOVE AUTO_BED_LEVELING_3POINT DEBUG_LEVELING_FEATURE \ EEPROM_SETTINGS EEPROM_CHITCHAT M114_DETAIL AUTO_REPORT_POSITION \ NO_VOLUMETRICS EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES AUTOTEMP G38_PROBE_TARGET JOYSTICK \ DIRECT_STEPPING DETECT_BROKEN_ENDSTOP \ FILAMENT_RUNOUT_SENSOR NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE Z_SAFE_HOMING FIL_RUNOUT3_PULLUP -exec_test $1 $2 "Azteeg X3 Pro | EXTRUDERS 4 | VIKI2 | Servo Probe | Multiple runout sensors (x4)" "$3" +exec_test $1 $2 "Multiple runout sensors (x5) | Distinct runout states" "$3" + # -# Extruder Only. No XYZ axes at all. +# Mixing Extruder with 5 steppers, Greek # restore_configs -opt_set DEFAULT_AXIS_STEPS_PER_UNIT '{ 4000 }' \ - DEFAULT_MAX_FEEDRATE '{ 5 }' \ - DEFAULT_MAX_ACCELERATION '{ 100 }' \ - MANUAL_FEEDRATE '{ 4*60 }' \ - AXIS_RELATIVE_MODES '{ false }' \ - HOMING_BUMP_MM '{}' HOMING_BUMP_DIVISOR '{}' HOMING_FEEDRATE_MM_M '{}' -opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER -opt_disable X_DRIVER_TYPE Y_DRIVER_TYPE Z_DRIVER_TYPE -exec_test $1 $2 "E Axis Only | DOGM MarlinUI" "$3" - -# -# Mixing Extruder with 5 steppers, Russian -# -restore_configs -opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO MIXING_STEPPERS 5 LCD_LANGUAGE ru \ - NUM_RUNOUT_SENSORS E_STEPPERS TEMP_SENSOR_BED 0 REDUNDANT_PART_COOLING_FAN 1 \ - FIL_RUNOUT2_PIN 16 FIL_RUNOUT3_PIN 17 FIL_RUNOUT4_PIN 4 FIL_RUNOUT5_PIN 5 +opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO MIXING_STEPPERS 5 LCD_LANGUAGE ru REDUNDANT_PART_COOLING_FAN 1 \ + FIL_RUNOUT2_PIN 16 FIL_RUNOUT3_PIN 17 FIL_RUNOUT4_PIN 4 FIL_RUNOUT5_PIN 5 \ + FIL_RUNOUT_ENABLED '{ true, true, true, true, true }' FIL_RUNOUT_MODE '{ 1, 2, 7, 0, 1 }' FIL_RUNOUT_DISTANCE_MM '{ 15, 15, 15, 15, 15 }' opt_enable MIXING_EXTRUDER GRADIENT_MIX GRADIENT_VTOOL CR10_STOCKDISPLAY \ USE_CONTROLLER_FAN CONTROLLER_FAN_EDITABLE CONTROLLER_FAN_IGNORE_Z \ - XY_AFTER_HOMING EVENT_GCODE_AFTER_HOMING \ - FILAMENT_RUNOUT_SENSOR ADVANCED_PAUSE_FEATURE NOZZLE_PARK_FEATURE INPUT_SHAPING_X INPUT_SHAPING_Y -opt_disable DISABLE_OTHER_EXTRUDERS -exec_test $1 $2 "Azteeg X3 | Mixing Extruder (x5) | Gradient Mix | Input Shaping | Russian" "$3" + FILAMENT_RUNOUT_SENSOR ADVANCED_PAUSE_FEATURE NOZZLE_PARK_FEATURE +opt_disable DISABLE_INACTIVE_EXTRUDER +exec_test $1 $2 "Azteeg X3 | Mixing Extruder (x5) | Gradient Mix | Greek" "$3" # # Test SPEAKER with BOARD_BQ_ZUM_MEGA_3D and BQ_LCD_SMART_CONTROLLER @@ -142,7 +126,7 @@ exec_test $1 $2 "Azteeg X3 | Mixing Extruder (x5) | Gradient Mix | Input Shaping #opt_set MOTHERBOARD BOARD_RIGIDBOARD_V2 #opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT BABYSTEPPING DAC_MOTOR_CURRENT_DEFAULT #exec_test $1 $2 "Stuff" "$3" -# +# # # G3D_PANEL with SDCARD_SORT_ALPHA and STATUS_MESSAGE_SCROLLING # #restore_configs @@ -193,9 +177,9 @@ exec_test $1 $2 "Azteeg X3 | Mixing Extruder (x5) | Gradient Mix | Input Shaping #opt_enable LCM1602 #exec_test $1 $2 "Stuff" "$3" -# -# Test Laser features with 12864 LCD -# +# # +# # Test Laser features with 12864 LCD +# # # restore_configs # opt_set MOTHERBOARD BOARD_RAMPS_14_EFB EXTRUDERS 0 LCD_LANGUAGE en TEMP_SENSOR_COOLER 1 TEMP_SENSOR_1 0 SERIAL_PORT_2 2 \ # DEFAULT_AXIS_STEPS_PER_UNIT '{ 80, 80, 400 }' \ @@ -207,9 +191,9 @@ exec_test $1 $2 "Azteeg X3 | Mixing Extruder (x5) | Gradient Mix | Input Shaping # LASER_FEATURE LASER_SAFETY_TIMEOUT_MS LASER_COOLANT_FLOW_METER AIR_EVACUATION AIR_EVACUATION_PIN AIR_ASSIST AIR_ASSIST_PIN LASER_SYNCHRONOUS_M106_M107 # exec_test $1 $2 "MEGA2560 RAMPS | Laser Options | 12864 | Meatpack | Fan Sync | SERIAL_PORT_2 " "$3" -# -# Test Laser features with 44780 LCD -# +# # +# # Test Laser features with 44780 LCD +# # # restore_configs # opt_set MOTHERBOARD BOARD_RAMPS_14_EFB EXTRUDERS 0 LCD_LANGUAGE en TEMP_SENSOR_COOLER 1 TEMP_SENSOR_1 0 \ # DEFAULT_AXIS_STEPS_PER_UNIT '{ 80, 80, 400 }' \ @@ -221,9 +205,9 @@ exec_test $1 $2 "Azteeg X3 | Mixing Extruder (x5) | Gradient Mix | Input Shaping # LASER_FEATURE LASER_SAFETY_TIMEOUT_MS LASER_COOLANT_FLOW_METER AIR_EVACUATION AIR_EVACUATION_PIN AIR_ASSIST AIR_ASSIST_PIN # exec_test $1 $2 "MEGA2560 RAMPS | Laser Feature | Air Evacuation | Air Assist | Cooler | Laser Safety Timeout | Flowmeter | 44780 LCD " "$3" -# -# Test redundant temperature sensors + MAX TC + Backlight Timeout -# +# # +# # Test redundant temperature sensors + MAX TC + Backlight Timeout +# # # restore_configs # opt_set MOTHERBOARD BOARD_RAMPS_14_EFB EXTRUDERS 1 \ # TEMP_SENSOR_0 -2 TEMP_SENSOR_REDUNDANT -2 \ @@ -234,9 +218,9 @@ exec_test $1 $2 "Azteeg X3 | Mixing Extruder (x5) | Gradient Mix | Input Shaping # opt_disable PIDTEMP # exec_test $1 $2 "MEGA2560 RAMPS | Redundant temperature sensor | 2x MAX6675 | BL Timeout" "$3" -# -# Polargraph Config -# +# # +# # Polargraph Config +# # # use_example_configs Polargraph # exec_test $1 $2 "RUMBA | POLARGRAPH | RRD LCD" "$3" @@ -284,12 +268,12 @@ opt_set MOTHERBOARD BOARD_RAMPS_14_EFB opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER \ SET_PROGRESS_MANUALLY SET_PROGRESS_PERCENT SET_REMAINING_TIME SET_INTERACTION_TIME M73_REPORT \ SHOW_PROGRESS_PERCENT SHOW_ELAPSED_TIME SHOW_REMAINING_TIME SHOW_INTERACTION_TIME PRINT_PROGRESS_SHOW_DECIMALS -exec_test $1 $2 "MEGA2560 RAMPS | 128x64 | progress rotation" "$3" +exec_test $1 $2 "MEGA2560 RAMPS | 12864 | progress rotation" "$3" opt_enable LIGHTWEIGHT_UI -exec_test $1 $2 "MEGA2560 RAMPS | 128x64 LIGHTWEIGHT_UI | progress rotation" "$3" +exec_test $1 $2 "MEGA2560 RAMPS | 12864 LIGHTWEIGHT_UI | progress rotation" "$3" opt_disable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER -exec_test $1 $2 "MEGA2560 RAMPS | HD44780 | progress rotation" "$3" +exec_test $1 $2 "MEGA2560 RAMPS | 44780 | progress rotation" "$3" # clean up restore_configs