From a7444021c6d31c554cb22e1062f72033e5f21c61 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Thu, 20 Jun 2024 12:42:26 -0500 Subject: [PATCH 01/41] =?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/41] [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/41] =?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/41] [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/41] =?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/41] [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/41] =?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/41] [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/41] =?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/41] =?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/41] =?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/41] [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/41] =?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/41] =?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/41] =?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/41] =?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/41] [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/41] =?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/41] [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/41] =?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/41] =?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/41] [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/41] =?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/41] [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 /** From 1d1eb97567b997bb2d1b5b502891978f24201420 Mon Sep 17 00:00:00 2001 From: ellensp <530024+ellensp@users.noreply.github.com> Date: Fri, 5 Jul 2024 12:43:17 +1200 Subject: [PATCH 25/41] =?UTF-8?q?=F0=9F=9A=B8=20Update=20Zonestar=20OLEDs?= =?UTF-8?q?=20to=20SPI=20(#27220)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Scott Lahteine --- Marlin/src/inc/Conditionals_LCD.h | 11 +- Marlin/src/lcd/dogm/marlinui_DOGM.h | 12 +- .../src/lcd/dogm/u8g/HAL_LCD_class_defines.h | 26 +- .../u8g/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp | 221 ++++++++-------- .../u8g_dev_ssd1306_sh1106_128x64_SWSPI.cpp | 246 ++++++++++++++++++ .../lcd/dogm/u8g/u8g_dev_ssd1309_12864.cpp | 104 +++++--- .../dogm/u8g/u8g_dev_uc1701_mini12864_HAL.cpp | 2 +- 7 files changed, 456 insertions(+), 166 deletions(-) create mode 100644 Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1306_sh1106_128x64_SWSPI.cpp diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index 7de6146f293c..f664e84691d0 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -654,11 +654,11 @@ #elif ENABLED(ZONESTAR_12864OLED) #define IS_RRD_SC 1 - #define U8GLIB_SH1106 + #define U8GLIB_SH1106_SPI #elif ENABLED(ZONESTAR_12864OLED_SSD1306) #define IS_RRD_SC 1 - #define IS_U8GLIB_SSD1306 + #define U8GLIB_SSD1306_SPI #elif ENABLED(RADDS_DISPLAY) #define IS_ULTIPANEL 1 @@ -716,7 +716,7 @@ #elif ENABLED(SAV_3DGLCD) - #ifdef U8GLIB_SSD1306 + #if ENABLED(U8GLIB_SSD1306) #define IS_U8GLIB_SSD1306 // Allow for U8GLIB_SSD1306 + SAV_3DGLCD #endif #define IS_NEWPANEL 1 @@ -857,9 +857,12 @@ #define STD_ENCODER_STEPS_PER_MENU_ITEM 1 #endif -// 128x64 I2C OLED LCDs - SSD1306/SSD1309/SH1106 +// 128x64 I2C OLED LCDs (SSD1306 / SSD1309 / SH1106) +// ...and 128x64 SPI OLED LCDs (SSD1306 / SH1106) #if ANY(U8GLIB_SSD1306, U8GLIB_SSD1309, U8GLIB_SH1106) #define HAS_U8GLIB_I2C_OLED 1 +#endif +#if ANY(HAS_U8GLIB_I2C_OLED, U8GLIB_SSD1306_SPI, U8GLIB_SH1106_SPI) #define HAS_WIRED_LCD 1 #define DOGLCD #endif diff --git a/Marlin/src/lcd/dogm/marlinui_DOGM.h b/Marlin/src/lcd/dogm/marlinui_DOGM.h index 9025395f5600..d3f38cd61994 100644 --- a/Marlin/src/lcd/dogm/marlinui_DOGM.h +++ b/Marlin/src/lcd/dogm/marlinui_DOGM.h @@ -155,7 +155,11 @@ #if ENABLED(ALTERNATIVE_LCD) #define U8G_CLASS U8GLIB_SH1306_128X64_2X // 4 stripes #else - #define U8G_CLASS U8GLIB_SH1306_128X64 // 8 stripes + #if ENABLED(U8GLIB_SSD1306_SPI) + #define U8G_CLASS U8GLIB_SSD1306_128X64_SW_SPI_HAL + #else + #define U8G_CLASS U8GLIB_SH1306_128X64 // 8 stripes + #endif #endif #elif ANY(MKS_12864OLED, ZONESTAR_12864OLED) @@ -168,7 +172,11 @@ #if ENABLED(ALTERNATIVE_LCD) #define U8G_CLASS U8GLIB_SH1106_128X64_2X // 4 stripes #else - #define U8G_CLASS U8GLIB_SH1106_128X64 // 8 stripes + #if ENABLED(U8GLIB_SH1106_SPI) + #define U8G_CLASS U8GLIB_SH1106_128X64_SW_SPI_HAL + #else + #define U8G_CLASS U8GLIB_SH1106_128X64 // 8 stripes + #endif #endif #elif ENABLED(U8GLIB_SH1106_EINSTART) diff --git a/Marlin/src/lcd/dogm/u8g/HAL_LCD_class_defines.h b/Marlin/src/lcd/dogm/u8g/HAL_LCD_class_defines.h index 907fa43c9bd7..33a9c21c4109 100644 --- a/Marlin/src/lcd/dogm/u8g/HAL_LCD_class_defines.h +++ b/Marlin/src/lcd/dogm/u8g/HAL_LCD_class_defines.h @@ -23,7 +23,7 @@ #include "../../../inc/MarlinConfig.h" -// use this file to create the public interface for device drivers that are NOT in the U8G library +// Use this file to create the public interface for device drivers that are NOT in the U8G library extern u8g_dev_t u8g_dev_st7565_64128n_HAL_2x_sw_spi; extern u8g_dev_t u8g_dev_st7565_64128n_HAL_2x_hw_spi; @@ -90,6 +90,30 @@ class U8GLIB_SSD1306_128X64_2X_I2C_2_WIRE : public U8GLIB { void init(uint8_t options = U8G_I2C_OPT_NONE) { U8GLIB::init(&u8g_dev_ssd1306_128x64_2x_i2c_2_wire, options); } }; +#if ENABLED(U8GLIB_SH1106_SPI) + extern u8g_dev_t u8g_dev_sh1106_128x64_HAL_sw_spi; + class U8GLIB_SH1106_128X64_SW_SPI_HAL : public U8GLIB { + public: + U8GLIB_SH1106_128X64_SW_SPI_HAL() : U8GLIB() { } + U8GLIB_SH1106_128X64_SW_SPI_HAL(pin_t sck, pin_t mosi, pin_t cs, pin_t reset = U8G_PIN_NONE) {init(sck, mosi, cs, reset); } + void init(pin_t sck, pin_t mosi, pin_t cs, pin_t reset=U8G_PIN_NONE) { + U8GLIB::init(&u8g_dev_sh1106_128x64_HAL_sw_spi, (uint8_t)sck, (uint8_t)mosi, (uint8_t)cs, U8G_PIN_NONE, (uint8_t)reset); + } + }; +#endif + +#if ENABLED(U8GLIB_SSD1306_SPI) + extern u8g_dev_t u8g_dev_ssd1306_128x64_HAL_sw_spi; + class U8GLIB_SSD1306_128X64_SW_SPI_HAL : public U8GLIB { + public: + U8GLIB_SSD1306_128X64_SW_SPI_HAL() : U8GLIB() { } + U8GLIB_SSD1306_128X64_SW_SPI_HAL(pin_t sck, pin_t mosi, pin_t cs, pin_t reset = U8G_PIN_NONE) {init(sck, mosi, cs, reset); } + void init(pin_t sck, pin_t mosi, pin_t cs, pin_t reset=U8G_PIN_NONE) { + U8GLIB::init(&u8g_dev_ssd1306_128x64_HAL_sw_spi, (uint8_t)sck, (uint8_t)mosi, (uint8_t)cs, U8G_PIN_NONE, (uint8_t)reset); + } + }; +#endif + // // Very basic support for 320x240 TFT screen // Tested on MKS Robin TFT_V2.0 with ST7789V controller diff --git a/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp b/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp index 4cd9b8f3c06d..4d4756c298cf 100644 --- a/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp +++ b/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp @@ -77,35 +77,34 @@ uint8_t u8g_WriteEscSeqP_2_wire(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_seq); -// The sh1106 is compatible to the ssd1306, but is 132x64. 128x64 display area is centered within -// the 132x64. +// SH1106 (132x64) is compatible with SSD1306 (128x64) by adding a small margin to the larger display + +#define SH1106_PAGE_ADR(N) (0x20), (N) +#define SH1106_COL_ADR(N) (0x10 | ((N) >> 4)), ((N) & 0xFF) +#define SH1106_COLUMN_RANGE(N,O) (0x21), (N), (O) +#define SH1106_PAGE_RANGE(N,O) (0x22), (N), (O) +#define SH1106_SCROLL(N) ((N) ? 0x2F : 0x2E) +#define SH1106_START_LINE(N) (0x40 | (N)) +#define SH1106_CONTRAST(N) (0x81), (N) +#define SH1106_CHARGE_PUMP(N) (0x8D), ((N) ? 0x14 : 0x10) +#define SH1106_ADC_REVERSE(N) ((N) ? 0xA1 : 0xA0) +#define SH1106_ALL_PIX(N) ((N) ? 0xA5 : 0xA4) +#define SH1106_INVERTED(N) ((N) ? 0xA7 : 0xA6) +#define SH1106_MUX_RATIO(N) (0xA8), (N) +#define SH1106_ON(N) ((N) ? 0xAF : 0xAE) +#define SH1106_OUT_MODE(N) ((N) ? 0xC8 : 0xC0) +#define SH1106_DISP_OFFS(N) (0xD3), (N) +#define SH1106_OSC_FREQ(R,F) (0xD5), ((F) << 4 | (R)) +#define SH1106_CHARGE_PER(P,D) (0xD9), ((D) << 4 | (P)) +#define SH1106_COM_CONFIG(N) (0xDA), ((N) ? 0x12 : 0x02) +#define SH1106_VCOM_DESEL(N) (0xDB), (N) +#define SH1106_NOOP() (0xE3) static const uint8_t u8g_dev_sh1106_128x64_data_start_2_wire[] PROGMEM = { - 0x010, // set upper 4 bit of the col adr to 0 - 0x002, // set lower 4 bit of the col adr to 2 (centered display with ssd1306) - U8G_ESC_END // end of sequence + SH1106_COL_ADR(2), // Column 2 to center 128 pixels in 132 pixels + U8G_ESC_END // End of sequence }; -#define SH1106_PAGE_ADR(N) (0x20), (N) -#define SH1106_COLUMN_RANGE(N) (0x21), (((N) >> 8) & 0xFF), ((N) & 0xFF) -#define SH1106_PAGE_RANGE(N,O) (0x22), (N), (O) -#define SH1106_SCROLL(N) ((N) ? 0x2F : 0x2E) -#define SH1106_START_LINE(N) (0x40 | (N)) -#define SH1106_CONTRAST(N) (0x81), (N) -#define SH1106_CHARGE_PUMP(N) (0x8D), ((N) ? 0x14 : 0x10) -#define SH1106_ADC_REVERSE(N) ((N) ? 0xA1 : 0xA0) -#define SH1106_ALL_PIX(N) ((N) ? 0xA5 : 0xA4) -#define SH1106_INVERTED(N) ((N) ? 0xA7 : 0xA6) -#define SH1106_MUX_RATIO(N) (0xA8), (N) -#define SH1106_ON(N) ((N) ? 0xAF : 0xAE) -#define SH1106_OUT_MODE(N) ((N) ? 0xC8 : 0xC0) -#define SH1106_DISP_OFFS(N) (0xD3), (N) -#define SH1106_OSC_FREQ(R,F) (0xD5), ((F) << 4 | (R)) -#define SH1106_CHARGE_PER(P,D) (0xD9), ((D) << 4 | (P)) -#define SH1106_COM_CONFIG(N) (0xDA), ((N) ? 0x12 : 0x02) -#define SH1106_VCOM_DESEL(N) (0xDB), (N) -#define SH1106_NOOP() (0xE3) - static const uint8_t u8g_dev_sh1106_128x64_init_seq_2_wire[] PROGMEM = { U8G_ESC_ADR(0), // Initiate command mode SH1106_ON(0), // Display off, sleep mode @@ -113,19 +112,19 @@ static const uint8_t u8g_dev_sh1106_128x64_init_seq_2_wire[] PROGMEM = { SH1106_DISP_OFFS(0), // Display offset SH1106_START_LINE(0), // Start line SH1106_ADC_REVERSE(1), // Segment remap A0/A1 - SH1106_OUT_MODE(1), // C0: scan dir normal, C8: reverse - SH1106_COM_CONFIG(1), // Com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) - SH1106_CONTRAST(0xCF), // [2] set contrast control - SH1106_PAGE_ADR(0x02), // 2012-05-27: page addressing mode - SH1106_COLUMN_RANGE(0x281), // Set column range from 0 through 131 - SH1106_PAGE_RANGE(0, 7), // Set page range from 0 through 7 - SH1106_CHARGE_PER(0x1, 0xF), // [2] pre-charge period 0x22/F1 + SH1106_OUT_MODE(1), // 0: scan dir normal, 1: reverse + SH1106_COM_CONFIG(1), // COM pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) + SH1106_CONTRAST(0xCF), // Set contrast control + SH1106_PAGE_ADR(0x02), // page addressing mode + SH1106_COLUMN_RANGE(2, 129), // Set column range 2 .. 129 + SH1106_PAGE_RANGE(0, 7), // Set page range 0 .. 7 + SH1106_CHARGE_PER(0x1, 0xF), // Pre-charge period SH1106_VCOM_DESEL(0x40), // Vcomh deselect level - SH1106_ALL_PIX(0), // Output ram to display + SH1106_ALL_PIX(0), // Output RAM to display SH1106_INVERTED(0), // Normal display mode SH1106_OSC_FREQ(0, 8), // Clock divide ratio (0:1) and oscillator frequency (8) - SH1106_CHARGE_PUMP(1), // [2] charge pump setting (P62): 0x14 enable, 0x10 disable - SH1106_SCROLL(0), // 2012-05-27: Deactivate scroll + SH1106_CHARGE_PUMP(1), // Charge pump setting + SH1106_SCROLL(0), // Deactivate scroll SH1106_ON(1), // Display on U8G_ESC_END // End of sequence }; @@ -136,28 +135,24 @@ uint8_t u8g_dev_sh1106_128x64_2x_2_wire_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t m u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_sh1106_128x64_init_seq_2_wire); break; - case U8G_DEV_MSG_STOP: - break; + case U8G_DEV_MSG_STOP: break; case U8G_DEV_MSG_PAGE_NEXT: { - u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); - u8g_SetAddress(u8g, dev, 0); // instruction mode - u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_sh1106_128x64_data_start_2_wire); - u8g_WriteByte(u8g, dev, 0x0B0 | (pb->p.page*2)); // select current page - u8g_SetAddress(u8g, dev, 1); // data mode - u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *) pb->buf); - u8g_SetChipSelect(u8g, dev, 0); - u8g_SetAddress(u8g, dev, 0); // instruction mode - u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_sh1106_128x64_data_start_2_wire); - u8g_WriteByte(u8g, dev, 0x0B0 | (pb->p.page*2+1)); // select current page - u8g_SetAddress(u8g, dev, 1); // data mode - u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *)(pb->buf)+pb->width); - u8g_SetChipSelect(u8g, dev, 0); - } - break; - case U8G_DEV_MSG_SLEEP_ON: - return 1; - case U8G_DEV_MSG_SLEEP_OFF: - return 1; + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + u8g_SetAddress(u8g, dev, 0); // Instruction mode + u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_sh1106_128x64_data_start_2_wire); + u8g_WriteByte(u8g, dev, 0xB0 | (pb->p.page*2)); // Select current page + u8g_SetAddress(u8g, dev, 1); // Data mode + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *) pb->buf); + u8g_SetChipSelect(u8g, dev, 0); + u8g_SetAddress(u8g, dev, 0); // Instruction mode + u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_sh1106_128x64_data_start_2_wire); + u8g_WriteByte(u8g, dev, 0xB0 | (pb->p.page*2+1)); // Select current page + u8g_SetAddress(u8g, dev, 1); // Data mode + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *)(pb->buf)+pb->width); + u8g_SetChipSelect(u8g, dev, 0); + } break; + case U8G_DEV_MSG_SLEEP_ON: return 1; + case U8G_DEV_MSG_SLEEP_OFF: return 1; } return u8g_dev_pb16v1_base_fn(u8g, dev, msg, arg); } @@ -169,33 +164,32 @@ u8g_dev_t u8g_dev_sh1106_128x64_2x_i2c_2_wire = { u8g_dev_sh1106_128x64_2x_2_wir ///////////////////////////////////////////////////////////////////////////////////////////// static const uint8_t u8g_dev_ssd1306_128x64_data_start_2_wire[] PROGMEM = { - 0x010, // set upper 4 bit of the col adr to 0 - 0x000, // set lower 4 bit of the col adr to 0 - U8G_ESC_END // end of sequence + SH1106_COL_ADR(0), // Column 0 + U8G_ESC_END // End of sequence }; static const uint8_t u8g_dev_ssd1306_128x64_init_seq_2_wire[] PROGMEM = { - U8G_ESC_ADR(0), // initiate command mode - 0x0AE, // display off, sleep mode - 0x0A8, 0x03F, // mux ratio - 0x0D3, 0x00, // display offset - 0x040, // start line - 0x0A1, // segment remap a0/a1 - 0x0C8, // c0: scan dir normal, c8: reverse - 0x0DA, 0x012, // com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) - 0x081, 0x0CF, // [2] set contrast control - 0x020, 0x002, // 2012-05-27: page addressing mode - 0x21, 0, 0x7F, // set column range from 0 through 127 - 0x22, 0, 7, // set page range from 0 through 7 - 0x0D9, 0x0F1, // [2] pre-charge period 0x022/f1 - 0x0DB, 0x040, // vcomh deselect level - 0x0A4, // output ram to display - 0x0A6, // none inverted normal display mode - 0x0D5, 0x080, // clock divide ratio (0x00=1) and oscillator frequency (0x8) - 0x08D, 0x014, // [2] charge pump setting (p62): 0x014 enable, 0x010 disable - 0x02E, // 2012-05-27: Deactivate scroll - 0x0AF, // display on - U8G_ESC_END // end of sequence + U8G_ESC_CS(0), // Disable chip + SH1106_ON(0), // Display off, sleep mode + SH1106_MUX_RATIO(0x3F), // Mux ratio + SH1106_DISP_OFFS(0), // Display offset + SH1106_START_LINE(0), // Start line + SH1106_ADC_REVERSE(1), // Segment remap A0/A1 + SH1106_OUT_MODE(1), // 0: scan dir normal, 1: reverse + SH1106_COM_CONFIG(1), // COM pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) + SH1106_CONTRAST(0xCF), // Set contrast control + SH1106_PAGE_ADR(0x02), // page addressing mode + SH1106_COLUMN_RANGE(0, 127), // Set column range 0 .. 127 + SH1106_PAGE_RANGE(0, 7), // Set page range from 0 .. 7 + SH1106_CHARGE_PER(0x1, 0xF), // Pre-charge period + SH1106_VCOM_DESEL(0x40), // Vcomh deselect level + SH1106_ALL_PIX(0), // Send RAM to display + SH1106_INVERTED(0), // Normal display mode + SH1106_OSC_FREQ(0, 8), // Clock divide ratio (0:1) and oscillator frequency (8) + SH1106_CHARGE_PUMP(1), // Charge pump setting + SH1106_SCROLL(0), // Deactivate scroll + SH1106_ON(1), // Display on + U8G_ESC_END // End of sequence }; uint8_t u8g_dev_ssd1306_128x64_2x_2_wire_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { @@ -204,28 +198,24 @@ uint8_t u8g_dev_ssd1306_128x64_2x_2_wire_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_ssd1306_128x64_init_seq_2_wire); break; - case U8G_DEV_MSG_STOP: - break; + case U8G_DEV_MSG_STOP: break; case U8G_DEV_MSG_PAGE_NEXT: { - u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); - u8g_SetAddress(u8g, dev, 0); // instruction mode - u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_ssd1306_128x64_data_start_2_wire); - u8g_WriteByte(u8g, dev, 0x0B0 | (pb->p.page*2)); // select current page - u8g_SetAddress(u8g, dev, 1); // data mode - u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *) pb->buf); - u8g_SetChipSelect(u8g, dev, 0); - u8g_SetAddress(u8g, dev, 0); // instruction mode - u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_ssd1306_128x64_data_start_2_wire); - u8g_WriteByte(u8g, dev, 0x0B0 | (pb->p.page*2+1)); // select current page - u8g_SetAddress(u8g, dev, 1); // data mode - u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *)(pb->buf)+pb->width); - u8g_SetChipSelect(u8g, dev, 0); - } - break; - case U8G_DEV_MSG_SLEEP_ON: - return 1; - case U8G_DEV_MSG_SLEEP_OFF: - return 1; + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + u8g_SetAddress(u8g, dev, 0); // Instruction mode + u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_ssd1306_128x64_data_start_2_wire); + u8g_WriteByte(u8g, dev, 0xB0 | (pb->p.page*2)); // Select current page + u8g_SetAddress(u8g, dev, 1); // Data mode + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *) pb->buf); + u8g_SetChipSelect(u8g, dev, 0); + u8g_SetAddress(u8g, dev, 0); // Instruction mode + u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_ssd1306_128x64_data_start_2_wire); + u8g_WriteByte(u8g, dev, 0xB0 | (pb->p.page*2+1)); // Select current page + u8g_SetAddress(u8g, dev, 1); // Data mode + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *)(pb->buf)+pb->width); + u8g_SetChipSelect(u8g, dev, 0); + } break; + case U8G_DEV_MSG_SLEEP_ON: return 1; + case U8G_DEV_MSG_SLEEP_OFF: return 1; } return u8g_dev_pb16v1_base_fn(u8g, dev, msg, arg); } @@ -236,10 +226,10 @@ u8g_dev_t u8g_dev_ssd1306_128x64_2x_i2c_2_wire = { u8g_dev_ssd1306_128x64_2x_2_w ///////////////////////////////////////////////////////////////////////////////////////////// -// This routine adds the instruction byte in between the command bytes. This makes the init -// sequences a lot easier to read. +// This routine adds the instruction byte in between the command bytes. +// This makes the init sequences a lot easier to read. -#define I2C_CMD_MODE 0x080 +#define I2C_CMD_MODE 0x80 uint8_t u8g_WriteEscSeqP_2_wire(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_seq) { uint8_t is_escape = 0; @@ -247,10 +237,8 @@ uint8_t u8g_WriteEscSeqP_2_wire(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_s uint8_t value = u8g_pgm_read(esc_seq); if (is_escape == 0) { if (value != 255) { - if (u8g_WriteByte(u8g, dev, value) == 0 ) - return 0; - if (u8g_WriteByte(u8g, dev, I2C_CMD_MODE) == 0 ) - return 0; + if (u8g_WriteByte(u8g, dev, value) == 0) return 0; + if (u8g_WriteByte(u8g, dev, I2C_CMD_MODE) == 0) return 0; } else { is_escape = 1; @@ -258,16 +246,14 @@ uint8_t u8g_WriteEscSeqP_2_wire(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_s } else { if (value == 255) { - if (u8g_WriteByte(u8g, dev, value) == 0 ) - return 0; - if (u8g_WriteByte(u8g, dev, I2C_CMD_MODE) == 0 ) - return 0; + if (u8g_WriteByte(u8g, dev, value) == 0) return 0; + if (u8g_WriteByte(u8g, dev, I2C_CMD_MODE) == 0) return 0; } else if (value == 254) { break; } - else if (value >= 0x0F0) { - /* not yet used, do nothing */ + else if (value >= 0xF0) { + // not yet used, do nothing } else if (value >= 0xE0 ) { u8g_SetAddress(u8g, dev, value & 0x0F); @@ -279,13 +265,14 @@ uint8_t u8g_WriteEscSeqP_2_wire(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_s u8g_SetResetLow(u8g, dev); value &= 0x0F; value <<= 4; - value+=2; + value += 2; u8g_Delay(value); u8g_SetResetHigh(u8g, dev); u8g_Delay(value); } - else if (value >= 0xBE) { /* not yet implemented */ - /* u8g_SetVCC(u8g, dev, value & 0x01); */ + else if (value >= 0xBE) { + // not yet implemented + //u8g_SetVCC(u8g, dev, value & 0x01); } else if (value <= 127) { u8g_Delay(value); diff --git a/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1306_sh1106_128x64_SWSPI.cpp b/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1306_sh1106_128x64_SWSPI.cpp new file mode 100644 index 000000000000..afb3c28a8ce3 --- /dev/null +++ b/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1306_sh1106_128x64_SWSPI.cpp @@ -0,0 +1,246 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Based on u8g_dev_ssd1306_128x64.c + * + * Universal 8bit Graphics Library + * + * Copyright (c) 2015, olikraus@gmail.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "../../../inc/MarlinConfig.h" + +#if ALL(HAS_MARLINUI_U8GLIB, FORCE_SOFT_SPI) && ANY(U8GLIB_SH1106_SPI, U8GLIB_SSD1306_SPI) + +#include "HAL_LCD_com_defines.h" + +#define WIDTH 128 +#define HEIGHT 64 +#define PAGE_HEIGHT 8 + +#define SH1106_PAGE_ADR(N) (0x20), (N) +#define SH1106_COL_ADR(N) (0x10 | ((N) >> 4)), ((N) & 0xFF) +#define SH1106_COLUMN_RANGE(N,O) (0x21), (N), (O) +#define SH1106_PAGE_RANGE(N,O) (0x22), (N), (O) +#define SH1106_SCROLL(N) ((N) ? 0x2F : 0x2E) +#define SH1106_START_LINE(N) (0x40 | (N)) +#define SH1106_CONTRAST(N) (0x81), (N) +#define SH1106_CHARGE_PUMP(N) (0x8D), ((N) ? 0x14 : 0x10) +#define SH1106_ADC_REVERSE(N) ((N) ? 0xA1 : 0xA0) +#define SH1106_ALL_PIX(N) ((N) ? 0xA5 : 0xA4) +#define SH1106_INVERTED(N) ((N) ? 0xA7 : 0xA6) +#define SH1106_MUX_RATIO(N) (0xA8), (N) +#define SH1106_ON(N) ((N) ? 0xAF : 0xAE) +#define SH1106_OUT_MODE(N) ((N) ? 0xC8 : 0xC0) +#define SH1106_DISP_OFFS(N) (0xD3), (N) +#define SH1106_OSC_FREQ(R,F) (0xD5), ((F) << 4 | (R)) +#define SH1106_CHARGE_PER(P,D) (0xD9), ((D) << 4 | (P)) +#define SH1106_COM_CONFIG(N) (0xDA), ((N) ? 0x12 : 0x02) +#define SH1106_VCOM_DESEL(N) (0xDB), (N) +#define SH1106_NOOP() (0xE3) + +static const uint8_t u8g_dev_ssd13xx_HAL_sleep_on[] PROGMEM = { + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_CS(1), // Enable chip + SH1106_ON(0) // Display off + U8G_ESC_CS(0), // Disable chip + U8G_ESC_END // End of sequence +}; + +static const uint8_t u8g_dev_ssd13xx_HAL_sleep_off[] PROGMEM = { + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_CS(1), // Enable chip + SH1106_ON(1), // Display on + U8G_ESC_DLY(50), // Delay 50 ms + U8G_ESC_CS(0), // Disable chip + U8G_ESC_END // End of sequence +}; + +#if ENABLED(U8GLIB_SH1106_SPI) + +// Init sequence Adafruit 128x64 OLED (NOT TESTED). Like Adafruit3, but with page addressing mode. +static const uint8_t u8g_dev_sh1106_128x64_HAL_init_seq[] PROGMEM = { + U8G_ESC_CS(0), // Disable chip + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_RST(1), // Do reset low pulse with (1*16)+2 milliseconds + U8G_ESC_CS(1), // Enable chip + SH1106_ON(0), // Display off, sleep mode + SH1106_OSC_FREQ(0, 8), // Clock divide ratio (0:1) and oscillator frequency (8) + SH1106_MUX_RATIO(0x3F), // Mux ratio + SH1106_DISP_OFFS(0), // Display offset + SH1106_START_LINE(0), // Start line + SH1106_CHARGE_PUMP(1), // Charge pump setting + SH1106_PAGE_ADR(0x02), // page addressing mode + SH1106_ADC_REVERSE(1), // Segment remap A0/A1 + SH1106_OUT_MODE(1), // 0: scan dir normal, 1: reverse + SH1106_COM_CONFIG(1), // COM pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) + SH1106_CONTRAST(0x80), // Set contrast control + SH1106_CHARGE_PER(0x1, 0xF), // Pre-charge period + SH1106_VCOM_DESEL(0x40), // Vcomh deselect level + SH1106_SCROLL(0), // Deactivate scroll + SH1106_ALL_PIX(0), // Output RAM to display + SH1106_INVERTED(0), // Normal display mode + SH1106_ON(1), // Display on + U8G_ESC_CS(0), // Disable chip + U8G_ESC_END // End of sequence +}; + +// SH1106 (132x64) is compatible with SSD1306 (128x64) by adding a small margin to the larger display +static const uint8_t u8g_dev_sh1106_128x64_HAL_data_start[] PROGMEM = { + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_CS(1), // Enable chip + SH1106_COL_ADR(2), // Column 2 to center 128 pixels in 132 pixels + U8G_ESC_END // End of sequence +}; + +uint8_t u8g_dev_sh1106_128x64_HAL_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { + switch(msg) { + case U8G_DEV_MSG_INIT: + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_sh1106_128x64_HAL_init_seq); + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_NEXT: { + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_sh1106_128x64_HAL_data_start); + u8g_WriteByte(u8g, dev, 0x0B0 | pb->p.page); // Select current page (SSD1306) + u8g_SetAddress(u8g, dev, 1); // Data mode + if (u8g_pb_WriteBuffer(pb, u8g, dev) == 0) return 0; + u8g_SetChipSelect(u8g, dev, 0); + } break; + case U8G_DEV_MSG_SLEEP_ON: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_HAL_sleep_on); + return 1; + case U8G_DEV_MSG_SLEEP_OFF: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_HAL_sleep_off); + return 1; + case U8G_DEV_MSG_CONTRAST: + u8g_SetChipSelect(u8g, dev, 1); + u8g_SetAddress(u8g, dev, 0); // Instruction mode + u8g_WriteByte(u8g, dev, 0x81); + u8g_WriteByte(u8g, dev, *(uint8_t *) arg); + u8g_SetChipSelect(u8g, dev, 0); + return 1; + } + return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg); +} + +U8G_PB_DEV(u8g_dev_sh1106_128x64_HAL_sw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_sh1106_128x64_HAL_fn, U8G_COM_HAL_SW_SPI_FN); + +#elif ENABLED(U8GLIB_SSD1306_SPI) + +static const uint8_t u8g_dev_ssd1306_128x64_HAL_init_seq[] PROGMEM = { + U8G_ESC_CS(0), // Disable chip + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_RST(1), // Do reset low pulse with (1*16)+2 milliseconds + U8G_ESC_CS(1), // Enable chip + SH1106_ON(0), // Display off, sleep mode + SH1106_OSC_FREQ(0, 8), // Clock divide ratio (0:1) and oscillator frequency (8) + SH1106_MUX_RATIO(0x3F), // Mux ratio + SH1106_DISP_OFFS(0), // Display offset + SH1106_START_LINE(0), // Start line + SH1106_CHARGE_PUMP(1), // Charge pump setting + SH1106_PAGE_ADR(0x02), // page addressing mode + SH1106_ADC_REVERSE(1), // Segment remap A0/A1 + SH1106_OUT_MODE(1), // 0: scan dir normal, 1: reverse + SH1106_COM_CONFIG(1), // COM pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) + SH1106_CONTRAST(0x80), // Set contrast control + SH1106_CHARGE_PER(0x1, 0xF), // Pre-charge period + SH1106_VCOM_DESEL(0x40), // Vcomh deselect level + SH1106_SCROLL(0), // Deactivate scroll + SH1106_ALL_PIX(0), // Output RAM to display + SH1106_INVERTED(0), // Normal display mode + SH1106_ON(1), // Display on + U8G_ESC_CS(0), // Disable chip + U8G_ESC_END // End of sequence +}; + +static const uint8_t u8g_dev_ssd1306_128x64_HAL_data_start[] PROGMEM = { + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_CS(1), // Enable chip + SH1106_COL_ADR(0), // Column 0 + U8G_ESC_END // End of sequence +}; + +uint8_t u8g_dev_ssd1306_128x64_HAL_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { + switch(msg) { + case U8G_DEV_MSG_INIT: + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_400NS); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1306_128x64_HAL_init_seq); + break; + case U8G_DEV_MSG_STOP: break; + case U8G_DEV_MSG_PAGE_NEXT: { + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1306_128x64_HAL_data_start); + u8g_WriteByte(u8g, dev, 0x0b0 | pb->p.page); // Select current page (SSD1306) + u8g_SetAddress(u8g, dev, 1); // Data mode + if (u8g_pb_WriteBuffer(pb, u8g, dev) == 0) return 0; + u8g_SetChipSelect(u8g, dev, 0); + } break; + case U8G_DEV_MSG_SLEEP_ON: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_HAL_sleep_on); + return 1; + case U8G_DEV_MSG_SLEEP_OFF: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_HAL_sleep_off); + return 1; + case U8G_DEV_MSG_CONTRAST: + u8g_SetChipSelect(u8g, dev, 1); + u8g_SetAddress(u8g, dev, 0); // Instruction mode + u8g_WriteByte(u8g, dev, 0x81); + u8g_WriteByte(u8g, dev, *(uint8_t *) arg); + u8g_SetChipSelect(u8g, dev, 0); + return 1; + } + return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg); +} + +U8G_PB_DEV(u8g_dev_ssd1306_128x64_HAL_sw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_ssd1306_128x64_HAL_fn, U8G_COM_HAL_SW_SPI_FN); + +#endif // U8GLIB_SSD1306_SPI +#endif // HAS_MARLINUI_U8GLIB diff --git a/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1309_12864.cpp b/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1309_12864.cpp index 4aa90d5e8e82..010231d0561f 100644 --- a/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1309_12864.cpp +++ b/Marlin/src/lcd/dogm/u8g/u8g_dev_ssd1309_12864.cpp @@ -31,61 +31,83 @@ #define HEIGHT 64 #define PAGE_HEIGHT 8 +#define SSD1309_PAGE_ADR(N) (0x20), (N) +#define SSD1309_COL_ADR(N) (0x10 | ((N) >> 4)), ((N) & 0xFF) +#define SSD1309_COLUMN_RANGE(N,O) (0x21), (N), (O) +#define SSD1309_PAGE_RANGE(N,O) (0x22), (N), (O) +#define SSD1309_SCROLL(N) ((N) ? 0x2F : 0x2E) +#define SSD1309_START_LINE(N) (0x40 | (N)) +#define SSD1309_CONTRAST(N) (0x81), (N) +#define SSD1309_CHARGE_PUMP(N) (0x8D), ((N) ? 0x14 : 0x10) +#define SSD1309_ADC_REVERSE(N) ((N) ? 0xA1 : 0xA0) +#define SSD1309_ALL_PIX(N) ((N) ? 0xA5 : 0xA4) +#define SSD1309_INVERTED(N) ((N) ? 0xA7 : 0xA6) +#define SSD1309_MUX_RATIO(N) (0xA8), (N) +#define SSD1309_ON(N) ((N) ? 0xAF : 0xAE) +#define SSD1309_OUT_MODE(N) ((N) ? 0xC8 : 0xC0) +#define SSD1309_DISP_OFFS(N) (0xD3), (N) +#define SSD1309_OSC_FREQ(R,F) (0xD5), ((F) << 4 | (R)) +#define SSD1309_CHARGE_PER(P,D) (0xD9), ((D) << 4 | (P)) +#define SSD1309_COM_CONFIG(N) (0xDA), ((N) ? 0x12 : 0x02) +#define SSD1309_VCOM_DESEL(N) (0xDB), (N) +#define SSD1309_NOOP() (0xE3) +#define SSD1309_COMMAND_LOCK(N) (0xFD), ((N) ? 0x16 : 0x12) + // SSD1309 init sequence static const uint8_t u8g_dev_ssd1309_128x64_init_seq[] PROGMEM = { - U8G_ESC_CS(0), // Disable chip - U8G_ESC_ADR(0), // Instruction mode - U8G_ESC_RST(1), // Do reset low pulse with (1*16)+2 milliseconds - U8G_ESC_CS(1), // Enable chip + U8G_ESC_CS(0), // Disable chip + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_RST(1), // Do reset low pulse with (1*16)+2 milliseconds + U8G_ESC_CS(1), // Enable chip + + SSD1309_COMMAND_LOCK(0), // Unlock OLED driver IC MCU command interface + SSD1309_ON(0), + SSD1309_OSC_FREQ(0, 10), // Clock divide ratio (0:1) and oscillator frequency (8) + SSD1309_MUX_RATIO(0x3F), // Mux ratio + SSD1309_DISP_OFFS(0), // Display offset + SSD1309_START_LINE(0), // Start line + SSD1309_ADC_REVERSE(1), // Segment remap A0/A1 + SSD1309_OUT_MODE(1), // 0: scan dir normal, 1: reverse + SSD1309_COM_CONFIG(1), // COM pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) + SSD1309_CONTRAST(0xDF), // Set contrast control + SSD1309_CHARGE_PER(0x2, 0x8), // Pre-charge period + SSD1309_VCOM_DESEL(0x34), // Vcomh deselect level + SSD1309_ALL_PIX(0), // Output RAM to display + SSD1309_INVERTED(0), // Normal display mode - 0xFD,0x12, // Command Lock - 0xAE, // Set Display Off - 0xD5,0xA0, // Set Display Clock Divide Ratio/Oscillator Frequency - 0xA8,0x3F, // Set Multiplex Ratio - 0x3D,0x00, // Set Display Offset - 0x40, // Set Display Start Line - 0xA1, // Set Segment Re-Map - 0xC8, // Set COM Output Scan Direction - 0xDA,0x12, // Set COM Pins Hardware Configuration - 0x81,0xDF, // Set Current Control - 0xD9,0x82, // Set Pre-Charge Period - 0xDB,0x34, // Set VCOMH Deselect Level - 0xA4, // Set Entire Display On/Off - 0xA6, // Set Normal/Inverse Display - U8G_ESC_VCC(1), // Power up VCC & Stabilized + U8G_ESC_VCC(1), // Power up VCC & stabilize U8G_ESC_DLY(50), - 0xAF, // Set Display On + SSD1309_ON(1), // Display on U8G_ESC_DLY(50), - U8G_ESC_CS(0), // Disable chip - U8G_ESC_END // End of sequence + U8G_ESC_CS(0), // Disable chip + U8G_ESC_END // End of sequence }; // Select one init sequence here #define u8g_dev_ssd1309_128x64_init_seq u8g_dev_ssd1309_128x64_init_seq static const uint8_t u8g_dev_ssd1309_128x64_data_start[] PROGMEM = { - U8G_ESC_ADR(0), // Instruction mode - U8G_ESC_CS(1), // Enable chip - 0x010, // Set upper 4 bit of the col adr to 0 - 0x000, // Set lower 4 bit of the col adr to 4 - U8G_ESC_END // End of sequence + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_CS(1), // Enable chip + SSD1309_COL_ADR(0), // Column 0 + U8G_ESC_END // End of sequence }; static const uint8_t u8g_dev_ssd13xx_sleep_on[] PROGMEM = { - U8G_ESC_ADR(0), // Instruction mode - U8G_ESC_CS(1), // Enable chip - 0x0AE, // Display off - U8G_ESC_CS(0), // Disable chip - U8G_ESC_END // End of sequence + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_CS(1), // Enable chip + SSD1309_ON(0), // Display off + U8G_ESC_CS(0), // Disable chip + U8G_ESC_END // End of sequence }; static const uint8_t u8g_dev_ssd13xx_sleep_off[] PROGMEM = { - U8G_ESC_ADR(0), // Instruction mode - U8G_ESC_CS(1), // Enable chip - 0x0AF, // Display on - U8G_ESC_DLY(50), // Delay 50 ms - U8G_ESC_CS(0), // Disable chip - U8G_ESC_END // End of sequence + U8G_ESC_ADR(0), // Instruction mode + U8G_ESC_CS(1), // Enable chip + SSD1309_ON(1), // Display on + U8G_ESC_DLY(50), // Delay 50 ms + U8G_ESC_CS(0), // Disable chip + U8G_ESC_END // End of sequence }; uint8_t u8g_dev_ssd1309_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { @@ -99,7 +121,7 @@ uint8_t u8g_dev_ssd1309_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void case U8G_DEV_MSG_PAGE_NEXT: { u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1309_128x64_data_start); - u8g_WriteByte(u8g, dev, 0x0B0 | pb->p.page); // Select current page (SSD1306) + u8g_WriteByte(u8g, dev, 0xB0 | pb->p.page); // Select current page (SSD1306) u8g_SetAddress(u8g, dev, 1); // Data mode if (u8g_pb_WriteBuffer(pb, u8g, dev) == 0) return 0; u8g_SetChipSelect(u8g, dev, 0); @@ -108,8 +130,8 @@ uint8_t u8g_dev_ssd1309_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void case U8G_DEV_MSG_CONTRAST: u8g_SetChipSelect(u8g, dev, 1); u8g_SetAddress(u8g, dev, 0); // Instruction mode - u8g_WriteByte(u8g, dev, 0x081); - u8g_WriteByte(u8g, dev, (*(uint8_t *)arg) ); // 11 Jul 2015: fixed contrast calculation + u8g_WriteByte(u8g, dev, 0x81); + u8g_WriteByte(u8g, dev, (*(uint8_t *)arg)); u8g_SetChipSelect(u8g, dev, 0); return 1; case U8G_DEV_MSG_SLEEP_ON: diff --git a/Marlin/src/lcd/dogm/u8g/u8g_dev_uc1701_mini12864_HAL.cpp b/Marlin/src/lcd/dogm/u8g/u8g_dev_uc1701_mini12864_HAL.cpp index 95ae2810f256..f9c68c15fc15 100644 --- a/Marlin/src/lcd/dogm/u8g/u8g_dev_uc1701_mini12864_HAL.cpp +++ b/Marlin/src/lcd/dogm/u8g/u8g_dev_uc1701_mini12864_HAL.cpp @@ -130,7 +130,7 @@ static const uint8_t u8g_dev_uc1701_mini12864_HAL_data_start[] PROGMEM = { UC1701_V5_RATIO(3), // set V0 voltage resistor ratio to large UC1701_INDICATOR(0), // indicator disable UC1701_ON(1), // display on - UC1701_COLUMN_HI(0), // set upper 4 bit of the col adr to 0 + UC1701_COLUMN_HI(0), // set upper 4 bits of the col adr to 0 U8G_ESC_END, // end of sequence U8G_ESC_DLY(5) // delay 5 ms #else From b5b9cc0b79bc4738bdff7502502ca808068d3db6 Mon Sep 17 00:00:00 2001 From: Keith Bennett <13375512+thisiskeithb@users.noreply.github.com> Date: Thu, 4 Jul 2024 17:48:48 -0700 Subject: [PATCH 26/41] =?UTF-8?q?=F0=9F=94=A5=20Drop=20BOARD=5FBIGTREE=5FS?= =?UTF-8?q?KR=5FV1=5F2=20"renamed"=20reference=20(#27230)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/pins/pins.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h index a9349910d79c..d8776f6abb73 100644 --- a/Marlin/src/pins/pins.h +++ b/Marlin/src/pins/pins.h @@ -980,8 +980,6 @@ #error "BOARD_BIQU_SKR_V1_1 is now BOARD_BTT_SKR_V1_1. Please update your configuration." #elif MB(BIGTREE_SKR_V1_1) #error "BOARD_BIGTREE_SKR_V1_1 is now BOARD_BTT_SKR_V1_1. Please update your configuration." - #elif MB(BIGTREE_SKR_V1_2) - #error "BOARD_BIGTREE_SKR_V1_2 is now BOARD_BTT_SKR_V1_2. Please update your configuration." #elif MB(BIGTREE_SKR_V1_3) #error "BOARD_BIGTREE_SKR_V1_3 is now BOARD_BTT_SKR_V1_3. Please update your configuration." #elif MB(BIGTREE_SKR_V1_4) From f2940adcf1829969f626ccc06af8fd7c948c2127 Mon Sep 17 00:00:00 2001 From: Keith Bennett <13375512+thisiskeithb@users.noreply.github.com> Date: Thu, 4 Jul 2024 17:50:34 -0700 Subject: [PATCH 27/41] =?UTF-8?q?=F0=9F=94=A5=20Drop=20BTT=20Manta=20XFER?= =?UTF-8?q?=20environments=20(#27240)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit USB is connected to SoC (CM4/CB1/CB2), not MCU --- Marlin/src/pins/pins.h | 10 +++++----- ini/renamed.ini | 6 ++++++ ini/stm32g0.ini | 26 -------------------------- 3 files changed, 11 insertions(+), 31 deletions(-) diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h index d8776f6abb73..1a356b17d785 100644 --- a/Marlin/src/pins/pins.h +++ b/Marlin/src/pins/pins.h @@ -564,15 +564,15 @@ #elif MB(BTT_SKR_MINI_E3_V3_0) #include "stm32g0/pins_BTT_SKR_MINI_E3_V3_0.h" // STM32G0 env:STM32G0B1RE_btt env:STM32G0B1RE_btt_xfer #elif MB(BTT_MANTA_M4P_V2_1) - #include "stm32g0/pins_BTT_MANTA_M4P_V2_1.h" // STM32G0 env:STM32G0B1RE_manta_btt env:STM32G0B1RE_manta_btt_xfer + #include "stm32g0/pins_BTT_MANTA_M4P_V2_1.h" // STM32G0 env:STM32G0B1RE_manta_btt #elif MB(BTT_MANTA_M5P_V1_0) - #include "stm32g0/pins_BTT_MANTA_M5P_V1_0.h" // STM32G0 env:STM32G0B1RE_manta_btt env:STM32G0B1RE_manta_btt_xfer + #include "stm32g0/pins_BTT_MANTA_M5P_V1_0.h" // STM32G0 env:STM32G0B1RE_manta_btt #elif MB(BTT_MANTA_E3_EZ_V1_0) - #include "stm32g0/pins_BTT_MANTA_E3_EZ_V1_0.h" // STM32G0 env:STM32G0B1RE_manta_btt env:STM32G0B1RE_manta_btt_xfer + #include "stm32g0/pins_BTT_MANTA_E3_EZ_V1_0.h" // STM32G0 env:STM32G0B1RE_manta_btt #elif MB(BTT_MANTA_M8P_V1_0) - #include "stm32g0/pins_BTT_MANTA_M8P_V1_0.h" // STM32G0 env:STM32G0B1VE_btt env:STM32G0B1VE_btt_xfer + #include "stm32g0/pins_BTT_MANTA_M8P_V1_0.h" // STM32G0 env:STM32G0B1VE_btt #elif MB(BTT_MANTA_M8P_V1_1) - #include "stm32g0/pins_BTT_MANTA_M8P_V1_1.h" // STM32G0 env:STM32G0B1VE_btt env:STM32G0B1VE_btt_xfer + #include "stm32g0/pins_BTT_MANTA_M8P_V1_1.h" // STM32G0 env:STM32G0B1VE_btt // // STM32 ARM Cortex-M3 diff --git a/ini/renamed.ini b/ini/renamed.ini index 85f2df286273..5540374c685e 100644 --- a/ini/renamed.ini +++ b/ini/renamed.ini @@ -98,3 +98,9 @@ extends = renamed [env:STM32F446_tronxy] ;=> TRONXY_CXY_446_V10 extends = renamed + +[env:STM32G0B1RE_manta_btt_xfer] ;=> STM32G0B1RE_manta_btt +extends = renamed + +[env:STM32G0B1VE_btt_xfer] ;=> STM32G0B1VE_btt +extends = renamed diff --git a/ini/stm32g0.ini b/ini/stm32g0.ini index 77bdde7438dd..40493b3ff1e5 100644 --- a/ini/stm32g0.ini +++ b/ini/stm32g0.ini @@ -88,21 +88,6 @@ extends = env:STM32G0B1RE_btt build_flags = ${env:STM32G0B1RE_btt.build_flags} -DPIN_SERIAL3_RX=PD_9 -DPIN_SERIAL3_TX=PD_8 -DENABLE_HWSERIAL3 -# -# BigTreeTech Manta M4P V2.1 (STM32G0B0RET6 ARM Cortex-M0+) -# BigTreeTech Manta E3 EZ V1.0 / Manta M5P V1.0 (STM32G0B1RET6 ARM Cortex-M0+) -# Custom upload to SD via Marlin with Binary Protocol -# Requires Marlin with BINARY_FILE_TRANSFER already installed on the target board. -# If CUSTOM_FIRMWARE_UPLOAD is also installed, Marlin will reboot the board to install the firmware. -# Currently CUSTOM_FIRMWARE_UPLOAD must also be enabled to use 'xfer' build envs. -# -[env:STM32G0B1RE_manta_btt_xfer] -extends = env:STM32G0B1RE_manta_btt -build_flags = ${env:STM32G0B1RE_manta_btt.build_flags} -DXFER_BUILD -extra_scripts = ${env:STM32G0B1RE_manta_btt.extra_scripts} - pre:buildroot/share/scripts/upload.py -upload_protocol = custom - # # BigTreeTech Manta M8P V1.x (STM32G0B1VET6 ARM Cortex-M0+) # @@ -123,14 +108,3 @@ build_flags = ${stm32_variant.build_flags} -Wl,--no-warn-rwx-segment upload_protocol = stlink debug_tool = stlink - -# -# BigTreeTech Manta M8P V1.x (STM32G0B1VET6 ARM Cortex-M0+) -# Custom upload to SD via Marlin with Binary Protocol -# -[env:STM32G0B1VE_btt_xfer] -extends = env:STM32G0B1VE_btt -build_flags = ${env:STM32G0B1VE_btt.build_flags} -DXFER_BUILD -extra_scripts = ${env:STM32G0B1VE_btt.extra_scripts} - pre:buildroot/share/scripts/upload.py -upload_protocol = custom From 3c601457929ad1656e9dec49250479e0d1f9d89e Mon Sep 17 00:00:00 2001 From: tombrazier <68918209+tombrazier@users.noreply.github.com> Date: Fri, 5 Jul 2024 02:31:25 +0100 Subject: [PATCH 28/41] =?UTF-8?q?=F0=9F=A9=B9=20Fix=20"calibration"=20ends?= =?UTF-8?q?top=20report=20(#27207)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Followup to #27204 --- Marlin/src/module/endstops.cpp | 2 +- Marlin/src/module/endstops.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index e7786749b5fc..e9aafa49c847 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -1307,7 +1307,7 @@ void Endstops::update() { ES_REPORT_CHANGE(Z_MIN_PROBE); #endif #if USE_CALIBRATION - ES_REPORT_STATE(CALIBRATION); + ES_REPORT_CHANGE(CALIBRATION); #endif #if USE_X2_MIN ES_REPORT_CHANGE(X2_MIN); diff --git a/Marlin/src/module/endstops.h b/Marlin/src/module/endstops.h index 7a6da5eefa8a..c6788330f01e 100644 --- a/Marlin/src/module/endstops.h +++ b/Marlin/src/module/endstops.h @@ -258,7 +258,7 @@ class Endstops { #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); + static void enable_calibration_probe(const bool onoff, const bool stop_state=true); #endif static void resync(); From a4d20031ec730fd6285b9877d675f544fee70e1c Mon Sep 17 00:00:00 2001 From: tombrazier <68918209+tombrazier@users.noreply.github.com> Date: Fri, 5 Jul 2024 02:33:45 +0100 Subject: [PATCH 29/41] =?UTF-8?q?=F0=9F=90=9B=20Fix=20backlash=20intial=20?= =?UTF-8?q?direction=20(#27208)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix regression from #25791 --- Marlin/src/feature/backlash.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Marlin/src/feature/backlash.cpp b/Marlin/src/feature/backlash.cpp index 07fa7725a06c..3b9d78cb2e89 100644 --- a/Marlin/src/feature/backlash.cpp +++ b/Marlin/src/feature/backlash.cpp @@ -171,13 +171,14 @@ int32_t Backlash::get_applied_steps(const AxisEnum axis) { const int32_t residual_error_axis = residual_error[axis]; - // At startup it is assumed the last move was forward. - // So the applied steps will always be negative. + // At startup, when no steps are applied, it is assumed the last move was backwards. + // So the applied steps will always be zero (when moving backwards) or a positive + // number (when moving forwards). - if (forward) return -residual_error_axis; + if (!forward) return -residual_error_axis; const float f_corr = float(correction) / all_on; - const int32_t full_error_axis = -f_corr * distance_mm[axis] * planner.settings.axis_steps_per_mm[axis]; + const int32_t full_error_axis = f_corr * distance_mm[axis] * planner.settings.axis_steps_per_mm[axis]; return full_error_axis - residual_error_axis; } From 785b1da021a952b5566b2df82d0e0b71fe8c9f61 Mon Sep 17 00:00:00 2001 From: Keith Bennett <13375512+thisiskeithb@users.noreply.github.com> Date: Thu, 4 Jul 2024 18:36:17 -0700 Subject: [PATCH 30/41] =?UTF-8?q?=F0=9F=90=9B=20Fix=20YHCB2004=20builds=20?= =?UTF-8?q?(#27210)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: ellensp <530024+ellensp@users.noreply.github.com> --- ini/features.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ini/features.ini b/ini/features.ini index b81c5285bf0b..d60bdcc6cf66 100644 --- a/ini/features.ini +++ b/ini/features.ini @@ -12,7 +12,7 @@ # The order of the features matters for source-filter resolution inside of common-dependencies.py. [features] -YHCB2004 = red-scorp/LiquidCrystal_AIP31068@^1.0.4, red-scorp/SoftSPIB@^1.1.1 +YHCB2004 = LiquidCrystal_AIP31068=https://github.com/ellensp/LiquidCrystal_AIP31068/archive/3fc43b7.zip, red-scorp/SoftSPIB@^1.1.1 HAS_TFT_LVGL_UI = lvgl=https://github.com/makerbase-mks/LVGL-6.1.1-MKS/archive/a3ebe98bc6.zip build_src_filter=+ extra_scripts=download_mks_assets.py From e6a61b182fcc5c7b62facf15dd65346ad06c32e5 Mon Sep 17 00:00:00 2001 From: Keith Bennett <13375512+thisiskeithb@users.noreply.github.com> Date: Thu, 4 Jul 2024 18:37:43 -0700 Subject: [PATCH 31/41] =?UTF-8?q?=F0=9F=90=9B=20Fix=20E3S1PRO=20DGUS=20bui?= =?UTF-8?q?lds=20(#27211)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Partially reverts #26261 --- Marlin/src/lcd/extui/dgus_e3s1pro/DGUSRxHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSRxHandler.cpp b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSRxHandler.cpp index dc80a7aed02b..118cfd35143b 100644 --- a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSRxHandler.cpp +++ b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSRxHandler.cpp @@ -101,7 +101,7 @@ void DGUSRxHandler::retractLength(DGUS_VP &vp, void *data) { void DGUSRxHandler::setLanguage(DGUS_VP &vp, void *data) { DGUS_Data::Language language = (DGUS_Data::Language)Endianness::fromBE_P(data); - ui_language = screen.config.language = language; + screen.config.language = language; screen.triggerEEPROMSave(); screen.triggerFullUpdate(); } From b303bb1e562a9a625ec960172613b48c4ac8de59 Mon Sep 17 00:00:00 2001 From: Keith Bennett <13375512+thisiskeithb@users.noreply.github.com> Date: Thu, 4 Jul 2024 18:57:21 -0700 Subject: [PATCH 32/41] =?UTF-8?q?=F0=9F=94=A7=20English=20as=20default=20o?= =?UTF-8?q?n=20MKS=20H43=20(#27218)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp b/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp index d78364cb3bc1..8e2b1bb8e48a 100644 --- a/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp +++ b/Marlin/src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp @@ -69,7 +69,7 @@ void MKS_reset_settings() { { 20, 20 }, { 20, 20 }, { X_CENTER, Y_CENTER } }; - mks_language_index = MKS_SimpleChinese; + mks_language_index = MKS_English; COPY(mks_corner_offsets, init_dgus_level_offsets); mks_park_pos.set(20, 20, 10); mks_min_extrusion_temp = 0; From 10ffb9cb68b1e21757c17fd3c1958eb740caa260 Mon Sep 17 00:00:00 2001 From: Vovodroid Date: Fri, 5 Jul 2024 05:22:16 +0300 Subject: [PATCH 33/41] =?UTF-8?q?=E2=9C=A8=20FAN=5FKICKSTART=5FLINEAR=20(#?= =?UTF-8?q?27072)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/Configuration_adv.h | 2 ++ Marlin/src/inc/Conditionals_post.h | 2 +- Marlin/src/inc/SanityCheck.h | 8 ++++++-- Marlin/src/module/planner.cpp | 16 ++++++++++------ 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 812310dcfc9e..cf203c447d65 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -604,6 +604,8 @@ */ //#define FAN_KICKSTART_TIME 100 // (ms) //#define FAN_KICKSTART_POWER 180 // 64-255 +//#define FAN_KICKSTART_LINEAR // Set kickstart time linearly based on the speed, e.g., for 20% (51) it will be FAN_KICKSTART_TIME * 0.2. + // Useful for quick speed up to low speed. Kickstart power must be set to 255. // Some coolers may require a non-zero "off" state. //#define FAN_OFF_PWM 1 diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index d1524cf82a12..7af8536d90fe 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -2757,7 +2757,7 @@ // Fan Kickstart #if FAN_KICKSTART_TIME && !defined(FAN_KICKSTART_POWER) - #define FAN_KICKSTART_POWER 180 + #define FAN_KICKSTART_POWER TERN(FAN_KICKSTART_LINEAR, 255, 180) #endif // Servos diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index a8b463c5d82c..7113e9946b47 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -1009,8 +1009,12 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #endif // Fan Kickstart power -#if FAN_KICKSTART_TIME && !WITHIN(FAN_KICKSTART_POWER, 64, 255) - #error "FAN_KICKSTART_POWER must be an integer from 64 to 255." +#if FAN_KICKSTART_TIME + #if ENABLED(FAN_KICKSTART_LINEAR) && FAN_KICKSTART_POWER != 255 + #error "FAN_KICKSTART_LINEAR requires a FAN_KICKSTART_POWER of 255." + #elif !WITHIN(FAN_KICKSTART_POWER, 64, 255) + #error "FAN_KICKSTART_POWER must be an integer from 64 to 255." + #endif #endif /** diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index b4546e0235bf..0e45f55214ed 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -1201,16 +1201,20 @@ void Planner::recalculate(const_float_t safe_exit_speed_sqr) { void Planner::kickstart_fan(uint8_t (&fan_speed)[FAN_COUNT], const millis_t &ms, const uint8_t f) { static millis_t fan_kick_end[FAN_COUNT] = { 0 }; + #if ENABLED(FAN_KICKSTART_LINEAR) + static uint8_t set_fan_speed[FAN_COUNT] = { 0 }; + #endif if (fan_speed[f] > FAN_OFF_PWM) { - if (fan_kick_end[f] == 0) { - fan_kick_end[f] = ms + FAN_KICKSTART_TIME; + const bool first_kick = fan_kick_end[f] == 0 && TERN1(FAN_KICKSTART_LINEAR, fan_speed[f] > set_fan_speed[f]); + if (first_kick) + fan_kick_end[f] = ms + (FAN_KICKSTART_TIME) TERN_(FAN_KICKSTART_LINEAR, * (fan_speed[f] - set_fan_speed[f]) / 255); + if (first_kick || PENDING(ms, fan_kick_end[f])) { fan_speed[f] = FAN_KICKSTART_POWER; + return; } - else if (PENDING(ms, fan_kick_end[f])) - fan_speed[f] = FAN_KICKSTART_POWER; } - else - fan_kick_end[f] = 0; + fan_kick_end[f] = 0; + TERN_(FAN_KICKSTART_LINEAR, set_fan_speed[f] = fan_speed[f]); } #endif From d0e110d6660453bf061c4118212879847eb4294b Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Fri, 5 Jul 2024 06:08:13 +0000 Subject: [PATCH 34/41] [cron] Bump distribution date (2024-07-05) --- 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 9922ba35a5db..ba2c4055649e 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-07-02" +//#define STRING_DISTRIBUTION_DATE "2024-07-05" /** * 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 c06e9ca2aaae..ac94f753b6e9 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-07-02" + #define STRING_DISTRIBUTION_DATE "2024-07-05" #endif /** From 4aff10785ee96a35eb4777c08b81722a59cecf68 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 5 Jul 2024 18:46:38 -0500 Subject: [PATCH 35/41] =?UTF-8?q?=F0=9F=A7=91=E2=80=8D=F0=9F=92=BB=20Use?= =?UTF-8?q?=20"enum=20class"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/MarlinCore.cpp | 14 ++++++------- Marlin/src/MarlinCore.h | 6 +++--- Marlin/src/gcode/control/M999.cpp | 2 +- Marlin/src/lcd/extui/mks_ui/draw_printing.cpp | 4 ++-- Marlin/src/lcd/extui/mks_ui/draw_ui.cpp | 2 +- Marlin/src/lcd/extui/ui_api.cpp | 2 +- Marlin/src/module/motion.cpp | 20 +++++++++---------- Marlin/src/module/motion.h | 10 ++++------ Marlin/src/module/planner.cpp | 4 ++-- Marlin/src/module/temperature.cpp | 4 ++-- Marlin/src/sd/cardreader.cpp | 6 +++--- 11 files changed, 36 insertions(+), 38 deletions(-) diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index be81388f3896..dbfb822015c4 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -263,7 +263,7 @@ PGMSTR(M112_KILL_STR, "M112 Shutdown"); -MarlinState marlin_state = MF_INITIALIZING; +MarlinState marlin_state = MarlinState::MF_INITIALIZING; // For M109 and M190, this flag may be cleared (by M108) to exit the wait loop bool wait_for_heatup = false; @@ -377,8 +377,8 @@ void startOrResumeJob() { } inline void finishSDPrinting() { - if (queue.enqueue_one(F("M1001"))) { // Keep trying until it gets queued - marlin_state = MF_RUNNING; // Signal to stop trying + if (queue.enqueue_one(F("M1001"))) { // Keep trying until it gets queued + marlin_state = MarlinState::MF_RUNNING; // Signal to stop trying TERN_(PASSWORD_AFTER_SD_PRINT_END, password.lock_machine()); TERN_(DGUS_LCD_UI_MKS, screen.sdPrintingFinished()); } @@ -773,7 +773,7 @@ void idle(const bool no_stepper_sleep/*=false*/) { TERN_(MAX7219_DEBUG, max7219.idle_tasks()); // Return if setup() isn't completed - if (marlin_state == MF_INITIALIZING) goto IDLE_DONE; + if (marlin_state == MarlinState::MF_INITIALIZING) goto IDLE_DONE; // TODO: Still causing errors TERN_(TOOL_SENSOR, (void)check_tool_sensor_stats(active_extruder, true)); @@ -959,7 +959,7 @@ void stop() { SERIAL_ERROR_MSG(STR_ERR_STOPPED); LCD_MESSAGE(MSG_STOPPED); safe_delay(350); // allow enough time for messages to get out before stopping - marlin_state = MF_STOPPED; + marlin_state = MarlinState::MF_STOPPED; } } @@ -1646,7 +1646,7 @@ void setup() { SETUP_RUN(ftMotion.init()); #endif - marlin_state = MF_RUNNING; + marlin_state = MarlinState::MF_RUNNING; #ifdef STARTUP_TUNE // Play a short startup tune before continuing. @@ -1678,7 +1678,7 @@ void loop() { #if HAS_MEDIA if (card.flag.abort_sd_printing) abortSDPrinting(); - if (marlin_state == MF_SD_COMPLETE) finishSDPrinting(); + if (marlin_state == MarlinState::MF_SD_COMPLETE) finishSDPrinting(); #endif queue.advance(); diff --git a/Marlin/src/MarlinCore.h b/Marlin/src/MarlinCore.h index e9c63bb31f35..9cf74de2c68f 100644 --- a/Marlin/src/MarlinCore.h +++ b/Marlin/src/MarlinCore.h @@ -42,7 +42,7 @@ void kill(FSTR_P const lcd_error=nullptr, FSTR_P const lcd_component=nullptr, co void minkill(const bool steppers_off=false); // Global State of the firmware -enum MarlinState : uint8_t { +enum class MarlinState : uint8_t { MF_INITIALIZING = 0, MF_STOPPED, MF_KILLED, @@ -53,8 +53,8 @@ enum MarlinState : uint8_t { }; extern MarlinState marlin_state; -inline bool IsRunning() { return marlin_state >= MF_RUNNING; } -inline bool IsStopped() { return marlin_state == MF_STOPPED; } +inline bool IsRunning() { return marlin_state >= MarlinState::MF_RUNNING; } +inline bool IsStopped() { return marlin_state == MarlinState::MF_STOPPED; } bool printingIsActive(); bool printJobOngoing(); diff --git a/Marlin/src/gcode/control/M999.cpp b/Marlin/src/gcode/control/M999.cpp index b7d6db9f2312..b4278fccad27 100644 --- a/Marlin/src/gcode/control/M999.cpp +++ b/Marlin/src/gcode/control/M999.cpp @@ -36,7 +36,7 @@ * existing command buffer. */ void GcodeSuite::M999() { - marlin_state = MF_RUNNING; + marlin_state = MarlinState::MF_RUNNING; ui.reset_alert_level(); if (parser.boolval('S')) return; diff --git a/Marlin/src/lcd/extui/mks_ui/draw_printing.cpp b/Marlin/src/lcd/extui/mks_ui/draw_printing.cpp index 345c5dd732c0..ee913d646548 100644 --- a/Marlin/src/lcd/extui/mks_ui/draw_printing.cpp +++ b/Marlin/src/lcd/extui/mks_ui/draw_printing.cpp @@ -294,7 +294,7 @@ void setProBarRate() { lv_label_set_text(bar1ValueText, public_buf_l); lv_obj_align(bar1ValueText, bar1, LV_ALIGN_CENTER, 0, 0); - if (marlin_state == MF_SD_COMPLETE) { + if (marlin_state == MarlinState::MF_SD_COMPLETE) { if (once_flag == 0) { stop_print_time(); @@ -309,7 +309,7 @@ void setProBarRate() { if (gCfgItems.finish_power_off) { gcode.process_subcommands_now(F("M1001")); queue.inject(F("M81")); - marlin_state = MF_RUNNING; + marlin_state = MarlinState::MF_RUNNING; } #endif } diff --git a/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp b/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp index 7408197f73fe..bd06e6c1f482 100644 --- a/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp +++ b/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp @@ -766,7 +766,7 @@ void GUI_RefreshPage() { disp_print_time(); disp_fan_Zpos(); } - if (printing_rate_update_flag || marlin_state == MF_SD_COMPLETE) { + if (printing_rate_update_flag || marlin_state == MarlinState::MF_SD_COMPLETE) { printing_rate_update_flag = false; if (!gcode_preview_over) setProBarRate(); } diff --git a/Marlin/src/lcd/extui/ui_api.cpp b/Marlin/src/lcd/extui/ui_api.cpp index 1fcfabdd7257..d89a09d8ada2 100644 --- a/Marlin/src/lcd/extui/ui_api.cpp +++ b/Marlin/src/lcd/extui/ui_api.cpp @@ -1219,7 +1219,7 @@ namespace ExtUI { void onSurviveInKilled() { thermalManager.disable_all_heaters(); flags.printer_killed = 0; - marlin_state = MF_RUNNING; + marlin_state = MarlinState::MF_RUNNING; //SERIAL_ECHOLNPGM("survived at: ", millis()); } diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index 473d54cc382b..4bbb182bc345 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -257,7 +257,7 @@ void report_current_position_projected() { AutoReporter position_auto_reporter; #endif -#if ANY(FULL_REPORT_TO_HOST_FEATURE, REALTIME_REPORTING_COMMANDS) +#if ENABLED(REALTIME_REPORTING_COMMANDS) M_StateEnum M_State_grbl = M_INIT; @@ -299,18 +299,18 @@ void report_current_position_projected() { */ M_StateEnum grbl_state_for_marlin_state() { switch (marlin_state) { - case MF_INITIALIZING: return M_INIT; - case MF_SD_COMPLETE: return M_ALARM; - case MF_WAITING: return M_IDLE; - case MF_STOPPED: return M_END; - case MF_RUNNING: return M_RUNNING; - case MF_PAUSED: return M_HOLD; - case MF_KILLED: return M_ERROR; - default: return M_IDLE; + case MarlinState::MF_INITIALIZING: return M_INIT; + case MarlinState::MF_SD_COMPLETE: return M_ALARM; + case MarlinState::MF_WAITING: return M_IDLE; + case MarlinState::MF_STOPPED: return M_END; + case MarlinState::MF_RUNNING: return M_RUNNING; + case MarlinState::MF_PAUSED: return M_HOLD; + case MarlinState::MF_KILLED: return M_ERROR; + default: return M_IDLE; } } -#endif +#endif // REALTIME_REPORTING_COMMANDS #if IS_KINEMATIC diff --git a/Marlin/src/module/motion.h b/Marlin/src/module/motion.h index f9748871f5c8..bb8f36446b0c 100644 --- a/Marlin/src/module/motion.h +++ b/Marlin/src/module/motion.h @@ -272,7 +272,7 @@ void report_current_position_projected(); extern AutoReporter position_auto_reporter; #endif -#if ANY(FULL_REPORT_TO_HOST_FEATURE, REALTIME_REPORTING_COMMANDS) +#if ENABLED(REALTIME_REPORTING_COMMANDS) #define HAS_GRBL_STATE 1 /** * Machine states for GRBL or TinyG @@ -305,11 +305,9 @@ void report_current_position_projected(); } #endif - #if ENABLED(REALTIME_REPORTING_COMMANDS) - void quickpause_stepper(); - void quickresume_stepper(); - #endif -#endif + void quickpause_stepper(); + void quickresume_stepper(); +#endif // REALTIME_REPORTING_COMMANDS float get_move_distance(const xyze_pos_t &diff OPTARG(HAS_ROTATIONAL_AXES, bool &is_cartesian_move)); diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index 0e45f55214ed..892258ff3b36 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -799,8 +799,8 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t // 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)); + NOLESS(initial_rate, uint32_t(MINIMAL_STEP_RATE)); + 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); diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index 16b43f62f098..1b8ebeea6964 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -1430,7 +1430,7 @@ int16_t Temperature::getHeaterPower(const heater_id_t heater_id) { // inline void loud_kill(FSTR_P const lcd_msg, const heater_id_t heater_id) { - marlin_state = MF_KILLED; + marlin_state = MarlinState::MF_KILLED; thermalManager.disable_all_heaters(); #if HAS_BEEPER for (uint8_t i = 20; i--;) { @@ -2077,7 +2077,7 @@ void Temperature::mintemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_T * - Update the heated bed PID output value */ void Temperature::task() { - if (marlin_state == MF_INITIALIZING) return hal.watchdog_refresh(); // If Marlin isn't started, at least reset the watchdog! + if (marlin_state == MarlinState::MF_INITIALIZING) return hal.watchdog_refresh(); // If Marlin isn't started, at least reset the watchdog! static bool no_reentry = false; // Prevent recursion if (no_reentry) return; diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index 14319940931b..c13ba37a96ef 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -497,7 +497,7 @@ void CardReader::mount() { cdroot(); else { #if ANY(HAS_SD_DETECT, USB_FLASH_DRIVE_SUPPORT) - if (marlin_state != MF_INITIALIZING) LCD_ALERTMESSAGE(MSG_MEDIA_INIT_FAIL); + if (marlin_state != MarlinState::MF_INITIALIZING) LCD_ALERTMESSAGE(MSG_MEDIA_INIT_FAIL); #endif } @@ -1412,8 +1412,8 @@ void CardReader::fileHasFinished() { endFilePrintNow(TERN_(SD_RESORT, true)); - flag.sdprintdone = true; // Stop getting bytes from the SD card - marlin_state = MF_SD_COMPLETE; // Tell Marlin to enqueue M1001 soon + flag.sdprintdone = true; // Stop getting bytes from the SD card + marlin_state = MarlinState::MF_SD_COMPLETE; // Tell Marlin to enqueue M1001 soon } #if ENABLED(AUTO_REPORT_SD_STATUS) From e0dcc610da359d180d6b820d0d6ebea52ea522b4 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Sat, 6 Jul 2024 00:22:12 +0000 Subject: [PATCH 36/41] [cron] Bump distribution date (2024-07-06) --- 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 ba2c4055649e..db4d215b18cd 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-07-05" +//#define STRING_DISTRIBUTION_DATE "2024-07-06" /** * 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 ac94f753b6e9..6e4c9d5b570c 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-07-05" + #define STRING_DISTRIBUTION_DATE "2024-07-06" #endif /** From 4af5229cee2a2bb49ae53d76fbc145fc69d802c6 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 5 Jul 2024 20:08:07 -0500 Subject: [PATCH 37/41] =?UTF-8?q?=F0=9F=A7=91=E2=80=8D=F0=9F=92=BB=20Condi?= =?UTF-8?q?tional=20HAS=5FLED=5FPOWEROFF=5FTIMEOUT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/feature/leds/leds.cpp | 2 +- Marlin/src/feature/leds/leds.h | 4 ++-- Marlin/src/inc/Conditionals_LCD.h | 4 ++++ Marlin/src/lcd/marlinui.cpp | 24 ++++++++---------------- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/Marlin/src/feature/leds/leds.cpp b/Marlin/src/feature/leds/leds.cpp index ac7f1815162b..8810c518cf70 100644 --- a/Marlin/src/feature/leds/leds.cpp +++ b/Marlin/src/feature/leds/leds.cpp @@ -239,7 +239,7 @@ void LEDLights::set_color(const LEDColor &incol void LEDLights::toggle() { if (lights_on) set_off(); else update(); } #endif -#if LED_POWEROFF_TIMEOUT > 0 +#if HAS_LED_POWEROFF_TIMEOUT millis_t LEDLights::led_off_time; // = 0 diff --git a/Marlin/src/feature/leds/leds.h b/Marlin/src/feature/leds/leds.h index 7a31ca685d49..da8ba42fba1a 100644 --- a/Marlin/src/feature/leds/leds.h +++ b/Marlin/src/feature/leds/leds.h @@ -164,11 +164,11 @@ class LEDLights { #if ENABLED(LED_CONTROL_MENU) static void toggle(); // swap "off" with color #endif - #if ANY(LED_CONTROL_MENU, CASE_LIGHT_USE_RGB_LED) || LED_POWEROFF_TIMEOUT > 0 + #if ANY(LED_CONTROL_MENU, CASE_LIGHT_USE_RGB_LED, HAS_LED_POWEROFF_TIMEOUT) static void update() { set_color(color); } #endif - #if LED_POWEROFF_TIMEOUT > 0 + #if HAS_LED_POWEROFF_TIMEOUT private: static millis_t led_off_time; public: diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index f664e84691d0..ab5fd9e55cbd 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -1898,6 +1898,10 @@ #define NEOPIXEL_BKGD_INDEX_LAST NEOPIXEL_BKGD_INDEX_FIRST #endif +#if LED_POWEROFF_TIMEOUT > 0 + #define HAS_LED_POWEROFF_TIMEOUT 1 +#endif + #if ALL(SPI_FLASH, HAS_MEDIA, MARLIN_DEV_MODE) #define SPI_FLASH_BACKUP 1 #endif diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index a967d921359f..bf5c43d98f9c 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -25,7 +25,7 @@ #include "../MarlinCore.h" // for printingIsPaused #include "../gcode/parser.h" // for axis_is_rotational, using_inch_units -#if LED_POWEROFF_TIMEOUT > 0 || ALL(HAS_WIRED_LCD, PRINTER_EVENT_LEDS) || (HAS_BACKLIGHT_TIMEOUT && defined(NEOPIXEL_BKGD_INDEX_FIRST)) +#if HAS_LED_POWEROFF_TIMEOUT || ALL(HAS_WIRED_LCD, PRINTER_EVENT_LEDS) || (HAS_BACKLIGHT_TIMEOUT && defined(NEOPIXEL_BKGD_INDEX_FIRST)) #include "../feature/leds/leds.h" #endif @@ -319,7 +319,7 @@ void MarlinUI::init() { #include "../feature/power_monitor.h" #endif - #if LED_POWEROFF_TIMEOUT > 0 + #if HAS_LED_POWEROFF_TIMEOUT #include "../feature/power.h" #endif @@ -943,9 +943,7 @@ void MarlinUI::init() { static uint16_t max_display_update_time = 0; const millis_t ms = millis(); - #if LED_POWEROFF_TIMEOUT > 0 - leds.update_timeout(powerManager.psu_on); - #endif + TERN_(HAS_LED_POWEROFF_TIMEOUT, leds.update_timeout(powerManager.psu_on)); #if HAS_MARLINUI_MENU @@ -1085,10 +1083,8 @@ void MarlinUI::init() { refresh(LCDVIEW_REDRAW_NOW); - #if LED_POWEROFF_TIMEOUT > 0 - if (!powerManager.psu_on) leds.reset_timeout(ms); - #endif - } // encoder activity + TERN_(HAS_LED_POWEROFF_TIMEOUT, if (!powerManager.psu_on) leds.reset_timeout(ms)); + } // encoder or click #endif // HAS_ENCODER_ACTION @@ -1863,14 +1859,10 @@ void MarlinUI::host_notify(const char * const cstr) { refresh(); - #if HAS_WIRED_LCD || LED_POWEROFF_TIMEOUT > 0 + #if HAS_WIRED_LCD || HAS_LED_POWEROFF_TIMEOUT const millis_t ms = millis(); - #endif - - TERN_(HAS_WIRED_LCD, next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL); // Delay LCD update for SD activity - - #if LED_POWEROFF_TIMEOUT > 0 - leds.reset_timeout(ms); + TERN_(HAS_WIRED_LCD, next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL); // Delay LCD update for SD activity + TERN_(HAS_LED_POWEROFF_TIMEOUT, leds.reset_timeout(ms)); #endif } From 571783fc04314b0cac57948d343690fc1ea10a06 Mon Sep 17 00:00:00 2001 From: David Buezas Date: Sat, 6 Jul 2024 23:41:02 +0100 Subject: [PATCH 38/41] =?UTF-8?q?=F0=9F=9A=B8=20SD=20card=20wake=20on=20in?= =?UTF-8?q?sert,=20status=20screen=20on=20remove=20(#27197)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Scott Lahteine --- Marlin/src/lcd/dogm/marlinui_DOGM.cpp | 2 +- Marlin/src/lcd/marlinui.cpp | 15 ++++++++------- Marlin/src/lcd/marlinui.h | 5 +++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp index eed2bf22751a..5e5267c95a40 100644 --- a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp +++ b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp @@ -392,7 +392,7 @@ void MarlinUI::clear_for_drawing() { #if HAS_DISPLAY_SLEEP void MarlinUI::sleep_display(const bool sleep/*=true*/) { static bool asleep = false; - if (asleep != sleep){ + if (asleep != sleep) { sleep ? u8g.sleepOn() : u8g.sleepOff(); asleep = sleep; } diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index bf5c43d98f9c..8b24cd26eb46 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -1824,13 +1824,14 @@ void MarlinUI::host_notify(const char * const cstr) { #endif void MarlinUI::media_changed(const uint8_t old_status, const uint8_t status) { + TERN_(HAS_DISPLAY_SLEEP, refresh_screen_timeout()); if (old_status == status) { TERN_(EXTENSIBLE_UI, ExtUI::onMediaError()); // Failed to mount/unmount return; } - if (status) { - if (old_status < 2) { + if (old_status < 2) { // Skip this section on first boot check + if (status) { // Media Mounted #if ENABLED(EXTENSIBLE_UI) ExtUI::onMediaMounted(); #elif ENABLED(BROWSE_MEDIA_ON_INSERT) @@ -1841,16 +1842,16 @@ void MarlinUI::host_notify(const char * const cstr) { LCD_MESSAGE(MSG_MEDIA_INSERTED); #endif } - } - else { - if (old_status < 2) { + else { // Media Removed #if ENABLED(EXTENSIBLE_UI) ExtUI::onMediaRemoved(); - #elif HAS_SD_DETECT + #elif HAS_SD_DETECT // Q: Does "Media Removed" need to be shown for manual release too? LCD_MESSAGE(MSG_MEDIA_REMOVED); #if HAS_MARLINUI_MENU - if (!defer_return_to_status) return_to_status(); + if (ENABLED(HAS_WIRED_LCD) || !defer_return_to_status) return_to_status(); #endif + #elif HAS_WIRED_LCD + return_to_status(); #endif } } diff --git a/Marlin/src/lcd/marlinui.h b/Marlin/src/lcd/marlinui.h index cc130327a96b..14bf42700f2c 100644 --- a/Marlin/src/lcd/marlinui.h +++ b/Marlin/src/lcd/marlinui.h @@ -304,6 +304,7 @@ class MarlinUI { static void refresh_screen_timeout(); #endif + // Sleep or wake the display (e.g., by turning the backlight off/on). static void sleep_display(const bool=true) IF_DISABLED(HAS_DISPLAY_SLEEP, {}); static void wake_display() { sleep_display(false); } @@ -743,7 +744,7 @@ class MarlinUI { static void draw_select_screen_prompt(FSTR_P const fpre, const char * const string=nullptr, FSTR_P const fsuf=nullptr); - #else + #else // !HAS_MARLINUI_MENU static void return_to_status() {} @@ -753,7 +754,7 @@ class MarlinUI { FORCE_INLINE static void run_current_screen() { status_screen(); } #endif - #endif + #endif // !HAS_MARLINUI_MENU #if ANY(HAS_MARLINUI_MENU, EXTENSIBLE_UI) static bool lcd_clicked; From 586313c2fb57020609605c0981baa21141e333a6 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Sun, 7 Jul 2024 00:25:40 +0000 Subject: [PATCH 39/41] [cron] Bump distribution date (2024-07-07) --- 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 db4d215b18cd..0cf58aea3edc 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-07-06" +//#define STRING_DISTRIBUTION_DATE "2024-07-07" /** * 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 6e4c9d5b570c..e033a908c46c 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-07-06" + #define STRING_DISTRIBUTION_DATE "2024-07-07" #endif /** From 9ebfdc4a869726742dfa322fd8089378d02298c9 Mon Sep 17 00:00:00 2001 From: Roxy-3D Date: Mon, 8 Jul 2024 10:35:41 -0500 Subject: [PATCH 40/41] Update README.md with hotlink to all supported boards --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b11a1193b976..77a23eaf2f70 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ Every new HAL opens up a world of hardware. At this time we need HALs for RP2040 [Teensy 4.0](https://www.pjrc.com/store/teensy40.html)|ARMĀ® Cortex-M7| [Teensy 4.1](https://www.pjrc.com/store/teensy41.html)|ARMĀ® Cortex-M7| Linux Native|x86/ARM/etc.|Raspberry Pi + [All supported boards](https://marlinfw.org/docs/hardware/boards.html#boards-list)|All platforms|All boards ## Marlin Support From 7c1f82cd9624fb61658f9329d492cbb29827777d Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Mon, 8 Jul 2024 18:06:51 +0000 Subject: [PATCH 41/41] [cron] Bump distribution date (2024-07-08) --- 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 0cf58aea3edc..d77c5cdafa56 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-07-07" +//#define STRING_DISTRIBUTION_DATE "2024-07-08" /** * 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 e033a908c46c..45df5eee0b7a 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-07-07" + #define STRING_DISTRIBUTION_DATE "2024-07-08" #endif /**