From d5977e7e2dffdb85846ca47f2e57766f9254785b Mon Sep 17 00:00:00 2001 From: ellensp <530024+ellensp@users.noreply.github.com> Date: Wed, 22 Oct 2025 18:41:38 +1300 Subject: [PATCH 01/11] =?UTF-8?q?=F0=9F=94=A7=20Separate=20Teensy=204.0=20?= =?UTF-8?q?/=204.1=20(#28122)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Scott Lahteine --- Marlin/src/core/boards.h | 9 +- Marlin/src/pins/pins.h | 4 +- Marlin/src/pins/teensy4/env_validate.h | 4 +- Marlin/src/pins/teensy4/pins_TEENSY40.h | 34 +++++++ Marlin/src/pins/teensy4/pins_TEENSY41.h | 100 ++----------------- Marlin/src/pins/teensy4/pins_TEENSY4x.h | 127 ++++++++++++++++++++++++ ini/teensy.ini | 12 ++- 7 files changed, 189 insertions(+), 101 deletions(-) create mode 100644 Marlin/src/pins/teensy4/pins_TEENSY40.h create mode 100644 Marlin/src/pins/teensy4/pins_TEENSY4x.h diff --git a/Marlin/src/core/boards.h b/Marlin/src/core/boards.h index 1b95b2ba52..7cc9760e49 100644 --- a/Marlin/src/core/boards.h +++ b/Marlin/src/core/boards.h @@ -513,10 +513,11 @@ #define BOARD_BTT_OCTOPUS_PRO_V1_1 6008 // BigTreeTech Octopus Pro v1.1 (STM32H723ZE) #define BOARD_BTT_MANTA_M8P_V2_0 6009 // BigTreeTech Manta M8P V2.0 (STM32H723ZE) #define BOARD_BTT_KRAKEN_V1_0 6010 // BigTreeTech Kraken v1.0 (STM32H723ZG) -#define BOARD_TEENSY41 6011 // Teensy 4.1 -#define BOARD_T41U5XBB 6012 // T41U5XBB Teensy 4.1 breakout board -#define BOARD_FLY_D8_PRO 6013 // FLY_D8_PRO (STM32H723VG) -#define BOARD_FLY_SUPER8_PRO 6014 // FLY SUPER8 PRO (STM32H723ZG) +#define BOARD_TEENSY40 6011 // Teensy 4.0 +#define BOARD_TEENSY41 6012 // Teensy 4.1 +#define BOARD_T41U5XBB 6013 // T41U5XBB Teensy 4.1 breakout board +#define BOARD_FLY_D8_PRO 6014 // FLY_D8_PRO (STM32H723VG) +#define BOARD_FLY_SUPER8_PRO 6015 // FLY SUPER8 PRO (STM32H723ZG) // // Espressif ESP32 WiFi diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h index ecf15758e0..abe4673407 100644 --- a/Marlin/src/pins/pins.h +++ b/Marlin/src/pins/pins.h @@ -854,8 +854,10 @@ #include "stm32h7/pins_BTT_MANTA_M8P_V2_0.h" // STM32H7 env:STM32H723ZE_btt #elif MB(BTT_KRAKEN_V1_0) #include "stm32h7/pins_BTT_KRAKEN_V1_0.h" // STM32H7 env:STM32H723ZG_btt +#elif MB(TEENSY40) + #include "teensy4/pins_TEENSY40.h" // Teensy-4.0 env:teensy40 #elif MB(TEENSY41) - #include "teensy4/pins_TEENSY41.h" // Teensy-4.x env:teensy41 + #include "teensy4/pins_TEENSY41.h" // Teensy-4.1 env:teensy41 #elif MB(T41U5XBB) #include "teensy4/pins_T41U5XBB.h" // Teensy-4.x env:teensy41 #elif MB(FLY_D8_PRO) diff --git a/Marlin/src/pins/teensy4/env_validate.h b/Marlin/src/pins/teensy4/env_validate.h index 5a89e8a409..38b94a636d 100644 --- a/Marlin/src/pins/teensy4/env_validate.h +++ b/Marlin/src/pins/teensy4/env_validate.h @@ -21,6 +21,8 @@ */ #pragma once -#if NOT_TARGET(IS_TEENSY41) +#if defined(IS_TEENSY40) && NOT_TARGET(IS_TEENSY40) + #error "Oops! Select 'Teensy 4.0' in 'Tools > Board.'" +#elif defined(IS_TEENSY41) && NOT_TARGET(IS_TEENSY41) #error "Oops! Select 'Teensy 4.1' in 'Tools > Board.'" #endif diff --git a/Marlin/src/pins/teensy4/pins_TEENSY40.h b/Marlin/src/pins/teensy4/pins_TEENSY40.h new file mode 100644 index 0000000000..88c8ccf97e --- /dev/null +++ b/Marlin/src/pins/teensy4/pins_TEENSY40.h @@ -0,0 +1,34 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2025 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 . + * + */ +#pragma once + +/**************************************************************************************** +* Teensy 4.0 (IMXRT1062) Breadboard pin assignments +* Requires the Teensyduino software with Teensy 4.0 selected in Arduino IDE! +* https://www.pjrc.com/teensy/teensyduino.html +****************************************************************************************/ + +#include "env_validate.h" + +#define BOARD_INFO_NAME "Teensy4.0" + +#include "pins_TEENSY4x.h" diff --git a/Marlin/src/pins/teensy4/pins_TEENSY41.h b/Marlin/src/pins/teensy4/pins_TEENSY41.h index 2a8a76f17c..121514e463 100644 --- a/Marlin/src/pins/teensy4/pins_TEENSY41.h +++ b/Marlin/src/pins/teensy4/pins_TEENSY41.h @@ -31,99 +31,11 @@ #define BOARD_INFO_NAME "Teensy4.1" -/** - * Plan for Teensy 4.0 and Teensy 4.1: - * USB - * GND |-----#####-----| VIN (3.65 TO 5.5V) - * X_STEP_PIN CS1 RX1 PWM 0 | ##### | GND - * X_DIR_PIN MISO1 TX1 PWM 1 | | 3.3V - * Y_STEP_PIN PWM 2 | | 23 A9 PWM SERVO1_PIN - * Y_DIR_PIN PWM 3 | | 22 A8 PWM SERVO0_PIN - * Z_STEP_PIN PWM 4 | | 21 A7 RX5 - * Z_DIR_PIN PWM 5 | | 20 A6 TX5 FILWIDTH_PIN - * X_ENABLE_PIN PWM 6 | | 19 A5 PWM SCL0 - * Y_ENABLE_PIN RX2 PWM 7 | | 18 A4 PWM SDA0 HEATER_1_PIN - * Z_ENABLE_PIN TX2 PWM 8 | | 17 A3 RX4 SDA1 - * E0_STEP_PIN PWM 9 | | 16 A2 TX4 SCL1 TEMP_0_PIN - * E0_DIR_PIN PWM 10 | | 15 A1 PWM RX3 TEMP_BED_PIN - * MOSI_PIN MOSI0 PWM 11 | | 14 A0 PWM TX3 TEMP_1_PIN - * MISO_PIN MISO0 PWM 12 | | 13 LED PWM SCK0 SCK_PIN - * 3.3V | | GND - * Z_STOP_PIN PWM 24 | | 41 A17 - * E0_ENABLE_PIN PWM 25 | | 40 A16 - * FAN0_PIN MOSI1 26 | | 39 A15 MISO1 X_STOP_PIN - * Z-PROBE PWR SCK1 27 | * * * * * | 38 A14 Y_STOP_PIN - * SOL1_PIN RX7 PWM 28 | | 37 PWM HEATER_0_PIN - * FAN0_PIN TX7 PWM 29 | | 36 PWM HEATER_BED_PIN - * X_CS_PIN 30 | | 35 TX8 E1_ENABLE_PIN - * y_CS_PIN 31 | SDCARD | 34 RX8 E1_DIR_PIN - * Z_CS_PIN 32 |_______________| 33 PWM E1_STEP_PIN - */ +#include "pins_TEENSY4x.h" -// -// Servos -// -#define SERVO0_PIN 22 -#define SERVO1_PIN 23 - -// -// Limit Switches -// -#define X_STOP_PIN 39 -#define Y_STOP_PIN 38 -#define Z_STOP_PIN 24 - -// -// Steppers -// -#define X_STEP_PIN 0 -#define X_DIR_PIN 1 -#define X_ENABLE_PIN 6 -//#define X_CS_PIN 30 - -#define Y_STEP_PIN 2 -#define Y_DIR_PIN 3 -#define Y_ENABLE_PIN 7 -//#define Y_CS_PIN 31 - -#define Z_STEP_PIN 4 -#define Z_DIR_PIN 5 -#define Z_ENABLE_PIN 8 -//#define Z_CS_PIN 32 - -#define E0_STEP_PIN 9 -#define E0_DIR_PIN 10 -#define E0_ENABLE_PIN 25 - -#define E1_STEP_PIN 33 -#define E1_DIR_PIN 34 -#define E1_ENABLE_PIN 35 - -// -// Heaters / Fans -// -#define HEATER_0_PIN 37 -#define HEATER_1_PIN 18 -#define HEATER_BED_PIN 36 -#ifndef FAN0_PIN - #define FAN0_PIN 29 -#endif - -// -// Temperature Sensors -// -#define TEMP_0_PIN 2 // Extruder / Analog pin numbering: 2 => A2 -#define TEMP_1_PIN 0 -#define TEMP_BED_PIN 1 // Bed / Analog pin numbering - -// -// Misc. Functions -// -#define LED_PIN 13 -#define SOL0_PIN 28 -//#define PS_ON_PIN 1 -//#define FILWIDTH_PIN 6 // A6 - -#ifndef SDCARD_CONNECTION - #define SDCARD_CONNECTION ONBOARD +// For the Ethernet Kit or WIZ812 +// https://www.pjrc.com/store/ethernet_kit.html +// https://www.pjrc.com/teensy/td_libs_Ethernet.html) +#if HAS_ETHERNET + #define ETHERNET_CS_PIN 10 // W5x00 module #endif diff --git a/Marlin/src/pins/teensy4/pins_TEENSY4x.h b/Marlin/src/pins/teensy4/pins_TEENSY4x.h new file mode 100644 index 0000000000..251f7533b3 --- /dev/null +++ b/Marlin/src/pins/teensy4/pins_TEENSY4x.h @@ -0,0 +1,127 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2025 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 . + * + */ +#pragma once + +/**************************************************************************************** +* Teensy 4.x (IMXRT1062) Breadboard pin assignments +* Requires the Teensyduino software with Teensy 4.0 / 4.1 selected in Arduino IDE! +* https://www.pjrc.com/teensy/teensyduino.html +****************************************************************************************/ + +#include "env_validate.h" + +/** + * Plan for Teensy 4.0 and Teensy 4.1: + * USB + * GND |-----#####-----| VIN (3.65 TO 5.5V) + * X_STEP_PIN CS1 RX1 PWM 0 | ##### | GND + * X_DIR_PIN MISO1 TX1 PWM 1 | | 3.3V + * Y_STEP_PIN PWM 2 | | 23 A9 PWM SERVO1_PIN + * Y_DIR_PIN PWM 3 | | 22 A8 PWM SERVO0_PIN + * Z_STEP_PIN PWM 4 | | 21 A7 RX5 + * Z_DIR_PIN PWM 5 | | 20 A6 TX5 FILWIDTH_PIN + * X_ENABLE_PIN PWM 6 | | 19 A5 PWM SCL0 + * Y_ENABLE_PIN RX2 PWM 7 | | 18 A4 PWM SDA0 HEATER_1_PIN + * Z_ENABLE_PIN TX2 PWM 8 | | 17 A3 RX4 SDA1 + * E0_STEP_PIN PWM 9 | | 16 A2 TX4 SCL1 TEMP_0_PIN + * E0_DIR_PIN PWM 10 | | 15 A1 PWM RX3 TEMP_BED_PIN + * MOSI_PIN MOSI0 PWM 11 | | 14 A0 PWM TX3 TEMP_1_PIN + * MISO_PIN MISO0 PWM 12 | | 13 LED PWM SCK0 SCK_PIN + * 3.3V | | GND + * Z_STOP_PIN PWM 24 | | 41 A17 + * E0_ENABLE_PIN PWM 25 | | 40 A16 + * FAN0_PIN MOSI1 26 | | 39 A15 MISO1 X_STOP_PIN + * Z-PROBE PWR SCK1 27 | * * * * * | 38 A14 Y_STOP_PIN + * SOL1_PIN RX7 PWM 28 | | 37 PWM HEATER_0_PIN + * FAN0_PIN TX7 PWM 29 | | 36 PWM HEATER_BED_PIN + * X_CS_PIN 30 | | 35 TX8 E1_ENABLE_PIN + * y_CS_PIN 31 | SDCARD | 34 RX8 E1_DIR_PIN + * Z_CS_PIN 32 |_______________| 33 PWM E1_STEP_PIN + */ + +// +// Servos +// +#define SERVO0_PIN 22 +#define SERVO1_PIN 23 + +// +// Limit Switches +// +#define X_STOP_PIN 39 +#define Y_STOP_PIN 38 +#define Z_STOP_PIN 24 + +// +// Steppers +// +#define X_STEP_PIN 0 +#define X_DIR_PIN 1 +#define X_ENABLE_PIN 6 +//#define X_CS_PIN 30 + +#define Y_STEP_PIN 2 +#define Y_DIR_PIN 3 +#define Y_ENABLE_PIN 7 +//#define Y_CS_PIN 31 + +#define Z_STEP_PIN 4 +#define Z_DIR_PIN 5 +#define Z_ENABLE_PIN 8 +//#define Z_CS_PIN 32 + +#define E0_STEP_PIN 9 +#define E0_DIR_PIN 10 +#define E0_ENABLE_PIN 25 + +#define E1_STEP_PIN 33 +#define E1_DIR_PIN 34 +#define E1_ENABLE_PIN 35 + +// +// Heaters / Fans +// +#define HEATER_0_PIN 37 +#define HEATER_1_PIN 18 +#define HEATER_BED_PIN 36 +#ifndef FAN0_PIN + #define FAN0_PIN 29 +#endif + +// +// Temperature Sensors +// +#define TEMP_0_PIN 2 // Extruder / Analog pin numbering: 2 => A2 +#define TEMP_1_PIN 0 +#define TEMP_BED_PIN 1 // Bed / Analog pin numbering + +// +// Misc. Functions +// +#define LED_PIN 13 +#define SOL0_PIN 28 +//#define PS_ON_PIN 1 +//#define FILWIDTH_PIN 6 // A6 + +#ifndef SDCARD_CONNECTION + #define SDCARD_CONNECTION ONBOARD +#endif diff --git a/ini/teensy.ini b/ini/teensy.ini index dac4b40c30..3e988b8d7c 100644 --- a/ini/teensy.ini +++ b/ini/teensy.ini @@ -71,10 +71,20 @@ board = teensy36 build_src_filter = ${teensy_arm.build_src_filter} + # -# Teensy 4.0 / 4.1 (ARM Cortex-M7) +# Teensy 4.0 (ARM Cortex-M7) +# +[env:teensy40] +extends = teensy_arm +board = teensy40 +build_src_filter = ${teensy_arm.build_src_filter} + +build_flags = -DIS_TEENSY40 + +# +# Teensy 4.1 (ARM Cortex-M7) # [env:teensy41] extends = teensy_arm board = teensy41 build_src_filter = ${teensy_arm.build_src_filter} + +build_flags = -DIS_TEENSY41 lib_ignore = From 1b307f7c998ba3ed7d27305ee65b1fbeca1a6a62 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Wed, 22 Oct 2025 06:34:59 +0000 Subject: [PATCH 02/11] [cron] Bump distribution date (2025-10-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 0b2327bf76..8252690420 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 "2025-10-21" +//#define STRING_DISTRIBUTION_DATE "2025-10-22" /** * The protocol for communication to the host. Protocol indicates communication diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index ec39ffec56..28b051217e 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 "2025-10-21" + #define STRING_DISTRIBUTION_DATE "2025-10-22" #endif /** From 898dd1917587bf8a1aa84d5bd5b38dc2bc1a10f8 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Wed, 22 Oct 2025 14:07:56 -0500 Subject: [PATCH 03/11] =?UTF-8?q?=F0=9F=94=A7=20Update=20config.ini?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/config.ini | 54 ++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/Marlin/config.ini b/Marlin/config.ini index d6d2395e39..fd2b81062a 100644 --- a/Marlin/config.ini +++ b/Marlin/config.ini @@ -86,13 +86,14 @@ heater_0_maxtemp = 275 pidtemp = on pid_k1 = 0.95 pid_max = 255 -pid_functional_range = 10 +pid_functional_range = 20 default_kp = 22.20 default_ki = 1.08 default_kd = 114.00 temp_sensor_bed = 1 +bed_check_interval = 5000 bed_mintemp = 5 bed_maxtemp = 150 @@ -163,18 +164,28 @@ min_steps_per_segment = 6 default_minsegmenttime = 20000 [config:basic] +hotend_overshoot = 15 bed_overshoot = 10 +max_bed_power = 255 + busy_while_heating = on +host_keepalive_feature = on default_keepalive_interval = 2 +printjob_timer_autostart = on + +jd_handle_small_segments = on +validate_homing_endstops = on +editable_steps_per_unit = on + eeprom_boot_silent = on eeprom_chitchat = on + endstoppullups = on -extrude_maxlength = 200 + +prevent_cold_extrusion = on extrude_mintemp = 170 -host_keepalive_feature = on -hotend_overshoot = 15 -jd_handle_small_segments = on -max_bed_power = 255 +prevent_lengthy_extrude = on +extrude_maxlength = 200 min_software_endstops = on max_software_endstops = on @@ -195,21 +206,19 @@ preheat_2_temp_hotend = 240 preheat_2_temp_bed = 110 preheat_2_fan_speed = 0 -prevent_cold_extrusion = on -prevent_lengthy_extrude = on -printjob_timer_autostart = on - temp_bed_hysteresis = 3 temp_bed_residency_time = 10 temp_bed_window = 1 temp_residency_time = 10 temp_window = 1 -validate_homing_endstops = on - -editable_steps_per_unit = on [config:advanced] arc_support = on +min_arc_segment_mm = 0.1 +max_arc_segment_mm = 1.0 +min_circle_segments = 72 +n_arc_correction = 25 + auto_report_temperatures = on autotemp = on @@ -223,22 +232,23 @@ disable_idle_x = on disable_idle_y = on disable_idle_z = on disable_idle_e = on + e0_auto_fan_pin = -1 + faster_gcode_parser = on debug_flags_gcode = on + homing_bump_mm = { 5, 5, 2 } -max_arc_segment_mm = 1.0 -min_arc_segment_mm = 0.1 -min_circle_segments = 72 -n_arc_correction = 25 -serial_overrun_protection = on + slowdown = on slowdown_divisor = 2 -tx_buffer_size = 0 +multistepping_limit = 16 -bed_check_interval = 5000 -watch_bed_temp_increase = 2 -watch_bed_temp_period = 60 +serial_overrun_protection = on +tx_buffer_size = 0 watch_temp_increase = 2 watch_temp_period = 40 + +watch_bed_temp_increase = 2 +watch_bed_temp_period = 60 From e4bc675fbf57272f41603d434efee27e3b826bdb Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Tue, 21 Oct 2025 19:24:25 -0500 Subject: [PATCH 04/11] =?UTF-8?q?=F0=9F=9A=B8=20Exit=20M122=20S/P=20withou?= =?UTF-8?q?t=20report?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/gcode/feature/trinamic/M122.cpp | 25 ++++++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/Marlin/src/gcode/feature/trinamic/M122.cpp b/Marlin/src/gcode/feature/trinamic/M122.cpp index b3ad144f14..fe87e485bc 100644 --- a/Marlin/src/gcode/feature/trinamic/M122.cpp +++ b/Marlin/src/gcode/feature/trinamic/M122.cpp @@ -28,11 +28,18 @@ #include "../../../feature/tmc_util.h" #include "../../../module/stepper/indirection.h" // for restore_stepper_drivers +#if AXIS_COLLISION('I') + #warning "M122 parameter 'I' collision with axis name." +#endif +#if AXIS_COLLISION('V') + #warning "M122 parameter 'V' collision with axis name." +#endif + /** * M122: Debug TMC drivers * - * I - Flag to re-initialize stepper drivers with current settings. - * X, Y, Z, E - Flags to only report the specified axes. + * I - Flag to re-initialize stepper drivers with current settings. + * X, Y, Z ... E - Flags to only report the specified axes. * * With TMC_DEBUG: * V - Report raw register data. Refer to the datasheet to decipher the report. @@ -45,20 +52,24 @@ void GcodeSuite::M122() { bool print_all = true; LOOP_LOGICAL_AXES(i) if (parser.seen_test(AXIS_CHAR(i))) { print_axis[i] = true; print_all = false; } - if (print_all) LOOP_LOGICAL_AXES(i) print_axis[i] = true; if (parser.boolval('I')) restore_stepper_drivers(); #if ENABLED(TMC_DEBUG) #if ENABLED(MONITOR_DRIVER_STATUS) - const bool sflag = parser.seen('S'), sval = sflag && parser.value_bool(); - if (sflag && !sval) // "S0" + if (parser.seenval('S') && !parser.value_bool()) { // "S0" tmc_set_report_interval(0); - else if (parser.seenval('P')) // "P" + return; + } + else if (parser.seenval('P')) { // "P" tmc_set_report_interval(_MAX(uint16_t(250), parser.value_ushort())); - else if (sval) // "S" or "S1" + return; + } + else if (parser.boolval('S')) { // "S" or "S1" tmc_set_report_interval(MONITOR_DRIVER_STATUS_INTERVAL_MS); + return; + } #endif if (parser.seen_test('V')) From e3a5319e3c855925e7218fc0204f6705a935c3ef Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Wed, 22 Oct 2025 15:04:42 -0500 Subject: [PATCH 05/11] =?UTF-8?q?=F0=9F=8E=A8=20Misc.=20cleanup,=20probe?= =?UTF-8?q?=20FR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/feature/tmc_util.cpp | 10 ++--- Marlin/src/gcode/calibrate/G34_M422.cpp | 6 +-- Marlin/src/module/endstops.cpp | 5 --- Marlin/src/module/endstops.h | 2 +- Marlin/src/module/ft_motion.cpp | 7 ++++ Marlin/src/module/ft_motion.h | 2 +- Marlin/src/module/motion.cpp | 2 +- Marlin/src/module/motion.h | 4 +- Marlin/src/module/planner.cpp | 2 +- Marlin/src/module/settings.cpp | 2 +- Marlin/src/module/stepper.cpp | 50 +++++++------------------ 11 files changed, 36 insertions(+), 56 deletions(-) diff --git a/Marlin/src/feature/tmc_util.cpp b/Marlin/src/feature/tmc_util.cpp index 06ee4c9e93..b1fc69f88a 100644 --- a/Marlin/src/feature/tmc_util.cpp +++ b/Marlin/src/feature/tmc_util.cpp @@ -973,14 +973,14 @@ TMC_REPORT("[mm/s]\t", TMC_TPWMTHRS_MMS); TMC_REPORT("OT prewarn", TMC_DEBUG_OTPW); #if ENABLED(MONITOR_DRIVER_STATUS) - TMC_REPORT("triggered\n OTP\t", TMC_OTPW_TRIGGERED); + TMC_REPORT("OTPW trig.\t", TMC_OTPW_TRIGGERED); #endif #if HAS_TMC220x - TMC_REPORT("pwm scale sum", TMC_PWM_SCALE_SUM); - TMC_REPORT("pwm scale auto", TMC_PWM_SCALE_AUTO); - TMC_REPORT("pwm offset auto", TMC_PWM_OFS_AUTO); - TMC_REPORT("pwm grad auto", TMC_PWM_GRAD_AUTO); + TMC_REPORT("pwm scale sum", TMC_PWM_SCALE_SUM); + TMC_REPORT("pwm scale auto", TMC_PWM_SCALE_AUTO); + TMC_REPORT("pwm offset auto", TMC_PWM_OFS_AUTO); + TMC_REPORT("pwm grad auto", TMC_PWM_GRAD_AUTO); #endif TMC_REPORT("off time", TMC_TOFF); diff --git a/Marlin/src/gcode/calibrate/G34_M422.cpp b/Marlin/src/gcode/calibrate/G34_M422.cpp index aba828d6dd..1ac58cc894 100644 --- a/Marlin/src/gcode/calibrate/G34_M422.cpp +++ b/Marlin/src/gcode/calibrate/G34_M422.cpp @@ -236,10 +236,8 @@ void GcodeSuite::G34() { Z_TWEEN_SAFE_CLEARANCE // z_clearance ); - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOLNPGM_P(PSTR("Probing X"), ppos.x, SP_Y_STR, ppos.y); - DEBUG_ECHOLNPGM("Height = ", z_probed_height); - } + if (DEBUGGING(LEVELING)) + DEBUG_ECHOLN(F("Probing X"), ppos.x, FPSTR(SP_Y_STR), ppos.y, F(" Height = "), z_probed_height); if (isnan(z_probed_height)) { SERIAL_ECHOLNPGM(STR_ERR_PROBING_FAILED); diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index b0ad431476..a12e432003 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -309,11 +309,6 @@ void Endstops::enable(const bool onoff) { resync(); } -// Disable / Enable endstops based on ENSTOPS_ONLY_FOR_HOMING and global enable -void Endstops::not_homing() { - enabled = enabled_globally; -} - #if ENABLED(VALIDATE_HOMING_ENDSTOPS) // If the last move failed to trigger an endstop, call kill void Endstops::validate_homing_move() { diff --git a/Marlin/src/module/endstops.h b/Marlin/src/module/endstops.h index 40975632ff..ab124c3536 100644 --- a/Marlin/src/module/endstops.h +++ b/Marlin/src/module/endstops.h @@ -246,7 +246,7 @@ class Endstops { static void enable(const bool onoff=true); // Disable / Enable endstops based on ENSTOPS_ONLY_FOR_HOMING and global enable - static void not_homing(); + static void not_homing() { enabled = enabled_globally; } #if ENABLED(VALIDATE_HOMING_ENDSTOPS) // If the last move failed to trigger an endstop, call kill diff --git a/Marlin/src/module/ft_motion.cpp b/Marlin/src/module/ft_motion.cpp index a72fe13fd6..cd0c162668 100644 --- a/Marlin/src/module/ft_motion.cpp +++ b/Marlin/src/module/ft_motion.cpp @@ -20,6 +20,13 @@ * */ +/** + * ft_motion.cpp - Singleton to execute Fixed Time Motion planning + * + * Fixed-Time Motion concept contributed by Ulendo with integration and + * overhaul optimizations by @thinkyhead, @narno2202, @dbuezas. + */ + #include "../inc/MarlinConfig.h" #if ENABLED(FT_MOTION) diff --git a/Marlin/src/module/ft_motion.h b/Marlin/src/module/ft_motion.h index 11f85aea53..a6b3e5fc58 100644 --- a/Marlin/src/module/ft_motion.h +++ b/Marlin/src/module/ft_motion.h @@ -145,7 +145,7 @@ class FTMotion { #if HAS_FTM_SHAPING // Refresh gains and indices used by shaping functions. - static void update_shaping_params(void); + static void update_shaping_params(); #endif #if ENABLED(FTM_SMOOTHING) diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index d7967f6aaf..1282e605eb 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -190,7 +190,7 @@ xyz_pos_t cartes; xyz_pos_t workspace_offset{0}; #endif -#if HAS_ABL_NOT_UBL +#if ABL_USES_GRID feedRate_t xy_probe_feedrate_mm_s = MMM_TO_MMS(XY_PROBE_FEEDRATE); #endif diff --git a/Marlin/src/module/motion.h b/Marlin/src/module/motion.h index 39da94a46e..e74562728d 100644 --- a/Marlin/src/module/motion.h +++ b/Marlin/src/module/motion.h @@ -62,7 +62,9 @@ extern xyz_pos_t cartes; extern abce_pos_t delta; #endif -#if HAS_ABL_NOT_UBL +// Determine XY_PROBE_FEEDRATE_MM_S - The feedrate used between Probe Points +#if ABL_USES_GRID + // ABL LINEAR and BILINEAR use 'G29 S' value, or MMM_TO_MMS(XY_PROBE_FEEDRATE) extern feedRate_t xy_probe_feedrate_mm_s; #define XY_PROBE_FEEDRATE_MM_S xy_probe_feedrate_mm_s #elif defined(XY_PROBE_FEEDRATE) diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index b088c0b392..f5507da7a5 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -3065,7 +3065,7 @@ bool Planner::buffer_line(const xyze_pos_t &cart, const feedRate_t fr_mm_s feedRate_t calculated_feedrate = fr_mm_s; const xyz_pos_t diff = delta - position_float; if (!NEAR_ZERO(diff.b)) { - if (delta.a <= POLAR_FAST_RADIUS ) + if (delta.a <= POLAR_FAST_RADIUS) calculated_feedrate = settings.max_feedrate_mm_s[Y_AXIS]; else { // Normalized vector of movement diff --git a/Marlin/src/module/settings.cpp b/Marlin/src/module/settings.cpp index e72a2d14ac..63f69d13c2 100644 --- a/Marlin/src/module/settings.cpp +++ b/Marlin/src/module/settings.cpp @@ -2518,7 +2518,7 @@ void MarlinSettings::postprocess() { #if HAS_TRINAMIC_CONFIG - #define SET_CURR(Q) stepper##Q.rms_current(currents.Q ? currents.Q : Q##_CURRENT) + #define SET_CURR(Q) stepper##Q.rms_current(currents.Q ?: Q##_CURRENT) if (!validating) { TERN_(X_IS_TRINAMIC, SET_CURR(X)); TERN_(Y_IS_TRINAMIC, SET_CURR(Y)); diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index 8bf839c39c..20415265b1 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -21,33 +21,25 @@ */ /** - * stepper.cpp - A singleton object to execute motion plans using stepper motors - * Marlin Firmware + * stepper.cpp - Singleton to execute motion plans using stepper motors * - * Derived from Grbl - * Copyright (c) 2009-2011 Simen Svale Skogsrud + * Marlin uses the Bresenham algorithm. For a detailed explanation of theory and + * method see https://www.cs.helsinki.fi/group/goa/mallinnus/lines/bresenh.html * - * Grbl 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. - * - * Grbl 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 Grbl. If not, see . - */ - -/** * Timer calculations informed by the 'RepRap cartesian firmware' by Zack Smith * and Philipp Tiefenbacher. + * + * Jerk controlled movements planner added Apr 2018 by Eduardo José Tagle. + * Equations based on Synthethos TinyG2 sources, but the fixed-point + * implementation is new, as we are running the ISR with a variable period. + * Also implemented the Bézier velocity curve evaluation in ARM assembler, + * to avoid impacting ISR speed. + * + * Fixed-Time Motion concept contributed by Ulendo with integration and + * overhaul optimizations by @thinkyhead, @narno2202, @dbuezas. */ -/** - * __________________________ +/** __________________________ * /| |\ _________________ ^ * / | | \ /| |\ | * / | | \ / | | \ s @@ -70,19 +62,6 @@ * - Reset the trapezoid generator. */ -/** - * Marlin uses the Bresenham algorithm. For a detailed explanation of theory and - * method see https://www.cs.helsinki.fi/group/goa/mallinnus/lines/bresenh.html - */ - -/** - * Jerk controlled movements planner added Apr 2018 by Eduardo José Tagle. - * Equations based on Synthethos TinyG2 sources, but the fixed-point - * implementation is new, as we are running the ISR with a variable period. - * Also implemented the Bézier velocity curve evaluation in ARM assembler, - * to avoid impacting ISR speed. - */ - #include "stepper.h" Stepper stepper; // Singleton @@ -3590,8 +3569,7 @@ void Stepper::report_positions() { if (last_set_direction != last_direction_bits) { // Apply directions (generally applying to the entire linear move) - #define _FTM_APPLY_DIR(A) if (last_direction_bits.A != last_set_direction.A) \ - SET_STEP_DIR(A); + #define _FTM_APPLY_DIR(A) if (last_direction_bits.A != last_set_direction.A) SET_STEP_DIR(A); LOGICAL_AXIS_MAP(_FTM_APPLY_DIR); last_set_direction = last_direction_bits; From 27da1995f32e90b11ed2a1d4347c37416ab094a1 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Wed, 22 Oct 2025 15:06:28 -0500 Subject: [PATCH 06/11] =?UTF-8?q?=F0=9F=9A=B8=20FT=20Motion=20toggle()=20m?= =?UTF-8?q?ore=20safely?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/lcd/menu/menu_motion.cpp | 5 +---- Marlin/src/module/ft_motion.h | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Marlin/src/lcd/menu/menu_motion.cpp b/Marlin/src/lcd/menu/menu_motion.cpp index f869436c7d..9e956711cf 100644 --- a/Marlin/src/lcd/menu/menu_motion.cpp +++ b/Marlin/src/lcd/menu/menu_motion.cpp @@ -465,10 +465,7 @@ void menu_move() { BACK_ITEM(MSG_MOTION); bool show_state = c.active; - EDIT_ITEM(bool, MSG_FIXED_TIME_MOTION, &show_state, []{ - FLIP(ftMotion.cfg.active); - ftMotion.update_shaping_params(); - }); + EDIT_ITEM(bool, MSG_FIXED_TIME_MOTION, &show_state, []{ (void)ftMotion.toggle(); }); // Show only when FT Motion is active (or optionally always show) if (c.active || ENABLED(FT_MOTION_NO_MENU_TOGGLE)) { diff --git a/Marlin/src/module/ft_motion.h b/Marlin/src/module/ft_motion.h index a6b3e5fc58..dfe10282e1 100644 --- a/Marlin/src/module/ft_motion.h +++ b/Marlin/src/module/ft_motion.h @@ -41,6 +41,9 @@ #endif #endif +/** + * FTConfig - The active configured state of FT Motion + */ typedef struct FTConfig { bool active = ENABLED(FTM_IS_DEFAULT_MOTION); // Active (else standard motion) bool axis_sync_enabled = true; // Axis synchronization enabled @@ -77,6 +80,9 @@ typedef struct FTConfig { float poly6_acceleration_overshoot; // Overshoot factor for Poly6 (1.25 to 2.0) } ft_config_t; +/** + * FTMotion - Singleton class encapsulating Fixed Time Motion + */ class FTMotion { public: @@ -157,6 +163,13 @@ class FTMotion { static void reset(); // Reset all states of the fixed time conversion to defaults. + static bool toggle() { + stepper.ftMotion_syncPosition(); + FLIP(cfg.active); + update_shaping_params(); + return cfg.active; + } + // Trajectory generator selection static void setTrajectoryType(const TrajectoryType type); static TrajectoryType getTrajectoryType() { return trajectoryType; } @@ -269,8 +282,12 @@ class FTMotion { }; // class FTMotion -extern FTMotion ftMotion; +extern FTMotion ftMotion; // Use ftMotion.thing, not FTMotion::thing. +/** + * Optional behavior to turn FT Motion off for homing/probing. + * Applies when FTM_HOME_AND_PROBE is disabled. + */ typedef struct FTMotionDisableInScope { #if DISABLED(FTM_HOME_AND_PROBE) bool isactive; From 788e86ccc6cec7081cbbbaffc9cf765d0e12dba4 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Thu, 23 Oct 2025 00:30:51 +0000 Subject: [PATCH 07/11] [cron] Bump distribution date (2025-10-23) --- 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 8252690420..2d37888314 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 "2025-10-22" +//#define STRING_DISTRIBUTION_DATE "2025-10-23" /** * The protocol for communication to the host. Protocol indicates communication diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 28b051217e..258884ab6d 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 "2025-10-22" + #define STRING_DISTRIBUTION_DATE "2025-10-23" #endif /** From 3a77a7eefdc7d2181e443eede82eb30a5db3459b Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Wed, 22 Oct 2025 23:50:04 -0500 Subject: [PATCH 08/11] =?UTF-8?q?=F0=9F=90=9B=20Fix=20SDSORT=5FQUICK=20wit?= =?UTF-8?q?h=20stack?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Followup to #28069 --- Marlin/src/sd/cardreader.cpp | 338 +++++++++++++++++------------------ Marlin/src/sd/cardreader.h | 4 - 2 files changed, 168 insertions(+), 174 deletions(-) diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index 9a5394d5e7..1d6fa06998 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -1328,171 +1328,6 @@ void CardReader::cdroot() { #endif #endif - #if ENABLED(SDSORT_QUICK) - - // Quick Sort - bool CardReader::sort_cmp_files(const int16_t o1, const int16_t o2) { - auto _sort_cmp_file = [](const char *const n1, const char *const n2) -> bool { - const bool sort = strcasecmp(n1, n2) < 0; - return (TERN(SDSORT_GCODE, sort_alpha == AS_REV, ENABLED(SDSORT_REVERSE))) ? !sort : sort; - }; - - #if ENABLED(SDSORT_USES_RAM) - const bool dir1 = IS_DIR(o1), dir2 = IS_DIR(o2); - const char *name1 = card.sortnames[o1], *name2 = card.sortnames[o2]; - #else - card.selectFileByIndex(o1); - char name1_buffer[LONG_FILENAME_LENGTH]; - strcpy(name1_buffer, card.longest_filename()); - const char *name1 = name1_buffer; - const bool dir1 = card.flag.filenameIsDir; - - card.selectFileByIndex(o2); - const char *name2 = card.longest_filename(); - const bool dir2 = card.flag.filenameIsDir; - #endif - - #if HAS_FOLDER_SORTING - #if ENABLED(SDSORT_GCODE) - if (card.sort_folders && dir1 != dir2) - return (card.sort_folders > 0) ? dir1 : !dir1; - #else - if (dir1 != dir2) - return (SDSORT_FOLDERS > 0) ? dir1 : !dir1; - #endif - #endif - - return _sort_cmp_file(name1, name2); - } - - int16_t CardReader::partition(uint8_t* arr, int16_t low, int16_t high) { - int16_t pivotIndex = arr[high]; - int16_t i = (low - 1); - - for (int16_t j = low; j < high; j++) { - if (sort_cmp_files(arr[j], pivotIndex)) { - i++; - uint8_t temp = arr[i]; - arr[i] = arr[j]; - arr[j] = temp; - } - } - // Manual swap - uint8_t temp = arr[i + 1]; - arr[i + 1] = arr[high]; - arr[high] = temp; - return (i + 1); - } - - void CardReader::quicksort(uint8_t* arr, int16_t low, int16_t high) { - int16_t stack[SDSORT_LIMIT + 1]; - int16_t top = -1; // Initialize top of stack - - // Push initial values to the stack - stack[++top] = low; - stack[++top] = high; - - // Pop from stack while not empty - while (top >= 0) { - high = stack[top--]; - low = stack[top--]; - - // Set pivot element at correct position - const int16_t pivot = partition(arr, low, high); - // If elements are on left side, push to stack - if (pivot - 1 > low) { - stack[++top] = low; - stack[++top] = pivot - 1; - } - // If elements are on right side, push to stack - if (pivot + 1 < high) { - stack[++top] = pivot + 1; - stack[++top] = high; - } - } - } - - #else // !SDSORT_QUICK - - // Bubble Sort - void CardReader::bubblesort(uint8_t* arr, int16_t fileCnt) { - for (int16_t i = fileCnt; --i;) { - bool didSwap = false; - int16_t o1 = arr[0]; - #if DISABLED(SDSORT_USES_RAM) - // By default re-read the names from SD for every compare - // retaining only two filenames at a time. This is very - // slow but is safest and uses minimal RAM. - char name1[LONG_FILENAME_LENGTH]; - selectFileByIndex(o1); // Pre-fetch the first entry and save it - strcpy(name1, longest_filename()); // so the loop only needs one fetch - #if HAS_FOLDER_SORTING - bool dir1 = flag.filenameIsDir; - #endif - if ((i & 0x7) == 7) hal.watchdog_refresh(); - #endif - - for (int16_t j = 0; j < i; ++j) { - const int16_t o2 = arr[j + 1]; - - // Compare names from the array or just the two buffered names - auto _sort_cmp_file = [](char * const n1, char * const n2) -> bool { - const bool sort = strcasecmp(n1, n2) > 0; - return (TERN(SDSORT_GCODE, sort_alpha == AS_REV, ENABLED(SDSORT_REVERSE))) ? !sort : sort; - }; - #define _SORT_CMP_FILE() _sort_cmp_file(TERN(SDSORT_USES_RAM, sortnames[o1], name1), TERN(SDSORT_USES_RAM, sortnames[o2], name2)) - - #if HAS_FOLDER_SORTING - #if ENABLED(SDSORT_USES_RAM) - // Folder sorting needs an index and bit to test for folder-ness. - #define _SORT_CMP_DIR(fs) (IS_DIR(o1) == IS_DIR(o2) ? _SORT_CMP_FILE() : IS_DIR(fs > 0 ? o1 : o2)) - #else - #define _SORT_CMP_DIR(fs) ((dir1 == flag.filenameIsDir) ? _SORT_CMP_FILE() : (fs > 0 ? dir1 : !dir1)) - #endif - #endif - - // The most economical method reads names as-needed - // throughout the loop. Slow if there are many. - #if DISABLED(SDSORT_USES_RAM) - selectFileByIndex(o2); - const bool dir2 = flag.filenameIsDir; - char * const name2 = longest_filename(); // Use the string in-place - if ((i & 0x7) == 7) hal.watchdog_refresh(); - #endif - - // Sort the current pair according to settings. - if ( - #if HAS_FOLDER_SORTING - #if ENABLED(SDSORT_GCODE) - sort_folders ? _SORT_CMP_DIR(sort_folders) : _SORT_CMP_FILE() - #else - _SORT_CMP_DIR(SDSORT_FOLDERS) - #endif - #else - _SORT_CMP_FILE() - #endif - ) { - // Reorder the index, indicate that sorting happened - // Note that the next o1 will be the current o1. No new fetch needed. - arr[j] = o2; - arr[j + 1] = o1; - didSwap = true; - } - else { - // The next o1 is the current o2. No new fetch needed. - o1 = o2; - #if DISABLED(SDSORT_USES_RAM) - TERN_(HAS_FOLDER_SORTING, dir1 = dir2); - strcpy(name1, name2); - #endif - } - } - if (!didSwap) break; - } - } - - #endif // !SDSORT_QUICK - /** * Read all the files and produce a sort key * @@ -1543,6 +1378,13 @@ void CardReader::cdroot() { #endif #endif + #else // !SDSORT_USES_RAM + + // By default re-read the names from SD for every compare + // retaining only two filenames at a time. This is very + // slow but is safest and uses minimal RAM. + char name1[LONG_FILENAME_LENGTH]; + #endif if (fileCnt > 1) { @@ -1564,15 +1406,171 @@ void CardReader::cdroot() { if (flag.filenameIsDir) SBI(isDir[ind], bit); #endif #endif - if ((i & 0x7) == 7) hal.watchdog_refresh(); } - // Sorting Algorithm #if ENABLED(SDSORT_QUICK) - quicksort(sort_order, 0, fileCnt - 1); + { + auto sort_cmp_files = [&](const int16_t o1, const int16_t o2) -> bool { + #if DISABLED(SDSORT_USES_RAM) + char name1[LONG_FILENAME_LENGTH]; + selectFileByIndex(o1); + strcpy(name1, longest_filename()); + #if HAS_FOLDER_SORTING + const bool dir1 = flag.filenameIsDir; + #endif + selectFileByIndex(o2); + const char *name2 = longest_filename(); + #if HAS_FOLDER_SORTING + const bool dir2 = flag.filenameIsDir; + #endif + #else + #if HAS_FOLDER_SORTING + const bool dir1 = IS_DIR(o1), dir2 = IS_DIR(o2); + #endif + const char *name1 = sortnames[o1], *name2 = sortnames[o2]; + #endif + + #if HAS_FOLDER_SORTING + #if ENABLED(SDSORT_GCODE) + if (sort_folders && dir1 != dir2) + return (sort_folders > 0) ? dir1 : !dir1; + #else + if (dir1 != dir2) + return (SDSORT_FOLDERS > 0) ? dir1 : !dir1; + #endif + #endif + + const bool sort = strcasecmp(name1, name2) < 0; + return (TERN(SDSORT_GCODE, sort_alpha == AS_REV, ENABLED(SDSORT_REVERSE))) ? !sort : sort; + }; + + auto partition = [&](uint8_t* arr, int16_t low, int16_t high) -> int16_t { + int16_t pivotIndex = arr[high]; + int16_t i = (low - 1); + + for (int16_t j = low; j < high; j++) { + if (sort_cmp_files(arr[j], pivotIndex)) { + i++; + uint8_t temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + } + // Manual swap + uint8_t temp = arr[i + 1]; + arr[i + 1] = arr[high]; + arr[high] = temp; + return (i + 1); + }; + + // Quick Sort + int16_t stack[SDSORT_LIMIT + 1]; + int16_t top = -1; // Initialize top of stack + + int16_t low = 0, high = fileCnt - 1; + + // Push initial values to the stack + stack[++top] = low; + stack[++top] = high; + + // Pop from stack while not empty + while (top >= 0) { + high = stack[top--]; + low = stack[top--]; + + // Set pivot element at correct position + const int16_t pivot = partition(sort_order, low, high); + + // If elements are on left side, push to stack + if (pivot - 1 > low) { + stack[++top] = low; + stack[++top] = pivot - 1; + } + // If elements are on right side, push to stack + if (pivot + 1 < high) { + stack[++top] = pivot + 1; + stack[++top] = high; + } + } + + } #else - bubblesort(sort_order, fileCnt); - #endif + { + // Bubble Sort + for (int16_t i = fileCnt; --i;) { + bool didSwap = false; + int16_t o1 = sort_order[0]; + #if DISABLED(SDSORT_USES_RAM) + // By default re-read the names from SD for every compare + // retaining only two filenames at a time. This is very + // slow but is safest and uses minimal RAM. + selectFileByIndex(o1); // Pre-fetch the first entry and save it + strcpy(name1, longest_filename()); // so the loop only needs one fetch + #if HAS_FOLDER_SORTING + bool dir1 = flag.filenameIsDir; + #endif + if ((i & 0x7) == 7) hal.watchdog_refresh(); + #endif + + for (int16_t j = 0; j < i; ++j) { + const int16_t o2 = sort_order[j + 1]; + + // Compare names from the array or just the two buffered names + auto _sort_cmp_file = [](char * const n1, char * const n2) -> bool { + const bool sort = strcasecmp(n1, n2) > 0; + return (TERN(SDSORT_GCODE, sort_alpha == AS_REV, ENABLED(SDSORT_REVERSE))) ? !sort : sort; + }; + #define _SORT_CMP_FILE() _sort_cmp_file(TERN(SDSORT_USES_RAM, sortnames[o1], name1), TERN(SDSORT_USES_RAM, sortnames[o2], name2)) + + #if HAS_FOLDER_SORTING + #if ENABLED(SDSORT_USES_RAM) + // Folder sorting needs an index and bit to test for folder-ness. + #define _SORT_CMP_DIR(fs) (IS_DIR(o1) == IS_DIR(o2) ? _SORT_CMP_FILE() : IS_DIR(fs > 0 ? o1 : o2)) + #else + #define _SORT_CMP_DIR(fs) ((dir1 == flag.filenameIsDir) ? _SORT_CMP_FILE() : (fs > 0 ? dir1 : !dir1)) + #endif + #endif + + // The most economical method reads names as-needed + // throughout the loop. Slow if there are many. + #if DISABLED(SDSORT_USES_RAM) + selectFileByIndex(o2); + const bool dir2 = flag.filenameIsDir; + char * const name2 = longest_filename(); // Use the string in-place + if ((i & 0x7) == 7) hal.watchdog_refresh(); + #endif + + // Sort the current pair according to settings. + if ( + #if HAS_FOLDER_SORTING + #if ENABLED(SDSORT_GCODE) + sort_folders ? _SORT_CMP_DIR(sort_folders) : _SORT_CMP_FILE() + #else + _SORT_CMP_DIR(SDSORT_FOLDERS) + #endif + #else + _SORT_CMP_FILE() + #endif + ) { + // Reorder the index, indicate that sorting happened + // Note that the next o1 will be the current o1. No new fetch needed. + sort_order[j] = o2; + sort_order[j + 1] = o1; + didSwap = true; + } + else { + // The next o1 is the current o2. No new fetch needed. + o1 = o2; + #if DISABLED(SDSORT_USES_RAM) + TERN_(HAS_FOLDER_SORTING, dir1 = dir2); + strcpy(name1, name2); + #endif + } + } + if (!didSwap) break; + } + } + #endif // Bubble Sort // Using RAM but not keeping names around #if ENABLED(SDSORT_USES_RAM) && DISABLED(SDSORT_CACHE_NAMES) diff --git a/Marlin/src/sd/cardreader.h b/Marlin/src/sd/cardreader.h index 5f1d99a561..c6b3dc6384 100644 --- a/Marlin/src/sd/cardreader.h +++ b/Marlin/src/sd/cardreader.h @@ -403,10 +403,6 @@ private: #endif // SDSORT_USES_RAM static void flush_presort(); - static bool sort_cmp_files(const int16_t o1, const int16_t o2); - static int16_t partition(uint8_t* arr, int16_t low, int16_t high); - static void quicksort(uint8_t* arr, int16_t low, int16_t high); - static void bubblesort(uint8_t* arr, int16_t fileCnt); #endif // SDCARD_SORT_ALPHA // From 9eea88bbfc08d370410aa5f5555cdad57fa900cf Mon Sep 17 00:00:00 2001 From: Harald Wagener Date: Thu, 23 Oct 2025 20:56:03 +0200 Subject: [PATCH 09/11] Update README.md (#28135) * Update README.md - Add some details about configuration branches - Link to the download page - Reword sections on 8 bit boards - Add a short section on 32 bit boards - Update Paragraph on HALs * Update README.md fix typo Co-authored-by: David Buezas * code formatting with prettier, remove https URI to be consistent with other links * expand on HALs --------- Co-authored-by: David Buezas --- README.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 90815578c8..45e91d62c0 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,8 @@ -Additional documentation can be found at the [Marlin Home Page](//marlinfw.org/). +Official documentation can be found at the [Marlin Home Page](//marlinfw.org/). + Please test this firmware and let us know if it misbehaves in any way. Volunteers are standing by! --- @@ -72,7 +73,7 @@ Please test this firmware and let us know if it misbehaves in any way. Volunteer **Not for production use. Use with caution!** -Marlin 2.1 continues to support both 32-bit ARM and 8-bit AVR boards while adding support for up to 9 coordinated axes and to up to 8 extruders. +Marlin 2.1 supports both 32-bit ARM and 8-bit AVR boards while adding support for up to 9 coordinated axes and to up to 8 extruders. This branch is for patches to the latest 2.1.x release version. Periodically this branch will form the basis for the next minor 2.1.x release. @@ -80,27 +81,32 @@ Download earlier versions of Marlin on the [Releases page](//github.com/MarlinFi ## Example Configurations -Before you can build Marlin for your machine you'll need a configuration for your specific hardware. Upon request, your vendor will be happy to provide you with the complete source code and configurations for your machine, but you'll need to get updated configuration files if you want to install a newer version of Marlin. Fortunately, Marlin users have contributed dozens of tested configurations to get you started. Visit the [MarlinFirmware/Configurations](//github.com/MarlinFirmware/Configurations) repository to find the right configuration for your hardware. +Before you can build Marlin for your machine you'll need a configuration for your specific hardware. Upon request, your vendor will be happy to provide you with the complete source code and configurations for your machine, but you'll need to get updated configuration files if you want to install a newer version of Marlin. Fortunately, Marlin users have contributed hundreds of tested configurations to get you started. Visit the [MarlinFirmware/Configurations](//github.com/MarlinFirmware/Configurations) repository to find the right configuration for your hardware. Make sure to select a compatible branch! [The Marlin Download Page](//marlinfw.org/meta/download/) matches compatible software and configuration packages. ## Building Marlin 2.1 To build and upload Marlin you will use one of these tools: - The free [Visual Studio Code](//code.visualstudio.com/download) using the [Auto Build Marlin](//marlinfw.org/docs/basics/auto_build_marlin.html) extension. -- The free [Arduino IDE](//www.arduino.cc/en/main/software) : See [Building Marlin with Arduino](//marlinfw.org/docs/basics/install_arduino.html) +- Marlin is optimized to build with the [PlatformIO IDE](//platformio.org/) extension for Visual Studio Code. - You can also use VSCode with devcontainer : See [Installing Marlin (VSCode devcontainer)](http://marlinfw.org/docs/basics/install_devcontainer_vscode.html). +- You can still build Marlin with [Arduino IDE](//www.arduino.cc/en/main/software) : See [Building Marlin with Arduino](//marlinfw.org/docs/basics/install_arduino.html). We hope to improve the Arduino build experience, but at this time, PlatformIO is the preferred choice. -Marlin is optimized to build with the **PlatformIO IDE** extension for **Visual Studio Code**. You can still build Marlin with **Arduino IDE**, and we hope to improve the Arduino build experience, but at this time PlatformIO is the better choice. +## 32-bit ARM boards + +Marlin is compatible with a plethora of 32-bit ARM boards, which offer ample computational power and memory and allows Marlin to deliver state-of-the-art performance and features we like to see in modern 3d printers. Some of the newer features in Marlin will require use of a 32-bit ARM board. ## 8-Bit AVR Boards -We intend to continue supporting 8-bit AVR boards in perpetuity, maintaining a single codebase that can apply to all machines. We want casual hobbyists and tinkerers and owners of older machines to benefit from the community's innovations just as much as those with fancier machines. Plus, those old AVR-based machines are often the best for your testing and feedback! +Marlin originates from the era of Arduino based 8-bit boards, and we aim to support 8-bit AVR boards in perpetuity. Both 32-bit and 8-bit boards are covered by a single code base that can apply to all machines. Our goal is to support casual hobbyists, tinkerers, and owners of older machines and boards, striving to allow them to benefit from the community's innovations just as much as those with fancier machines and newer baords. In addition, these venerable AVR-based machines are often the best for testing and feedback! ## Hardware Abstraction Layer (HAL) -Marlin includes an abstraction layer to provide a common API for all the platforms it targets. This allows Marlin code to address the details of motion and user interface tasks at the lowest and highest levels with no system overhead, tying all events directly to the hardware clock. +Marlin's Hardware Abstraction Layer provides a common API for all the platforms it targets. This allows Marlin code to address the details of motion and user interface tasks at the lowest and highest levels with no system overhead, tying all events directly to the hardware clock. -Every new HAL opens up a world of hardware. At this time we need HALs for RP2040 and the Duet3D family of boards. A HAL that wraps an RTOS is an interesting concept that could be explored. Did you know that Marlin includes a Simulator that can run on Windows, macOS, and Linux? Join the Discord to help move these sub-projects forward! +Every new HAL opens up a world of hardware. Marlin currently has HALs for more than a dozen platforms. While AVR and STM32 are the most well known and popular ones, others like ESP32 and LPC1768 support a variety of less common boards. At this time, an HAL for RP2040 is available in beta; we would like to add one for the Duet3D family of boards. A HAL that wraps an RTOS is an interesting concept that could be explored. + +Did you know that Marlin includes a Simulator that can run on Windows, macOS, and Linux? Join the Discord to help move these sub-projects forward! ### Supported Platforms From 4349f4ab0cde4f7c0e28e52661f8f9fada20a8b8 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Thu, 23 Oct 2025 17:44:23 -0500 Subject: [PATCH 10/11] =?UTF-8?q?=F0=9F=A7=91=E2=80=8D=F0=9F=92=BB=20Add?= =?UTF-8?q?=20'make=20clean'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 97441dc856..db1066b2ef 100644 --- a/Makefile +++ b/Makefile @@ -66,6 +66,9 @@ marlin: ./buildroot/bin/mftest -a .PHONY: marlin +clean: + rm -r .pio/build + tests-single-ci: export GIT_RESET_HARD=true $(MAKE) tests-single-local TEST_TARGET=$(TEST_TARGET) PLATFORMIO_BUILD_FLAGS=-DGITHUB_ACTION From fbc2c76870d9eb343bb9996241687ba4050cc270 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Fri, 24 Oct 2025 00:28:38 +0000 Subject: [PATCH 11/11] [cron] Bump distribution date (2025-10-24) --- 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 2d37888314..d45979e25a 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 "2025-10-23" +//#define STRING_DISTRIBUTION_DATE "2025-10-24" /** * The protocol for communication to the host. Protocol indicates communication diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 258884ab6d..791b387b82 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 "2025-10-23" + #define STRING_DISTRIBUTION_DATE "2025-10-24" #endif /**