diff --git a/Makefile b/Makefile index f1f64e1342..97441dc856 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,31 @@ CONTAINER_RT_OPTS := --rm -v $(PWD):/code -v platformio-cache:/root/.platformio CONTAINER_IMAGE := marlin-dev UNIT_TEST_CONFIG ?= default +# Find a Python 3 interpreter +ifeq ($(OS),Windows_NT) + # Windows: use `where` – fall back through the three common names + PYTHON := $(shell where python 2>nul || where python3 2>nul || where py 2>nul) + # Windows: Use cmd tools to find pins files + PINS_RAW := $(shell cmd //c "dir /s /b Marlin\src\pins\*.h 2>nul | findstr /r ".*Marlin\\\\src\\\\pins\\\\.*\\\\pins_.*\.h"") + PINS := $(subst \,/,$(PINS_RAW)) +else + # POSIX: use `command -v` – prefer python3 over python + PYTHON := $(shell command -v python3 2>/dev/null || command -v python 2>/dev/null) + # Unix/Linux: Use find command + PINS := $(shell find Marlin/src/pins -mindepth 2 -name 'pins_*.h') +endif + +# Check that the found interpreter is Python 3 +# Error if there's no Python 3 available +ifneq ($(strip $(PYTHON)),) + PYTHON_VERSION := $(shell $(PYTHON) -c "import sys; print(sys.version_info[0])" 2>/dev/null) + ifneq ($(PYTHON_VERSION),3) + $(error $(PYTHON) is not Python 3 – install a Python‑3.x interpreter or adjust your PATH) + endif +else + $(error No Python executable found – install Python 3.x and make sure it is in your PATH) +endif + help: @echo "Tasks for local development:" @echo "make marlin : Build Marlin for the configured board" @@ -20,7 +45,7 @@ help: @echo "make unit-test-single-local-docker : Run unit tests for a single config locally, using docker" @echo "make unit-test-all-local : Run all code tests locally" @echo "make unit-test-all-local-docker : Run all code tests locally, using docker" - @echo "make setup-local-docker : Setup local docker using buildx" + @echo "make setup-local-docker : Setup local docker" @echo "" @echo "Options for testing:" @echo " TEST_TARGET Set when running tests-single-*, to select the" @@ -57,10 +82,10 @@ tests-single-local-docker: $(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) make tests-single-local TEST_TARGET=$(TEST_TARGET) VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD) ONLY_TEST="$(ONLY_TEST)" tests-all-local: - @python -c "import yaml" 2>/dev/null || (echo 'pyyaml module is not installed. Install it with "python -m pip install pyyaml"' && exit 1) + @$(PYTHON) -c "import yaml" 2>/dev/null || (echo 'pyyaml module is not installed. Install it with "$(PYTHON) -m pip install pyyaml"' && exit 1) export PATH="./buildroot/bin/:./buildroot/tests/:${PATH}" \ && export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \ - && for TEST_TARGET in $$(python $(SCRIPTS_DIR)/get_test_targets.py) ; do \ + && for TEST_TARGET in $$($(PYTHON) $(SCRIPTS_DIR)/get_test_targets.py) ; do \ if [ "$$TEST_TARGET" = "linux_native" ] && [ "$$(uname)" = "Darwin" ]; then \ echo "Skipping tests for $$TEST_TARGET on macOS" ; \ continue ; \ @@ -88,18 +113,36 @@ unit-test-all-local-docker: @if ! $(CONTAINER_RT_BIN) images -q $(CONTAINER_IMAGE) > /dev/null ; then $(MAKE) setup-local-docker ; fi $(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) make unit-test-all-local -setup-local-docker: - $(CONTAINER_RT_BIN) buildx build -t $(CONTAINER_IMAGE) -f docker/Dockerfile . +USERNAME := $(shell whoami) +USER_ID := $(shell id -u) +GROUP_ID := $(shell id -g) -PINS := $(shell find Marlin/src/pins -mindepth 2 -name '*.h') +.PHONY: setup-local-docker setup-local-docker-old + +setup-local-docker: + @echo "Building marlin-dev Docker image..." + $(CONTAINER_RT_BIN) build -t $(CONTAINER_IMAGE) \ + --build-arg USERNAME=$(USERNAME) \ + --build-arg USER_ID=$(USER_ID) \ + --build-arg GROUP_ID=$(GROUP_ID) \ + -f docker/Dockerfile . + @echo + @echo "To run all tests in Docker:" + @echo " make tests-all-local-docker" + @echo "To run a single test in Docker:" + @echo " make tests-single-local-docker TEST_TARGET=mega2560" + +setup-local-docker-old: + $(CONTAINER_RT_BIN) buildx build -t $(CONTAINER_IMAGE) -f docker/Dockerfile . .PHONY: $(PINS) format-pins validate-pins $(PINS): %: @echo "Formatting pins $@" - @python $(SCRIPTS_DIR)/pinsformat.py $< $@ + @$(PYTHON) $(SCRIPTS_DIR)/pinsformat.py $< $@ format-pins: $(PINS) + @echo "Processed $(words $(PINS)) pins files" validate-pins: format-pins @echo "Validating pins files" @@ -109,8 +152,8 @@ validate-pins: format-pins format-lines: @echo "Formatting all sources" - @python $(SCRIPTS_DIR)/linesformat.py buildroot - @python $(SCRIPTS_DIR)/linesformat.py Marlin + @$(PYTHON) $(SCRIPTS_DIR)/linesformat.py buildroot + @$(PYTHON) $(SCRIPTS_DIR)/linesformat.py Marlin validate-lines: @echo "Validating text formatting" @@ -122,4 +165,4 @@ BOARDS_FILE := Marlin/src/core/boards.h validate-boards: @echo "Validating boards.h file" - @python $(SCRIPTS_DIR)/validate_boards.py $(BOARDS_FILE) || (echo "\nError: boards.h file is not valid. Please check and correct it.\n" && exit 1) + @$(PYTHON) $(SCRIPTS_DIR)/validate_boards.py $(BOARDS_FILE) || (echo "\nError: boards.h file is not valid. Please check and correct it.\n" && exit 1) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 40b8ba5f22..7947ba65c5 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -942,7 +942,7 @@ * protect against a broken or disconnected thermistor wire. * * The issue: If a thermistor falls out, it will report the much lower - * temperature of the air in the room, and the the firmware will keep + * temperature of the air in the room, and the firmware will keep * the heater on. * * If you get "Thermal Runaway" or "Heating failed" errors the @@ -3468,6 +3468,7 @@ * NOTOSANS - Default font with anti-aliasing. Supports Latin Extended and non-Latin characters. * UNIFONT - Lightweight font, no anti-aliasing. Supports Latin Extended and non-Latin characters. * HELVETICA - Lightweight font, no anti-aliasing. Supports Basic Latin (0x0020-0x007F) and Latin-1 Supplement (0x0080-0x00FF) characters only. + * :['NOTOSANS', 'UNIFONT', 'HELVETICA'] */ #define TFT_FONT NOTOSANS @@ -3477,6 +3478,7 @@ * BLUE_MARLIN - Default theme with 'midnight blue' background * BLACK_MARLIN - Theme with 'black' background * ANET_BLACK - Theme used for Anet ET4/5 + * :['BLUE_MARLIN', 'BLACK_MARLIN', 'ANET_BLACK'] */ #define TFT_THEME BLACK_MARLIN diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 215f1f8026..122a7a458d 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -297,7 +297,7 @@ * protect against a broken or disconnected thermistor wire. * * The issue: If a thermistor falls out, it will report the much lower - * temperature of the air in the room, and the the firmware will keep + * temperature of the air in the room, and the firmware will keep * the heater on. * * The solution: Once the temperature reaches the target, start observing. @@ -778,7 +778,7 @@ // @section endstops -// If you want endstops to stay on (by default) even when not homing +// If you want endstops to stay on (by default) even when not homing, // enable this option. Override at any time with M120, M121. //#define ENDSTOPS_ALWAYS_ON_DEFAULT @@ -1143,49 +1143,83 @@ /** * Fixed-time-based Motion Control -- BETA FEATURE - * Enable/disable and set parameters with G-code M493. + * Enable/disable and set parameters with G-code M493 and M494. * See ft_types.h for named values used by FTM options. */ //#define FT_MOTION #if ENABLED(FT_MOTION) - //#define FTM_IS_DEFAULT_MOTION // Use FT Motion as the factory default? + //#define FTM_IS_DEFAULT_MOTION // Use FT Motion as the factory default? + //#define FT_MOTION_MENU // Provide a MarlinUI menu to set M493 and M494 parameters + //#define FTM_HOME_AND_PROBE // Use FT Motion for homing / probing. Disable if FT Motion breaks these functions. + #define FTM_DEFAULT_DYNFREQ_MODE dynFreqMode_DISABLED // Default mode of dynamic frequency calculation. (DISABLED, Z_BASED, MASS_BASED) - #define FTM_LINEAR_ADV_DEFAULT_ENA false // Default linear advance enable (true) or disable (false) - #define FTM_LINEAR_ADV_DEFAULT_K 0.0f // Default linear advance gain. (Acceleration-based scaling factor.) + #define FTM_LINEAR_ADV_DEFAULT_ENA false // Default linear advance enable (true) or disable (false) + #define FTM_LINEAR_ADV_DEFAULT_K 0.0f // Default linear advance gain. (Acceleration-based scaling factor.) #define FTM_DEFAULT_SHAPER_X ftMotionShaper_NONE // Default shaper mode on X axis (NONE, ZV, ZVD, ZVDD, ZVDDD, EI, 2HEI, 3HEI, MZV) - #define FTM_SHAPING_DEFAULT_FREQ_X 37.0f // (Hz) Default peak frequency used by input shapers - #define FTM_SHAPING_ZETA_X 0.1f // Zeta used by input shapers for X axis - #define FTM_SHAPING_V_TOL_X 0.05f // Vibration tolerance used by EI input shapers for X axis + #define FTM_SHAPING_DEFAULT_FREQ_X 37.0f // (Hz) Default peak frequency used by input shapers + #define FTM_SHAPING_ZETA_X 0.1f // Zeta used by input shapers for X axis + #define FTM_SHAPING_V_TOL_X 0.05f // Vibration tolerance used by EI input shapers for X axis #define FTM_DEFAULT_SHAPER_Y ftMotionShaper_NONE // Default shaper mode on Y axis - #define FTM_SHAPING_DEFAULT_FREQ_Y 37.0f // (Hz) Default peak frequency used by input shapers - #define FTM_SHAPING_ZETA_Y 0.1f // Zeta used by input shapers for Y axis - #define FTM_SHAPING_V_TOL_Y 0.05f // Vibration tolerance used by EI input shapers for Y axis + #define FTM_SHAPING_DEFAULT_FREQ_Y 37.0f // (Hz) Default peak frequency used by input shapers + #define FTM_SHAPING_ZETA_Y 0.1f // Zeta used by input shapers for Y axis + #define FTM_SHAPING_V_TOL_Y 0.05f // Vibration tolerance used by EI input shapers for Y axis - //#define FT_MOTION_MENU // Provide a MarlinUI menu to set M493 parameters + //#define FTM_SHAPER_Z // Include Z shaping support + #define FTM_DEFAULT_SHAPER_Z ftMotionShaper_NONE // Default shaper mode on Z axis + #define FTM_SHAPING_DEFAULT_FREQ_Z 21.0f // (Hz) Default peak frequency used by input shapers + #define FTM_SHAPING_ZETA_Z 0.03f // Zeta used by input shapers for Z axis + #define FTM_SHAPING_V_TOL_Z 0.05f // Vibration tolerance used by EI input shapers for Z axis + + //#define FTM_SHAPER_E // Include E shaping support + // Required to synchronize extruder with XYZ (better quality) + #define FTM_DEFAULT_SHAPER_E ftMotionShaper_NONE // Default shaper mode on Extruder axis + #define FTM_SHAPING_DEFAULT_FREQ_E 21.0f // (Hz) Default peak frequency used by input shapers + #define FTM_SHAPING_ZETA_E 0.03f // Zeta used by input shapers for E axis + #define FTM_SHAPING_V_TOL_E 0.05f // Vibration tolerance used by EI input shapers for E axis + + //#define FTM_SMOOTHING // Smoothing can reduce artifacts and make steppers quieter + // on sharp corners, but too much will round corners. + #if ENABLED(FTM_SMOOTHING) + #define FTM_MAX_SMOOTHING_TIME 0.10f // (s) Maximum smoothing time. Higher values consume more RAM. + // Increase smoothing time to reduce jerky motion, ghosting and noises. + #define FTM_SMOOTHING_TIME_X 0.00f // (s) Smoothing time for X axis. Zero means disabled. + #define FTM_SMOOTHING_TIME_Y 0.00f // (s) Smoothing time for Y axis + #define FTM_SMOOTHING_TIME_Z 0.00f // (s) Smoothing time for Z axis + #define FTM_SMOOTHING_TIME_E 0.02f // (s) Smoothing time for E axis. Prevents noise/skipping from LA by + // smoothing acceleration peaks, which may also smooth curved surfaces. + #endif + + #define FTM_TRAJECTORY_TYPE TRAPEZOIDAL // Block acceleration profile (TRAPEZOIDAL, POLY5, POLY6) + // TRAPEZOIDAL: Continuous Velocity. Max acceleration is respected. + // POLY5: Like POLY6 with 1.5x but cpu cheaper. + // POLY6: Continuous Acceleration (aka S_CURVE). + // POLY trajectories not only reduce resonances without rounding corners, but also + // reduce extruder strain due to linear advance. + + #define FTM_POLY6_ACCELERATION_OVERSHOOT 1.875f // Max acceleration overshoot factor for POLY6 (1.25 to 1.875) /** * Advanced configuration */ - #define FTM_UNIFIED_BWS // DON'T DISABLE unless you use Ulendo FBS (not implemented) + #define FTM_UNIFIED_BWS // DON'T DISABLE unless you use Ulendo FBS (not implemented) #if ENABLED(FTM_UNIFIED_BWS) - #define FTM_BW_SIZE 100 // Unified Window and Batch size with a ratio of 2 + #define FTM_BW_SIZE 100 // Unified Window and Batch size with a ratio of 2 #else - #define FTM_WINDOW_SIZE 200 // Custom Window size for trajectory generation needed by Ulendo FBS - #define FTM_BATCH_SIZE 100 // Custom Batch size for trajectory generation needed by Ulendo FBS + #define FTM_WINDOW_SIZE 200 // Custom Window size for trajectory generation needed by Ulendo FBS + #define FTM_BATCH_SIZE 100 // Custom Batch size for trajectory generation needed by Ulendo FBS #endif - #define FTM_FS 1000 // (Hz) Frequency for trajectory generation. (Reciprocal of FTM_TS) - #define FTM_TS 0.001f // (s) Time step for trajectory generation. (Reciprocal of FTM_FS) + #define FTM_FS 1000 // (Hz) Frequency for trajectory generation. (Reciprocal of FTM_TS) #if DISABLED(COREXY) - #define FTM_STEPPER_FS 20000 // (Hz) Frequency for stepper I/O update + #define FTM_STEPPER_FS 20000 // (Hz) Frequency for stepper I/O update // Use this to adjust the time required to consume the command buffer. // Try increasing this value if stepper motion is choppy. - #define FTM_STEPPERCMD_BUFF_SIZE 3000 // Size of the stepper command buffers + #define FTM_STEPPERCMD_BUFF_SIZE 3000 // Size of the stepper command buffers #else // CoreXY motion needs a larger buffer size. These values are based on our testing. @@ -1193,17 +1227,7 @@ #define FTM_STEPPERCMD_BUFF_SIZE 6000 #endif - #define FTM_STEPS_PER_UNIT_TIME (FTM_STEPPER_FS / FTM_FS) // Interpolated stepper commands per unit time - #define FTM_MIN_TICKS ((STEPPER_TIMER_RATE) / (FTM_STEPPER_FS)) // Minimum stepper ticks between steps - - #define FTM_MIN_SHAPE_FREQ 10 // Minimum shaping frequency - #define FTM_RATIO (FTM_FS / FTM_MIN_SHAPE_FREQ) // Factor for use in FTM_ZMAX. DON'T CHANGE. - #define FTM_ZMAX (FTM_RATIO * 2) // Maximum delays for shaping functions (even numbers only!) - // Calculate as: - // ZV : FTM_RATIO / 2 - // ZVD, MZV : FTM_RATIO - // 2HEI : FTM_RATIO * 3 / 2 - // 3HEI : FTM_RATIO * 2 + #define FTM_MIN_SHAPE_FREQ 10 // (Hz) Minimum shaping frequency, lower consumes more RAM #endif // FT_MOTION /** @@ -1853,6 +1877,7 @@ #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. + #define SDSORT_QUICK true // Use Quick Sort as a sorting algorithm. Otherwise use Bubble Sort. #endif // Allow international symbols in long filenames. To display correctly, the @@ -4261,7 +4286,7 @@ //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper // steps per full revolution (motor steps/rev * microstepping) //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. - #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_MICROSTEP // Type of error error correction. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_MICROSTEP // Type of error correction. #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the // printer will attempt to correct the error; errors // smaller than this are ignored to minimize effects of @@ -4693,6 +4718,11 @@ // //#define PINS_DEBUGGING +// +// M265 - I2C Scanner +// +//#define I2C_SCANNER + // Enable Tests that will run at startup and produce a report //#define MARLIN_TEST_BUILD diff --git a/Marlin/Version.h b/Marlin/Version.h index c6b0482653..87d1def5b0 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-09-15" +//#define STRING_DISTRIBUTION_DATE "2025-10-19" /** * The protocol for communication to the host. Protocol indicates communication diff --git a/Marlin/src/HAL/AVR/fastio.cpp b/Marlin/src/HAL/AVR/fastio.cpp index 5c6ef18915..7d46afadcb 100644 --- a/Marlin/src/HAL/AVR/fastio.cpp +++ b/Marlin/src/HAL/AVR/fastio.cpp @@ -241,7 +241,7 @@ uint8_t extDigitalRead(const int8_t pin) { * * DC values -1.0 to 1.0. Negative duty cycle inverts the pulse. */ -uint16_t set_pwm_frequency_hz(const_float_t hz, const float dca, const float dcb, const float dcc) { +uint16_t set_pwm_frequency_hz(const float hz, const float dca, const float dcb, const float dcc) { float count = 0; if (hz > 0 && (dca || dcb || dcc)) { count = float(F_CPU) / hz; // 1x prescaler, TOP for 16MHz base freq. diff --git a/Marlin/src/HAL/ESP32/timers.cpp b/Marlin/src/HAL/ESP32/timers.cpp index 743ed65f13..a2996a860f 100644 --- a/Marlin/src/HAL/ESP32/timers.cpp +++ b/Marlin/src/HAL/ESP32/timers.cpp @@ -78,8 +78,8 @@ void IRAM_ATTR timer_isr(void *para) { /** * Enable and initialize the timer - * @param timer_num timer number to initialize - * @param frequency frequency of the timer + * @param timer_num timer number to initialize + * @param frequency frequency of the timer */ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { const tTimerConfig timer = timer_config[timer_num]; diff --git a/Marlin/src/HAL/HC32/Servo.h b/Marlin/src/HAL/HC32/Servo.h index db2f60d190..0a9715494c 100644 --- a/Marlin/src/HAL/HC32/Servo.h +++ b/Marlin/src/HAL/HC32/Servo.h @@ -37,9 +37,9 @@ public: MarlinServo(); /** - * @brief attach the pin to the servo, set pin mode, return channel number - * @param pin pin to attach to - * @return channel number, -1 if failed + * @brief attach the pin to the servo, set pin mode, return channel number + * @param pin pin to attach to + * @return channel number, -1 if failed */ int8_t attach(const pin_t apin); diff --git a/Marlin/src/HAL/LPC1768/inc/Conditionals_post.h b/Marlin/src/HAL/LPC1768/inc/Conditionals_post.h index 0b03cb2aea..a1b4dd5099 100644 --- a/Marlin/src/HAL/LPC1768/inc/Conditionals_post.h +++ b/Marlin/src/HAL/LPC1768/inc/Conditionals_post.h @@ -29,6 +29,6 @@ // LPC1768 boards seem to lose steps when saving to EEPROM during print (issue #20785) // TODO: Which other boards are incompatible? -#if defined(MCU_LPC1768) && ENABLED(FLASH_EEPROM_EMULATION) && PRINTCOUNTER_SAVE_INTERVAL > 0 +#if ALL(MCU_LPC1768, FLASH_EEPROM_EMULATION) && PRINTCOUNTER_SAVE_INTERVAL > 0 #define PRINTCOUNTER_SYNC #endif diff --git a/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.c b/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.c index 466fc80203..51ad7e095b 100644 --- a/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.c +++ b/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.c @@ -27,7 +27,7 @@ * * Couldn't just call exact copies because the overhead killed the LCD update speed * With an intermediate level the softspi was running in the 10-20kHz range which - * resulted in using about about 25% of the CPU's time. + * resulted in using about 25% of the CPU's time. */ #ifdef TARGET_LPC1768 diff --git a/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.h b/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.h index d60d93dadd..45e0610fb1 100644 --- a/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.h +++ b/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.h @@ -28,7 +28,7 @@ * * Couldn't just call exact copies because the overhead killed the LCD update speed * With an intermediate level the softspi was running in the 10-20kHz range which - * resulted in using about about 25% of the CPU's time. + * resulted in using about 25% of the CPU's time. */ void u8g_SetPinOutput(uint8_t internal_pin_number); diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp index 3566528079..9cb33694a3 100644 --- a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp +++ b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp @@ -27,7 +27,7 @@ * * Couldn't just call exact copies because the overhead killed the LCD update speed * With an intermediate level the softspi was running in the 10-20kHz range which - * resulted in using about about 25% of the CPU's time. + * resulted in using about 25% of the CPU's time. */ #ifdef __PLAT_NATIVE_SIM__ diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h index 39af4d7e68..ab73635d28 100644 --- a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h +++ b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h @@ -28,7 +28,7 @@ * * Couldn't just call exact copies because the overhead killed the LCD update speed * With an intermediate level the softspi was running in the 10-20kHz range which - * resulted in using about about 25% of the CPU's time. + * resulted in using about 25% of the CPU's time. */ #ifdef __cplusplus diff --git a/Marlin/src/HAL/SAMD21/u8g/LCD_pin_routines.c b/Marlin/src/HAL/SAMD21/u8g/LCD_pin_routines.c index f9f77825f6..b2079fef9b 100644 --- a/Marlin/src/HAL/SAMD21/u8g/LCD_pin_routines.c +++ b/Marlin/src/HAL/SAMD21/u8g/LCD_pin_routines.c @@ -32,7 +32,7 @@ * * Couldn't just call exact copies because the overhead killed the LCD update speed * With an intermediate level the softspi was running in the 10-20kHz range which - * resulted in using about about 25% of the CPU's time. + * resulted in using about 25% of the CPU's time. */ #ifdef __SAMD21__ diff --git a/Marlin/src/HAL/SAMD21/u8g/LCD_pin_routines.h b/Marlin/src/HAL/SAMD21/u8g/LCD_pin_routines.h index 92626552b0..a4bf2800fe 100644 --- a/Marlin/src/HAL/SAMD21/u8g/LCD_pin_routines.h +++ b/Marlin/src/HAL/SAMD21/u8g/LCD_pin_routines.h @@ -33,7 +33,7 @@ * * Couldn't just call exact copies because the overhead killed the LCD update speed * With an intermediate level the softspi was running in the 10-20kHz range which - * resulted in using about about 25% of the CPU's time. + * resulted in using about 25% of the CPU's time. */ void u8g_SetPinOutput(uint8_t internal_pin_number); diff --git a/Marlin/src/HAL/STM32/Servo.cpp b/Marlin/src/HAL/STM32/Servo.cpp index 4f026ffc6d..eb535b1eb1 100644 --- a/Marlin/src/HAL/STM32/Servo.cpp +++ b/Marlin/src/HAL/STM32/Servo.cpp @@ -39,8 +39,8 @@ static_assert(COUNT(servoDelay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM static uint32_t servo_interrupt_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), TIM_IRQ_PRIO, TIM_IRQ_SUBPRIO); // This must be called after the STM32 Servo class has initialized the timer. -// It may only be needed after the first call to attach(), but it is possible -// that is is necessary after every detach() call. To be safe this is currently +// It may only be needed after the first call to attach(), but it's possible +// that this is needed after every detach() call. To be safe this is currently // called after every call to attach(). static void fixServoTimerInterruptPriority() { NVIC_SetPriority(getTimerUpIrq(TIMER_SERVO), servo_interrupt_priority); diff --git a/Marlin/src/HAL/STM32/inc/Conditionals_post.h b/Marlin/src/HAL/STM32/inc/Conditionals_post.h index 6c97a635b3..8d72e720c1 100644 --- a/Marlin/src/HAL/STM32/inc/Conditionals_post.h +++ b/Marlin/src/HAL/STM32/inc/Conditionals_post.h @@ -29,6 +29,6 @@ #endif // Some STM32F4 boards may lose steps when saving to EEPROM during print (PR #17946) -#if defined(STM32F4xx) && ENABLED(FLASH_EEPROM_EMULATION) && PRINTCOUNTER_SAVE_INTERVAL > 0 +#if ALL(STM32F4xx, FLASH_EEPROM_EMULATION) && PRINTCOUNTER_SAVE_INTERVAL > 0 #define PRINTCOUNTER_SYNC #endif diff --git a/Marlin/src/HAL/STM32/tft/tft_fsmc.cpp b/Marlin/src/HAL/STM32/tft/tft_fsmc.cpp index bb011ec6f4..faf7d2b048 100644 --- a/Marlin/src/HAL/STM32/tft/tft_fsmc.cpp +++ b/Marlin/src/HAL/STM32/tft/tft_fsmc.cpp @@ -132,6 +132,9 @@ void TFT_FSMC::init() { DMAtx.Init.Priority = DMA_PRIORITY_HIGH; LCD = (LCD_CONTROLLER_TypeDef *)controllerAddress; + + DMAtx.Init.PeriphInc = DMA_PINC_DISABLE; + HAL_DMA_Init(&DMAtx); } uint32_t TFT_FSMC::getID() { @@ -179,15 +182,19 @@ void TFT_FSMC::abort() { } void TFT_FSMC::transmitDMA(uint32_t memoryIncrease, uint16_t *data, uint16_t count) { - DMAtx.Init.PeriphInc = memoryIncrease; - HAL_DMA_Init(&DMAtx); + if (DMAtx.Init.PeriphInc != memoryIncrease) { + DMAtx.Init.PeriphInc = memoryIncrease; + HAL_DMA_Init(&DMAtx); + } HAL_DMA_Start(&DMAtx, (uint32_t)data, (uint32_t)&(LCD->RAM), count); TERN_(TFT_SHARED_IO, while (isBusy())); } void TFT_FSMC::transmit(uint32_t memoryIncrease, uint16_t *data, uint16_t count) { - DMAtx.Init.PeriphInc = memoryIncrease; - HAL_DMA_Init(&DMAtx); + if (DMAtx.Init.PeriphInc != memoryIncrease) { + DMAtx.Init.PeriphInc = memoryIncrease; + HAL_DMA_Init(&DMAtx); + } dataTransferBegin(); HAL_DMA_Start(&DMAtx, (uint32_t)data, (uint32_t)&(LCD->RAM), count); HAL_DMA_PollForTransfer(&DMAtx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY); diff --git a/Marlin/src/HAL/STM32/u8g/LCD_defines.h b/Marlin/src/HAL/STM32/u8g/LCD_defines.h index 59b2b8839a..96f73002a5 100644 --- a/Marlin/src/HAL/STM32/u8g/LCD_defines.h +++ b/Marlin/src/HAL/STM32/u8g/LCD_defines.h @@ -30,3 +30,6 @@ uint8_t u8g_com_HAL_STM32_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, vo uint8_t u8g_com_stm32duino_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); // See U8glib-HAL #define U8G_COM_HAL_HW_SPI_FN u8g_com_stm32duino_hw_spi_fn + +uint8_t u8g_com_stm32duino_ssd_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); // u8g_com_stm32duino_ssd_i2c.cpp +#define U8G_COM_SSD_I2C_HAL u8g_com_stm32duino_ssd_i2c_fn diff --git a/Marlin/src/HAL/STM32/u8g/u8g_com_stm32duino_ssd_i2c.cpp b/Marlin/src/HAL/STM32/u8g/u8g_com_stm32duino_ssd_i2c.cpp new file mode 100644 index 0000000000..72abe1a656 --- /dev/null +++ b/Marlin/src/HAL/STM32/u8g/u8g_com_stm32duino_ssd_i2c.cpp @@ -0,0 +1,194 @@ +/** + * 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 . + * + */ + +/** + * 2-Wire I2C COM Driver + * + * Handles both Hardware and Software I2C so any pins can be used as SDA and SLC. + * Wire library is used for Hardware I2C. + * SlowSoftWire is used for Software I2C. + * + * Wire / SoftWire library selection can be done automatically at runtime. + * + * SDA and SLC pins must be named DOGLCD_SDA_PIN, DOGLCD_SCL_PIN to distinguish + * from other I2C devices (e.g., EEPROM) that use I2C_SDA_PIN, I2C_SLC_PIN. + */ +#ifdef ARDUINO_ARCH_STM32 + +#include "../../../inc/MarlinConfig.h" + +#if HAS_U8GLIB_I2C_OLED + +#include + +#if ENABLED(U8G_USES_HW_I2C) + #include + #ifndef MASTER_ADDRESS + #define MASTER_ADDRESS 0x01 + #endif +#endif + +#if ENABLED(U8G_USES_SW_I2C) + #include + #include +#endif + +/** + * BUFFER_LENGTH is defined in libraries\Wire\utility\WireBase.h + * Default value is 32 + * Increase this value to 144 to send U8G_COM_MSG_WRITE_SEQ in single block + */ +#ifndef BUFFER_LENGTH + #define BUFFER_LENGTH 32 +#endif +#if BUFFER_LENGTH > 144 + #error "BUFFER_LENGTH should not be greater than 144." +#endif +#define I2C_MAX_LENGTH (BUFFER_LENGTH - 1) + +uint8_t u8g_com_stm32duino_ssd_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { + // Hardware I2C flag + #ifdef COMPILE_TIME_I2C_IS_HARDWARE + constexpr bool isHardI2C = ENABLED(COMPILE_TIME_I2C_IS_HARDWARE); + #else + static bool isHardI2C = false; + static bool i2c_initialized = false; // Flag to only run init/linking code once + if (!i2c_initialized) { // Init runtime linkages + i2c_initialized = true; // Only do this once + I2C_TypeDef *i2cInstance1 = (I2C_TypeDef *)pinmap_peripheral(digitalPinToPinName(DOGLCD_SDA_PIN), PinMap_I2C_SDA); + I2C_TypeDef *i2cInstance2 = (I2C_TypeDef *)pinmap_peripheral(digitalPinToPinName(DOGLCD_SCL_PIN), PinMap_I2C_SCL); + isHardI2C = (i2cInstance1 && (i2cInstance1 == i2cInstance2)); // Found hardware I2C controller + } + #endif + + static uint8_t msgInitCount = 0; // Ignore all messages until 2nd U8G_COM_MSG_INIT + if (msgInitCount) { + if (msg == U8G_COM_MSG_INIT) msgInitCount--; + if (msgInitCount) return -1; + } + + static uint8_t control; + if (isHardI2C) { // Found hardware I2C controller + #if ENABLED(U8G_USES_HW_I2C) + static TwoWire wire2; // A TwoWire object for use below + switch (msg) { + case U8G_COM_MSG_INIT: + wire2.setClock(400000); + wire2.setSCL(DOGLCD_SCL_PIN); + wire2.setSDA(DOGLCD_SDA_PIN); + wire2.begin(MASTER_ADDRESS, 0); // Start as master + break; + + case U8G_COM_MSG_ADDRESS: // Define cmd (arg_val = 0) or data mode (arg_val = 1) + control = arg_val ? 0x40 : 0x00; + break; + + case U8G_COM_MSG_WRITE_BYTE: + wire2.beginTransmission(0x3C); + wire2.write(control); + wire2.write(arg_val); + wire2.endTransmission(); + break; + + case U8G_COM_MSG_WRITE_SEQ: { + uint8_t* dataptr = (uint8_t*)arg_ptr; + #ifdef I2C_MAX_LENGTH + while (arg_val > 0) { + wire2.beginTransmission(0x3C); + wire2.write(control); + if (arg_val <= I2C_MAX_LENGTH) { + wire2.write(dataptr, arg_val); + arg_val = 0; + } + else { + wire2.write(dataptr, I2C_MAX_LENGTH); + arg_val -= I2C_MAX_LENGTH; + dataptr += I2C_MAX_LENGTH; + } + wire2.endTransmission(); + } + #else + wire2.beginTransmission(0x3C); + wire2.write(control); + wire2.write(dataptr, arg_val); + wire2.endTransmission(); + #endif // I2C_MAX_LENGTH + break; + } + } + #endif // U8G_USES_HW_I2C + } + else { // Software I2C + #if ENABLED(U8G_USES_SW_I2C) + static SlowSoftWire sWire = SlowSoftWire(DOGLCD_SDA_PIN, DOGLCD_SCL_PIN); + + switch (msg) { + case U8G_COM_MSG_INIT: + sWire.setClock(400000); + sWire.begin(); // Start as master + break; + + case U8G_COM_MSG_ADDRESS: // Define cmd (arg_val = 0) or data mode (arg_val = 1) + control = arg_val ? 0x40 : 0x00; + break; + + case U8G_COM_MSG_WRITE_BYTE: + sWire.beginTransmission((uint8_t)0x3C); + sWire.write((uint8_t)control); + sWire.write((uint8_t)arg_val); + sWire.endTransmission(); + break; + + case U8G_COM_MSG_WRITE_SEQ: { + uint8_t* dataptr = (uint8_t*)arg_ptr; + #ifdef I2C_MAX_LENGTH + while (arg_val > 0) { + sWire.beginTransmission((uint8_t)0x3C); + sWire.write((uint8_t)control); + if (arg_val <= I2C_MAX_LENGTH) { + sWire.write((const uint8_t *)dataptr, (size_t)arg_val); + arg_val = 0; + } + else { + sWire.write((const uint8_t *)dataptr, I2C_MAX_LENGTH); + arg_val -= I2C_MAX_LENGTH; + dataptr += I2C_MAX_LENGTH; + } + sWire.endTransmission(); + } + #else + sWire.beginTransmission((uint8_t)0x3C); + sWire.write((uint8_t)control); + sWire.write((const uint8_t *)dataptr, (size_t)arg_val); + sWire.endTransmission(); + #endif // I2C_MAX_LENGTH + break; + } + } + #endif // U8G_USES_SW_I2C + } + + return 1; +} + +#endif // HAS_U8GLIB_I2C_OLED +#endif // ARDUINO_ARCH_STM32 diff --git a/Marlin/src/HAL/STM32F1/HAL_N32.h b/Marlin/src/HAL/STM32F1/HAL_N32.h index 8b47ef4b96..719368f6f1 100644 --- a/Marlin/src/HAL/STM32F1/HAL_N32.h +++ b/Marlin/src/HAL/STM32F1/HAL_N32.h @@ -800,7 +800,7 @@ void ADC_StartCalibration(ADC_Module* NS_ADCx); void ADC_EnableDMA(ADC_Module* NS_ADCx, uint32_t Cmd); /**================================================================ - * Configure ADC interrupt enable enable + * Configure ADC interrupt enable ================================================================*/ void ADC_ConfigInt(ADC_Module* NS_ADCx, uint16_t ADC_IT, uint32_t Cmd); diff --git a/Marlin/src/HAL/STM32F1/MinSerial.cpp b/Marlin/src/HAL/STM32F1/MinSerial.cpp index 8fb9133254..0d9a611d7e 100644 --- a/Marlin/src/HAL/STM32F1/MinSerial.cpp +++ b/Marlin/src/HAL/STM32F1/MinSerial.cpp @@ -92,7 +92,7 @@ void install_min_serial() { HAL_min_serial_out = &TX; } -#if DISABLED(DYNAMIC_VECTORTABLE) && DISABLED(STM32F0xx) // Cortex M0 can't branch to a symbol that's too far, so we have a specific hack for them +#if NONE(DYNAMIC_VECTORTABLE, STM32F0xx) // Cortex M0 can't branch to a symbol that's too far, so we have a specific hack for them extern "C" { __attribute__((naked)) void JumpHandler_ASM() { __asm__ __volatile__ ( diff --git a/Marlin/src/HAL/STM32F1/tft/tft_fsmc.cpp b/Marlin/src/HAL/STM32F1/tft/tft_fsmc.cpp index 51f70b9365..73b0e7efb9 100644 --- a/Marlin/src/HAL/STM32F1/tft/tft_fsmc.cpp +++ b/Marlin/src/HAL/STM32F1/tft/tft_fsmc.cpp @@ -86,7 +86,6 @@ __attribute__((always_inline)) __STATIC_INLINE void __DSB() { #define FSMC_ADDRESS_SETUP_TIME 15 // AddressSetupTime #define FSMC_DATA_SETUP_TIME 15 // DataSetupTime -static uint8_t fsmcInit = 0; void TFT_FSMC::init() { uint8_t cs = FSMC_CS_PIN, rs = FSMC_RS_PIN; uint32_t controllerAddress; @@ -99,8 +98,9 @@ void TFT_FSMC::init() { struct fsmc_nor_psram_reg_map* fsmcPsramRegion; + static bool fsmcInit = false; if (fsmcInit) return; - fsmcInit = 1; + fsmcInit = true; switch (cs) { case FSMC_CS_NE1: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION1; fsmcPsramRegion = FSMC_NOR_PSRAM1_BASE; break; diff --git a/Marlin/src/HAL/shared/backtrace/unwarm_arm.cpp b/Marlin/src/HAL/shared/backtrace/unwarm_arm.cpp index decf74e6e9..e6064f65da 100644 --- a/Marlin/src/HAL/shared/backtrace/unwarm_arm.cpp +++ b/Marlin/src/HAL/shared/backtrace/unwarm_arm.cpp @@ -414,7 +414,7 @@ UnwResult UnwStartArm(UnwState * const state) { /* S indicates that banked registers (untracked) are used, unless * this is a load including the PC when the S-bit indicates that - * that CPSR is loaded from SPSR (also untracked, but ignored). + * CPSR is loaded from SPSR (also untracked, but ignored). */ if (S && (!L || (regList & (0x01 << 15)) == 0)) { UnwPrintd1("\nError:S-bit set requiring banked registers\n"); @@ -431,7 +431,7 @@ UnwResult UnwStartArm(UnwState * const state) { /* Check if ascending or descending. * Registers are loaded/stored in order of address. - * i.e. r0 is at the lowest address, r15 at the highest. + * i.e., r0 is at the lowest address, r15 at the highest. */ r = U ? 0 : 15; do { diff --git a/Marlin/src/core/boards.h b/Marlin/src/core/boards.h index 0ee4b75cfa..1b95b2ba52 100644 --- a/Marlin/src/core/boards.h +++ b/Marlin/src/core/boards.h @@ -28,6 +28,7 @@ #include "macros.h" +#define BOARD_ERROR -2 #define BOARD_UNKNOWN -1 // @@ -175,16 +176,17 @@ #define BOARD_GT2560_V41B 1322 // Geeetech GT2560 V4.1B for A10(M/T/D) #define BOARD_EINSTART_S 1323 // Einstart retrofit #define BOARD_WANHAO_ONEPLUS 1324 // Wanhao 0ne+ i3 Mini -#define BOARD_OVERLORD 1325 // Overlord/Overlord Pro -#define BOARD_HJC2560C_REV1 1326 // ADIMLab Gantry v1 -#define BOARD_HJC2560C_REV2 1327 // ADIMLab Gantry v2 -#define BOARD_LEAPFROG_XEED2015 1328 // Leapfrog Xeed 2015 -#define BOARD_PICA_REVB 1329 // PICA Shield (original version) -#define BOARD_PICA 1330 // PICA Shield (rev C or later) -#define BOARD_INTAMSYS40 1331 // Intamsys 4.0 (Funmat HT) -#define BOARD_MALYAN_M180 1332 // Malyan M180 Mainboard Version 2 (no display function, direct G-code only) -#define BOARD_PROTONEER_CNC_SHIELD_V3 1333 // Mega controller & Protoneer CNC Shield V3.00 -#define BOARD_WEEDO_62A 1334 // WEEDO 62A board (TINA2, Monoprice Cadet, etc.) +#define BOARD_WANHAO_D9 1325 // Wanhao D9 MK2 +#define BOARD_OVERLORD 1326 // Overlord/Overlord Pro +#define BOARD_HJC2560C_REV1 1327 // ADIMLab Gantry v1 +#define BOARD_HJC2560C_REV2 1328 // ADIMLab Gantry v2 +#define BOARD_LEAPFROG_XEED2015 1329 // Leapfrog Xeed 2015 +#define BOARD_PICA_REVB 1330 // PICA Shield (original version) +#define BOARD_PICA 1331 // PICA Shield (rev C or later) +#define BOARD_INTAMSYS40 1332 // Intamsys 4.0 (Funmat HT) +#define BOARD_MALYAN_M180 1333 // Malyan M180 Mainboard Version 2 (no display function, direct G-code only) +#define BOARD_PROTONEER_CNC_SHIELD_V3 1334 // Mega controller & Protoneer CNC Shield V3.00 +#define BOARD_WEEDO_62A 1335 // WEEDO 62A board (TINA2, Monoprice Cadet, etc.) // // ATmega1281, ATmega2561 diff --git a/Marlin/src/core/language.h b/Marlin/src/core/language.h index 3a50fcdc6b..f2860ae7d4 100644 --- a/Marlin/src/core/language.h +++ b/Marlin/src/core/language.h @@ -358,6 +358,21 @@ #define STR_Z2 STR_C "2" #define STR_Z3 STR_C "3" #define STR_Z4 STR_C "4" +#if CORE_IS_XY || CORE_IS_XZ + #define STEPPER_A_NAME 'A' +#else + #define STEPPER_A_NAME 'X' +#endif +#if CORE_IS_XY || CORE_IS_YZ + #define STEPPER_B_NAME 'B' +#else + #define STEPPER_B_NAME 'Y' +#endif +#if CORE_IS_XZ || CORE_IS_YZ + #define STEPPER_C_NAME 'C' +#else + #define STEPPER_C_NAME 'Z' +#endif // // Endstop Names used by Endstops::report_states diff --git a/Marlin/src/core/macros.h b/Marlin/src/core/macros.h index fd6296707f..d66450f758 100644 --- a/Marlin/src/core/macros.h +++ b/Marlin/src/core/macros.h @@ -58,6 +58,7 @@ // Macros to make a string from a macro #define STRINGIFY_(M) #M #define STRINGIFY(M) STRINGIFY_(M) +#define CHARIFY(M) STRINGIFY(M)[0] #define A(CODE) " " CODE "\n\t" #define L(CODE) CODE ":\n\t" diff --git a/Marlin/src/core/serial.cpp b/Marlin/src/core/serial.cpp index 7ac2a5084c..852cfc77f6 100644 --- a/Marlin/src/core/serial.cpp +++ b/Marlin/src/core/serial.cpp @@ -99,7 +99,7 @@ void SERIAL_WARN_START() { SERIAL_ECHO(F("Warning:")); } void SERIAL_ECHO_SP(uint8_t count) { count *= (PROPORTIONAL_FONT_RATIO); while (count--) SERIAL_CHAR(' '); } -void serial_offset(const_float_t v, const uint8_t sp/*=0*/) { +void serial_offset(const float v, const uint8_t sp/*=0*/) { if (v == 0 && sp == 1) SERIAL_CHAR(' '); else if (v > 0 || (v == 0 && sp == 2)) @@ -121,7 +121,7 @@ void print_bin(uint16_t val) { } } -void _print_xyz(NUM_AXIS_ARGS_(const_float_t) FSTR_P const prefix) { +void _print_xyz(NUM_AXIS_ARGS_(const float) FSTR_P const prefix) { if (prefix) SERIAL_ECHO(prefix); #if NUM_AXES SERIAL_ECHOPGM_P(NUM_AXIS_PAIRED_LIST( @@ -132,12 +132,12 @@ void _print_xyz(NUM_AXIS_ARGS_(const_float_t) FSTR_P const prefix) { #endif } -void print_xyz(NUM_AXIS_ARGS_(const_float_t) FSTR_P const prefix/*=nullptr*/, FSTR_P const suffix/*=nullptr*/) { +void print_xyz(NUM_AXIS_ARGS_(const float) FSTR_P const prefix/*=nullptr*/, FSTR_P const suffix/*=nullptr*/) { _print_xyz(NUM_AXIS_LIST_(x, y, z, i, j, k, u, v, w) prefix); if (suffix) SERIAL_ECHO(suffix); else SERIAL_EOL(); } -void print_xyze(LOGICAL_AXIS_ARGS_(const_float_t) FSTR_P const prefix/*=nullptr*/, FSTR_P const suffix/*=nullptr*/) { +void print_xyze(LOGICAL_AXIS_ARGS_(const float) FSTR_P const prefix/*=nullptr*/, FSTR_P const suffix/*=nullptr*/) { _print_xyz(NUM_AXIS_LIST_(x, y, z, i, j, k, u, v, w) prefix); #if HAS_EXTRUDERS SERIAL_ECHOPGM_P(SP_E_STR, e); diff --git a/Marlin/src/core/serial.h b/Marlin/src/core/serial.h index a1e539b9c7..6c73d72a22 100644 --- a/Marlin/src/core/serial.h +++ b/Marlin/src/core/serial.h @@ -236,16 +236,16 @@ void SERIAL_ECHO_SP(uint8_t count); inline FSTR_P const ON_OFF(const bool onoff) { return onoff ? F("ON") : F("OFF"); } inline FSTR_P const TRUE_FALSE(const bool tf) { return tf ? F("true") : F("false"); } -void serial_offset(const_float_t v, const uint8_t sp=0); // For v==0 draw space (sp==1) or plus (sp==2) +void serial_offset(const float v, const uint8_t sp=0); // For v==0 draw space (sp==1) or plus (sp==2) void print_bin(const uint16_t val); -void print_xyz(NUM_AXIS_ARGS_(const_float_t) FSTR_P const prefix=nullptr, FSTR_P const suffix=nullptr); +void print_xyz(NUM_AXIS_ARGS_(const float) FSTR_P const prefix=nullptr, FSTR_P const suffix=nullptr); inline void print_xyz(const xyz_pos_t &xyz, FSTR_P const prefix=nullptr, FSTR_P const suffix=nullptr) { print_xyz(NUM_AXIS_ELEM_(xyz) prefix, suffix); } -void print_xyze(LOGICAL_AXIS_ARGS_(const_float_t) FSTR_P const prefix=nullptr, FSTR_P const suffix=nullptr); +void print_xyze(LOGICAL_AXIS_ARGS_(const float) FSTR_P const prefix=nullptr, FSTR_P const suffix=nullptr); inline void print_xyze(const xyze_pos_t &xyze, FSTR_P const prefix=nullptr, FSTR_P const suffix=nullptr) { print_xyze(LOGICAL_AXIS_ELEM_LC_(xyze) prefix, suffix); } diff --git a/Marlin/src/core/types.h b/Marlin/src/core/types.h index 18e4c49264..99a4e31a5d 100644 --- a/Marlin/src/core/types.h +++ b/Marlin/src/core/types.h @@ -167,6 +167,21 @@ template struct IF { typedef L type; }; #define GANG_ITEM_E(N) #endif +// Emitters for code that only cares about XYZE and not IJKUVW +#define CARTES_COUNT TERN(HAS_EXTRUDERS, INCREMENT(XYZ_COUNT), XYZ_COUNT) +#define CARTES_LIST(x,y,z,e) XYZ_LIST(x,y,z) LIST_ITEM_E(e) +#define CARTES_PAIRED_LIST(V...) LIST_N(DOUBLE(CARTES_COUNT), V) +#define CARTES_ARRAY(x,y,z,e) { CARTES_LIST(x,y,z,e) } +#define CARTES_CODE(x,y,z,e) XYZ_CODE(x,y,z) CODE_ITEM_E(e) +#define CARTES_GANG(x,y,z,e) XYZ_GANG(x,y,z) GANG_ITEM_E(e) +#define CARTES_AXIS_NAMES CARTES_LIST(X,Y,Z,E) +#define CARTES_MAP(F) MAP(F, CARTES_AXIS_NAMES) +#if CARTES_COUNT + #define CARTES_COMMA , +#else + #define CARTES_COMMA +#endif + #define AXIS_COLLISION(L) (AXIS4_NAME == L || AXIS5_NAME == L || AXIS6_NAME == L || AXIS7_NAME == L || AXIS8_NAME == L || AXIS9_NAME == L) // Helpers @@ -363,17 +378,6 @@ typedef uint16_t raw_adc_t; typedef int16_t celsius_t; typedef float celsius_float_t; -// -// On AVR pointers are only 2 bytes so use 'const float &' for 'const float' -// -#ifdef __AVR__ - typedef const float & const_float_t; -#else - typedef const float const_float_t; -#endif -typedef const_float_t const_feedRate_t; -typedef const_float_t const_celsius_float_t; - // Type large enough to count leveling grid points typedef IF 255)), uint16_t, uint8_t>::type grid_count_t; @@ -382,7 +386,7 @@ typedef IF 255)), uint16_t, uint8_t>::ty #define MMS_TO_MMM(MM_S) (static_cast(MM_S) * 60.0f) // Packaged character for C macro and other usage -typedef struct SerialChar { char c; SerialChar(char n) : c(n) { } } serial_char_t; +typedef struct SerialChar { char c; SerialChar(const char n) : c(n) { } } serial_char_t; #define C(c) serial_char_t(c) // Packaged types: float with precision and/or width; a repeated space/character diff --git a/Marlin/src/feature/babystep.cpp b/Marlin/src/feature/babystep.cpp index 014ccea1af..91b3c7f403 100644 --- a/Marlin/src/feature/babystep.cpp +++ b/Marlin/src/feature/babystep.cpp @@ -54,12 +54,12 @@ void Babystep::step_axis(const AxisEnum axis) { } } -void Babystep::add_mm(const AxisEnum axis, const_float_t mm) { +void Babystep::add_mm(const AxisEnum axis, const float mm) { add_steps(axis, mm * planner.settings.axis_steps_per_mm[axis]); } #if ENABLED(BD_SENSOR) - void Babystep::set_mm(const AxisEnum axis, const_float_t mm) { + void Babystep::set_mm(const AxisEnum axis, const float mm) { //if (DISABLED(BABYSTEP_WITHOUT_HOMING) && axis_should_home(axis)) return; const int16_t distance = mm * planner.settings.axis_steps_per_mm[axis]; accum = distance; // Count up babysteps for the UI diff --git a/Marlin/src/feature/babystep.h b/Marlin/src/feature/babystep.h index 666a0ee8c5..da330672b2 100644 --- a/Marlin/src/feature/babystep.h +++ b/Marlin/src/feature/babystep.h @@ -61,7 +61,7 @@ public: static bool can_babystep(const AxisEnum axis); static void add_steps(const AxisEnum axis, const int16_t distance); - static void add_mm(const AxisEnum axis, const_float_t mm); + static void add_mm(const AxisEnum axis, const float mm); #if ENABLED(EP_BABYSTEPPING) // Step Z for M293 / M294 @@ -79,7 +79,7 @@ public: #endif // EP_BABYSTEPPING #if ENABLED(BD_SENSOR) - static void set_mm(const AxisEnum axis, const_float_t mm); + static void set_mm(const AxisEnum axis, const float mm); #endif static bool has_steps() { diff --git a/Marlin/src/feature/backlash.h b/Marlin/src/feature/backlash.h index 593e51b9d0..b4790cb161 100644 --- a/Marlin/src/feature/backlash.h +++ b/Marlin/src/feature/backlash.h @@ -81,10 +81,10 @@ public: static void set_correction(const float v) { set_correction_uint8(_MAX(0, _MIN(1.0, v)) * all_on + 0.5f); } static float get_correction() { return float(get_correction_uint8()) / all_on; } static void set_distance_mm(const AxisEnum axis, const float v); - static float get_distance_mm(const AxisEnum axis) {return distance_mm[axis];} + static float get_distance_mm(const AxisEnum axis) { return distance_mm[axis]; } #ifdef BACKLASH_SMOOTHING_MM static void set_smoothing_mm(const float v); - static float get_smoothing_mm() {return smoothing_mm;} + static float get_smoothing_mm() { return smoothing_mm; } #endif #endif diff --git a/Marlin/src/feature/bedlevel/abl/bbl.cpp b/Marlin/src/feature/bedlevel/abl/bbl.cpp index 14c4bd24bc..918b06d2b4 100644 --- a/Marlin/src/feature/bedlevel/abl/bbl.cpp +++ b/Marlin/src/feature/bedlevel/abl/bbl.cpp @@ -229,7 +229,7 @@ void LevelingBilinear::print_leveling_grid(const bed_mesh_t* _z_values/*=nullptr ) * 0.5f; } - float LevelingBilinear::virt_2cmr(const uint8_t x, const uint8_t y, const_float_t tx, const_float_t ty) { + float LevelingBilinear::virt_2cmr(const uint8_t x, const uint8_t y, const float tx, const float ty) { float row[4], column[4]; for (uint8_t i = 0; i < 4; ++i) { for (uint8_t j = 0; j < 4; ++j) { @@ -369,7 +369,7 @@ float LevelingBilinear::get_z_correction(const xy_pos_t &raw) { * Prepare a bilinear-leveled linear move on Cartesian, * splitting the move where it crosses grid borders. */ - void LevelingBilinear::line_to_destination(const_feedRate_t scaled_fr_mm_s, uint16_t x_splits, uint16_t y_splits) { + void LevelingBilinear::line_to_destination(const feedRate_t scaled_fr_mm_s, uint16_t x_splits, uint16_t y_splits) { // Get current and destination cells for this line xy_int_t c1 { CELL_INDEX(x, current_position.x), CELL_INDEX(y, current_position.y) }, c2 { CELL_INDEX(x, destination.x), CELL_INDEX(y, destination.y) }; diff --git a/Marlin/src/feature/bedlevel/abl/bbl.h b/Marlin/src/feature/bedlevel/abl/bbl.h index ca2e96593f..fb890333dc 100644 --- a/Marlin/src/feature/bedlevel/abl/bbl.h +++ b/Marlin/src/feature/bedlevel/abl/bbl.h @@ -45,7 +45,7 @@ private: static float virt_coord(const uint8_t x, const uint8_t y); static float virt_cmr(const float p[4], const uint8_t i, const float t); - static float virt_2cmr(const uint8_t x, const uint8_t y, const_float_t tx, const_float_t ty); + static float virt_2cmr(const uint8_t x, const uint8_t y, const float tx, const float ty); static void subdivide_mesh(); #endif @@ -63,7 +63,7 @@ public: static constexpr float get_z_offset() { return 0.0f; } #if IS_CARTESIAN && DISABLED(SEGMENT_LEVELED_MOVES) - static void line_to_destination(const_feedRate_t scaled_fr_mm_s, uint16_t x_splits=0xFFFF, uint16_t y_splits=0xFFFF); + static void line_to_destination(const feedRate_t scaled_fr_mm_s, uint16_t x_splits=0xFFFF, uint16_t y_splits=0xFFFF); #endif }; diff --git a/Marlin/src/feature/bedlevel/bedlevel.cpp b/Marlin/src/feature/bedlevel/bedlevel.cpp index 12d620e5af..e479e4c70a 100644 --- a/Marlin/src/feature/bedlevel/bedlevel.cpp +++ b/Marlin/src/feature/bedlevel/bedlevel.cpp @@ -91,7 +91,7 @@ TemporaryBedLevelingState::TemporaryBedLevelingState(const bool enable) : saved( #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - void set_z_fade_height(const_float_t zfh, const bool do_report/*=true*/) { + void set_z_fade_height(const float zfh, const bool do_report/*=true*/) { if (planner.z_fade_height == zfh) return; diff --git a/Marlin/src/feature/bedlevel/bedlevel.h b/Marlin/src/feature/bedlevel/bedlevel.h index ccb9543e72..5bfa2b7faf 100644 --- a/Marlin/src/feature/bedlevel/bedlevel.h +++ b/Marlin/src/feature/bedlevel/bedlevel.h @@ -38,7 +38,7 @@ void set_bed_leveling_enabled(const bool enable=true); void reset_bed_level(); #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - void set_z_fade_height(const_float_t zfh, const bool do_report=true); + void set_z_fade_height(const float zfh, const bool do_report=true); #endif #if ANY(MESH_BED_LEVELING, PROBE_MANUALLY) diff --git a/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp b/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp index 14216ac424..155d34c4df 100644 --- a/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp +++ b/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp @@ -61,7 +61,7 @@ * Prepare a mesh-leveled linear move in a Cartesian setup, * splitting the move where it crosses mesh borders. */ - void mesh_bed_leveling::line_to_destination(const_feedRate_t scaled_fr_mm_s, uint8_t x_splits, uint8_t y_splits) { + void mesh_bed_leveling::line_to_destination(const feedRate_t scaled_fr_mm_s, uint8_t x_splits, uint8_t y_splits) { // Get current and destination cells for this line xy_uint8_t scel = cell_indexes(current_position), ecel = cell_indexes(destination); NOMORE(scel.x, GRID_MAX_CELLS_X - 1); diff --git a/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.h b/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.h index cb4f36cd59..43dabd3adb 100644 --- a/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.h +++ b/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.h @@ -55,7 +55,7 @@ public: static bool mesh_is_valid() { return has_mesh(); } - static void set_z(const int8_t px, const int8_t py, const_float_t z) { z_values[px][py] = z; } + static void set_z(const int8_t px, const int8_t py, const float z) { z_values[px][py] = z; } static void zigzag(const int8_t index, int8_t &px, int8_t &py) { px = index % (GRID_MAX_POINTS_X); @@ -63,7 +63,7 @@ public: if (py & 1) px = (GRID_MAX_POINTS_X) - 1 - px; // Zig zag } - static void set_zigzag_z(const int8_t index, const_float_t z) { + static void set_zigzag_z(const int8_t index, const float z) { int8_t px, py; zigzag(index, px, py); set_z(px, py, z); @@ -72,33 +72,33 @@ public: static float get_mesh_x(const uint8_t i) { return index_to_xpos[i]; } static float get_mesh_y(const uint8_t i) { return index_to_ypos[i]; } - static uint8_t cell_index_x(const_float_t x) { + static uint8_t cell_index_x(const float x) { int8_t cx = (x - (MESH_MIN_X)) * RECIPROCAL(MESH_X_DIST); return constrain(cx, 0, GRID_MAX_CELLS_X - 1); } - static uint8_t cell_index_y(const_float_t y) { + static uint8_t cell_index_y(const float y) { int8_t cy = (y - (MESH_MIN_Y)) * RECIPROCAL(MESH_Y_DIST); return constrain(cy, 0, GRID_MAX_CELLS_Y - 1); } - static xy_uint8_t cell_indexes(const_float_t x, const_float_t y) { + static xy_uint8_t cell_indexes(const float x, const float y) { return { cell_index_x(x), cell_index_y(y) }; } static xy_uint8_t cell_indexes(const xy_pos_t &xy) { return cell_indexes(xy.x, xy.y); } - static int8_t probe_index_x(const_float_t x) { + static int8_t probe_index_x(const float x) { int8_t px = (x - (MESH_MIN_X) + 0.5f * (MESH_X_DIST)) * RECIPROCAL(MESH_X_DIST); return WITHIN(px, 0, (GRID_MAX_POINTS_X) - 1) ? px : -1; } - static int8_t probe_index_y(const_float_t y) { + static int8_t probe_index_y(const float y) { int8_t py = (y - (MESH_MIN_Y) + 0.5f * (MESH_Y_DIST)) * RECIPROCAL(MESH_Y_DIST); return WITHIN(py, 0, (GRID_MAX_POINTS_Y) - 1) ? py : -1; } - static xy_int8_t probe_indexes(const_float_t x, const_float_t y) { + static xy_int8_t probe_indexes(const float x, const float y) { return { probe_index_x(x), probe_index_y(y) }; } static xy_int8_t probe_indexes(const xy_pos_t &xy) { return probe_indexes(xy.x, xy.y); } - static float calc_z0(const_float_t a0, const_float_t a1, const_float_t z1, const_float_t a2, const_float_t z2) { + static float calc_z0(const float a0, const float a1, const float z1, const float a2, const float z2) { const float delta_z = (z2 - z1) / (a2 - a1), delta_a = a0 - a1; return z1 + delta_a * delta_z; @@ -118,7 +118,7 @@ public: } #if IS_CARTESIAN && DISABLED(SEGMENT_LEVELED_MOVES) - static void line_to_destination(const_feedRate_t scaled_fr_mm_s, uint8_t x_splits=0xFF, uint8_t y_splits=0xFF); + static void line_to_destination(const feedRate_t scaled_fr_mm_s, uint8_t x_splits=0xFF, uint8_t y_splits=0xFF); #endif }; diff --git a/Marlin/src/feature/bedlevel/ubl/ubl.cpp b/Marlin/src/feature/bedlevel/ubl/ubl.cpp index 0228bd247e..e1f2ed4c16 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl.cpp @@ -102,7 +102,7 @@ void unified_bed_leveling::invalidate() { set_all_mesh_points_to_value(NAN); } -void unified_bed_leveling::set_all_mesh_points_to_value(const_float_t value) { +void unified_bed_leveling::set_all_mesh_points_to_value(const float value) { GRID_LOOP(x, y) { z_values[x][y] = value; TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, value)); @@ -115,7 +115,7 @@ void unified_bed_leveling::set_all_mesh_points_to_value(const_float_t value) { constexpr int16_t Z_STEPS_NAN = INT16_MAX; void unified_bed_leveling::set_store_from_mesh(const bed_mesh_t &in_values, mesh_store_t &stored_values) { - auto z_to_store = [](const_float_t z) { + auto z_to_store = [](const float z) { if (isnan(z)) return Z_STEPS_NAN; const int32_t z_scaled = TRUNC(z * mesh_store_scaling); if (z_scaled == Z_STEPS_NAN || !WITHIN(z_scaled, INT16_MIN, INT16_MAX)) diff --git a/Marlin/src/feature/bedlevel/ubl/ubl.h b/Marlin/src/feature/bedlevel/ubl/ubl.h index 84ecc3a6c7..f6e9ba0cd9 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl.h +++ b/Marlin/src/feature/bedlevel/ubl/ubl.h @@ -67,15 +67,15 @@ private: static G29_parameters_t param; #if IS_NEWPANEL - static void move_z_with_encoder(const_float_t multiplier); + static void move_z_with_encoder(const float multiplier); static float measure_point_with_encoder(); static float measure_business_card_thickness(); - static void manually_probe_remaining_mesh(const xy_pos_t&, const_float_t, const_float_t, const bool) __O0; + static void manually_probe_remaining_mesh(const xy_pos_t&, const float, const float, const bool) __O0; static void fine_tune_mesh(const xy_pos_t &pos, const bool do_ubl_mesh_map) __O0; #endif static bool G29_parse_parameters() __O0; - static void shift_mesh_height(); + static void shift_mesh_height(const float zoffs); static void probe_entire_mesh(const xy_pos_t &near, const bool do_ubl_mesh_map, const bool stow_probe, const bool do_furthest) __O0; static void tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map); static bool smart_fill_one(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir); @@ -101,13 +101,13 @@ public: static mesh_index_pair find_furthest_invalid_mesh_point() __O0; static void reset(); static void invalidate(); - static void set_all_mesh_points_to_value(const_float_t value); - static void adjust_mesh_to_mean(const bool cflag, const_float_t value); + static void set_all_mesh_points_to_value(const float value); + static void adjust_mesh_to_mean(const bool cflag, const float value); static bool sanity_check(); static void smart_fill_mesh(); static void G29() __O0; // O0 for no optimization - static void smart_fill_wlsf(const_float_t ) __O2; // O2 gives smaller code than Os on A2560 + static void smart_fill_wlsf(const float ) __O2; // O2 gives smaller code than Os on A2560 static int8_t storage_slot; @@ -130,42 +130,42 @@ public: unified_bed_leveling(); - FORCE_INLINE static void set_z(const int8_t px, const int8_t py, const_float_t z) { z_values[px][py] = z; } + FORCE_INLINE static void set_z(const int8_t px, const int8_t py, const float z) { z_values[px][py] = z; } - static int8_t cell_index_x_raw(const_float_t x) { + static int8_t cell_index_x_raw(const float x) { return FLOOR((x - (MESH_MIN_X)) * RECIPROCAL(MESH_X_DIST)); } - static int8_t cell_index_y_raw(const_float_t y) { + static int8_t cell_index_y_raw(const float y) { return FLOOR((y - (MESH_MIN_Y)) * RECIPROCAL(MESH_Y_DIST)); } - static bool cell_index_x_valid(const_float_t x) { + static bool cell_index_x_valid(const float x) { return WITHIN(cell_index_x_raw(x), 0, GRID_MAX_CELLS_X - 1); } - static bool cell_index_y_valid(const_float_t y) { + static bool cell_index_y_valid(const float y) { return WITHIN(cell_index_y_raw(y), 0, GRID_MAX_CELLS_Y - 1); } - static uint8_t cell_index_x(const_float_t x) { + static uint8_t cell_index_x(const float x) { return constrain(cell_index_x_raw(x), 0, GRID_MAX_CELLS_X - 1); } - static uint8_t cell_index_y(const_float_t y) { + static uint8_t cell_index_y(const float y) { return constrain(cell_index_y_raw(y), 0, GRID_MAX_CELLS_Y - 1); } - static xy_uint8_t cell_indexes(const_float_t x, const_float_t y) { + static xy_uint8_t cell_indexes(const float x, const float y) { return { cell_index_x(x), cell_index_y(y) }; } static xy_uint8_t cell_indexes(const xy_pos_t &xy) { return cell_indexes(xy.x, xy.y); } - static int8_t closest_x_index(const_float_t x) { + static int8_t closest_x_index(const float x) { const int8_t px = (x - (MESH_MIN_X) + (MESH_X_DIST) * 0.5) * RECIPROCAL(MESH_X_DIST); return WITHIN(px, 0, (GRID_MAX_POINTS_X) - 1) ? px : -1; } - static int8_t closest_y_index(const_float_t y) { + static int8_t closest_y_index(const float y) { const int8_t py = (y - (MESH_MIN_Y) + (MESH_Y_DIST) * 0.5) * RECIPROCAL(MESH_Y_DIST); return WITHIN(py, 0, (GRID_MAX_POINTS_Y) - 1) ? py : -1; } @@ -188,7 +188,7 @@ public: * It is fairly expensive with its 4 floating point additions and 2 floating point * multiplications. */ - FORCE_INLINE static float calc_z0(const_float_t a0, const_float_t a1, const_float_t z1, const_float_t a2, const_float_t z2) { + FORCE_INLINE static float calc_z0(const float a0, const float a1, const float z1, const float a2, const float z2) { return z1 + (z2 - z1) * (a0 - a1) / (a2 - a1); } @@ -202,7 +202,7 @@ public: * z_correction_for_x_on_horizontal_mesh_line is an optimization for * the case where the printer is making a vertical line that only crosses horizontal mesh lines. */ - static float z_correction_for_x_on_horizontal_mesh_line(const_float_t rx0, const int x1_i, const int yi) { + static float z_correction_for_x_on_horizontal_mesh_line(const float rx0, const int x1_i, const int yi) { if (!WITHIN(x1_i, 0, (GRID_MAX_POINTS_X) - 1) || !WITHIN(yi, 0, (GRID_MAX_POINTS_Y) - 1)) { if (DEBUGGING(LEVELING)) { @@ -225,7 +225,7 @@ public: // // See comments above for z_correction_for_x_on_horizontal_mesh_line // - static float z_correction_for_y_on_vertical_mesh_line(const_float_t ry0, const int xi, const int y1_i) { + static float z_correction_for_y_on_vertical_mesh_line(const float ry0, const int xi, const int y1_i) { if (!WITHIN(xi, 0, (GRID_MAX_POINTS_X) - 1) || !WITHIN(y1_i, 0, (GRID_MAX_POINTS_Y) - 1)) { if (DEBUGGING(LEVELING)) { @@ -251,7 +251,7 @@ public: * Z-Height at both ends. Then it does a linear interpolation of these heights based * on the Y position within the cell. */ - static float get_z_correction(const_float_t rx0, const_float_t ry0) { + static float get_z_correction(const float rx0, const float ry0) { const int8_t cx = cell_index_x(rx0), cy = cell_index_y(ry0); // return values are clamped /** @@ -295,9 +295,9 @@ public: } #if UBL_SEGMENTED - static bool line_to_destination_segmented(const_feedRate_t scaled_fr_mm_s); + static bool line_to_destination_segmented(const feedRate_t scaled_fr_mm_s); #else - static void line_to_destination_cartesian(const_feedRate_t scaled_fr_mm_s, const uint8_t e); + static void line_to_destination_cartesian(const feedRate_t scaled_fr_mm_s, const uint8_t e); #endif static bool mesh_is_valid() { diff --git a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp index e6f93a001b..1f43508ead 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp @@ -48,7 +48,7 @@ #include "../hilbert_curve.h" #endif -#if FT_MOTION_DISABLE_FOR_PROBING +#if ENABLED(FT_MOTION) #include "../../../module/ft_motion.h" #endif @@ -313,9 +313,8 @@ void unified_bed_leveling::G29() { const uint8_t p_val = parser.byteval('P'); const bool may_move = p_val == 1 || p_val == 2 || p_val == 4 || parser.seen_test('J'); - #if FT_MOTION_DISABLE_FOR_PROBING - FTMotionDisableInScope FT_Disabler; // Disable Fixed-Time Motion for probing - #endif + // Potentially disable Fixed-Time Motion for probing + TERN_(FT_MOTION, FTMotionDisableInScope FT_Disabler); // Check for commands that require the printer to be homed if (may_move) { @@ -612,7 +611,7 @@ void unified_bed_leveling::G29() { case 5: adjust_mesh_to_mean(param.C_seen, param.C_constant); break; - case 6: shift_mesh_height(); break; + case 6: shift_mesh_height(param.C_constant); break; } } @@ -716,7 +715,7 @@ void unified_bed_leveling::G29() { * G29 P5 C : Adjust Mesh To Mean (and subtract the given offset). * Find the mean average and shift the mesh to center on that value. */ -void unified_bed_leveling::adjust_mesh_to_mean(const bool cflag, const_float_t offset) { +void unified_bed_leveling::adjust_mesh_to_mean(const bool cflag, const float offset) { float sum = 0; uint8_t n = 0; GRID_LOOP(x, y) @@ -752,10 +751,10 @@ void unified_bed_leveling::adjust_mesh_to_mean(const bool cflag, const_float_t o /** * G29 P6 C : Shift Mesh Height by a uniform constant. */ -void unified_bed_leveling::shift_mesh_height() { +void unified_bed_leveling::shift_mesh_height(const float zoffs) { GRID_LOOP(x, y) if (!isnan(z_values[x][y])) { - z_values[x][y] += param.C_constant; + z_values[x][y] += zoffs; TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y])); } } @@ -782,7 +781,7 @@ void unified_bed_leveling::shift_mesh_height() { const grid_count_t point_num = (GRID_MAX_POINTS - count) + 1; SERIAL_ECHOLNPGM("Probing mesh point ", point_num, "/", GRID_MAX_POINTS, "."); - TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT_F(MSG_PROBING_POINT), point_num, int(GRID_MAX_POINTS))); + TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), point_num, int(GRID_MAX_POINTS))); TERN_(HAS_BACKLIGHT_TIMEOUT, ui.refresh_backlight_timeout()); #if HAS_MARLINUI_MENU @@ -870,7 +869,7 @@ void set_message_with_feedback(FSTR_P const fstr) { return false; } - void unified_bed_leveling::move_z_with_encoder(const_float_t multiplier) { + void unified_bed_leveling::move_z_with_encoder(const float multiplier) { ui.wait_for_release(); while (!ui.button_pressed()) { idle(); @@ -953,7 +952,7 @@ void set_message_with_feedback(FSTR_P const fstr) { * Move to INVALID points and * NOTE: Blocks the G-code queue and captures Marlin UI during use. */ - void unified_bed_leveling::manually_probe_remaining_mesh(const xy_pos_t &pos, const_float_t z_clearance, const_float_t thick, const bool do_ubl_mesh_map) { + void unified_bed_leveling::manually_probe_remaining_mesh(const xy_pos_t &pos, const float z_clearance, const float thick, const bool do_ubl_mesh_map) { ui.capture(); TERN_(EXTENSIBLE_UI, ExtUI::onLevelingStart()); @@ -1511,7 +1510,7 @@ void unified_bed_leveling::smart_fill_mesh() { for (uint8_t i = 0; i < 3; ++i) { SERIAL_ECHOLNPGM("Tilting mesh (", i + 1, "/3)"); - TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), GET_TEXT_F(MSG_LCD_TILTING_MESH), i + 1)); + TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), GET_TEXT(MSG_LCD_TILTING_MESH), i + 1)); measured_z = probe.probe_at_point(points[i], i < 2 ? PROBE_PT_RAISE : PROBE_PT_LAST_STOW, param.V_verbosity); if ((abort_flag = isnan(measured_z))) break; @@ -1567,7 +1566,7 @@ void unified_bed_leveling::smart_fill_mesh() { #endif SERIAL_ECHOLNPGM("Tilting mesh point ", point_num, "/", total_points, "\n"); - TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT_F(MSG_LCD_TILTING_MESH), point_num, total_points)); + TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_LCD_TILTING_MESH), point_num, total_points)); measured_z = probe.probe_at_point(rpos, parser.seen_test('E') ? PROBE_PT_STOW : PROBE_PT_RAISE, param.V_verbosity); // TODO: Needs error handling @@ -1661,10 +1660,10 @@ void unified_bed_leveling::smart_fill_mesh() { */ #if ENABLED(VALIDATE_MESH_TILT) auto d_from = []{ DEBUG_ECHOPGM("D from "); }; - auto normed = [&](const xy_pos_t &pos, const_float_t zadd) { + auto normed = [&](const xy_pos_t &pos, const float zadd) { return normal.x * pos.x + normal.y * pos.y + zadd; }; - auto debug_pt = [](const int num, const xy_pos_t &pos, const_float_t zadd) { + auto debug_pt = [](const int num, const xy_pos_t &pos, const float zadd) { d_from(); DEBUG_ECHOLN(F("Point "), num, C(':'), p_float_t(normed(pos, zadd), 6), F(" Z error = "), p_float_t(zadd - get_z_correction(pos), 6)); }; @@ -1685,7 +1684,7 @@ void unified_bed_leveling::smart_fill_mesh() { #endif // HAS_BED_PROBE #if ENABLED(UBL_G29_P31) - void unified_bed_leveling::smart_fill_wlsf(const_float_t weight_factor) { + void unified_bed_leveling::smart_fill_wlsf(const float weight_factor) { // For each undefined mesh point, compute a distance-weighted least squares fit // from all the originally populated mesh points, weighted toward the point diff --git a/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp b/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp index 053a68b77d..be9fb7b947 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp @@ -47,7 +47,7 @@ // corners of cells. To fix the issue, simply check if the start/end of the line // is very close to a cell boundary in advance and don't split the line there. - void unified_bed_leveling::line_to_destination_cartesian(const_feedRate_t scaled_fr_mm_s, const uint8_t extruder) { + void unified_bed_leveling::line_to_destination_cartesian(const feedRate_t scaled_fr_mm_s, const uint8_t extruder) { /** * Much of the nozzle movement will be within the same cell. So we will do as little computation * as possible to determine if this is the case. If this move is within the same cell, we will @@ -351,7 +351,7 @@ * Returns true if did NOT move, false if moved (requires current_position update). */ - bool __O2 unified_bed_leveling::line_to_destination_segmented(const_feedRate_t scaled_fr_mm_s) { + bool __O2 unified_bed_leveling::line_to_destination_segmented(const feedRate_t scaled_fr_mm_s) { if (!position_is_reachable(destination)) // fail if moving outside reachable boundary return true; // did not move, so current_position still accurate diff --git a/Marlin/src/feature/encoder_i2c.h b/Marlin/src/feature/encoder_i2c.h index 861a8e52d4..e8485a6b75 100644 --- a/Marlin/src/feature/encoder_i2c.h +++ b/Marlin/src/feature/encoder_i2c.h @@ -188,7 +188,7 @@ class I2CPositionEncoder { FORCE_INLINE void set_ec_method(const byte method) { ecMethod = method; } FORCE_INLINE float get_ec_threshold() { return ecThreshold; } - FORCE_INLINE void set_ec_threshold(const_float_t newThreshold) { ecThreshold = newThreshold; } + FORCE_INLINE void set_ec_threshold(const float newThreshold) { ecThreshold = newThreshold; } FORCE_INLINE int get_encoder_ticks_mm() { switch (type) { diff --git a/Marlin/src/feature/filwidth.h b/Marlin/src/feature/filwidth.h index ab50fe0af3..d9e2a00025 100644 --- a/Marlin/src/feature/filwidth.h +++ b/Marlin/src/feature/filwidth.h @@ -78,7 +78,7 @@ public: static void update_measured_mm() { measured_mm = raw_to_mm(); } // Update ring buffer used to delay filament measurements - static void advance_e(const_float_t e_move) { + static void advance_e(const float e_move) { // Increment counters with the E distance e_count += e_move; diff --git a/Marlin/src/feature/max7219.cpp b/Marlin/src/feature/max7219.cpp index 16c7c4f55b..81f588008d 100644 --- a/Marlin/src/feature/max7219.cpp +++ b/Marlin/src/feature/max7219.cpp @@ -283,7 +283,7 @@ void Max7219::set(const uint8_t line, const uint8_t bits) { } // Draw a float with a decimal point and optional digits - void Max7219::print(const uint8_t start, const_float_t value, const uint8_t pre_size, const uint8_t post_size, const bool leadzero=false) { + void Max7219::print(const uint8_t start, const float value, const uint8_t pre_size, const uint8_t post_size, const bool leadzero=false) { if (pre_size) print(start, value, pre_size, leadzero, !!post_size); if (post_size) { const int16_t after = ABS(value) * (10 ^ post_size); diff --git a/Marlin/src/feature/max7219.h b/Marlin/src/feature/max7219.h index f476f7cde4..799524dc5f 100644 --- a/Marlin/src/feature/max7219.h +++ b/Marlin/src/feature/max7219.h @@ -166,7 +166,7 @@ public: // Draw an integer with optional leading zeros and optional decimal point void print(const uint8_t start, int16_t value, uint8_t size, const bool leadzero=false, bool dec=false); // Draw a float with a decimal point and optional digits - void print(const uint8_t start, const_float_t value, const uint8_t pre_size, const uint8_t post_size, const bool leadzero=false); + void print(const uint8_t start, const float value, const uint8_t pre_size, const uint8_t post_size, const bool leadzero=false); #endif // Set a single LED by XY coordinate diff --git a/Marlin/src/feature/mixing.cpp b/Marlin/src/feature/mixing.cpp index f3fb2d07a3..bc98bf3b26 100644 --- a/Marlin/src/feature/mixing.cpp +++ b/Marlin/src/feature/mixing.cpp @@ -166,7 +166,7 @@ void Mixer::refresh_collector(const float proportion/*=1.0*/, const uint8_t t/*= float Mixer::prev_z; // = 0 - void Mixer::update_gradient_for_z(const_float_t z) { + void Mixer::update_gradient_for_z(const float z) { if (z == prev_z) return; prev_z = z; diff --git a/Marlin/src/feature/mixing.h b/Marlin/src/feature/mixing.h index c0f45e364a..bd7ffb560e 100644 --- a/Marlin/src/feature/mixing.h +++ b/Marlin/src/feature/mixing.h @@ -174,9 +174,9 @@ class Mixer { static float prev_z; // Update the current mix from the gradient for a given Z - static void update_gradient_for_z(const_float_t z); + static void update_gradient_for_z(const float z); static void update_gradient_for_planner_z(); - static void gradient_control(const_float_t z) { + static void gradient_control(const float z) { if (gradient.enabled) { if (z >= gradient.end_z) T(gradient.end_vtool); diff --git a/Marlin/src/feature/mmu/mmu2-serial-protocol.md b/Marlin/src/feature/mmu/mmu2-serial-protocol.md index 40799d41a9..474fcd488b 100644 --- a/Marlin/src/feature/mmu/mmu2-serial-protocol.md +++ b/Marlin/src/feature/mmu/mmu2-serial-protocol.md @@ -7,9 +7,9 @@ When initialized, MMU sends We follow with - MMU <= 'S1\n' -- MMU => 'ok*Firmware version*\n' +- MMU => 'ok<_Firmware version_>\n' - MMU <= 'S2\n' -- MMU => 'ok*Build number*\n' +- MMU => 'ok<_Build number_>\n' #if (12V_mode) @@ -19,25 +19,25 @@ We follow with #endif - MMU <= 'P0\n' -- MMU => '_FINDA status_\n' +- MMU => '<_FINDA status_>\n' Now we are sure MMU is available and ready. If there was a timeout or other communication problem somewhere, printer will be killed. -- _Firmware version_ is an integer value, but we don't care about it -- _Build number_ is an integer value and has to be >=126, or =>132 if 12V mode is enabled -- _FINDA status_ is 1 if the filament is loaded to the extruder, 0 otherwise +- <_Firmware version_> is an integer value, but we don't care about it. +- <_Build number_> is an integer value and has to be >=126, or =>132 if 12V mode is enabled. +- <_FINDA status_> is 1 if the filament is loaded to the extruder, 0 otherwise. -_Build number_ is checked against the required value, if it does not match, printer is halted. +<_Build number_> is checked against the required value, if it does not match, printer is halted. # Toolchange -- MMU <= 'T*Filament index*\n' +- MMU <= 'T<_Filament index_>\n' MMU sends - MMU => 'ok\n' -as soon as the filament is fed down to the extruder. We follow with +as soon as the filament is fed down to the extruder. We follow with: - MMU <= 'C0\n' @@ -52,15 +52,15 @@ be one or more extruder moves to feed the filament into the hotend. # FINDA status - MMU <= 'P0\n' -- MMU => '_FINDA status_\n' +- MMU => '<_FINDA status_>\n' _FINDA status_ is 1 if the is filament loaded to the extruder, 0 otherwise. This could be used as filament runout sensor if probed regularly. # Load filament -- MMU <= 'L*Filament index*\n' +- MMU <= 'L<_Filament index_>\n' -MMU will feed filament down to the extruder, when done +MMU will feed filament down to the extruder, when done: - MMU => 'ok\n' @@ -68,11 +68,11 @@ MMU will feed filament down to the extruder, when done - MMU <= 'U0\n' -MMU will retract current filament from the extruder, when done +MMU will retract current filament from the extruder, when done: - MMU => 'ok\n' # Eject filament -- MMU <= 'E*Filament index*\n' +- MMU <= 'E<_Filament index_>\n' - MMU => 'ok\n' diff --git a/Marlin/src/feature/mmu/mmu2.cpp b/Marlin/src/feature/mmu/mmu2.cpp index 96724d0d70..b976150ed9 100644 --- a/Marlin/src/feature/mmu/mmu2.cpp +++ b/Marlin/src/feature/mmu/mmu2.cpp @@ -96,7 +96,7 @@ struct E_Step { feedRate_t feedRate; //!< feed rate in mm/s }; -inline void unscaled_mmu2_e_move(const float &dist, const feedRate_t fr_mm_s, const bool sync=true) { +inline void unscaled_mmu2_e_move(const float dist, const feedRate_t fr_mm_s, const bool sync=true) { current_position.e += dist / planner.e_factor[active_extruder]; line_to_current_position(fr_mm_s); if (sync) planner.synchronize(); diff --git a/Marlin/src/feature/mmu3/mmu3_marlin.h b/Marlin/src/feature/mmu3/mmu3_marlin.h index 2754a2274b..1a0050cd0e 100644 --- a/Marlin/src/feature/mmu3/mmu3_marlin.h +++ b/Marlin/src/feature/mmu3/mmu3_marlin.h @@ -33,10 +33,10 @@ namespace MMU3 { // - Unify implementation among MK3 and Buddy FW // - Enable unit testing of MMU top layer - void extruder_move(const_float_t distance, const_float_t feedRate_mm_s, const bool sync=true); - void extruder_schedule_turning(const_float_t feedRate_mm_s); + void extruder_move(const float distance, const float feedRate_mm_s, const bool sync=true); + void extruder_schedule_turning(const float feedRate_mm_s); - float move_raise_z(const_float_t delta); + float move_raise_z(const float delta); void planner_abort_queued_moves(); void planner_synchronize(); diff --git a/Marlin/src/feature/mmu3/mmu3_marlin1.cpp b/Marlin/src/feature/mmu3/mmu3_marlin1.cpp index be54695c74..03e50da218 100644 --- a/Marlin/src/feature/mmu3/mmu3_marlin1.cpp +++ b/Marlin/src/feature/mmu3/mmu3_marlin1.cpp @@ -49,13 +49,13 @@ namespace MMU3 { planner_synchronize(); } - void extruder_move(const_float_t delta, const_float_t feedRate_mm_s, const bool sync/*=true*/) { + void extruder_move(const float delta, const float feedRate_mm_s, const bool sync/*=true*/) { current_position.e += delta / planner.e_factor[active_extruder]; planner_line_to_current_position(feedRate_mm_s); if (sync) planner.synchronize(); } - float move_raise_z(const_float_t delta) { + float move_raise_z(const float delta) { //return raise_z(delta); xyze_pos_t current_position_before = current_position; do_z_clearance_by(delta); diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp index bd86133771..e48a0f8ec4 100644 --- a/Marlin/src/feature/pause.cpp +++ b/Marlin/src/feature/pause.cpp @@ -188,10 +188,8 @@ static bool ensure_safe_temperature(const bool wait=true, const PauseMode mode=P * * Returns 'true' if load was completed, 'false' for abort */ -bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load_length/*=0*/, const_float_t purge_length/*=0*/, const int8_t max_beep_count/*=0*/, - const bool show_lcd/*=false*/, const bool pause_for_user/*=false*/, - const PauseMode mode/*=PAUSE_MODE_PAUSE_PRINT*/ - DXC_ARGS +bool load_filament(const float slow_load_length/*=0*/, const float fast_load_length/*=0*/, const float purge_length/*=0*/, const int8_t max_beep_count/*=0*/, + const bool show_lcd/*=false*/, const bool pause_for_user/*=false*/, const PauseMode mode/*=PAUSE_MODE_PAUSE_PRINT*/ DXC_ARGS ) { DEBUG_SECTION(lf, "load_filament", true); DEBUG_ECHOLNPGM("... slowlen:", slow_load_length, " fastlen:", fast_load_length, " purgelen:", purge_length, " maxbeep:", max_beep_count, " showlcd:", show_lcd, " pauseforuser:", pause_for_user, " pausemode:", mode DXC_SAY); @@ -344,10 +342,10 @@ inline void disable_active_extruder() { * * Returns 'true' if unload was completed, 'false' for abort */ -bool unload_filament(const_float_t unload_length, const bool show_lcd/*=false*/, +bool unload_filament(const float unload_length, const bool show_lcd/*=false*/, const PauseMode mode/*=PAUSE_MODE_PAUSE_PRINT*/ #if ALL(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) - , const_float_t mix_multiplier/*=1.0*/ + , const float mix_multiplier/*=1.0*/ #endif ) { DEBUG_SECTION(uf, "unload_filament", true); @@ -418,7 +416,7 @@ bool unload_filament(const_float_t unload_length, const bool show_lcd/*=false*/, */ uint8_t did_pause_print = 0; -bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool show_lcd/*=false*/, const_float_t unload_length/*=0*/ DXC_ARGS) { +bool pause_print(const float retract, const xyz_pos_t &park_point, const bool show_lcd/*=false*/, const float unload_length/*=0*/ DXC_ARGS) { DEBUG_SECTION(pp, "pause_print", true); DEBUG_ECHOLNPGM("... park.x:", park_point.x, " y:", park_point.y, " z:", park_point.z, " unloadlen:", unload_length, " showlcd:", show_lcd DXC_SAY); @@ -639,9 +637,9 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep * - Resume the current SD print job, if any */ void resume_print( - const_float_t slow_load_length/*=0*/, - const_float_t fast_load_length/*=0*/, - const_float_t purge_length/*=ADVANCED_PAUSE_PURGE_LENGTH*/, + const float slow_load_length/*=0*/, + const float fast_load_length/*=0*/, + const float purge_length/*=ADVANCED_PAUSE_PURGE_LENGTH*/, const int8_t max_beep_count/*=0*/, const celsius_t targetTemp/*=0*/, const bool show_lcd/*=true*/, diff --git a/Marlin/src/feature/pause.h b/Marlin/src/feature/pause.h index 5ee2e50ea7..4fbb108180 100644 --- a/Marlin/src/feature/pause.h +++ b/Marlin/src/feature/pause.h @@ -91,10 +91,10 @@ extern uint8_t did_pause_print; // Pause the print. If unload_length is set, do a Filament Unload bool pause_print( - const_float_t retract, // (mm) Retraction length + const float retract, // (mm) Retraction length const xyz_pos_t &park_point, // Parking XY Position and Z Raise const bool show_lcd=false, // Set LCD status messages? - const_float_t unload_length=0 // (mm) Filament Change Unload Length - 0 to skip + const float unload_length=0 // (mm) Filament Change Unload Length - 0 to skip DXC_PARAMS // Dual-X-Carriage extruder index ); @@ -105,9 +105,9 @@ void wait_for_confirmation( ); void resume_print( - const_float_t slow_load_length=0, // (mm) Slow Load Length for finishing move - const_float_t fast_load_length=0, // (mm) Fast Load Length for initial move - const_float_t purge_length=ADVANCED_PAUSE_PURGE_LENGTH, // (mm) Purge length + const float slow_load_length=0, // (mm) Slow Load Length for finishing move + const float fast_load_length=0, // (mm) Fast Load Length for initial move + const float purge_length=ADVANCED_PAUSE_PURGE_LENGTH, // (mm) Purge length const int8_t max_beep_count=0, // Beep alert for attention const celsius_t targetTemp=0, // (°C) A target temperature for the hotend const bool show_lcd=true, // Set LCD status messages? @@ -116,9 +116,9 @@ void resume_print( ); bool load_filament( - const_float_t slow_load_length=0, // (mm) Slow Load Length for finishing move - const_float_t fast_load_length=0, // (mm) Fast Load Length for initial move - const_float_t purge_length=0, // (mm) Purge length + const float slow_load_length=0, // (mm) Slow Load Length for finishing move + const float fast_load_length=0, // (mm) Fast Load Length for initial move + const float purge_length=0, // (mm) Purge length const int8_t max_beep_count=0, // Beep alert for attention const bool show_lcd=false, // Set LCD status messages? const bool pause_for_user=false, // Pause for user before returning? @@ -127,11 +127,11 @@ bool load_filament( ); bool unload_filament( - const_float_t unload_length, // (mm) Filament Unload Length - 0 to skip + const float unload_length, // (mm) Filament Unload Length - 0 to skip const bool show_lcd=false, // Set LCD status messages? const PauseMode mode=PAUSE_MODE_PAUSE_PRINT // Pause Mode to apply #if ALL(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) - , const_float_t mix_multiplier=1.0f // Extrusion multiplier (for a Mixing Extruder) + , const float mix_multiplier=1.0f // Extrusion multiplier (for a Mixing Extruder) #endif ); diff --git a/Marlin/src/feature/powerloss.cpp b/Marlin/src/feature/powerloss.cpp index d4f5e04882..01a4d3bc02 100644 --- a/Marlin/src/feature/powerloss.cpp +++ b/Marlin/src/feature/powerloss.cpp @@ -270,7 +270,7 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW #if ENABLED(BACKUP_POWER_SUPPLY) - void PrintJobRecovery::retract_and_lift(const_float_t zraise) { + void PrintJobRecovery::retract_and_lift(const float zraise) { #if POWER_LOSS_RETRACT_LEN || POWER_LOSS_ZRAISE gcode.set_relative_mode(true); // Use relative coordinates diff --git a/Marlin/src/feature/powerloss.h b/Marlin/src/feature/powerloss.h index 8e1e299ac0..187e804aa8 100644 --- a/Marlin/src/feature/powerloss.h +++ b/Marlin/src/feature/powerloss.h @@ -237,7 +237,7 @@ class PrintJobRecovery { static void write(); #if ENABLED(BACKUP_POWER_SUPPLY) - static void retract_and_lift(const_float_t zraise); + static void retract_and_lift(const float zraise); #endif #if PIN_EXISTS(POWER_LOSS) || ENABLED(DEBUG_POWER_LOSS_RECOVERY) diff --git a/Marlin/src/feature/probe_temp_comp.cpp b/Marlin/src/feature/probe_temp_comp.cpp index f640a9fd2f..413beda161 100644 --- a/Marlin/src/feature/probe_temp_comp.cpp +++ b/Marlin/src/feature/probe_temp_comp.cpp @@ -104,12 +104,12 @@ void ProbeTempComp::print_offsets() { #endif } -void ProbeTempComp::prepare_new_calibration(const_float_t init_meas_z) { +void ProbeTempComp::prepare_new_calibration(const float init_meas_z) { calib_idx = 0; init_measurement = init_meas_z; } -void ProbeTempComp::push_back_new_measurement(const TempSensorID tsi, const_float_t meas_z) { +void ProbeTempComp::push_back_new_measurement(const TempSensorID tsi, const float meas_z) { if (calib_idx >= cali_info[tsi].measurements) return; sensor_z_offsets[tsi][calib_idx++] = static_cast((meas_z - init_measurement) * 1000.0f); } @@ -186,7 +186,7 @@ void ProbeTempComp::compensate_measurement(const TempSensorID tsi, const celsius }; // Interpolate Z based on a temperature being within a given range - auto linear_interp = [](const_float_t x, xy_float_t p1, xy_float_t p2) { + auto linear_interp = [](const float x, xy_float_t p1, xy_float_t p2) { // zoffs1 + zoffset_per_toffset * toffset return p1.y + (p2.y - p1.y) / (p2.x - p1.x) * (x - p1.x); }; diff --git a/Marlin/src/feature/probe_temp_comp.h b/Marlin/src/feature/probe_temp_comp.h index 42348db684..e6509a20cf 100644 --- a/Marlin/src/feature/probe_temp_comp.h +++ b/Marlin/src/feature/probe_temp_comp.h @@ -84,8 +84,8 @@ class ProbeTempComp { } static bool set_offset(const TempSensorID tsi, const uint8_t idx, const int16_t offset); static void print_offsets(); - static void prepare_new_calibration(const_float_t init_meas_z); - static void push_back_new_measurement(const TempSensorID tsi, const_float_t meas_z); + static void prepare_new_calibration(const float init_meas_z); + static void push_back_new_measurement(const TempSensorID tsi, const float meas_z); static bool finish_calibration(const TempSensorID tsi); static void set_enabled(const bool ena) { enabled = ena; } diff --git a/Marlin/src/feature/runout.cpp b/Marlin/src/feature/runout.cpp index aa64ed9b93..f0b94d0de8 100644 --- a/Marlin/src/feature/runout.cpp +++ b/Marlin/src/feature/runout.cpp @@ -51,7 +51,6 @@ bool FilamentMonitorBase::enabled = true, #if ENABLED(FILAMENT_MOTION_SENSOR) uint8_t FilamentSensorEncoder::motion_detected; #endif - #if ENABLED(FILAMENT_SWITCH_AND_MOTION) bool RunoutResponseDelayed::ignore_motion = false; float RunoutResponseDelayed::motion_distance_mm = FILAMENT_MOTION_DISTANCE_MM; diff --git a/Marlin/src/feature/runout.h b/Marlin/src/feature/runout.h index e6b4daaa6d..1cd90b0bb2 100644 --- a/Marlin/src/feature/runout.h +++ b/Marlin/src/feature/runout.h @@ -123,12 +123,12 @@ class TFilamentMonitor : public FilamentMonitorBase { response.filament_motion_present(extruder); } static float& motion_distance() { return response.motion_distance_mm; } - static void set_motion_distance(const_float_t mm) { response.motion_distance_mm = mm; } + static void set_motion_distance(const float mm) { response.motion_distance_mm = mm; } #endif #if HAS_FILAMENT_RUNOUT_DISTANCE static float& runout_distance() { return response.runout_distance_mm; } - static void set_runout_distance(const_float_t mm) { response.runout_distance_mm = mm; } + static void set_runout_distance(const float mm) { response.runout_distance_mm = mm; } #endif // Handle a block completion. RunoutResponseDelayed uses this to @@ -143,38 +143,37 @@ class TFilamentMonitor : public FilamentMonitorBase { // Give the response a chance to update its counter. static void run() { - if (enabled && !filament_ran_out && should_monitor_runout()) { - TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, cli()); // Prevent RunoutResponseDelayed::block_completed from accumulating here - response.run(); - sensor.run(); - const runout_flags_t runout_flags = response.has_run_out(); - TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, sei()); - #if MULTI_FILAMENT_SENSOR - #if ENABLED(WATCH_ALL_RUNOUT_SENSORS) - const bool ran_out = bool(runout_flags); // any sensor triggers - uint8_t extruder = 0; - if (ran_out) while (!runout_flags.test(extruder)) extruder++; - #else - const bool ran_out = runout_flags[active_extruder]; // suppress non active extruders - uint8_t extruder = active_extruder; - #endif + if (!enabled || filament_ran_out || !should_monitor_runout()) return; + TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, cli()); // Prevent RunoutResponseDelayed::block_completed from accumulating here + response.run(); + sensor.run(); + const runout_flags_t runout_flags = response.has_run_out(); + TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, sei()); + #if MULTI_FILAMENT_SENSOR + #if ENABLED(WATCH_ALL_RUNOUT_SENSORS) + const bool ran_out = bool(runout_flags); // any sensor triggers + uint8_t extruder = 0; + if (ran_out) while (!runout_flags.test(extruder)) extruder++; #else - const bool ran_out = bool(runout_flags); + const bool ran_out = runout_flags[active_extruder]; // suppress non active extruders uint8_t extruder = active_extruder; #endif + #else + const bool ran_out = bool(runout_flags); + uint8_t extruder = active_extruder; + #endif - if (ran_out) { - #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) - SERIAL_ECHOPGM("Runout Sensors: "); - for (uint8_t i = 0; i < 8; ++i) SERIAL_CHAR('0' + char(runout_flags[i])); - SERIAL_ECHOLNPGM(" -> ", extruder, " RUN OUT"); - #endif + if (!ran_out) return; - filament_ran_out = true; - event_filament_runout(extruder); - planner.synchronize(); - } - } + #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) + SERIAL_ECHOPGM("Runout Sensors: "); + for (uint8_t i = 0; i < 8; ++i) SERIAL_CHAR('0' + char(runout_flags[i])); + SERIAL_ECHOLNPGM(" -> ", extruder, " RUN OUT"); + #endif + + filament_ran_out = true; + event_filament_runout(extruder); + planner.synchronize(); } // Reset after a filament runout or upon resuming a job @@ -376,7 +375,9 @@ class FilamentSensorBase { class RunoutResponseDelayed { private: static countdown_t mm_countdown; - static bool ignore_motion; // Flag to ignore the encoder + #if ENABLED(FILAMENT_SWITCH_AND_MOTION) + static bool ignore_motion; // Flag to ignore the encoder + #endif public: static float runout_distance_mm; @@ -385,13 +386,17 @@ class FilamentSensorBase { static float motion_distance_mm; #endif - static void set_ignore_motion(const bool ignore=true) { ignore_motion = ignore; } + static void set_ignore_motion(const bool ignore=true) { + UNUSED(ignore); + TERN_(FILAMENT_SWITCH_AND_MOTION, ignore_motion = ignore); + } static void reset() { for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) filament_present(i); #if ENABLED(FILAMENT_SWITCH_AND_MOTION) for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i) filament_motion_present(i); #endif + set_ignore_motion(false); } static void run() { @@ -413,13 +418,24 @@ class FilamentSensorBase { // Get runout status for all presence sensors and motion sensors static runout_flags_t has_run_out() { runout_flags_t runout_flags{0}; - // Runout based on filament presence - for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) if (mm_countdown.runout[i] < 0) runout_flags.set(i); - // Runout based on filament motion + #if ENABLED(FILAMENT_SWITCH_AND_MOTION) - if (!ignore_motion) - for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i) if (mm_countdown.motion[i] < 0) runout_flags.set(i); + // Runout based on filament motion + if (!ignore_motion) { + for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i) { + if (mm_countdown.motion[i] < 0) { + runout_flags.set(i); + mm_countdown.runout[i] = -1; // For a filament jam don't wait for runout_distance_mm! + } + } + } #endif + + // Runout based on filament presence + for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) + if (mm_countdown.runout[i] < 0) + runout_flags.set(i); + return runout_flags; } @@ -471,8 +487,8 @@ class FilamentSensorBase { if (mm_countdown.runout_reset[e]) filament_present(e); // Reset pending. Try to reset. } - // Apply E distance to motion countdown, reset if flagged #if ENABLED(FILAMENT_SWITCH_AND_MOTION) + // Apply E distance to motion countdown, reset if flagged if (!ignore_motion && e < NUM_MOTION_SENSORS) { mm_countdown.motion[e] -= mm; if (mm_countdown.motion_reset[e]) filament_motion_present(e); // Reset pending. Try to reset. @@ -484,7 +500,7 @@ class FilamentSensorBase { static void init_for_restart(const bool onoff=true) { UNUSED(onoff); #if ENABLED(FILAMENT_SWITCH_AND_MOTION) - reset(); + reset(); // also calls set_ignore_motion(false) set_ignore_motion(!onoff); #endif } diff --git a/Marlin/src/feature/spindle_laser.h b/Marlin/src/feature/spindle_laser.h index a283f0786d..8702bd289a 100644 --- a/Marlin/src/feature/spindle_laser.h +++ b/Marlin/src/feature/spindle_laser.h @@ -54,7 +54,7 @@ class SpindleLaser { public: static CutterMode cutter_mode; - static constexpr uint8_t pct_to_ocr(const_float_t pct) { return uint8_t(PCT_TO_PWM(pct)); } + static constexpr uint8_t pct_to_ocr(const float pct) { return uint8_t(PCT_TO_PWM(pct)); } // cpower = configured values (e.g., SPEED_POWER_MAX) // Convert configured power range to a percentage diff --git a/Marlin/src/feature/stepper_driver_safety.cpp b/Marlin/src/feature/stepper_driver_safety.cpp index 3ddc05ea1e..acdd695909 100644 --- a/Marlin/src/feature/stepper_driver_safety.cpp +++ b/Marlin/src/feature/stepper_driver_safety.cpp @@ -31,7 +31,7 @@ static uint32_t axis_plug_backward = 0; void stepper_driver_backward_error(FSTR_P const fstr) { SERIAL_ERROR_START(); SERIAL_ECHOLN(fstr, F(" driver is backward!")); - ui.status_printf(2, F(S_FMT S_FMT), FTOP(fstr), GET_TEXT_F(MSG_DRIVER_BACKWARD)); + ui.status_printf(2, F(S_FMT S_FMT), FTOP(fstr), GET_TEXT(MSG_DRIVER_BACKWARD)); } void stepper_driver_backward_check() { diff --git a/Marlin/src/feature/x_twist.cpp b/Marlin/src/feature/x_twist.cpp index 2b7924707e..6b155c49ab 100644 --- a/Marlin/src/feature/x_twist.cpp +++ b/Marlin/src/feature/x_twist.cpp @@ -53,7 +53,7 @@ void XATC::print_points() { SERIAL_EOL(); } -float lerp(const_float_t t, const_float_t a, const_float_t b) { return a + t * (b - a); } +float lerp(const float t, const float a, const float b) { return a + t * (b - a); } float XATC::compensation(const xy_pos_t &raw) { if (!enabled) return 0; diff --git a/Marlin/src/gcode/bedlevel/G26.cpp b/Marlin/src/gcode/bedlevel/G26.cpp index 94e9b82506..b655c3026f 100644 --- a/Marlin/src/gcode/bedlevel/G26.cpp +++ b/Marlin/src/gcode/bedlevel/G26.cpp @@ -170,7 +170,7 @@ float g26_random_deviation = 0.0; #endif -void move_to(const_float_t rx, const_float_t ry, const_float_t z, const_float_t e_delta) { +void move_to(const float rx, const float ry, const float z, const float e_delta) { static float last_z = -999.99; const xy_pos_t dest = { rx, ry }; @@ -196,7 +196,7 @@ void move_to(const_float_t rx, const_float_t ry, const_float_t z, const_float_t prepare_internal_move_to_destination(fr_mm_s); } -void move_to(const xyz_pos_t &where, const_float_t de) { move_to(where.x, where.y, where.z, de); } +void move_to(const xyz_pos_t &where, const float de) { move_to(where.x, where.y, where.z, de); } typedef struct { float extrusion_multiplier = EXTRUSION_MULTIPLIER, diff --git a/Marlin/src/gcode/bedlevel/abl/G29.cpp b/Marlin/src/gcode/bedlevel/abl/G29.cpp index e0cf28156b..ea578e5710 100644 --- a/Marlin/src/gcode/bedlevel/abl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/abl/G29.cpp @@ -59,7 +59,7 @@ #define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) #include "../../../core/debug_out.h" -#if DISABLED(PROBE_MANUALLY) && FT_MOTION_DISABLE_FOR_PROBING +#if DISABLED(PROBE_MANUALLY) && ENABLED(FT_MOTION) #include "../../../module/ft_motion.h" #endif @@ -275,8 +275,9 @@ G29_TYPE GcodeSuite::G29() { // Set and report "probing" state to host TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_PROBE, false)); - #if DISABLED(PROBE_MANUALLY) && FT_MOTION_DISABLE_FOR_PROBING - FTMotionDisableInScope FT_Disabler; // Disable Fixed-Time Motion for probing + #if DISABLED(PROBE_MANUALLY) && ENABLED(FT_MOTION) + // Potentially disable Fixed-Time Motion for probing + FTMotionDisableInScope FT_Disabler; #endif /** @@ -708,7 +709,7 @@ G29_TYPE GcodeSuite::G29() { if (TERN0(IS_KINEMATIC, !probe.can_reach(abl.probePos))) continue; if (abl.verbose_level) SERIAL_ECHOLNPGM("Probing mesh point ", pt_index, "/", abl.abl_points, "."); - TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT_F(MSG_PROBING_POINT), int(pt_index), int(abl.abl_points))); + TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), int(pt_index), int(abl.abl_points))); #if ENABLED(BD_SENSOR_PROBE_NO_STOP) if (PR_INNER_VAR == inStart) { @@ -813,7 +814,7 @@ G29_TYPE GcodeSuite::G29() { for (uint8_t i = 0; i < 3; ++i) { if (abl.verbose_level) SERIAL_ECHOLNPGM("Probing point ", i + 1, "/3."); - TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), GET_TEXT_F(MSG_PROBING_POINT), int(i + 1))); + TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), GET_TEXT(MSG_PROBING_POINT), int(i + 1))); // Retain the last probe position abl.probePos = xy_pos_t(points[i]); diff --git a/Marlin/src/gcode/bedlevel/mbl/G29.cpp b/Marlin/src/gcode/bedlevel/mbl/G29.cpp index 4bd444c5a3..7b826acba7 100644 --- a/Marlin/src/gcode/bedlevel/mbl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/mbl/G29.cpp @@ -45,7 +45,7 @@ #define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) #include "../../../core/debug_out.h" -#if FT_MOTION_DISABLE_FOR_PROBING +#if ENABLED(FT_MOTION) #include "../../module/ft_motion.h" #endif @@ -67,9 +67,8 @@ inline void echo_not_entered(const char c) { SERIAL_CHAR(c); SERIAL_ECHOLNPGM(" */ void GcodeSuite::G29() { - #if FT_MOTION_DISABLE_FOR_PROBING - FTMotionDisableInScope FT_Disabler; // Disable Fixed-Time Motion for probing - #endif + // Potentially disable Fixed-Time Motion for probing + TERN_(FT_MOTION, FTMotionDisableInScope FT_Disabler); DEBUG_SECTION(log_G29, "G29", true); @@ -261,7 +260,7 @@ void GcodeSuite::G29() { if (state == MeshNext) { SERIAL_ECHOLNPGM("MBL G29 point ", _MIN(mbl_probe_index, GRID_MAX_POINTS), " of ", GRID_MAX_POINTS); - if (mbl_probe_index > 0) TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT_F(MSG_PROBING_POINT), _MIN(mbl_probe_index, GRID_MAX_POINTS), int(GRID_MAX_POINTS))); + if (mbl_probe_index > 0) TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), _MIN(mbl_probe_index, GRID_MAX_POINTS), int(GRID_MAX_POINTS))); } report_current_position(); diff --git a/Marlin/src/gcode/calibrate/G28.cpp b/Marlin/src/gcode/calibrate/G28.cpp index 6ac51e4235..92f05b1fba 100644 --- a/Marlin/src/gcode/calibrate/G28.cpp +++ b/Marlin/src/gcode/calibrate/G28.cpp @@ -52,7 +52,7 @@ #include "../../feature/bltouch.h" #endif -#if FT_MOTION_DISABLE_FOR_PROBING +#if ENABLED(FT_MOTION) #include "../../module/ft_motion.h" #endif @@ -130,9 +130,8 @@ inline void home_z_safely() { - #if FT_MOTION_DISABLE_FOR_PROBING - FTMotionDisableInScope FT_Disabler; // Disable Fixed-Time Motion for homing - #endif + // Potentially disable Fixed-Time Motion for homing + TERN_(FT_MOTION, FTMotionDisableInScope FT_Disabler); DEBUG_SECTION(log_G28, "home_z_safely", DEBUGGING(LEVELING)); @@ -290,9 +289,8 @@ void GcodeSuite::G28() { motion_state_t saved_motion_state = begin_slow_homing(); #endif - #if FT_MOTION_DISABLE_FOR_PROBING - FTMotionDisableInScope FT_Disabler; // Disable Fixed-Time Motion for homing - #endif + // Potentially disable Fixed-Time Motion for homing + TERN_(FT_MOTION, FTMotionDisableInScope FT_Disabler); // Always home with tool 0 active #if HAS_MULTI_HOTEND diff --git a/Marlin/src/gcode/calibrate/G33.cpp b/Marlin/src/gcode/calibrate/G33.cpp index 409a9c8707..11c3cdca78 100644 --- a/Marlin/src/gcode/calibrate/G33.cpp +++ b/Marlin/src/gcode/calibrate/G33.cpp @@ -87,7 +87,7 @@ void ac_cleanup() { TERN_(HAS_BED_PROBE, probe.use_probing_tool(false)); } -void print_signed_float(FSTR_P const prefix, const_float_t f) { +void print_signed_float(FSTR_P const prefix, const float f) { SERIAL_ECHO(F(" "), prefix, C(':')); serial_offset(f); } diff --git a/Marlin/src/gcode/calibrate/G34_M422.cpp b/Marlin/src/gcode/calibrate/G34_M422.cpp index fc22b354eb..aba828d6dd 100644 --- a/Marlin/src/gcode/calibrate/G34_M422.cpp +++ b/Marlin/src/gcode/calibrate/G34_M422.cpp @@ -323,7 +323,7 @@ void GcodeSuite::G34() { msg.echoln(); ui.set_status(msg); - auto decreasing_accuracy = [](const_float_t v1, const_float_t v2) { + auto decreasing_accuracy = [](const float v1, const float v2) { if (v1 < v2 * 0.7f) { SERIAL_ECHOLNPGM("Decreasing Accuracy Detected."); LCD_MESSAGE(MSG_DECREASING_ACCURACY); diff --git a/Marlin/src/gcode/calibrate/G76_M871.cpp b/Marlin/src/gcode/calibrate/G76_M871.cpp index 7051540e7b..a909ef4c84 100644 --- a/Marlin/src/gcode/calibrate/G76_M871.cpp +++ b/Marlin/src/gcode/calibrate/G76_M871.cpp @@ -320,7 +320,7 @@ */ void GcodeSuite::M871() { - if (parser.seen('R')) { + if (parser.seen_test('R')) { // Reset z-probe offsets to factory defaults ptc.clear_all_offsets(); SERIAL_ECHOLNPGM("Offsets reset to default."); diff --git a/Marlin/src/gcode/calibrate/M48.cpp b/Marlin/src/gcode/calibrate/M48.cpp index 981a1d9877..0c4355f5b1 100644 --- a/Marlin/src/gcode/calibrate/M48.cpp +++ b/Marlin/src/gcode/calibrate/M48.cpp @@ -124,7 +124,7 @@ void GcodeSuite::M48() { max = -99999.9, // Largest value sampled so far sample_set[n_samples]; // Storage for sampled values - auto dev_report = [](const bool verbose, const_float_t mean, const_float_t sigma, const_float_t min, const_float_t max, const bool final=false) { + auto dev_report = [](const bool verbose, const float mean, const float sigma, const float min, const float max, const bool final=false) { if (verbose) { SERIAL_ECHOPGM("Mean: ", p_float_t(mean, 6)); if (!final) SERIAL_ECHOPGM(" Sigma: ", p_float_t(sigma, 6)); @@ -149,7 +149,7 @@ void GcodeSuite::M48() { for (uint8_t n = 0; n < n_samples; ++n) { #if HAS_STATUS_MESSAGE // Display M48 progress in the status bar - ui.status_printf(0, F(S_FMT ": %d/%d"), GET_TEXT_F(MSG_M48_POINT), int(n + 1), int(n_samples)); + ui.status_printf(0, F(S_FMT ": %d/%d"), GET_TEXT(MSG_M48_POINT), int(n + 1), int(n_samples)); #endif // When there are "legs" of movement move around the point before probing diff --git a/Marlin/src/gcode/config/M210.cpp b/Marlin/src/gcode/config/M210.cpp index f9ae155f60..f07e009b4a 100644 --- a/Marlin/src/gcode/config/M210.cpp +++ b/Marlin/src/gcode/config/M210.cpp @@ -48,31 +48,31 @@ void GcodeSuite::M210() { return M210_report(); #if HAS_X_AXIS - if (parser.floatval('X') > 0) homing_feedrate_mm_m.x = parser.value_axis_units(X_AXIS); + if (parser.floatval(AXIS1_PARAM) > 0) homing_feedrate_mm_m.x = parser.value_axis_units(X_AXIS); #endif #if HAS_Y_AXIS - if (parser.floatval('Y') > 0) homing_feedrate_mm_m.y = parser.value_axis_units(Y_AXIS); + if (parser.floatval(AXIS2_PARAM) > 0) homing_feedrate_mm_m.y = parser.value_axis_units(Y_AXIS); #endif #if HAS_Z_AXIS - if (parser.floatval('Z') > 0) homing_feedrate_mm_m.z = parser.value_axis_units(Z_AXIS); + if (parser.floatval(AXIS3_PARAM) > 0) homing_feedrate_mm_m.z = parser.value_axis_units(Z_AXIS); #endif #if HAS_I_AXIS - if (parser.floatval(AXIS4_NAME) > 0) homing_feedrate_mm_m.i = parser.value_axis_units(I_AXIS); + if (parser.floatval(AXIS4_PARAM) > 0) homing_feedrate_mm_m.i = parser.value_axis_units(I_AXIS); #endif #if HAS_J_AXIS - if (parser.floatval(AXIS5_NAME) > 0) homing_feedrate_mm_m.j = parser.value_axis_units(J_AXIS); + if (parser.floatval(AXIS5_PARAM) > 0) homing_feedrate_mm_m.j = parser.value_axis_units(J_AXIS); #endif #if HAS_K_AXIS - if (parser.floatval(AXIS6_NAME) > 0) homing_feedrate_mm_m.k = parser.value_axis_units(K_AXIS); + if (parser.floatval(AXIS6_PARAM) > 0) homing_feedrate_mm_m.k = parser.value_axis_units(K_AXIS); #endif #if HAS_U_AXIS - if (parser.floatval(AXIS7_NAME) > 0) homing_feedrate_mm_m.u = parser.value_axis_units(U_AXIS); + if (parser.floatval(AXIS7_PARAM) > 0) homing_feedrate_mm_m.u = parser.value_axis_units(U_AXIS); #endif #if HAS_V_AXIS - if (parser.floatval(AXIS8_NAME) > 0) homing_feedrate_mm_m.v = parser.value_axis_units(V_AXIS); + if (parser.floatval(AXIS8_PARAM) > 0) homing_feedrate_mm_m.v = parser.value_axis_units(V_AXIS); #endif #if HAS_W_AXIS - if (parser.floatval(AXIS9_NAME) > 0) homing_feedrate_mm_m.w = parser.value_axis_units(W_AXIS); + if (parser.floatval(AXIS9_PARAM) > 0) homing_feedrate_mm_m.w = parser.value_axis_units(W_AXIS); #endif } diff --git a/Marlin/src/gcode/config/M43.cpp b/Marlin/src/gcode/config/M43.cpp index a515acb241..deeabf8fac 100644 --- a/Marlin/src/gcode/config/M43.cpp +++ b/Marlin/src/gcode/config/M43.cpp @@ -154,37 +154,36 @@ inline void servo_probe_test() { SET_INPUT_PULLUP(PROBE_TEST_PIN); - // First, check for a probe that recognizes an advanced BLTouch sequence. - // In addition to STOW and DEPLOY, it uses SW MODE (and RESET in the beginning) - // to see if this is one of the following: BLTOUCH Classic 1.2, 1.3, or - // BLTouch Smart 1.0, 2.0, 2.2, 3.0, 3.1. But only if the user has actually - // configured a BLTouch as being present. If the user has not configured this, - // the BLTouch will be detected in the last phase of these tests (see further on). - bool blt = false; - // This code will try to detect a BLTouch probe or clone + /** + * This code will try to detect a BLTouch probe or clone. + * First, check for a probe that recognizes an advanced BLTouch sequence. + * In addition to STOW and DEPLOY, it uses SW MODE (and RESET in the beginning) + * to see if this is one of the following: BLTOUCH Classic 1.2, 1.3, or + * BLTouch Smart 1.0, 2.0, 2.2, 3.0, 3.1. But only if the user has actually + * configured a BLTouch as being present. If the user has not configured this, + * the BLTouch will be detected in the last phase of these tests (see further on). + */ #if ENABLED(BLTOUCH) - SERIAL_ECHOLNPGM(". Check for BLTOUCH"); - bltouch._reset(); - bltouch._stow(); - if (!PROBE_TRIGGERED()) { - bltouch._set_SW_mode(); - if (PROBE_TRIGGERED()) { - bltouch._deploy(); - if (!PROBE_TRIGGERED()) { - bltouch._stow(); - SERIAL_ECHOLNPGM("= BLTouch Classic 1.2, 1.3, Smart 1.0, 2.0, 2.2, 3.0, 3.1 detected."); - // Check for a 3.1 by letting the user trigger it, later - blt = true; - } - } - } + bool blt = false; + do { + SERIAL_ECHOLNPGM(". Check for BLTOUCH"); + bltouch._reset(); + bltouch._stow(); if ( PROBE_TRIGGERED()) break; + bltouch._set_SW_mode(); if (!PROBE_TRIGGERED()) break; + bltouch._deploy(); if ( PROBE_TRIGGERED()) break; + bltouch._stow(); + SERIAL_ECHOLNPGM("= BLTouch Classic 1.2, 1.3, Smart 1.0, 2.0, 2.2, 3.0, 3.1 detected."); + blt = true; // Check for a 3.1 by letting the user trigger it, later + } while(0); + #else + static constexpr bool blt = false; #endif // The following code is common to all kinds of servo probes. // Since it could be a real servo or a BLTouch (any kind) or a clone, // use only "common" functions - i.e. SERVO_MOVE. No bltouch.xxxx stuff. - // If it is already recognised as a being a BLTouch, no need for this test + // If it is already recognized as a being a BLTouch, no need for this test if (!blt) { // DEPLOY and STOW 4 times and see if the signal follows // Then it is a mechanical switch diff --git a/Marlin/src/gcode/feature/camera/M240.cpp b/Marlin/src/gcode/feature/camera/M240.cpp index bb1d3f9eee..23ec4ea1e7 100644 --- a/Marlin/src/gcode/feature/camera/M240.cpp +++ b/Marlin/src/gcode/feature/camera/M240.cpp @@ -47,7 +47,7 @@ #endif #ifdef PHOTO_RETRACT_MM - inline void e_move_m240(const float length, const_feedRate_t fr_mm_s) { + inline void e_move_m240(const float length, const feedRate_t fr_mm_s) { if (length && thermalManager.hotEnoughToExtrude(active_extruder)) unscaled_e_move(length, fr_mm_s); } diff --git a/Marlin/src/gcode/feature/cancel/M486.cpp b/Marlin/src/gcode/feature/cancel/M486.cpp index 37347e9d43..237654e433 100644 --- a/Marlin/src/gcode/feature/cancel/M486.cpp +++ b/Marlin/src/gcode/feature/cancel/M486.cpp @@ -47,7 +47,7 @@ void GcodeSuite::M486() { if (parser.seenval('S')) cancelable.set_active_object(parser.value_int()); - if (parser.seen('C')) cancelable.cancel_active_object(); + if (parser.seen_test('C')) cancelable.cancel_active_object(); if (parser.seenval('P')) cancelable.cancel_object(parser.value_int()); diff --git a/Marlin/src/gcode/feature/ft_motion/M493.cpp b/Marlin/src/gcode/feature/ft_motion/M493.cpp index fe57de6ac8..f1dc4d0753 100644 --- a/Marlin/src/gcode/feature/ft_motion/M493.cpp +++ b/Marlin/src/gcode/feature/ft_motion/M493.cpp @@ -28,8 +28,9 @@ #include "../../../module/ft_motion.h" #include "../../../module/stepper.h" -void say_shaper_type(const AxisEnum a) { - SERIAL_ECHOPGM(" axis "); +void say_shaper_type(const AxisEnum a, bool &sep, const char axis_name) { + if (sep) SERIAL_ECHOPGM(" ; "); + SERIAL_CHAR(axis_name, '='); switch (ftMotion.cfg.shaper[a]) { default: break; case ftMotionShaper_ZV: SERIAL_ECHOPGM("ZV"); break; @@ -41,46 +42,31 @@ void say_shaper_type(const AxisEnum a) { case ftMotionShaper_3HEI: SERIAL_ECHOPGM("3 Hump EI"); break; case ftMotionShaper_MZV: SERIAL_ECHOPGM("MZV"); break; } - SERIAL_ECHOPGM(" shaping"); + sep = true; } -#if CORE_IS_XY || CORE_IS_XZ - #define AXIS_0_NAME "A" -#else - #define AXIS_0_NAME "X" -#endif -#if CORE_IS_XY || CORE_IS_YZ - #define AXIS_1_NAME "B" -#else - #define AXIS_1_NAME "Y" -#endif - void say_shaping() { // FT Enabled SERIAL_ECHO_TERNARY(ftMotion.cfg.active, "Fixed-Time Motion ", "en", "dis", "abled"); // FT Shaping - #if HAS_X_AXIS - if (AXIS_IS_SHAPING(X)) { - SERIAL_ECHOPGM(" with " AXIS_0_NAME); - say_shaper_type(X_AXIS); - } - #endif - #if HAS_Y_AXIS - if (AXIS_IS_SHAPING(Y)) { - SERIAL_ECHOPGM(" and with " AXIS_1_NAME); - say_shaper_type(Y_AXIS); - } - #endif - - SERIAL_ECHOLNPGM("."); + const bool is_shaping = AXIS_IS_SHAPING(X) || AXIS_IS_SHAPING(Y) || AXIS_IS_SHAPING(Z) || AXIS_IS_SHAPING(E); + bool sep = false; + if (is_shaping) { + #define STEPPER_E_NAME 'E' + #define _SAY_SHAPER(A) if (AXIS_IS_SHAPING(A)) say_shaper_type(_AXIS(A), sep, STEPPER_##A##_NAME); + SERIAL_ECHOPGM(" ("); + SHAPED_CODE(_SAY_SHAPER(A), _SAY_SHAPER(B), _SAY_SHAPER(C), _SAY_SHAPER(E)); + SERIAL_CHAR(')'); + } + SERIAL_EOL(); const bool z_based = TERN0(HAS_DYNAMIC_FREQ_MM, ftMotion.cfg.dynFreqMode == dynFreqMode_Z_BASED), g_based = TERN0(HAS_DYNAMIC_FREQ_G, ftMotion.cfg.dynFreqMode == dynFreqMode_MASS_BASED), dynamic = z_based || g_based; // FT Dynamic Frequency Mode - if (AXIS_IS_SHAPING(X) || AXIS_IS_SHAPING(Y)) { + if (is_shaping) { #if HAS_DYNAMIC_FREQ SERIAL_ECHOPGM("Dynamic Frequency Mode "); switch (ftMotion.cfg.dynFreqMode) { @@ -97,7 +83,8 @@ void say_shaping() { #endif #if HAS_X_AXIS - SERIAL_ECHO_TERNARY(dynamic, AXIS_0_NAME " ", "base dynamic", "static", " shaper frequency: "); + SERIAL_CHAR(STEPPER_A_NAME); + SERIAL_ECHO_TERNARY(dynamic, " ", "base dynamic", "static", " shaper frequency: "); SERIAL_ECHO(p_float_t(ftMotion.cfg.baseFreq.x, 2), F("Hz")); #if HAS_DYNAMIC_FREQ if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(ftMotion.cfg.dynFreqK.x, 2), F("Hz/"), z_based ? F("mm") : F("g")); @@ -106,21 +93,31 @@ void say_shaping() { #endif #if HAS_Y_AXIS - SERIAL_ECHO_TERNARY(dynamic, AXIS_1_NAME " ", "base dynamic", "static", " shaper frequency: "); + SERIAL_CHAR(STEPPER_B_NAME); + SERIAL_ECHO_TERNARY(dynamic, " ", "base dynamic", "static", " shaper frequency: "); SERIAL_ECHO(p_float_t(ftMotion.cfg.baseFreq.y, 2), F(" Hz")); #if HAS_DYNAMIC_FREQ if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(ftMotion.cfg.dynFreqK.y, 2), F("Hz/"), z_based ? F("mm") : F("g")); #endif SERIAL_EOL(); #endif + + #if ENABLED(FTM_SHAPER_Z) + SERIAL_CHAR(STEPPER_C_NAME); + SERIAL_ECHO_TERNARY(dynamic, " ", "base dynamic", "static", " shaper frequency: "); + SERIAL_ECHO(p_float_t(ftMotion.cfg.baseFreq.z, 2), F(" Hz")); + #if HAS_DYNAMIC_FREQ + if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(ftMotion.cfg.dynFreqK.z, 2), F("Hz/"), z_based ? F("mm") : F("g")); + #endif + SERIAL_EOL(); + #endif } #if HAS_EXTRUDERS - SERIAL_ECHO_TERNARY(ftMotion.cfg.linearAdvEna, "Linear Advance ", "en", "dis", "abled"); - if (ftMotion.cfg.linearAdvEna) + if (ftMotion.cfg.active) { + SERIAL_ECHO_TERNARY(ftMotion.cfg.linearAdvEna, "Linear Advance ", "en", "dis", "abled"); SERIAL_ECHOLNPGM(". Gain: ", ftMotion.cfg.linearAdvK); - else - SERIAL_EOL(); + } #endif } @@ -129,26 +126,44 @@ void GcodeSuite::M493_report(const bool forReplay/*=true*/) { report_heading_etc(forReplay, F(STR_FT_MOTION)); const ft_config_t &c = ftMotion.cfg; - SERIAL_ECHOPGM(" M493 S", c.active); - #if HAS_X_AXIS - SERIAL_ECHOPGM(" A", c.baseFreq.x); - #if HAS_Y_AXIS - SERIAL_ECHOPGM(" B", c.baseFreq.y); - #endif - #endif - #if HAS_DYNAMIC_FREQ - SERIAL_ECHOPGM(" D", c.dynFreqMode); + SERIAL_ECHOLNPGM( + " M493 S", c.active #if HAS_X_AXIS - SERIAL_ECHOPGM(" F", c.dynFreqK.x); + , " A", c.baseFreq.x + #endif + #if HAS_Y_AXIS + , " B", c.baseFreq.y + #endif + #if ENABLED(FTM_SHAPER_Z) + , " C", c.baseFreq.z + #endif + #if ENABLED(FTM_SHAPER_E) + , " E", c.baseFreq.e + #endif + + #if HAS_DYNAMIC_FREQ + , " D", c.dynFreqMode + #if HAS_X_AXIS + , " F", c.dynFreqK.x + #endif #if HAS_Y_AXIS - SERIAL_ECHOPGM(" H", c.dynFreqK.y); + , " H", c.dynFreqK.y + #endif + #if ENABLED(FTM_SHAPER_Z) + , " L", c.dynFreqK.z + #endif + #if ENABLED(FTM_SHAPER_E) + , " O", c.dynFreqK.e #endif #endif - #endif - #if HAS_EXTRUDERS - SERIAL_ECHOPGM(" P", c.linearAdvEna, " K", c.linearAdvK); - #endif - SERIAL_EOL(); + + , " G", c.axis_sync_enabled + + #if HAS_EXTRUDERS + , " P", c.linearAdvEna, " K", c.linearAdvK + #endif + + ); } /** @@ -158,8 +173,8 @@ void GcodeSuite::M493_report(const bool forReplay/*=true*/) { * 0: Fixed-Time Motion OFF (Standard Motion) * 1: Fixed-Time Motion ON * - * X/Y Set the vibration compensator [input shaper] mode for X / Y axis. - * Users / slicers must remember to set the mode for both axes! + * X/Y/Z/E Set the vibration compensator [input shaper] mode for an axis. + * Users / slicers must remember to set the mode for all relevant axes! * 0: NONE : No input shaper * 1: ZV : Zero Vibration * 2: ZVD : Zero Vibration and Derivative @@ -174,20 +189,35 @@ void GcodeSuite::M493_report(const bool forReplay/*=true*/) { * * K Set Linear Advance gain * + * G Enable (1) or Disable (0) axis synchronization. + * * D Set Dynamic Frequency mode * 0: DISABLED * 1: Z-based (Requires a Z axis) * 2: Mass-based (Requires X and E axes) * - * A Set static/base frequency for the X axis - * F Set frequency scaling for the X axis - * I 0.0 Set damping ratio for the X axis - * Q 0.00 Set the vibration tolerance for the X axis + * A Set X static/base frequency + * F Set X frequency scaling + * I Set X damping ratio + * Q Set X vibration tolerance + * + * B Set Y static/base frequency + * H Set Y frequency scaling + * J Set Y damping ratio + * R Set Y vibration tolerance + * + * With FTM_SHAPING_Z: + * C Set Z static/base frequency + * L Set Z frequency scaling + * O Set Z damping ratio + * M Set Z vibration tolerance + * + * With FTM_SHAPING_E: + * W Set E static/base frequency + * O Set E frequency scaling + * U Set E damping ratio + * V Set E vibration tolerance * - * B Set static/base frequency for the Y axis - * H Set frequency scaling for the Y axis - * J 0.0 Set damping ratio for the Y axis - * R 0.00 Set the vibration tolerance for the Y axis */ void GcodeSuite::M493() { struct { bool update:1, report:1; } flag = { false }; @@ -205,7 +235,8 @@ void GcodeSuite::M493() { } } - #if HAS_X_AXIS + #if NUM_AXES_SHAPED > 0 + auto set_shaper = [&](const AxisEnum axis, const char c) { const ftMotionShaper_t newsh = (ftMotionShaper_t)parser.value_byte(); if (newsh != ftMotion.cfg.shaper[axis]) { @@ -228,13 +259,10 @@ void GcodeSuite::M493() { return false; }; - if (parser.seenval('X') && set_shaper(X_AXIS, 'X')) return; // Parse 'X' mode parameter + #define _SET_SHAPER(A) if (parser.seenval(CHARIFY(A)) && set_shaper(_AXIS(A), CHARIFY(A))) return; + SHAPED_MAP(_SET_SHAPER); - #if HAS_Y_AXIS - if (parser.seenval('Y') && set_shaper(Y_AXIS, 'Y')) return; // Parse 'Y' mode parameter - #endif - - #endif // HAS_X_AXIS + #endif // NUM_AXES_SHAPED > 0 #if HAS_EXTRUDERS @@ -243,13 +271,12 @@ void GcodeSuite::M493() { const bool val = parser.value_bool(); ftMotion.cfg.linearAdvEna = val; flag.report = true; - SERIAL_ECHO_TERNARY(val, "Linear Advance ", "en", "dis", "abled.\n"); } // Pressure control (linear advance) gain parameter. if (parser.seenval('K')) { const float val = parser.value_float(); - if (val >= 0.0f) { + if (WITHIN(val, 0.0f, 10.0f)) { ftMotion.cfg.linearAdvK = val; flag.report = true; } @@ -259,11 +286,20 @@ void GcodeSuite::M493() { #endif // HAS_EXTRUDERS + // Parse '?' axis synchronization parameter. + if (parser.seen('?')) { + const bool enabled = parser.value_bool(); + if (enabled != ftMotion.cfg.axis_sync_enabled) { + ftMotion.cfg.axis_sync_enabled = enabled; + flag.report = true; + } + } + #if HAS_DYNAMIC_FREQ // Dynamic frequency mode parameter. if (parser.seenval('D')) { - if (AXIS_IS_SHAPING(X) || AXIS_IS_SHAPING(Y)) { + if (AXIS_IS_SHAPING(X) || AXIS_IS_SHAPING(Y) || AXIS_IS_SHAPING(Z) || AXIS_IS_SHAPING(E)) { const dynFreqMode_t val = dynFreqMode_t(parser.value_byte()); switch (val) { #if HAS_DYNAMIC_FREQ_MM @@ -295,7 +331,7 @@ void GcodeSuite::M493() { #if HAS_X_AXIS - // Parse frequency parameter (X axis). + // Parse X frequency parameter if (parser.seenval('A')) { if (AXIS_IS_SHAPING(X)) { const float val = parser.value_float(); @@ -305,59 +341,59 @@ void GcodeSuite::M493() { flag.update = flag.report = true; } else // Frequency out of range. - SERIAL_ECHOLNPGM("Invalid [", C('A'), "] frequency value."); + SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_A_NAME), " [", C('A'), "] frequency value."); } else // Mode doesn't use frequency. - SERIAL_ECHOLNPGM("Wrong mode for [", C('A'), "] frequency."); + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " [", C('A'), "] frequency."); } #if HAS_DYNAMIC_FREQ - // Parse frequency scaling parameter (X axis). + // Parse X frequency scaling parameter if (parser.seenval('F')) { if (modeUsesDynFreq) { ftMotion.cfg.dynFreqK.x = parser.value_float(); flag.report = true; } else - SERIAL_ECHOLNPGM("Wrong mode for [", C('F'), "] frequency scaling."); + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " [", C('F'), "] frequency scaling."); } #endif - // Parse zeta parameter (X axis). + // Parse X zeta parameter if (parser.seenval('I')) { const float val = parser.value_float(); if (AXIS_IS_SHAPING(X)) { if (WITHIN(val, 0.01f, 1.0f)) { - ftMotion.cfg.zeta[0] = val; + ftMotion.cfg.zeta.x = val; flag.update = true; } else - SERIAL_ECHOLNPGM("Invalid X zeta [", C('I'), "] value."); // Zeta out of range. + SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_A_NAME), " zeta [", C('I'), "] value."); // Zeta out of range } else - SERIAL_ECHOLNPGM("Wrong mode for zeta parameter."); + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " zeta parameter."); } - // Parse vtol parameter (X axis). + // Parse X vtol parameter if (parser.seenval('Q')) { const float val = parser.value_float(); if (AXIS_IS_EISHAPING(X)) { if (WITHIN(val, 0.00f, 1.0f)) { - ftMotion.cfg.vtol[0] = val; + ftMotion.cfg.vtol.x = val; flag.update = true; } else - SERIAL_ECHOLNPGM("Invalid X vtol [", C('Q'), "] value."); // VTol out of range. + SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_A_NAME), " vtol [", C('Q'), "] value."); // VTol out of range. } else - SERIAL_ECHOLNPGM("Wrong mode for vtol parameter."); + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " vtol parameter."); } #endif // HAS_X_AXIS #if HAS_Y_AXIS - // Parse frequency parameter (Y axis). + // Parse Y frequency parameter if (parser.seenval('B')) { if (AXIS_IS_SHAPING(Y)) { const float val = parser.value_float(); @@ -366,56 +402,178 @@ void GcodeSuite::M493() { flag.update = flag.report = true; } else // Frequency out of range. - SERIAL_ECHOLNPGM("Invalid frequency [", C('B'), "] value."); + SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_B_NAME), " frequency [", C('B'), "] value."); } else // Mode doesn't use frequency. - SERIAL_ECHOLNPGM("Wrong mode for [", C('B'), "] frequency."); + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " [", C('B'), "] frequency."); } #if HAS_DYNAMIC_FREQ - // Parse frequency scaling parameter (Y axis). + // Parse Y frequency scaling parameter if (parser.seenval('H')) { if (modeUsesDynFreq) { ftMotion.cfg.dynFreqK.y = parser.value_float(); flag.report = true; } else - SERIAL_ECHOLNPGM("Wrong mode for [", C('H'), "] frequency scaling."); + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " [", C('H'), "] frequency scaling."); } #endif - // Parse zeta parameter (Y axis). + // Parse Y zeta parameter if (parser.seenval('J')) { const float val = parser.value_float(); if (AXIS_IS_SHAPING(Y)) { if (WITHIN(val, 0.01f, 1.0f)) { - ftMotion.cfg.zeta[1] = val; + ftMotion.cfg.zeta.y = val; flag.update = true; } else - SERIAL_ECHOLNPGM("Invalid Y zeta [", C('J'), "] value."); // Zeta Out of range + SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_B_NAME), " zeta [", C('J'), "] value."); // Zeta out of range } else - SERIAL_ECHOLNPGM("Wrong mode for zeta parameter."); + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " zeta parameter."); } - // Parse vtol parameter (Y axis). + // Parse Y vtol parameter if (parser.seenval('R')) { const float val = parser.value_float(); if (AXIS_IS_EISHAPING(Y)) { if (WITHIN(val, 0.00f, 1.0f)) { - ftMotion.cfg.vtol[1] = val; + ftMotion.cfg.vtol.y = val; flag.update = true; } else - SERIAL_ECHOLNPGM("Invalid Y vtol [", C('R'), "] value."); // VTol out of range. + SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_B_NAME), " vtol [", C('R'), "] value."); // VTol out of range. } else - SERIAL_ECHOLNPGM("Wrong mode for vtol parameter."); + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " vtol parameter."); } #endif // HAS_Y_AXIS + #if ENABLED(FTM_SHAPER_Z) + + // Parse Z frequency parameter + if (parser.seenval('C')) { + if (AXIS_IS_SHAPING(Z)) { + const float val = parser.value_float(); + if (WITHIN(val, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2)) { + ftMotion.cfg.baseFreq.z = val; + flag.update = flag.report = true; + } + else // Frequency out of range. + SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_C_NAME), " frequency [", C('C'), "] value."); + } + else // Mode doesn't use frequency. + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " [", C('C'), "] frequency."); + } + + #if HAS_DYNAMIC_FREQ + // Parse Z frequency scaling parameter + if (parser.seenval('L')) { + if (modeUsesDynFreq) { + ftMotion.cfg.dynFreqK.z = parser.value_float(); + flag.report = true; + } + else + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " [", C('L'), "] frequency scaling."); + } + #endif + + // Parse Z zeta parameter + if (parser.seenval('O')) { + const float val = parser.value_float(); + if (AXIS_IS_SHAPING(Z)) { + if (WITHIN(val, 0.01f, 1.0f)) { + ftMotion.cfg.zeta.z = val; + flag.update = true; + } + else + SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_C_NAME), " zeta [", C('O'), "] value."); // Zeta out of range + } + else + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " zeta parameter."); + } + + // Parse Z vtol parameter + if (parser.seenval('M')) { + const float val = parser.value_float(); + if (AXIS_IS_EISHAPING(Z)) { + if (WITHIN(val, 0.00f, 1.0f)) { + ftMotion.cfg.vtol.z = val; + flag.update = true; + } + else + SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_C_NAME), " vtol [", C('M'), "] value."); // VTol out of range. + } + else + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " vtol parameter."); + } + + #endif // FTM_SHAPER_Z + + #if ENABLED(FTM_SHAPER_E) + + // Parse E frequency parameter + if (parser.seenval('W')) { + if (AXIS_IS_SHAPING(E)) { + const float val = parser.value_float(); + if (WITHIN(val, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2)) { + ftMotion.cfg.baseFreq.e = val; + flag.update = flag.report = true; + } + else // Frequency out of range. + SERIAL_ECHOLNPGM("?Invalid ", C('E'), " frequency [", C('W'), "] value."); + } + else // Mode doesn't use frequency. + SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " [", C('W'), "] frequency."); + } + + #if HAS_DYNAMIC_FREQ + // Parse E frequency scaling parameter + if (parser.seenval('O')) { + if (modeUsesDynFreq) { + ftMotion.cfg.dynFreqK.e = parser.value_float(); + flag.report = true; + } + else + SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " [", C('O'), "] frequency scaling."); + } + #endif + + // Parse E zeta parameter + if (parser.seenval('U')) { + const float val = parser.value_float(); + if (AXIS_IS_SHAPING(E)) { + if (WITHIN(val, 0.01f, 1.0f)) { + ftMotion.cfg.zeta.e = val; + flag.update = true; + } + else + SERIAL_ECHOLNPGM("?Invalid ", C('E'), " zeta [", C('U'), "] value."); // Zeta out of range + } + else + SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " zeta parameter."); + } + + // Parse E vtol parameter + if (parser.seenval('V')) { + const float val = parser.value_float(); + if (AXIS_IS_EISHAPING(E)) { + if (WITHIN(val, 0.00f, 1.0f)) { + ftMotion.cfg.vtol.e = val; + flag.update = true; + } + else + SERIAL_ECHOLNPGM("?Invalid ", C('E'), " vtol [", C('V'), "] value."); // VTol out of range. + } + else + SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " vtol parameter."); + } + + #endif // FTM_SHAPER_E + if (flag.update) ftMotion.update_shaping_params(); if (flag.report) say_shaping(); diff --git a/Marlin/src/gcode/feature/ft_motion/M494.cpp b/Marlin/src/gcode/feature/ft_motion/M494.cpp new file mode 100644 index 0000000000..10856be280 --- /dev/null +++ b/Marlin/src/gcode/feature/ft_motion/M494.cpp @@ -0,0 +1,137 @@ +/** + * 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 . + * + */ +#include "../../../inc/MarlinConfigPre.h" + +#if ENABLED(FT_MOTION) + +#include "../../gcode.h" +#include "../../../module/ft_motion.h" +#include "../../../module/stepper.h" +#include "../../../module/planner.h" + +static FSTR_P get_trajectory_type_name() { + switch (ftMotion.getTrajectoryType()) { + default: + case TrajectoryType::TRAPEZOIDAL: return GET_TEXT_F(MSG_FTM_TRAPEZOIDAL); + case TrajectoryType::POLY5: return GET_TEXT_F(MSG_FTM_POLY5); + case TrajectoryType::POLY6: return GET_TEXT_F(MSG_FTM_POLY6); + } +} + +void say_ftm_settings() { + SERIAL_ECHOLN(F(" Trajectory: "), get_trajectory_type_name(), C('('), (uint8_t)ftMotion.getTrajectoryType(), C(')')); + + const ft_config_t &c = ftMotion.cfg; + + if (ftMotion.getTrajectoryType() == TrajectoryType::POLY6) + SERIAL_ECHOLNPGM(" Poly6 Overshoot: ", p_float_t(c.poly6_acceleration_overshoot, 3)); + + #if ENABLED(FTM_SMOOTHING) + #define _SMOO_REPORT(A) SERIAL_ECHOLN(F(" "), C(IAXIS_CHAR(_AXIS(A))), F(" smoothing time: "), p_float_t(c.smoothingTime.A, 3), C('s')); + CARTES_MAP(_SMOO_REPORT); + #endif +} + +void GcodeSuite::M494_report(const bool forReplay/*=true*/) { + TERN_(MARLIN_SMALL_BUILD, return); + + const ft_config_t &c = ftMotion.cfg; + + report_heading_etc(forReplay, F("FT Motion")); + SERIAL_ECHOPGM(" M494 T", (uint8_t)ftMotion.getTrajectoryType()); + + #if ENABLED(FTM_SMOOTHING) + SERIAL_ECHOPGM( + CARTES_PAIRED_LIST( + " X", c.smoothingTime.X, " Y", c.smoothingTime.Y, + " Z", c.smoothingTime.Z, " E", c.smoothingTime.E + ) + ); + #endif + + if (ftMotion.getTrajectoryType() == TrajectoryType::POLY6) + SERIAL_ECHOPGM(" O", c.poly6_acceleration_overshoot); + + SERIAL_EOL(); +} + +/** + * M494: Set Fixed-time Motion Control parameters + * + * Parameters: + * T Set trajectory generator type (0=TRAPEZOIDAL, 1=POLY5, 2=POLY6) + * O Set acceleration overshoot for POLY6 (1.25-1.875) + * X