From a7444021c6d31c554cb22e1062f72033e5f21c61 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Thu, 20 Jun 2024 12:42:26 -0500 Subject: [PATCH 01/24] =?UTF-8?q?=F0=9F=94=A8=20Fatal=20error=20for=20wron?= =?UTF-8?q?g=20GCC=20on=20macOS=20Native=20Sim?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../share/PlatformIO/scripts/simulator.py | 58 ++++++++++++------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/buildroot/share/PlatformIO/scripts/simulator.py b/buildroot/share/PlatformIO/scripts/simulator.py index 4276a2593ef1..2b30ec32c0b5 100644 --- a/buildroot/share/PlatformIO/scripts/simulator.py +++ b/buildroot/share/PlatformIO/scripts/simulator.py @@ -17,37 +17,53 @@ env['PROGNAME'] = "MarlinSimulator" # - # If Xcode is installed add the path to its Frameworks folder, - # or if Mesa is installed try to use its GL/gl.h. + # Check for a valid GCC and available OpenGL on macOS # - + emsg = '' + fatal = 0 import sys if sys.platform == 'darwin': - # - # Silence half of the ranlib warnings. (No equivalent for 'ARFLAGS') - # - env['RANLIBFLAGS'] += [ "-no_warning_for_no_symbols" ] + import shutil + gcc = shutil.which('gcc') + if gcc == '' or gcc == '/usr/bin/gcc': + if gcc == '': + emsg = "\u001b[31mNo GCC found in your configured shell PATH." + elif gcc == '/usr/bin/gcc': + emsg = "\u001b[31mCan't build Marlin Native on macOS using the included version of GCC (clang)." + emsg += "\n\u001b[31mSee 'native.ini' for instructions to install GCC with MacPorts or Homebrew." + fatal = 1 - # Default paths for Xcode and a lucky GL/gl.h dropped by Mesa - xcode_path = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks" - mesa_path = "/opt/local/include/GL/gl.h" + else: - import os.path + # + # Silence half of the ranlib warnings. (No equivalent for 'ARFLAGS') + # + env['RANLIBFLAGS'] += [ "-no_warning_for_no_symbols" ] - if os.path.exists(xcode_path): + # Default paths for Xcode and a lucky GL/gl.h dropped by Mesa + xcode_path = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks" + mesa_path = "/opt/local/include/GL/gl.h" - env['BUILD_FLAGS'] += [ "-F" + xcode_path ] - print("Using OpenGL framework headers from Xcode.app") + import os.path - elif os.path.exists(mesa_path): + if os.path.exists(xcode_path): - env['BUILD_FLAGS'] += [ '-D__MESA__' ] - print("Using OpenGL header from", mesa_path) + env['BUILD_FLAGS'] += [ "-F" + xcode_path ] + emsg = "\u001b[33mUsing OpenGL framework headers from Xcode.app" - else: + elif os.path.exists(mesa_path): + + env['BUILD_FLAGS'] += [ '-D__MESA__' ] + emsg = f"\u001b[33mUsing OpenGL header from {mesa_path}" + + else: + + emsg = "\u001b[31mNo OpenGL headers found. Install Xcode for matching headers, or use 'sudo port install mesa' to get a GL/gl.h." + fatal = 1 - print("\n\nNo OpenGL headers found. Install Xcode for matching headers, or use 'sudo port install mesa' to get a GL/gl.h.\n\n") + # Print error message, if any + if emsg: print(f"\n\n{emsg}\n\n") - # Break out of the PIO build immediately - sys.exit(1) + # Break out of the PIO build immediately + if fatal: sys.exit(1) From b3d462b890b4a54b710e7b00f284ba7ac5294bb0 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Thu, 20 Jun 2024 18:07:46 +0000 Subject: [PATCH 02/24] [cron] Bump distribution date (2024-06-20) --- Marlin/Version.h | 2 +- Marlin/src/inc/Version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/Version.h b/Marlin/Version.h index 65453dfc7a89..46845471f37c 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -41,7 +41,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2024-06-17" +//#define STRING_DISTRIBUTION_DATE "2024-06-20" /** * Defines a generic printer name to be output to the LCD after booting Marlin. diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index fe8523b74590..be9f0a926dd9 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2024-06-17" + #define STRING_DISTRIBUTION_DATE "2024-06-20" #endif /** From 6d7d28155981c0a1617fe00ea8ccd4049ba55aa5 Mon Sep 17 00:00:00 2001 From: Keith Bennett <13375512+thisiskeithb@users.noreply.github.com> Date: Fri, 21 Jun 2024 17:30:29 -0700 Subject: [PATCH 03/24] =?UTF-8?q?=F0=9F=94=A7=20Warning=20for=20ZV=20Shapi?= =?UTF-8?q?ng=20on=20CoreQZ=20(#27200)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/inc/Warnings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/inc/Warnings.cpp b/Marlin/src/inc/Warnings.cpp index 8fc775d4c21a..8f7a31ffb457 100644 --- a/Marlin/src/inc/Warnings.cpp +++ b/Marlin/src/inc/Warnings.cpp @@ -789,7 +789,7 @@ * Input Shaping */ #if HAS_ZV_SHAPING - #if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) + #if ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX) #warning "Input Shaping for CORE / MARKFORGED kinematic axes is still experimental." #endif #if ENABLED(I2S_STEPPER_STREAM) From 60d843b540fdc886767180e62c4a1f0d33a27f3e Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Sat, 22 Jun 2024 06:07:24 +0000 Subject: [PATCH 04/24] [cron] Bump distribution date (2024-06-22) --- Marlin/Version.h | 2 +- Marlin/src/inc/Version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/Version.h b/Marlin/Version.h index 46845471f37c..1df0756b8014 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -41,7 +41,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2024-06-20" +//#define STRING_DISTRIBUTION_DATE "2024-06-22" /** * Defines a generic printer name to be output to the LCD after booting Marlin. diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index be9f0a926dd9..c459a12bcf2a 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2024-06-20" + #define STRING_DISTRIBUTION_DATE "2024-06-22" #endif /** From f2248f79d3c4a3649bd9a4b9d6abab0f94e4af94 Mon Sep 17 00:00:00 2001 From: Jonathan Brazier <66009857+JonBr306@users.noreply.github.com> Date: Mon, 24 Jun 2024 20:52:49 +0100 Subject: [PATCH 05/24] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20Implement=20CALIBRAT?= =?UTF-8?q?ION=5FGCODE=20as=20endstop=20(#27204)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/Configuration_adv.h | 2 - Marlin/src/HAL/AVR/endstop_interrupts.h | 8 ++++ Marlin/src/HAL/DUE/endstop_interrupts.h | 1 + Marlin/src/HAL/ESP32/endstop_interrupts.h | 1 + Marlin/src/HAL/HC32/endstop_interrupts.cpp | 4 +- Marlin/src/HAL/LPC1768/endstop_interrupts.h | 6 +++ Marlin/src/HAL/SAMD21/endstop_interrupts.h | 10 +++- Marlin/src/HAL/SAMD51/endstop_interrupts.h | 10 +++- Marlin/src/HAL/STM32/endstop_interrupts.h | 1 + Marlin/src/HAL/STM32F1/endstop_interrupts.h | 1 + .../src/HAL/TEENSY31_32/endstop_interrupts.h | 1 + .../src/HAL/TEENSY35_36/endstop_interrupts.h | 1 + .../src/HAL/TEENSY40_41/endstop_interrupts.h | 1 + Marlin/src/core/language.h | 2 + Marlin/src/gcode/calibrate/G425.cpp | 30 ++++-------- Marlin/src/inc/Changes.h | 2 + Marlin/src/inc/Conditionals_post.h | 5 ++ Marlin/src/module/endstops.cpp | 46 ++++++++++++++++++- Marlin/src/module/endstops.h | 14 +++++- 19 files changed, 116 insertions(+), 30 deletions(-) diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 6cac4e5d498b..812310dcfc9e 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -1331,8 +1331,6 @@ //#define CALIBRATION_SCRIPT_PRE "M117 Starting Auto-Calibration\nT0\nG28\nG12\nM117 Calibrating..." //#define CALIBRATION_SCRIPT_POST "M500\nM117 Calibration data saved" - #define CALIBRATION_MEASUREMENT_RESOLUTION 0.01 // mm - #define CALIBRATION_FEEDRATE_SLOW 60 // mm/min #define CALIBRATION_FEEDRATE_FAST 1200 // mm/min #define CALIBRATION_FEEDRATE_TRAVEL 3000 // mm/min diff --git a/Marlin/src/HAL/AVR/endstop_interrupts.h b/Marlin/src/HAL/AVR/endstop_interrupts.h index 91cb336e2462..a6813ff27752 100644 --- a/Marlin/src/HAL/AVR/endstop_interrupts.h +++ b/Marlin/src/HAL/AVR/endstop_interrupts.h @@ -345,6 +345,14 @@ void setup_endstop_interrupts() { pciSetup(Z_MIN_PROBE_PIN); #endif #endif + #if USE_CALIBRATION + #if (digitalPinToInterrupt(CALIBRATION_PIN) != NOT_AN_INTERRUPT) + _ATTACH(CALIBRATION_PIN); + #else + static_assert(digitalPinHasPCICR(CALIBRATION_PIN), "CALIBRATION_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."); + pciSetup(CALIBRATION_PIN); + #endif + #endif // If we arrive here without raising an assertion, each pin has either an EXT-interrupt or a PCI. } diff --git a/Marlin/src/HAL/DUE/endstop_interrupts.h b/Marlin/src/HAL/DUE/endstop_interrupts.h index 954eb625a575..798ca4f0cbf7 100644 --- a/Marlin/src/HAL/DUE/endstop_interrupts.h +++ b/Marlin/src/HAL/DUE/endstop_interrupts.h @@ -64,6 +64,7 @@ void setup_endstop_interrupts() { TERN_(USE_Z4_MAX, _ATTACH(Z4_MAX_PIN)); TERN_(USE_Z4_MIN, _ATTACH(Z4_MIN_PIN)); TERN_(USE_Z_MIN_PROBE, _ATTACH(Z_MIN_PROBE_PIN)); + TERN_(USE_CALIBRATION, _ATTACH(CALIBRATION_PIN)); TERN_(USE_I_MAX, _ATTACH(I_MAX_PIN)); TERN_(USE_I_MIN, _ATTACH(I_MIN_PIN)); TERN_(USE_J_MAX, _ATTACH(J_MAX_PIN)); diff --git a/Marlin/src/HAL/ESP32/endstop_interrupts.h b/Marlin/src/HAL/ESP32/endstop_interrupts.h index 137734599295..8b88f1f41f33 100644 --- a/Marlin/src/HAL/ESP32/endstop_interrupts.h +++ b/Marlin/src/HAL/ESP32/endstop_interrupts.h @@ -59,6 +59,7 @@ void setup_endstop_interrupts() { TERN_(USE_Z4_MAX, _ATTACH(Z4_MAX_PIN)); TERN_(USE_Z4_MIN, _ATTACH(Z4_MIN_PIN)); TERN_(USE_Z_MIN_PROBE, _ATTACH(Z_MIN_PROBE_PIN)); + TERN_(USE_CALIBRATION, _ATTACH(CALIBRATION_PIN)); TERN_(USE_I_MAX, _ATTACH(I_MAX_PIN)); TERN_(USE_I_MIN, _ATTACH(I_MIN_PIN)); TERN_(USE_J_MAX, _ATTACH(J_MAX_PIN)); diff --git a/Marlin/src/HAL/HC32/endstop_interrupts.cpp b/Marlin/src/HAL/HC32/endstop_interrupts.cpp index 99987ec76f5b..06c4d0e1867d 100644 --- a/Marlin/src/HAL/HC32/endstop_interrupts.cpp +++ b/Marlin/src/HAL/HC32/endstop_interrupts.cpp @@ -101,12 +101,14 @@ void setup_endstop_interrupts() { SETUP(Z_MIN_PROBE); + SETUP(CALIBRATION); + #undef SETUP } // Ensure 1 - 10 IRQs are registered // Disable some endstops if you encounter this error -#define ENDSTOPS_INTERRUPTS_COUNT COUNT_ENABLED(USE_X_MAX, USE_X_MIN, USE_X2_MAX, USE_X2_MIN, USE_Y_MAX, USE_Y_MIN, USE_Y2_MAX, USE_Y2_MIN, USE_Z_MAX, USE_Z_MIN, USE_Z2_MAX, USE_Z2_MIN, USE_Z3_MAX, USE_Z3_MIN, USE_Z4_MAX, USE_Z4_MIN, USE_Z_MIN_PROBE) +#define ENDSTOPS_INTERRUPTS_COUNT COUNT_ENABLED(USE_X_MAX, USE_X_MIN, USE_X2_MAX, USE_X2_MIN, USE_Y_MAX, USE_Y_MIN, USE_Y2_MAX, USE_Y2_MIN, USE_Z_MAX, USE_Z_MIN, USE_Z2_MAX, USE_Z2_MIN, USE_Z3_MAX, USE_Z3_MIN, USE_Z4_MAX, USE_Z4_MIN, USE_Z_MIN_PROBE, USE_CALIBRATION) #if ENDSTOPS_INTERRUPTS_COUNT > 10 #error "Too many endstop interrupts! HC32F460 only supports 10 endstop interrupts." #elif ENDSTOPS_INTERRUPTS_COUNT == 0 diff --git a/Marlin/src/HAL/LPC1768/endstop_interrupts.h b/Marlin/src/HAL/LPC1768/endstop_interrupts.h index 7a67b958b441..2c75fe6986cc 100644 --- a/Marlin/src/HAL/LPC1768/endstop_interrupts.h +++ b/Marlin/src/HAL/LPC1768/endstop_interrupts.h @@ -146,6 +146,12 @@ void setup_endstop_interrupts() { #endif _ATTACH(Z_MIN_PROBE_PIN); #endif + #if USE_CALIBRATION + #if !LPC1768_PIN_INTERRUPT_M(CALIBRATION_PIN) + #error "CALIBRATION_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." + #endif + _ATTACH(CALIBRATION_PIN); + #endif #if USE_I_MAX #if !LPC1768_PIN_INTERRUPT_M(I_MAX_PIN) #error "I_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." diff --git a/Marlin/src/HAL/SAMD21/endstop_interrupts.h b/Marlin/src/HAL/SAMD21/endstop_interrupts.h index 37fdb7504b58..4ef075f8f9d1 100644 --- a/Marlin/src/HAL/SAMD21/endstop_interrupts.h +++ b/Marlin/src/HAL/SAMD21/endstop_interrupts.h @@ -83,6 +83,7 @@ #define MATCH_Z4_MAX_EILINE(P) TERN0(USE_Z4_MAX, DEFER4(MATCH_EILINE)(P, Z4_MAX_PIN)) #define MATCH_Z4_MIN_EILINE(P) TERN0(USE_Z4_MIN, DEFER4(MATCH_EILINE)(P, Z4_MIN_PIN)) #define MATCH_Z_MIN_PROBE_EILINE(P) TERN0(USE_Z_MIN_PROBE, DEFER4(MATCH_EILINE)(P, Z_MIN_PROBE_PIN)) +#define MATCH_CALIBRATION_EILINE(P) TERN0(USE_CALIBRATION, DEFER4(MATCH_EILINE)(P, CALIBRATION_PIN)) #define AVAILABLE_EILINE(P) ( PIN_TO_EILINE(P) != -1 \ && !MATCH_X_MAX_EILINE(P) && !MATCH_X_MIN_EILINE(P) \ @@ -99,7 +100,8 @@ && !MATCH_Z2_MAX_EILINE(P) && !MATCH_Z2_MIN_EILINE(P) \ && !MATCH_Z3_MAX_EILINE(P) && !MATCH_Z3_MIN_EILINE(P) \ && !MATCH_Z4_MAX_EILINE(P) && !MATCH_Z4_MIN_EILINE(P) \ - && !MATCH_Z_MIN_PROBE_EILINE(P) ) + && !MATCH_Z_MIN_PROBE_EILINE(P) \ + && !MATCH_CALIBRATION_EILINE(P) ) // One ISR for all EXT-Interrupts void endstop_ISR() { endstops.update(); } @@ -208,6 +210,12 @@ void setup_endstop_interrupts() { #endif _ATTACH(Z_MIN_PROBE_PIN); #endif + #if USE_CALIBRATION + #if !AVAILABLE_EILINE(CALIBRATION_PIN) + #error "CALIBRATION_PIN has no EXTINT line available. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." + #endif + _ATTACH(CALIBRATION_PIN); + #endif #if USE_I_MAX #if !AVAILABLE_EILINE(I_MAX_PIN) #error "I_MAX_PIN has no EXTINT line available. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." diff --git a/Marlin/src/HAL/SAMD51/endstop_interrupts.h b/Marlin/src/HAL/SAMD51/endstop_interrupts.h index 84b6c46da985..34c238ba5c77 100644 --- a/Marlin/src/HAL/SAMD51/endstop_interrupts.h +++ b/Marlin/src/HAL/SAMD51/endstop_interrupts.h @@ -82,6 +82,7 @@ #define MATCH_Z4_MAX_EILINE(P) TERN0(USE_Z4_MAX, DEFER4(MATCH_EILINE)(P, Z4_MAX_PIN)) #define MATCH_Z4_MIN_EILINE(P) TERN0(USE_Z4_MIN, DEFER4(MATCH_EILINE)(P, Z4_MIN_PIN)) #define MATCH_Z_MIN_PROBE_EILINE(P) TERN0(USE_Z_MIN_PROBE, DEFER4(MATCH_EILINE)(P, Z_MIN_PROBE_PIN)) +#define MATCH_CALIBRATION_EILINE(P) TERN0(USE_CALIBRATION, DEFER4(MATCH_EILINE)(P, CALIBRATION_PIN)) #define AVAILABLE_EILINE(P) ( PIN_TO_EILINE(P) != -1 \ && !MATCH_X_MAX_EILINE(P) && !MATCH_X_MIN_EILINE(P) \ @@ -98,7 +99,8 @@ && !MATCH_Z2_MAX_EILINE(P) && !MATCH_Z2_MIN_EILINE(P) \ && !MATCH_Z3_MAX_EILINE(P) && !MATCH_Z3_MIN_EILINE(P) \ && !MATCH_Z4_MAX_EILINE(P) && !MATCH_Z4_MIN_EILINE(P) \ - && !MATCH_Z_MIN_PROBE_EILINE(P) ) + && !MATCH_Z_MIN_PROBE_EILINE(P) \ + && !MATCH_CALIBRATION_EILINE(P) ) // One ISR for all EXT-Interrupts void endstop_ISR() { endstops.update(); } @@ -183,6 +185,12 @@ void setup_endstop_interrupts() { #endif _ATTACH(Z_MIN_PROBE_PIN); #endif + #if USE_CALIBRATION + #if !AVAILABLE_EILINE(CALIBRATION_PIN) + #error "CALIBRATION_PIN has no EXTINT line available. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." + #endif + _ATTACH(CALIBRATION_PIN); + #endif #if USE_I_MAX #if !AVAILABLE_EILINE(I_MAX_PIN) #error "I_MAX_PIN has no EXTINT line available. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." diff --git a/Marlin/src/HAL/STM32/endstop_interrupts.h b/Marlin/src/HAL/STM32/endstop_interrupts.h index ab86bf29c220..e17b8a4c8ea3 100644 --- a/Marlin/src/HAL/STM32/endstop_interrupts.h +++ b/Marlin/src/HAL/STM32/endstop_interrupts.h @@ -45,6 +45,7 @@ void setup_endstop_interrupts() { TERN_(USE_Z4_MAX, _ATTACH(Z4_MAX_PIN)); TERN_(USE_Z4_MIN, _ATTACH(Z4_MIN_PIN)); TERN_(USE_Z_MIN_PROBE, _ATTACH(Z_MIN_PROBE_PIN)); + TERN_(USE_CALIBRATION, _ATTACH(CALIBRATION_PIN)); TERN_(USE_I_MAX, _ATTACH(I_MAX_PIN)); TERN_(USE_I_MIN, _ATTACH(I_MIN_PIN)); TERN_(USE_J_MAX, _ATTACH(J_MAX_PIN)); diff --git a/Marlin/src/HAL/STM32F1/endstop_interrupts.h b/Marlin/src/HAL/STM32F1/endstop_interrupts.h index d11b3bf50503..6724bf34564c 100644 --- a/Marlin/src/HAL/STM32F1/endstop_interrupts.h +++ b/Marlin/src/HAL/STM32F1/endstop_interrupts.h @@ -70,6 +70,7 @@ void setup_endstop_interrupts() { TERN_(USE_Z4_MAX, _ATTACH(Z4_MAX_PIN)); TERN_(USE_Z4_MIN, _ATTACH(Z4_MIN_PIN)); TERN_(USE_Z_MIN_PROBE, _ATTACH(Z_MIN_PROBE_PIN)); + TERN_(USE_CALIBRATION, _ATTACH(CALIBRATION_PIN)); TERN_(USE_I_MAX, _ATTACH(I_MAX_PIN)); TERN_(USE_I_MIN, _ATTACH(I_MIN_PIN)); TERN_(USE_J_MAX, _ATTACH(J_MAX_PIN)); diff --git a/Marlin/src/HAL/TEENSY31_32/endstop_interrupts.h b/Marlin/src/HAL/TEENSY31_32/endstop_interrupts.h index 954eb625a575..798ca4f0cbf7 100644 --- a/Marlin/src/HAL/TEENSY31_32/endstop_interrupts.h +++ b/Marlin/src/HAL/TEENSY31_32/endstop_interrupts.h @@ -64,6 +64,7 @@ void setup_endstop_interrupts() { TERN_(USE_Z4_MAX, _ATTACH(Z4_MAX_PIN)); TERN_(USE_Z4_MIN, _ATTACH(Z4_MIN_PIN)); TERN_(USE_Z_MIN_PROBE, _ATTACH(Z_MIN_PROBE_PIN)); + TERN_(USE_CALIBRATION, _ATTACH(CALIBRATION_PIN)); TERN_(USE_I_MAX, _ATTACH(I_MAX_PIN)); TERN_(USE_I_MIN, _ATTACH(I_MIN_PIN)); TERN_(USE_J_MAX, _ATTACH(J_MAX_PIN)); diff --git a/Marlin/src/HAL/TEENSY35_36/endstop_interrupts.h b/Marlin/src/HAL/TEENSY35_36/endstop_interrupts.h index bc8e177fb7dc..a938041b5abd 100644 --- a/Marlin/src/HAL/TEENSY35_36/endstop_interrupts.h +++ b/Marlin/src/HAL/TEENSY35_36/endstop_interrupts.h @@ -63,6 +63,7 @@ void setup_endstop_interrupts() { TERN_(USE_Z4_MAX, _ATTACH(Z4_MAX_PIN)); TERN_(USE_Z4_MIN, _ATTACH(Z4_MIN_PIN)); TERN_(USE_Z_MIN_PROBE, _ATTACH(Z_MIN_PROBE_PIN)); + TERN_(USE_CALIBRATION, _ATTACH(CALIBRATION_PIN)); TERN_(USE_I_MAX, _ATTACH(I_MAX_PIN)); TERN_(USE_I_MIN, _ATTACH(I_MIN_PIN)); TERN_(USE_J_MAX, _ATTACH(J_MAX_PIN)); diff --git a/Marlin/src/HAL/TEENSY40_41/endstop_interrupts.h b/Marlin/src/HAL/TEENSY40_41/endstop_interrupts.h index 722912c89056..f59a9409c872 100644 --- a/Marlin/src/HAL/TEENSY40_41/endstop_interrupts.h +++ b/Marlin/src/HAL/TEENSY40_41/endstop_interrupts.h @@ -63,6 +63,7 @@ void setup_endstop_interrupts() { TERN_(USE_Z4_MAX, _ATTACH(Z4_MAX_PIN)); TERN_(USE_Z4_MIN, _ATTACH(Z4_MIN_PIN)); TERN_(USE_Z_MIN_PROBE, _ATTACH(Z_MIN_PROBE_PIN)); + TERN_(USE_CALIBRATION, _ATTACH(CALIBRATION_PIN)); TERN_(USE_I_MAX, _ATTACH(I_MAX_PIN)); TERN_(USE_I_MIN, _ATTACH(I_MIN_PIN)); TERN_(USE_J_MAX, _ATTACH(J_MAX_PIN)); diff --git a/Marlin/src/core/language.h b/Marlin/src/core/language.h index ad84966453f1..9d2cdca897e7 100644 --- a/Marlin/src/core/language.h +++ b/Marlin/src/core/language.h @@ -355,6 +355,8 @@ #define STR_PROBE_EN "probe_en" #define STR_FILAMENT "filament" +#define STR_CALIBRATION "calibration" + // General axis names #define STR_X "X" #define STR_Y "Y" diff --git a/Marlin/src/gcode/calibrate/G425.cpp b/Marlin/src/gcode/calibrate/G425.cpp index 992d7c38e621..ad17b2e106ba 100644 --- a/Marlin/src/gcode/calibrate/G425.cpp +++ b/Marlin/src/gcode/calibrate/G425.cpp @@ -181,20 +181,6 @@ inline void park_above_object(measurements_t &m, const float uncertainty) { #endif -#if !PIN_EXISTS(CALIBRATION) - #include "../../module/probe.h" -#endif - -inline bool read_calibration_pin() { - return ( - #if PIN_EXISTS(CALIBRATION) - READ(CALIBRATION_PIN) != CALIBRATION_PIN_INVERTING - #else - PROBE_TRIGGERED() - #endif - ); -} - /** * Move along axis in the specified dir until the probe value becomes stop_state, * then return the axis value. @@ -205,18 +191,18 @@ inline bool read_calibration_pin() { * fast in - Fast vs. precise measurement */ float measuring_movement(const AxisEnum axis, const int dir, const bool stop_state, const bool fast) { - const float step = fast ? 0.25 : CALIBRATION_MEASUREMENT_RESOLUTION; const feedRate_t mms = fast ? MMM_TO_MMS(CALIBRATION_FEEDRATE_FAST) : MMM_TO_MMS(CALIBRATION_FEEDRATE_SLOW); const float limit = fast ? 50 : 5; destination = current_position; - for (float travel = 0; travel < limit; travel += step) { - destination[axis] += dir * step; - do_blocking_move_to((xyz_pos_t)destination, mms); - planner.synchronize(); - if (read_calibration_pin() == stop_state) break; - } - return destination[axis]; + destination[axis] += dir * limit; + endstops.enable_calibration_probe(true, stop_state); + do_blocking_move_to((xyz_pos_t)destination, mms); + endstops.enable_calibration_probe(false); + endstops.hit_on_purpose(); + set_current_from_steppers_for_axis(axis); + sync_plan_position(); + return current_position[axis]; } /** diff --git a/Marlin/src/inc/Changes.h b/Marlin/src/inc/Changes.h index 8c45edccbeeb..a5319e46544b 100644 --- a/Marlin/src/inc/Changes.h +++ b/Marlin/src/inc/Changes.h @@ -697,6 +697,8 @@ #error "Z_PROBE_END_SCRIPT is now EVENT_GCODE_AFTER_G29." #elif defined(WIFI_SERIAL) #error "WIFI_SERIAL is now WIFI_SERIAL_PORT." +#elif defined(CALIBRATION_MEASUREMENT_RESOLUTION) + #error "CALIBRATION_MEASUREMENT_RESOLUTION is no longer needed and should be removed." #endif // Changes to Probe Temp Compensation (#17392) diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index 8446a1acf05d..d43132e13c82 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -2200,6 +2200,11 @@ #define HAS_Z_PROBE_STATE 1 #endif +#if PIN_EXISTS(CALIBRATION) + #define USE_CALIBRATION 1 + #define HAS_CALIBRATION_STATE 1 +#endif + #undef _ANY_STOP #undef _USE_STOP #undef _HAS_STATE diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index 33565f7f5d85..e7786749b5fc 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -87,6 +87,11 @@ Endstops::endstop_mask_t Endstops::live_state = 0; volatile bool Endstops::z_probe_enabled = false; #endif +#if ENABLED(CALIBRATION_GCODE) + volatile bool Endstops::calibration_probe_enabled = false; + volatile bool Endstops::calibration_stop_state; +#endif + // Initialized by settings.load() #if ENABLED(X_DUAL_ENDSTOPS) float Endstops::x2_endstop_adj; @@ -203,7 +208,7 @@ void Endstops::init() { _INIT_ENDSTOP(MAX,W,); #endif - #if PIN_EXISTS(CALIBRATION) + #if USE_CALIBRATION #if ENABLED(CALIBRATION_PIN_PULLUP) SET_INPUT_PULLUP(CALIBRATION_PIN); #elif ENABLED(CALIBRATION_PIN_PULLDOWN) @@ -283,6 +288,17 @@ void Endstops::not_homing() { } #endif +// Enable / disable calibration probe checking +#if ENABLED(CALIBRATION_GCODE) + void Endstops::enable_calibration_probe(const bool onoff, const bool stop_state) { + // Avoid race condition by setting stop state first + if (onoff) calibration_stop_state = stop_state; + calibration_probe_enabled = onoff; + + resync(); + } +#endif + // Get the stable endstop states when enabled void Endstops::resync() { if (!abort_enabled()) return; // If endstops/probes are disabled the loop below can hang @@ -485,6 +501,9 @@ void __O2 Endstops::report_states() { #if USE_Z_MIN_PROBE print_es_state(PROBE_TRIGGERED(), F(STR_Z_PROBE)); #endif + #if USE_CALIBRATION + print_es_state(READ(CALIBRATION_PIN) != CALIBRATION_PIN_INVERTING, F(STR_CALIBRATION)); + #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) { @@ -530,6 +549,16 @@ void Endstops::update() { if (G38_move) UPDATE_LIVE_STATE(Z, TERN(USE_Z_MIN_PROBE, MIN_PROBE, MIN)); #endif + #if ENABLED(CALIBRATION_GCODE) + if (calibration_probe_enabled) { + #if HAS_CALIBRATION_STATE + SET_BIT_TO(live_state, CALIBRATION, READ(CALIBRATION_PIN) != CALIBRATION_PIN_INVERTING); + #else + UPDATE_LIVE_STATE(Z, TERN(USE_Z_MIN_PROBE, MIN_PROBE, MIN)); + #endif + } + #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 @@ -797,6 +826,15 @@ void Endstops::update() { } #endif + #if ENABLED(CALIBRATION_GCODE) + if (calibration_probe_enabled) { + #if HAS_CALIBRATION_STATE + if (TEST(live_state, CALIBRATION) == calibration_stop_state) stepper.quick_stop(); + #else + if (TEST(live_state, Z_MIN_PROBE) == calibration_stop_state) stepper.quick_stop(); + #endif + } + #endif // Signal, after validation, if an endstop limit is pressed or not bool moving_neg; @@ -1173,6 +1211,9 @@ void Endstops::update() { #if USE_Z_MIN_PROBE ES_GET_STATE(Z_MIN_PROBE); #endif + #if USE_CALIBRATION + ES_GET_STATE(CALIBRATION); + #endif #if USE_X2_MIN ES_GET_STATE(X2_MIN); #endif @@ -1265,6 +1306,9 @@ void Endstops::update() { #if USE_Z_MIN_PROBE ES_REPORT_CHANGE(Z_MIN_PROBE); #endif + #if USE_CALIBRATION + ES_REPORT_STATE(CALIBRATION); + #endif #if USE_X2_MIN ES_REPORT_CHANGE(X2_MIN); #endif diff --git a/Marlin/src/module/endstops.h b/Marlin/src/module/endstops.h index bbdb0bc77bf6..7a6da5eefa8a 100644 --- a/Marlin/src/module/endstops.h +++ b/Marlin/src/module/endstops.h @@ -66,6 +66,9 @@ enum EndstopEnum : char { // Extra Endstops for XYZ ES_MINMAX(X2) ES_MINMAX(Y2) ES_MINMAX(Z2) ES_MINMAX(Z3) ES_MINMAX(Z4) + // Calibration pin state + ES_ITEM(HAS_CALIBRATION_STATE, CALIBRATION) + // Bed Probe state is distinct or shared with Z_MIN (i.e., when the probe is the only Z endstop) ES_ITEM(HAS_Z_PROBE_STATE, Z_MIN_PROBE IF_DISABLED(USE_Z_MIN_PROBE, = Z_MIN)) @@ -165,10 +168,10 @@ class Endstops { static void init(); /** - * Are endstops or the probe set to abort the move? + * Are endstops or the Z min probe or the CALIBRATION probe set to abort the move? */ FORCE_INLINE static bool abort_enabled() { - return enabled || TERN0(HAS_BED_PROBE, z_probe_enabled); + return enabled || TERN0(HAS_BED_PROBE, z_probe_enabled) || TERN0(CALIBRATION_GCODE, calibration_probe_enabled); } static bool global_enabled() { return enabled_globally; } @@ -251,6 +254,13 @@ class Endstops { static void enable_z_probe(const bool onoff=true); #endif + // Enable / disable calibration probe checking + #if ENABLED(CALIBRATION_GCODE) + static volatile bool calibration_probe_enabled; + static volatile bool calibration_stop_state; + static void enable_calibration_probe(const bool onoff,const bool stop_state = true); + #endif + static void resync(); // Debugging of endstops From 1e0719dac5ad75dcaca0f86eeb575bd72af8409f Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Tue, 25 Jun 2024 00:22:37 +0000 Subject: [PATCH 06/24] [cron] Bump distribution date (2024-06-25) --- Marlin/Version.h | 2 +- Marlin/src/inc/Version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/Version.h b/Marlin/Version.h index 1df0756b8014..22cd61fb075f 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -41,7 +41,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2024-06-22" +//#define STRING_DISTRIBUTION_DATE "2024-06-25" /** * Defines a generic printer name to be output to the LCD after booting Marlin. diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index c459a12bcf2a..7f4fb8613d80 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2024-06-22" + #define STRING_DISTRIBUTION_DATE "2024-06-25" #endif /** From 9a6d4b5e56e8dd6c2dda4a7c510b4ed34d19835c Mon Sep 17 00:00:00 2001 From: Ben <92957639+buppgard@users.noreply.github.com> Date: Tue, 25 Jun 2024 23:34:33 -0400 Subject: [PATCH 07/24] =?UTF-8?q?=F0=9F=9A=B8=20PLR:=20Add=20FR=20and=20Fl?= =?UTF-8?q?ow=20(#27201)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Scott Lahteine --- Marlin/src/feature/powerloss.cpp | 19 ++++++-- Marlin/src/feature/powerloss.h | 2 + Marlin/src/lcd/e3v2/jyersui/dwin.cpp | 2 +- .../lcd/extui/mks_ui/draw_change_speed.cpp | 47 +++++-------------- Marlin/src/lcd/extui/mks_ui/draw_dialog.cpp | 8 +--- Marlin/src/lcd/extui/mks_ui/draw_ui.cpp | 8 +--- Marlin/src/lcd/extui/mks_ui/wifi_module.cpp | 10 +--- 7 files changed, 35 insertions(+), 61 deletions(-) diff --git a/Marlin/src/feature/powerloss.cpp b/Marlin/src/feature/powerloss.cpp index 1867aba6ed25..cd5fc13ddab3 100644 --- a/Marlin/src/feature/powerloss.cpp +++ b/Marlin/src/feature/powerloss.cpp @@ -205,6 +205,9 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW // info.sdpos and info.current_position are pre-filled from the Stepper ISR info.feedrate = uint16_t(MMS_TO_MMM(feedrate_mm_s)); + info.feedrate_percentage = feedrate_percentage; + COPY(info.flow_percentage, planner.flow_percentage); + info.zraise = zraise; info.flag.raised = raised; // Was Z raised before power-off? @@ -216,7 +219,7 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW #if DISABLED(NO_VOLUMETRICS) info.flag.volumetric_enabled = parser.volumetric_enabled; #if HAS_MULTI_EXTRUDER - EXTRUDER_LOOP() info.filament_size[e] = planner.filament_size[e]; + COPY(info.filament_size, planner.filament_size); #else if (parser.volumetric_enabled) info.filament_size[0] = planner.filament_size[active_extruder]; #endif @@ -269,7 +272,10 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW #if POWER_LOSS_RETRACT_LEN // Retract filament now - gcode.process_subcommands_now(F("G1 F3000 E-" STRINGIFY(POWER_LOSS_RETRACT_LEN))); + const uint16_t old_flow = planner.flow_percentage[active_extruder]; + planner.set_flow(active_extruder, 100); + gcode.process_subcommands_now(F("G1F3000E-" STRINGIFY(POWER_LOSS_RETRACT_LEN))); + planner.set_flow(active_extruder, old_flow); #endif #if POWER_LOSS_ZRAISE @@ -555,8 +561,12 @@ void PrintJobRecovery::resume() { // Move back down to the saved Z for printing PROCESS_SUBCOMMANDS_NOW(TS(F("G1F600Z"), p_float_t(z_print, 3))); - // Restore the feedrate + // Restore the feedrate and percentage PROCESS_SUBCOMMANDS_NOW(TS(F("G1F"), info.feedrate)); + feedrate_percentage = info.feedrate_percentage; + + // Flowrate percentage + EXTRUDER_LOOP() planner.set_flow(e, info.flow_percentage[e]); // Restore E position with G92.9 PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9E"), p_float_t(resume_pos.e, 3))); @@ -589,7 +599,8 @@ void PrintJobRecovery::resume() { } DEBUG_EOL(); - DEBUG_ECHOLNPGM("feedrate: ", info.feedrate); + DEBUG_ECHOLN(F("feedrate: "), info.feedrate, F(" x "), info.feedrate_percentage, '%'); + EXTRUDER_LOOP() DEBUG_ECHOLN('E', e + 1, F(" flow %: "), info.flow_percentage[e]); DEBUG_ECHOLNPGM("zraise: ", info.zraise, " ", info.flag.raised ? "(before)" : ""); diff --git a/Marlin/src/feature/powerloss.h b/Marlin/src/feature/powerloss.h index 7de8450c9146..238f276c1bc8 100644 --- a/Marlin/src/feature/powerloss.h +++ b/Marlin/src/feature/powerloss.h @@ -59,6 +59,8 @@ typedef struct { // Machine state xyze_pos_t current_position; uint16_t feedrate; + int16_t feedrate_percentage; + uint16_t flow_percentage[EXTRUDERS]; float zraise; diff --git a/Marlin/src/lcd/e3v2/jyersui/dwin.cpp b/Marlin/src/lcd/e3v2/jyersui/dwin.cpp index c9191dd31df3..1c641817b877 100644 --- a/Marlin/src/lcd/e3v2/jyersui/dwin.cpp +++ b/Marlin/src/lcd/e3v2/jyersui/dwin.cpp @@ -828,7 +828,7 @@ void JyersDWIN::drawStatusArea(const bool icons/*=false*/) { } 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]); + 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, flow); } #endif diff --git a/Marlin/src/lcd/extui/mks_ui/draw_change_speed.cpp b/Marlin/src/lcd/extui/mks_ui/draw_change_speed.cpp index 6b07d4b71970..e5d0f4244f4f 100644 --- a/Marlin/src/lcd/extui/mks_ui/draw_change_speed.cpp +++ b/Marlin/src/lcd/extui/mks_ui/draw_change_speed.cpp @@ -51,42 +51,22 @@ static void event_handler(lv_obj_t *obj, lv_event_t event) { if (event != LV_EVENT_RELEASED) return; switch (obj->mks_obj_id) { case ID_C_ADD: - if (!editingFlowrate) { - if (feedrate_percentage < MAX_EXT_SPEED_PERCENT - uiCfg.stepPrintSpeed) - feedrate_percentage += uiCfg.stepPrintSpeed; - else - feedrate_percentage = MAX_EXT_SPEED_PERCENT; - } + if (!editingFlowrate) + feedrate_percentage = _MIN(MAX_EXT_SPEED_PERCENT, feedrate_percentage + uiCfg.stepPrintSpeed); else { - if (planner.flow_percentage[0] < MAX_EXT_SPEED_PERCENT - uiCfg.stepPrintSpeed) - planner.flow_percentage[0] += uiCfg.stepPrintSpeed; - else - planner.flow_percentage[0] = MAX_EXT_SPEED_PERCENT; - planner.refresh_e_factor(0); - #if HAS_MULTI_EXTRUDER - planner.flow_percentage[1] = planner.flow_percentage[0]; - planner.refresh_e_factor(1); - #endif + const int16_t new_flow = _MIN(MAX_EXT_SPEED_PERCENT, planner.flow_percentage[0] + uiCfg.stepPrintSpeed); + planner.set_flow(0, new_flow); + TERN_(HAS_MULTI_EXTRUDER, planner.set_flow(1, new_flow)); } disp_print_speed(); break; case ID_C_DEC: - if (!editingFlowrate) { - if (feedrate_percentage > MIN_EXT_SPEED_PERCENT + uiCfg.stepPrintSpeed) - feedrate_percentage -= uiCfg.stepPrintSpeed; - else - feedrate_percentage = MIN_EXT_SPEED_PERCENT; - } + if (!editingFlowrate) + feedrate_percentage = _MAX(MIN_EXT_SPEED_PERCENT, feedrate_percentage + uiCfg.stepPrintSpeed); else { - if (planner.flow_percentage[0] > MIN_EXT_SPEED_PERCENT + uiCfg.stepPrintSpeed) - planner.flow_percentage[0] -= uiCfg.stepPrintSpeed; - else - planner.flow_percentage[0] = MIN_EXT_SPEED_PERCENT; - planner.refresh_e_factor(0); - #if HAS_MULTI_EXTRUDER - planner.flow_percentage[1] = planner.flow_percentage[0]; - planner.refresh_e_factor(1); - #endif + const int16_t new_flow = _MAX(MIN_EXT_SPEED_PERCENT, planner.flow_percentage[0] - uiCfg.stepPrintSpeed); + planner.set_flow(0, new_flow); + TERN_(HAS_MULTI_EXTRUDER, planner.set_flow(1, new_flow)); } disp_print_speed(); break; @@ -101,12 +81,7 @@ static void event_handler(lv_obj_t *obj, lv_event_t event) { disp_print_speed(); break; case ID_C_STEP: - if (uiCfg.stepPrintSpeed == 1) - uiCfg.stepPrintSpeed = 5; - else if (uiCfg.stepPrintSpeed == 5) - uiCfg.stepPrintSpeed = 10; - else - uiCfg.stepPrintSpeed = 1; + uiCfg.stepPrintSpeed = (uiCfg.stepPrintSpeed == 5) ? 10 : (uiCfg.stepPrintSpeed == 1) ? 5 : 1; disp_speed_step(); break; case ID_C_RETURN: diff --git a/Marlin/src/lcd/extui/mks_ui/draw_dialog.cpp b/Marlin/src/lcd/extui/mks_ui/draw_dialog.cpp index 32eb7e77d73b..4b2474a8e619 100644 --- a/Marlin/src/lcd/extui/mks_ui/draw_dialog.cpp +++ b/Marlin/src/lcd/extui/mks_ui/draw_dialog.cpp @@ -102,12 +102,8 @@ static void btn_ok_event_cb(lv_obj_t *btn, lv_event_t event) { card.openFileRead(cur_name); if (card.isFileOpen()) { feedrate_percentage = 100; - planner.flow_percentage[0] = 100; - planner.e_factor[0] = planner.flow_percentage[0] * 0.01f; - #if HAS_MULTI_EXTRUDER - planner.flow_percentage[1] = 100; - planner.e_factor[1] = planner.flow_percentage[1] * 0.01f; - #endif + TERN_(HAS_EXTRUDERS, planner.set_flow(0, 100)); + TERN_(HAS_MULTI_EXTRUDER, planner.set_flow(1, 100)); card.startOrResumeFilePrinting(); TERN_(POWER_LOSS_RECOVERY, recovery.prepare()); once_flag = false; diff --git a/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp b/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp index 61ab345dd76e..7408197f73fe 100644 --- a/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp +++ b/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp @@ -660,12 +660,8 @@ char *creat_title_text() { card.openFileRead(cur_name); if (card.isFileOpen()) { feedrate_percentage = 100; - planner.flow_percentage[0] = 100; - planner.e_factor[0] = planner.flow_percentage[0] * 0.01; - #if HAS_MULTI_EXTRUDER - planner.flow_percentage[1] = 100; - planner.e_factor[1] = planner.flow_percentage[1] * 0.01; - #endif + TERN_(HAS_EXTRUDERS, planner.set_flow(0, 100)); + TERN_(HAS_MULTI_EXTRUDER, planner.set_flow(1, 100)); card.startOrResumeFilePrinting(); TERN_(POWER_LOSS_RECOVERY, recovery.prepare()); once_flag = false; diff --git a/Marlin/src/lcd/extui/mks_ui/wifi_module.cpp b/Marlin/src/lcd/extui/mks_ui/wifi_module.cpp index 46ba86023918..19b2cd8597ed 100644 --- a/Marlin/src/lcd/extui/mks_ui/wifi_module.cpp +++ b/Marlin/src/lcd/extui/mks_ui/wifi_module.cpp @@ -1011,14 +1011,8 @@ static void wifi_gcode_exec(uint8_t * const cmd_line) { if (card.isFileOpen()) { //saved_feedrate_percentage = feedrate_percentage; feedrate_percentage = 100; - #if HAS_EXTRUDERS - planner.flow_percentage[0] = 100; - planner.e_factor[0] = planner.flow_percentage[0] * 0.01f; - #endif - #if HAS_MULTI_EXTRUDER - planner.flow_percentage[1] = 100; - planner.e_factor[1] = planner.flow_percentage[1] * 0.01f; - #endif + TERN_(HAS_EXTRUDERS, planner.set_flow(0, 100)); + TERN_(HAS_MULTI_EXTRUDER, planner.set_flow(1, 100)); card.startOrResumeFilePrinting(); TERN_(POWER_LOSS_RECOVERY, recovery.prepare()); once_flag = false; From 37fc32d972197756672036509d0404f297752bb5 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Wed, 26 Jun 2024 06:07:26 +0000 Subject: [PATCH 08/24] [cron] Bump distribution date (2024-06-26) --- Marlin/Version.h | 2 +- Marlin/src/inc/Version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/Version.h b/Marlin/Version.h index 22cd61fb075f..dba979929153 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -41,7 +41,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2024-06-25" +//#define STRING_DISTRIBUTION_DATE "2024-06-26" /** * Defines a generic printer name to be output to the LCD after booting Marlin. diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 7f4fb8613d80..6e99cc0f3396 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2024-06-25" + #define STRING_DISTRIBUTION_DATE "2024-06-26" #endif /** From 7b21cd5d7253a95e1a65760b4817d7f6475ff280 Mon Sep 17 00:00:00 2001 From: David Buezas Date: Wed, 26 Jun 2024 23:04:58 +0200 Subject: [PATCH 09/24] =?UTF-8?q?=F0=9F=A9=B9=20Don't=20reinit=20i2c=20LCD?= =?UTF-8?q?s=20(#27194)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Scott Lahteine --- Marlin/src/inc/Conditionals_post.h | 4 ++-- Marlin/src/lcd/marlinui.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index d43132e13c82..41c22e483577 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -557,8 +557,8 @@ #endif #endif - #if HAS_SD_DETECT && NONE(HAS_GRAPHICAL_TFT, LCD_USE_DMA_FSMC, HAS_FSMC_GRAPHICAL_TFT, HAS_SPI_GRAPHICAL_TFT, IS_DWIN_MARLINUI, EXTENSIBLE_UI, HAS_DWIN_E3V2) - #define REINIT_NOISY_LCD 1 // Have the LCD re-init on SD insertion + #if HAS_SD_DETECT && NONE(HAS_GRAPHICAL_TFT, LCD_USE_DMA_FSMC, HAS_FSMC_GRAPHICAL_TFT, HAS_SPI_GRAPHICAL_TFT, IS_DWIN_MARLINUI, EXTENSIBLE_UI, HAS_DWIN_E3V2, HAS_U8GLIB_I2C_OLED) + #define REINIT_NOISY_SPI_LCD 1 // Have LCDs with shared SPI re-init on SD insertion #endif #endif // HAS_MEDIA diff --git a/Marlin/src/lcd/marlinui.h b/Marlin/src/lcd/marlinui.h index 835102546da9..6a29110be882 100644 --- a/Marlin/src/lcd/marlinui.h +++ b/Marlin/src/lcd/marlinui.h @@ -211,7 +211,7 @@ class MarlinUI { static void init_lcd() {} #endif - static void reinit_lcd() { TERN_(REINIT_NOISY_LCD, init_lcd()); } + static void reinit_lcd() { TERN_(REINIT_NOISY_SPI_LCD, init_lcd()); } #if HAS_WIRED_LCD static bool detected(); From bf1995140aa7e08e90118c0ce77f1dd9b7b7db64 Mon Sep 17 00:00:00 2001 From: Keith Bennett <13375512+thisiskeithb@users.noreply.github.com> Date: Wed, 26 Jun 2024 14:26:42 -0700 Subject: [PATCH 10/24] =?UTF-8?q?=F0=9F=94=A8=20TMC2100=20is=20STANDALONE?= =?UTF-8?q?=20(#27209)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/core/drivers.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Marlin/src/core/drivers.h b/Marlin/src/core/drivers.h index e28fc1bba7af..c4417aab7531 100644 --- a/Marlin/src/core/drivers.h +++ b/Marlin/src/core/drivers.h @@ -103,7 +103,8 @@ #define HAS_TRINAMIC HAS_TRINAMIC_CONFIG -#if ( HAS_DRIVER(TMC2130_STANDALONE) || HAS_DRIVER(TMC2160_STANDALONE) \ +#if ( HAS_DRIVER(TMC2100) \ + || HAS_DRIVER(TMC2130_STANDALONE) || HAS_DRIVER(TMC2160_STANDALONE) \ || HAS_DRIVER(TMC2208_STANDALONE) || HAS_DRIVER(TMC2209_STANDALONE) \ || HAS_DRIVER(TMC2660_STANDALONE) || HAS_DRIVER(TMC5130_STANDALONE) \ || HAS_DRIVER(TMC5160_STANDALONE) ) From 1f9fc665ec21f95666801aa4fccc4f4f71932018 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Wed, 26 Jun 2024 18:27:05 -0500 Subject: [PATCH 11/24] =?UTF-8?q?=F0=9F=9A=B8=20MarlinUI::=20clear=5Ffor?= =?UTF-8?q?=5Fdrawing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/inc/Conditionals_LCD.h | 3 +++ Marlin/src/inc/Conditionals_post.h | 4 ++-- Marlin/src/lcd/HD44780/marlinui_HD44780.cpp | 3 ++- Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp | 2 ++ Marlin/src/lcd/dogm/marlinui_DOGM.cpp | 14 +++++++++++++- Marlin/src/lcd/e3v2/creality/dwin.cpp | 2 ++ Marlin/src/lcd/e3v2/jyersui/dwin.cpp | 2 ++ Marlin/src/lcd/e3v2/marlinui/ui_common.cpp | 6 ++++-- Marlin/src/lcd/e3v2/proui/dwin.cpp | 2 ++ Marlin/src/lcd/e3v2/proui/proui_extui.cpp | 1 + Marlin/src/lcd/extui/ui_api.cpp | 3 +++ Marlin/src/lcd/marlinui.cpp | 3 ++- Marlin/src/lcd/marlinui.h | 12 ++++++++---- Marlin/src/lcd/menu/menu.cpp | 2 +- Marlin/src/lcd/menu/menu_ubl.cpp | 2 +- Marlin/src/lcd/tft/touch.cpp | 8 ++++---- Marlin/src/lcd/tft/ui_color_ui.cpp | 2 +- Marlin/src/lcd/tft/ui_common.cpp | 8 +++++--- Marlin/src/lcd/tft/ui_move_axis_screen_1024.cpp | 2 +- Marlin/src/lcd/tft/ui_move_axis_screen_320.cpp | 2 +- Marlin/src/lcd/tft/ui_move_axis_screen_480.cpp | 2 +- 21 files changed, 61 insertions(+), 24 deletions(-) diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index 6b9ac4efe66b..7de6146f293c 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -1099,6 +1099,9 @@ * - poweroff (for PSU_CONTROL and HAS_MARLINUI_MENU) * * ...and implements these MarlinUI methods: + * - init_lcd + * - clear_lcd + * - clear_for_drawing * - zoffset_overlay (if BABYSTEP_GFX_OVERLAY or MESH_EDIT_GFX_OVERLAY are supported) * - draw_kill_screen * - kill_screen diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index 41c22e483577..d43132e13c82 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -557,8 +557,8 @@ #endif #endif - #if HAS_SD_DETECT && NONE(HAS_GRAPHICAL_TFT, LCD_USE_DMA_FSMC, HAS_FSMC_GRAPHICAL_TFT, HAS_SPI_GRAPHICAL_TFT, IS_DWIN_MARLINUI, EXTENSIBLE_UI, HAS_DWIN_E3V2, HAS_U8GLIB_I2C_OLED) - #define REINIT_NOISY_SPI_LCD 1 // Have LCDs with shared SPI re-init on SD insertion + #if HAS_SD_DETECT && NONE(HAS_GRAPHICAL_TFT, LCD_USE_DMA_FSMC, HAS_FSMC_GRAPHICAL_TFT, HAS_SPI_GRAPHICAL_TFT, IS_DWIN_MARLINUI, EXTENSIBLE_UI, HAS_DWIN_E3V2) + #define REINIT_NOISY_LCD 1 // Have the LCD re-init on SD insertion #endif #endif // HAS_MEDIA diff --git a/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp b/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp index ea732432503e..ae92d0a5f89a 100644 --- a/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp +++ b/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp @@ -467,6 +467,7 @@ bool MarlinUI::detected() { #endif void MarlinUI::clear_lcd() { lcd.clear(); } +void MarlinUI::clear_for_drawing() { clear_lcd(); } #if ENABLED(SHOW_BOOTSCREEN) @@ -1515,7 +1516,7 @@ void MarlinUI::draw_status_screen() { lower_right.column = 0; lower_right.row = 0; - clear_lcd(); + clear_for_drawing(); x_map_pixels = (HD44780_CHAR_WIDTH) * (MESH_MAP_COLS) - 2; // Minus 2 because we are drawing a box around the map y_map_pixels = (HD44780_CHAR_HEIGHT) * (MESH_MAP_ROWS) - 2; diff --git a/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp b/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp index b29653f7b01f..6dc5a41fdd6b 100644 --- a/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp +++ b/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp @@ -376,6 +376,8 @@ void MarlinUI::clear_lcd() { lcd.clear_buffer(); } +void MarlinUI::clear_for_drawing() { clear_lcd(); } + #if HAS_LCD_CONTRAST void MarlinUI::_set_contrast() { lcd.setContrast(contrast); } #endif diff --git a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp index 1bc55630af38..b99a31341ab8 100644 --- a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp +++ b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp @@ -374,7 +374,19 @@ void MarlinUI::draw_kill_screen() { } while (u8g.nextPage()); } -void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop +// Erase the LCD contents by drawing an empty box. +void MarlinUI::clear_lcd() { + u8g.setColorIndex(0); + u8g.firstPage(); + do { + u8g.drawBox(0, 0, u8g.getWidth(), u8g.getHeight()); + } while (u8g.nextPage()); +} + +// U8G displays are drawn over multiple loops so must do their own clearing. +void MarlinUI::clear_for_drawing() { + // Automatically cleared by Picture Loop +} #if HAS_DISPLAY_SLEEP void MarlinUI::sleep_display(const bool sleep/*=true*/) { diff --git a/Marlin/src/lcd/e3v2/creality/dwin.cpp b/Marlin/src/lcd/e3v2/creality/dwin.cpp index 7f057137d8a0..34bdd29694a4 100644 --- a/Marlin/src/lcd/e3v2/creality/dwin.cpp +++ b/Marlin/src/lcd/e3v2/creality/dwin.cpp @@ -1816,6 +1816,8 @@ void hmiSDCardInit() { card.cdroot(); } // Initialize or re-initialize the LCD void MarlinUI::init_lcd() { dwinStartup(); } +void MarlinUI::clear_lcd() {} + void MarlinUI::update() { eachMomentUpdate(); // Status update hmiSDCardUpdate(); // SD card update diff --git a/Marlin/src/lcd/e3v2/jyersui/dwin.cpp b/Marlin/src/lcd/e3v2/jyersui/dwin.cpp index 1c641817b877..2edc03dfd655 100644 --- a/Marlin/src/lcd/e3v2/jyersui/dwin.cpp +++ b/Marlin/src/lcd/e3v2/jyersui/dwin.cpp @@ -5155,6 +5155,8 @@ void MarlinUI::init_lcd() { jyersDWIN.redrawScreen(); } +void MarlinUI::clear_lcd() {} + #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; diff --git a/Marlin/src/lcd/e3v2/marlinui/ui_common.cpp b/Marlin/src/lcd/e3v2/marlinui/ui_common.cpp index 4a60f77c9dab..31cf26922722 100644 --- a/Marlin/src/lcd/e3v2/marlinui/ui_common.cpp +++ b/Marlin/src/lcd/e3v2/marlinui/ui_common.cpp @@ -90,6 +90,8 @@ void MarlinUI::clear_lcd() { did_first_redraw = false; } +void MarlinUI::clear_for_drawing() { clear_lcd(); } + #if ENABLED(SHOW_BOOTSCREEN) void MarlinUI::show_bootscreen() { @@ -111,7 +113,7 @@ void MarlinUI::clear_lcd() { dwinDrawString(false, font10x20, COLOR_YELLOW, COLOR_BG_BLACK, INFO_CENTER - (dwin_string.length * 10) / 2, VERSION_Y, S(dwin_string.string())); TERN_(SHOW_CUSTOM_BOOTSCREEN, safe_delay(CUSTOM_BOOTSCREEN_TIMEOUT)); - clear_lcd(); + clear_for_drawing(); dwinIconShow(BOOT_ICON, ICON_MarlinBoot, LOGO_CENTER - 266 / 2, 15); #if ENABLED(DWIN_MARLINUI_PORTRAIT) @@ -132,7 +134,7 @@ void MarlinUI::clear_lcd() { void MarlinUI::bootscreen_completion(const millis_t sofar) { if ((BOOTSCREEN_TIMEOUT) > sofar) safe_delay((BOOTSCREEN_TIMEOUT) - sofar); - clear_lcd(); + clear_for_drawing(); } #endif diff --git a/Marlin/src/lcd/e3v2/proui/dwin.cpp b/Marlin/src/lcd/e3v2/proui/dwin.cpp index 56c7fec517d8..2b691326c0ee 100644 --- a/Marlin/src/lcd/e3v2/proui/dwin.cpp +++ b/Marlin/src/lcd/e3v2/proui/dwin.cpp @@ -1913,6 +1913,8 @@ void MarlinUI::init_lcd() { dwinJPGCacheTo1(Language_English); } +void MarlinUI::clear_lcd() {} + void dwinInitScreen() { dwinSetColorDefaults(); hmiInit(); // Draws boot screen diff --git a/Marlin/src/lcd/e3v2/proui/proui_extui.cpp b/Marlin/src/lcd/e3v2/proui/proui_extui.cpp index ae85a5a60cb3..2adca7cbe6cc 100644 --- a/Marlin/src/lcd/e3v2/proui/proui_extui.cpp +++ b/Marlin/src/lcd/e3v2/proui/proui_extui.cpp @@ -195,6 +195,7 @@ namespace ExtUI { void onPIDTuning(const pidresult_t rst) { // Called for temperature PID tuning result switch (rst) { + default: break; #if ENABLED(PIDTEMP) case PID_STARTED: dwinPIDTuning(PIDTEMP_START); break; #endif diff --git a/Marlin/src/lcd/extui/ui_api.cpp b/Marlin/src/lcd/extui/ui_api.cpp index 29f9b34fe4fa..1fcfabdd7257 100644 --- a/Marlin/src/lcd/extui/ui_api.cpp +++ b/Marlin/src/lcd/extui/ui_api.cpp @@ -1279,6 +1279,9 @@ namespace ExtUI { #if DISABLED(HAS_DWIN_E3V2) void MarlinUI::init_lcd() { ExtUI::onStartup(); } + void MarlinUI::clear_lcd() {} + void MarlinUI::clear_for_drawing() {} + void MarlinUI::update() { ExtUI::onIdle(); } void MarlinUI::kill_screen(FSTR_P const error, FSTR_P const component) { diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index 5b83f0c6bf72..a967d921359f 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -226,6 +226,7 @@ void MarlinUI::init() { #endif init_lcd(); + clear_lcd(); #if BUTTON_EXISTS(EN1) SET_INPUT_PULLUP(BTN_EN1); @@ -1204,7 +1205,7 @@ void MarlinUI::init() { // Change state of drawing flag between screen updates if (!drawing_screen) switch (lcdDrawUpdate) { case LCDVIEW_CLEAR_CALL_REDRAW: - clear_lcd(); break; + clear_for_drawing(); break; case LCDVIEW_REDRAW_NOW: refresh(LCDVIEW_NONE); case LCDVIEW_NONE: diff --git a/Marlin/src/lcd/marlinui.h b/Marlin/src/lcd/marlinui.h index 6a29110be882..cc130327a96b 100644 --- a/Marlin/src/lcd/marlinui.h +++ b/Marlin/src/lcd/marlinui.h @@ -207,11 +207,14 @@ class MarlinUI { #if HAS_DISPLAY || HAS_DWIN_E3V2 static void init_lcd(); + // Erase the LCD contents. Do the lowest-level thing required to clear the LCD. + static void clear_lcd(); #else static void init_lcd() {} + static void clear_lcd() {} #endif - static void reinit_lcd() { TERN_(REINIT_NOISY_SPI_LCD, init_lcd()); } + static void reinit_lcd() { TERN_(REINIT_NOISY_LCD, init_lcd()); } #if HAS_WIRED_LCD static bool detected(); @@ -246,9 +249,6 @@ class MarlinUI { static void update_indicators(); #endif - // LCD implementations - static void clear_lcd(); - #if ALL(HAS_MARLINUI_MENU, TOUCH_SCREEN_CALIBRATION) static void check_touch_calibration() { if (touch_calibration.need_calibration()) currentScreen = touch_calibration_screen; @@ -520,6 +520,9 @@ class MarlinUI { #if HAS_DISPLAY + // Clear the LCD before new drawing. Some LCDs do nothing because they redraw frequently. + static void clear_for_drawing(); + static void abort_print(); static void pause_print(); static void resume_print(); @@ -630,6 +633,7 @@ class MarlinUI { #else // No LCD + static void clear_for_drawing() {} static void kill_screen(FSTR_P const, FSTR_P const) {} #endif diff --git a/Marlin/src/lcd/menu/menu.cpp b/Marlin/src/lcd/menu/menu.cpp index 892af5dbabd8..f939452143c9 100644 --- a/Marlin/src/lcd/menu/menu.cpp +++ b/Marlin/src/lcd/menu/menu.cpp @@ -209,7 +209,7 @@ void MarlinUI::goto_screen(screenFunc_t screen, const uint16_t encoder/*=0*/, co TERN_(AUTO_BED_LEVELING_UBL, bedlevel.lcd_map_control = false); } - clear_lcd(); + clear_for_drawing(); // Re-initialize custom characters that may be re-used #if HAS_MARLINUI_HD44780 diff --git a/Marlin/src/lcd/menu/menu_ubl.cpp b/Marlin/src/lcd/menu/menu_ubl.cpp index 2d28d4499173..ff7225a16679 100644 --- a/Marlin/src/lcd/menu/menu_ubl.cpp +++ b/Marlin/src/lcd/menu/menu_ubl.cpp @@ -96,7 +96,7 @@ void _lcd_mesh_fine_tune(FSTR_P const fmsg) { // To capture encoder events UBL will also call ui.capture and ui.release. // void MarlinUI::ubl_mesh_edit_start(const_float_t initial) { - TERN_(HAS_GRAPHICAL_TFT, clear_lcd()); + TERN_(HAS_GRAPHICAL_TFT, clear_for_drawing()); mesh_edit_accumulator = initial; goto_screen([]{ _lcd_mesh_fine_tune(GET_TEXT_F(MSG_MESH_EDIT_Z)); }); } diff --git a/Marlin/src/lcd/tft/touch.cpp b/Marlin/src/lcd/tft/touch.cpp index 7fc5f2fa214d..e48f97453603 100644 --- a/Marlin/src/lcd/tft/touch.cpp +++ b/Marlin/src/lcd/tft/touch.cpp @@ -184,7 +184,7 @@ void Touch::touch(touch_control_t *control) { case HEATER: int8_t heater; heater = control->data; - ui.clear_lcd(); + ui.clear_for_drawing(); #if HAS_HOTEND if (heater >= 0) { // HotEnd #if HOTENDS == 1 @@ -213,20 +213,20 @@ void Touch::touch(touch_control_t *control) { break; case FAN: - ui.clear_lcd(); + ui.clear_for_drawing(); static uint8_t fan, fan_speed; fan = 0; fan_speed = thermalManager.fan_speed[fan]; MenuItem_percent::action(GET_TEXT_F(MSG_FIRST_FAN_SPEED), &fan_speed, 0, 255, []{ thermalManager.set_fan_speed(fan, fan_speed); TERN_(LASER_SYNCHRONOUS_M106_M107, planner.buffer_sync_block(BLOCK_BIT_SYNC_FANS));}); break; case FEEDRATE: - ui.clear_lcd(); + ui.clear_for_drawing(); MenuItem_int3::action(GET_TEXT_F(MSG_SPEED), &feedrate_percentage, SPEED_EDIT_MIN, SPEED_EDIT_MAX); break; #if HAS_EXTRUDERS case FLOWRATE: - ui.clear_lcd(); + ui.clear_for_drawing(); MenuItemBase::itemIndex = control->data; #if EXTRUDERS == 1 MenuItem_int3::action(GET_TEXT_F(MSG_FLOW), &planner.flow_percentage[MenuItemBase::itemIndex], FLOW_EDIT_MIN, FLOW_EDIT_MAX, []{ planner.refresh_e_factor(MenuItemBase::itemIndex); }); diff --git a/Marlin/src/lcd/tft/ui_color_ui.cpp b/Marlin/src/lcd/tft/ui_color_ui.cpp index 279ea9715a19..9861cbc1f6ff 100644 --- a/Marlin/src/lcd/tft/ui_color_ui.cpp +++ b/Marlin/src/lcd/tft/ui_color_ui.cpp @@ -79,7 +79,7 @@ void MarlinUI::tft_idle() { void MarlinUI::bootscreen_completion(const millis_t sofar) { if ((BOOTSCREEN_TIMEOUT) > sofar) safe_delay((BOOTSCREEN_TIMEOUT) - sofar); - clear_lcd(); + clear_for_drawing(); } #endif diff --git a/Marlin/src/lcd/tft/ui_common.cpp b/Marlin/src/lcd/tft/ui_common.cpp index 23f276349bcf..e42ca7e689fd 100644 --- a/Marlin/src/lcd/tft/ui_common.cpp +++ b/Marlin/src/lcd/tft/ui_common.cpp @@ -199,7 +199,7 @@ void moveAxis(const AxisEnum axis, const int8_t direction) { tft.queue.reset(); if (!sleepCleared) { sleepCleared = true; - ui.clear_lcd(); + ui.clear_for_drawing(); tft.queue.async(); } touch.idle(); @@ -407,7 +407,7 @@ void MarlinUI::init_lcd() { tft.add_glyphs(EXTRA_FONT_NAME); #endif TERN_(TOUCH_SCREEN, touch.init()); - clear_lcd(); + clear_for_drawing(); } void MarlinUI::clear_lcd() { @@ -421,6 +421,8 @@ void MarlinUI::clear_lcd() { cursor.set(0, 0); } +void MarlinUI::clear_for_drawing() { clear_lcd(); } + #if HAS_LCD_BRIGHTNESS void MarlinUI::_set_brightness() { @@ -441,7 +443,7 @@ void MarlinUI::clear_lcd() { if (stage == CALIBRATION_NONE) { defer_status_screen(true); - clear_lcd(); + clear_for_drawing(); stage = touch_calibration.calibration_start(); } else { diff --git a/Marlin/src/lcd/tft/ui_move_axis_screen_1024.cpp b/Marlin/src/lcd/tft/ui_move_axis_screen_1024.cpp index a68752c9ddce..a15c05d25e8e 100644 --- a/Marlin/src/lcd/tft/ui_move_axis_screen_1024.cpp +++ b/Marlin/src/lcd/tft/ui_move_axis_screen_1024.cpp @@ -133,7 +133,7 @@ void MarlinUI::move_axis_screen() { motionAxisState.blocked = false; TERN_(TOUCH_SCREEN, touch.enable()); - ui.clear_lcd(); + ui.clear_for_drawing(); TERN_(TOUCH_SCREEN, touch.clear()); diff --git a/Marlin/src/lcd/tft/ui_move_axis_screen_320.cpp b/Marlin/src/lcd/tft/ui_move_axis_screen_320.cpp index 54a65c17bf4b..5b1fbaf958d4 100644 --- a/Marlin/src/lcd/tft/ui_move_axis_screen_320.cpp +++ b/Marlin/src/lcd/tft/ui_move_axis_screen_320.cpp @@ -146,7 +146,7 @@ void MarlinUI::move_axis_screen() { motionAxisState.blocked = false; TERN_(TOUCH_SCREEN, touch.enable()); - ui.clear_lcd(); + ui.clear_for_drawing(); TERN_(TOUCH_SCREEN, touch.clear()); diff --git a/Marlin/src/lcd/tft/ui_move_axis_screen_480.cpp b/Marlin/src/lcd/tft/ui_move_axis_screen_480.cpp index e311c7e8ecd2..9e424115809a 100644 --- a/Marlin/src/lcd/tft/ui_move_axis_screen_480.cpp +++ b/Marlin/src/lcd/tft/ui_move_axis_screen_480.cpp @@ -146,7 +146,7 @@ void MarlinUI::move_axis_screen() { motionAxisState.blocked = false; TERN_(TOUCH_SCREEN, touch.enable()); - ui.clear_lcd(); + ui.clear_for_drawing(); TERN_(TOUCH_SCREEN, touch.clear()); From 8cf2a41f81c779a1d5a8c0e239aa5fedf6dadbb1 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Thu, 27 Jun 2024 00:22:45 +0000 Subject: [PATCH 12/24] [cron] Bump distribution date (2024-06-27) --- Marlin/Version.h | 2 +- Marlin/src/inc/Version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/Version.h b/Marlin/Version.h index dba979929153..697e7325d35c 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -41,7 +41,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2024-06-26" +//#define STRING_DISTRIBUTION_DATE "2024-06-27" /** * Defines a generic printer name to be output to the LCD after booting Marlin. diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 6e99cc0f3396..c9fa45c2ee0a 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2024-06-26" + #define STRING_DISTRIBUTION_DATE "2024-06-27" #endif /** From 9240ec89d034632443d02baaeb140acc3134c67f Mon Sep 17 00:00:00 2001 From: Keith Bennett <13375512+thisiskeithb@users.noreply.github.com> Date: Thu, 27 Jun 2024 09:50:26 -0700 Subject: [PATCH 13/24] =?UTF-8?q?=E2=9C=85=20Add=20`fail-fast:=20true`=20d?= =?UTF-8?q?efault=20strategy=20to=20build=20test=20CI=20(#27215)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci-build-tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci-build-tests.yml b/.github/workflows/ci-build-tests.yml index 546faa5f38f6..edd69c1c15cd 100644 --- a/.github/workflows/ci-build-tests.yml +++ b/.github/workflows/ci-build-tests.yml @@ -37,6 +37,7 @@ jobs: runs-on: ubuntu-latest strategy: + fail-fast: true matrix: test-platform: From 11f90de87364656a851b4d0724f144396dc5b144 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Thu, 27 Jun 2024 18:35:00 -0500 Subject: [PATCH 14/24] =?UTF-8?q?=F0=9F=A9=B9=20Set=20color=201=20on=20DOG?= =?UTF-8?q?M=20clear?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Followup to `clear_for_drawing` --- Marlin/src/lcd/dogm/marlinui_DOGM.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp index b99a31341ab8..eed2bf22751a 100644 --- a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp +++ b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp @@ -381,6 +381,7 @@ void MarlinUI::clear_lcd() { do { u8g.drawBox(0, 0, u8g.getWidth(), u8g.getHeight()); } while (u8g.nextPage()); + u8g.setColorIndex(1); } // U8G displays are drawn over multiple loops so must do their own clearing. From cb6fd130ba21fa4fbca4172b3082a37550e8b9d9 Mon Sep 17 00:00:00 2001 From: David Buezas Date: Fri, 28 Jun 2024 01:37:35 +0200 Subject: [PATCH 15/24] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20Load/init=20(most)?= =?UTF-8?q?=20settings=20after=20showing=20boot-screen=20(#27199)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Scott Lahteine Co-authored-by: Peter Ellens --- Marlin/src/MarlinCore.cpp | 9 +++- Marlin/src/inc/Conditionals_post.h | 4 ++ Marlin/src/module/settings.cpp | 86 +++++++++++++++++++++++------- Marlin/src/module/settings.h | 20 ++++++- 4 files changed, 98 insertions(+), 21 deletions(-) diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index 63e20842bb6d..f297951d828a 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -1334,14 +1334,19 @@ void setup() { SETUP_RUN(card.mount()); // Mount media with settings before first_load #endif - SETUP_RUN(settings.first_load()); // Load data from EEPROM if available (or use defaults) - // This also updates variables in the planner, elsewhere + // Prepare some LCDs to display early + #if HAS_EARLY_LCD_SETTINGS + SETUP_RUN(settings.load_lcd_state()); + #endif #if ALL(HAS_WIRED_LCD, SHOW_BOOTSCREEN) SETUP_RUN(ui.show_bootscreen()); const millis_t bootscreen_ms = millis(); #endif + SETUP_RUN(settings.first_load()); // Load data from EEPROM if available (or use defaults) + // This also updates variables in the planner, elsewhere + #if ENABLED(PROBE_TARE) SETUP_RUN(probe.tare_init()); #endif diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index d43132e13c82..bdaba1570a68 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -3384,6 +3384,10 @@ #define LCD_HEIGHT TERN(IS_ULTIPANEL, 4, 2) #endif #endif + // Prepare the LCD to show the bootscreen early in setup + #if ENABLED(SHOW_BOOTSCREEN) && ANY(HAS_LCD_CONTRAST, HAS_LCD_BRIGHTNESS) + #define HAS_EARLY_LCD_SETTINGS 1 + #endif #endif #if BUTTONS_EXIST(EN1, EN2, ENC) diff --git a/Marlin/src/module/settings.cpp b/Marlin/src/module/settings.cpp index a9f2f888bff4..d4467b76877d 100644 --- a/Marlin/src/module/settings.cpp +++ b/Marlin/src/module/settings.cpp @@ -778,11 +778,13 @@ void MarlinSettings::postprocess() { #define TWO_BYTE_HASH(A,B) uint16_t((uint16_t(A ^ 0xC3) << 4) ^ (uint16_t(B ^ 0xC3) << 12)) + #define EEPROM_OFFSETOF(FIELD) (EEPROM_OFFSET + offsetof(SettingsData, FIELD)) + #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, \ + eeprom_error || eeprom_index == EEPROM_OFFSETOF(FIELD), \ "Field " STRINGIFY(FIELD) " mismatch." \ ) #else @@ -797,7 +799,7 @@ void MarlinSettings::postprocess() { #define EEPROM_READ_ALWAYS(V...) EEPROM_READ_ALWAYS_(V) #endif - const char version[4] = EEPROM_VERSION; + constexpr char version_str[4] = EEPROM_VERSION; #if ENABLED(EEPROM_INIT_NOW) constexpr uint32_t strhash32(const char *s, const uint32_t h=0) { @@ -827,14 +829,14 @@ void MarlinSettings::postprocess() { */ bool MarlinSettings::save() { float dummyf = 0; - MString<3> ver(F("ERR")); if (!EEPROM_START(EEPROM_OFFSET)) return false; EEPROM_Error eeprom_error = ERR_EEPROM_NOERR; // Write or Skip version. (Flash doesn't allow rewrite without erase.) - TERN(FLASH_EEPROM_EMULATION, EEPROM_SKIP, EEPROM_WRITE)(ver); + constexpr char dummy_version[] = "ERR"; + TERN(FLASH_EEPROM_EMULATION, EEPROM_SKIP, EEPROM_WRITE)(dummy_version); #if ENABLED(EEPROM_INIT_NOW) EEPROM_SKIP(build_hash); // Skip the hash slot which will be written later @@ -1765,7 +1767,7 @@ void MarlinSettings::postprocess() { // Write the EEPROM header eeprom_index = EEPROM_OFFSET; - EEPROM_WRITE(version); + EEPROM_WRITE(version_str); #if ENABLED(EEPROM_INIT_NOW) EEPROM_WRITE(build_hash); #endif @@ -1797,29 +1799,39 @@ void MarlinSettings::postprocess() { return success; } + EEPROM_Error MarlinSettings::check_version() { + if (!EEPROM_START(EEPROM_OFFSET)) return ERR_EEPROM_NOPROM; + char stored_ver[4]; + EEPROM_READ_ALWAYS(stored_ver); + + // Version has to match or defaults are used + if (strncmp(stored_ver, version_str, 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 ")"); + return ERR_EEPROM_VERSION; + } + return ERR_EEPROM_NOERR; + } + /** * M501 - Retrieve Configuration */ EEPROM_Error MarlinSettings::_load() { EEPROM_Error eeprom_error = ERR_EEPROM_NOERR; - if (!EEPROM_START(EEPROM_OFFSET)) return eeprom_error; - - char stored_ver[4]; - EEPROM_READ_ALWAYS(stored_ver); + const EEPROM_Error check = check_version(); + if (check == ERR_EEPROM_VERSION) return eeprom_error; 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; + if (check == ERR_EEPROM_VERSION) { + eeprom_error = check; break; } @@ -2880,8 +2892,7 @@ void MarlinSettings::postprocess() { } else if (!validating) { DEBUG_ECHO_START(); - DEBUG_ECHO(version); - DEBUG_ECHOLNPGM(" stored settings retrieved (", eeprom_total, " bytes; crc ", working_crc, ")"); + DEBUG_ECHOLN(version_str, F(" stored settings retrieved ("), eeprom_total, F(" bytes; crc "), working_crc, ')'); TERN_(HOST_EEPROM_CHITCHAT, hostui.notify(F("Stored settings retrieved"))); } @@ -2967,6 +2978,26 @@ void MarlinSettings::postprocess() { return (err == ERR_EEPROM_NOERR); } + #if HAS_EARLY_LCD_SETTINGS + + #if HAS_LCD_CONTRAST + void MarlinSettings::load_contrast() { + uint8_t lcd_contrast; EEPROM_START(EEPROM_OFFSETOF(lcd_contrast)); EEPROM_READ(lcd_contrast); + DEBUG_ECHOLNPGM("LCD Contrast: ", lcd_contrast); + ui.contrast = lcd_contrast; + } + #endif + + #if HAS_LCD_BRIGHTNESS + void MarlinSettings::load_brightness() { + uint8_t lcd_brightness; EEPROM_START(EEPROM_OFFSETOF(lcd_brightness)); EEPROM_READ(lcd_brightness); + DEBUG_ECHOLNPGM("LCD Brightness: ", lcd_brightness); + ui.brightness = lcd_brightness; + } + #endif + + #endif // HAS_EARLY_LCD_SETTINGS + bool MarlinSettings::load() { if (validate()) { const EEPROM_Error err = _load(); @@ -3117,6 +3148,25 @@ void MarlinSettings::postprocess() { #endif // !EEPROM_SETTINGS +#if HAS_EARLY_LCD_SETTINGS + + void MarlinSettings::load_lcd_state() { + if (TERN0(EEPROM_SETTINGS, check_version() == ERR_EEPROM_NOERR)) { + #if ENABLED(EEPROM_SETTINGS) + TERN_(HAS_LCD_CONTRAST, load_contrast()); + TERN_(HAS_LCD_BRIGHTNESS, load_brightness()); + #endif + } + else { + TERN_(HAS_LCD_CONTRAST, ui.contrast = LCD_CONTRAST_DEFAULT); + TERN_(HAS_LCD_BRIGHTNESS, ui.brightness = LCD_BRIGHTNESS_DEFAULT); + } + TERN_(HAS_LCD_CONTRAST, ui.refresh_contrast()); + TERN_(HAS_LCD_BRIGHTNESS, ui.refresh_brightness()); + } + +#endif // HAS_EARLY_LCD_SETTINGS + /** * M502 - Reset Configuration */ diff --git a/Marlin/src/module/settings.h b/Marlin/src/module/settings.h index b7c5210db5b2..f181e4014dae 100644 --- a/Marlin/src/module/settings.h +++ b/Marlin/src/module/settings.h @@ -34,7 +34,8 @@ ERR_EEPROM_VERSION, ERR_EEPROM_SIZE, ERR_EEPROM_CRC, - ERR_EEPROM_CORRUPT + ERR_EEPROM_CORRUPT, + ERR_EEPROM_NOPROM }; #endif @@ -66,11 +67,24 @@ class MarlinSettings { static bool load(); // Return 'true' if data was loaded ok static bool validate(); // Return 'true' if EEPROM data is ok + static EEPROM_Error check_version(); + static void first_load() { static bool loaded = false; if (!loaded && load()) loaded = true; } + #if HAS_EARLY_LCD_SETTINGS + // Special cases for LCD contrast and brightness, so + // some LCDs can display bootscreens earlier in setup(). + #if HAS_LCD_CONTRAST + static void load_contrast(); + #endif + #if HAS_LCD_BRIGHTNESS + static void load_brightness(); + #endif + #endif + #if ENABLED(AUTO_BED_LEVELING_UBL) // Eventually make these available if any leveling system // That can store is enabled static uint16_t meshes_start_index(); @@ -93,6 +107,10 @@ class MarlinSettings { #endif // !EEPROM_SETTINGS + #if HAS_EARLY_LCD_SETTINGS + static void load_lcd_state(); + #endif + #if DISABLED(DISABLE_M503) static void report(const bool forReplay=false); #else From 96e3dfed4620bfd6d2b1a8e9e63f39cc23634630 Mon Sep 17 00:00:00 2001 From: thisiskeithb <13375512+thisiskeithb@users.noreply.github.com> Date: Thu, 27 Jun 2024 14:08:14 -0700 Subject: [PATCH 16/24] =?UTF-8?q?=F0=9F=A9=B9=20Fix/Add=20Malyan=20M300=20?= =?UTF-8?q?E0=5FAUTO=5FFAN=5FPIN?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/pins/stm32f0/pins_MALYAN_M300.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Marlin/src/pins/stm32f0/pins_MALYAN_M300.h b/Marlin/src/pins/stm32f0/pins_MALYAN_M300.h index c55c63aa29b6..ba6263cd74f0 100644 --- a/Marlin/src/pins/stm32f0/pins_MALYAN_M300.h +++ b/Marlin/src/pins/stm32f0/pins_MALYAN_M300.h @@ -90,4 +90,6 @@ #define HEATER_0_PIN PA1 // HOTEND0 MOSFET #define HEATER_BED_PIN PA5 // BED MOSFET -#define AUTO_FAN_PIN PA8 +#ifndef E0_AUTO_FAN_PIN + #define E0_AUTO_FAN_PIN PA8 +#endif From 13290e798b415664100e23cdcac76b268a716168 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Fri, 28 Jun 2024 00:22:46 +0000 Subject: [PATCH 17/24] [cron] Bump distribution date (2024-06-28) --- Marlin/Version.h | 2 +- Marlin/src/inc/Version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/Version.h b/Marlin/Version.h index 697e7325d35c..8a983e207503 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -41,7 +41,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2024-06-27" +//#define STRING_DISTRIBUTION_DATE "2024-06-28" /** * Defines a generic printer name to be output to the LCD after booting Marlin. diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index c9fa45c2ee0a..8ec891a98c5a 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2024-06-27" + #define STRING_DISTRIBUTION_DATE "2024-06-28" #endif /** From 563296fc8be3fc08d646473bbfb6202966414eaa Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 28 Jun 2024 12:51:51 -0500 Subject: [PATCH 18/24] =?UTF-8?q?=F0=9F=A9=B9=20LCD=5FCONTRAST=20=3D>=20LC?= =?UTF-8?q?D=5FCONTRAST=5FINIT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h | 2 +- Marlin/src/pins/stm32f4/pins_BLACKBEEZMINI.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h b/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h index 4c5cccfab125..a01833db0362 100644 --- a/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h +++ b/Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h @@ -334,7 +334,7 @@ #define LCD_BACKLIGHT_PIN -1 #define NEOPIXEL_PIN EXP1_07_PIN - #define LCD_CONTRAST 255 + #define LCD_CONTRAST_INIT 255 #define DOGLCD_CS EXP1_03_PIN #define DOGLCD_A0 EXP1_01_PIN diff --git a/Marlin/src/pins/stm32f4/pins_BLACKBEEZMINI.h b/Marlin/src/pins/stm32f4/pins_BLACKBEEZMINI.h index ead1ee5e05ba..64cce5630220 100644 --- a/Marlin/src/pins/stm32f4/pins_BLACKBEEZMINI.h +++ b/Marlin/src/pins/stm32f4/pins_BLACKBEEZMINI.h @@ -166,7 +166,7 @@ // // GLCD features // - //#define LCD_CONTRAST 190 + //#define LCD_CONTRAST_INIT 190 // // Dcreen orientation From f84a97f51c789a6de394ca12a788938caa3c0a76 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Sat, 29 Jun 2024 00:22:24 +0000 Subject: [PATCH 19/24] [cron] Bump distribution date (2024-06-29) --- Marlin/Version.h | 2 +- Marlin/src/inc/Version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/Version.h b/Marlin/Version.h index 8a983e207503..4f0d5d8703d1 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -41,7 +41,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2024-06-28" +//#define STRING_DISTRIBUTION_DATE "2024-06-29" /** * Defines a generic printer name to be output to the LCD after booting Marlin. diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 8ec891a98c5a..ba35bb82cc05 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2024-06-28" + #define STRING_DISTRIBUTION_DATE "2024-06-29" #endif /** From b6284c9f0136c6eec2cee65854745374d5aa0e11 Mon Sep 17 00:00:00 2001 From: David Buezas Date: Sat, 29 Jun 2024 22:43:08 +0200 Subject: [PATCH 20/24] =?UTF-8?q?=F0=9F=9A=B8=20Skip=20REINIT=5FNOISY=5FLC?= =?UTF-8?q?D=20for=20I2C=20OLED=20(#27222)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/inc/Conditionals_post.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index bdaba1570a68..d1524cf82a12 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -557,7 +557,7 @@ #endif #endif - #if HAS_SD_DETECT && NONE(HAS_GRAPHICAL_TFT, LCD_USE_DMA_FSMC, HAS_FSMC_GRAPHICAL_TFT, HAS_SPI_GRAPHICAL_TFT, IS_DWIN_MARLINUI, EXTENSIBLE_UI, HAS_DWIN_E3V2) + #if HAS_SD_DETECT && NONE(HAS_GRAPHICAL_TFT, LCD_USE_DMA_FSMC, HAS_FSMC_GRAPHICAL_TFT, HAS_SPI_GRAPHICAL_TFT, IS_DWIN_MARLINUI, EXTENSIBLE_UI, HAS_DWIN_E3V2, HAS_U8GLIB_I2C_OLED) #define REINIT_NOISY_LCD 1 // Have the LCD re-init on SD insertion #endif From c95825a0ff58e8b9f8cced4a93431c4b70f89a86 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sat, 29 Jun 2024 15:50:35 -0500 Subject: [PATCH 21/24] =?UTF-8?q?=F0=9F=94=A7=20Simplify=20sensitive=20pin?= =?UTF-8?q?s=20(#27219)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/HAL/AVR/HAL.h | 2 +- Marlin/src/HAL/LPC1768/HAL.h | 2 +- Marlin/src/HAL/STM32/inc/Conditionals_adv.h | 3 - Marlin/src/MarlinCore.cpp | 21 +- Marlin/src/pins/sensitive_pins.h | 1435 +++++++------------ 5 files changed, 517 insertions(+), 946 deletions(-) diff --git a/Marlin/src/HAL/AVR/HAL.h b/Marlin/src/HAL/AVR/HAL.h index d131985916ec..717bc7e3fe93 100644 --- a/Marlin/src/HAL/AVR/HAL.h +++ b/Marlin/src/HAL/AVR/HAL.h @@ -159,7 +159,7 @@ typedef Servo hal_servo_t; #define GET_PIN_MAP_INDEX(pin) pin #define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval) -#define HAL_SENSITIVE_PINS 0, 1, +#define HAL_SENSITIVE_PINS 0, 1 #ifdef __AVR_AT90USB1286__ #define JTAG_DISABLE() do{ MCUCR = 0x80; MCUCR = 0x80; }while(0) diff --git a/Marlin/src/HAL/LPC1768/HAL.h b/Marlin/src/HAL/LPC1768/HAL.h index c3c984c76ea6..dfa090210f14 100644 --- a/Marlin/src/HAL/LPC1768/HAL.h +++ b/Marlin/src/HAL/LPC1768/HAL.h @@ -159,7 +159,7 @@ constexpr pin_t GET_PIN_MAP_PIN(const int16_t index) { // Parse a G-code word into a pin index int16_t PARSED_PIN_INDEX(const char code, const int16_t dval); // P0.6 thru P0.9 are for the onboard SD card -#define HAL_SENSITIVE_PINS P0_06, P0_07, P0_08, P0_09, +#define HAL_SENSITIVE_PINS P0_06, P0_07, P0_08, P0_09 // ------------------------ // Defines diff --git a/Marlin/src/HAL/STM32/inc/Conditionals_adv.h b/Marlin/src/HAL/STM32/inc/Conditionals_adv.h index 032716a294ce..f345b925bbb4 100644 --- a/Marlin/src/HAL/STM32/inc/Conditionals_adv.h +++ b/Marlin/src/HAL/STM32/inc/Conditionals_adv.h @@ -30,6 +30,3 @@ #undef F_CPU #define F_CPU BOARD_F_CPU #endif - -// The Sensitive Pins array is not optimizable -#define RUNTIME_ONLY_ANALOG_TO_DIGITAL diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index f297951d828a..be81388f3896 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -308,23 +308,12 @@ bool wait_for_heatup = false; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnarrowing" -#ifndef RUNTIME_ONLY_ANALOG_TO_DIGITAL - template - constexpr pin_t OnlyPins<_SP_END, D...>::table[sizeof...(D)]; -#endif - bool pin_is_protected(const pin_t pin) { - #ifdef RUNTIME_ONLY_ANALOG_TO_DIGITAL - static const pin_t sensitive_pins[] PROGMEM = { SENSITIVE_PINS }; - const size_t pincount = COUNT(sensitive_pins); - #else - static constexpr size_t pincount = OnlyPins::size; - static const pin_t (&sensitive_pins)[pincount] PROGMEM = OnlyPins::table; - #endif - for (uint8_t i = 0; i < pincount; ++i) { - const pin_t * const pptr = &sensitive_pins[i]; - if (pin == (sizeof(pin_t) == 2 ? (pin_t)pgm_read_word(pptr) : (pin_t)pgm_read_byte(pptr))) return true; - } + #define pgm_read_pin(P) (sizeof(pin_t) == 2 ? (pin_t)pgm_read_word(P) : (pin_t)pgm_read_byte(P)) + for (uint8_t i = 0; i < COUNT(sensitive_dio); ++i) + if (pin == pgm_read_pin(&sensitive_dio[i])) return true; + for (uint8_t i = 0; i < COUNT(sensitive_aio); ++i) + if (pin == analogInputToDigitalPin(pgm_read_pin(&sensitive_dio[i]))) return true; return false; } diff --git a/Marlin/src/pins/sensitive_pins.h b/Marlin/src/pins/sensitive_pins.h index 7264a2653968..0c6592ea934c 100644 --- a/Marlin/src/pins/sensitive_pins.h +++ b/Marlin/src/pins/sensitive_pins.h @@ -21,1003 +21,588 @@ */ #pragma once +#include + // -// Prepare a list of protected pins for M42/M43 +// Define unsorted and arrays of pins which may have duplicstes, +// but don't allocate any runtime memory for these arrays. +// We'll use constexpr functions to get the Nth distinct value, +// and return -1 if we go past the end of the array. // -#if HAS_X_AXIS +constexpr pin_t sensitive_dio[] PROGMEM = { - #if PIN_EXISTS(X_MIN) - #define _X_MIN X_MIN_PIN, - #else - #define _X_MIN - #endif - #if PIN_EXISTS(X_MAX) - #define _X_MAX X_MAX_PIN, - #else - #define _X_MAX - #endif - #if PIN_EXISTS(X_CS) && AXIS_HAS_SPI(X) - #define _X_CS X_CS_PIN, - #else - #define _X_CS - #endif - #if PIN_EXISTS(X_MS1) - #define _X_MS1 X_MS1_PIN, - #else - #define _X_MS1 - #endif - #if PIN_EXISTS(X_MS2) - #define _X_MS2 X_MS2_PIN, - #else - #define _X_MS2 - #endif - #if PIN_EXISTS(X_MS3) - #define _X_MS3 X_MS3_PIN, - #else - #define _X_MS3 - #endif - #if PIN_EXISTS(X_ENABLE) - #define _X_ENABLE_PIN X_ENABLE_PIN, - #else - #define _X_ENABLE_PIN + #if HAS_X_AXIS + #if PIN_EXISTS(X_MIN) + X_MIN_PIN, + #endif + #if PIN_EXISTS(X_MAX) + X_MAX_PIN, + #endif + #if PIN_EXISTS(X_CS) && AXIS_HAS_SPI(X) + X_CS_PIN, + #endif + #if PIN_EXISTS(X_MS1) + X_MS1_PIN, + #endif + #if PIN_EXISTS(X_MS2) + X_MS2_PIN, + #endif + #if PIN_EXISTS(X_MS3) + X_MS3_PIN, + #endif + #if PIN_EXISTS(X_ENABLE) + X_ENABLE_PIN, + #endif #endif - #define _X_PINS X_STEP_PIN, X_DIR_PIN, _X_ENABLE_PIN _X_MIN _X_MAX _X_MS1 _X_MS2 _X_MS3 _X_CS - -#else - - #define _X_PINS - -#endif - -#if HAS_Y_AXIS - - #if PIN_EXISTS(Y_MIN) - #define _Y_MIN Y_MIN_PIN, - #else - #define _Y_MIN - #endif - #if PIN_EXISTS(Y_MAX) - #define _Y_MAX Y_MAX_PIN, - #else - #define _Y_MAX - #endif - #if PIN_EXISTS(Y_CS) && AXIS_HAS_SPI(Y) - #define _Y_CS Y_CS_PIN, - #else - #define _Y_CS - #endif - #if PIN_EXISTS(Y_MS1) - #define _Y_MS1 Y_MS1_PIN, - #else - #define _Y_MS1 - #endif - #if PIN_EXISTS(Y_MS2) - #define _Y_MS2 Y_MS2_PIN, - #else - #define _Y_MS2 - #endif - #if PIN_EXISTS(Y_MS3) - #define _Y_MS3 Y_MS3_PIN, - #else - #define _Y_MS3 - #endif - #if PIN_EXISTS(Y_ENABLE) - #define _Y_ENABLE_PIN Y_ENABLE_PIN, - #else - #define _Y_ENABLE_PIN + #if HAS_Y_AXIS + #if PIN_EXISTS(Y_MIN) + Y_MIN_PIN, + #endif + #if PIN_EXISTS(Y_MAX) + Y_MAX_PIN, + #endif + #if PIN_EXISTS(Y_CS) && AXIS_HAS_SPI(Y) + Y_CS_PIN, + #endif + #if PIN_EXISTS(Y_MS1) + Y_MS1_PIN, + #endif + #if PIN_EXISTS(Y_MS2) + Y_MS2_PIN, + #endif + #if PIN_EXISTS(Y_MS3) + Y_MS3_PIN, + #endif + #if PIN_EXISTS(Y_ENABLE) + Y_ENABLE_PIN, + #endif #endif - #define _Y_PINS Y_STEP_PIN, Y_DIR_PIN, _Y_ENABLE_PIN _Y_MIN _Y_MAX _Y_MS1 _Y_MS2 _Y_MS3 _Y_CS - -#else - - #define _Y_PINS - -#endif - -#if HAS_Z_AXIS - - #if PIN_EXISTS(Z_MIN) - #define _Z_MIN Z_MIN_PIN, - #else - #define _Z_MIN - #endif - #if PIN_EXISTS(Z_MAX) - #define _Z_MAX Z_MAX_PIN, - #else - #define _Z_MAX - #endif - #if PIN_EXISTS(Z_CS) && AXIS_HAS_SPI(Z) - #define _Z_CS Z_CS_PIN, - #else - #define _Z_CS - #endif - #if PIN_EXISTS(Z_MS1) - #define _Z_MS1 Z_MS1_PIN, - #else - #define _Z_MS1 - #endif - #if PIN_EXISTS(Z_MS2) - #define _Z_MS2 Z_MS2_PIN, - #else - #define _Z_MS2 - #endif - #if PIN_EXISTS(Z_MS3) - #define _Z_MS3 Z_MS3_PIN, - #else - #define _Z_MS3 - #endif - #if PIN_EXISTS(Z_ENABLE) - #define _Z_ENABLE_PIN Z_ENABLE_PIN, - #else - #define _Z_ENABLE_PIN + #if HAS_Z_AXIS + #if PIN_EXISTS(Z_MIN) + Z_MIN_PIN, + #endif + #if PIN_EXISTS(Z_MAX) + Z_MAX_PIN, + #endif + #if PIN_EXISTS(Z_CS) && AXIS_HAS_SPI(Z) + Z_CS_PIN, + #endif + #if PIN_EXISTS(Z_MS1) + Z_MS1_PIN, + #endif + #if PIN_EXISTS(Z_MS2) + Z_MS2_PIN, + #endif + #if PIN_EXISTS(Z_MS3) + Z_MS3_PIN, + #endif + #if PIN_EXISTS(Z_ENABLE) + Z_ENABLE_PIN, + #endif #endif - #define _Z_PINS Z_STEP_PIN, Z_DIR_PIN, _Z_ENABLE_PIN _Z_MIN _Z_MAX _Z_MS1 _Z_MS2 _Z_MS3 _Z_CS - -#else - - #define _Z_PINS - -#endif - -#if HAS_I_AXIS - - #if PIN_EXISTS(I_MIN) - #define _I_MIN I_MIN_PIN, - #else - #define _I_MIN - #endif - #if PIN_EXISTS(I_MAX) - #define _I_MAX I_MAX_PIN, - #else - #define _I_MAX - #endif - #if PIN_EXISTS(I_CS) && AXIS_HAS_SPI(I) - #define _I_CS I_CS_PIN, - #else - #define _I_CS - #endif - #if PIN_EXISTS(I_MS1) - #define _I_MS1 I_MS1_PIN, - #else - #define _I_MS1 - #endif - #if PIN_EXISTS(I_MS2) - #define _I_MS2 I_MS2_PIN, - #else - #define _I_MS2 + #if HAS_I_AXIS + #if PIN_EXISTS(I_MIN) + I_MIN_PIN, + #endif + #if PIN_EXISTS(I_MAX) + I_MAX_PIN, + #endif + #if PIN_EXISTS(I_CS) && AXIS_HAS_SPI(I) + I_CS_PIN, + #endif + #if PIN_EXISTS(I_MS1) + I_MS1_PIN, + #endif + #if PIN_EXISTS(I_MS2) + I_MS2_PIN, + #endif + #if PIN_EXISTS(I_MS3) + I_MS3_PIN, + #endif + #if PIN_EXISTS(I_ENABLE) + I_ENABLE_PIN, + #endif #endif - #if PIN_EXISTS(I_MS3) - #define _I_MS3 I_MS3_PIN, - #else - #define _I_MS3 + + #if HAS_J_AXIS + #if PIN_EXISTS(J_MIN) + J_MIN_PIN, + #endif + #if PIN_EXISTS(J_MAX) + J_MAX_PIN, + #endif + #if PIN_EXISTS(J_CS) && AXIS_HAS_SPI(J) + J_CS_PIN, + #endif + #if PIN_EXISTS(J_MS1) + J_MS1_PIN, + #endif + #if PIN_EXISTS(J_MS2) + J_MS2_PIN, + #endif + #if PIN_EXISTS(J_MS3) + J_MS3_PIN, + #endif + #if PIN_EXISTS(J_ENABLE) + J_ENABLE_PIN, + #endif #endif - #if PIN_EXISTS(I_ENABLE) - #define _I_ENABLE_PIN I_ENABLE_PIN, - #else - #define _I_ENABLE_PIN + + #if HAS_K_AXIS + #if PIN_EXISTS(K_MIN) + K_MIN_PIN, + #endif + #if PIN_EXISTS(K_MAX) + K_MAX_PIN, + #endif + #if PIN_EXISTS(K_CS) && AXIS_HAS_SPI(K) + K_CS_PIN, + #endif + #if PIN_EXISTS(K_MS1) + K_MS1_PIN, + #endif + #if PIN_EXISTS(K_MS2) + K_MS2_PIN, + #endif + #if PIN_EXISTS(K_MS3) + K_MS3_PIN, + #endif + #if PIN_EXISTS(K_ENABLE) + K_ENABLE_PIN, + #endif #endif - #define _I_PINS I_STEP_PIN, I_DIR_PIN, _I_ENABLE_PIN _I_MIN _I_MAX _I_MS1 _I_MS2 _I_MS3 _I_CS + #if HAS_U_AXIS + #if PIN_EXISTS(U_MIN) + U_MIN_PIN, + #endif + #if PIN_EXISTS(U_MAX) + U_MAX_PIN, + #endif + #if PIN_EXISTS(U_CS) && AXIS_HAS_SPI(U) + U_CS_PIN, + #endif + #if PIN_EXISTS(U_MS1) + U_MS1_PIN, + #endif + #if PIN_EXISTS(U_MS2) + U_MS2_PIN, + #endif + #if PIN_EXISTS(U_MS3) + U_MS3_PIN, + #endif + #endif -#else + #if HAS_V_AXIS + #if PIN_EXISTS(V_MIN) + V_MIN_PIN, + #endif + #if PIN_EXISTS(V_MAX) + V_MAX_PIN, + #endif + #if PIN_EXISTS(V_CS) && AXIS_HAS_SPI(V) + V_CS_PIN, + #endif + #if PIN_EXISTS(V_MS1) + V_MS1_PIN, + #endif + #if PIN_EXISTS(V_MS2) + V_MS2_PIN, + #endif + #if PIN_EXISTS(V_MS3) + V_MS3_PIN, + #endif + #endif - #define _I_PINS + #if HAS_W_AXIS + #if PIN_EXISTS(W_MIN) + W_MIN_PIN, + #endif + #if PIN_EXISTS(W_MAX) + W_MAX_PIN, + #endif + #if PIN_EXISTS(W_CS) && AXIS_HAS_SPI(W) + W_CS_PIN, + #endif + #if PIN_EXISTS(W_MS1) + W_MS1_PIN, + #endif + #if PIN_EXISTS(W_MS2) + W_MS2_PIN, + #endif + #if PIN_EXISTS(W_MS3) + W_MS3_PIN, + #endif + #endif -#endif + // + // Extruder Chip Select, Digital Micro-steps + // -#if HAS_J_AXIS + // Mixing stepper, Switching stepper, or regular stepper + #define E_NEEDED(N) (ENABLED(MIXING_EXTRUDER) && MIXING_STEPPERS > N) \ + || (HAS_SWITCHING_EXTRUDER && E_STEPPERS > N) \ + || (NONE(SWITCHING_EXTRUDER, MIXING_EXTRUDER) && EXTRUDERS > N) - #if PIN_EXISTS(J_MIN) - #define _J_MIN J_MIN_PIN, - #else - #define _J_MIN - #endif - #if PIN_EXISTS(J_MAX) - #define _J_MAX J_MAX_PIN, - #else - #define _J_MAX - #endif - #if PIN_EXISTS(J_CS) && AXIS_HAS_SPI(J) - #define _J_CS J_CS_PIN, - #else - #define _J_CS - #endif - #if PIN_EXISTS(J_MS1) - #define _J_MS1 J_MS1_PIN, - #else - #define _J_MS1 + #if E_NEEDED(0) + E0_STEP_PIN, E0_DIR_PIN, E0_ENABLE_PIN, + #if PIN_EXISTS(E0_CS) && AXIS_HAS_SPI(E0) + E0_CS_PIN, + #endif + #if PIN_EXISTS(E0_MS1) + E0_MS1_PIN, + #endif + #if PIN_EXISTS(E0_MS2) + E0_MS2_PIN, + #endif + #if PIN_EXISTS(E0_MS3) + E0_MS3_PIN, + #endif #endif - #if PIN_EXISTS(J_MS2) - #define _J_MS2 J_MS2_PIN, - #else - #define _J_MS2 + + #if E_NEEDED(1) + E1_STEP_PIN, E1_DIR_PIN, E1_ENABLE_PIN, + #if PIN_EXISTS(E1_CS) && AXIS_HAS_SPI(E1) + E1_CS_PIN, + #endif + #if PIN_EXISTS(E1_MS1) + E1_MS1_PIN, + #endif + #if PIN_EXISTS(E1_MS2) + E1_MS2_PIN, + #endif + #if PIN_EXISTS(E1_MS3) + E1_MS3_PIN, + #endif #endif - #if PIN_EXISTS(J_MS3) - #define _J_MS3 J_MS3_PIN, - #else - #define _J_MS3 + + #if E_NEEDED(2) + E2_STEP_PIN, E2_DIR_PIN, E2_ENABLE_PIN, + #if PIN_EXISTS(E2_CS) && AXIS_HAS_SPI(E2) + E2_CS_PIN, + #endif + #if PIN_EXISTS(E2_MS1) + E2_MS1_PIN, + #endif + #if PIN_EXISTS(E2_MS2) + E2_MS2_PIN, + #endif + #if PIN_EXISTS(E2_MS3) + E2_MS3_PIN, + #endif #endif - #if PIN_EXISTS(J_ENABLE) - #define _J_ENABLE_PIN J_ENABLE_PIN, - #else - #define _J_ENABLE_PIN + + #if E_NEEDED(3) + E3_STEP_PIN, E3_DIR_PIN, E3_ENABLE_PIN, + #if PIN_EXISTS(E3_CS) && AXIS_HAS_SPI(E3) + E3_CS_PIN, + #endif + #if PIN_EXISTS(E3_MS1) + E3_MS1_PIN, + #endif + #if PIN_EXISTS(E3_MS2) + E3_MS2_PIN, + #endif + #if PIN_EXISTS(E3_MS3) + E3_MS3_PIN, + #endif #endif - #define _J_PINS J_STEP_PIN, J_DIR_PIN, _J_ENABLE_PIN _J_MIN _J_MAX _J_MS1 _J_MS2 _J_MS3 _J_CS + #if E_NEEDED(4) + E4_STEP_PIN, E4_DIR_PIN, E4_ENABLE_PIN, + #if PIN_EXISTS(E4_CS) && AXIS_HAS_SPI(E4) + E4_CS_PIN, + #endif + #if PIN_EXISTS(E4_MS1) + E4_MS1_PIN, + #endif + #if PIN_EXISTS(E4_MS2) + E4_MS2_PIN, + #endif + #if PIN_EXISTS(E4_MS3) + E4_MS3_PIN, + #endif + #endif -#else + #if E_NEEDED(5) + E5_STEP_PIN, E5_DIR_PIN, E5_ENABLE_PIN, + #if PIN_EXISTS(E5_CS) && AXIS_HAS_SPI(E5) + E5_CS_PIN, + #endif + #if PIN_EXISTS(E5_MS1) + E5_MS1_PIN, + #endif + #if PIN_EXISTS(E5_MS2) + E5_MS2_PIN, + #endif + #if PIN_EXISTS(E5_MS3) + E5_MS3_PIN, + #endif + #endif - #define _J_PINS + #if E_NEEDED(6) + E6_STEP_PIN, E6_DIR_PIN, E6_ENABLE_PIN, + #if PIN_EXISTS(E6_CS) && AXIS_HAS_SPI(E6) + E6_CS_PIN, + #endif + #if PIN_EXISTS(E6_MS2) + E6_MS2_PIN, + #endif + #if PIN_EXISTS(E6_MS3) + E6_MS3_PIN, + #endif + #if PIN_EXISTS(E6_MS4) + E6_MS4_PIN, + #endif + #endif -#endif + #if E_NEEDED(7) + E7_STEP_PIN, E7_DIR_PIN, E7_ENABLE_PIN, + #if PIN_EXISTS(E7_CS) && AXIS_HAS_SPI(E7) + E7_CS_PIN, + #endif + #if PIN_EXISTS(E7_MS3) + E7_MS3_PIN, + #endif + #if PIN_EXISTS(E7_MS4) + E7_MS4_PIN, + #endif + #if PIN_EXISTS(E7_MS5) + E7_MS5_PIN, + #endif + #endif -#if HAS_K_AXIS + // + // Hotend Heaters and Fans + // - #if PIN_EXISTS(K_MIN) - #define _K_MIN K_MIN_PIN, - #else - #define _K_MIN - #endif - #if PIN_EXISTS(K_MAX) - #define _K_MAX K_MAX_PIN, - #else - #define _K_MAX - #endif - #if PIN_EXISTS(K_CS) && AXIS_HAS_SPI(K) - #define _K_CS K_CS_PIN, - #else - #define _K_CS - #endif - #if PIN_EXISTS(K_MS1) - #define _K_MS1 K_MS1_PIN, - #else - #define _K_MS1 - #endif - #if PIN_EXISTS(K_MS2) - #define _K_MS2 K_MS2_PIN, - #else - #define _K_MS2 - #endif - #if PIN_EXISTS(K_MS3) - #define _K_MS3 K_MS3_PIN, - #else - #define _K_MS3 + #if HAS_HOTEND + HEATER_0_PIN, + #if PIN_EXISTS(E0_AUTO_FAN) + E0_AUTO_FAN_PIN, + #endif #endif - #if PIN_EXISTS(K_ENABLE) - #define _K_ENABLE_PIN K_ENABLE_PIN, - #else - #define _K_ENABLE_PIN + #if HAS_MULTI_HOTEND + HEATER_1_PIN, + #if PIN_EXISTS(E1_AUTO_FAN) + E1_AUTO_FAN_PIN, + #endif #endif - - #define _K_PINS K_STEP_PIN, K_DIR_PIN, _K_ENABLE_PIN _K_MIN _K_MAX _K_MS1 _K_MS2 _K_MS3 _K_CS - -#else - - #define _K_PINS - -#endif - -#if HAS_U_AXIS - #if PIN_EXISTS(U_MIN) - #define _U_MIN U_MIN_PIN, - #else - #define _U_MIN + #if HOTENDS > 2 + HEATER_2_PIN, + #if PIN_EXISTS(E2_AUTO_FAN) + E2_AUTO_FAN_PIN, + #endif #endif - #if PIN_EXISTS(U_MAX) - #define _U_MAX U_MAX_PIN, - #else - #define _U_MAX + #if HOTENDS > 3 + HEATER_3_PIN, + #if PIN_EXISTS(E3_AUTO_FAN) + E3_AUTO_FAN_PIN, + #endif #endif - #if PIN_EXISTS(U_CS) && AXIS_HAS_SPI(U) - #define _U_CS U_CS_PIN, - #else - #define _U_CS + #if HOTENDS > 4 + HEATER_4_PIN, + #if PIN_EXISTS(E4_AUTO_FAN) + E4_AUTO_FAN_PIN, + #endif #endif - #if PIN_EXISTS(U_MS1) - #define _U_MS1 U_MS1_PIN, - #else - #define _U_MS1 + #if HOTENDS > 5 + HEATER_5_PIN, + #if PIN_EXISTS(E5_AUTO_FAN) + E5_AUTO_FAN_PIN, + #endif #endif - #if PIN_EXISTS(U_MS2) - #define _U_MS2 U_MS2_PIN, - #else - #define _U_MS2 + #if HOTENDS > 6 + HEATER_6_PIN, + #if PIN_EXISTS(E6_AUTO_FAN) + E6_AUTO_FAN_PIN, + #endif #endif - #if PIN_EXISTS(U_MS3) - #define _U_MS3 U_MS3_PIN, - #else - #define _U_MS3 + #if HOTENDS > 7 + HEATER_7_PIN, + #if PIN_EXISTS(E7_AUTO_FAN) + E7_AUTO_FAN_PIN, + #endif #endif - #define _U_PINS U_STEP_PIN, U_DIR_PIN, U_ENABLE_PIN, _U_MIN _U_MAX _U_MS1 _U_MS2 _U_MS3 _U_CS - -#else - - #define _U_PINS + // + // Dual X, Dual Y, Multi-Z + // Chip Select and Digital Micro-stepping + // -#endif - -#if HAS_V_AXIS - #if PIN_EXISTS(V_MIN) - #define _V_MIN V_MIN_PIN, - #else - #define _V_MIN - #endif - #if PIN_EXISTS(V_MAX) - #define _V_MAX V_MAX_PIN, - #else - #define _V_MAX - #endif - #if PIN_EXISTS(V_CS) && AXIS_HAS_SPI(V) - #define _V_CS V_CS_PIN, - #else - #define _V_CS - #endif - #if PIN_EXISTS(V_MS1) - #define _V_MS1 V_MS1_PIN, - #else - #define _V_MS1 - #endif - #if PIN_EXISTS(V_MS2) - #define _V_MS2 V_MS2_PIN, - #else - #define _V_MS2 + #if HAS_X2_STEPPER + #if PIN_EXISTS(X2_CS) && AXIS_HAS_SPI(X2) + X2_CS_PIN, + #endif + #if PIN_EXISTS(X2_MS1) + X2_MS1_PIN, + #endif + #if PIN_EXISTS(X2_MS2) + X2_MS2_PIN, + #endif + #if PIN_EXISTS(X2_MS3) + X2_MS3_PIN, + #endif #endif - #if PIN_EXISTS(V_MS3) - #define _V_MS3 V_MS3_PIN, - #else - #define _V_MS3 + + #if HAS_Y2_STEPPER + #if PIN_EXISTS(Y2_CS) && AXIS_HAS_SPI(Y2) + Y2_CS_PIN, + #endif + #if PIN_EXISTS(Y2_MS1) + Y2_MS1_PIN, + #endif + #if PIN_EXISTS(Y2_MS2) + Y2_MS2_PIN, + #endif + #if PIN_EXISTS(Y2_MS3) + Y2_MS3_PIN, + #endif #endif - #define _V_PINS V_STEP_PIN, V_DIR_PIN, V_ENABLE_PIN, _V_MIN _V_MAX _V_MS1 _V_MS2 _V_MS3 _V_CS + #if NUM_Z_STEPPERS >= 2 + #if PIN_EXISTS(Z2_CS) && AXIS_HAS_SPI(Z2) + Z2_CS_PIN, + #endif + #if PIN_EXISTS(Z2_MS1) + Z2_MS1_PIN, + #endif + #if PIN_EXISTS(Z2_MS2) + Z2_MS2_PIN, + #endif + #if PIN_EXISTS(Z2_MS3) + Z2_MS3_PIN, + #endif + #endif -#else + #if NUM_Z_STEPPERS >= 3 + #if PIN_EXISTS(Z3_CS) && AXIS_HAS_SPI(Z3) + Z3_CS_PIN, + #endif + #if PIN_EXISTS(Z3_MS1) + Z3_MS1_PIN, + #endif + #if PIN_EXISTS(Z3_MS2) + Z3_MS2_PIN, + #endif + #if PIN_EXISTS(Z3_MS3) + Z3_MS3_PIN, + #endif + #endif - #define _V_PINS + #if NUM_Z_STEPPERS >= 4 + #if PIN_EXISTS(Z4_CS) && AXIS_HAS_SPI(Z4) + Z4_CS_PIN, + #endif + #if PIN_EXISTS(Z4_MS1) + Z4_MS1_PIN, + #endif + #if PIN_EXISTS(Z4_MS2) + Z4_MS2_PIN, + #endif + #if PIN_EXISTS(Z4_MS3) + Z4_MS3_PIN, + #endif + #endif -#endif + #if PIN_EXISTS(PS_ON) + PS_ON_PIN, + #endif -#if HAS_W_AXIS - #if PIN_EXISTS(W_MIN) - #define _W_MIN W_MIN_PIN, - #else - #define _W_MIN + #if HAS_BED_PROBE && PIN_EXISTS(Z_MIN_PROBE) + Z_MIN_PROBE_PIN, #endif - #if PIN_EXISTS(W_MAX) - #define _W_MAX W_MAX_PIN, - #else - #define _W_MAX + + #if PIN_EXISTS(FAN0) + FAN0_PIN, #endif - #if PIN_EXISTS(W_CS) && AXIS_HAS_SPI(W) - #define _W_CS W_CS_PIN, - #else - #define _W_CS + #if PIN_EXISTS(FAN1) + FAN1_PIN, #endif - #if PIN_EXISTS(W_MS1) - #define _W_MS1 W_MS1_PIN, - #else - #define _W_MS1 + #if PIN_EXISTS(FAN2) + FAN2_PIN, #endif - #if PIN_EXISTS(W_MS2) - #define _W_MS2 W_MS2_PIN, - #else - #define _W_MS2 + #if PIN_EXISTS(FAN3) + FAN3_PIN, #endif - #if PIN_EXISTS(W_MS3) - #define _W_MS3 W_MS3_PIN, - #else - #define _W_MS3 + #if PIN_EXISTS(FAN4) + FAN4_PIN, #endif - - #define _W_PINS W_STEP_PIN, W_DIR_PIN, W_ENABLE_PIN, _W_MIN _W_MAX _W_MS1 _W_MS2 _W_MS3 _W_CS - -#else - - #define _W_PINS - -#endif - -// -// Extruder Chip Select, Digital Micro-steps -// - -// Mixing stepper, Switching stepper, or regular stepper -#define E_NEEDED(N) (ENABLED(MIXING_EXTRUDER) && MIXING_STEPPERS > N) \ - || (HAS_SWITCHING_EXTRUDER && E_STEPPERS > N) \ - || (NONE(SWITCHING_EXTRUDER, MIXING_EXTRUDER) && EXTRUDERS > N) - -#define _E0_CS -#define _E0_MS1 -#define _E0_MS2 -#define _E0_MS3 - -#if E_NEEDED(0) - #if PIN_EXISTS(E0_CS) && AXIS_HAS_SPI(E0) - #undef _E0_CS - #define _E0_CS E0_CS_PIN, + #if PIN_EXISTS(FAN5) + FAN5_PIN, #endif - #if PIN_EXISTS(E0_MS1) - #undef _E0_MS1 - #define _E0_MS1 E0_MS1_PIN, + #if PIN_EXISTS(FAN6) + FAN6_PIN, #endif - #if PIN_EXISTS(E0_MS2) - #undef _E0_MS2 - #define _E0_MS2 E0_MS2_PIN, + #if PIN_EXISTS(FAN7) + FAN7_PIN, #endif - #if PIN_EXISTS(E0_MS3) - #undef _E0_MS3 - #define _E0_MS3 E0_MS3_PIN, + #if PIN_EXISTS(CONTROLLER_FAN) + CONTROLLER_FAN_PIN, #endif -#endif -#define _E1_CS -#define _E1_MS1 -#define _E1_MS2 -#define _E1_MS3 - -#if E_NEEDED(1) - #if PIN_EXISTS(E1_CS) && AXIS_HAS_SPI(E1) - #undef _E1_CS - #define _E1_CS E1_CS_PIN, - #endif - #if PIN_EXISTS(E1_MS1) - #undef _E1_MS1 - #define _E1_MS1 E1_MS1_PIN, + #if TEMP_SENSOR_BED && PINS_EXIST(TEMP_BED, HEATER_BED) + HEATER_BED_PIN, #endif - #if PIN_EXISTS(E1_MS2) - #undef _E1_MS2 - #define _E1_MS2 E1_MS2_PIN, - #endif - #if PIN_EXISTS(E1_MS3) - #undef _E1_MS3 - #define _E1_MS3 E1_MS3_PIN, - #endif -#endif -#define _E2_CS -#define _E2_MS1 -#define _E2_MS2 -#define _E2_MS3 - -#if E_NEEDED(2) - #if PIN_EXISTS(E2_CS) && AXIS_HAS_SPI(E2) - #undef _E2_CS - #define _E2_CS E2_CS_PIN, - #endif - #if PIN_EXISTS(E2_MS1) - #undef _E2_MS1 - #define _E2_MS1 E2_MS1_PIN, - #endif - #if PIN_EXISTS(E2_MS2) - #undef _E2_MS2 - #define _E2_MS2 E2_MS2_PIN, - #endif - #if PIN_EXISTS(E2_MS3) - #undef _E2_MS3 - #define _E2_MS3 E2_MS3_PIN, + #if TEMP_SENSOR_CHAMBER && PIN_EXISTS(TEMP_CHAMBER) + #if PIN_EXISTS(HEATER_CHAMBER) + HEATER_CHAMBER_PIN, + #endif + #if PIN_EXISTS(CHAMBER_AUTO_FAN) + CHAMBER_AUTO_FAN_PIN, + #endif #endif -#endif -#define _E3_CS -#define _E3_MS1 -#define _E3_MS2 -#define _E3_MS3 - -#if E_NEEDED(3) - #if PIN_EXISTS(E3_CS) && AXIS_HAS_SPI(E3) - #undef _E3_CS - #define _E3_CS E3_CS_PIN, - #endif - #if PIN_EXISTS(E3_MS1) - #undef _E3_MS1 - #define _E3_MS1 E3_MS1_PIN, - #endif - #if PIN_EXISTS(E3_MS2) - #undef _E3_MS2 - #define _E3_MS2 E3_MS2_PIN, - #endif - #if PIN_EXISTS(E3_MS3) - #undef _E3_MS3 - #define _E3_MS3 E3_MS3_PIN, + #if TEMP_SENSOR_COOLER && PIN_EXISTS(TEMP_COOLER) + #if PIN_EXISTS(COOLER_AUTO_FAN) + COOLER_AUTO_FAN_PIN, + #endif + #if PIN_EXISTS(COOLER) + COOLER_PIN, + #endif #endif -#endif - -#define _E4_CS -#define _E4_MS1 -#define _E4_MS2 -#define _E4_MS3 -#if E_NEEDED(4) - #if PIN_EXISTS(E4_CS) && AXIS_HAS_SPI(E4) - #undef _E4_CS - #define _E4_CS E4_CS_PIN, + #ifdef HAL_SENSITIVE_PINS + HAL_SENSITIVE_PINS #endif - #if PIN_EXISTS(E4_MS1) - #undef _E4_MS1 - #define _E4_MS1 E4_MS1_PIN, - #endif - #if PIN_EXISTS(E4_MS2) - #undef _E4_MS2 - #define _E4_MS2 E4_MS2_PIN, - #endif - #if PIN_EXISTS(E4_MS3) - #undef _E4_MS3 - #define _E4_MS3 E4_MS3_PIN, - #endif -#endif - -#define _E5_CS -#define _E5_MS1 -#define _E5_MS2 -#define _E5_MS3 +}; -#if E_NEEDED(5) - #if PIN_EXISTS(E5_CS) && AXIS_HAS_SPI(E5) - #undef _E5_CS - #define _E5_CS E5_CS_PIN, +constexpr pin_t sensitive_aio[] PROGMEM = { + #if HAS_HOTEND + TEMP_0_PIN, #endif - #if PIN_EXISTS(E5_MS1) - #undef _E5_MS1 - #define _E5_MS1 E5_MS1_PIN, - #endif - #if PIN_EXISTS(E5_MS2) - #undef _E5_MS2 - #define _E5_MS2 E5_MS2_PIN, + #if HAS_MULTI_HOTEND + TEMP_1_PIN, #endif - #if PIN_EXISTS(E5_MS3) - #undef _E5_MS3 - #define _E5_MS3 E5_MS3_PIN, + #if HOTENDS > 2 + TEMP_2_PIN, #endif -#endif - -#define _E6_CS -#define _E6_MS1 -#define _E6_MS2 -#define _E6_MS3 - -#if E_NEEDED(6) - #if PIN_EXISTS(E6_CS) && AXIS_HAS_SPI(E6) - #undef _E6_CS - #define _E6_CS E6_CS_PIN, + #if HOTENDS > 3 + TEMP_3_PIN, #endif - #if PIN_EXISTS(E6_MS2) - #undef _E6_MS2 - #define _E6_MS2 E6_MS2_PIN, + #if HOTENDS > 4 + TEMP_4_PIN, #endif - #if PIN_EXISTS(E6_MS3) - #undef _E6_MS3 - #define _E6_MS3 E6_MS3_PIN, + #if HOTENDS > 5 + TEMP_5_PIN, #endif - #if PIN_EXISTS(E6_MS4) - #undef _E6_MS4 - #define _E6_MS4 E6_MS4_PIN, + #if HOTENDS > 6 + TEMP_6_PIN, #endif -#endif - -#define _E7_CS -#define _E7_MS1 -#define _E7_MS2 -#define _E7_MS3 - -#if E_NEEDED(7) - #if PIN_EXISTS(E7_CS) && AXIS_HAS_SPI(E7) - #undef _E7_CS - #define _E7_CS E7_CS_PIN, + #if HOTENDS > 7 + TEMP_7_PIN, #endif - #if PIN_EXISTS(E7_MS3) - #undef _E7_MS3 - #define _E7_MS3 E7_MS3_PIN, + #if TEMP_SENSOR_BED && PINS_EXIST(TEMP_BED, HEATER_BED) + TEMP_BED_PIN, #endif - #if PIN_EXISTS(E7_MS4) - #undef _E7_MS4 - #define _E7_MS4 E7_MS4_PIN, + #if TEMP_SENSOR_CHAMBER && PIN_EXISTS(TEMP_CHAMBER) + TEMP_CHAMBER_PIN, #endif - #if PIN_EXISTS(E7_MS5) - #undef _E7_MS5 - #define _E7_MS5 E7_MS5_PIN, + #if TEMP_SENSOR_COOLER && PIN_EXISTS(TEMP_COOLER) + TEMP_COOLER_PIN, #endif -#endif - -// -// E Steppers -// - -#define _E0_PINS -#define _E1_PINS -#define _E2_PINS -#define _E3_PINS -#define _E4_PINS -#define _E5_PINS -#define _E6_PINS -#define _E7_PINS - -#if HAS_EXTRUDERS - #undef _E0_PINS - #define _E0_PINS E0_STEP_PIN, E0_DIR_PIN, E0_ENABLE_PIN, _E0_CS _E0_MS1 _E0_MS2 _E0_MS3 -#endif - -#if HAS_SWITCHING_EXTRUDER - // Tools 0 and 1 use E0 - #if EXTRUDERS > 2 // Tools 2 and 3 use E1 - #undef _E1_PINS - #define _E1_PINS E1_STEP_PIN, E1_DIR_PIN, E1_ENABLE_PIN, _E1_CS _E1_MS1 _E1_MS2 _E1_MS3 - #if EXTRUDERS > 4 // Tools 4 and 5 use E2 - #undef _E2_PINS - #define _E2_PINS E2_STEP_PIN, E2_DIR_PIN, E2_ENABLE_PIN, _E2_CS _E2_MS1 _E2_MS2 _E2_MS3 - #endif - #endif - -#elif ANY(HAS_MULTI_EXTRUDER, MIXING_EXTRUDER) - - #undef _E1_PINS - #define _E1_PINS E1_STEP_PIN, E1_DIR_PIN, E1_ENABLE_PIN, _E1_CS _E1_MS1 _E1_MS2 _E1_MS3 - #if EXTRUDERS > 2 || (ENABLED(MIXING_EXTRUDER) && MIXING_STEPPERS > 2) - #undef _E2_PINS - #define _E2_PINS E2_STEP_PIN, E2_DIR_PIN, E2_ENABLE_PIN, _E2_CS _E2_MS1 _E2_MS2 _E2_MS3 - #if EXTRUDERS > 3 || (ENABLED(MIXING_EXTRUDER) && MIXING_STEPPERS > 3) - #undef _E3_PINS - #define _E3_PINS E3_STEP_PIN, E3_DIR_PIN, E3_ENABLE_PIN, _E3_CS _E3_MS1 _E3_MS2 _E3_MS3 - #if EXTRUDERS > 4 || (ENABLED(MIXING_EXTRUDER) && MIXING_STEPPERS > 4) - #undef _E4_PINS - #define _E4_PINS E4_STEP_PIN, E4_DIR_PIN, E4_ENABLE_PIN, _E4_CS _E4_MS1 _E4_MS2 _E4_MS3 - #if EXTRUDERS > 5 || (ENABLED(MIXING_EXTRUDER) && MIXING_STEPPERS > 5) - #undef _E5_PINS - #define _E5_PINS E5_STEP_PIN, E5_DIR_PIN, E5_ENABLE_PIN, _E5_CS _E5_MS1 _E5_MS2 _E5_MS3 - #if EXTRUDERS > 6 || (ENABLED(MIXING_EXTRUDER) && MIXING_STEPPERS > 6) - #undef _E6_PINS - #define _E6_PINS E6_STEP_PIN, E6_DIR_PIN, E6_ENABLE_PIN, _E6_CS _E6_MS1 _E6_MS2 _E6_MS3 - #if EXTRUDERS > 7 || (ENABLED(MIXING_EXTRUDER) && MIXING_STEPPERS > 7) - #undef _E7_PINS - #define _E7_PINS E7_STEP_PIN, E7_DIR_PIN, E7_ENABLE_PIN, _E7_CS _E7_MS1 _E7_MS2 _E7_MS3 - #endif // EXTRUDERS > 7 || MIXING_EXTRUDER > 7 - #endif // EXTRUDERS > 6 || MIXING_EXTRUDER > 6 - #endif // EXTRUDERS > 5 || MIXING_EXTRUDER > 5 - #endif // EXTRUDERS > 4 || MIXING_EXTRUDER > 4 - #endif // EXTRUDERS > 3 || MIXING_EXTRUDER > 3 - #endif // EXTRUDERS > 2 || MIXING_EXTRUDER > 2 - -#endif // HAS_MULTI_EXTRUDER || MIXING_EXTRUDER - -// -// Heaters, Fans, Temp Sensors -// - -#ifndef E0_AUTO_FAN_PIN - #define E0_AUTO_FAN_PIN -1 -#endif -#ifndef E1_AUTO_FAN_PIN - #define E1_AUTO_FAN_PIN -1 -#endif -#ifndef E2_AUTO_FAN_PIN - #define E2_AUTO_FAN_PIN -1 -#endif -#ifndef E3_AUTO_FAN_PIN - #define E3_AUTO_FAN_PIN -1 -#endif -#ifndef E4_AUTO_FAN_PIN - #define E4_AUTO_FAN_PIN -1 -#endif -#ifndef E5_AUTO_FAN_PIN - #define E5_AUTO_FAN_PIN -1 -#endif -#ifndef E6_AUTO_FAN_PIN - #define E6_AUTO_FAN_PIN -1 -#endif -#ifndef E7_AUTO_FAN_PIN - #define E7_AUTO_FAN_PIN -1 -#endif - -#define _H0_PINS -#define _H1_PINS -#define _H2_PINS -#define _H3_PINS -#define _H4_PINS -#define _H5_PINS -#define _H6_PINS -#define _H7_PINS - -#define DIO_PIN(P) TERN(TARGET_LPC1768, P, analogInputToDigitalPin(P)) - -#if HAS_HOTEND - #undef _H0_PINS - #define _H0_PINS HEATER_0_PIN, E0_AUTO_FAN_PIN, DIO_PIN(TEMP_0_PIN), - #if HAS_MULTI_HOTEND - #undef _H1_PINS - #define _H1_PINS HEATER_1_PIN, E1_AUTO_FAN_PIN, DIO_PIN(TEMP_1_PIN), - #if HOTENDS > 2 - #undef _H2_PINS - #define _H2_PINS HEATER_2_PIN, E2_AUTO_FAN_PIN, DIO_PIN(TEMP_2_PIN), - #if HOTENDS > 3 - #undef _H3_PINS - #define _H3_PINS HEATER_3_PIN, E3_AUTO_FAN_PIN, DIO_PIN(TEMP_3_PIN), - #if HOTENDS > 4 - #undef _H4_PINS - #define _H4_PINS HEATER_4_PIN, E4_AUTO_FAN_PIN, DIO_PIN(TEMP_4_PIN), - #if HOTENDS > 5 - #undef _H5_PINS - #define _H5_PINS HEATER_5_PIN, E5_AUTO_FAN_PIN, DIO_PIN(TEMP_5_PIN), - #if HOTENDS > 6 - #undef _H6_PINS - #define _H6_PINS HEATER_6_PIN, E6_AUTO_FAN_PIN, DIO_PIN(TEMP_6_PIN), - #if HOTENDS > 7 - #undef _H7_PINS - #define _H7_PINS HEATER_7_PIN, E7_AUTO_FAN_PIN, DIO_PIN(TEMP_7_PIN), - #endif // HOTENDS > 7 - #endif // HOTENDS > 6 - #endif // HOTENDS > 5 - #endif // HOTENDS > 4 - #endif // HOTENDS > 3 - #endif // HOTENDS > 2 - #endif // HAS_MULTI_HOTEND -#endif // HOTENDS - -// -// Dual X, Dual Y, Multi-Z -// Chip Select and Digital Micro-stepping -// - -#if HAS_X2_STEPPER - #if PIN_EXISTS(X2_CS) && AXIS_HAS_SPI(X2) - #define _X2_CS X2_CS_PIN, - #else - #define _X2_CS - #endif - #if PIN_EXISTS(X2_MS1) - #define _X2_MS1 X2_MS1_PIN, - #else - #define _X2_MS1 - #endif - #if PIN_EXISTS(X2_MS2) - #define _X2_MS2 X2_MS2_PIN, - #else - #define _X2_MS2 - #endif - #if PIN_EXISTS(X2_MS3) - #define _X2_MS3 X2_MS3_PIN, - #else - #define _X2_MS3 - #endif - #define _X2_PINS X2_STEP_PIN, X2_DIR_PIN, X2_ENABLE_PIN, _X2_CS _X2_MS1 _X2_MS2 _X2_MS3 -#else - #define _X2_PINS -#endif - -#if HAS_Y2_STEPPER - #if PIN_EXISTS(Y2_CS) && AXIS_HAS_SPI(Y2) - #define _Y2_CS Y2_CS_PIN, - #else - #define _Y2_CS - #endif - #if PIN_EXISTS(Y2_MS1) - #define _Y2_MS1 Y2_MS1_PIN, - #else - #define _Y2_MS1 - #endif - #if PIN_EXISTS(Y2_MS2) - #define _Y2_MS2 Y2_MS2_PIN, - #else - #define _Y2_MS2 - #endif - #if PIN_EXISTS(Y2_MS3) - #define _Y2_MS3 Y2_MS3_PIN, - #else - #define _Y2_MS3 - #endif - #define _Y2_PINS Y2_STEP_PIN, Y2_DIR_PIN, Y2_ENABLE_PIN, _Y2_CS _Y2_MS1 _Y2_MS2 _Y2_MS3 -#else - #define _Y2_PINS -#endif - -#if NUM_Z_STEPPERS >= 2 - #if PIN_EXISTS(Z2_CS) && AXIS_HAS_SPI(Z2) - #define _Z2_CS Z2_CS_PIN, - #else - #define _Z2_CS - #endif - #if PIN_EXISTS(Z2_MS1) - #define _Z2_MS1 Z2_MS1_PIN, - #else - #define _Z2_MS1 - #endif - #if PIN_EXISTS(Z2_MS2) - #define _Z2_MS2 Z2_MS2_PIN, - #else - #define _Z2_MS2 - #endif - #if PIN_EXISTS(Z2_MS3) - #define _Z2_MS3 Z2_MS3_PIN, - #else - #define _Z2_MS3 - #endif - #define _Z2_PINS Z2_STEP_PIN, Z2_DIR_PIN, Z2_ENABLE_PIN, _Z2_CS _Z2_MS1 _Z2_MS2 _Z2_MS3 -#else - #define _Z2_PINS -#endif - -#if NUM_Z_STEPPERS >= 3 - #if PIN_EXISTS(Z3_CS) && AXIS_HAS_SPI(Z3) - #define _Z3_CS Z3_CS_PIN, - #else - #define _Z3_CS - #endif - #if PIN_EXISTS(Z3_MS1) - #define _Z3_MS1 Z3_MS1_PIN, - #else - #define _Z3_MS1 - #endif - #if PIN_EXISTS(Z3_MS2) - #define _Z3_MS2 Z3_MS2_PIN, - #else - #define _Z3_MS2 - #endif - #if PIN_EXISTS(Z3_MS3) - #define _Z3_MS3 Z3_MS3_PIN, - #else - #define _Z3_MS3 - #endif - #define _Z3_PINS Z3_STEP_PIN, Z3_DIR_PIN, Z3_ENABLE_PIN, _Z3_CS _Z3_MS1 _Z3_MS2 _Z3_MS3 -#else - #define _Z3_PINS -#endif - -#if NUM_Z_STEPPERS >= 4 - #if PIN_EXISTS(Z4_CS) && AXIS_HAS_SPI(Z4) - #define _Z4_CS Z4_CS_PIN, - #else - #define _Z4_CS - #endif - #if PIN_EXISTS(Z4_MS1) - #define _Z4_MS1 Z4_MS1_PIN, - #else - #define _Z4_MS1 - #endif - #if PIN_EXISTS(Z4_MS2) - #define _Z4_MS2 Z4_MS2_PIN, - #else - #define _Z4_MS2 - #endif - #if PIN_EXISTS(Z4_MS3) - #define _Z4_MS3 Z4_MS3_PIN, - #else - #define _Z4_MS3 - #endif - #define _Z4_PINS Z4_STEP_PIN, Z4_DIR_PIN, Z4_ENABLE_PIN, _Z4_CS _Z4_MS1 _Z4_MS2 _Z4_MS3 -#else - #define _Z4_PINS -#endif - -// -// Generate the final Sensitive Pins array, -// keeping the array as small as possible. -// - -#if PIN_EXISTS(PS_ON) - #define _PS_ON PS_ON_PIN, -#else - #define _PS_ON -#endif - -#if HAS_BED_PROBE && PIN_EXISTS(Z_MIN_PROBE) - #define _Z_PROBE Z_MIN_PROBE_PIN, -#else - #define _Z_PROBE -#endif - -#if PIN_EXISTS(FAN0) - #define _FAN0 FAN0_PIN, -#else - #define _FAN0 -#endif -#if PIN_EXISTS(FAN1) - #define _FAN1 FAN1_PIN, -#else - #define _FAN1 -#endif -#if PIN_EXISTS(FAN2) - #define _FAN2 FAN2_PIN, -#else - #define _FAN2 -#endif -#if PIN_EXISTS(FAN3) - #define _FAN3 FAN3_PIN, -#else - #define _FAN3 -#endif -#if PIN_EXISTS(FAN4) - #define _FAN4 FAN4_PIN, -#else - #define _FAN4 -#endif -#if PIN_EXISTS(FAN5) - #define _FAN5 FAN5_PIN, -#else - #define _FAN5 -#endif -#if PIN_EXISTS(FAN6) - #define _FAN6 FAN6_PIN, -#else - #define _FAN6 -#endif -#if PIN_EXISTS(FAN7) - #define _FAN7 FAN7_PIN, -#else - #define _FAN7 -#endif -#if PIN_EXISTS(CONTROLLER_FAN) - #define _FANC CONTROLLER_FAN_PIN, -#else - #define _FANC -#endif - -#if TEMP_SENSOR_BED && PINS_EXIST(TEMP_BED, HEATER_BED) - #define _BED_PINS HEATER_BED_PIN, DIO_PIN(TEMP_BED_PIN), -#else - #define _BED_PINS -#endif - -#if TEMP_SENSOR_CHAMBER && PIN_EXISTS(TEMP_CHAMBER) - #define _CHAMBER_TEMP DIO_PIN(TEMP_CHAMBER_PIN), -#else - #define _CHAMBER_TEMP -#endif -#if TEMP_SENSOR_CHAMBER && PINS_EXIST(TEMP_CHAMBER, HEATER_CHAMBER) - #define _CHAMBER_HEATER HEATER_CHAMBER_PIN, -#else - #define _CHAMBER_HEATER -#endif -#if TEMP_SENSOR_CHAMBER && PINS_EXIST(TEMP_CHAMBER, CHAMBER_AUTO_FAN) - #define _CHAMBER_FAN CHAMBER_AUTO_FAN_PIN, -#else - #define _CHAMBER_FAN -#endif - -#if TEMP_SENSOR_COOLER && PIN_EXISTS(TEMP_COOLER) - #define _COOLER_TEMP DIO_PIN(TEMP_COOLER_PIN), -#else - #define _COOLER_TEMP -#endif -#if TEMP_SENSOR_COOLER && PIN_EXISTS(COOLER) - #define _COOLER COOLER_PIN, -#else - #define _COOLER -#endif -#if TEMP_SENSOR_COOLER && PINS_EXIST(TEMP_COOLER, COOLER_AUTO_FAN) - #define _COOLER_FAN COOLER_AUTO_FAN_PIN, -#else - #define _COOLER_FAN -#endif - -#ifndef HAL_SENSITIVE_PINS - #define HAL_SENSITIVE_PINS -#endif - -#ifdef RUNTIME_ONLY_ANALOG_TO_DIGITAL - #define _SP_END -#else - #define _SP_END -2 - - // Move a regular pin in front to the end - template - struct OnlyPins : OnlyPins { }; - - // Remove a -1 from the front - template - struct OnlyPins<-1, D...> : OnlyPins { }; - - // Remove -2 from the front, emit the rest, cease propagation - template - struct OnlyPins<_SP_END, D...> { static constexpr size_t size = sizeof...(D); static constexpr pin_t table[sizeof...(D)] PROGMEM = { D... }; }; -#endif - -#define SENSITIVE_PINS \ - _X_PINS _Y_PINS _Z_PINS _I_PINS _J_PINS _K_PINS _U_PINS _V_PINS _W_PINS \ - _X2_PINS _Y2_PINS _Z2_PINS _Z3_PINS _Z4_PINS _Z_PROBE \ - _E0_PINS _E1_PINS _E2_PINS _E3_PINS _E4_PINS _E5_PINS _E6_PINS _E7_PINS \ - _H0_PINS _H1_PINS _H2_PINS _H3_PINS _H4_PINS _H5_PINS _H6_PINS _H7_PINS \ - _PS_ON _FAN0 _FAN1 _FAN2 _FAN3 _FAN4 _FAN5 _FAN6 _FAN7 _FANC \ - _BED_PINS _CHAMBER_TEMP _CHAMBER_HEATER _CHAMBER_FAN \ - _COOLER_TEMP _COOLER _COOLER_FAN HAL_SENSITIVE_PINS \ - _SP_END +}; From c81416438d5a4779b1bdb103e9a166252b39ae96 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Sun, 30 Jun 2024 00:25:29 +0000 Subject: [PATCH 22/24] [cron] Bump distribution date (2024-06-30) --- Marlin/Version.h | 2 +- Marlin/src/inc/Version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/Version.h b/Marlin/Version.h index 4f0d5d8703d1..52dc937e206b 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -41,7 +41,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2024-06-29" +//#define STRING_DISTRIBUTION_DATE "2024-06-30" /** * Defines a generic printer name to be output to the LCD after booting Marlin. diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index ba35bb82cc05..6ca19f247fb9 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2024-06-29" + #define STRING_DISTRIBUTION_DATE "2024-06-30" #endif /** From 6fed66dd428f46d073a3c28f6ff39b13c86cc65e Mon Sep 17 00:00:00 2001 From: Mihai <299015+mh-dm@users.noreply.github.com> Date: Mon, 1 Jul 2024 21:56:06 +0300 Subject: [PATCH 23/24] =?UTF-8?q?=F0=9F=A9=B9=E2=9A=A1=EF=B8=8F=20Fix=20ju?= =?UTF-8?q?dder,=20optimize=20planner=20(#27035)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/module/planner.cpp | 327 +++++++++++++--------------------- Marlin/src/module/planner.h | 11 +- 2 files changed, 127 insertions(+), 211 deletions(-) diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index 8f11f4ec18a5..b4546e0235bf 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -128,7 +128,6 @@ Planner planner; block_t Planner::block_buffer[BLOCK_BUFFER_SIZE]; volatile uint8_t Planner::block_buffer_head, // Index of the next block to be pushed Planner::block_buffer_nonbusy, // Index of the first non-busy block - Planner::block_buffer_planned, // Index of the optimally planned block Planner::block_buffer_tail; // Index of the busy block, if any uint16_t Planner::cleaning_buffer_counter; // A counter to disable queuing of blocks uint8_t Planner::delay_before_delivering; // Delay block delivery so initial blocks in an empty queue may merge @@ -768,10 +767,6 @@ block_t* Planner::get_current_block() { // As this block is busy, advance the nonbusy block pointer block_buffer_nonbusy = next_block_index(block_buffer_tail); - // Push block_buffer_planned pointer, if encountered. - if (block_buffer_tail == block_buffer_planned) - block_buffer_planned = block_buffer_nonbusy; - // Return the block return block; } @@ -784,29 +779,30 @@ block_t* Planner::get_current_block() { /** * Calculate trapezoid parameters, multiplying the entry- and exit-speeds - * by the provided factors. Requires that initial_rate and final_rate are - * no less than sqrt(block->acceleration_steps_per_s2 / 2), which is ensured - * through minimum_planner_speed_sqr in _populate_block(). + * by the provided factors. If entry_factor is 0 don't change the initial_rate. + * Assumes that the implied initial_rate and final_rate are no less than + * sqrt(block->acceleration_steps_per_s2 / 2). This is ensured through + * minimum_planner_speed_sqr / min_entry_speed_sqr though note there's one + * exception in recalculate_trapezoids(). ** * ############ VERY IMPORTANT ############ * NOTE that the PRECONDITION to call this function is that the block is * NOT BUSY and it is marked as RECALCULATE. That WARRANTIES the Stepper ISR - * is not and will not use the block while we modify it, so it is safe to - * alter its values. + * is not and will not use the block while we modify it. */ -void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t entry_factor, const_float_t exit_factor) { +void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t entry_speed, const_float_t exit_speed) { - uint32_t initial_rate = LROUND(block->nominal_rate * entry_factor), - final_rate = LROUND(block->nominal_rate * exit_factor); // (steps per second) + const float spmm = block->steps_per_mm; + uint32_t initial_rate = entry_speed ? LROUND(entry_speed * spmm) : block->initial_rate, + final_rate = LROUND(exit_speed * spmm); - // Legacy check against supposed timer overflow. However Stepper::calc_timer_interval() already - // should protect against it. But removing this code produces judder in direction-switching - // moves. This is because the current discrete stepping math diverges from physical motion under - // constant acceleration when acceleration_steps_per_s2 is large compared to initial/final_rate. - NOLESS(initial_rate, uint32_t(MINIMAL_STEP_RATE)); // Enforce the minimum speed - NOLESS(final_rate, uint32_t(MINIMAL_STEP_RATE)); - NOMORE(initial_rate, block->nominal_rate); // NOTE: The nominal rate may be less than MINIMAL_STEP_RATE! - NOMORE(final_rate, block->nominal_rate); + // Removing code to constrain values produces judder in direction-switching moves because the + // current discrete stepping math diverges from physical motion under constant acceleration + // when acceleration_steps_per_s2 is large compared to initial/final_rate. + NOLESS(initial_rate, long(MINIMAL_STEP_RATE)); + NOLESS(final_rate, long(MINIMAL_STEP_RATE)); + NOMORE(initial_rate, block->nominal_rate); // NOTE: The nominal rate may be less than MINIMAL_STEP_RATE! + NOMORE(final_rate, block->nominal_rate); #if ANY(S_CURVE_ACCELERATION, LIN_ADVANCE) // If we have some plateau time, the cruise rate will be the nominal rate @@ -942,16 +938,16 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t * * Recalculates the motion plan according to the following basic guidelines: * - * 1. Go over every feasible block sequentially in reverse order and calculate the junction speeds - * (i.e. current->entry_speed) such that: - * a. No junction speed exceeds the pre-computed maximum junction speed limit or nominal speeds of - * neighboring blocks. - * b. A block entry speed cannot exceed one reverse-computed from its exit speed (next->entry_speed) - * with a maximum allowable deceleration over the block travel distance. - * c. The last (or newest appended) block is planned from safe_exit_speed_sqr. - * 2. Go over every block in chronological (forward) order and dial down junction speed values if - * a. The exit speed exceeds the one forward-computed from its entry speed with the maximum allowable - * acceleration over the block travel distance. + * 1. Go over blocks sequentially in reverse order and maximize the entry junction speed: + * a. Entry speed should stay below/at the pre-computed maximum junction speed limit + * b. Aim for the maximum entry speed which is the one reverse-computed from its exit speed + * (next->entry_speed) if assuming maximum deceleration over the full block travel distance + * c. The last (newest appended) block uses safe_exit_speed exit speed (there's no 'next') + * 2. Go over blocks in chronological (forward) order and fix the exit junction speed: + * a. Exit speed (next->entry_speed) must be below/at the maximum exit speed forward-computed + * from its entry speed if assuming maximum acceleration over the full block travel distance + * b. Exit speed should stay above/at the pre-computed minimum junction speed limit + * 3. Convert entry / exit speeds (mm/s) into final/initial steps/s * * When these stages are complete, the planner will have maximized the velocity profiles throughout the all * of the planner blocks, where every block is operating at its maximum allowable acceleration limits. In @@ -959,28 +955,22 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t * are possible. If a new block is added to the buffer, the plan is recomputed according to the said * guidelines for a new optimal plan. * - * To increase computational efficiency of these guidelines, a set of planner block pointers have been - * created to indicate stop-compute points for when the planner guidelines cannot logically make any further - * changes or improvements to the plan when in normal operation and new blocks are streamed and added to the - * planner buffer. For example, if a subset of sequential blocks in the planner have been planned and are - * bracketed by junction velocities at their maximums (or by the first planner block as well), no new block - * added to the planner buffer will alter the velocity profiles within them. So we no longer have to compute - * them. Or, if a set of sequential blocks from the first block in the planner (or a optimal stop-compute - * point) are all accelerating, they are all optimal and can not be altered by a new block added to the - * planner buffer, as this will only further increase the plan speed to chronological blocks until a maximum - * junction velocity is reached. However, if the operational conditions of the plan changes from infrequently - * used feed holds or feedrate overrides, the stop-compute pointers will be reset and the entire plan is - * recomputed as stated in the general guidelines. + * To increase computational efficiency of these guidelines: + * 1. We keep track of which blocks need calculation (block->flag.recalculate) + * 2. We stop the reverse pass on the first block whose entry_speed == max_entry_speed. As soon + * as that happens, there can be no further increases (ensured by the previous recalculate) + * 3. On the forward pass we skip through to the first block with a modified exit speed + * (next->entry_speed) + * 4. On the forward pass if we encounter a full acceleration block that limits its exit speed + * (next->entry_speed) we also update the maximum for that junction (next->max_entry_speed) + * so it's never updated again + * 5. We use speed squared (ex: entry_speed_sqr in mm^2/s^2) in acceleration limit computations + * 6. We don't recompute sqrt(entry_speed_sqr) if the block's entry speed didn't change * * Planner buffer index mapping: * - block_buffer_tail: Points to the beginning of the planner buffer. First to be executed or being executed. * - block_buffer_head: Points to the buffer block after the last block in the buffer. Used to indicate whether * the buffer is full or empty. As described for standard ring buffers, this block is always empty. - * - block_buffer_planned: Points to the first buffer block after the last optimally planned block for normal - * streaming operating conditions. Use for planning optimizations by avoiding recomputing parts of the - * planner buffer that don't change with the addition of a new block, as describe above. In addition, - * this block can never be less than block_buffer_tail and will always be pushed forward and maintain - * this requirement when encountered by the Planner::release_current_block() routine during a cycle. * * NOTE: Since the planner only computes on what's in the planner buffer, some motions with many short * segments (e.g., complex curves) may seem to move slowly. This is because there simply isn't @@ -1003,7 +993,8 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t */ // The kernel called by recalculate() when scanning the plan from last to first entry. -void Planner::reverse_pass_kernel(block_t * const current, const block_t * const next, const_float_t safe_exit_speed_sqr) { +// Returns true if it could increase the current block's entry speed. +bool Planner::reverse_pass_kernel(block_t * const current, const block_t * const next, const_float_t safe_exit_speed_sqr) { // We need to recalculate only for the last block added or if next->entry_speed_sqr changed. if (!next || next->flag.recalculate) { // And only if we're not already at max entry speed. @@ -1021,196 +1012,136 @@ void Planner::reverse_pass_kernel(block_t * const current, const block_t * const // become BUSY just before being marked RECALCULATE, so check for that! if (stepper.is_block_busy(current)) { // Block became busy. Clear the RECALCULATE flag (no point in - // recalculating BUSY blocks). And don't set its speed, as it can't - // be updated at this time. + // recalculating BUSY blocks). current->flag.recalculate = false; } else { // Block is not BUSY so this is ahead of the Stepper ISR: - // Just Set the new entry speed. + current->entry_speed_sqr = new_entry_speed_sqr; + return true; } } } } + return false; } /** * recalculate() needs to go over the current plan twice. - * Once in reverse and once forward. This implements the reverse pass. + * Once in reverse and once forward. This implements the reverse pass that + * coarsely maximizes the entry speeds starting from last block. + * Requires there's at least one block with flag.recalculate in the buffer. */ void Planner::reverse_pass(const_float_t safe_exit_speed_sqr) { // Initialize block index to the last block in the planner buffer. + // This last block will have flag.recalculate set. uint8_t block_index = prev_block_index(block_buffer_head); - // Read the index of the last buffer planned block. - // The ISR may change it so get a stable local copy. - uint8_t planned_block_index = block_buffer_planned; - - // If there was a race condition and block_buffer_planned was incremented - // or was pointing at the head (queue empty) break loop now and avoid - // planning already consumed blocks - if (planned_block_index == block_buffer_head) return; + // The ISR may change block_buffer_nonbusy so get a stable local copy. + uint8_t nonbusy_block_index = block_buffer_nonbusy; - // Reverse Pass: Coarsely maximize all possible deceleration curves back-planning from the last - // block in buffer. Cease planning when the last optimal planned or tail pointer is reached. - // NOTE: Forward pass will later refine and correct the reverse pass to create an optimal plan. const block_t *next = nullptr; - while (block_index != planned_block_index) { - - // Perform the reverse pass + // Don't try to change the entry speed of the first non-busy block. + while (block_index != nonbusy_block_index) { block_t *current = &block_buffer[block_index]; // Only process movement blocks if (current->is_move()) { - reverse_pass_kernel(current, next, safe_exit_speed_sqr); + // If no entry speed increase was possible we end the reverse pass. + if (!reverse_pass_kernel(current, next, safe_exit_speed_sqr)) return; next = current; } - // Advance to the next block_index = prev_block_index(block_index); - // The ISR could advance the block_buffer_planned while we were doing the reverse pass. + // The ISR could advance block_buffer_nonbusy while we were doing the reverse pass. // We must try to avoid using an already consumed block as the last one - So follow // changes to the pointer and make sure to limit the loop to the currently busy block - while (planned_block_index != block_buffer_planned) { + while (nonbusy_block_index != block_buffer_nonbusy) { // If we reached the busy block or an already processed block, break the loop now - if (block_index == planned_block_index) return; + if (block_index == nonbusy_block_index) return; // Advance the pointer, following the busy block - planned_block_index = next_block_index(planned_block_index); + nonbusy_block_index = next_block_index(nonbusy_block_index); } } } -// The kernel called by recalculate() when scanning the plan from first to last entry. -void Planner::forward_pass_kernel(const block_t * const previous, block_t * const current, const uint8_t block_index) { - // Check against previous speed only on current->entry_speed_sqr changes (or if first time). - if (current->flag.recalculate) { - // If the previous block is accelerating check if it's too short to complete the full speed - // change then adjust the entry speed accordingly. Entry speeds have already been maximized. - if (previous->entry_speed_sqr < current->entry_speed_sqr) { - float new_entry_speed_sqr = max_allowable_speed_sqr(-previous->acceleration, previous->entry_speed_sqr, previous->millimeters); - - // If true, previous block is full-acceleration and we can move the planned pointer forward. - if (new_entry_speed_sqr < current->entry_speed_sqr) { - // Current entry speed limited by full acceleration from previous entry speed. - // Make sure entry speed not lower than minimum_planner_speed_sqr. - NOLESS(new_entry_speed_sqr, current->min_entry_speed_sqr); - current->entry_speed_sqr = new_entry_speed_sqr; - - // Set optimal plan pointer. - block_buffer_planned = block_index; - } - else { - // Previous entry speed has been maximized. - block_buffer_planned = prev_block_index(block_index); - } +// The kernel called during the forward pass. Assumes current->flag.recalculate. +void Planner::forward_pass_kernel(const block_t * const previous, block_t * const current) { + // Check if the previous block is accelerating. + if (previous->entry_speed_sqr < current->entry_speed_sqr) { + // Compute the maximum achievable speed if the previous block was fully accelerating. + float new_exit_speed_sqr = max_allowable_speed_sqr(-previous->acceleration, previous->entry_speed_sqr, previous->millimeters); + + if (new_exit_speed_sqr < current->entry_speed_sqr) { + // Current entry speed limited by full acceleration from previous entry speed. + + // Make sure entry speed not lower than minimum_planner_speed_sqr. + NOLESS(new_exit_speed_sqr, current->min_entry_speed_sqr); + current->entry_speed_sqr = new_exit_speed_sqr; + // Ensure we don't try updating entry_speed_sqr again. + current->max_entry_speed_sqr = new_exit_speed_sqr; } - - // Any block set at its maximum entry speed also creates an optimal plan up to this - // point in the buffer. When the plan is bracketed by either the beginning of the - // buffer and a maximum entry speed or two maximum entry speeds, every block in between - // cannot logically be further improved. Hence, we don't have to recompute them anymore. - if (current->entry_speed_sqr == current->max_entry_speed_sqr) - block_buffer_planned = block_index; } -} -/** - * recalculate() needs to go over the current plan twice. - * Once in reverse and once forward. This implements the forward pass. - */ -void Planner::forward_pass() { - - // Forward Pass: Forward plan the acceleration curve from the planned pointer onward. - // Also scans for optimal plan breakpoints and appropriately updates the planned pointer. - - // Begin at buffer planned pointer. Note that block_buffer_planned can be modified - // by the stepper ISR, so read it ONCE. It it guaranteed that block_buffer_planned - // will never lead head, so the loop is safe to execute. Also note that the forward - // pass will never modify the values at the tail. - uint8_t block_index = block_buffer_planned; - - block_t *block; - const block_t * previous = nullptr; - while (block_index != block_buffer_head) { - - // Perform the forward pass - block = &block_buffer[block_index]; - - // Only process movement blocks - if (block->is_move()) { - // If there's no previous block or the previous block is not - // BUSY (thus, modifiable) run the forward_pass_kernel. Otherwise, - // the previous block became BUSY, so assume the current block's - // entry speed can't be altered (since that would also require - // updating the exit speed of the previous block). - if (previous && !stepper.is_block_busy(previous)) - forward_pass_kernel(previous, block, block_index); - previous = block; - } - // Advance to the previous - block_index = next_block_index(block_index); - } + // The fully optimized entry speed is our new minimum speed. + current->min_entry_speed_sqr = current->entry_speed_sqr; } /** - * Recalculate the trapezoid speed profiles for all blocks in the plan - * according to the entry_factor for each junction. Must be called by - * recalculate() after updating the blocks. + * Do the forward pass and recalculate the trapezoid speed profiles for all blocks in the plan + * according to entry/exit speeds. */ void Planner::recalculate_trapezoids(const_float_t safe_exit_speed_sqr) { - // The tail may be changed by the ISR so get a local copy. + // Start with the block that's about to execute or is executing. uint8_t block_index = block_buffer_tail, head_block_index = block_buffer_head; - // Since there could be a sync block in the head of the queue, and the - // next loop must not recalculate the head block (as it needs to be - // specially handled), scan backwards to the first non-SYNC block. - while (head_block_index != block_index) { - - // Go back (head always point to the first free block) - const uint8_t prev_index = prev_block_index(head_block_index); - - // Get the pointer to the block - block_t *prev = &block_buffer[prev_index]; - - // It the block is a move, we're done with this loop - if (prev->is_move()) break; - // Examine the previous block. This and all following are SYNC blocks - head_block_index = prev_index; - } - - // Go from the tail (currently executed block) to the first block, without including it) block_t *block = nullptr, *next = nullptr; - float current_entry_speed = 0.0f, next_entry_speed = 0.0f; + float next_entry_speed = 0.0f; while (block_index != head_block_index) { next = &block_buffer[block_index]; - // Only process movement blocks if (next->is_move()) { - next_entry_speed = SQRT(next->entry_speed_sqr); - - if (block) { - - // If the next block is marked to RECALCULATE, also mark the previously-fetched one - if (next->flag.recalculate) block->flag.recalculate = true; + // Check if the next block's entry speed changed + if (next->flag.recalculate) { + if (!block) { + // 'next' is the first move due to either being the first added move or due to the planner + // having completely fallen behind. Revert any reverse pass change. + next->entry_speed_sqr = next->min_entry_speed_sqr; + next_entry_speed = SQRT(next->min_entry_speed_sqr); + } + else { + // Try to fix exit speed which requires trapezoid recalculation + block->flag.recalculate = true; + + // But there is an inherent race condition here, as the block may have + // become BUSY just before being marked RECALCULATE, so check for that! + if (stepper.is_block_busy(block)) { + // Block is BUSY so we can't change the exit speed. Revert any reverse pass change. + next->entry_speed_sqr = next->min_entry_speed_sqr; + if (!next->initial_rate) { + // 'next' was never calculated. Planner is falling behind so for maximum efficiency + // set next's stepping speed directly and forgo checking against min_entry_speed_sqr. + // calculate_trapezoid_for_block() can handle it, albeit sub-optimally. + next->initial_rate = block->final_rate; + } + // Note that at this point next_entry_speed is (still) 0. + } + else { + // Block is not BUSY: we won the race against the ISR or recalculate was already set - // Recalculate if current block entry or exit junction speed has changed. - if (block->flag.recalculate) { + if (next->entry_speed_sqr != next->min_entry_speed_sqr) + forward_pass_kernel(block, next); - // But there is an inherent race condition here, as the block maybe - // became BUSY, just before it was marked as RECALCULATE, so check - // if that is the case! - if (!stepper.is_block_busy(block)) { - // Block is not BUSY, we won the race against the Stepper ISR: + const float current_entry_speed = next_entry_speed; + next_entry_speed = SQRT(next->entry_speed_sqr); - // NOTE: Entry and exit factors always > 0 by all previous logic operations. - const float nomr = 1.0f / block->nominal_speed; - calculate_trapezoid_for_block(block, current_entry_speed * nomr, next_entry_speed * nomr); + calculate_trapezoid_for_block(block, current_entry_speed, next_entry_speed); } // Reset current only to ensure next trapezoid is computed - The @@ -1220,30 +1151,17 @@ void Planner::recalculate_trapezoids(const_float_t safe_exit_speed_sqr) { } block = next; - current_entry_speed = next_entry_speed; } block_index = next_block_index(block_index); } - // Last/newest block in buffer. Always recalculated. - if (block) { + // Last/newest block in buffer. The above guarantees it's a move block. + if (block && block->flag.recalculate) { + const float current_entry_speed = next_entry_speed; next_entry_speed = SQRT(safe_exit_speed_sqr); - // Mark the next(last) block as RECALCULATE, to prevent the Stepper ISR running it. - // As the last block is always recalculated here, there is a chance the block isn't - // marked as RECALCULATE yet. That's the reason for the following line. - block->flag.recalculate = true; - - // But there is an inherent race condition here, as the block maybe - // became BUSY, just before it was marked as RECALCULATE, so check - // if that is the case! - if (!stepper.is_block_busy(block)) { - // Block is not BUSY, we won the race against the Stepper ISR: - - const float nomr = 1.0f / block->nominal_speed; - calculate_trapezoid_for_block(block, current_entry_speed * nomr, next_entry_speed * nomr); - } + calculate_trapezoid_for_block(block, current_entry_speed, next_entry_speed); // Reset block to ensure its trapezoid is computed - The stepper is free to use // the block from now on. @@ -1251,14 +1169,10 @@ void Planner::recalculate_trapezoids(const_float_t safe_exit_speed_sqr) { } } +// Requires there's at least one block with flag.recalculate in the buffer void Planner::recalculate(const_float_t safe_exit_speed_sqr) { - // Initialize block index to the last block in the planner buffer. - const uint8_t block_index = prev_block_index(block_buffer_head); - // If there is just one block, no planning can be done. Avoid it! - if (block_index != block_buffer_planned) { - reverse_pass(safe_exit_speed_sqr); - forward_pass(); - } + reverse_pass(safe_exit_speed_sqr); + // The forward pass is done as part of recalculate_trapezoids() recalculate_trapezoids(safe_exit_speed_sqr); } @@ -1667,7 +1581,7 @@ void Planner::quick_stop() { const bool was_enabled = stepper.suspend(); // Drop all queue entries - block_buffer_nonbusy = block_buffer_planned = block_buffer_head = block_buffer_tail; + block_buffer_nonbusy = block_buffer_head = block_buffer_tail; // Restart the block delay for the first movement - As the queue was // forced to empty, there's no risk the ISR will touch this. @@ -2436,6 +2350,7 @@ bool Planner::_populate_block( // Compute and limit the acceleration rate for the trapezoid generator. const float steps_per_mm = block->step_event_count * inverse_millimeters; + block->steps_per_mm = steps_per_mm; uint32_t accel; #if ENABLED(LIN_ADVANCE) bool use_advance_lead = false; @@ -2829,6 +2744,8 @@ bool Planner::_populate_block( block->entry_speed_sqr = minimum_planner_speed_sqr; // Set min entry speed. Rarely it could be higher than the previous nominal speed but that's ok. block->min_entry_speed_sqr = minimum_planner_speed_sqr; + // Zero the initial_rate to indicate that calculate_trapezoid_for_block() hasn't been called yet. + block->initial_rate = 0; block->flag.recalculate = true; diff --git a/Marlin/src/module/planner.h b/Marlin/src/module/planner.h index fd26b4340e07..1053a27688d3 100644 --- a/Marlin/src/module/planner.h +++ b/Marlin/src/module/planner.h @@ -219,6 +219,7 @@ typedef struct PlannerBlock { min_entry_speed_sqr, // Minimum allowable junction entry speed in (mm/sec)^2 max_entry_speed_sqr, // Maximum allowable junction entry speed in (mm/sec)^2 millimeters, // The total travel of this block in mm + steps_per_mm, // steps/mm acceleration; // acceleration mm/sec^2 union { @@ -442,7 +443,6 @@ class Planner { static block_t block_buffer[BLOCK_BUFFER_SIZE]; static volatile uint8_t block_buffer_head, // Index of the next block to be pushed block_buffer_nonbusy, // Index of the first non busy block - block_buffer_planned, // Index of the optimally planned block block_buffer_tail; // Index of the busy block, if any static uint16_t cleaning_buffer_counter; // A counter to disable queuing of blocks static uint8_t delay_before_delivering; // This counter delays delivery of blocks when queue becomes empty to allow the opportunity of merging blocks @@ -804,7 +804,7 @@ class Planner { FORCE_INLINE static uint8_t nonbusy_movesplanned() { return block_dec_mod(block_buffer_head, block_buffer_nonbusy); } // Remove all blocks from the buffer - FORCE_INLINE static void clear_block_buffer() { block_buffer_nonbusy = block_buffer_planned = block_buffer_head = block_buffer_tail = 0; } + FORCE_INLINE static void clear_block_buffer() { block_buffer_nonbusy = block_buffer_head = block_buffer_tail = 0; } // Check if movement queue is full FORCE_INLINE static bool is_full() { return block_buffer_tail == next_block_index(block_buffer_head); } @@ -1081,13 +1081,12 @@ class Planner { } #endif - static void calculate_trapezoid_for_block(block_t * const block, const_float_t entry_factor, const_float_t exit_factor); + static void calculate_trapezoid_for_block(block_t * const block, const_float_t entry_speed, const_float_t exit_speed); - static void reverse_pass_kernel(block_t * const current, const block_t * const next, const_float_t safe_exit_speed_sqr); - static void forward_pass_kernel(const block_t * const previous, block_t * const current, uint8_t block_index); + static bool reverse_pass_kernel(block_t * const current, const block_t * const next, const_float_t safe_exit_speed_sqr); + static void forward_pass_kernel(const block_t * const previous, block_t * const current); static void reverse_pass(const_float_t safe_exit_speed_sqr); - static void forward_pass(); static void recalculate_trapezoids(const_float_t safe_exit_speed_sqr); From 0103cffcd02493ca412363d63d13204262e7ca4c Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Tue, 2 Jul 2024 00:23:05 +0000 Subject: [PATCH 24/24] [cron] Bump distribution date (2024-07-02) --- Marlin/Version.h | 2 +- Marlin/src/inc/Version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/Version.h b/Marlin/Version.h index 52dc937e206b..9922ba35a5db 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -41,7 +41,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2024-06-30" +//#define STRING_DISTRIBUTION_DATE "2024-07-02" /** * Defines a generic printer name to be output to the LCD after booting Marlin. diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 6ca19f247fb9..c06e9ca2aaae 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2024-06-30" + #define STRING_DISTRIBUTION_DATE "2024-07-02" #endif /**