diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 77479946b5..96d6af1932 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -41,11 +41,11 @@ ] // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], + // , "forwardPorts": [] // Use 'postCreateCommand' to run commands after the container is created. - // "postCreateCommand": "pip3 install --user -r requirements.txt", + // , "postCreateCommand": "pip3 install --user -r requirements.txt" // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. - // "remoteUser": "vscode" + // , "remoteUser": "vscode" } diff --git a/.github/workflows/ci-build-tests.yml b/.github/workflows/ci-build-tests.yml index b3b0c94243..5d53536a27 100644 --- a/.github/workflows/ci-build-tests.yml +++ b/.github/workflows/ci-build-tests.yml @@ -58,7 +58,7 @@ jobs: - at90usb1286_dfu # AVR Extended - - FYSETC_F6 + - mega2560ext - melzi_optiboot - rambo - sanguino1284p diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 diff --git a/Makefile b/Makefile index f1f64e1342..68c522e5b6 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 which python 2>nul || which python3 2>nul || which 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" @@ -41,6 +66,9 @@ marlin: ./buildroot/bin/mftest -a .PHONY: marlin +clean: + rm -rf .pio/build* + tests-single-ci: export GIT_RESET_HARD=true $(MAKE) tests-single-local TEST_TARGET=$(TEST_TARGET) PLATFORMIO_BUILD_FLAGS=-DGITHUB_ACTION @@ -57,10 +85,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 +116,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 +155,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 +168,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..bd07add891 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -305,6 +305,18 @@ #endif +/** + * Differential Extruder + * + * The X and E steppers work together to create a differential drive system. + * Simple : E steps = X + E ; X steps = X (E drives a loop, X stays the same) + * Balanced: E steps = X + E/2 ; X steps = X - E/2 (Dual loop system) + */ +//#define DIFFERENTIAL_EXTRUDER +#if ENABLED(DIFFERENTIAL_EXTRUDER) + //#define BALANCED_DIFFERENTIAL_EXTRUDER +#endif + /** * Switching Toolhead * @@ -706,13 +718,13 @@ #if ENABLED(PID_PARAMS_PER_HOTEND) // Specify up to one value per hotend here, according to your setup. // If there are fewer values, the last one applies to the remaining hotends. - #define DEFAULT_Kp_LIST { 22.20, 22.20 } - #define DEFAULT_Ki_LIST { 1.08, 1.08 } - #define DEFAULT_Kd_LIST { 114.00, 114.00 } + #define DEFAULT_KP_LIST { 22.20, 22.20 } + #define DEFAULT_KI_LIST { 1.08, 1.08 } + #define DEFAULT_KD_LIST { 114.00, 114.00 } #else - #define DEFAULT_Kp 22.20 - #define DEFAULT_Ki 1.08 - #define DEFAULT_Kd 114.00 + #define DEFAULT_KP 22.20 + #define DEFAULT_KI 1.08 + #define DEFAULT_KD 114.00 #endif #else #define BANG_MAX 255 // Limit hotend current while in bang-bang mode; 255=full current @@ -810,9 +822,9 @@ // 120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+) // from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10) - #define DEFAULT_bedKp 10.00 - #define DEFAULT_bedKi 0.023 - #define DEFAULT_bedKd 305.4 + #define DEFAULT_BED_KP 10.00 + #define DEFAULT_BED_KI 0.023 + #define DEFAULT_BED_KD 305.4 // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles. #else @@ -893,9 +905,9 @@ // Lasko "MyHeat Personal Heater" (200w) modified with a Fotek SSR-10DA to control only the heating element // and placed inside the small Creality printer enclosure tent. - #define DEFAULT_chamberKp 37.04 - #define DEFAULT_chamberKi 1.40 - #define DEFAULT_chamberKd 655.17 + #define DEFAULT_CHAMBER_KP 37.04 + #define DEFAULT_CHAMBER_KI 1.40 + #define DEFAULT_CHAMBER_KD 655.17 // M309 P37.04 I1.04 D655.17 // FIND YOUR OWN: "M303 E-2 C8 S50" to run autotune on the chamber at 50 degreesC for 8 cycles. @@ -942,7 +954,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 @@ -1053,7 +1065,8 @@ // Delta radius and diagonal rod adjustments //#define DELTA_RADIUS_TRIM_TOWER { 0.0, 0.0, 0.0 } // (mm) //#define DELTA_DIAGONAL_ROD_TRIM_TOWER { 0.0, 0.0, 0.0 } // (mm) -#endif + +#endif // DELTA // @section scara @@ -1109,17 +1122,37 @@ #define TPARA_LINKAGE_1 120 // (mm) #define TPARA_LINKAGE_2 120 // (mm) - // TPARA tower offset (position of Tower relative to bed zero position) + // Height of the Shoulder axis (pivot) relative to the tower floor + #define TPARA_SHOULDER_AXIS_HEIGHT 135.0 // (mm) + + // The position of the last linkage relative to the robot arm origin + // (intersection of the base axis and floor) when at the home position + #define TPARA_ARM_X_HOME_POS 28.75 // (mm) Measured from shoulder axis to tool holder axis in home position + #define TPARA_ARM_Y_HOME_POS 0 // (mm) + #define TPARA_ARM_Z_HOME_POS 250.00 // (mm) Measured from tool holder axis to the floor + + // TPARA Workspace offset relative to the tower (position of workspace origin relative to robot Tower origin ) // This needs to be reasonably accurate as it defines the printbed position in the TPARA space. - #define TPARA_OFFSET_X 0 // (mm) - #define TPARA_OFFSET_Y 0 // (mm) - #define TPARA_OFFSET_Z 0 // (mm) + #define TPARA_OFFSET_X 127.0 // (mm) to coincide with minimum radius MIDDLE_DEAD_ZONE_R, and W(0,0,0) is reachable + #define TPARA_OFFSET_Y 0.0 // (mm) + #define TPARA_OFFSET_Z 0.0 // (mm) + + // TPARA tool connection point offset, relative to the tool moving frame origin which is in the last linkage axis, + // (TCP: tool center/connection point) of the robot, + // the plane of measured offset must be alligned with home position plane + #define TPARA_TCP_OFFSET_X 27.0 // (mm) Tool flange: 27 (distance from pivot to bolt holes), extruder tool: 50.0, + #define TPARA_TCP_OFFSET_Y 0.0 // (mm) + #define TPARA_TCP_OFFSET_Z -65.0 // (mm) Tool flange (bottom): -6 (caution as Z 0 posiion will crash second linkage to the floor, -35 is safe for testing with no tool), extruder tool (depends on extruder): -65.0 #define FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly // Radius around the center where the arm cannot reach - #define MIDDLE_DEAD_ZONE_R 0 // (mm) -#endif + // For now use a hardcoded uniform limit, although it should be calculated, or fix a limit for each axis angle + #define MIDDLE_DEAD_ZONE_R 100 // (mm) + + // Max angle between L1 and L2 + #define TPARA_MAX_L1L2_ANGLE 140.0f // (degrees) +#endif // AXEL_TPARA // @section polar @@ -1395,6 +1428,11 @@ * See https://github.com/synthetos/TinyG/wiki/Jerk-Controlled-Motion-Explained */ //#define S_CURVE_ACCELERATION +#if ENABLED(S_CURVE_ACCELERATION) + // Define to use 4th instead of 6th order motion curve + //#define S_CURVE_FACTOR 0.25 // Initial and final acceleration factor, ideally 0.1 to 0.4. + // Shouldn't generally require tuning. +#endif //=========================================================================== //============================= Z Probe Options ============================= @@ -1623,7 +1661,7 @@ * Nozzle-to-Probe offsets { X, Y, Z } * * X and Y offset - * Use a caliper or ruler to measure the distance from the tip of + * Use a caliper or ruler to measure the distance (in mm) from the tip of * the Nozzle to the center-point of the Probe in the X and Y axes. * * Z offset @@ -1659,7 +1697,7 @@ * | [-] | * O-- FRONT --+ */ -#define NOZZLE_TO_PROBE_OFFSET { 10, 10, 0 } +#define NOZZLE_TO_PROBE_OFFSET { 10, 10, 0 } // (mm) X, Y, Z distance from Nozzle tip to Probe trigger-point // Enable and set to use a specific tool for probing. Disable to allow any tool. #define PROBING_TOOL 0 @@ -1667,6 +1705,8 @@ //#define PROBE_TOOLCHANGE_NO_MOVE // Suppress motion on probe tool-change #endif +//#define PROBE_WAKEUP_TIME_MS 30 // (ms) Time for the probe to wake up + // Most probes should stay away from the edges of the bed, but // with NOZZLE_AS_PROBE this can be negative for a wider probing area. #define PROBING_MARGIN 10 @@ -3468,6 +3508,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 +3518,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..b8d7ed694d 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. @@ -415,14 +415,19 @@ // A well-chosen Kc value should add just enough power to melt the increased material volume. //#define PID_EXTRUSION_SCALING #if ENABLED(PID_EXTRUSION_SCALING) - #define DEFAULT_Kc (100) // heating power = Kc * e_speed #define LPQ_MAX_LEN 50 + #define DEFAULT_KC 100 // heating power = Kc * e_speed + #if ENABLED(PID_PARAMS_PER_HOTEND) + // Specify up to one value per hotend here, according to your setup. + // If there are fewer values, the last one applies to the remaining hotends. + #define DEFAULT_KC_LIST { DEFAULT_KC, DEFAULT_KC } // heating power = Kc * e_speed + #endif #endif /** * Add an additional term to the heater power, proportional to the fan speed. * A well-chosen Kf value should add just enough power to compensate for power-loss from the cooling fan. - * You can either just add a constant compensation with the DEFAULT_Kf value + * You can either just add a constant compensation with the DEFAULT_KF value * or follow the instruction below to get speed-dependent compensation. * * Constant compensation (use only with fan speeds of 0% and 100%) @@ -453,21 +458,26 @@ #if ENABLED(PID_FAN_SCALING_ALTERNATIVE_DEFINITION) // The alternative definition is used for an easier configuration. // Just figure out Kf at full speed (255) and PID_FAN_SCALING_MIN_SPEED. - // DEFAULT_Kf and PID_FAN_SCALING_LIN_FACTOR are calculated accordingly. + // DEFAULT_KF and PID_FAN_SCALING_LIN_FACTOR are calculated accordingly. - #define PID_FAN_SCALING_AT_FULL_SPEED 13.0 //=PID_FAN_SCALING_LIN_FACTOR*255+DEFAULT_Kf - #define PID_FAN_SCALING_AT_MIN_SPEED 6.0 //=PID_FAN_SCALING_LIN_FACTOR*PID_FAN_SCALING_MIN_SPEED+DEFAULT_Kf + #define PID_FAN_SCALING_AT_FULL_SPEED 13.0 //=PID_FAN_SCALING_LIN_FACTOR*255+DEFAULT_KF + #define PID_FAN_SCALING_AT_MIN_SPEED 6.0 //=PID_FAN_SCALING_LIN_FACTOR*PID_FAN_SCALING_MIN_SPEED+DEFAULT_KF #define PID_FAN_SCALING_MIN_SPEED 10.0 // Minimum fan speed at which to enable PID_FAN_SCALING - #define DEFAULT_Kf (255.0*PID_FAN_SCALING_AT_MIN_SPEED-PID_FAN_SCALING_AT_FULL_SPEED*PID_FAN_SCALING_MIN_SPEED)/(255.0-PID_FAN_SCALING_MIN_SPEED) - #define PID_FAN_SCALING_LIN_FACTOR (PID_FAN_SCALING_AT_FULL_SPEED-DEFAULT_Kf)/255.0 + #define DEFAULT_KF (255.0*PID_FAN_SCALING_AT_MIN_SPEED-PID_FAN_SCALING_AT_FULL_SPEED*PID_FAN_SCALING_MIN_SPEED)/(255.0-PID_FAN_SCALING_MIN_SPEED) + #define PID_FAN_SCALING_LIN_FACTOR (PID_FAN_SCALING_AT_FULL_SPEED-DEFAULT_KF)/255.0 #else #define PID_FAN_SCALING_LIN_FACTOR (0) // Power-loss due to cooling = Kf * (fan_speed) - #define DEFAULT_Kf 10 // A constant value added to the PID-tuner + #define DEFAULT_KF 10 // A constant value added to the PID-tuner #define PID_FAN_SCALING_MIN_SPEED 10 // Minimum fan speed at which to enable PID_FAN_SCALING #endif #endif + #if ENABLED(PID_PARAMS_PER_HOTEND) + // Specify up to one value per hotend here, according to your setup. + // If there are fewer values, the last one applies to the remaining hotends. + #define DEFAULT_KF_LIST { DEFAULT_KF, DEFAULT_KF } + #endif #endif /** @@ -486,15 +496,15 @@ #define AUTOTEMP #if ENABLED(AUTOTEMP) #define AUTOTEMP_OLDWEIGHT 0.98 // Factor used to weight previous readings (0.0 < value < 1.0) - #define AUTOTEMP_MIN 210 - #define AUTOTEMP_MAX 250 + #define AUTOTEMP_MIN 210 + #define AUTOTEMP_MAX 250 #define AUTOTEMP_FACTOR 0.1f // Turn on AUTOTEMP on M104/M109 by default using proportions set here //#define AUTOTEMP_PROPORTIONAL #if ENABLED(AUTOTEMP_PROPORTIONAL) - #define AUTOTEMP_MIN_P 0 // (°C) Added to the target temperature - #define AUTOTEMP_MAX_P 5 // (°C) Added to the target temperature - #define AUTOTEMP_FACTOR_P 1 // Apply this F parameter by default (overridden by M104/M109 F) + #define AUTOTEMP_MIN_P 0 // (°C) Added to the target temperature + #define AUTOTEMP_MAX_P 5 // (°C) Added to the target temperature + #define AUTOTEMP_FACTOR_P 1 // Apply this F parameter by default (overridden by M104/M109 F) #endif #endif @@ -778,7 +788,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,67 +1153,91 @@ /** * 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_DEFAULT_DYNFREQ_MODE dynFreqMode_DISABLED // Default mode of dynamic frequency calculation. (DISABLED, Z_BASED, MASS_BASED) + //#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_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 NO_STANDARD_MOTION // Disable the standard motion system entirely to save Flash and RAM + #if DISABLED(NO_STANDARD_MOTION) + //#define FTM_HOME_AND_PROBE // Use FT Motion for homing / probing. Disable if FT Motion breaks these functions. + #endif + + //#define FTM_DYNAMIC_FREQ // Enable for linear adjustment of XY shaping frequency according to Z or E + #if ENABLED(FTM_DYNAMIC_FREQ) + #define FTM_DEFAULT_DYNFREQ_MODE dynFreqMode_DISABLED // Default mode of dynamic frequency calculation. (DISABLED, Z_BASED, MASS_BASED) + #endif + + // Disable unused shapers if you need more free space + #define FTM_SHAPER_ZV + #define FTM_SHAPER_ZVD + #define FTM_SHAPER_ZVDD + #define FTM_SHAPER_ZVDDD + #define FTM_SHAPER_EI + #define FTM_SHAPER_2HEI + #define FTM_SHAPER_3HEI + #define FTM_SHAPER_MZV #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_RESONANCE_TEST // Sine sweep motion for resonance study + + //#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_POLYS // Disable POLY5/6 to save ~3k of Flash. Preserves TRAPEZOIDAL. + #if ENABLED(FTM_POLYS) + #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 uses less CPU. + // 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) + #endif /** * Advanced configuration */ - #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 - #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 - #endif + #define FTM_BUFFER_SIZE 128 // Window size for trajectory generation, must be a power of 2 (e.g 64, 128, 256, ...) + // The total buffered time in seconds is (FTM_BUFFER_SIZE/FTM_FS) + #define FTM_FS 1000 // (Hz) Frequency for trajectory generation. + #define FTM_MIN_SHAPE_FREQ 20 // (Hz) Minimum shaping frequency, lower consumes more RAM - #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) - - #if DISABLED(COREXY) - #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 - - #else - // CoreXY motion needs a larger buffer size. These values are based on our testing. - #define FTM_STEPPER_FS 30000 - #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 #endif // FT_MOTION /** @@ -1623,7 +1657,7 @@ #if HAS_MARLINUI_U8GLIB //#define BOOT_MARLIN_LOGO_ANIMATED // Animated Marlin logo. Costs ~3260 (or ~940) bytes of flash. #endif - #if ANY(HAS_MARLINUI_U8GLIB, TOUCH_UI_FTDI_EVE, HAS_MARLINUI_HD44780) + #if ANY(HAS_MARLINUI_U8GLIB, TOUCH_UI_FTDI_EVE, HAS_MARLINUI_HD44780, HAS_GRAPHICAL_TFT) //#define SHOW_CUSTOM_BOOTSCREEN // Show the bitmap in Marlin/_Bootscreen.h on startup. #endif #endif @@ -1779,6 +1813,14 @@ #define PE_LEDS_COMPLETED_TIME (30*60) // (seconds) Time to keep the LED "done" color before restoring normal illumination #endif + /** + * Priming for the Remaining Time estimate + * Long processes at the start of a G-code file can skew the Remaining Time estimate. + * Enable these options to start this estimation at a later point in the G-code file. + */ + //#define REMAINING_TIME_PRIME // Provide G-code 'M75 R' to prime the Remaining Time estimate + //#define REMAINING_TIME_AUTOPRIME // Prime the Remaining Time estimate later (e.g., at the end of 'M109') + /** * Continue after Power-Loss (Creality3D) * @@ -1790,6 +1832,8 @@ //#define POWER_LOSS_RECOVERY #if ENABLED(POWER_LOSS_RECOVERY) #define PLR_ENABLED_DEFAULT false // Power-Loss Recovery enabled by default. (Set with 'M413 Sn' & M500) + //#define PLR_HEAT_BED_ON_REBOOT // Heat up bed immediately on reboot to mitigate object detaching/warping. + //#define PLR_HEAT_BED_EXTRA 0 // (°C) Relative increase of bed temperature for better adhesion (limited by max temp). //#define PLR_BED_THRESHOLD BED_MAXTEMP // (°C) Skip user confirmation at or above this bed temperature (0 to disable) //#define POWER_LOSS_PIN 44 // Pin to detect power-loss. Set to -1 to disable default pin on boards without module, or comment to use board default. @@ -1853,6 +1897,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 @@ -2363,13 +2408,17 @@ * See https://marlinfw.org/docs/features/lin_advance.html for full instructions. */ //#define LIN_ADVANCE -#if ENABLED(LIN_ADVANCE) + +#if ANY(LIN_ADVANCE, FT_MOTION) #if ENABLED(DISTINCT_E_FACTORS) - #define ADVANCE_K { 0.22 } // (mm) Compression length per 1mm/s extruder speed, per extruder + #define ADVANCE_K { 0.22 } // (mm) Compression length per 1mm/s extruder speed, per extruder. Override with 'M900 T K'. #else - #define ADVANCE_K 0.22 // (mm) Compression length applying to all extruders + #define ADVANCE_K 0.22 // (mm) Compression length for all extruders. Override with 'M900 K'. #endif - //#define ADVANCE_K_EXTRA // Add a second linear advance constant, configurable with M900 L. + //#define ADVANCE_K_EXTRA // Add a second linear advance constant, configurable with 'M900 L'. +#endif + +#if ENABLED(LIN_ADVANCE) //#define LA_DEBUG // Print debug information to serial during operation. Disable for production use. //#define EXPERIMENTAL_I2S_LA // Allow I2S_STEPPER_STREAM to be used with LA. Performance degrades as the LA step rate reaches ~20kHz. @@ -4081,13 +4130,17 @@ /** * G-code Macros * - * Add G-codes M810-M819 to define and run G-code macros. - * Macros are not saved to EEPROM. + * Add G-codes M810-M819 to define and run G-code macros + * and M820 to report the current set of macros. + * Macros are not saved to EEPROM unless enabled below. */ //#define GCODE_MACROS #if ENABLED(GCODE_MACROS) #define GCODE_MACROS_SLOTS 5 // Up to 10 may be used #define GCODE_MACROS_SLOT_SIZE 50 // Maximum length of a single macro + #if ENABLED(EEPROM_SETTINGS) + //#define GCODE_MACROS_IN_EEPROM // Include macros in EEPROM + #endif #endif /** @@ -4109,22 +4162,27 @@ #define MAIN_MENU_ITEM_1_DESC "Home & UBL Info" #define MAIN_MENU_ITEM_1_GCODE "G28\nG29 W" //#define MAIN_MENU_ITEM_1_CONFIRM // Show a confirmation dialog before this action + //#define MAIN_MENU_ITEM_1_IMMEDIATE // Skip the queue and execute immediately. Rarely needed. #define MAIN_MENU_ITEM_2_DESC "Preheat for " PREHEAT_1_LABEL #define MAIN_MENU_ITEM_2_GCODE "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) //#define MAIN_MENU_ITEM_2_CONFIRM + //#define MAIN_MENU_ITEM_2_IMMEDIATE //#define MAIN_MENU_ITEM_3_DESC "Preheat for " PREHEAT_2_LABEL //#define MAIN_MENU_ITEM_3_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) //#define MAIN_MENU_ITEM_3_CONFIRM + //#define MAIN_MENU_ITEM_3_IMMEDIATE //#define MAIN_MENU_ITEM_4_DESC "Heat Bed/Home/Level" //#define MAIN_MENU_ITEM_4_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" //#define MAIN_MENU_ITEM_4_CONFIRM + //#define MAIN_MENU_ITEM_4_IMMEDIATE //#define MAIN_MENU_ITEM_5_DESC "Home & Info" //#define MAIN_MENU_ITEM_5_GCODE "G28\nM503" //#define MAIN_MENU_ITEM_5_CONFIRM + //#define MAIN_MENU_ITEM_5_IMMEDIATE #endif // @section custom config menu @@ -4141,22 +4199,27 @@ #define CONFIG_MENU_ITEM_1_DESC "Wifi ON" #define CONFIG_MENU_ITEM_1_GCODE "M118 [ESP110] WIFI-STA pwd=12345678" //#define CONFIG_MENU_ITEM_1_CONFIRM // Show a confirmation dialog before this action + //#define CONFIG_MENU_ITEM_1_IMMEDIATE // Skip the queue and execute immediately. Rarely needed. #define CONFIG_MENU_ITEM_2_DESC "Bluetooth ON" #define CONFIG_MENU_ITEM_2_GCODE "M118 [ESP110] BT pwd=12345678" //#define CONFIG_MENU_ITEM_2_CONFIRM + //#define CONFIG_MENU_ITEM_2_IMMEDIATE //#define CONFIG_MENU_ITEM_3_DESC "Radio OFF" //#define CONFIG_MENU_ITEM_3_GCODE "M118 [ESP110] OFF pwd=12345678" //#define CONFIG_MENU_ITEM_3_CONFIRM + //#define CONFIG_MENU_ITEM_3_IMMEDIATE //#define CONFIG_MENU_ITEM_4_DESC "Wifi ????" //#define CONFIG_MENU_ITEM_4_GCODE "M118 ????" //#define CONFIG_MENU_ITEM_4_CONFIRM + //#define CONFIG_MENU_ITEM_4_IMMEDIATE //#define CONFIG_MENU_ITEM_5_DESC "Wifi ????" //#define CONFIG_MENU_ITEM_5_GCODE "M118 ????" //#define CONFIG_MENU_ITEM_5_CONFIRM + //#define CONFIG_MENU_ITEM_5_IMMEDIATE #endif // @section custom buttons @@ -4173,6 +4236,7 @@ #define BUTTON1_WHEN_PRINTING false // Button allowed to trigger during printing? #define BUTTON1_GCODE "G28" #define BUTTON1_DESC "Homing" // Optional string to set the LCD status + //#define BUTTON1_IMMEDIATE // Skip the queue and execute immediately. Rarely needed. #endif //#define BUTTON2_PIN -1 @@ -4181,6 +4245,7 @@ #define BUTTON2_WHEN_PRINTING false #define BUTTON2_GCODE "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) #define BUTTON2_DESC "Preheat for " PREHEAT_1_LABEL + //#define BUTTON2_IMMEDIATE #endif //#define BUTTON3_PIN -1 @@ -4189,6 +4254,7 @@ #define BUTTON3_WHEN_PRINTING false #define BUTTON3_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) #define BUTTON3_DESC "Preheat for " PREHEAT_2_LABEL + //#define BUTTON3_IMMEDIATE #endif #endif @@ -4261,7 +4327,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 +4759,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/Makefile b/Marlin/Makefile index fb1786b6b0..aed2506ac8 100644 --- a/Marlin/Makefile +++ b/Marlin/Makefile @@ -188,15 +188,15 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1033) else ifeq ($(HARDWARE_MOTHERBOARD),1034) # RAMPS 1.6+ (Power outputs: Hotend, Fan, Bed) -else ifeq ($(HARDWARE_MOTHERBOARD),1035) +else ifeq ($(HARDWARE_MOTHERBOARD),1040) # RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Bed) -else ifeq ($(HARDWARE_MOTHERBOARD),1036) +else ifeq ($(HARDWARE_MOTHERBOARD),1041) # RAMPS 1.6+ (Power outputs: Hotend, Fan0, Fan1) -else ifeq ($(HARDWARE_MOTHERBOARD),1037) +else ifeq ($(HARDWARE_MOTHERBOARD),1042) # RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Fan) -else ifeq ($(HARDWARE_MOTHERBOARD),1038) +else ifeq ($(HARDWARE_MOTHERBOARD),1043) # RAMPS 1.6+ (Power outputs: Spindle, Controller Fan) -else ifeq ($(HARDWARE_MOTHERBOARD),1039) +else ifeq ($(HARDWARE_MOTHERBOARD),1044) # # RAMPS Derivatives - ATmega1280, ATmega2560 @@ -286,60 +286,62 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1138) else ifeq ($(HARDWARE_MOTHERBOARD),1139) # Creality: CR10S, CR20, CR-X else ifeq ($(HARDWARE_MOTHERBOARD),1140) -# Dagoma F5 +# Creality CR-10 V2, CR-10 V3 else ifeq ($(HARDWARE_MOTHERBOARD),1141) -# Dagoma D6 (as found in the Dagoma DiscoUltimate V2 TMC) +# Dagoma F5 else ifeq ($(HARDWARE_MOTHERBOARD),1142) -# FYSETC F6 1.3 +# Dagoma D6 (as found in the Dagoma DiscoUltimate V2 TMC) else ifeq ($(HARDWARE_MOTHERBOARD),1143) -# FYSETC F6 1.4 +# FYSETC F6 1.3 else ifeq ($(HARDWARE_MOTHERBOARD),1144) -# Wanhao Duplicator i3 Plus +# FYSETC F6 1.4 else ifeq ($(HARDWARE_MOTHERBOARD),1145) -# VORON Design +# Wanhao Duplicator i3 Plus else ifeq ($(HARDWARE_MOTHERBOARD),1146) -# Tronxy TRONXY-V3-1.0 +# VORON Design else ifeq ($(HARDWARE_MOTHERBOARD),1147) -# Z-Bolt X Series +# Tronxy TRONXY-V3-1.0 else ifeq ($(HARDWARE_MOTHERBOARD),1148) -# TT OSCAR +# Z-Bolt X Series else ifeq ($(HARDWARE_MOTHERBOARD),1149) -# BIQU Tango V1 +# TT OSCAR else ifeq ($(HARDWARE_MOTHERBOARD),1150) -# MKS GEN L V2 +# BIQU Tango V1 else ifeq ($(HARDWARE_MOTHERBOARD),1151) -# MKS GEN L V2.1 +# MKS GEN L V2 else ifeq ($(HARDWARE_MOTHERBOARD),1152) -# Copymaster 3D +# MKS GEN L V2.1 else ifeq ($(HARDWARE_MOTHERBOARD),1153) -# Ortur 4 +# Copymaster 3D else ifeq ($(HARDWARE_MOTHERBOARD),1154) -# Tenlog D3 Hero IDEX printer +# Ortur 4 else ifeq ($(HARDWARE_MOTHERBOARD),1155) -# Tenlog D3, D5, D6 IDEX Printer +# Tenlog D3 Hero IDEX printer else ifeq ($(HARDWARE_MOTHERBOARD),1156) -# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Fan, Bed) +# Tenlog D3, D5, D6 IDEX Printer else ifeq ($(HARDWARE_MOTHERBOARD),1157) -# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Hotend2, Bed) +# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Fan, Bed) else ifeq ($(HARDWARE_MOTHERBOARD),1158) -# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend, Fan0, Fan1, Bed) +# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Hotend2, Bed) else ifeq ($(HARDWARE_MOTHERBOARD),1159) -# Longer LK1 PRO / Alfawise U20 Pro (PRO version) +# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend, Fan0, Fan1, Bed) else ifeq ($(HARDWARE_MOTHERBOARD),1160) -# Longer LKx PRO / Alfawise Uxx Pro (PRO version) +# Longer LK1 PRO / Alfawise U20 Pro (PRO version) else ifeq ($(HARDWARE_MOTHERBOARD),1161) -# Pxmalion Core I3 +# Longer LKx PRO / Alfawise Uxx Pro (PRO version) else ifeq ($(HARDWARE_MOTHERBOARD),1162) -# Panowin Cutlass (as found in the Panowin F1) +# Pxmalion Core I3 else ifeq ($(HARDWARE_MOTHERBOARD),1163) -# Kodama Bardo V1.x (as found in the Kodama Trinus) +# Panowin Cutlass (as found in the Panowin F1) else ifeq ($(HARDWARE_MOTHERBOARD),1164) -# XTLW MFF V1.0 +# Kodama Bardo V1.x (as found in the Kodama Trinus) else ifeq ($(HARDWARE_MOTHERBOARD),1165) -# XTLW MFF V2.0 +# XTLW MFF V1.0 else ifeq ($(HARDWARE_MOTHERBOARD),1166) -# E3D Rumba BigBox +# XTLW MFF V2.0 else ifeq ($(HARDWARE_MOTHERBOARD),1167) +# E3D Rumba BigBox +else ifeq ($(HARDWARE_MOTHERBOARD),1168) # # RAMBo and derivatives @@ -408,32 +410,34 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1319) else ifeq ($(HARDWARE_MOTHERBOARD),1320) # Geeetech GT2560 Rev B for A20(M/T/D) else ifeq ($(HARDWARE_MOTHERBOARD),1321) -# Einstart retrofit -else ifeq ($(HARDWARE_MOTHERBOARD),1322) -# Wanhao 0ne+ i3 Mini -else ifeq ($(HARDWARE_MOTHERBOARD),1323) -# Overlord/Overlord Pro -else ifeq ($(HARDWARE_MOTHERBOARD),1324) -# ADIMLab Gantry v1 -else ifeq ($(HARDWARE_MOTHERBOARD),1325) -# ADIMLab Gantry v2 -else ifeq ($(HARDWARE_MOTHERBOARD),1326) -# Leapfrog Xeed 2015 -else ifeq ($(HARDWARE_MOTHERBOARD),1327) -# PICA Shield (original version) -else ifeq ($(HARDWARE_MOTHERBOARD),1328) -# PICA Shield (rev C or later) -else ifeq ($(HARDWARE_MOTHERBOARD),1329) -# Intamsys 4.0 (Funmat HT) -else ifeq ($(HARDWARE_MOTHERBOARD),1330) -# Malyan M180 Mainboard Version 2 (no display function, direct G-code only) -else ifeq ($(HARDWARE_MOTHERBOARD),1331) -# Mega controller & Protoneer CNC Shield V3.00 -else ifeq ($(HARDWARE_MOTHERBOARD),1332) -# WEEDO 62A board (TINA2, Monoprice Cadet, etc.) -else ifeq ($(HARDWARE_MOTHERBOARD),1333) # Geeetech GT2560 V4.1B for A10(M/T/D) +else ifeq ($(HARDWARE_MOTHERBOARD),1322) +# Einstart retrofit +else ifeq ($(HARDWARE_MOTHERBOARD),1323) +# Wanhao 0ne+ i3 Mini +else ifeq ($(HARDWARE_MOTHERBOARD),1324) +# Wanhao D9 MK2 +else ifeq ($(HARDWARE_MOTHERBOARD),1325) +# Overlord/Overlord Pro +else ifeq ($(HARDWARE_MOTHERBOARD),1326) +# ADIMLab Gantry v1 +else ifeq ($(HARDWARE_MOTHERBOARD),1327) +# ADIMLab Gantry v2 +else ifeq ($(HARDWARE_MOTHERBOARD),1328) +# Leapfrog Xeed 2015 +else ifeq ($(HARDWARE_MOTHERBOARD),1329) +# PICA Shield (original version) +else ifeq ($(HARDWARE_MOTHERBOARD),1330) +# PICA Shield (rev C or later) +else ifeq ($(HARDWARE_MOTHERBOARD),1331) +# Intamsys 4.0 (Funmat HT) +else ifeq ($(HARDWARE_MOTHERBOARD),1332) +# Malyan M180 Mainboard Version 2 +else ifeq ($(HARDWARE_MOTHERBOARD),1333) +# Mega controller & Protoneer CNC Shield V3.00 else ifeq ($(HARDWARE_MOTHERBOARD),1334) +# WEEDO 62A board (TINA2, Monoprice Cadet, etc.) +else ifeq ($(HARDWARE_MOTHERBOARD),1335) # # ATmega1281, ATmega2561 @@ -513,7 +517,7 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1511) MCU ?= atmega1284p PROG_MCU ?= m1284p # ZoneStar ZMIB V2 -else ifeq ($(HARDWARE_MOTHERBOARD),1511) +else ifeq ($(HARDWARE_MOTHERBOARD),1512) HARDWARE_VARIANT ?= Sanguino MCU ?= atmega1284p PROG_MCU ?= m1284p @@ -627,6 +631,10 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1707) MCU ?= at90usb1286 PROG_MCU ?= usb1286 +# +# SAM3X8E ARM Cortex-M3 +# + # UltiMachine Archim1 (with DRV8825 drivers) else ifeq ($(HARDWARE_MOTHERBOARD),3023) HARDWARE_VARIANT ?= archim diff --git a/Marlin/Version.h b/Marlin/Version.h index c6b0482653..926bddf13f 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-12-14" /** * The protocol for communication to the host. Protocol indicates communication diff --git a/Marlin/config.ini b/Marlin/config.ini index d6d2395e39..fd2b81062a 100644 --- a/Marlin/config.ini +++ b/Marlin/config.ini @@ -86,13 +86,14 @@ heater_0_maxtemp = 275 pidtemp = on pid_k1 = 0.95 pid_max = 255 -pid_functional_range = 10 +pid_functional_range = 20 default_kp = 22.20 default_ki = 1.08 default_kd = 114.00 temp_sensor_bed = 1 +bed_check_interval = 5000 bed_mintemp = 5 bed_maxtemp = 150 @@ -163,18 +164,28 @@ min_steps_per_segment = 6 default_minsegmenttime = 20000 [config:basic] +hotend_overshoot = 15 bed_overshoot = 10 +max_bed_power = 255 + busy_while_heating = on +host_keepalive_feature = on default_keepalive_interval = 2 +printjob_timer_autostart = on + +jd_handle_small_segments = on +validate_homing_endstops = on +editable_steps_per_unit = on + eeprom_boot_silent = on eeprom_chitchat = on + endstoppullups = on -extrude_maxlength = 200 + +prevent_cold_extrusion = on extrude_mintemp = 170 -host_keepalive_feature = on -hotend_overshoot = 15 -jd_handle_small_segments = on -max_bed_power = 255 +prevent_lengthy_extrude = on +extrude_maxlength = 200 min_software_endstops = on max_software_endstops = on @@ -195,21 +206,19 @@ preheat_2_temp_hotend = 240 preheat_2_temp_bed = 110 preheat_2_fan_speed = 0 -prevent_cold_extrusion = on -prevent_lengthy_extrude = on -printjob_timer_autostart = on - temp_bed_hysteresis = 3 temp_bed_residency_time = 10 temp_bed_window = 1 temp_residency_time = 10 temp_window = 1 -validate_homing_endstops = on - -editable_steps_per_unit = on [config:advanced] arc_support = on +min_arc_segment_mm = 0.1 +max_arc_segment_mm = 1.0 +min_circle_segments = 72 +n_arc_correction = 25 + auto_report_temperatures = on autotemp = on @@ -223,22 +232,23 @@ disable_idle_x = on disable_idle_y = on disable_idle_z = on disable_idle_e = on + e0_auto_fan_pin = -1 + faster_gcode_parser = on debug_flags_gcode = on + homing_bump_mm = { 5, 5, 2 } -max_arc_segment_mm = 1.0 -min_arc_segment_mm = 0.1 -min_circle_segments = 72 -n_arc_correction = 25 -serial_overrun_protection = on + slowdown = on slowdown_divisor = 2 -tx_buffer_size = 0 +multistepping_limit = 16 -bed_check_interval = 5000 -watch_bed_temp_increase = 2 -watch_bed_temp_period = 60 +serial_overrun_protection = on +tx_buffer_size = 0 watch_temp_increase = 2 watch_temp_period = 40 + +watch_bed_temp_increase = 2 +watch_bed_temp_period = 60 diff --git a/Marlin/src/HAL/AVR/HAL.cpp b/Marlin/src/HAL/AVR/HAL.cpp index 97173c63f9..4fbab8941f 100644 --- a/Marlin/src/HAL/AVR/HAL.cpp +++ b/Marlin/src/HAL/AVR/HAL.cpp @@ -119,7 +119,6 @@ void MarlinHAL::reboot() { #if ENABLED(USE_WATCHDOG) #include - #include "../../MarlinCore.h" // Initialize watchdog with 8s timeout, if possible. Otherwise, make it 4s. void MarlinHAL::watchdog_init() { @@ -154,7 +153,7 @@ void MarlinHAL::reboot() { ISR(WDT_vect) { sei(); // With the interrupt driven serial we need to allow interrupts. SERIAL_ERROR_MSG(STR_WATCHDOG_FIRED); - minkill(); // interrupt-safe final kill and infinite loop + marlin.minkill(); // interrupt-safe final kill and infinite loop } #endif diff --git a/Marlin/src/HAL/AVR/HAL.h b/Marlin/src/HAL/AVR/HAL.h index e7a82a3b83..02c5d42beb 100644 --- a/Marlin/src/HAL/AVR/HAL.h +++ b/Marlin/src/HAL/AVR/HAL.h @@ -206,7 +206,7 @@ public: static void delay_ms(const int ms) { delay(ms); } - // Tasks, called from idle() + // Tasks, called from marlin.idle() static void idletask() {} // Reset diff --git a/Marlin/src/HAL/AVR/MarlinSerial.cpp b/Marlin/src/HAL/AVR/MarlinSerial.cpp index d070731418..750776c4be 100644 --- a/Marlin/src/HAL/AVR/MarlinSerial.cpp +++ b/Marlin/src/HAL/AVR/MarlinSerial.cpp @@ -41,7 +41,6 @@ #if !defined(USBCON) && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H)) #include "MarlinSerial.h" -#include "../../MarlinCore.h" #if ENABLED(DIRECT_STEPPING) #include "../../feature/direct_stepping.h" diff --git a/Marlin/src/HAL/AVR/fastio.cpp b/Marlin/src/HAL/AVR/fastio.cpp index 5c6ef18915..98fd636ebf 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. @@ -254,7 +254,7 @@ uint16_t set_pwm_frequency_hz(const_float_t hz, const float dca, const float dcb else { prescaler = 1; SET_CS(5, PRESCALER_1); } count /= float(prescaler); - const float pwm_top = round(count); // Get the rounded count + const float pwm_top = roundf(count); // Get the rounded count ICR5 = (uint16_t)pwm_top - 1; // Subtract 1 for TOP OCR5A = pwm_top * ABS(dca); // Update and scale DCs @@ -280,7 +280,7 @@ uint16_t set_pwm_frequency_hz(const_float_t hz, const float dca, const float dcb SET_CS(5, PRESCALER_64); // 16MHz / 64 = 250kHz OCR5A = OCR5B = OCR5C = 0; } - return round(count); + return roundf(count); } #endif diff --git a/Marlin/src/HAL/AVR/inc/SanityCheck.h b/Marlin/src/HAL/AVR/inc/SanityCheck.h index 85ee683685..08fe21d4f8 100644 --- a/Marlin/src/HAL/AVR/inc/SanityCheck.h +++ b/Marlin/src/HAL/AVR/inc/SanityCheck.h @@ -95,7 +95,7 @@ /** * The Trinamic library includes SoftwareSerial.h, leading to a compile error. */ -#if ALL(HAS_TRINAMIC_CONFIG, ENDSTOP_INTERRUPTS_FEATURE) +#if ALL(HAS_TMC_SW_SERIAL, ENDSTOP_INTERRUPTS_FEATURE) #error "TMCStepper includes SoftwareSerial.h which is incompatible with ENDSTOP_INTERRUPTS_FEATURE. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." #endif diff --git a/Marlin/src/HAL/AVR/registers.h b/Marlin/src/HAL/AVR/registers.h index 64c0955c3e..0eac4888cd 100644 --- a/Marlin/src/HAL/AVR/registers.h +++ b/Marlin/src/HAL/AVR/registers.h @@ -93,15 +93,15 @@ namespace AVRHelpers { typedef T type; }; template - struct voltype { + struct voltype { typedef uint8_t type; }; template - struct voltype { + struct voltype { typedef uint16_t type; }; template - struct voltype { + struct voltype { typedef uint32_t type; }; @@ -2007,7 +2007,7 @@ inline void _ATmega_resetperipherals() { #if defined(__AVR_TRM01__) || defined(__AVR_TRM02__) || defined(__AVR_TRM03__) || defined(__AVR_TRM05__) _EEAR._EEAR = 0; - dwrite(_EEDR, (uint8_t)0u); + dwrite(_EEDR, (uint8_t)0U); #endif #if defined(__AVR_TRM01__) || defined(__AVR_TRM02__) || defined(__AVR_TRM03__) || defined(__AVR_TRM04__) || defined(__AVR_TRM05__) diff --git a/Marlin/src/HAL/AVR/timers.h b/Marlin/src/HAL/AVR/timers.h index 94b17f3102..1800da0985 100644 --- a/Marlin/src/HAL/AVR/timers.h +++ b/Marlin/src/HAL/AVR/timers.h @@ -28,7 +28,7 @@ // ------------------------ typedef uint16_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFF +#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT16_MAX) // ------------------------ // Defines @@ -46,15 +46,14 @@ typedef uint16_t hal_timer_t; #define MF_TIMER_TEMP 0 #endif -#define TEMP_TIMER_FREQUENCY (((F_CPU) + 0x2000) / 0x4000) +#define TEMP_TIMER_FREQUENCY (((F_CPU) + 0x2000) / 0x4000) -#define STEPPER_TIMER_RATE HAL_TIMER_RATE -#define STEPPER_TIMER_PRESCALE 8 -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) +#define STEPPER_TIMER_RATE HAL_TIMER_RATE +#define STEPPER_TIMER_PRESCALE 8 +#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // (MHz) Stepper Timer ticks per µs -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US +#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer +#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE #define ENABLE_STEPPER_DRIVER_INTERRUPT() SBI(TIMSK1, OCIE1A) #define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A) @@ -111,8 +110,8 @@ FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) { * (otherwise, characters will be lost due to UART overflow). * Then: Stepper, Endstops, Temperature, and -finally- all others. */ -#define HAL_timer_isr_prologue(T) NOOP -#define HAL_timer_isr_epilogue(T) NOOP +inline void HAL_timer_isr_prologue(const uint8_t) {} +inline void HAL_timer_isr_epilogue(const uint8_t) {} #ifndef HAL_STEP_TIMER_ISR diff --git a/Marlin/src/HAL/DUE/HAL.cpp b/Marlin/src/HAL/DUE/HAL.cpp index 9b3cf1a516..19a174259a 100644 --- a/Marlin/src/HAL/DUE/HAL.cpp +++ b/Marlin/src/HAL/DUE/HAL.cpp @@ -27,7 +27,6 @@ #ifdef ARDUINO_ARCH_SAM #include "../../inc/MarlinConfig.h" -#include "../../MarlinCore.h" #include #include "usb/usb_task.h" diff --git a/Marlin/src/HAL/DUE/HAL.h b/Marlin/src/HAL/DUE/HAL.h index 54a977c2d8..f83668ca9d 100644 --- a/Marlin/src/HAL/DUE/HAL.h +++ b/Marlin/src/HAL/DUE/HAL.h @@ -132,7 +132,7 @@ public: static void delay_ms(const int ms) { delay(ms); } - // Tasks, called from idle() + // Tasks, called from marlin.idle() static void idletask(); // Reset diff --git a/Marlin/src/HAL/DUE/MarlinSerial.cpp b/Marlin/src/HAL/DUE/MarlinSerial.cpp index 90efe55fc2..2e80b4c8d1 100644 --- a/Marlin/src/HAL/DUE/MarlinSerial.cpp +++ b/Marlin/src/HAL/DUE/MarlinSerial.cpp @@ -31,7 +31,6 @@ #include "MarlinSerial.h" #include "InterruptVectors.h" -#include "../../MarlinCore.h" template typename MarlinSerial::ring_buffer_r MarlinSerial::rx_buffer = { 0, 0, { 0 } }; template typename MarlinSerial::ring_buffer_t MarlinSerial::tx_buffer = { 0 }; diff --git a/Marlin/src/HAL/DUE/timers.h b/Marlin/src/HAL/DUE/timers.h index db5d83a06f..f892eac8f5 100644 --- a/Marlin/src/HAL/DUE/timers.h +++ b/Marlin/src/HAL/DUE/timers.h @@ -34,7 +34,7 @@ #define FORCE_INLINE __attribute__((always_inline)) inline typedef uint32_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF +#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT32_MAX) #define HAL_TIMER_PRESCALER 2 #define HAL_TIMER_RATE ((F_CPU) / (HAL_TIMER_PRESCALER)) // frequency of timers peripherals @@ -52,19 +52,18 @@ typedef uint32_t hal_timer_t; #define MF_TIMER_TONE 6 // index of timer to use for beeper tones #endif -#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency +#define TEMP_TIMER_FREQUENCY 1000 // (Hz) Temperature ISR frequency -#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs +#define STEPPER_TIMER_RATE HAL_TIMER_RATE // (Hz) Frequency of Stepper Timer ISR (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) +#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // (MHz) Stepper Timer ticks per µs #define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer +#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer #define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) +#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) #define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) +#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) #define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) @@ -127,4 +126,4 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) { pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_SR; } -#define HAL_timer_isr_epilogue(T) NOOP +inline void HAL_timer_isr_epilogue(const uint8_t) {} diff --git a/Marlin/src/HAL/DUE/usb/.editorconfig b/Marlin/src/HAL/DUE/usb/.editorconfig new file mode 100644 index 0000000000..f2c26de5ee --- /dev/null +++ b/Marlin/src/HAL/DUE/usb/.editorconfig @@ -0,0 +1,5 @@ +# editorconfig.org + +[{*.c,*.cpp,*.h}] +indent_style = tab +indent_size = 4 diff --git a/Marlin/src/HAL/ESP32/HAL.cpp b/Marlin/src/HAL/ESP32/HAL.cpp index c48aee0e21..acfec29b2f 100644 --- a/Marlin/src/HAL/ESP32/HAL.cpp +++ b/Marlin/src/HAL/ESP32/HAL.cpp @@ -271,7 +271,7 @@ void MarlinHAL::adc_start(const pin_t pin) { uint32_t mv; esp_adc_cal_get_voltage((adc_channel_t)chan, &characteristics[attenuations[chan]], &mv); - adc_result = mv * isr_float_t(1023) / isr_float_t(ADC_REFERENCE_VOLTAGE) / isr_float_t(1000); + adc_result = (mv * 1023) * (1000.f / (ADC_REFERENCE_VOLTAGE)); // Change the attenuation level based on the new reading adc_atten_t atten; diff --git a/Marlin/src/HAL/ESP32/HAL.h b/Marlin/src/HAL/ESP32/HAL.h index baa03d8a76..f48eabea0d 100644 --- a/Marlin/src/HAL/ESP32/HAL.h +++ b/Marlin/src/HAL/ESP32/HAL.h @@ -64,10 +64,10 @@ #define CRITICAL_SECTION_END() portEXIT_CRITICAL(&hal.spinlock) #define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment -#define PWM_FREQUENCY 1000u // Default PWM frequency when set_pwm_duty() is called without set_pwm_frequency() -#define PWM_RESOLUTION 10u // Default PWM bit resolution -#define CHANNEL_MAX_NUM 15u // max PWM channel # to allocate (7 to only use low speed, 15 to use low & high) -#define MAX_PWM_IOPIN 33u // hardware pwm pins < 34 +#define PWM_FREQUENCY 1000U // Default PWM frequency when set_pwm_duty() is called without set_pwm_frequency() +#define PWM_RESOLUTION 10U // Default PWM bit resolution +#define CHANNEL_MAX_NUM 15U // max PWM channel # to allocate (7 to only use low speed, 15 to use low & high) +#define MAX_PWM_IOPIN 33U // hardware pwm pins < 34 #ifndef MAX_EXPANDER_BITS #define MAX_EXPANDER_BITS 32 // I2S expander bit width (max 32) #endif @@ -76,7 +76,6 @@ // Types // ------------------------ -typedef double isr_float_t; // FPU ops are used for single-precision, so use double for ISRs. typedef int16_t pin_t; typedef struct pwm_pin { @@ -194,7 +193,7 @@ public: static void delay_ms(const int ms) { delay(ms); } - // Tasks, called from idle() + // Tasks, called from marlin.idle() static void idletask(); // Reset diff --git a/Marlin/src/HAL/ESP32/Servo.cpp b/Marlin/src/HAL/ESP32/Servo.cpp index ca3950d07f..3a2c11832d 100644 --- a/Marlin/src/HAL/ESP32/Servo.cpp +++ b/Marlin/src/HAL/ESP32/Servo.cpp @@ -35,7 +35,7 @@ Servo::Servo() {} int8_t Servo::attach(const int inPin) { if (inPin > 0) pin = inPin; - channel = get_pwm_channel(pin, 50u, 16u); + channel = get_pwm_channel(pin, 50U, 16U); return channel; // -1 if no PWM avail. } diff --git a/Marlin/src/HAL/ESP32/i2s.cpp b/Marlin/src/HAL/ESP32/i2s.cpp index 6aeeb0e3dc..f7c01730b3 100644 --- a/Marlin/src/HAL/ESP32/i2s.cpp +++ b/Marlin/src/HAL/ESP32/i2s.cpp @@ -156,38 +156,43 @@ void stepperTask(void *parameter) { while (dma.rw_pos < DMA_SAMPLE_COUNT) { - #if ENABLED(FT_MOTION) + if (using_ftMotion) { - if (using_ftMotion) { + #if ENABLED(FT_MOTION) if (!nextMainISR) stepper.ftMotion_stepper(); nextMainISR = 0; - } + #endif - #endif + } + else { - if (!using_ftMotion) { - if (!nextMainISR) { - stepper.pulse_phase_isr(); - nextMainISR = stepper.block_phase_isr(); - } - #if ENABLED(LIN_ADVANCE) - else if (!nextAdvanceISR) { - stepper.advance_isr(); - nextAdvanceISR = stepper.la_interval; + #if HAS_STANDARD_MOTION + + if (!nextMainISR) { + stepper.pulse_phase_isr(); + nextMainISR = stepper.block_phase_isr(); } - #endif - else - i2s_push_sample(); + #if ENABLED(LIN_ADVANCE) + else if (!nextAdvanceISR) { + stepper.advance_isr(); + nextAdvanceISR = stepper.la_interval; + } + #endif + else + i2s_push_sample(); - nextMainISR--; + nextMainISR--; - #if ENABLED(LIN_ADVANCE) - if (nextAdvanceISR == stepper.LA_ADV_NEVER) - nextAdvanceISR = stepper.la_interval; + #if ENABLED(LIN_ADVANCE) + if (nextAdvanceISR == stepper.LA_ADV_NEVER) + nextAdvanceISR = stepper.la_interval; + + if (nextAdvanceISR && nextAdvanceISR != stepper.LA_ADV_NEVER) + nextAdvanceISR--; + #endif + + #endif // HAS_STANDARD_MOTION - if (nextAdvanceISR && nextAdvanceISR != stepper.LA_ADV_NEVER) - nextAdvanceISR--; - #endif } } } 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/ESP32/timers.h b/Marlin/src/HAL/ESP32/timers.h index 3f336fbfc9..d656e92224 100644 --- a/Marlin/src/HAL/ESP32/timers.h +++ b/Marlin/src/HAL/ESP32/timers.h @@ -30,41 +30,45 @@ #define FORCE_INLINE __attribute__((always_inline)) inline typedef uint64_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFFFFFFFFFFULL +#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT64_MAX) #ifndef MF_TIMER_STEP #define MF_TIMER_STEP 0 // Timer Index for Stepper #endif #ifndef MF_TIMER_PULSE - #define MF_TIMER_PULSE MF_TIMER_STEP + #define MF_TIMER_PULSE MF_TIMER_STEP // Timer Index for Pulse interval #endif #ifndef MF_TIMER_TEMP #define MF_TIMER_TEMP 1 // Timer Index for Temperature #endif #ifndef MF_TIMER_PWM - #define MF_TIMER_PWM 2 // index of timer to use for PWM outputs + #define MF_TIMER_PWM 2 // Timer Index for PWM outputs #endif #ifndef MF_TIMER_TONE - #define MF_TIMER_TONE 3 // index of timer for beeper tones + #define MF_TIMER_TONE 3 // Timer Index for beeper tones #endif -#define HAL_TIMER_RATE APB_CLK_FREQ // frequency of timer peripherals +#define HAL_TIMER_RATE APB_CLK_FREQ // Frequency of timer peripherals + +#define TEMP_TIMER_PRESCALE 1000 // Prescaler for setting Temp Timer, 72Khz +#define TEMP_TIMER_FREQUENCY 1000 // (Hz) Temperature ISR frequency #if ENABLED(I2S_STEPPER_STREAM) #define STEPPER_TIMER_PRESCALE 1 - #define STEPPER_TIMER_RATE 250000 // 250khz, 4µs pulses of i2s word clock + #define STEPPER_TIMER_RATE 250'000 // 250khz, 4µs pulses of i2s word clock + #define STEPPER_TIMER_TICKS_PER_US 0.25 // (MHz) Stepper Timer ticks per µs #else #define STEPPER_TIMER_PRESCALE 40 - #define STEPPER_TIMER_RATE ((HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE)) // frequency of stepper timer, 2MHz + #define STEPPER_TIMER_RATE ((HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE)) // (Hz) Frequency of Stepper Timer ISR, 2MHz + #define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1'000'000UL) // (MHz) Stepper Timer ticks per µs #endif -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs #define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts -#define TONE_TIMER_PRESCALE 1000 // Arbitrary value, no idea what i'm doing here +#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer +#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz -#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency +#define TONE_TIMER_PRESCALE 1000 // Arbitrary value, no idea what i'm doing here #define PWM_TIMER_PRESCALE 10 #if ENABLED(FAST_PWM_FAN) @@ -74,13 +78,9 @@ typedef uint64_t hal_timer_t; #endif #define MAX_PWM_PINS 32 // Number of PWM pin-slots -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US - -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) +#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) #define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) +#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) #define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) @@ -135,5 +135,5 @@ void HAL_timer_enable_interrupt(const uint8_t timer_num); void HAL_timer_disable_interrupt(const uint8_t timer_num); bool HAL_timer_interrupt_enabled(const uint8_t timer_num); -#define HAL_timer_isr_prologue(T) NOOP -#define HAL_timer_isr_epilogue(T) NOOP +inline void HAL_timer_isr_prologue(const uint8_t) {} +inline void HAL_timer_isr_epilogue(const uint8_t) {} diff --git a/Marlin/src/HAL/GD32_MFL/HAL.cpp b/Marlin/src/HAL/GD32_MFL/HAL.cpp index 460ed52297..9ba20784f0 100644 --- a/Marlin/src/HAL/GD32_MFL/HAL.cpp +++ b/Marlin/src/HAL/GD32_MFL/HAL.cpp @@ -53,12 +53,15 @@ uint16_t MarlinHAL::adc_result; // Initializes the Marlin HAL void MarlinHAL::init() { + // Ensure F_CPU is a constant expression. + // If the compiler breaks here, it means that delay code that should compute at compile time will not work. + // So better safe than sorry here. constexpr unsigned int cpuFreq = F_CPU; UNUSED(cpuFreq); -#if PIN_EXISTS(LED) - OUT_WRITE(LED_PIN, LOW); -#endif + #if PIN_EXISTS(LED) + OUT_WRITE(LED_PIN, LOW); + #endif SetTimerInterruptPriorities(); diff --git a/Marlin/src/HAL/GD32_MFL/HAL.h b/Marlin/src/HAL/GD32_MFL/HAL.h index 56e52b53b5..6195212028 100644 --- a/Marlin/src/HAL/GD32_MFL/HAL.h +++ b/Marlin/src/HAL/GD32_MFL/HAL.h @@ -57,7 +57,6 @@ #define __bss_end __bss_end__ // Types -typedef double isr_float_t; // FPU ops are used for single-precision, so use double for ISRs. typedef uint8_t pin_t; // Parity with mfl platform // Servo diff --git a/Marlin/src/HAL/GD32_MFL/temp_soc.h b/Marlin/src/HAL/GD32_MFL/temp_soc.h index 5f1be64e43..bd78fba5b9 100644 --- a/Marlin/src/HAL/GD32_MFL/temp_soc.h +++ b/Marlin/src/HAL/GD32_MFL/temp_soc.h @@ -26,4 +26,4 @@ #define TS_TYPICAL_SLOPE 4.5 // TODO: Implement voltage scaling (calibrated Vrefint) and ADC resolution scaling (when applicable) -#define TEMP_SOC_SENSOR(RAW) ((TS_TYPICAL_V - (RAW) / float(OVERSAMPLENR) / float(HAL_ADC_RANGE) * (float(ADC_VREF_MV) / 1000.0f)) / ((TS_TYPICAL_SLOPE) / 1000.0f) + TS_TYPICAL_TEMP) +#define TEMP_SOC_SENSOR(RAW) ((TS_TYPICAL_V - (RAW) / float(OVERSAMPLENR) / float(HAL_ADC_RANGE) * (float(ADC_VREF_MV) * 0.001f)) / ((TS_TYPICAL_SLOPE) * 0.001f) + TS_TYPICAL_TEMP) diff --git a/Marlin/src/HAL/GD32_MFL/timers.cpp b/Marlin/src/HAL/GD32_MFL/timers.cpp index 632499742c..13a5c166ef 100644 --- a/Marlin/src/HAL/GD32_MFL/timers.cpp +++ b/Marlin/src/HAL/GD32_MFL/timers.cpp @@ -121,9 +121,10 @@ void HAL_timer_start(const uint8_t timer_number, const uint32_t frequency) { if (is_step) { timer.setPrescaler(STEPPER_TIMER_PRESCALE); - timer.setRolloverValue(_MIN(static_cast(HAL_TIMER_TYPE_MAX), - (HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE)), - TimerFormat::TICK); + timer.setRolloverValue( + _MIN(HAL_TIMER_TYPE_MAX, hal_timer_t((HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE))), + TimerFormat::TICK + ); is_step_timer_initialized = true; } else { diff --git a/Marlin/src/HAL/GD32_MFL/timers.h b/Marlin/src/HAL/GD32_MFL/timers.h index a5d36d9eca..1c69c0b468 100644 --- a/Marlin/src/HAL/GD32_MFL/timers.h +++ b/Marlin/src/HAL/GD32_MFL/timers.h @@ -29,26 +29,27 @@ // Defines // ------------------------ -// Timer configuration constants -#define STEPPER_TIMER_RATE 2000000 -#define TEMP_TIMER_FREQUENCY 1000 - // Timer instance definitions #define MF_TIMER_STEP 3 #define MF_TIMER_TEMP 1 #define MF_TIMER_PULSE MF_TIMER_STEP -#define hal_timer_t uint32_t -#define HAL_TIMER_TYPE_MAX UINT16_MAX +typedef uint32_t hal_timer_t; +#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT16_MAX) extern uint32_t GetStepperTimerClkFreq(); +// Timer configuration constants +#define STEPPER_TIMER_RATE 2000000 +#define TEMP_TIMER_FREQUENCY 1000 + // Timer prescaler calculations -#define STEPPER_TIMER_PRESCALE (GetStepperTimerClkFreq() / STEPPER_TIMER_RATE) // Prescaler = 30 +#define STEPPER_TIMER_PRESCALE (GetStepperTimerClkFreq() / STEPPER_TIMER_RATE) // Prescaler = 30 +#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // (MHz) Stepper Timer ticks per µs + +// Pulse Timer (counter) calculations +#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer #define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // Stepper timer ticks per µs -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US // Timer interrupt priorities #define STEP_TIMER_IRQ_PRIORITY 2 @@ -141,5 +142,5 @@ FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_number, const } } -#define HAL_timer_isr_prologue(T) NOOP -#define HAL_timer_isr_epilogue(T) NOOP +inline void HAL_timer_isr_prologue(const uint8_t) {} +inline void HAL_timer_isr_epilogue(const uint8_t) {} diff --git a/Marlin/src/HAL/HC32/MarlinHAL.h b/Marlin/src/HAL/HC32/MarlinHAL.h index 86dc3c7e53..ba3ac4c731 100644 --- a/Marlin/src/HAL/HC32/MarlinHAL.h +++ b/Marlin/src/HAL/HC32/MarlinHAL.h @@ -67,7 +67,7 @@ public: static void delay_ms(const int ms); - // Tasks, called from idle() + // Tasks, called from marlin.idle() static void idletask(); // Reset 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/HC32/inc/SanityCheck.h b/Marlin/src/HAL/HC32/inc/SanityCheck.h index e38bce91e5..c6b3b221df 100644 --- a/Marlin/src/HAL/HC32/inc/SanityCheck.h +++ b/Marlin/src/HAL/HC32/inc/SanityCheck.h @@ -83,7 +83,7 @@ #error "POSTMORTEM_DEBUGGING requires CORE_DISABLE_FAULT_HANDLER to be set." #endif -#if defined(PANIC_ENABLE) +#ifdef PANIC_ENABLE #if defined(PANIC_USART1_TX_PIN) || defined(PANIC_USART2_TX_PIN) || defined(PANIC_USART3_TX_PIN) || defined(PANIC_USART3_TX_PIN) #error "HC32 HAL uses a custom panic handler. Do not define PANIC_USARTx_TX_PIN." #endif diff --git a/Marlin/src/HAL/HC32/sysclock.cpp b/Marlin/src/HAL/HC32/sysclock.cpp index 493515b0e8..e98395c42e 100644 --- a/Marlin/src/HAL/HC32/sysclock.cpp +++ b/Marlin/src/HAL/HC32/sysclock.cpp @@ -171,7 +171,7 @@ void core_hook_sysclock_init() { panic("HRC is not 16 MHz"); } - #if defined(BOARD_XTAL_FREQUENCY) + #ifdef BOARD_XTAL_FREQUENCY #warning "No valid XTAL frequency defined, falling back to HRC." #endif diff --git a/Marlin/src/HAL/HC32/timers.cpp b/Marlin/src/HAL/HC32/timers.cpp index 5f7d499622..b8eab34cf7 100644 --- a/Marlin/src/HAL/HC32/timers.cpp +++ b/Marlin/src/HAL/HC32/timers.cpp @@ -35,19 +35,19 @@ Timer0 temp_timer(&TIMER02A_config, &Temp_Handler); */ Timer0 step_timer(&TIMER02B_config, &Step_Handler); -void HAL_timer_start(const timer_channel_t timer_num, const uint32_t frequency) { - if (timer_num == TEMP_TIMER_NUM) { +void HAL_timer_start(const timer_channel_t timer_ch, const uint32_t frequency) { + if (timer_ch == MF_TIMER_TEMP) { CORE_DEBUG_PRINTF("HAL_timer_start: temp timer, f=%ld\n", long(frequency)); - timer_num->start(frequency, TEMP_TIMER_PRESCALE); - timer_num->setCallbackPriority(TEMP_TIMER_PRIORITY); + timer_ch->start(frequency, TEMP_TIMER_PRESCALE); + timer_ch->setCallbackPriority(TEMP_TIMER_PRIORITY); } - else if (timer_num == STEP_TIMER_NUM) { + else if (timer_ch == MF_TIMER_STEP) { CORE_DEBUG_PRINTF("HAL_timer_start: step timer, f=%ld\n", long(frequency)); - timer_num->start(frequency, STEPPER_TIMER_PRESCALE); - timer_num->setCallbackPriority(STEP_TIMER_PRIORITY); + timer_ch->start(frequency, STEPPER_TIMER_PRESCALE); + timer_ch->setCallbackPriority(STEP_TIMER_PRIORITY); } else { - CORE_ASSERT_FAIL("HAL_timer_start: invalid timer_num") + CORE_ASSERT_FAIL("HAL_timer_start: invalid timer_ch") } } diff --git a/Marlin/src/HAL/HC32/timers.h b/Marlin/src/HAL/HC32/timers.h index e5ab3f21f5..8a4465e2d8 100644 --- a/Marlin/src/HAL/HC32/timers.h +++ b/Marlin/src/HAL/HC32/timers.h @@ -27,7 +27,7 @@ // typedef Timer0 *timer_channel_t; typedef uint16_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFF +#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT16_MAX) // // Timer instances @@ -54,75 +54,68 @@ extern Timer0 step_timer; #define HAL_TIMER_RATE F_PCLK1 // Temperature timer -#define TEMP_TIMER_NUM (&temp_timer) +#define MF_TIMER_TEMP (&temp_timer) #define TEMP_TIMER_PRIORITY DDL_IRQ_PRIORITY_02 -#define TEMP_TIMER_PRESCALE 16UL // 12.5MHz +#define TEMP_TIMER_PRESCALE 16UL // 12.5MHz #define TEMP_TIMER_RATE 1000 // 1kHz #define TEMP_TIMER_FREQUENCY TEMP_TIMER_RATE // 1kHz also // Stepper timer -#define STEP_TIMER_NUM (&step_timer) +#define MF_TIMER_STEP (&step_timer) #define STEP_TIMER_PRIORITY DDL_IRQ_PRIORITY_00 // Top priority, nothing else uses it -#define STEPPER_TIMER_PRESCALE 16UL // 12.5MHz +#define STEPPER_TIMER_PRESCALE 16UL // 12.5MHz -#define STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // 50MHz / 16 = 3.125MHz -#define STEPPER_TIMER_TICKS_PER_US (STEPPER_TIMER_RATE / 1000000UL) // Integer 3 +#define STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // 50MHz / 16 = 3.125MHz +#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // Integer 3 // Pulse timer (== stepper timer) -#define PULSE_TIMER_NUM STEP_TIMER_NUM -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US - -// -// Channel aliases -// -#define MF_TIMER_TEMP TEMP_TIMER_NUM -#define MF_TIMER_STEP STEP_TIMER_NUM -#define MF_TIMER_PULSE PULSE_TIMER_NUM +#define MF_TIMER_PULSE MF_TIMER_STEP +#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer +#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE // // HAL functions // -void HAL_timer_start(const timer_channel_t timer_num, const uint32_t frequency); +void HAL_timer_start(const timer_channel_t timer_ch, const uint32_t frequency); // Inlined since they are somewhat critical #define MARLIN_HAL_TIMER_INLINE_ATTR __attribute__((always_inline)) inline -MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_enable_interrupt(const timer_channel_t timer_num) { - timer_num->resume(); +MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_enable_interrupt(const timer_channel_t timer_ch) { + timer_ch->resume(); } -MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_disable_interrupt(const timer_channel_t timer_num) { - timer_num->pause(); +MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_disable_interrupt(const timer_channel_t timer_ch) { + timer_ch->pause(); } -MARLIN_HAL_TIMER_INLINE_ATTR bool HAL_timer_interrupt_enabled(const timer_channel_t timer_num) { - return timer_num->isPaused(); +MARLIN_HAL_TIMER_INLINE_ATTR bool HAL_timer_interrupt_enabled(const timer_channel_t timer_ch) { + return timer_ch->isPaused(); } -MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_set_compare(const timer_channel_t timer_num, const hal_timer_t compare) { - timer_num->setCompareValue(compare); +MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_set_compare(const timer_channel_t timer_ch, const hal_timer_t compare) { + timer_ch->setCompareValue(compare); } -MARLIN_HAL_TIMER_INLINE_ATTR hal_timer_t HAL_timer_get_count(const timer_channel_t timer_num) { - return timer_num->getCount(); +MARLIN_HAL_TIMER_INLINE_ATTR hal_timer_t HAL_timer_get_count(const timer_channel_t timer_ch) { + return timer_ch->getCount(); } -MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_isr_prologue(const timer_channel_t timer_num) { - timer_num->clearInterruptFlag(); +MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_isr_prologue(const timer_channel_t timer_ch) { + timer_ch->clearInterruptFlag(); } -MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_isr_epilogue(const timer_channel_t timer_num) {} +inline void HAL_timer_isr_epilogue(const timer_channel_t) {} // // HAL function aliases // -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM) +#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) +#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) +#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM) -#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM); +#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) +#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP); // // HAL ISR callbacks @@ -131,8 +124,8 @@ void Step_Handler(); void Temp_Handler(); #ifndef HAL_STEP_TIMER_ISR -#define HAL_STEP_TIMER_ISR() void Step_Handler() + #define HAL_STEP_TIMER_ISR() void Step_Handler() #endif #ifndef HAL_TEMP_TIMER_ISR -#define HAL_TEMP_TIMER_ISR() void Temp_Handler() + #define HAL_TEMP_TIMER_ISR() void Temp_Handler() #endif diff --git a/Marlin/src/HAL/LINUX/HAL.h b/Marlin/src/HAL/LINUX/HAL.h index 68e0e1062c..66e4036fdc 100644 --- a/Marlin/src/HAL/LINUX/HAL.h +++ b/Marlin/src/HAL/LINUX/HAL.h @@ -126,7 +126,7 @@ public: static void delay_ms(const int ms) { delay(ms); } - // Tasks, called from idle() + // Tasks, called from marlin.idle() static void idletask() {} // Reset diff --git a/Marlin/src/HAL/LINUX/timers.h b/Marlin/src/HAL/LINUX/timers.h index 2b29edce0b..39c76f02b5 100644 --- a/Marlin/src/HAL/LINUX/timers.h +++ b/Marlin/src/HAL/LINUX/timers.h @@ -34,7 +34,7 @@ #define FORCE_INLINE __attribute__((always_inline)) inline typedef uint32_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF +#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT32_MAX) #define HAL_TIMER_RATE ((SystemCoreClock) / 4) // frequency of timers peripherals @@ -49,21 +49,20 @@ typedef uint32_t hal_timer_t; #endif #define TEMP_TIMER_RATE 1000000 -#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency +#define TEMP_TIMER_FREQUENCY 1000 // (Hz) Temperature ISR frequency -#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs -#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) +#define STEPPER_TIMER_RATE HAL_TIMER_RATE // (Hz) Frequency of Stepper Timer ISR (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) +#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // (MHz) Stepper Timer ticks per µs +#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US +#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer +#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) +#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) +#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) +#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) +#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) #ifndef HAL_STEP_TIMER_ISR @@ -93,5 +92,5 @@ void HAL_timer_enable_interrupt(const uint8_t timer_num); void HAL_timer_disable_interrupt(const uint8_t timer_num); bool HAL_timer_interrupt_enabled(const uint8_t timer_num); -#define HAL_timer_isr_prologue(T) NOOP -#define HAL_timer_isr_epilogue(T) NOOP +inline void HAL_timer_isr_prologue(const uint8_t) {} +inline void HAL_timer_isr_epilogue(const uint8_t) {} diff --git a/Marlin/src/HAL/LPC1768/HAL.h b/Marlin/src/HAL/LPC1768/HAL.h index 9a68cdf748..052d6637c8 100644 --- a/Marlin/src/HAL/LPC1768/HAL.h +++ b/Marlin/src/HAL/LPC1768/HAL.h @@ -160,7 +160,7 @@ public: static bool watchdog_timed_out() IF_DISABLED(USE_WATCHDOG, { return false; }); static void watchdog_clear_timeout_flag() IF_DISABLED(USE_WATCHDOG, {}); - // Tasks, called from idle() + // Tasks, called from marlin.idle() static void idletask(); // Reset diff --git a/Marlin/src/HAL/LPC1768/Servo.h b/Marlin/src/HAL/LPC1768/Servo.h index 221001c948..d7f0a2a555 100644 --- a/Marlin/src/HAL/LPC1768/Servo.h +++ b/Marlin/src/HAL/LPC1768/Servo.h @@ -49,6 +49,8 @@ #include +#include "../../MarlinCore.h" + class libServo: public Servo { public: void move(const int value) { 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/timers.h b/Marlin/src/HAL/LPC1768/timers.h index bae01703ed..3aec2418d2 100644 --- a/Marlin/src/HAL/LPC1768/timers.h +++ b/Marlin/src/HAL/LPC1768/timers.h @@ -57,9 +57,9 @@ #define _HAL_TIMER_ISR(T) __HAL_TIMER_ISR(T) typedef uint32_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF +#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT32_MAX) -#define HAL_TIMER_RATE ((F_CPU) / 4) // frequency of timers peripherals +#define HAL_TIMER_RATE ((F_CPU) / 4) // (Hz) Frequency of timers peripherals #ifndef MF_TIMER_STEP #define MF_TIMER_STEP 0 // Timer Index for Stepper @@ -74,22 +74,21 @@ typedef uint32_t hal_timer_t; #define MF_TIMER_PWM 3 // Timer Index for PWM #endif -#define TEMP_TIMER_RATE 1000000 -#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency +#define TEMP_TIMER_RATE 1000000 // 1MHz +#define TEMP_TIMER_FREQUENCY 1000 // (Hz) Temperature ISR frequency -#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs -#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) +#define STEPPER_TIMER_RATE HAL_TIMER_RATE // (Hz) Frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) +#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // (MHz) Stepper Timer ticks per µs +#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US +#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer +#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) +#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) +#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) +#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) +#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) #ifndef HAL_STEP_TIMER_ISR @@ -171,4 +170,4 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) { } } -#define HAL_timer_isr_epilogue(T) NOOP +inline void HAL_timer_isr_epilogue(const uint8_t) {} 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/HAL.h b/Marlin/src/HAL/NATIVE_SIM/HAL.h index 661c502f22..b3b66d54d3 100644 --- a/Marlin/src/HAL/NATIVE_SIM/HAL.h +++ b/Marlin/src/HAL/NATIVE_SIM/HAL.h @@ -197,7 +197,7 @@ public: static void delay_ms(const int ms) { delay(ms); } - // Tasks, called from idle() + // Tasks, called from marlin.idle() static void idletask(); // Reset diff --git a/Marlin/src/HAL/NATIVE_SIM/fastio.h b/Marlin/src/HAL/NATIVE_SIM/fastio.h index f501afdbaa..e0b7af09f9 100644 --- a/Marlin/src/HAL/NATIVE_SIM/fastio.h +++ b/Marlin/src/HAL/NATIVE_SIM/fastio.h @@ -28,6 +28,8 @@ #include "../shared/Marduino.h" #include +#define NO_COMPILE_TIME_PWM + #define SET_DIR_INPUT(IO) Gpio::setDir(IO, 1) #define SET_DIR_OUTPUT(IO) Gpio::setDir(IO, 0) diff --git a/Marlin/src/HAL/NATIVE_SIM/timers.h b/Marlin/src/HAL/NATIVE_SIM/timers.h index d46e8e7b94..be59bb8676 100644 --- a/Marlin/src/HAL/NATIVE_SIM/timers.h +++ b/Marlin/src/HAL/NATIVE_SIM/timers.h @@ -34,7 +34,7 @@ #define FORCE_INLINE __attribute__((always_inline)) inline typedef uint64_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFFFFFFFFFF +#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT64_MAX) #define HAL_TIMER_RATE ((SystemCoreClock) / 4) // frequency of timers peripherals @@ -52,22 +52,21 @@ typedef uint64_t hal_timer_t; #endif #define SYSTICK_TIMER_FREQUENCY 1000 -#define TEMP_TIMER_RATE 1000000 -#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency +#define TEMP_TIMER_RATE 1'000'000 // (Hz) Temperature Timer count rate +#define TEMP_TIMER_FREQUENCY 1000 // (Hz) Temperature ISR call frequency -#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs -#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) +#define STEPPER_TIMER_RATE HAL_TIMER_RATE // (Hz) Frequency of Stepper Timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) +#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1'000'000) // (MHz) Stepper Timer ticks per µs +#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US +#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer +#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) +#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) +#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) +#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) +#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) #ifndef HAL_STEP_TIMER_ISR @@ -88,5 +87,5 @@ void HAL_timer_enable_interrupt(const uint8_t timer_num); void HAL_timer_disable_interrupt(const uint8_t timer_num); bool HAL_timer_interrupt_enabled(const uint8_t timer_num); -#define HAL_timer_isr_prologue(T) NOOP -#define HAL_timer_isr_epilogue(T) NOOP +inline void HAL_timer_isr_prologue(const uint8_t) {} +inline void HAL_timer_isr_epilogue(const uint8_t) {} 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/RP2040/HAL.cpp b/Marlin/src/HAL/RP2040/HAL.cpp index 1b519e4004..9341480078 100644 --- a/Marlin/src/HAL/RP2040/HAL.cpp +++ b/Marlin/src/HAL/RP2040/HAL.cpp @@ -32,17 +32,123 @@ extern "C" { #include "pico/bootrom.h" #include "hardware/watchdog.h" + #include "pico/multicore.h" + #include "hardware/adc.h" + #include "pico/time.h" } #if HAS_SD_HOST_DRIVE #include "msc_sd.h" - #include "usbd_cdc_if.h" #endif +// Core 1 watchdog configuration +#define CORE1_MAX_RESETS 5 // Maximum number of Core 1 resets before halting system + // ------------------------ // Public Variables // ------------------------ +volatile uint32_t adc_accumulators[5] = {0}; // Accumulators for oversampling (sum of readings) +volatile uint8_t adc_counts[5] = {0}; // Count of readings accumulated per channel +volatile uint16_t adc_values[5] = {512, 512, 512, 512, 512}; // Final oversampled ADC values (averages) - initialized to mid-range + +// Core 1 watchdog monitoring +volatile uint32_t core1_last_heartbeat = 0; // Timestamp of Core 1's last activity +volatile bool core1_watchdog_triggered = false; // Flag to indicate Core 1 reset +volatile uint8_t core1_reset_count = 0; // Count of Core 1 resets - halt system if >= CORE1_MAX_RESETS +volatile uint8_t current_pin; +volatile bool MarlinHAL::adc_has_result; +volatile uint8_t adc_channels_enabled[5] = {false}; // Track which ADC channels are enabled + +// Helper function for LED blinking patterns +void blink_led_pattern(uint8_t blink_count, uint32_t blink_duration_us = 100000) { + #if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED) + for (uint8_t i = 0; i < blink_count; i++) { + WRITE(LED_PIN, HIGH); + busy_wait_us(blink_duration_us); + WRITE(LED_PIN, LOW); + if (i < blink_count - 1) { // Don't delay after the last blink + busy_wait_us(blink_duration_us); + } + } + #endif +} + +// Core 1 ADC reading task - dynamically reads all enabled channels with oversampling +void core1_adc_task() { + static uint32_t last_led_toggle = 0; + const uint8_t OVERSAMPLENR = 16; // Standard Marlin oversampling count + + // Signal successful Core 1 startup/restart + SERIAL_ECHO_MSG("Core 1 ADC task started"); + + while (true) { + // Update heartbeat timestamp at start of each scan cycle + core1_last_heartbeat = time_us_32(); + + // Scan all enabled ADC channels + for (uint8_t channel = 0; channel < 5; channel++) { + if (!adc_channels_enabled[channel]) continue; + + // Enable temperature sensor if reading channel 4 + if (channel == 4) { + adc_set_temp_sensor_enabled(true); + } + + // Select and read the channel + adc_select_input(channel); + busy_wait_us(100); // Settling delay + adc_fifo_drain(); + adc_run(true); + + // Wait for conversion with timeout + uint32_t timeout = 10000; + while (adc_fifo_is_empty() && timeout--) { + busy_wait_us(1); + } + + adc_run(false); + uint16_t reading = adc_fifo_is_empty() ? 0 : adc_fifo_get(); + + // Accumulate readings for oversampling + adc_accumulators[channel] += reading; + adc_counts[channel]++; + + // Update the averaged value with current accumulation (provides immediate valid data) + adc_values[channel] = adc_accumulators[channel] / adc_counts[channel]; + + // When we reach the full oversampling count, reset accumulator for next cycle + if (adc_counts[channel] >= OVERSAMPLENR) { + adc_accumulators[channel] = 0; + adc_counts[channel] = 0; + } + + // Disable temp sensor after reading to save power + if (channel == 4) { + adc_set_temp_sensor_enabled(false); + } + } + + // Core 1 LED indicator: Double blink every 2 seconds to show Core 1 is active + uint32_t now = time_us_32(); + if (now - last_led_toggle >= 2000000) { // 2 seconds + last_led_toggle = now; + #if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED) + // Triple blink pattern if watchdog was triggered (shows Core 1 was reset) + if (core1_watchdog_triggered) { + core1_watchdog_triggered = false; // Clear flag + blink_led_pattern(3); // Triple blink for watchdog reset + } else { + blink_led_pattern(2); // Normal double blink + } + #endif + } + + // Delay between full scan cycles + busy_wait_us(10000); // 10ms between scans + } +} + volatile uint16_t adc_result; // ------------------------ @@ -56,7 +162,7 @@ void MarlinHAL::init() { // Ensure F_CPU is a constant expression. // If the compiler breaks here, it means that delay code that should compute at compile time will not work. // So better safe than sorry here. - constexpr int cpuFreq = F_CPU; + constexpr unsigned int cpuFreq = F_CPU; UNUSED(cpuFreq); #if HAS_MEDIA && DISABLED(ONBOARD_SDIO) && PIN_EXISTS(SD_SS) @@ -118,9 +224,28 @@ void MarlinHAL::reboot() { watchdog_reboot(0, 0, 1); } } void MarlinHAL::watchdog_refresh() { + // If Core 1 has reset CORE1_MAX_RESETS+ times, stop updating watchdog to halt system + if (core1_reset_count >= CORE1_MAX_RESETS) { + SERIAL_ECHO_MSG("Core 1 reset limit exceeded (", core1_reset_count, " resets) - halting system for safety"); + return; // Don't update watchdog - system will halt + } + watchdog_update(); + + // Check Core 1 watchdog (15 second timeout) + uint32_t now = time_us_32(); + if (now - core1_last_heartbeat > 15000000) { // 15 seconds + // Core 1 appears stuck - reset it + multicore_reset_core1(); + multicore_launch_core1(core1_adc_task); + core1_watchdog_triggered = true; // Signal for LED indicator + core1_reset_count++; // Increment reset counter + SERIAL_ECHO_MSG("Core 1 ADC watchdog triggered - resetting Core 1 (attempt ", core1_reset_count, ")"); + } + #if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED) - TOGGLE(LED_PIN); // heartbeat indicator + // Core 0 LED indicator: Single toggle every watchdog refresh (shows Core 0 activity) + TOGGLE(LED_PIN); #endif } @@ -130,43 +255,35 @@ void MarlinHAL::reboot() { watchdog_reboot(0, 0, 1); } // ADC // ------------------------ -volatile bool MarlinHAL::adc_has_result = false; - void MarlinHAL::adc_init() { analogReadResolution(HAL_ADC_RESOLUTION); ::adc_init(); adc_fifo_setup(true, false, 1, false, false); - irq_set_exclusive_handler(ADC_IRQ_FIFO, adc_exclusive_handler); - irq_set_enabled(ADC_IRQ_FIFO, true); - adc_irq_set_enabled(true); + // Launch Core 1 for continuous ADC reading + multicore_launch_core1(core1_adc_task); + adc_has_result = true; // Results are always available with continuous sampling } void MarlinHAL::adc_enable(const pin_t pin) { - if (pin >= A0 && pin <= A3) + if (pin >= A0 && pin <= A3) { adc_gpio_init(pin); - else if (pin == HAL_ADC_MCU_TEMP_DUMMY_PIN) - adc_set_temp_sensor_enabled(true); -} - -void MarlinHAL::adc_start(const pin_t pin) { - adc_has_result = false; - // Select an ADC input. 0...3 are GPIOs 26...29 respectively. - adc_select_input(pin == HAL_ADC_MCU_TEMP_DUMMY_PIN ? 4 : pin - A0); - adc_run(true); -} - -void MarlinHAL::adc_exclusive_handler() { - adc_run(false); // Disable since we only want one result - irq_clear(ADC_IRQ_FIFO); // Clear the IRQ - - if (adc_fifo_get_level() >= 1) { - adc_result = adc_fifo_get(); // Pop the result - adc_fifo_drain(); - adc_has_result = true; // Signal the end of the conversion + adc_channels_enabled[pin - A0] = true; // Mark this channel as enabled + } + else if (pin == HAL_ADC_MCU_TEMP_DUMMY_PIN) { + adc_channels_enabled[4] = true; // Mark MCU temp channel as enabled } } -uint16_t MarlinHAL::adc_value() { return adc_result; } +void MarlinHAL::adc_start(const pin_t pin) { + // Just store which pin we need to read - values are continuously updated by Core 1 + current_pin = pin; +} + +uint16_t MarlinHAL::adc_value() { + // Return the latest ADC value from Core 1's continuous readings + const uint8_t channel = (current_pin == HAL_ADC_MCU_TEMP_DUMMY_PIN) ? 4 : (current_pin - A0); + return adc_values[channel]; +} // Reset the system to initiate a firmware flash void flashFirmware(const int16_t) { hal.reboot(); } diff --git a/Marlin/src/HAL/RP2040/HAL.h b/Marlin/src/HAL/RP2040/HAL.h index 11472f72f5..a1305bd135 100644 --- a/Marlin/src/HAL/RP2040/HAL.h +++ b/Marlin/src/HAL/RP2040/HAL.h @@ -40,6 +40,11 @@ #include "msc_sd.h" #endif +// ADC index 4 is the MCU temperature +#define HAL_ADC_MCU_TEMP_DUMMY_PIN 127 +#define TEMP_SOC_PIN HAL_ADC_MCU_TEMP_DUMMY_PIN // ADC4 is internal temp sensor +#include "temp_soc.h" + // // Serial Ports // @@ -85,8 +90,6 @@ typedef libServo hal_servo_t; #else #define HAL_ADC_RESOLUTION 12 #endif -// ADC index 4 is the MCU temperature -#define HAL_ADC_MCU_TEMP_DUMMY_PIN 127 // // Pin Mapping for M42, M43, M226 @@ -141,7 +144,7 @@ public: static void delay_ms(const int ms) { delay(ms); } - // Tasks, called from idle() + // Tasks, called from marlin.idle() static void idletask() { TERN_(HAS_SD_HOST_DRIVE, tuh_task()); } // Reset @@ -164,9 +167,6 @@ public: // Begin ADC sampling on the given pin. Called from Temperature::isr! static void adc_start(const pin_t pin); - // This ADC runs a periodic task - static void adc_exclusive_handler(); - // Is the ADC ready for reading? static volatile bool adc_has_result; static bool adc_ready() { return adc_has_result; } diff --git a/Marlin/src/HAL/RP2040/HAL_MinSerial.cpp b/Marlin/src/HAL/RP2040/HAL_MinSerial.cpp index d829edff24..dc332053bc 100644 --- a/Marlin/src/HAL/RP2040/HAL_MinSerial.cpp +++ b/Marlin/src/HAL/RP2040/HAL_MinSerial.cpp @@ -44,15 +44,15 @@ static void TXBegin() { #endif } -static void TX(char b){ - #if SERIAL_PORT == -1 - USBSerial - #elif SERIAL_PORT == 0 - USBSerial - #elif SERIAL_PORT == 1 - Serial1 - #endif - .write(b); +static void TX(char b) { + #if SERIAL_PORT == -1 + USBSerial + #elif SERIAL_PORT == 0 + USBSerial + #elif SERIAL_PORT == 1 + Serial1 + #endif + .write(b); } // A SW memory barrier, to ensure GCC does not overoptimize loops diff --git a/Marlin/src/HAL/RP2040/eeprom/eeprom_flash.cpp b/Marlin/src/HAL/RP2040/eeprom/eeprom_flash.cpp index 89e882d77b..bf52109173 100644 --- a/Marlin/src/HAL/RP2040/eeprom/eeprom_flash.cpp +++ b/Marlin/src/HAL/RP2040/eeprom/eeprom_flash.cpp @@ -31,28 +31,48 @@ // NOTE: The Bigtreetech SKR Pico has an onboard W25Q16 flash module -// Use EEPROM.h for compatibility, for now. -#include +// RP2040 Flash-based EEPROM emulation using internal flash memory +#include +#include -static bool eeprom_data_written = false; +// Flash sector size is already defined in hardware/flash.h as FLASH_SECTOR_SIZE +// Place EEPROM emulation at the end of flash, before the filesystem +// This assumes 2MB flash, adjust if using different flash size +#define FLASH_TARGET_OFFSET (PICO_FLASH_SIZE_BYTES - FLASH_SECTOR_SIZE) #ifndef MARLIN_EEPROM_SIZE #define MARLIN_EEPROM_SIZE size_t(E2END + 1) #endif + +static uint8_t eeprom_buffer[MARLIN_EEPROM_SIZE]; +static bool eeprom_data_written = false; +static bool eeprom_initialized = false; size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } bool PersistentStore::access_start() { - EEPROM.begin(); // Avoid EEPROM.h warning (do nothing) - eeprom_buffer_fill(); + if (!eeprom_initialized) { + // Read from flash into buffer + const uint8_t *flash_data = (const uint8_t *)(XIP_BASE + FLASH_TARGET_OFFSET); + memcpy(eeprom_buffer, flash_data, MARLIN_EEPROM_SIZE); + eeprom_initialized = true; + } return true; } bool PersistentStore::access_finish() { if (eeprom_data_written) { TERN_(HAS_PAUSE_SERVO_OUTPUT, PAUSE_SERVO_OUTPUT()); - hal.isr_off(); - eeprom_buffer_flush(); - hal.isr_on(); + + // Disable interrupts during flash write + const uint32_t intstate = save_and_disable_interrupts(); + + // Erase and program the sector + flash_range_erase(FLASH_TARGET_OFFSET, FLASH_SECTOR_SIZE); + flash_range_program(FLASH_TARGET_OFFSET, eeprom_buffer, MARLIN_EEPROM_SIZE); + + // Restore interrupts + restore_interrupts(intstate); + TERN_(HAS_PAUSE_SERVO_OUTPUT, RESUME_SERVO_OUTPUT()); eeprom_data_written = false; } @@ -62,8 +82,8 @@ bool PersistentStore::access_finish() { bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { while (size--) { uint8_t v = *value; - if (v != eeprom_buffered_read_byte(pos)) { - eeprom_buffered_write_byte(pos, v); + if (pos < (int)MARLIN_EEPROM_SIZE && v != eeprom_buffer[pos]) { + eeprom_buffer[pos] = v; eeprom_data_written = true; } crc16(crc, &v, 1); @@ -75,7 +95,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { do { - const uint8_t c = eeprom_buffered_read_byte(pos); + const uint8_t c = (pos < (int)MARLIN_EEPROM_SIZE) ? eeprom_buffer[pos] : 0xFF; if (writing) *value = c; crc16(crc, &c, 1); pos++; diff --git a/Marlin/src/HAL/RP2040/pinsDebug.h b/Marlin/src/HAL/RP2040/pinsDebug.h index f3842c4aff..8f58089fb1 100644 --- a/Marlin/src/HAL/RP2040/pinsDebug.h +++ b/Marlin/src/HAL/RP2040/pinsDebug.h @@ -25,7 +25,7 @@ #include "HAL.h" #ifndef NUM_DIGITAL_PINS - #error "Expected NUM_DIGITAL_PINS not found" + #error "Expected NUM_DIGITAL_PINS not found." #endif /** @@ -74,6 +74,27 @@ * signal. The Arduino pin number is listed by the M43 I command. */ +/** + * Pins Debugging for RP2040 + * + * - NUMBER_PINS_TOTAL + * - MULTI_NAME_PAD + * - getPinByIndex(index) + * - printPinNameByIndex(index) + * - getPinIsDigitalByIndex(index) + * - digitalPinToAnalogIndex(pin) + * - getValidPinMode(pin) + * - isValidPin(pin) + * - isAnalogPin(pin) + * - digitalRead_mod(pin) + * - pwm_status(pin) + * - printPinPWM(pin) + * - printPinPort(pin) + * - printPinNumber(pin) + * - printPinAnalog(pin) + */ + +#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS #define NUM_ANALOG_FIRST A0 #define MODE_PIN_INPUT 0 // Input mode (reset state) @@ -81,66 +102,66 @@ #define MODE_PIN_ALT 2 // Alternate function mode #define MODE_PIN_ANALOG 3 // Analog mode -#define PIN_NUM(P) (P & 0x000F) -#define PIN_NUM_ALPHA_LEFT(P) (((P & 0x000F) < 10) ? ('0' + (P & 0x000F)) : '1') -#define PIN_NUM_ALPHA_RIGHT(P) (((P & 0x000F) > 9) ? ('0' + (P & 0x000F) - 10) : 0 ) -#define PORT_NUM(P) ((P >> 4) & 0x0007) -#define PORT_ALPHA(P) ('A' + (P >> 4)) +#define getPinByIndex(x) pin_array[x].pin +#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) +#define getPinIsDigitalByIndex(x) pin_array[x].is_digital +#define digitalPinToAnalogIndex(P) digital_pin_to_analog_pin(P) -/** - * Translation of routines & variables used by pinsDebug.h - */ -#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS -#define VALID_PIN(ANUM) (pin_t(ANUM) >= 0 && pin_t(ANUM) < NUMBER_PINS_TOTAL) -#define digitalRead_mod(Ard_num) extDigitalRead(Ard_num) // must use Arduino pin numbers when doing reads -#define PRINT_PIN(Q) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) -#define DIGITAL_PIN_TO_ANALOG_PIN(ANUM) -1 // will report analog pin number in the print port routine +uint8_t get_pin_mode(const pin_t pin) { + // Check if pin is in alternate function mode (I2C, SPI, etc.) + const uint32_t gpio_func = gpio_get_function(pin); -// x is a variable used to search pin_array -#define GET_ARRAY_IS_DIGITAL(x) ((bool) pin_array[x].is_digital) -#define GET_ARRAY_PIN(x) ((pin_t) pin_array[x].pin) -#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) -#define MULTI_NAME_PAD 33 // space needed to be pretty if not first name assigned to a pin - -uint8_t get_pin_mode(const pin_t Ard_num) { - - uint dir = gpio_get_dir( Ard_num); - - if (dir) return MODE_PIN_OUTPUT; - else return MODE_PIN_INPUT; + // GPIO_FUNC_I2C is typically function 3 on RP2040 + if ( gpio_func == GPIO_FUNC_I2C + || gpio_func == GPIO_FUNC_SPI + || gpio_func == GPIO_FUNC_UART + || gpio_func == GPIO_FUNC_PWM + ) { + return MODE_PIN_ALT; + } + // For GPIO mode, check direction + return gpio_get_dir(pin) ? MODE_PIN_OUTPUT : MODE_PIN_INPUT; } -bool getValidPinMode(const pin_t Ard_num) { - const uint8_t pin_mode = get_pin_mode(Ard_num); +bool getValidPinMode(const pin_t pin) { + const uint8_t pin_mode = get_pin_mode(pin); return pin_mode == MODE_PIN_OUTPUT || pin_mode == MODE_PIN_ALT; // assume all alt definitions are PWM } -int8_t digital_pin_to_analog_pin(pin_t Ard_num) { - Ard_num -= NUM_ANALOG_FIRST; - return (Ard_num >= 0 && Ard_num < NUM_ANALOG_INPUTS) ? Ard_num : -1; +#define isValidPin(P) WITHIN(P, 0, pin_t(NUMBER_PINS_TOTAL - 1)) + +int8_t digital_pin_to_analog_pin(pin_t pin) { + pin -= NUM_ANALOG_FIRST; + return (WITHIN(pin, 0, NUM_ANALOG_INPUTS - 1)) ? pin : -1; } -bool isAnalogPin(const pin_t Ard_num) { - return digital_pin_to_analog_pin(Ard_num) != -1; +bool isAnalogPin(const pin_t pin) { + return digital_pin_to_analog_pin(pin) != -1; } -bool is_digital(const pin_t x) { - const uint8_t pin_mode = get_pin_mode(x); - return pin_mode == MODE_PIN_INPUT || pin_mode == MODE_PIN_OUTPUT; +#define digitalRead_mod(A) extDigitalRead(A) // must use Arduino pin numbers when doing reads +#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("%3d "), P); SERIAL_ECHO(buffer); }while(0) +#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0) +#define MULTI_NAME_PAD 33 // space needed to be pretty if not first name assigned to a pin + +//bool is_digital(const pin_t pin) { +// const uint8_t pin_mode = get_pin_mode(pin); +// return pin_mode == MODE_PIN_INPUT || pin_mode == MODE_PIN_OUTPUT; +//} + +bool pwm_status(const pin_t pin) { + // Check if this pin is configured for PWM + return PWM_PIN(pin) && get_pin_mode(pin) == MODE_PIN_ALT; } -void printPinPort(const pin_t Ard_num) { - SERIAL_ECHOPGM("Pin: "); - SERIAL_ECHO(Ard_num); -} - -bool pwm_status(const pin_t Ard_num) { - return get_pin_mode(Ard_num) == MODE_PIN_ALT; -} - -void printPinPWM(const pin_t Ard_num) { - if (PWM_PIN(Ard_num)) { +void printPinPWM(const pin_t pin) { + if (pwm_status(pin)) { + // RP2040 has hardware PWM on specific pins + char buffer[22]; + sprintf_P(buffer, PSTR("PWM: pin %d "), pin); + SERIAL_ECHO(buffer); } } + +void printPinPort(const pin_t pin) {} diff --git a/Marlin/src/HAL/RP2040/temp_soc.h b/Marlin/src/HAL/RP2040/temp_soc.h new file mode 100644 index 0000000000..e182fb88dc --- /dev/null +++ b/Marlin/src/HAL/RP2040/temp_soc.h @@ -0,0 +1,30 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2025 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +// RP2040 internal temperature sensor +// Formula: T = 27 - (ADC_voltage - 0.706) / 0.001721 +// ADC_voltage = (RAW / OVERSAMPLENR) * 3.3 / 4096 (RAW is accumulated over OVERSAMPLENR samples) +// T = 27 - ((RAW / OVERSAMPLENR) * 3.3 / 4096 - 0.706) / 0.001721 +// Simplified: T = 437.423 - (RAW / OVERSAMPLENR) * 0.46875 + +#define TEMP_SOC_SENSOR(RAW) (437.423f - ((RAW) / OVERSAMPLENR) * 0.46875f) diff --git a/Marlin/src/HAL/RP2040/timers.h b/Marlin/src/HAL/RP2040/timers.h index 512c6ba465..8d9fde57a8 100644 --- a/Marlin/src/HAL/RP2040/timers.h +++ b/Marlin/src/HAL/RP2040/timers.h @@ -41,9 +41,9 @@ #define _HAL_TIMER_ISR(T) __HAL_TIMER_ISR(T) typedef uint64_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFFFFFFFFFF +#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT64_MAX) -#define HAL_TIMER_RATE (1000000ull) // fixed value as we use a microsecond timesource +#define HAL_TIMER_RATE (1'000'000ULL) // fixed value as we use a microsecond timesource #ifndef MF_TIMER_STEP #define MF_TIMER_STEP 0 // Timer Index for Stepper #endif @@ -58,21 +58,20 @@ typedef uint64_t hal_timer_t; #endif #define TEMP_TIMER_RATE HAL_TIMER_RATE -#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency +#define TEMP_TIMER_FREQUENCY 1000 // (Hz) Temperature ISR frequency #define STEPPER_TIMER_RATE HAL_TIMER_RATE / 10 // 100khz roughly #define STEPPER_TIMER_TICKS_PER_US (0.1) // fixed value as we use a microsecond timesource #define STEPPER_TIMER_PRESCALE (10) -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US +#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer +#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) +#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) +#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) +#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) +#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) #ifndef HAL_STEP_TIMER_ISR @@ -86,10 +85,10 @@ typedef uint64_t hal_timer_t; //#define STEP_TIMER_PTR _HAL_TIMER(MF_TIMER_STEP) //#define TEMP_TIMER_PTR _HAL_TIMER(MF_TIMER_TEMP) -extern alarm_pool_t* HAL_timer_pool_0; -extern alarm_pool_t* HAL_timer_pool_1; -extern alarm_pool_t* HAL_timer_pool_2; -extern alarm_pool_t* HAL_timer_pool_3; +extern alarm_pool_t *HAL_timer_pool_0; +extern alarm_pool_t *HAL_timer_pool_1; +extern alarm_pool_t *HAL_timer_pool_2; +extern alarm_pool_t *HAL_timer_pool_3; extern struct repeating_timer HAL_timer_0; @@ -120,28 +119,23 @@ void HAL_timer_stop(const uint8_t timer_num); FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, hal_timer_t compare) { - if (timer_num == MF_TIMER_STEP){ - if (compare == HAL_TIMER_TYPE_MAX){ - HAL_timer_stop(timer_num); - return; - } + if (timer_num == MF_TIMER_STEP && compare == HAL_TIMER_TYPE_MAX) { + HAL_timer_stop(timer_num); + return; } - compare = compare *10; //Dirty fix, figure out a proper way + compare *= 10; // Dirty fix, figure out a proper way switch (timer_num) { case 0: alarm_pool_add_alarm_in_us(HAL_timer_pool_0, compare, HAL_timer_alarm_pool_0_callback, 0, false); break; - case 1: alarm_pool_add_alarm_in_us(HAL_timer_pool_1, compare, HAL_timer_alarm_pool_1_callback, 0, false); break; - case 2: alarm_pool_add_alarm_in_us(HAL_timer_pool_2, compare, HAL_timer_alarm_pool_2_callback, 0, false); break; - case 3: alarm_pool_add_alarm_in_us(HAL_timer_pool_3, compare, HAL_timer_alarm_pool_3_callback, 0, false); break; @@ -151,27 +145,20 @@ FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, hal_time FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) { return 0; } - FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { if (timer_num == MF_TIMER_STEP) return 0ull; return time_us_64(); } - FORCE_INLINE static void HAL_timer_enable_interrupt(const uint8_t timer_num) { HAL_timer_irq_en[timer_num] = 1; } - FORCE_INLINE static void HAL_timer_disable_interrupt(const uint8_t timer_num) { HAL_timer_irq_en[timer_num] = 0; } - FORCE_INLINE static bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { - return HAL_timer_irq_en[timer_num]; //lucky coincidence that timer_num and rp2040 irq num matches + return HAL_timer_irq_en[timer_num]; // Lucky coincidence that timer_num and rp2040 IRQ num matches } -FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) { - return; -} - -#define HAL_timer_isr_epilogue(T) NOOP +inline void HAL_timer_isr_prologue(const uint8_t) {} +inline void HAL_timer_isr_epilogue(const uint8_t) {} diff --git a/Marlin/src/HAL/RP2040/u8g/LCD_defines.h b/Marlin/src/HAL/RP2040/u8g/LCD_defines.h new file mode 100644 index 0000000000..acdd94b477 --- /dev/null +++ b/Marlin/src/HAL/RP2040/u8g/LCD_defines.h @@ -0,0 +1,28 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2025 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * RP2040 LCD-specific defines + */ +uint8_t u8g_com_rp2040_ssd_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); // u8g_com_rp2040_ssd_i2c.cpp +#define U8G_COM_SSD_I2C_HAL u8g_com_rp2040_ssd_i2c_fn diff --git a/Marlin/src/HAL/RP2040/u8g/u8g_com_rp2040_ssd_i2c.cpp b/Marlin/src/HAL/RP2040/u8g/u8g_com_rp2040_ssd_i2c.cpp new file mode 100644 index 0000000000..ea42bf190d --- /dev/null +++ b/Marlin/src/HAL/RP2040/u8g/u8g_com_rp2040_ssd_i2c.cpp @@ -0,0 +1,108 @@ +/** + * 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 Hardware I2C on valid pin combinations. + * Wire library is used for Hardware I2C. + * + * Hardware I2C uses pins defined in pins_arduino.h. + */ + +#ifdef __PLAT_RP2040__ + +#include "../../../inc/MarlinConfig.h" + +#if HAS_U8GLIB_I2C_OLED + +#include + +#include +#ifndef MASTER_ADDRESS + #define MASTER_ADDRESS 0x01 +#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_rp2040_ssd_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { + + // Hardware I2C flag + //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 + //} + + static uint8_t control; + // Use the global Wire instance (already initialized with correct pins for RP2040) + switch (msg) { + case U8G_COM_MSG_INIT: + Wire.setClock(400000); + // Wire already initialized in MarlinUI::init(), no need to call begin() again + 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: + ::Wire.beginTransmission(0x3C); + ::Wire.write(control); + ::Wire.write(arg_val); + ::Wire.endTransmission(); + break; + + case U8G_COM_MSG_WRITE_SEQ: { + uint8_t* dataptr = (uint8_t*)arg_ptr; + while (arg_val > 0) { + ::Wire.beginTransmission(0x3C); + ::Wire.write(control); + if (arg_val <= I2C_MAX_LENGTH) { + ::Wire.write(dataptr, arg_val); + arg_val = 0; + } + else { + ::Wire.write(dataptr, I2C_MAX_LENGTH); + arg_val -= I2C_MAX_LENGTH; + dataptr += I2C_MAX_LENGTH; + } + ::Wire.endTransmission(); + } + break; + } + } + return 1; +} + +#endif // HAS_U8GLIB_I2C_OLED +#endif // __PLAT_RP2040__ diff --git a/Marlin/src/HAL/SAMD21/HAL.h b/Marlin/src/HAL/SAMD21/HAL.h index e95f0e6f70..5545630ce3 100644 --- a/Marlin/src/HAL/SAMD21/HAL.h +++ b/Marlin/src/HAL/SAMD21/HAL.h @@ -144,7 +144,7 @@ public: static void delay_ms(const int ms) { delay(ms); } - // Tasks, called from idle() + // Tasks, called from marlin.idle() static void idletask() {} // Reset diff --git a/Marlin/src/HAL/SAMD21/eeprom/eeprom_flash.cpp b/Marlin/src/HAL/SAMD21/eeprom/eeprom_flash.cpp index 1c190495de..0b5323cda4 100644 --- a/Marlin/src/HAL/SAMD21/eeprom/eeprom_flash.cpp +++ b/Marlin/src/HAL/SAMD21/eeprom/eeprom_flash.cpp @@ -83,7 +83,7 @@ bool PersistentStore::access_start() { NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_PBC; while (NVMCTRL->INTFLAG.bit.READY == 0) { } - PAGE_SIZE = pow(2,3 + NVMCTRL->PARAM.bit.PSZ); + PAGE_SIZE = POW(2, 3 + NVMCTRL->PARAM.bit.PSZ); ROW_SIZE= PAGE_SIZE * 4; /*NVMCTRL->SEECFG.reg = NVMCTRL_SEECFG_WMODE_BUFFERED; // Buffered mode and segment reallocation active if (NVMCTRL->SEESTAT.bit.RLOCK) diff --git a/Marlin/src/HAL/SAMD21/timers.cpp b/Marlin/src/HAL/SAMD21/timers.cpp index 4ec6e5d867..21a1767fc0 100644 --- a/Marlin/src/HAL/SAMD21/timers.cpp +++ b/Marlin/src/HAL/SAMD21/timers.cpp @@ -165,7 +165,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { tc->COUNT32.INTENCLR.reg = TC_INTENCLR_OVF; // disable overflow interrupt // TCn clock setup - GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC4_TC5)) ; + GCLK->CLKCTRL.reg = uint16_t(GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC4_TC5)); SYNC (GCLK->STATUS.bit.SYNCBUSY); tcReset(tc); // reset TC diff --git a/Marlin/src/HAL/SAMD21/timers.h b/Marlin/src/HAL/SAMD21/timers.h index 303ccbdc50..dfae605595 100644 --- a/Marlin/src/HAL/SAMD21/timers.h +++ b/Marlin/src/HAL/SAMD21/timers.h @@ -33,7 +33,7 @@ // -------------------------------------------------------------------------- typedef uint32_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF +#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT32_MAX) #define HAL_TIMER_RATE F_CPU // frequency of timers peripherals @@ -49,15 +49,14 @@ typedef uint32_t hal_timer_t; #define MF_TIMER_TEMP MF_TIMER_RTC // Timer Index for Temperature #endif -#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency +#define TEMP_TIMER_FREQUENCY 1000 // (Hz) Temperature ISR frequency -#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) -#define STEPPER_TIMER_TICKS_PER_US (STEPPER_TIMER_RATE / 1000000) // stepper timer ticks per µs +#define STEPPER_TIMER_RATE HAL_TIMER_RATE // (Hz) Frequency of Stepper Timer ISR (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) +#define STEPPER_TIMER_TICKS_PER_US (STEPPER_TIMER_RATE / 1000000) // (MHz) Stepper Timer ticks per µs #define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US +#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer +#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE #define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) #define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) @@ -143,9 +142,8 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) { Rtc * const rtc = timer_config[timer_num].pRtc; // Clear interrupt flag rtc->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0| RTC_MODE0_INTFLAG_OVF; - } - else if (timer_config[timer_num].type == TimerType::tcc){ + else if (timer_config[timer_num].type == TimerType::tcc) { Tcc * const tc = timer_config[timer_num].pTcc; // Clear interrupt flag tc->INTFLAG.reg = TCC_INTFLAG_OVF; @@ -157,4 +155,4 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) { } } -#define HAL_timer_isr_epilogue(timer_num) +inline void HAL_timer_isr_epilogue(const uint8_t) {} 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/SAMD51/HAL.h b/Marlin/src/HAL/SAMD51/HAL.h index 51fed64e35..65dcce966d 100644 --- a/Marlin/src/HAL/SAMD51/HAL.h +++ b/Marlin/src/HAL/SAMD51/HAL.h @@ -121,7 +121,7 @@ public: static void delay_ms(const int ms) { delay(ms); } - // Tasks, called from idle() + // Tasks, called from marlin.idle() static void idletask() {} // Reset diff --git a/Marlin/src/HAL/SAMD51/timers.h b/Marlin/src/HAL/SAMD51/timers.h index 86c3241892..2682891cdc 100644 --- a/Marlin/src/HAL/SAMD51/timers.h +++ b/Marlin/src/HAL/SAMD51/timers.h @@ -32,7 +32,7 @@ // -------------------------------------------------------------------------- typedef uint32_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF +#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT32_MAX) #define HAL_TIMER_RATE F_CPU // frequency of timers peripherals @@ -48,15 +48,14 @@ typedef uint32_t hal_timer_t; #define MF_TIMER_TEMP MF_TIMER_RTC // Timer Index for Temperature #endif -#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency +#define TEMP_TIMER_FREQUENCY 1000 // (Hz) Temperature ISR frequency -#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) -#define STEPPER_TIMER_TICKS_PER_US (STEPPER_TIMER_RATE / 1000000) // stepper timer ticks per µs +#define STEPPER_TIMER_RATE HAL_TIMER_RATE // (Hz) Frequency of Stepper Timer ISR (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) +#define STEPPER_TIMER_TICKS_PER_US (STEPPER_TIMER_RATE / 1000000) // (MHz) Stepper Timer ticks per µs #define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US +#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer +#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE #define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) #define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) @@ -145,4 +144,4 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) { } } -#define HAL_timer_isr_epilogue(timer_num) +inline void HAL_timer_isr_epilogue(const uint8_t) {} diff --git a/Marlin/src/HAL/STM32/HAL.cpp b/Marlin/src/HAL/STM32/HAL.cpp index bdccdd546d..018fb48881 100644 --- a/Marlin/src/HAL/STM32/HAL.cpp +++ b/Marlin/src/HAL/STM32/HAL.cpp @@ -66,7 +66,7 @@ void MarlinHAL::init() { // Ensure F_CPU is a constant expression. // If the compiler breaks here, it means that delay code that should compute at compile time will not work. // So better safe than sorry here. - constexpr int cpuFreq = F_CPU; + constexpr unsigned int cpuFreq = F_CPU; UNUSED(cpuFreq); #if HAS_MEDIA && DISABLED(ONBOARD_SDIO) && PIN_EXISTS(SD_SS) @@ -114,7 +114,7 @@ void MarlinHAL::idletask() { void MarlinHAL::reboot() { NVIC_SystemReset(); } uint8_t MarlinHAL::get_reset_source() { - return + return ( #ifdef RCC_FLAG_IWDGRST // Some sources may not exist... RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) ? RST_WATCHDOG : #endif @@ -134,7 +134,7 @@ uint8_t MarlinHAL::get_reset_source() { RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) ? RST_POWER_ON : #endif 0 - ; + ); } void MarlinHAL::clear_reset_source() { __HAL_RCC_CLEAR_RESET_FLAGS(); } diff --git a/Marlin/src/HAL/STM32/HAL.h b/Marlin/src/HAL/STM32/HAL.h index a8ef51bcfc..24889c872a 100644 --- a/Marlin/src/HAL/STM32/HAL.h +++ b/Marlin/src/HAL/STM32/HAL.h @@ -63,8 +63,6 @@ // Types // ------------------------ -typedef double isr_float_t; // FPU ops are used for single-precision, so use double for ISRs. - typedef int32_t pin_t; // Parity with platform/ststm32 class libServo; @@ -157,7 +155,7 @@ public: static void delay_ms(const int ms) { delay(ms); } - // Tasks, called from idle() + // Tasks, called from marlin.idle() static void idletask(); // Reset 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/pinsDebug.h b/Marlin/src/HAL/STM32/pinsDebug.h index b14c9c721c..89e2514af0 100644 --- a/Marlin/src/HAL/STM32/pinsDebug.h +++ b/Marlin/src/HAL/STM32/pinsDebug.h @@ -136,10 +136,8 @@ const XrefInfo pin_xref[] PROGMEM = { #define printPinNumber(Q) #define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0) #define digitalPinToAnalogIndex(P) -1 // will report analog pin number in the print port routine - -// x is a variable used to search pin_array -#define getPinIsDigitalByIndex(x) ((bool) pin_array[x].is_digital) -#define getPinByIndex(x) ((pin_t) pin_array[x].pin) +#define getPinIsDigitalByIndex(x) bool(pin_array[x].is_digital) +#define getPinByIndex(x) pin_t(pin_array[x].pin) #define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) #define MULTI_NAME_PAD 33 // space needed to be pretty if not first name assigned to a pin @@ -229,8 +227,7 @@ void printPinPort(const pin_t pin) { calc_p -= NUM_ANALOG_FIRST; if (calc_p > 7) calc_p += 8; } - SERIAL_ECHOPGM(" M42 P", calc_p); - SERIAL_CHAR(' '); + SERIAL_ECHO(F(" M42 P"), calc_p, C(' ')); if (calc_p < 100) { SERIAL_CHAR(' '); if (calc_p < 10) diff --git a/Marlin/src/HAL/STM32/tft/tft_fsmc.cpp b/Marlin/src/HAL/STM32/tft/tft_fsmc.cpp index bb011ec6f4..70caef6778 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 (!__IS_DMA_CONFIGURED(&DMAtx) || 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 (!__IS_DMA_CONFIGURED(&DMAtx) || 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/timers.cpp b/Marlin/src/HAL/STM32/timers.cpp index 10e0dc43a4..b4271d3a58 100644 --- a/Marlin/src/HAL/STM32/timers.cpp +++ b/Marlin/src/HAL/STM32/timers.cpp @@ -141,7 +141,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { */ timer_instance[timer_num]->setPrescaleFactor(STEPPER_TIMER_PRESCALE); //the -1 is done internally - timer_instance[timer_num]->setOverflow(_MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE) /* /frequency */), TICK_FORMAT); + timer_instance[timer_num]->setOverflow(_MIN(HAL_TIMER_TYPE_MAX, hal_timer_t((HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE) /* / frequency */)), TICK_FORMAT); break; case MF_TIMER_TEMP: // TEMP TIMER - any available 16bit timer timer_instance[timer_num] = new HardwareTimer(TEMP_TIMER_DEV); diff --git a/Marlin/src/HAL/STM32/timers.h b/Marlin/src/HAL/STM32/timers.h index 180e240314..7b55f8a52d 100644 --- a/Marlin/src/HAL/STM32/timers.h +++ b/Marlin/src/HAL/STM32/timers.h @@ -38,7 +38,7 @@ // of adding a run-time check and HAL_TIMER_TYPE_MAX is refactored to allow unique // values for each timer. #define hal_timer_t uint32_t -#define HAL_TIMER_TYPE_MAX UINT16_MAX +#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT16_MAX) // Marlin timer_instance[] content (unrelated to timer selection) #define MF_TIMER_STEP 0 // Timer Index for Stepper @@ -51,20 +51,20 @@ #define TEMP_TIMER_FREQUENCY 1000 // Temperature::isr() is expected to be called at around 1kHz // TODO: get rid of manual rate/prescale/ticks/cycles taken for procedures in stepper.cpp -#define STEPPER_TIMER_RATE 2000000 // 2 Mhz +#define STEPPER_TIMER_RATE 2'000'000 // 2 Mhz extern uint32_t GetStepperTimerClkFreq(); #define STEPPER_TIMER_PRESCALE (GetStepperTimerClkFreq() / (STEPPER_TIMER_RATE)) -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs +#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // (MHz) Stepper Timer ticks per µs -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US +// Pulse Timer (counter) calculations +#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer +#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) +#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) +#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) +#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) +#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) extern void Step_Handler(); @@ -116,5 +116,5 @@ FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const ha } } -#define HAL_timer_isr_prologue(T) NOOP -#define HAL_timer_isr_epilogue(T) NOOP +inline void HAL_timer_isr_prologue(const uint8_t) {} +inline void HAL_timer_isr_epilogue(const uint8_t) {} 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.h b/Marlin/src/HAL/STM32F1/HAL.h index 68773bdf27..2c7321403f 100644 --- a/Marlin/src/HAL/STM32F1/HAL.h +++ b/Marlin/src/HAL/STM32F1/HAL.h @@ -187,7 +187,7 @@ public: static void delay_ms(const int ms) { delay(ms); } - // Tasks, called from idle() + // Tasks, called from marlin.idle() static void idletask(); // Reset 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/Servo.cpp b/Marlin/src/HAL/STM32F1/Servo.cpp index 7aa8fe3d00..00caec287b 100644 --- a/Marlin/src/HAL/STM32F1/Servo.cpp +++ b/Marlin/src/HAL/STM32F1/Servo.cpp @@ -29,8 +29,6 @@ uint8_t ServoCount = 0; #include "Servo.h" -//#include "Servo.h" - #include #include #include diff --git a/Marlin/src/HAL/STM32F1/eeprom/eeprom_flash.cpp b/Marlin/src/HAL/STM32F1/eeprom/eeprom_flash.cpp index 03326db80e..2292c02203 100644 --- a/Marlin/src/HAL/STM32F1/eeprom/eeprom_flash.cpp +++ b/Marlin/src/HAL/STM32F1/eeprom/eeprom_flash.cpp @@ -47,14 +47,14 @@ static uint8_t ram_eeprom[MARLIN_EEPROM_SIZE] __attribute__((aligned(4))) = {0}; static bool eeprom_dirty = false; bool PersistentStore::access_start() { - const uint32_t *source = reinterpret_cast(EEPROM_PAGE0_BASE); - uint32_t *destination = reinterpret_cast(ram_eeprom); + const uint32_t *src = reinterpret_cast(EEPROM_PAGE0_BASE); + uint32_t *dst = reinterpret_cast(ram_eeprom); static_assert(0 == (MARLIN_EEPROM_SIZE) % 4, "MARLIN_EEPROM_SIZE is corrupted. (Must be a multiple of 4.)"); // Ensure copying as uint32_t is safe constexpr size_t eeprom_size_u32 = (MARLIN_EEPROM_SIZE) / 4; - for (size_t i = 0; i < eeprom_size_u32; ++i, ++destination, ++source) - *destination = *source; + for (size_t i = 0; i < eeprom_size_u32; ++i, ++dst, ++src) + *dst = *src; eeprom_dirty = false; return true; @@ -80,9 +80,9 @@ bool PersistentStore::access_finish() { status = FLASH_ErasePage(EEPROM_PAGE1_BASE); if (status != FLASH_COMPLETE) ACCESS_FINISHED(true); - const uint16_t *source = reinterpret_cast(ram_eeprom); - for (size_t i = 0; i < long(MARLIN_EEPROM_SIZE); i += 2, ++source) { - if (FLASH_ProgramHalfWord(EEPROM_PAGE0_BASE + i, *source) != FLASH_COMPLETE) + const uint16_t *src = reinterpret_cast(ram_eeprom); + for (size_t i = 0; i < long(MARLIN_EEPROM_SIZE); i += 2, ++src) { + if (FLASH_ProgramHalfWord(EEPROM_PAGE0_BASE + i, *src) != FLASH_COMPLETE) ACCESS_FINISHED(false); } 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/STM32F1/timers.cpp b/Marlin/src/HAL/STM32F1/timers.cpp index 12477a4583..141dc80b80 100644 --- a/Marlin/src/HAL/STM32F1/timers.cpp +++ b/Marlin/src/HAL/STM32F1/timers.cpp @@ -84,7 +84,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { timer_set_prescaler(STEP_TIMER_DEV, (uint16_t)(STEPPER_TIMER_PRESCALE - 1)); timer_set_reload(STEP_TIMER_DEV, 0xFFFF); timer_oc_set_mode(STEP_TIMER_DEV, STEP_TIMER_CHAN, TIMER_OC_MODE_FROZEN, TIMER_OC_NO_PRELOAD); // no output pin change - timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, _MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (STEPPER_TIMER_RATE) / frequency)); + timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, _MIN(HAL_TIMER_TYPE_MAX, hal_timer_t((STEPPER_TIMER_RATE) / frequency))); timer_no_ARR_preload_ARPE(STEP_TIMER_DEV); // Need to be sure no preload on ARR register timer_attach_interrupt(STEP_TIMER_DEV, STEP_TIMER_CHAN, stepTC_Handler); HAL_timer_set_interrupt_priority(MF_TIMER_STEP, STEP_TIMER_IRQ_PRIO); @@ -97,7 +97,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { timer_set_count(TEMP_TIMER_DEV, 0); timer_set_prescaler(TEMP_TIMER_DEV, (uint16_t)(TEMP_TIMER_PRESCALE - 1)); timer_set_reload(TEMP_TIMER_DEV, 0xFFFF); - timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, _MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (F_CPU) / (TEMP_TIMER_PRESCALE) / frequency)); + timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, _MIN(HAL_TIMER_TYPE_MAX, hal_timer_t((F_CPU) / (TEMP_TIMER_PRESCALE) / frequency))); timer_attach_interrupt(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, tempTC_Handler); HAL_timer_set_interrupt_priority(MF_TIMER_TEMP, TEMP_TIMER_IRQ_PRIO); timer_generate_update(TEMP_TIMER_DEV); diff --git a/Marlin/src/HAL/STM32F1/timers.h b/Marlin/src/HAL/STM32F1/timers.h index 89a609c2c3..3d6650a1a2 100644 --- a/Marlin/src/HAL/STM32F1/timers.h +++ b/Marlin/src/HAL/STM32F1/timers.h @@ -40,7 +40,7 @@ */ typedef uint16_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFF +#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT16_MAX) #define HAL_TIMER_RATE uint32_t(F_CPU) // frequency of timers peripherals @@ -95,27 +95,26 @@ typedef uint16_t hal_timer_t; #define TEMP_TIMER_IRQ_PRIO 3 #define SERVO0_TIMER_IRQ_PRIO 1 -#define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz -#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency +#define TEMP_TIMER_PRESCALE 1000 // Prescaler for setting Temp Timer, 72Khz +#define TEMP_TIMER_FREQUENCY 1000 // (Hz) Temperature ISR frequency -#define STEPPER_TIMER_PRESCALE 18 // prescaler for setting stepper timer, 4Mhz -#define STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // frequency of stepper timer -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs +#define STEPPER_TIMER_PRESCALE 18 // Prescaler for setting stepper timer, 4Mhz +#define STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // (Hz) Frequency of Stepper Timer ISR +#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // (MHz) Stepper Timer ticks per µs -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer +#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer #define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US timer_dev* HAL_get_timer_dev(int number); #define TIMER_DEV(num) HAL_get_timer_dev(num) #define STEP_TIMER_DEV TIMER_DEV(MF_TIMER_STEP) #define TEMP_TIMER_DEV TIMER_DEV(MF_TIMER_TEMP) -#define ENABLE_STEPPER_DRIVER_INTERRUPT() timer_enable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() timer_disable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) +#define ENABLE_STEPPER_DRIVER_INTERRUPT() timer_enable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN) +#define DISABLE_STEPPER_DRIVER_INTERRUPT() timer_disable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN) +#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) -#define ENABLE_TEMPERATURE_INTERRUPT() timer_enable_irq(TEMP_TIMER_DEV, TEMP_TIMER_CHAN) +#define ENABLE_TEMPERATURE_INTERRUPT() timer_enable_irq(TEMP_TIMER_DEV, TEMP_TIMER_CHAN) #define DISABLE_TEMPERATURE_INTERRUPT() timer_disable_irq(TEMP_TIMER_DEV, TEMP_TIMER_CHAN) #define HAL_timer_get_count(timer_num) timer_get_count(TIMER_DEV(timer_num)) @@ -188,7 +187,7 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) { } } -#define HAL_timer_isr_epilogue(T) NOOP +inline void HAL_timer_isr_epilogue(const uint8_t) {} // No command is available in framework to turn off ARPE bit, which is turned on by default in libmaple. // Needed here to reset ARPE=0 for stepper timer diff --git a/Marlin/src/HAL/TEENSY31_32/HAL.h b/Marlin/src/HAL/TEENSY31_32/HAL.h index 03610c65f8..b98ee9eb39 100644 --- a/Marlin/src/HAL/TEENSY31_32/HAL.h +++ b/Marlin/src/HAL/TEENSY31_32/HAL.h @@ -142,7 +142,7 @@ public: static void delay_ms(const int ms) { delay(ms); } - // Tasks, called from idle() + // Tasks, called from marlin.idle() static void idletask() {} // Reset diff --git a/Marlin/src/HAL/TEENSY31_32/Servo.h b/Marlin/src/HAL/TEENSY31_32/Servo.h index 82b601d956..2da74fd25d 100644 --- a/Marlin/src/HAL/TEENSY31_32/Servo.h +++ b/Marlin/src/HAL/TEENSY31_32/Servo.h @@ -31,7 +31,5 @@ class libServo : public Servo { void move(const int value); private: typedef Servo super; - uint16_t min_ticks; - uint16_t max_ticks; uint8_t servoIndex; // index into the channel data for this servo }; diff --git a/Marlin/src/HAL/TEENSY31_32/timers.h b/Marlin/src/HAL/TEENSY31_32/timers.h index 3bbc2421e0..cdca84ec1c 100644 --- a/Marlin/src/HAL/TEENSY31_32/timers.h +++ b/Marlin/src/HAL/TEENSY31_32/timers.h @@ -34,7 +34,7 @@ #define FORCE_INLINE __attribute__((always_inline)) inline typedef uint32_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF +#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT32_MAX) #define FTM0_TIMER_PRESCALE 8 #define FTM1_TIMER_PRESCALE 4 @@ -58,26 +58,25 @@ typedef uint32_t hal_timer_t; #define TEMP_TIMER_FREQUENCY 1000 -#define STEPPER_TIMER_RATE HAL_TIMER_RATE -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) -#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) +#define STEPPER_TIMER_RATE HAL_TIMER_RATE +#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // (MHz) Stepper Timer ticks per µs +#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US +#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer +#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) +#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) +#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) +#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) +#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) #ifndef HAL_STEP_TIMER_ISR - #define HAL_STEP_TIMER_ISR() extern "C" void ftm0_isr() //void TC3_Handler() + #define HAL_STEP_TIMER_ISR() extern "C" void ftm0_isr() #endif #ifndef HAL_TEMP_TIMER_ISR - #define HAL_TEMP_TIMER_ISR() extern "C" void ftm1_isr() //void TC4_Handler() + #define HAL_TEMP_TIMER_ISR() extern "C" void ftm1_isr() #endif void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); @@ -110,4 +109,4 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num); bool HAL_timer_interrupt_enabled(const uint8_t timer_num); void HAL_timer_isr_prologue(const uint8_t timer_num); -#define HAL_timer_isr_epilogue(T) NOOP +inline void HAL_timer_isr_epilogue(const uint8_t) {} diff --git a/Marlin/src/HAL/TEENSY35_36/HAL.h b/Marlin/src/HAL/TEENSY35_36/HAL.h index 0f229000d4..85d02cec8c 100644 --- a/Marlin/src/HAL/TEENSY35_36/HAL.h +++ b/Marlin/src/HAL/TEENSY35_36/HAL.h @@ -147,7 +147,7 @@ public: static void delay_ms(const int ms) { delay(ms); } - // Tasks, called from idle() + // Tasks, called from marlin.idle() static void idletask() {} // Reset diff --git a/Marlin/src/HAL/TEENSY35_36/Servo.h b/Marlin/src/HAL/TEENSY35_36/Servo.h index 719011f102..c37567a813 100644 --- a/Marlin/src/HAL/TEENSY35_36/Servo.h +++ b/Marlin/src/HAL/TEENSY35_36/Servo.h @@ -35,7 +35,5 @@ class libServo : public Servo { void move(const int value); private: typedef Servo super; - uint16_t min_ticks; - uint16_t max_ticks; uint8_t servoIndex; // Index into the channel data for this servo }; diff --git a/Marlin/src/HAL/TEENSY35_36/timers.h b/Marlin/src/HAL/TEENSY35_36/timers.h index 3536b62265..1a5a8460c6 100644 --- a/Marlin/src/HAL/TEENSY35_36/timers.h +++ b/Marlin/src/HAL/TEENSY35_36/timers.h @@ -34,7 +34,7 @@ #define FORCE_INLINE __attribute__((always_inline)) inline typedef uint32_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF +#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT32_MAX) #define FTM0_TIMER_PRESCALE 8 #define FTM1_TIMER_PRESCALE 4 @@ -58,19 +58,18 @@ typedef uint32_t hal_timer_t; #define TEMP_TIMER_FREQUENCY 1000 -#define STEPPER_TIMER_RATE HAL_TIMER_RATE -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) -#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) +#define STEPPER_TIMER_RATE HAL_TIMER_RATE +#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) // (MHz) Stepper Timer ticks per µs +#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US +#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer +#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) +#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) +#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) +#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) +#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) #ifndef HAL_STEP_TIMER_ISR @@ -110,4 +109,4 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num); bool HAL_timer_interrupt_enabled(const uint8_t timer_num); void HAL_timer_isr_prologue(const uint8_t timer_num); -#define HAL_timer_isr_epilogue(T) NOOP +inline void HAL_timer_isr_epilogue(const uint8_t) {} diff --git a/Marlin/src/HAL/TEENSY40_41/HAL.cpp b/Marlin/src/HAL/TEENSY40_41/HAL.cpp index 1f27a283f7..3a1f06095b 100644 --- a/Marlin/src/HAL/TEENSY40_41/HAL.cpp +++ b/Marlin/src/HAL/TEENSY40_41/HAL.cpp @@ -98,7 +98,7 @@ void MarlinHAL::clear_reset_source() { #define WDT_TIMEOUT TERN(WATCHDOG_DURATION_8S, 8, 4) // 4 or 8 second timeout - constexpr uint8_t timeoutval = (WDT_TIMEOUT - 0.5f) / 0.5f; + constexpr uint8_t timeoutval = (WDT_TIMEOUT - 0.5f) * 2.0f; void MarlinHAL::watchdog_init() { CCM_CCGR3 |= CCM_CCGR3_WDOG1(3); // enable WDOG1 clocks diff --git a/Marlin/src/HAL/TEENSY40_41/HAL.h b/Marlin/src/HAL/TEENSY40_41/HAL.h index f884db6684..fc75539e9b 100644 --- a/Marlin/src/HAL/TEENSY40_41/HAL.h +++ b/Marlin/src/HAL/TEENSY40_41/HAL.h @@ -160,7 +160,7 @@ public: static void delay_ms(const int ms) { delay(ms); } - // Tasks, called from idle() + // Tasks, called from marlin.idle() static void idletask() {} // Reset diff --git a/Marlin/src/HAL/TEENSY40_41/Servo.h b/Marlin/src/HAL/TEENSY40_41/Servo.h index 699fd700c9..fceb9465ea 100644 --- a/Marlin/src/HAL/TEENSY40_41/Servo.h +++ b/Marlin/src/HAL/TEENSY40_41/Servo.h @@ -37,7 +37,5 @@ class libServo : public PWMServo { private: typedef PWMServo super; uint8_t servoPin; - uint16_t min_ticks; - uint16_t max_ticks; uint8_t servoIndex; // Index into the channel data for this servo }; diff --git a/Marlin/src/HAL/TEENSY40_41/timers.cpp b/Marlin/src/HAL/TEENSY40_41/timers.cpp index ed99f65d6e..011f9fe31c 100644 --- a/Marlin/src/HAL/TEENSY40_41/timers.cpp +++ b/Marlin/src/HAL/TEENSY40_41/timers.cpp @@ -30,41 +30,82 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { switch (timer_num) { + + // + // Step Timer – GPT1 - Compare Interrupt OCR1 - Reset Mode + // case MF_TIMER_STEP: - CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL; // turn off 24mhz mode + // 24MHz mode off – Use peripheral clock (150MHz) + CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL; + // Enable GPT1 clock gating CCM_CCGR1 |= CCM_CCGR1_GPT1_BUS(CCM_CCGR_ON); - GPT1_CR = 0; // disable timer - GPT1_SR = 0x3F; // clear all prior status - GPT1_PR = GPT1_TIMER_PRESCALE - 1; - GPT1_CR |= GPT_CR_CLKSRC(1); //clock selection #1 (peripheral clock = 150 MHz) - GPT1_CR |= GPT_CR_ENMOD; //reset count to zero before enabling - GPT1_CR |= GPT_CR_OM1(1); // toggle mode - GPT1_OCR1 = (GPT1_TIMER_RATE / frequency) -1; // Initial compare value - GPT1_IR = GPT_IR_OF1IE; // Compare3 value - GPT1_CR |= GPT_CR_EN; //enable GPT2 counting at 150 MHz + // Disable timer, clear all status bits + GPT1_CR = 0; // Disable timer + GPT1_SR = 0x3F; // Clear all prior status - OUT_WRITE(15, HIGH); + // Prescaler = 2 => 75MHz counting clock + GPT1_PR = GPT1_TIMER_PRESCALE - 1; + + GPT1_CR = GPT_CR_CLKSRC(1) // Clock selection #1 (peripheral clock = 150 MHz) + | GPT_CR_ENMOD // Reset count to zero before enabling + | GPT_CR_OM2(TERN(MARLIN_DEV_MODE, 1, 0)); // 0 = edge compare, 1 = toggle + + // Compare value – the number of clocks between edges + GPT1_OCR1 = (GPT1_TIMER_RATE / frequency) - 1; + + // Enable compare‑event interrupt + GPT1_IR = GPT_IR_OF1IE; // OF1 interrupt enabled + + // Pull Pin 15 HIGH (logic‑high is the “idle” state) + TERN_(MARLIN_DEV_MODE, OUT_WRITE(15, HIGH)); + + // Attach and enable Stepper IRQ + // Note: UART priority is 16 attachInterruptVector(IRQ_GPT1, &stepTC_Handler); - NVIC_SET_PRIORITY(IRQ_GPT1, 16); + NVIC_SET_PRIORITY(IRQ_GPT1, 16); // Priority 16 (higher than Temp Timer) + + // Start GPT1 counting at 150 MHz + GPT1_CR |= GPT_CR_EN; + break; + + // + // Temperature Timer – GPT2 - Compare Interrupt OCR1 - Reset Mode + // case MF_TIMER_TEMP: - CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL; // turn off 24mhz mode + // 24MHz mode off – Use peripheral clock (150MHz) + CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL; + // Enable GPT2 clock gating CCM_CCGR0 |= CCM_CCGR0_GPT2_BUS(CCM_CCGR_ON); - GPT2_CR = 0; // disable timer - GPT2_SR = 0x3F; // clear all prior status - GPT2_PR = GPT2_TIMER_PRESCALE - 1; - GPT2_CR |= GPT_CR_CLKSRC(1); //clock selection #1 (peripheral clock = 150 MHz) - GPT2_CR |= GPT_CR_ENMOD; //reset count to zero before enabling - GPT2_CR |= GPT_CR_OM1(1); // toggle mode - GPT2_OCR1 = (GPT2_TIMER_RATE / frequency) -1; // Initial compare value - GPT2_IR = GPT_IR_OF1IE; // Compare3 value - GPT2_CR |= GPT_CR_EN; //enable GPT2 counting at 150 MHz + // Disable timer, clear all status bits + GPT2_CR = 0; // Disable timer + GPT2_SR = 0x3F; // Clear all prior status - OUT_WRITE(14, HIGH); + // Prescaler = 10 => 15MHz counting clock + GPT2_PR = GPT2_TIMER_PRESCALE - 1; + + GPT2_CR = GPT_CR_CLKSRC(1) // Clock selection #1 (peripheral clock = 150 MHz) + | GPT_CR_ENMOD // and reset count to zero before enabling + | GPT_CR_OM2(TERN(MARLIN_DEV_MODE, 1, 0)); // 0 = edge compare, 1 = toggle + + // Compare value – the number of clocks between edges + GPT2_OCR1 = (GPT2_TIMER_RATE / frequency) - 1; + + // Enable compare‑event interrupt + GPT2_IR = GPT_IR_OF1IE; // OF1 interrupt enabled + + // Pull Pin 14 HIGH (logic‑high is the “idle” state) + TERN_(MARLIN_DEV_MODE, OUT_WRITE(14, HIGH)); + + // Attach Temperature ISR attachInterruptVector(IRQ_GPT2, &tempTC_Handler); - NVIC_SET_PRIORITY(IRQ_GPT2, 32); + NVIC_SET_PRIORITY(IRQ_GPT2, 32); // Priority 32 (lower than Step Timer) + + // Start GPT2 counting at 150 MHz + GPT2_CR |= GPT_CR_EN; + break; } } @@ -82,6 +123,7 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num) { case MF_TIMER_TEMP: NVIC_DISABLE_IRQ(IRQ_GPT2); break; } + // Ensure the CPU actually stops servicing the IRQ // We NEED memory barriers to ensure Interrupts are actually disabled! // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the ) asm volatile("dsb"); @@ -97,8 +139,8 @@ bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { void HAL_timer_isr_prologue(const uint8_t timer_num) { switch (timer_num) { - case MF_TIMER_STEP: GPT1_SR = GPT_IR_OF1IE; break; // clear OF3 bit - case MF_TIMER_TEMP: GPT2_SR = GPT_IR_OF1IE; break; // clear OF3 bit + case MF_TIMER_STEP: GPT1_SR = GPT_IR_OF1IE; break; // clear OF1 + case MF_TIMER_TEMP: GPT2_SR = GPT_IR_OF1IE; break; } asm volatile("dsb"); } diff --git a/Marlin/src/HAL/TEENSY40_41/timers.h b/Marlin/src/HAL/TEENSY40_41/timers.h index fc160ab8b8..66d00b1788 100644 --- a/Marlin/src/HAL/TEENSY40_41/timers.h +++ b/Marlin/src/HAL/TEENSY40_41/timers.h @@ -34,7 +34,7 @@ #define FORCE_INLINE __attribute__((always_inline)) inline typedef uint32_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFE +#define HAL_TIMER_TYPE_MAX hal_timer_t(UINT32_MAX-1UL) #define GPT_TIMER_RATE (F_CPU / 4) // 150MHz (Can't use F_BUS_ACTUAL because it's extern volatile) @@ -57,20 +57,19 @@ typedef uint32_t hal_timer_t; #define TEMP_TIMER_RATE 1000000 #define TEMP_TIMER_FREQUENCY 1000 -#define HAL_TIMER_RATE GPT1_TIMER_RATE -#define STEPPER_TIMER_RATE HAL_TIMER_RATE -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) -#define STEPPER_TIMER_PRESCALE ((GPT_TIMER_RATE / 1000000) / STEPPER_TIMER_TICKS_PER_US) +#define HAL_TIMER_RATE GPT1_TIMER_RATE +#define STEPPER_TIMER_RATE HAL_TIMER_RATE +#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000UL) +#define STEPPER_TIMER_PRESCALE (GPT_TIMER_RATE / STEPPER_TIMER_RATE) -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US +#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // (Hz) Frequency of Pulse Timer +#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) +#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) +#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) +#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) +#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) #ifndef HAL_STEP_TIMER_ISR @@ -89,8 +88,16 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) { switch (timer_num) { - case MF_TIMER_STEP: GPT1_OCR1 = compare - 1; break; - case MF_TIMER_TEMP: GPT2_OCR1 = compare - 1; break; + case MF_TIMER_STEP: + GPT1_CR |= GPT_CR_FRR; // Free Run Mode (setting OCRx preserves CNT) + GPT1_OCR1 = compare - 1; + GPT1_CR &= ~GPT_CR_FRR; // Reset Mode (CNT resets on trigger) + break; + case MF_TIMER_TEMP: + GPT2_CR |= GPT_CR_FRR; // Free Run Mode (setting OCRx preserves CNT) + GPT2_OCR1 = compare - 1; + GPT2_CR &= ~GPT_CR_FRR; // Reset Mode (CNT resets on trigger) + break; } } @@ -115,5 +122,4 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num); bool HAL_timer_interrupt_enabled(const uint8_t timer_num); void HAL_timer_isr_prologue(const uint8_t timer_num); -//void HAL_timer_isr_epilogue(const uint8_t timer_num) {} -#define HAL_timer_isr_epilogue(T) NOOP +inline void HAL_timer_isr_epilogue(const uint8_t) {} 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/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index 29e0c79cbc..2a21163a1b 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -74,11 +74,11 @@ #endif #if HAS_DWIN_E3V2 - #include "lcd/e3v2/common/encoder.h" + #include "lcd/dwin/common/encoder.h" #if ENABLED(DWIN_CREALITY_LCD) - #include "lcd/e3v2/creality/dwin.h" + #include "lcd/dwin/creality/dwin.h" #elif ENABLED(DWIN_CREALITY_LCD_JYERSUI) - #include "lcd/e3v2/jyersui/dwin.h" + #include "lcd/dwin/jyersui/dwin.h" #elif ENABLED(DWIN_LCD_PROUI) #include "lcd/extui/ui_api.h" #elif ENABLED(SOVOL_SV06_RTS) @@ -162,15 +162,6 @@ #include "feature/spindle_laser.h" #endif -#if HAS_MEDIA - CardReader card; -#endif - -#if ENABLED(G38_PROBE_TARGET) - uint8_t G38_move; // = 0 - bool G38_did_trigger; // = false -#endif - #if ENABLED(DELTA) #include "module/delta.h" #elif ENABLED(POLARGRAPH) @@ -271,33 +262,51 @@ #include "feature/rs485.h" #endif +/** + * Spin in place here while keeping temperature processing alive + */ +void safe_delay(millis_t ms) { + while (ms > 50) { + ms -= 50; + delay(50); + thermalManager.task(); + } + delay(ms); + thermalManager.task(); // This keeps us safe if too many small safe_delay() calls are made +} + +// Singleton for Marlin global data and methods +Marlin marlin; + +// Marlin static data +#if ENABLED(CONFIGURABLE_MACHINE_NAME) + MString<64> Marlin::machine_name; +#endif + +// Global state of the firmware +MarlinState Marlin::state = MF_INITIALIZING; + +// For M109 and M190, this flag may be cleared (by M108) to exit the wait loop +bool Marlin::wait_for_heatup = false; + #if !HAS_MEDIA CardReader card; // Stub instance with "no media" methods #endif PGMSTR(M112_KILL_STR, "M112 Shutdown"); -#if ENABLED(CONFIGURABLE_MACHINE_NAME) - MString<64> machine_name; -#endif - -MarlinState marlin_state = MarlinState::MF_INITIALIZING; - -// For M109 and M190, this flag may be cleared (by M108) to exit the wait loop -bool wait_for_heatup = false; - // For M0/M1, this flag may be cleared (by M108) to exit the wait-for-user loop #if HAS_RESUME_CONTINUE - bool wait_for_user; // = false + bool Marlin::wait_for_user; // = false - void wait_for_user_response(millis_t ms/*=0*/, const bool no_sleep/*=false*/) { + void Marlin::wait_for_user_response(millis_t ms/*=0*/, const bool no_sleep/*=false*/) { UNUSED(no_sleep); KEEPALIVE_STATE(PAUSED_FOR_USER); - wait_for_user = true; + wait_start(); if (ms) ms += millis(); // expire time while (wait_for_user && !(ms && ELAPSED(millis(), ms))) idle(TERN_(ADVANCED_PAUSE_FEATURE, no_sleep)); - wait_for_user = false; + user_resume(); while (ui.button_pressed()) safe_delay(50); } @@ -327,7 +336,7 @@ bool wait_for_heatup = false; #pragma GCC diagnostic ignored "-Wnarrowing" #pragma GCC diagnostic ignored "-Wsign-compare" -bool pin_is_protected(const pin_t pin) { +bool Marlin::pin_is_protected(const pin_t pin) { #define pgm_read_pin(P) (sizeof(pin_t) == 2 ? (pin_t)pgm_read_word(P) : (pin_t)pgm_read_byte(P)) for (uint8_t i = 0; i < COUNT(sensitive_dio); ++i) if (pin == pgm_read_pin(&sensitive_dio[i])) return true; @@ -338,28 +347,28 @@ bool pin_is_protected(const pin_t pin) { #pragma GCC diagnostic pop -bool printer_busy() { +bool Marlin::printer_busy() { return planner.has_blocks_queued() || printingIsActive(); } /** * A Print Job exists when the timer is running or SD is printing */ -bool printJobOngoing() { return print_job_timer.isRunning() || card.isStillPrinting(); } +bool Marlin::printJobOngoing() { return print_job_timer.isRunning() || card.isStillPrinting(); } /** * Printing is active when a job is underway but not paused */ -bool printingIsActive() { return !did_pause_print && printJobOngoing(); } +bool Marlin::printingIsActive() { return !did_pause_print && printJobOngoing(); } /** * Printing is paused according to SD or host indicators */ -bool printingIsPaused() { +bool Marlin::printingIsPaused() { return did_pause_print || print_job_timer.isPaused() || card.isPaused(); } -void startOrResumeJob() { +void Marlin::startOrResumeJob() { if (!printingIsPaused()) { TERN_(GCODE_REPEAT_MARKERS, repeat.reset()); TERN_(CANCEL_OBJECTS, cancelable.reset()); @@ -385,7 +394,7 @@ void startOrResumeJob() { TERN(HAS_CUTTER, cutter.kill(), thermalManager.zero_fan_speeds()); // Full cutter shutdown including ISR control - wait_for_heatup = false; + marlin.heatup_done(); TERN_(POWER_LOSS_RECOVERY, recovery.purge()); @@ -397,8 +406,8 @@ void startOrResumeJob() { } inline void finishSDPrinting() { - if (queue.enqueue_one(F("M1001"))) { // Keep trying until it gets queued - marlin_state = MarlinState::MF_RUNNING; // Signal to stop trying + if (queue.enqueue_one(F("M1001"))) { // Keep trying until it gets queued + marlin.setState(MF_RUNNING); // Signal to stop trying TERN_(PASSWORD_AFTER_SD_PRINT_END, password.lock_machine()); TERN_(DGUS_LCD_UI_MKS, screen.sdPrintingFinished()); } @@ -419,7 +428,7 @@ void startOrResumeJob() { * - Check if an idle but hot extruder needs filament extruded (EXTRUDER_RUNOUT_PREVENT) * - Pulse FET_SAFETY_PIN if it exists */ -inline void manage_inactivity(const bool no_stepper_sleep=false) { +void Marlin::manage_inactivity(const bool no_stepper_sleep/*=false*/) { queue.get_available_commands(); @@ -533,11 +542,15 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) { constexpr millis_t CUB_DEBOUNCE_DELAY_##N = 250UL; \ static millis_t next_cub_ms_##N; \ if (BUTTON##N##_HIT_STATE == READ(BUTTON##N##_PIN) \ - && (ENABLED(BUTTON##N##_WHEN_PRINTING) || printer_not_busy)) { \ + && (ENABLED(BUTTON##N##_WHEN_PRINTING) || printer_not_busy) \ + ) { \ if (ELAPSED(ms, next_cub_ms_##N)) { \ next_cub_ms_##N = ms + CUB_DEBOUNCE_DELAY_##N; \ CODE; \ - queue.inject(F(BUTTON##N##_GCODE)); \ + if (ENABLED(BUTTON##N##_IMMEDIATE)) \ + gcode.process_subcommands_now(F(BUTTON##N##_GCODE)); \ + else \ + queue.inject(F(BUTTON##N##_GCODE)); \ TERN_(HAS_MARLINUI_MENU, ui.quick_feedback()); \ } \ } \ @@ -711,9 +724,9 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) { #if ENABLED(DUAL_X_CARRIAGE) // handle delayed move timeout - if (delayed_move_time && ELAPSED(ms, delayed_move_time) && IsRunning()) { + if (delayed_move_time && ELAPSED(ms, delayed_move_time) && isRunning()) { // travel moves have been received so enact them - delayed_move_time = 0xFFFFFFFFUL; // force moves to be done + delayed_move_time = UINT32_MAX; // force moves to be done destination = current_position; prepare_line_to_destination(); planner.synchronize(); @@ -740,7 +753,8 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) { WRITE(FET_SAFETY_PIN, FET_SAFETY_INVERTED); } #endif -} // manage_inactivity() + +} // Marlin::manage_inactivity() #if ALL(EP_BABYSTEPPING, EMERGENCY_PARSER) #include "feature/babystep.h" @@ -768,14 +782,14 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) { * - Update the Průša MMU2 * - Handle Joystick jogging */ -void idle(const bool no_stepper_sleep/*=false*/) { +void Marlin::idle(const bool no_stepper_sleep/*=false*/) { #ifdef MAX7219_DEBUG_PROFILE CodeProfiler idle_profiler; #endif #if ENABLED(MARLIN_DEV_MODE) static uint16_t idle_depth = 0; - if (++idle_depth > 5) SERIAL_ECHOLNPGM("idle() call depth: ", idle_depth); + if (++idle_depth > 5) SERIAL_ECHOLNPGM("Marlin::idle() call depth: ", idle_depth); #endif // Bed Distance Sensor task @@ -791,7 +805,7 @@ void idle(const bool no_stepper_sleep/*=false*/) { TERN_(MAX7219_DEBUG, max7219.idle_tasks()); // Return if setup() isn't completed - if (marlin_state == MarlinState::MF_INITIALIZING) goto IDLE_DONE; + if (is(MF_INITIALIZING)) goto IDLE_DONE; // TODO: Still causing errors TERN_(TOOL_SENSOR, (void)check_tool_sensor_stats(active_extruder, true)); @@ -891,13 +905,14 @@ void idle(const bool no_stepper_sleep/*=false*/) { TERN_(MARLIN_DEV_MODE, idle_depth--); return; -} // idle() + +} // Marlin::idle() /** * Kill all activity and lock the machine. * After this the machine will need to be reset. */ -void kill(FSTR_P const lcd_error/*=nullptr*/, FSTR_P const lcd_component/*=nullptr*/, const bool steppers_off/*=false*/) { +void Marlin::kill(FSTR_P const lcd_error/*=nullptr*/, FSTR_P const lcd_component/*=nullptr*/, const bool steppers_off/*=false*/) { thermalManager.disable_all_heaters(); TERN_(HAS_CUTTER, cutter.kill()); // Full cutter shutdown including ISR control @@ -923,7 +938,7 @@ void kill(FSTR_P const lcd_error/*=nullptr*/, FSTR_P const lcd_component/*=nullp minkill(steppers_off); } -void minkill(const bool steppers_off/*=false*/) { +void Marlin::minkill(const bool steppers_off/*=false*/) { // Wait a short time (allows messages to get out before shutting down. for (int i = 1000; i--;) DELAY_US(600); @@ -963,13 +978,14 @@ void minkill(const bool steppers_off/*=false*/) { for (;;) hal.watchdog_refresh(); // Wait for RESET button or power-cycle #endif -} + +} // Marlin::minkill /** * Turn off heaters and stop the print in progress * After a stop the machine may be resumed with M999 */ -void stop() { +void Marlin::stop() { thermalManager.disable_all_heaters(); // 'unpause' taken care of in here print_job_timer.stop(); @@ -978,13 +994,13 @@ void stop() { thermalManager.set_fans_paused(false); // Un-pause fans for safety #endif - if (!IsStopped()) { + if (!isStopped()) { SERIAL_ERROR_MSG(STR_ERR_STOPPED); LCD_MESSAGE(MSG_STOPPED); - safe_delay(350); // allow enough time for messages to get out before stopping - marlin_state = MarlinState::MF_STOPPED; + safe_delay(350); // Allow enough time for messages to get out before stopping + setState(MF_STOPPED); } -} // stop() +} // Marlin::stop() inline void tmc_standby_setup() { #if PIN_EXISTS(X_STDBY) @@ -1695,7 +1711,7 @@ void setup() { SETUP_RUN(ftMotion.init()); #endif - marlin_state = MarlinState::MF_RUNNING; + marlin.setState(MF_RUNNING); #ifdef STARTUP_TUNE // Play a short startup tune before continuing. @@ -1711,7 +1727,7 @@ void setup() { /** * The main Marlin program loop * - * - Call idle() to handle all tasks between G-code commands + * - Call marlin.idle() to handle all tasks between G-code commands * Note that no G-codes from the queue can be executed during idle() * but many G-codes can be called directly anytime like macros. * - Check whether SD card auto-start is needed now. @@ -1723,11 +1739,11 @@ void setup() { */ void loop() { do { - idle(); + marlin.idle(); #if HAS_MEDIA if (card.flag.abort_sd_printing) abortSDPrinting(); - if (marlin_state == MarlinState::MF_SD_COMPLETE) finishSDPrinting(); + if (marlin.is(MF_SD_COMPLETE)) finishSDPrinting(); #endif queue.advance(); diff --git a/Marlin/src/MarlinCore.h b/Marlin/src/MarlinCore.h index ecab0e3630..35482983ec 100644 --- a/Marlin/src/MarlinCore.h +++ b/Marlin/src/MarlinCore.h @@ -27,26 +27,8 @@ #include #include -void stop(); - -// Pass true to keep steppers from timing out -void idle(const bool no_stepper_sleep=false); -inline void idle_no_sleep() { idle(true); } - -#if ENABLED(G38_PROBE_TARGET) - extern uint8_t G38_move; // Flag to tell the ISR that G38 is in progress, and the type - extern bool G38_did_trigger; // Flag from the ISR to indicate the endstop changed -#endif - -void kill(FSTR_P const lcd_error=nullptr, FSTR_P const lcd_component=nullptr, const bool steppers_off=false); -void minkill(const bool steppers_off=false); - -#if ENABLED(CONFIGURABLE_MACHINE_NAME) - extern MString<64> machine_name; -#endif - // Global State of the firmware -enum class MarlinState : uint8_t { +enum MarlinState : uint8_t { MF_INITIALIZING = 0, MF_STOPPED, MF_KILLED, @@ -56,35 +38,81 @@ enum class MarlinState : uint8_t { MF_WAITING, }; -extern MarlinState marlin_state; -inline bool IsRunning() { return marlin_state >= MarlinState::MF_RUNNING; } -inline bool IsStopped() { return marlin_state == MarlinState::MF_STOPPED; } +typedef bool (*testFunc_t)(); -bool printingIsActive(); -bool printJobOngoing(); -bool printingIsPaused(); -void startOrResumeJob(); +// Delay ensuring that temperatures are updated and the watchdog is kept alive +void safe_delay(millis_t ms); -bool printer_busy(); +// Singleton for Marlin global data and methods -extern bool wait_for_heatup; - -#if HAS_RESUME_CONTINUE - extern bool wait_for_user; - void wait_for_user_response(millis_t ms=0, const bool no_sleep=false); -#endif - -bool pin_is_protected(const pin_t pin); - -#if HAS_SUICIDE - inline void suicide() { OUT_WRITE(SUICIDE_PIN, SUICIDE_PIN_STATE); } -#endif - -#if HAS_KILL - #ifndef KILL_PIN_STATE - #define KILL_PIN_STATE LOW +class Marlin { +public: + #if ENABLED(CONFIGURABLE_MACHINE_NAME) + static MString<64> machine_name; #endif - inline bool kill_state() { return READ(KILL_PIN) == KILL_PIN_STATE; } -#endif + + static MarlinState state; + static void setState(const MarlinState s) { state = s; } + static bool is(const MarlinState s) { return state == s; } + static bool isStopped() { return is(MF_STOPPED); } + static bool isRunning() { return state >= MF_RUNNING; } + + static bool printingIsActive(); + static bool printJobOngoing(); + static bool printingIsPaused(); + static void startOrResumeJob(); + + static bool printer_busy(); + + static void stop(); + + // Maintain all important activities + static void manage_inactivity(const bool no_stepper_sleep=false); + + // Pass true to keep steppers from timing out + static void idle(const bool no_stepper_sleep=false); + static void idle_no_sleep() { idle(true); } + + static void kill(FSTR_P const lcd_error=nullptr, FSTR_P const lcd_component=nullptr, const bool steppers_off=false); + static void minkill(const bool steppers_off=false); + + #if HAS_RESUME_CONTINUE + // Global waiting for user response + static bool wait_for_user; + static void wait_start() { wait_for_user = true; } + static void user_resume() { wait_for_user = false; } + static void wait_for_user_response(millis_t ms=0, const bool no_sleep=false); + #endif + + // Global waiting for heatup state + static bool wait_for_heatup; + static bool is_heating() { return wait_for_heatup; } + static void heatup_start() { wait_for_heatup = true; } + static void heatup_done() { wait_for_heatup = false; } + static void end_waiting() { TERN_(HAS_RESUME_CONTINUE, wait_for_user =) wait_for_heatup = false; } + + // Shared function for M42 / M43 + static bool pin_is_protected(const pin_t pin); + + #if HAS_SUICIDE + static void suicide() { OUT_WRITE(SUICIDE_PIN, SUICIDE_PIN_STATE); } + #endif + + static bool kill_state() { + return ( + #if HAS_KILL + #ifndef KILL_PIN_STATE + #define KILL_PIN_STATE LOW + #endif + READ(KILL_PIN) == KILL_PIN_STATE + #else + false + #endif + ); + } + +}; + +extern Marlin marlin; extern const char M112_KILL_STR[]; diff --git a/Marlin/src/core/boards.h b/Marlin/src/core/boards.h index 0ee4b75cfa..6c51cb01a4 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 // @@ -54,11 +55,11 @@ #define BOARD_RAMPS_PLUS_EEF 1033 // RAMPS Plus 3DYMY (Power outputs: Hotend0, Hotend1, Fan) #define BOARD_RAMPS_PLUS_SF 1034 // RAMPS Plus 3DYMY (Power outputs: Spindle, Controller Fan) -#define BOARD_RAMPS_BTT_16_PLUS_EFB 1035 // RAMPS 1.6+ (Power outputs: Hotend, Fan, Bed) -#define BOARD_RAMPS_BTT_16_PLUS_EEB 1036 // RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Bed) -#define BOARD_RAMPS_BTT_16_PLUS_EFF 1037 // RAMPS 1.6+ (Power outputs: Hotend, Fan0, Fan1) -#define BOARD_RAMPS_BTT_16_PLUS_EEF 1038 // RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Fan) -#define BOARD_RAMPS_BTT_16_PLUS_SF 1039 // RAMPS 1.6+ (Power outputs: Spindle, Controller Fan) +#define BOARD_RAMPS_BTT_16_PLUS_EFB 1040 // RAMPS 1.6+ (Power outputs: Hotend, Fan, Bed) +#define BOARD_RAMPS_BTT_16_PLUS_EEB 1041 // RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Bed) +#define BOARD_RAMPS_BTT_16_PLUS_EFF 1042 // RAMPS 1.6+ (Power outputs: Hotend, Fan0, Fan1) +#define BOARD_RAMPS_BTT_16_PLUS_EEF 1043 // RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Fan) +#define BOARD_RAMPS_BTT_16_PLUS_SF 1044 // RAMPS 1.6+ (Power outputs: Spindle, Controller Fan) // // RAMPS Derivatives - ATmega1280, ATmega2560 @@ -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 @@ -429,67 +431,68 @@ // STM32 ARM Cortex-M4F // -#define BOARD_ARMED 5200 // Arm'ed STM32F4-based controller -#define BOARD_RUMBA32_V1_0 5201 // RUMBA32 STM32F446VE based controller from Aus3D -#define BOARD_RUMBA32_V1_1 5202 // RUMBA32 STM32F446VE based controller from Aus3D -#define BOARD_RUMBA32_MKS 5203 // RUMBA32 STM32F446VE based controller from Makerbase -#define BOARD_RUMBA32_BTT 5204 // RUMBA32 STM32F446VE based controller from BIGTREETECH -#define BOARD_BLACK_STM32F407VE 5205 // Black STM32F407VE development board -#define BOARD_BLACK_STM32F407ZE 5206 // Black STM32F407ZE development board -#define BOARD_BTT_SKR_MINI_E3_V3_0_1 5207 // BigTreeTech SKR Mini E3 V3.0.1 (STM32F401RC) -#define BOARD_BTT_SKR_PRO_V1_1 5208 // BigTreeTech SKR Pro v1.1 (STM32F407ZG) -#define BOARD_BTT_SKR_PRO_V1_2 5209 // BigTreeTech SKR Pro v1.2 (STM32F407ZG) -#define BOARD_BTT_BTT002_V1_0 5210 // BigTreeTech BTT002 v1.0 (STM32F407VG) -#define BOARD_BTT_E3_RRF 5211 // BigTreeTech E3 RRF (STM32F407VG) -#define BOARD_BTT_SKR_V2_0_REV_A 5212 // BigTreeTech SKR v2.0 Rev A (STM32F407VG) -#define BOARD_BTT_SKR_V2_0_REV_B 5213 // BigTreeTech SKR v2.0 Rev B (STM32F407VG/STM32F429VG) -#define BOARD_BTT_GTR_V1_0 5214 // BigTreeTech GTR v1.0 (STM32F407IGT) -#define BOARD_BTT_OCTOPUS_V1_0 5215 // BigTreeTech Octopus v1.0 (STM32F446ZE) -#define BOARD_BTT_OCTOPUS_V1_1 5216 // BigTreeTech Octopus v1.1 (STM32F446ZE) -#define BOARD_BTT_OCTOPUS_PRO_V1_0 5217 // BigTreeTech Octopus Pro v1.0 (STM32F446ZE / STM32F429ZG) -#define BOARD_LERDGE_K 5218 // Lerdge K (STM32F407ZG) -#define BOARD_LERDGE_S 5219 // Lerdge S (STM32F407VE) -#define BOARD_LERDGE_X 5220 // Lerdge X (STM32F407VE) -#define BOARD_FYSETC_S6 5221 // FYSETC S6 (STM32F446VE) -#define BOARD_FYSETC_S6_V2_0 5222 // FYSETC S6 v2.0 (STM32F446VE) -#define BOARD_FYSETC_SPIDER 5223 // FYSETC Spider (STM32F446VE) -#define BOARD_FYSETC_SPIDER_V2_2 5224 // FYSETC Spider V2.2 (STM32F446VE) -#define BOARD_FLYF407ZG 5225 // FLYmaker FLYF407ZG (STM32F407ZG) -#define BOARD_MKS_ROBIN2 5226 // MKS Robin2 V1.0 (STM32F407ZE) -#define BOARD_MKS_ROBIN_PRO_V2 5227 // MKS Robin Pro V2 (STM32F407VE) -#define BOARD_MKS_ROBIN_NANO_V3 5228 // MKS Robin Nano V3 (STM32F407VG) -#define BOARD_MKS_ROBIN_NANO_V3_1 5229 // MKS Robin Nano V3.1 (STM32F407VE) -#define BOARD_MKS_MONSTER8_V1 5230 // MKS Monster8 V1 (STM32F407VE) -#define BOARD_MKS_MONSTER8_V2 5231 // MKS Monster8 V2 (STM32F407VE) -#define BOARD_ANET_ET4 5232 // ANET ET4 V1.x (STM32F407VG) -#define BOARD_ANET_ET4P 5233 // ANET ET4P V1.x (STM32F407VG) -#define BOARD_FYSETC_CHEETAH_V20 5234 // FYSETC Cheetah V2.0 (STM32F401RC) -#define BOARD_FYSETC_CHEETAH_V30 5235 // FYSETC Cheetah V3.0 (STM32F446RC) -#define BOARD_TH3D_EZBOARD_V2 5236 // TH3D EZBoard v2.0 (STM32F405RG) -#define BOARD_OPULO_LUMEN_REV3 5237 // Opulo Lumen PnP Controller REV3 (STM32F407VE / STM32F407VG) -#define BOARD_OPULO_LUMEN_REV4 5238 // Opulo Lumen PnP Controller REV4 (STM32F407VE / STM32F407VG) -#define BOARD_MKS_ROBIN_NANO_V1_3_F4 5239 // MKS Robin Nano V1.3 and MKS Robin Nano-S V1.3 (STM32F407VE) -#define BOARD_MKS_EAGLE 5240 // MKS Eagle (STM32F407VE) -#define BOARD_ARTILLERY_RUBY 5241 // Artillery Ruby (STM32F401RC) -#define BOARD_CREALITY_V24S1_301F4 5242 // Creality v2.4.S1_301F4 (STM32F401RC) as found in the Ender-3 S1 F4 -#define BOARD_CREALITY_CR4NTXXC10 5243 // Creality E3 Free-runs Silent Motherboard (STM32F401RET6) -#define BOARD_FYSETC_SPIDER_KING407 5244 // FYSETC Spider King407 (STM32F407ZG) -#define BOARD_MKS_SKIPR_V1 5245 // MKS SKIPR v1.0 all-in-one board (STM32F407VE) -#define BOARD_TRONXY_CXY_446_V10 5246 // TRONXY CXY-446-V10-220413/CXY-V6-191121 (STM32F446ZE) -#define BOARD_CREALITY_F401RE 5247 // Creality CR4NS200141C13 (STM32F401RE) as found in the Ender-5 S1 -#define BOARD_BLACKPILL_CUSTOM 5248 // Custom board based on STM32F401CDU6. -#define BOARD_I3DBEEZ9_V1 5249 // I3DBEEZ9 V1 (STM32F407ZG) -#define BOARD_MELLOW_FLY_E3_V2 5250 // Mellow Fly E3 V2 (STM32F407VG) -#define BOARD_BLACKBEEZMINI_V1 5251 // BlackBeezMini V1 (STM32F401CCU6) -#define BOARD_XTLW_CLIMBER_8TH 5252 // XTLW Climber-8th (STM32F407VGT6) -#define BOARD_FLY_RRF_E3_V1 5253 // Fly RRF E3 V1.0 (STM32F407VG) -#define BOARD_FLY_SUPER8 5254 // Fly SUPER8 (STM32F407ZGT6) -#define BOARD_FLY_D8 5255 // FLY D8 (STM32F407VG) -#define BOARD_FLY_CDY_V3 5256 // FLY CDY V3 (STM32F407VGT6) -#define BOARD_ZNP_ROBIN_NANO 5257 // Elegoo Neptune 2 v1.2 board -#define BOARD_ZNP_ROBIN_NANO_V1_3 5258 // Elegoo Neptune 2 v1.3 board -#define BOARD_MKS_NEPTUNE_X 5259 // Elegoo Neptune X -#define BOARD_MKS_NEPTUNE_3 5260 // Elegoo Neptune 3 +#define BOARD_ARMED 5200 // Arm'ed STM32F4-based controller +#define BOARD_RUMBA32_V1_0 5201 // RUMBA32 STM32F446VE based controller from Aus3D +#define BOARD_RUMBA32_V1_1 5202 // RUMBA32 STM32F446VE based controller from Aus3D +#define BOARD_RUMBA32_MKS 5203 // RUMBA32 STM32F446VE based controller from Makerbase +#define BOARD_RUMBA32_BTT 5204 // RUMBA32 STM32F446VE based controller from BIGTREETECH +#define BOARD_BLACK_STM32F407VE 5205 // Black STM32F407VE development board +#define BOARD_BLACK_STM32F407ZE 5206 // Black STM32F407ZE development board +#define BOARD_BTT_SKR_MINI_E3_V3_0_1 5207 // BigTreeTech SKR Mini E3 V3.0.1 (STM32F401RC) +#define BOARD_BTT_SKR_PRO_V1_1 5208 // BigTreeTech SKR Pro v1.1 (STM32F407ZG) +#define BOARD_BTT_SKR_PRO_V1_2 5209 // BigTreeTech SKR Pro v1.2 (STM32F407ZG) +#define BOARD_BTT_BTT002_V1_0 5210 // BigTreeTech BTT002 v1.0 (STM32F407VG) +#define BOARD_BTT_E3_RRF 5211 // BigTreeTech E3 RRF (STM32F407VG) +#define BOARD_BTT_SKR_V2_0_REV_A 5212 // BigTreeTech SKR v2.0 Rev A (STM32F407VG) +#define BOARD_BTT_SKR_V2_0_REV_B 5213 // BigTreeTech SKR v2.0 Rev B (STM32F407VG/STM32F429VG) +#define BOARD_BTT_GTR_V1_0 5214 // BigTreeTech GTR v1.0 (STM32F407IGT) +#define BOARD_BTT_OCTOPUS_V1_0 5215 // BigTreeTech Octopus v1.0 (STM32F446ZE) +#define BOARD_BTT_OCTOPUS_V1_1 5216 // BigTreeTech Octopus v1.1 (STM32F446ZE) +#define BOARD_BTT_OCTOPUS_PRO_V1_0 5217 // BigTreeTech Octopus Pro v1.0 (STM32F446ZE / STM32F429ZG) +#define BOARD_LERDGE_K 5218 // Lerdge K (STM32F407ZG) +#define BOARD_LERDGE_S 5219 // Lerdge S (STM32F407VE) +#define BOARD_LERDGE_X 5220 // Lerdge X (STM32F407VE) +#define BOARD_FYSETC_S6 5221 // FYSETC S6 (STM32F446VE) +#define BOARD_FYSETC_S6_V2_0 5222 // FYSETC S6 v2.0 (STM32F446VE) +#define BOARD_FYSETC_SPIDER 5223 // FYSETC Spider (STM32F446VE) +#define BOARD_FYSETC_SPIDER_V2_2 5224 // FYSETC Spider V2.2 (STM32F446VE) +#define BOARD_FLYF407ZG 5225 // FLYmaker FLYF407ZG (STM32F407ZG) +#define BOARD_MKS_ROBIN2 5226 // MKS Robin2 V1.0 (STM32F407ZE) +#define BOARD_MKS_ROBIN_PRO_V2 5227 // MKS Robin Pro V2 (STM32F407VE) +#define BOARD_MKS_ROBIN_NANO_V3 5228 // MKS Robin Nano V3 (STM32F407VG) +#define BOARD_MKS_ROBIN_NANO_V3_1 5229 // MKS Robin Nano V3.1 (STM32F407VE) +#define BOARD_MKS_MONSTER8_V1 5230 // MKS Monster8 V1 (STM32F407VE) +#define BOARD_MKS_MONSTER8_V2 5231 // MKS Monster8 V2 (STM32F407VE) +#define BOARD_ANET_ET4 5232 // ANET ET4 V1.x (STM32F407VG) +#define BOARD_ANET_ET4P 5233 // ANET ET4P V1.x (STM32F407VG) +#define BOARD_FYSETC_CHEETAH_V20 5234 // FYSETC Cheetah V2.0 (STM32F401RC) +#define BOARD_FYSETC_CHEETAH_V30 5235 // FYSETC Cheetah V3.0 (STM32F446RC) +#define BOARD_TH3D_EZBOARD_V2 5236 // TH3D EZBoard v2.0 (STM32F405RG) +#define BOARD_OPULO_LUMEN_REV3 5237 // Opulo Lumen PnP Controller REV3 (STM32F407VE / STM32F407VG) +#define BOARD_OPULO_LUMEN_REV4 5238 // Opulo Lumen PnP Controller REV4 (STM32F407VE / STM32F407VG) +#define BOARD_MKS_ROBIN_NANO_V1_3_F4 5239 // MKS Robin Nano V1.3 and MKS Robin Nano-S V1.3 (STM32F407VE) +#define BOARD_MKS_EAGLE 5240 // MKS Eagle (STM32F407VE) +#define BOARD_ARTILLERY_RUBY 5241 // Artillery Ruby (STM32F401RC) +#define BOARD_CREALITY_V24S1_301F4 5242 // Creality v2.4.S1_301F4 (STM32F401RC) as found in the Ender-3 S1 F4 +#define BOARD_CREALITY_CR4NTXXC10 5243 // Creality E3 Free-runs Silent Motherboard (STM32F401RET6) +#define BOARD_FYSETC_SPIDER_KING_V1_F407 5244 // FYSETC Spider King v1 (STM32F407ZG) +#define BOARD_FYSETC_SPIDER_KING_V1_1_F407 5245 // FYSETC Spider King v1.1 (STM32F407ZG) +#define BOARD_MKS_SKIPR_V1 5246 // MKS SKIPR v1.0 all-in-one board (STM32F407VE) +#define BOARD_TRONXY_CXY_446_V10 5247 // TRONXY CXY-446-V10-220413/CXY-V6-191121 (STM32F446ZE) +#define BOARD_CREALITY_F401RE 5248 // Creality CR4NS200141C13 (STM32F401RE) as found in the Ender-5 S1 +#define BOARD_BLACKPILL_CUSTOM 5249 // Custom board based on STM32F401CDU6. +#define BOARD_I3DBEEZ9_V1 5250 // I3DBEEZ9 V1 (STM32F407ZG) +#define BOARD_MELLOW_FLY_E3_V2 5251 // Mellow Fly E3 V2 (STM32F407VG) +#define BOARD_BLACKBEEZMINI_V1 5252 // BlackBeezMini V1 (STM32F401CCU6) +#define BOARD_XTLW_CLIMBER_8TH 5253 // XTLW Climber-8th (STM32F407VGT6) +#define BOARD_FLY_RRF_E3_V1 5254 // Fly RRF E3 V1.0 (STM32F407VG) +#define BOARD_FLY_SUPER8 5255 // Fly SUPER8 (STM32F407ZGT6) +#define BOARD_FLY_D8 5256 // FLY D8 (STM32F407VG) +#define BOARD_FLY_CDY_V3 5257 // FLY CDY V3 (STM32F407VGT6) +#define BOARD_ZNP_ROBIN_NANO 5258 // Elegoo Neptune 2 v1.2 board +#define BOARD_ZNP_ROBIN_NANO_V1_3 5259 // Elegoo Neptune 2 v1.3 board +#define BOARD_MKS_NEPTUNE_X 5260 // Elegoo Neptune X +#define BOARD_MKS_NEPTUNE_3 5261 // Elegoo Neptune 3 // // Other ARM Cortex-M4 @@ -500,21 +503,24 @@ // ARM Cortex-M7 // -#define BOARD_REMRAM_V1 6000 // RemRam v1 -#define BOARD_NUCLEO_F767ZI 6001 // ST NUCLEO-F767ZI Dev Board -#define BOARD_BTT_SKR_SE_BX_V2 6002 // BigTreeTech SKR SE BX V2.0 (STM32H743II) -#define BOARD_BTT_SKR_SE_BX_V3 6003 // BigTreeTech SKR SE BX V3.0 (STM32H743II) -#define BOARD_BTT_SKR_V3_0 6004 // BigTreeTech SKR V3.0 (STM32H743VI / STM32H723VG) -#define BOARD_BTT_SKR_V3_0_EZ 6005 // BigTreeTech SKR V3.0 EZ (STM32H743VI / STM32H723VG) -#define BOARD_BTT_OCTOPUS_MAX_EZ_V1_0 6006 // BigTreeTech Octopus Max EZ V1.0 (STM32H723ZE) -#define BOARD_BTT_OCTOPUS_PRO_V1_0_1 6007 // BigTreeTech Octopus Pro v1.0.1 (STM32H723ZE) -#define BOARD_BTT_OCTOPUS_PRO_V1_1 6008 // BigTreeTech Octopus Pro v1.1 (STM32H723ZE) -#define BOARD_BTT_MANTA_M8P_V2_0 6009 // BigTreeTech Manta M8P V2.0 (STM32H723ZE) -#define BOARD_BTT_KRAKEN_V1_0 6010 // BigTreeTech Kraken v1.0 (STM32H723ZG) -#define BOARD_TEENSY41 6011 // Teensy 4.1 -#define BOARD_T41U5XBB 6012 // T41U5XBB Teensy 4.1 breakout board -#define BOARD_FLY_D8_PRO 6013 // FLY_D8_PRO (STM32H723VG) -#define BOARD_FLY_SUPER8_PRO 6014 // FLY SUPER8 PRO (STM32H723ZG) +#define BOARD_REMRAM_V1 6000 // RemRam v1 +#define BOARD_NUCLEO_F767ZI 6001 // ST NUCLEO-F767ZI Dev Board +#define BOARD_BTT_SKR_SE_BX_V2 6002 // BigTreeTech SKR SE BX V2.0 (STM32H743II) +#define BOARD_BTT_SKR_SE_BX_V3 6003 // BigTreeTech SKR SE BX V3.0 (STM32H743II) +#define BOARD_BTT_SKR_V3_0 6004 // BigTreeTech SKR V3.0 (STM32H743VI / STM32H723VG) +#define BOARD_BTT_SKR_V3_0_EZ 6005 // BigTreeTech SKR V3.0 EZ (STM32H743VI / STM32H723VG) +#define BOARD_BTT_OCTOPUS_MAX_EZ_V1_0 6006 // BigTreeTech Octopus Max EZ V1.0 (STM32H723ZE) +#define BOARD_BTT_OCTOPUS_PRO_V1_0_1 6007 // BigTreeTech Octopus Pro v1.0.1 (STM32H723ZE) +#define BOARD_BTT_OCTOPUS_PRO_V1_1 6008 // BigTreeTech Octopus Pro v1.1 (STM32H723ZE) +#define BOARD_BTT_MANTA_M8P_V2_0 6009 // BigTreeTech Manta M8P V2.0 (STM32H723ZE) +#define BOARD_BTT_KRAKEN_V1_0 6010 // BigTreeTech Kraken v1.0 (STM32H723ZG) +#define BOARD_TEENSY40 6011 // Teensy 4.0 +#define BOARD_TEENSY41 6012 // Teensy 4.1 +#define BOARD_T41U5XBB 6013 // T41U5XBB Teensy 4.1 breakout board +#define BOARD_FLY_D8_PRO 6014 // FLY_D8_PRO (STM32H723VG) +#define BOARD_FLY_SUPER8_PRO 6015 // FLY SUPER8 PRO (STM32H723ZG) +#define BOARD_FYSETC_SPIDER_KING_V1_H723 6016 // FYSETC Spider King v1 (STM32H723ZG) +#define BOARD_FYSETC_SPIDER_KING_V1_1_H723 6017 // FYSETC Spider King v1.1 (STM32H723ZG) // // Espressif ESP32 WiFi @@ -572,7 +578,8 @@ // #define BOARD_RP2040 6200 // Generic RP2040 Test board -#define BOARD_BTT_SKR_PICO 6201 // BigTreeTech SKR Pico 1.x +#define BOARD_RASPBERRY_PI_PICO 6201 // Raspberry Pi Pico +#define BOARD_BTT_SKR_PICO 6202 // BigTreeTech SKR Pico 1.x // // Custom board diff --git a/Marlin/src/core/language.h b/Marlin/src/core/language.h index 3a50fcdc6b..837f3885b9 100644 --- a/Marlin/src/core/language.h +++ b/Marlin/src/core/language.h @@ -210,6 +210,8 @@ #define STR_KILL_BUTTON "KILL button/pin" // temperature.cpp strings +#define STR_WAIT_FOR_HOTEND "Wait for hotend heating..." +#define STR_WAIT_FOR_BED "Wait for bed heating..." #define STR_PID_AUTOTUNE "PID Autotune" #define STR_PID_AUTOTUNE_START " start" #define STR_PID_BAD_HEATER_ID " failed! Bad heater id" @@ -230,6 +232,8 @@ #define STR_PID_DEBUG_INPUT ": Input " #define STR_PID_DEBUG_OUTPUT " Output " #define STR_INVALID_EXTRUDER_NUM " - Invalid extruder number !" + +// MPCTEMP strings #define STR_MPC_AUTOTUNE_START "MPC Autotune start for " STR_E #define STR_MPC_AUTOTUNE_INTERRUPTED "MPC Autotune interrupted!" #define STR_MPC_AUTOTUNE_FINISHED "MPC Autotune finished! Put the constants below into Configuration.h" @@ -238,6 +242,7 @@ #define STR_MPC_MEASURING_AMBIENT "Measuring ambient heatloss at " #define STR_MPC_TEMPERATURE_ERROR "Temperature error" +// Temperature Sensors #define STR_HEATER_BED "bed" #define STR_HEATER_CHAMBER "chamber" #define STR_COOLER "cooler" @@ -247,6 +252,7 @@ #define STR_REDUNDANT "redundant " #define STR_LASER_TEMP "laser temperature" +// Misc. Errors, Thermal Runaway #define STR_STOPPED_HEATER ", system stopped! Heater_ID: " #define STR_DETECTED_TEMP_B " (temp: " #define STR_DETECTED_TEMP_E ")" @@ -269,6 +275,7 @@ #define STR_DEBUG_COMMUNICATION "COMMUNICATION" #define STR_DEBUG_DETAIL "DETAIL" +// Password Security #define STR_PRINTER_LOCKED "Printer locked! (Unlock with M511 or LCD)" #define STR_WRONG_PASSWORD "Incorrect Password" #define STR_PASSWORD_TOO_LONG "Password too long" @@ -296,6 +303,7 @@ #define STR_TOOL_CHANGING "Tool-changing" #define STR_HOTEND_OFFSETS "Hotend offsets" #define STR_SERVO_ANGLES "Servo Angles" +#define STR_AUTOTEMP "Auto Temp Control" #define STR_HOTEND_PID "Hotend PID" #define STR_BED_PID "Bed PID" #define STR_CHAMBER_PID "Chamber PID" @@ -358,6 +366,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..4f6b1df98b 100644 --- a/Marlin/src/core/macros.h +++ b/Marlin/src/core/macros.h @@ -25,12 +25,6 @@ #define __has_include(...) 1 #endif -#define ABCE 4 -#define XYZE 4 -#define ABC 3 -#define XYZ 3 -#define XY 2 - #define _AXIS(A) (A##_AXIS) #define _FORCE_INLINE_ __attribute__((__always_inline__)) __inline__ @@ -58,6 +52,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" @@ -214,7 +209,10 @@ // "Ternary" that emits or omits the given content #define EMIT(V...) V #define OMIT(...) -#define TERN_(O,A) _TERN(_ENA_1(O),OMIT,EMIT)(A) // OPTION ? 'A' : '' +#define TERN_(O,A) TERF(O,EMIT)(A) // OPTION ? 'A' : '' ; Usage: TERN_(OPTION, EMITTHIS) + +// Call G(...) or swallow with OMIT(...) +#define TERF(O,G) _TERN(_ENA_1(O),OMIT,G) // OPTION ? 'G' : 'OMIT' ; Usage: TERF(OPTION, CALLTHIS)(ARGS...) // Macros to conditionally emit array items and function arguments #define _OPTITEM(A...) A, diff --git a/Marlin/src/core/mstring.h b/Marlin/src/core/mstring.h index e3fb78c50e..1e540a5a5a 100644 --- a/Marlin/src/core/mstring.h +++ b/Marlin/src/core/mstring.h @@ -280,12 +280,11 @@ public: // Quick hash to detect change (e.g., to avoid expensive drawing) typedef IF::type hash_t; hash_t hash() const { + const int sz = length(); #if ENABLED(DJB2_HASH) hash_t hval = 5381; - char c; - while ((c = *str++)) hval += (hval << 5) + c; // = hval * 33 + c + for (int i = 0; i < sz; i++) hval += (hval << 5) + str[i]; // = hval * 33 + c #else - const int sz = length(); hash_t hval = hash_t(sz); for (int i = 0; i < sz; i++) hval = ((hval << 1) | (hval >> 15)) ^ str[i]; // ROL, XOR #endif 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/serial_base.h b/Marlin/src/core/serial_base.h index a8700f3d23..07bed55b35 100644 --- a/Marlin/src/core/serial_base.h +++ b/Marlin/src/core/serial_base.h @@ -228,7 +228,7 @@ struct SerialBase { // Handle negative numbers if (number < 0.0) { write('-'); - number = -number; + number *= -1; } // Round correctly so that print(1.999, 2) prints as "2.00" diff --git a/Marlin/src/core/types.h b/Marlin/src/core/types.h index 18e4c49264..7008d04c53 100644 --- a/Marlin/src/core/types.h +++ b/Marlin/src/core/types.h @@ -50,6 +50,7 @@ template struct IF { typedef L type; }; #define NUM_AXIS_DECL_LC(T,V) NUM_AXIS_LIST(T x=V, T y=V, T z=V, T i=V, T j=V, T k=V, T u=V, T v=V, T w=V) #define MAIN_AXIS_NAMES NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W) #define MAIN_AXIS_NAMES_LC NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w) +#define NUM_AXIS_CALL(G) do { NUM_AXIS_CODE(G(X_AXIS), G(Y_AXIS), G(Z_AXIS), G(I_AXIS), G(J_AXIS), G(K_AXIS), G(U_AXIS), G(V_AXIS), G(W_AXIS)); } while(0) #define STR_AXES_MAIN NUM_AXIS_GANG("X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W) #define LOGICAL_AXIS_GANG(N,V...) NUM_AXIS_GANG(V) GANG_ITEM_E(N) @@ -68,6 +69,7 @@ template struct IF { typedef L type; }; #define LOGICAL_AXIS_NAMES_LC LOGICAL_AXIS_LIST(e, x, y, z, i, j, k, u, v, w) #define LOGICAL_AXIS_MAP(F) MAP(F, LOGICAL_AXIS_NAMES) #define LOGICAL_AXIS_MAP_LC(F) MAP(F, LOGICAL_AXIS_NAMES_LC) +#define LOGICAL_AXIS_CALL(G) do { LOGICAL_AXIS_CODE(G(E_AXIS), G(X_AXIS), G(Y_AXIS), G(Z_AXIS), G(I_AXIS), G(J_AXIS), G(K_AXIS), G(U_AXIS), G(V_AXIS), G(W_AXIS)); } while(0) #define STR_AXES_LOGICAL LOGICAL_AXIS_GANG("E", "X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W) #define NUM_AXIS_PAIRED_LIST(V...) LIST_N(DOUBLE(NUM_AXES), V) @@ -167,6 +169,22 @@ 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_AXIS_NAMES_LC 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 @@ -223,6 +241,24 @@ struct Flags { FI bool operator[](const int n) const { return test(n); } FI int size() const { return sizeof(b); } FI operator bool() const { return b != 0; } + + FI Flags& operator|=(Flags &p) const { b |= p.b; return *this; } + FI Flags& operator&=(Flags &p) const { b &= p.b; return *this; } + FI Flags& operator^=(Flags &p) const { b ^= p.b; return *this; } + + FI Flags& operator|=(const flagbits_t &p) { b |= flagbits_t(p); return *this; } + FI Flags& operator&=(const flagbits_t &p) { b &= flagbits_t(p); return *this; } + FI Flags& operator^=(const flagbits_t &p) { b ^= flagbits_t(p); return *this; } + + FI Flags operator|(Flags &p) const { return Flags(b | p.b); } + FI Flags operator&(Flags &p) const { return Flags(b & p.b); } + FI Flags operator^(Flags &p) const { return Flags(b ^ p.b); } + FI Flags operator~() const { return Flags(~b); } + + FI flagbits_t operator|(const flagbits_t &p) const { return b | flagbits_t(p); } + FI flagbits_t operator&(const flagbits_t &p) const { return b & flagbits_t(p); } + FI flagbits_t operator^(const flagbits_t &p) const { return b ^ flagbits_t(p); } + }; // Flag bits for more than 64 states @@ -363,17 +399,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 +407,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 @@ -488,7 +513,7 @@ typedef ab_float_t ab_pos_t; typedef abc_float_t abc_pos_t; typedef abce_float_t abce_pos_t; -// External conversion methods +// External conversion methods (motion.h) void toLogical(xy_pos_t &raw); void toLogical(xyz_pos_t &raw); void toLogical(xyze_pos_t &raw); @@ -519,9 +544,9 @@ struct XYval { #endif #if HAS_Y_AXIS FI void set(const T px, const T py) { x = px; y = py; } - FI void set(const T (&arr)[XY]) { x = arr[0]; y = arr[1]; } + FI void set(const T (&arr)[2]) { x = arr[0]; y = arr[1]; } #endif - #if NUM_AXES > XY + #if NUM_AXES > 2 FI void set(const T (&arr)[NUM_AXES]) { x = arr[0]; y = arr[1]; } #endif #if LOGICAL_AXES > NUM_AXES @@ -543,13 +568,18 @@ struct XYval { FI constexpr T large() const { return _MAX(x, y); } // Explicit copy and copies with conversion - FI constexpr XYval copy() const { return *this; } - FI constexpr XYval ABS() const { return { T(_ABS(x)), T(_ABS(y)) }; } - FI constexpr XYval asInt() const { return { int16_t(x), int16_t(y) }; } - FI constexpr XYval asLong() const { return { int32_t(x), int32_t(y) }; } - FI constexpr XYval ROUNDL() const { return { int32_t(LROUND(x)), int32_t(LROUND(y)) }; } - FI constexpr XYval asFloat() const { return { static_cast(x), static_cast(y) }; } - FI constexpr XYval reciprocal() const { return { _RECIP(x), _RECIP(y) }; } + FI constexpr XYval copy() const { return *this; } + FI constexpr XYval ABS() const { return { T(_ABS(x)), T(_ABS(y)) }; } + FI constexpr XYval ROUNDL() const { return { int32_t(LROUND(x)), int32_t(LROUND(y)) }; } + FI constexpr XYval reciprocal() const { return { _RECIP(x), _RECIP(y) }; } + + // Conversion to other types + FI constexpr XYval asInt16() const { return { int16_t(x), int16_t(y) }; } + FI constexpr XYval asInt32() const { return { int32_t(x), int32_t(y) }; } + FI constexpr XYval asUInt32() const { return { uint32_t(x), uint32_t(y) }; } + FI constexpr XYval asInt64() const { return { int64_t(x), int64_t(y) }; } + FI constexpr XYval asUInt64() const { return { uint64_t(x), uint64_t(y) }; } + FI constexpr XYval asFloat() const { return { static_cast(x), static_cast(y) }; } // Marlin workspace shifting is done with G92 and M206 FI XYval asLogical() const { XYval o = asFloat(); toLogical(o); return o; } @@ -621,6 +651,26 @@ struct XYval { FI bool operator!=(const XYval &rs) const { return !operator==(rs); } FI bool operator!=(const XYZval &rs) const { return !operator==(rs); } FI bool operator!=(const XYZEval &rs) const { return !operator==(rs); } + + // Exact comparison to a single value + FI bool operator==(const T &p) const { return x == p && y == p; } + FI bool operator!=(const T &p) const { return !operator==(p); } + + FI bool operator< (const XYval &rs) const { return x < rs.x && y < rs.y; } + FI bool operator<=(const XYval &rs) const { return x <= rs.x && y <= rs.y; } + FI bool operator> (const XYval &rs) const { return x > rs.x && y > rs.y; } + FI bool operator>=(const XYval &rs) const { return x >= rs.x && y >= rs.y; } + + FI bool operator< (const XYZval &rs) const { return true XY_GANG(&& x < rs.x, && y < rs.y); } + FI bool operator<=(const XYZval &rs) const { return true XY_GANG(&& x <= rs.x, && y <= rs.y); } + FI bool operator> (const XYZval &rs) const { return true XY_GANG(&& x > rs.x, && y > rs.y); } + FI bool operator>=(const XYZval &rs) const { return true XY_GANG(&& x >= rs.x, && y >= rs.y); } + + FI bool operator< (const XYZEval &rs) const { return true XY_GANG(&& x < rs.x, && y < rs.y); } + FI bool operator<=(const XYZEval &rs) const { return true XY_GANG(&& x <= rs.x, && y <= rs.y); } + FI bool operator> (const XYZEval &rs) const { return true XY_GANG(&& x > rs.x, && y > rs.y); } + FI bool operator>=(const XYZEval &rs) const { return true XY_GANG(&& x >= rs.x, && y >= rs.y); } + }; // @@ -697,12 +747,17 @@ struct XYZval { // Explicit copy and copies with conversion FI constexpr XYZval copy() const { XYZval o = *this; return o; } FI constexpr XYZval ABS() const { return NUM_AXIS_ARRAY(T(_ABS(x)), T(_ABS(y)), T(_ABS(z)), T(_ABS(i)), T(_ABS(j)), T(_ABS(k)), T(_ABS(u)), T(_ABS(v)), T(_ABS(w))); } - FI constexpr XYZval asInt() const { return NUM_AXIS_ARRAY(int16_t(x), int16_t(y), int16_t(z), int16_t(i), int16_t(j), int16_t(k), int16_t(u), int16_t(v), int16_t(w)); } - FI constexpr XYZval asLong() const { return NUM_AXIS_ARRAY(int32_t(x), int32_t(y), int32_t(z), int32_t(i), int32_t(j), int32_t(k), int32_t(u), int32_t(v), int32_t(w)); } FI constexpr XYZval ROUNDL() const { return NUM_AXIS_ARRAY(int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)), int32_t(LROUND(i)), int32_t(LROUND(j)), int32_t(LROUND(k)), int32_t(LROUND(u)), int32_t(LROUND(v)), int32_t(LROUND(w))); } - FI constexpr XYZval asFloat() const { return NUM_AXIS_ARRAY(static_cast(x), static_cast(y), static_cast(z), static_cast(i), static_cast(j), static_cast(k), static_cast(u), static_cast(v), static_cast(w)); } FI constexpr XYZval reciprocal() const { return NUM_AXIS_ARRAY(_RECIP(x), _RECIP(y), _RECIP(z), _RECIP(i), _RECIP(j), _RECIP(k), _RECIP(u), _RECIP(v), _RECIP(w)); } + // Conversion to other types + FI constexpr XYZval asInt16() const { return NUM_AXIS_ARRAY(int16_t(x), int16_t(y), int16_t(z), int16_t(i), int16_t(j), int16_t(k), int16_t(u), int16_t(v), int16_t(w)); } + FI constexpr XYZval asInt32() const { return NUM_AXIS_ARRAY(int32_t(x), int32_t(y), int32_t(z), int32_t(i), int32_t(j), int32_t(k), int32_t(u), int32_t(v), int32_t(w)); } + FI constexpr XYZval asUInt32() const { return NUM_AXIS_ARRAY(uint32_t(x), uint32_t(y), uint32_t(z), uint32_t(i), uint32_t(j), uint32_t(k), uint32_t(u), uint32_t(v), uint32_t(w)); } + FI constexpr XYZval asInt64() const { return NUM_AXIS_ARRAY(int64_t(x), int64_t(y), int64_t(z), int64_t(i), int64_t(j), int64_t(k), int64_t(u), int64_t(v), int64_t(w)); } + FI constexpr XYZval asUInt64() const { return NUM_AXIS_ARRAY(uint64_t(x), uint64_t(y), uint64_t(z), uint64_t(i), uint64_t(j), uint64_t(k), uint64_t(u), uint64_t(v), uint64_t(w)); } + FI constexpr XYZval asFloat() const { return NUM_AXIS_ARRAY(static_cast(x), static_cast(y), static_cast(z), static_cast(i), static_cast(j), static_cast(k), static_cast(u), static_cast(v), static_cast(w)); } + // Marlin workspace shifting is done with G92 and M206 FI XYZval asLogical() const { XYZval o = asFloat(); toLogical(o); return o; } FI XYZval asNative() const { XYZval o = asFloat(); toNative(o); return o; } @@ -764,12 +819,28 @@ struct XYZval { FI XYZval& operator/=(const XYZEval &rs) { NUM_AXIS_CODE(x /= rs.x, y /= rs.y, z /= rs.z, i /= rs.i, j /= rs.j, k /= rs.k, u /= rs.u, v /= rs.v, w /= rs.w); return *this; } FI XYZval& operator*=(const float &p) { NUM_AXIS_CODE(x *= p, y *= p, z *= p, i *= p, j *= p, k *= p, u *= p, v *= p, w *= p); return *this; } FI XYZval& operator*=(const int &p) { NUM_AXIS_CODE(x *= p, y *= p, z *= p, i *= p, j *= p, k *= p, u *= p, v *= p, w *= p); return *this; } + FI XYZval& operator/=(const float &p) { NUM_AXIS_CODE(x /= p, y /= p, z /= p, i /= p, j /= p, k /= p, u /= p, v /= p, w /= p); return *this; } FI XYZval& operator>>=(const int &p) { NUM_AXIS_CODE(_RSE(x), _RSE(y), _RSE(z), _RSE(i), _RSE(j), _RSE(k), _RSE(u), _RSE(v), _RSE(w)); return *this; } FI XYZval& operator<<=(const int &p) { NUM_AXIS_CODE(_LSE(x), _LSE(y), _LSE(z), _LSE(i), _LSE(j), _LSE(k), _LSE(u), _LSE(v), _LSE(w)); return *this; } // Exact comparisons. For floats a "NEAR" operation may be better. - FI bool operator==(const XYZEval &rs) const { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); } + FI bool operator==(const XYZEval &rs) const { return ENABLED(HAS_X_AXIS) NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); } FI bool operator!=(const XYZEval &rs) const { return !operator==(rs); } + + // Exact comparison to a single value + FI bool operator==(const T &p) const { return ENABLED(HAS_X_AXIS) NUM_AXIS_GANG(&& x == p, && y == p, && z == p, && i == p, && j == p, && k == p, && u == p, && v == p, && w == p); } + FI bool operator!=(const T &p) const { return !operator==(p); } + + FI bool operator< (const XYZval &rs) const { return true NUM_AXIS_GANG(&& x < rs.x, && y < rs.y, && z < rs.z, && i < rs.i, && j < rs.j, && k < rs.k, && u < rs.u, && v < rs.v, && w < rs.w); } + FI bool operator<=(const XYZval &rs) const { return true NUM_AXIS_GANG(&& x <= rs.x, && y <= rs.y, && z <= rs.z, && i <= rs.i, && j <= rs.j, && k <= rs.k, && u <= rs.u, && v <= rs.v, && w <= rs.w); } + FI bool operator> (const XYZval &rs) const { return true NUM_AXIS_GANG(&& x > rs.x, && y > rs.y, && z > rs.z, && i > rs.i, && j > rs.j, && k > rs.k, && u > rs.u, && v > rs.v, && w > rs.w); } + FI bool operator>=(const XYZval &rs) const { return true NUM_AXIS_GANG(&& x >= rs.x, && y >= rs.y, && z >= rs.z, && i >= rs.i, && j >= rs.j, && k >= rs.k, && u >= rs.u, && v >= rs.v, && w >= rs.w); } + + FI bool operator< (const XYZEval &rs) const { return true NUM_AXIS_GANG(&& x < rs.x, && y < rs.y, && z < rs.z, && i < rs.i, && j < rs.j, && k < rs.k, && u < rs.u, && v < rs.v, && w < rs.w); } + FI bool operator<=(const XYZEval &rs) const { return true NUM_AXIS_GANG(&& x <= rs.x, && y <= rs.y, && z <= rs.z, && i <= rs.i, && j <= rs.j, && k <= rs.k, && u <= rs.u, && v <= rs.v, && w <= rs.w); } + FI bool operator> (const XYZEval &rs) const { return true NUM_AXIS_GANG(&& x > rs.x, && y > rs.y, && z > rs.z, && i > rs.i, && j > rs.j, && k > rs.k, && u > rs.u, && v > rs.v, && w > rs.w); } + FI bool operator>=(const XYZEval &rs) const { return true NUM_AXIS_GANG(&& x >= rs.x, && y >= rs.y, && z >= rs.z, && i >= rs.i, && j >= rs.j, && k >= rs.k, && u >= rs.u, && v >= rs.v, && w >= rs.w); } + }; // @@ -800,7 +871,7 @@ struct XYZEval { FI void set(const XYZval &pxyz, const T pe) { set(pxyz); e = pe; } FI void set(LOGICAL_AXIS_ARGS_LC(const T)) { LOGICAL_AXIS_CODE(_e = e, a = x, b = y, c = z, _i = i, _j = j, _k = k, _u = u, _v = v, _w = w); } #if DISTINCT_AXES > LOGICAL_AXES - FI void set(const T (&arr)[DISTINCT_AXES]) { LOGICAL_AXIS_CODE(e = arr[LOGICAL_AXES-1], x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5], u = arr[6], v = arr[7], w = arr[8]); } + FI void set(const T (&arr)[DISTINCT_AXES], const uint8_t eindex) { LOGICAL_AXIS_CODE(e = arr[LOGICAL_AXES-1 + eindex], x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5], u = arr[6], v = arr[7], w = arr[8]); } #endif #endif @@ -845,13 +916,18 @@ struct XYZEval { FI constexpr T large() const { return _MAX(LOGICAL_AXIS_LIST(e, x, y, z, i, j, k, u, v, w)); } // Explicit copy and copies with conversion - FI constexpr XYZEval copy() const { XYZEval v = *this; return v; } - FI constexpr XYZEval ABS() const { return LOGICAL_AXIS_ARRAY(T(_ABS(e)), T(_ABS(x)), T(_ABS(y)), T(_ABS(z)), T(_ABS(i)), T(_ABS(j)), T(_ABS(k)), T(_ABS(u)), T(_ABS(v)), T(_ABS(w))); } - FI constexpr XYZEval asInt() const { return LOGICAL_AXIS_ARRAY(int16_t(e), int16_t(x), int16_t(y), int16_t(z), int16_t(i), int16_t(j), int16_t(k), int16_t(u), int16_t(v), int16_t(w)); } - FI constexpr XYZEval asLong() const { return LOGICAL_AXIS_ARRAY(int32_t(e), int32_t(x), int32_t(y), int32_t(z), int32_t(i), int32_t(j), int32_t(k), int32_t(u), int32_t(v), int32_t(w)); } - FI constexpr XYZEval ROUNDL() const { return LOGICAL_AXIS_ARRAY(int32_t(LROUND(e)), int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)), int32_t(LROUND(i)), int32_t(LROUND(j)), int32_t(LROUND(k)), int32_t(LROUND(u)), int32_t(LROUND(v)), int32_t(LROUND(w))); } - FI constexpr XYZEval asFloat() const { return LOGICAL_AXIS_ARRAY(static_cast(e), static_cast(x), static_cast(y), static_cast(z), static_cast(i), static_cast(j), static_cast(k), static_cast(u), static_cast(v), static_cast(w)); } - FI constexpr XYZEval reciprocal() const { return LOGICAL_AXIS_ARRAY(_RECIP(e), _RECIP(x), _RECIP(y), _RECIP(z), _RECIP(i), _RECIP(j), _RECIP(k), _RECIP(u), _RECIP(v), _RECIP(w)); } + FI constexpr XYZEval copy() const { XYZEval v = *this; return v; } + FI constexpr XYZEval ABS() const { return LOGICAL_AXIS_ARRAY(T(_ABS(e)), T(_ABS(x)), T(_ABS(y)), T(_ABS(z)), T(_ABS(i)), T(_ABS(j)), T(_ABS(k)), T(_ABS(u)), T(_ABS(v)), T(_ABS(w))); } + FI constexpr XYZEval ROUNDL() const { return LOGICAL_AXIS_ARRAY(int32_t(LROUND(e)), int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)), int32_t(LROUND(i)), int32_t(LROUND(j)), int32_t(LROUND(k)), int32_t(LROUND(u)), int32_t(LROUND(v)), int32_t(LROUND(w))); } + FI constexpr XYZEval reciprocal() const { return LOGICAL_AXIS_ARRAY(_RECIP(e), _RECIP(x), _RECIP(y), _RECIP(z), _RECIP(i), _RECIP(j), _RECIP(k), _RECIP(u), _RECIP(v), _RECIP(w)); } + + // Conversion to other types + FI constexpr XYZEval asInt16() const { return LOGICAL_AXIS_ARRAY(int16_t(e), int16_t(x), int16_t(y), int16_t(z), int16_t(i), int16_t(j), int16_t(k), int16_t(u), int16_t(v), int16_t(w)); } + FI constexpr XYZEval asInt32() const { return LOGICAL_AXIS_ARRAY(int32_t(e), int32_t(x), int32_t(y), int32_t(z), int32_t(i), int32_t(j), int32_t(k), int32_t(u), int32_t(v), int32_t(w)); } + FI constexpr XYZEval asUInt32() const { return LOGICAL_AXIS_ARRAY(uint32_t(e), uint32_t(x), uint32_t(y), uint32_t(z), uint32_t(i), uint32_t(j), uint32_t(k), uint32_t(u), uint32_t(v), uint32_t(w)); } + FI constexpr XYZEval asInt64() const { return LOGICAL_AXIS_ARRAY(int64_t(e), int64_t(x), int64_t(y), int64_t(z), int64_t(i), int64_t(j), int64_t(k), int64_t(u), int64_t(v), int64_t(w)); } + FI constexpr XYZEval asUInt64() const { return LOGICAL_AXIS_ARRAY(uint64_t(e), uint64_t(x), uint64_t(y), uint64_t(z), uint64_t(i), uint64_t(j), uint64_t(k), uint64_t(u), uint64_t(v), uint64_t(w)); } + FI constexpr XYZEval asFloat() const { return LOGICAL_AXIS_ARRAY(static_cast(e), static_cast(x), static_cast(y), static_cast(z), static_cast(i), static_cast(j), static_cast(k), static_cast(u), static_cast(v), static_cast(w)); } // Marlin workspace shifting is done with G92 and M206 FI XYZEval asLogical() const { XYZEval o = asFloat(); toLogical(o); return o; } @@ -885,7 +961,10 @@ struct XYZEval { FI constexpr XYZEval operator- (const XYZEval &rs) const { return LOGICAL_AXIS_ARRAY(T(e - rs.e), T(x - rs.x), T(y - rs.y), T(z - rs.z), T(i - rs.i), T(j - rs.j), T(k - rs.k), T(u - rs.u), T(v - rs.v), T(w - rs.w)); } FI constexpr XYZEval operator* (const XYZEval &rs) const { return LOGICAL_AXIS_ARRAY(T(e * rs.e), T(x * rs.x), T(y * rs.y), T(z * rs.z), T(i * rs.i), T(j * rs.j), T(k * rs.k), T(u * rs.u), T(v * rs.v), T(w * rs.w)); } FI constexpr XYZEval operator/ (const XYZEval &rs) const { return LOGICAL_AXIS_ARRAY(T(e / rs.e), T(x / rs.x), T(y / rs.y), T(z / rs.z), T(i / rs.i), T(j / rs.j), T(k / rs.k), T(u / rs.u), T(v / rs.v), T(w / rs.w)); } + FI constexpr XYZEval operator+ (const uint32_t &p) const { return LOGICAL_AXIS_ARRAY(T(e + p), T(x + p), T(y + p), T(z + p), T(i + p), T(j + p), T(k + p), T(u + p), T(v + p), T(w + p)); } FI constexpr XYZEval operator* (const float &p) const { return LOGICAL_AXIS_ARRAY(T(e * p), T(x * p), T(y * p), T(z * p), T(i * p), T(j * p), T(k * p), T(u * p), T(v * p), T(w * p)); } + FI constexpr XYZEval operator* (const uint32_t &p) const { return LOGICAL_AXIS_ARRAY(T(e * p), T(x * p), T(y * p), T(z * p), T(i * p), T(j * p), T(k * p), T(u * p), T(v * p), T(w * p)); } + FI constexpr XYZEval operator& (const int64_t &p) const { return LOGICAL_AXIS_ARRAY(T(e & p), T(x & p), T(y & p), T(z & p), T(i & p), T(j & p), T(k & p), T(u & p), T(v & p), T(w & p)); } FI constexpr XYZEval operator* (const int &p) const { return LOGICAL_AXIS_ARRAY(e * p, x * p, y * p, z * p, i * p, j * p, k * p, u * p, v * p, w * p); } FI constexpr XYZEval operator/ (const float &p) const { return LOGICAL_AXIS_ARRAY(T(e / p), T(x / p), T(y / p), T(z / p), T(i / p), T(j / p), T(k / p), T(u / p), T(v / p), T(w / p)); } FI constexpr XYZEval operator/ (const int &p) const { return LOGICAL_AXIS_ARRAY(e / p, x / p, y / p, z / p, i / p, j / p, k / p, u / p, v / p, w / p); } @@ -911,19 +990,40 @@ struct XYZEval { FI XYZEval& operator-=(const XYZEval &rs) { LOGICAL_AXIS_CODE(e -= rs.e, x -= rs.x, y -= rs.y, z -= rs.z, i -= rs.i, j -= rs.j, k -= rs.k, u -= rs.u, v -= rs.v, w -= rs.w); return *this; } FI XYZEval& operator*=(const XYZEval &rs) { LOGICAL_AXIS_CODE(e *= rs.e, x *= rs.x, y *= rs.y, z *= rs.z, i *= rs.i, j *= rs.j, k *= rs.k, u *= rs.u, v *= rs.v, w *= rs.w); return *this; } FI XYZEval& operator/=(const XYZEval &rs) { LOGICAL_AXIS_CODE(e /= rs.e, x /= rs.x, y /= rs.y, z /= rs.z, i /= rs.i, j /= rs.j, k /= rs.k, u /= rs.u, v /= rs.v, w /= rs.w); return *this; } + FI XYZEval& operator+=(const T &p) { LOGICAL_AXIS_CODE(e += p, x += p, y += p, z += p, i += p, j += p, k += p, u += p, v += p, w += p); return *this; } + FI XYZEval& operator-=(const T &p) { LOGICAL_AXIS_CODE(e -= p, x -= p, y -= p, z -= p, i -= p, j -= p, k -= p, u -= p, v -= p, w -= p); return *this; } FI XYZEval& operator*=(const T &p) { LOGICAL_AXIS_CODE(e *= p, x *= p, y *= p, z *= p, i *= p, j *= p, k *= p, u *= p, v *= p, w *= p); return *this; } + FI XYZEval& operator/=(const T &p) { LOGICAL_AXIS_CODE(e /= p, x /= p, y /= p, z /= p, i /= p, j /= p, k /= p, u /= p, v /= p, w /= p); return *this; } FI XYZEval& operator>>=(const int &p) { LOGICAL_AXIS_CODE(_RSE(e), _RSE(x), _RSE(y), _RSE(z), _RSE(i), _RSE(j), _RSE(k), _RSE(u), _RSE(v), _RSE(w)); return *this; } FI XYZEval& operator<<=(const int &p) { LOGICAL_AXIS_CODE(_LSE(e), _LSE(x), _LSE(y), _LSE(z), _LSE(i), _LSE(j), _LSE(k), _LSE(u), _LSE(v), _LSE(w)); return *this; } // Exact comparisons. For floats a "NEAR" operation may be better. - FI bool operator==(const XYZval &rs) const { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); } - FI bool operator==(const XYZEval &rs) const { return true LOGICAL_AXIS_GANG(&& e == rs.e, && x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); } + FI bool operator==(const XYZval &rs) const { return ENABLED(HAS_X_AXIS) NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); } + FI bool operator==(const XYZEval &rs) const { return ANY(HAS_X_AXIS, HAS_EXTRUDERS) LOGICAL_AXIS_GANG(&& e == rs.e, && x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); } FI bool operator!=(const XYZval &rs) const { return !operator==(rs); } FI bool operator!=(const XYZEval &rs) const { return !operator==(rs); } + + // Exact comparison to a single value + FI bool operator==(const T &p) const { return ENABLED(HAS_X_AXIS) LOGICAL_AXIS_GANG(&& e == p, && x == p, && y == p, && z == p, && i == p, && j == p, && k == p, && u == p, && v == p, && w == p); } + FI bool operator!=(const T &p) const { return !operator==(p); } + + FI bool operator< (const XYZEval &rs) const { return true LOGICAL_AXIS_GANG(&& e < rs.e, && x < rs.x, && y < rs.y, && z < rs.z, && i < rs.i, && j < rs.j, && k < rs.k, && u < rs.u, && v < rs.v, && w < rs.w); } + FI bool operator<=(const XYZEval &rs) const { return true LOGICAL_AXIS_GANG(&& e <= rs.e, && x <= rs.x, && y <= rs.y, && z <= rs.z, && i <= rs.i, && j <= rs.j, && k <= rs.k, && u <= rs.u, && v <= rs.v, && w <= rs.w); } + FI bool operator> (const XYZEval &rs) const { return true LOGICAL_AXIS_GANG(&& e > rs.e, && x > rs.x, && y > rs.y, && z > rs.z, && i > rs.i, && j > rs.j, && k > rs.k, && u > rs.u, && v > rs.v, && w > rs.w); } + FI bool operator>=(const XYZEval &rs) const { return true LOGICAL_AXIS_GANG(&& e >= rs.e, && x >= rs.x, && y >= rs.y, && z >= rs.z, && i >= rs.i, && j >= rs.j, && k >= rs.k, && u >= rs.u, && v >= rs.v, && w >= rs.w); } + + FI bool operator< (const XYZval &rs) const { return true NUM_AXIS_GANG(&& x < rs.x, && y < rs.y, && z < rs.z, && i < rs.i, && j < rs.j, && k < rs.k, && u < rs.u, && v < rs.v, && w < rs.w); } + FI bool operator<=(const XYZval &rs) const { return true NUM_AXIS_GANG(&& x <= rs.x, && y <= rs.y, && z <= rs.z, && i <= rs.i, && j <= rs.j, && k <= rs.k, && u <= rs.u, && v <= rs.v, && w <= rs.w); } + FI bool operator> (const XYZval &rs) const { return true NUM_AXIS_GANG(&& x > rs.x, && y > rs.y, && z > rs.z, && i > rs.i, && j > rs.j, && k > rs.k, && u > rs.u, && v > rs.v, && w > rs.w); } + FI bool operator>=(const XYZval &rs) const { return true NUM_AXIS_GANG(&& x >= rs.x, && y >= rs.y, && z >= rs.z, && i >= rs.i, && j >= rs.j, && k >= rs.k, && u >= rs.u, && v >= rs.v, && w >= rs.w); } + }; #include // for memset +// +// Axis indexed arrays of type T (x[SIZE], y[SIZE], etc.) +// template struct XYZarray { typedef T el[SIZE]; @@ -1023,6 +1123,9 @@ struct XYZEarray { FI XYZEval operator[](const int n) const { return XYZval(LOGICAL_AXIS_ARRAY(e[n], x[n], y[n], z[n], i[n], j[n], k[n], u[n], v[n], w[n])); } }; +// +// Axes mapped to bits in a mask of minimum size, bits_t(NUM_AXIS_HEADS) +// class AxisBits { public: typedef bits_t(NUM_AXIS_HEADS) el; @@ -1220,6 +1323,7 @@ public: FI AxisBits operator|(const AxisBits &p) const { return AxisBits(bits | p.bits); } FI AxisBits operator&(const AxisBits &p) const { return AxisBits(bits & p.bits); } FI AxisBits operator^(const AxisBits &p) const { return AxisBits(bits ^ p.bits); } + FI AxisBits operator~() const { return AxisBits(~bits); } FI operator bool() const { return !!bits; } FI operator uint16_t() const { return uint16_t(bits & 0xFFFF); } @@ -1237,7 +1341,7 @@ public: // Axis names for G-code parsing, reports, etc. constexpr xyze_char_t axis_codes LOGICAL_AXIS_ARRAY('E', 'X', 'Y', 'Z', AXIS4_NAME, AXIS5_NAME, AXIS6_NAME, AXIS7_NAME, AXIS8_NAME, AXIS9_NAME); -#if NUM_AXES <= XYZ && !HAS_EXTRUDERS +#if NUM_AXES <= 3 && !HAS_EXTRUDERS #define AXIS_CHAR(A) ((char)('X' + A)) #define IAXIS_CHAR AXIS_CHAR #else diff --git a/Marlin/src/core/utility.cpp b/Marlin/src/core/utility.cpp index cc49cf2cfb..f6b8b304c0 100644 --- a/Marlin/src/core/utility.cpp +++ b/Marlin/src/core/utility.cpp @@ -22,26 +22,16 @@ #include "utility.h" -#include "../MarlinCore.h" #include "../module/temperature.h" #if ENABLED(MARLIN_DEV_MODE) MarlinError marlin_error_number; // Error Number - Marlin can beep X times periodically, display, and emit... #endif -void safe_delay(millis_t ms) { - while (ms > 50) { - ms -= 50; - delay(50); - thermalManager.task(); - } - delay(ms); - thermalManager.task(); // This keeps us safe if too many small safe_delay() calls are made -} - // A delay to provide brittle hosts time to receive bytes #if ENABLED(SERIAL_OVERRUN_PROTECTION) + #include "../MarlinCore.h" // for safe_delay #include "../gcode/gcode.h" // for set_autoreport_paused void serial_delay(const millis_t ms) { @@ -143,7 +133,7 @@ void safe_delay(millis_t ms) { SERIAL_ECHOPGM("ABL Adjustment"); LOOP_NUM_AXES(a) { SERIAL_ECHOPGM_P((PGM_P)pgm_read_ptr(&SP_AXIS_STR[a])); - serial_offset(planner.get_axis_position_mm(AxisEnum(a)) - current_position[a]); + serial_offset(planner.get_axis_position_mm((AxisEnum)a) - current_position[a]); } #else #if ENABLED(AUTO_BED_LEVELING_UBL) diff --git a/Marlin/src/core/utility.h b/Marlin/src/core/utility.h index 77e8bac016..b8b4de7f28 100644 --- a/Marlin/src/core/utility.h +++ b/Marlin/src/core/utility.h @@ -25,8 +25,6 @@ #include "../core/types.h" #include "../core/millis_t.h" -void safe_delay(millis_t ms); // Delay ensuring that temperatures are updated and the watchdog is kept alive. - #if ENABLED(SERIAL_OVERRUN_PROTECTION) void serial_delay(const millis_t ms); #else diff --git a/Marlin/src/feature/babystep.cpp b/Marlin/src/feature/babystep.cpp index 014ccea1af..d61784517b 100644 --- a/Marlin/src/feature/babystep.cpp +++ b/Marlin/src/feature/babystep.cpp @@ -25,8 +25,7 @@ #if ENABLED(BABYSTEPPING) #include "babystep.h" -#include "../MarlinCore.h" -#include "../module/motion.h" // for axes_should_home(), BABYSTEP_ALLOWED +#include "../module/motion.h" // for axis_should_home(), BABYSTEP_ALLOWED #include "../module/planner.h" // for axis_steps_per_mm[] #include "../module/stepper.h" @@ -49,17 +48,17 @@ int16_t Babystep::accum; void Babystep::step_axis(const AxisEnum axis) { const int16_t curTodo = steps[BS_AXIS_IND(axis)]; // get rid of volatile for performance if (curTodo) { - stepper.do_babystep((AxisEnum)axis, curTodo > 0); + stepper.do_babystep(axis, curTodo > 0); if (curTodo > 0) steps[BS_AXIS_IND(axis)]--; else steps[BS_AXIS_IND(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/bdl/bdl.cpp b/Marlin/src/feature/bedlevel/bdl/bdl.cpp index 7e9d583cc1..45c7792d5c 100644 --- a/Marlin/src/feature/bedlevel/bdl/bdl.cpp +++ b/Marlin/src/feature/bedlevel/bdl/bdl.cpp @@ -24,7 +24,6 @@ #if ENABLED(BD_SENSOR) -#include "../../../MarlinCore.h" #include "../../../gcode/gcode.h" #include "../../../module/settings.h" #include "../../../module/motion.h" @@ -101,7 +100,7 @@ bool BDS_Leveling::check(const uint16_t data, const bool raw_data/*=false*/, con } float BDS_Leveling::interpret(const uint16_t data) { - return (data & 0x3FF) / 100.0f; + return (data & 0x3FF) * 0.01f; } float BDS_Leveling::read() { @@ -110,7 +109,7 @@ float BDS_Leveling::read() { } void BDS_Leveling::process() { - if (config_state == BDS_IDLE && printingIsActive()) return; + if (config_state == BDS_IDLE && marlin.printingIsActive()) return; static millis_t next_check_ms = 0; // starting at T=0 static float zpos = 0.0f; const millis_t ms = millis(); @@ -156,7 +155,7 @@ void BDS_Leveling::process() { } else if (config_state == BDS_HOMING_Z) { SERIAL_ECHOLNPGM("Read:", tmp); - kill(F("BDsensor connect Err!")); + marlin.kill(F("BDsensor connect Err!")); } DEBUG_ECHOLNPGM("BD:", tmp & 0x3FF, " Z:", cur_z, "|", current_position.z); 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..2357437633 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl.cpp @@ -28,7 +28,6 @@ unified_bed_leveling bedlevel; -#include "../../../MarlinCore.h" #include "../../../gcode/gcode.h" #include "../../../module/settings.h" @@ -102,7 +101,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 +114,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)) @@ -221,7 +220,7 @@ void unified_bed_leveling::display_map(const uint8_t map_type) { if (human) SERIAL_CHAR(is_current ? ']' : ' '); SERIAL_FLUSHTX(); - idle_no_sleep(); + marlin.idle_no_sleep(); } if (!lcd) SERIAL_EOL(); 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..6341933bfb 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp @@ -26,7 +26,6 @@ #include "../bedlevel.h" -#include "../../../MarlinCore.h" #include "../../../HAL/shared/eeprom_api.h" #include "../../../libs/hex_print.h" #include "../../../module/settings.h" @@ -48,7 +47,7 @@ #include "../hilbert_curve.h" #endif -#if FT_MOTION_DISABLE_FOR_PROBING +#if ENABLED(FT_MOTION) #include "../../../module/ft_motion.h" #endif @@ -313,9 +312,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, FTM_DISABLE_IN_SCOPE()); // Check for commands that require the printer to be homed if (may_move) { @@ -376,7 +374,7 @@ void unified_bed_leveling::G29() { bool invalidate_all = count >= GRID_MAX_POINTS; if (!invalidate_all) { while (count--) { - if ((count & 0x0F) == 0x0F) idle(); + if ((count & 0x0F) == 0x0F) marlin.idle(); const mesh_index_pair closest = find_closest_mesh_point_of_type(REAL, param.XY_pos); // No more REAL mesh points to invalidate? Assume the user meant // to invalidate the ENTIRE mesh, which can't be done with @@ -398,7 +396,7 @@ void unified_bed_leveling::G29() { if (parser.seen('Q')) { const int16_t test_pattern = parser.has_value() ? parser.value_int() : -99; if (!WITHIN(test_pattern, TERN0(UBL_DEVEL_DEBUGGING, -1), 2)) { - SERIAL_ECHOLNPGM("?Invalid (Q) test pattern. (" TERN(UBL_DEVEL_DEBUGGING, "-1", "0") " to 2)\n"); + SERIAL_ECHOLN(F("?Invalid "), F("(Q) test pattern. (" TERN(UBL_DEVEL_DEBUGGING, "-1", "0") " to 2)\n")); return; } SERIAL_ECHOLNPGM("Applying test pattern.\n"); @@ -612,7 +610,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; } } @@ -649,7 +647,7 @@ void unified_bed_leveling::G29() { } if (!WITHIN(param.KLS_storage_slot, 0, a - 1)) { - SERIAL_ECHOLNPGM("?Invalid storage slot.\n?Use 0 to ", a - 1); + SERIAL_ECHOLN(F("?Invalid "), F("storage slot.\n?Use 0 to "), a - 1); return; } @@ -677,7 +675,7 @@ void unified_bed_leveling::G29() { } if (!WITHIN(param.KLS_storage_slot, 0, a - 1)) { - SERIAL_ECHOLNPGM("?Invalid storage slot.\n?Use 0 to ", a - 1); + SERIAL_ECHOLN(F("?Invalid "), F("storage slot.\n?Use 0 to "), a - 1); goto LEAVE; } @@ -716,7 +714,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 +750,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 +780,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 @@ -857,7 +855,7 @@ void set_message_with_feedback(FSTR_P const fstr) { ui.quick_feedback(false); // Preserve button state for click-and-hold const millis_t nxt = millis() + 1500UL; while (ui.button_pressed()) { // Loop while the encoder is pressed. Uses hardware flag! - idle(); // idle, of course + marlin.idle(); // idle, of course if (ELAPSED(millis(), nxt)) { // After 1.5 seconds ui.quick_feedback(); if (func) (*func)(); @@ -870,10 +868,10 @@ 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(); + marlin.idle(); gcode.reset_stepper_timeout(); // Keep steppers powered if (encoder_diff) { do_blocking_move_to_z(current_position.z + float(encoder_diff) * multiplier); @@ -953,7 +951,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()); @@ -1089,7 +1087,7 @@ void set_message_with_feedback(FSTR_P const fstr) { SET_SOFT_ENDSTOP_LOOSE(true); do { - idle_no_sleep(); + marlin.idle_no_sleep(); new_z = ui.ubl_mesh_value(); TERN_(UBL_MESH_EDIT_MOVES_Z, do_blocking_move_to_z(h_offset + new_z)); // Move the nozzle as the point is edited SERIAL_FLUSH(); // Prevent host M105 buffer overrun. @@ -1162,16 +1160,16 @@ bool unified_bed_leveling::G29_parse_parameters() { } if (parser.seen('P')) { - const uint8_t pv = parser.value_byte(); + const uint8_t pval = parser.value_byte(); #if !HAS_BED_PROBE - if (pv == 1) { + if (pval == 1) { SERIAL_ECHOLNPGM("G29 P1 requires a probe.\n"); err_flag = true; } else #endif { - param.P_phase = pv; + param.P_phase = pval; if (!WITHIN(param.P_phase, 0, 6)) { SERIAL_ECHOLNPGM("?(P)hase value invalid (0-6).\n"); err_flag = true; @@ -1183,7 +1181,7 @@ bool unified_bed_leveling::G29_parse_parameters() { #if HAS_BED_PROBE param.J_grid_size = parser.value_byte(); if (param.J_grid_size && !WITHIN(param.J_grid_size, 2, 9)) { - SERIAL_ECHOLNPGM("?Invalid grid size (J) specified (2-9).\n"); + SERIAL_ECHOLN(F("?Invalid "), F("grid size (J) specified (2-9).\n")); err_flag = true; } #else @@ -1511,7 +1509,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 +1565,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 +1659,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 +1683,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 @@ -1729,7 +1727,7 @@ void unified_bed_leveling::smart_fill_mesh() { const float ez = -lsf_results.D - lsf_results.A * ppos.x - lsf_results.B * ppos.y; z_values[ix][iy] = ez; TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(ix, iy, z_values[ix][iy])); - idle(); // housekeeping + marlin.idle(); // housekeeping } } } @@ -1786,7 +1784,7 @@ void unified_bed_leveling::smart_fill_mesh() { SERIAL_EOL(); #if HAS_KILL - SERIAL_ECHOLNPGM("Kill pin on :", KILL_PIN, " state:", kill_state()); + SERIAL_ECHOLNPGM("Kill pin on :", KILL_PIN, " state:", marlin.kill_state()); #endif SERIAL_EOL(); @@ -1824,7 +1822,7 @@ void unified_bed_leveling::smart_fill_mesh() { SERIAL_ECHO_MSG("EEPROM Dump:"); persistentStore.access_start(); for (uint16_t i = 0; i < persistentStore.capacity(); i += 16) { - if (!(i & 0x3)) idle(); + if (!(i & 0x3)) marlin.idle(); print_hex_word(i); SERIAL_ECHOPGM(": "); for (uint16_t j = 0; j < 16; j++) { @@ -1852,7 +1850,7 @@ void unified_bed_leveling::smart_fill_mesh() { } if (!parser.has_value() || !WITHIN(parser.value_int(), 0, a - 1)) { - SERIAL_ECHOLNPGM("?Invalid storage slot.\n?Use 0 to ", a - 1); + SERIAL_ECHOLN(F("?Invalid "), F("storage slot.\n?Use 0 to "), a - 1); return; } diff --git a/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp b/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp index 053a68b77d..b6b9ec4368 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp @@ -32,7 +32,6 @@ #include "../../../module/delta.h" #endif -#include "../../../MarlinCore.h" #include //#define DEBUG_UBL_MOTION @@ -47,7 +46,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 +350,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/bltouch.cpp b/Marlin/src/feature/bltouch.cpp index 5b498cd474..85b69d66c4 100644 --- a/Marlin/src/feature/bltouch.cpp +++ b/Marlin/src/feature/bltouch.cpp @@ -71,11 +71,9 @@ void BLTouch::init(const bool set_voltage/*=false*/) { #else - #ifdef DEBUG_OUT - if (DEBUGGING(LEVELING)) - DEBUG_ECHOLN( F("BLTouch Mode: "), bltouch.od_5v_mode ? F("5V") : F("OD"), - F(" (Default " TERN(BLTOUCH_SET_5V_MODE, "5V", "OD") ")")); - #endif + if (DEBUGGING(LEVELING)) + DEBUG_ECHOLN( F("BLTouch Mode: "), bltouch.od_5v_mode ? F("5V") : F("OD"), + F(" (Default " TERN(BLTOUCH_SET_5V_MODE, "5V", "OD") ")")); const bool should_set = od_5v_mode != ENABLED(BLTOUCH_SET_5V_MODE); diff --git a/Marlin/src/feature/controllerfan.cpp b/Marlin/src/feature/controllerfan.cpp index 243f0606ce..0636402136 100644 --- a/Marlin/src/feature/controllerfan.cpp +++ b/Marlin/src/feature/controllerfan.cpp @@ -134,7 +134,7 @@ void ControllerFan::update() { } while (0) #if ENABLED(FAN_SOFT_PWM) - soft_pwm_speed = speed; + soft_pwm_speed = speed >> 1; // Controller Fan Soft PWM uses 0-127 as 0-100% so cut the 0-255 range in half. #else SET_CONTROLLER_FAN(); #if PIN_EXISTS(CONTROLLER_FAN2) diff --git a/Marlin/src/feature/dac/dac_dac084s085.cpp b/Marlin/src/feature/dac/dac_dac084s085.cpp index 772bb68de4..1338e5979d 100644 --- a/Marlin/src/feature/dac/dac_dac084s085.cpp +++ b/Marlin/src/feature/dac/dac_dac084s085.cpp @@ -10,7 +10,6 @@ #include "dac_dac084s085.h" -#include "../../MarlinCore.h" #include "../../HAL/shared/Delay.h" dac084s085::dac084s085() { } diff --git a/Marlin/src/feature/dac/stepper_dac.cpp b/Marlin/src/feature/dac/stepper_dac.cpp index f5664bc598..65423d3189 100644 --- a/Marlin/src/feature/dac/stepper_dac.cpp +++ b/Marlin/src/feature/dac/stepper_dac.cpp @@ -68,7 +68,7 @@ void StepperDAC::set_current_value(const uint8_t channel, uint16_t val) { } void StepperDAC::set_current_percent(const uint8_t channel, float val) { - set_current_value(channel, _MIN(val, 100.0f) * (DAC_STEPPER_MAX) / 100.0f); + set_current_value(channel, _MIN(val, 100.0f) * (DAC_STEPPER_MAX) * 0.01f); } static float dac_perc(int8_t n) { return mcp4728.getDrvPct(dac_order[n]); } @@ -87,7 +87,7 @@ void StepperDAC::print_values() { LOOP_LOGICAL_AXES(a) { SERIAL_CHAR(' ', IAXIS_CHAR(a), ':'); SERIAL_ECHO(dac_perc(a)); - SERIAL_ECHOPGM_P(PSTR(" ("), dac_amps(AxisEnum(a)), PSTR(")")); + SERIAL_ECHOPGM_P(PSTR(" ("), dac_amps((AxisEnum)a), PSTR(")")); } #if HAS_EXTRUDERS SERIAL_ECHOLNPGM_P(SP_E_LBL, dac_perc(E_AXIS), PSTR(" ("), dac_amps(E_AXIS), PSTR(")")); diff --git a/Marlin/src/feature/direct_stepping.cpp b/Marlin/src/feature/direct_stepping.cpp index 13cf71e076..08cda561b1 100644 --- a/Marlin/src/feature/direct_stepping.cpp +++ b/Marlin/src/feature/direct_stepping.cpp @@ -175,7 +175,7 @@ namespace DirectStepping { template void SerialPageManager::write_responses() { if (fatal_error) { - kill(GET_TEXT_F(MSG_BAD_PAGE)); + marlin.kill(GET_TEXT_F(MSG_BAD_PAGE)); return; } diff --git a/Marlin/src/feature/e_parser.cpp b/Marlin/src/feature/e_parser.cpp index e249d81969..bda1232154 100644 --- a/Marlin/src/feature/e_parser.cpp +++ b/Marlin/src/feature/e_parser.cpp @@ -33,6 +33,9 @@ // Static data members bool EmergencyParser::killed_by_M112, // = false EmergencyParser::quickstop_by_M410, + #if ENABLED(FTM_RESONANCE_TEST) + EmergencyParser::rt_stop_by_M496, // = false + #endif #if HAS_MEDIA EmergencyParser::sd_abort_by_M524, #endif @@ -46,9 +49,6 @@ bool EmergencyParser::killed_by_M112, // = false // Global instance EmergencyParser emergency_parser; -// External references -extern bool wait_for_user, wait_for_heatup; - #if ENABLED(EP_BABYSTEPPING) #include "babystep.h" #endif @@ -147,9 +147,22 @@ void EmergencyParser::update(EmergencyParser::State &state, const uint8_t c) { case EP_M10: state = (c == '8') ? EP_M108 : EP_IGNORE; break; case EP_M11: state = (c == '2') ? EP_M112 : EP_IGNORE; break; - case EP_M4: state = (c == '1') ? EP_M41 : EP_IGNORE; break; + case EP_M4: + switch (c) { + case '1' :state = EP_M41; break; + #if ENABLED(FT_MOTION_RESONANCE_TEST) + case '9': state = EP_M49; break; + #endif + default: state = EP_IGNORE; + } + break; + case EP_M41: state = (c == '0') ? EP_M410 : EP_IGNORE; break; + #if ENABLED(FTM_RESONANCE_TEST) + case EP_M49: state = (c == '6') ? EP_M496 : EP_IGNORE; break; + #endif + #if HAS_MEDIA case EP_M5: state = (c == '2') ? EP_M52 : EP_IGNORE; break; case EP_M52: state = (c == '4') ? EP_M524 : EP_IGNORE; break; @@ -192,9 +205,12 @@ void EmergencyParser::update(EmergencyParser::State &state, const uint8_t c) { default: if (ISEOL(c)) { if (enabled) switch (state) { - case EP_M108: wait_for_user = wait_for_heatup = false; break; + case EP_M108: marlin.end_waiting(); break; case EP_M112: killed_by_M112 = true; break; case EP_M410: quickstop_by_M410 = true; break; + #if ENABLED(FTM_RESONANCE_TEST) + case EP_M496: rt_stop_by_M496 = true; break; + #endif #if ENABLED(EP_BABYSTEPPING) case EP_M293: babystep.ep_babysteps++; break; case EP_M294: babystep.ep_babysteps--; break; diff --git a/Marlin/src/feature/e_parser.h b/Marlin/src/feature/e_parser.h index 8dacb0581c..9f74a38116 100644 --- a/Marlin/src/feature/e_parser.h +++ b/Marlin/src/feature/e_parser.h @@ -43,6 +43,9 @@ public: #if HAS_MEDIA EP_M5, EP_M52, EP_M524, #endif + #if ENABLED(FTM_RESONANCE_TEST) + EP_M49, EP_M496, + #endif #if ENABLED(EP_BABYSTEPPING) EP_M2, EP_M29, EP_M293, EP_M294, #endif @@ -64,6 +67,10 @@ public: static bool killed_by_M112; static bool quickstop_by_M410; + #if ENABLED(FTM_RESONANCE_TEST) + static bool rt_stop_by_M496; + #endif + #if HAS_MEDIA static bool sd_abort_by_M524; #endif @@ -79,6 +86,8 @@ public: static void update(State &state, const uint8_t c); + static bool isEnabled() { return enabled; } + private: static bool enabled; }; diff --git a/Marlin/src/feature/easythreed_ui.cpp b/Marlin/src/feature/easythreed_ui.cpp index bfa51096f5..7180c4dbcd 100644 --- a/Marlin/src/feature/easythreed_ui.cpp +++ b/Marlin/src/feature/easythreed_ui.cpp @@ -91,7 +91,7 @@ void EasythreedUI::blinkLED() { // Load/Unload buttons are a 3 position switch with a common center ground. // void EasythreedUI::loadButton() { - if (printingIsActive()) return; + if (marlin.printingIsActive()) return; enum FilamentStatus : uint8_t { FS_IDLE, FS_PRESS, FS_CHECK, FS_PROCEED }; static uint8_t filament_status = FS_IDLE; @@ -185,7 +185,7 @@ void EasythreedUI::printButton() { if (PENDING(ms, key_time, 1200 - BTN_DEBOUNCE_MS)) { // Register a press < 1.2 seconds switch (print_key_flag) { case PF_START: { // The "Print" button starts an SD card print - if (printingIsActive()) break; // Already printing? (find another line that checks for 'is planner doing anything else right now?') + if (marlin.printingIsActive()) break; // Already printing? (find another line that checks for 'is planner doing anything else right now?') blink_interval_ms = LED_BLINK_2; // Blink the indicator LED at 1 second intervals print_key_flag = PF_PAUSE; // The "Print" button now pauses the print card.mount(); // Force SD card to mount - now! @@ -201,13 +201,13 @@ void EasythreedUI::printButton() { card.openAndPrintFile(card.filename); // Start printing it } break; case PF_PAUSE: { // Pause printing (not currently firing) - if (!printingIsActive()) break; + if (!marlin.printingIsActive()) break; blink_interval_ms = LED_ON; // Set indicator to steady ON queue.inject(F("M25")); // Queue Pause print_key_flag = PF_RESUME; // The "Print" button now resumes the print } break; case PF_RESUME: { // Resume printing - if (printingIsActive()) break; + if (marlin.printingIsActive()) break; blink_interval_ms = LED_BLINK_2; // Blink the indicator LED at 1 second intervals queue.inject(F("M24")); // Queue resume print_key_flag = PF_PAUSE; // The "Print" button now pauses the print @@ -215,7 +215,7 @@ void EasythreedUI::printButton() { } } else { // Register a longer press - if (print_key_flag == PF_START && !printingIsActive()) { // While not printing, this moves Z up 10mm + if (print_key_flag == PF_START && !marlin.printingIsActive()) { // While not printing, this moves Z up 10mm blink_interval_ms = LED_ON; queue.inject(F("G91\nG0 Z10 F600\nG90")); // Raise Z soon after returning to main loop } diff --git a/Marlin/src/feature/encoder_i2c.cpp b/Marlin/src/feature/encoder_i2c.cpp index 1930176aa6..7c83053b89 100644 --- a/Marlin/src/feature/encoder_i2c.cpp +++ b/Marlin/src/feature/encoder_i2c.cpp @@ -149,7 +149,7 @@ void I2CPositionEncoder::update() { #ifdef I2CPE_ERR_THRESH_ABORT if (ABS(error) > I2CPE_ERR_THRESH_ABORT * planner.settings.axis_steps_per_mm[encoderAxis]) { - //kill(F("Significant Error")); + //marlin.kill(F("Significant Error")); SERIAL_ECHOLNPGM("Axis error over threshold, aborting!", error); safe_delay(5000); } @@ -801,7 +801,7 @@ void I2CPositionEncodersMgr::M860() { if (I2CPE_idx == 0xFF) { LOOP_LOGICAL_AXES(i) { if (!I2CPE_anyaxis || parser.seen_test(AXIS_CHAR(i))) { - const uint8_t idx = idx_from_axis(AxisEnum(i)); + const uint8_t idx = idx_from_axis((AxisEnum)i); if ((int8_t)idx >= 0) report_position(idx, hasU, hasO); } } @@ -828,7 +828,7 @@ void I2CPositionEncodersMgr::M861() { if (I2CPE_idx == 0xFF) { LOOP_LOGICAL_AXES(i) { if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) { - const uint8_t idx = idx_from_axis(AxisEnum(i)); + const uint8_t idx = idx_from_axis((AxisEnum)i); if ((int8_t)idx >= 0) report_status(idx); } } @@ -856,7 +856,7 @@ void I2CPositionEncodersMgr::M862() { if (I2CPE_idx == 0xFF) { LOOP_LOGICAL_AXES(i) { if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) { - const uint8_t idx = idx_from_axis(AxisEnum(i)); + const uint8_t idx = idx_from_axis((AxisEnum)i); if ((int8_t)idx >= 0) test_axis(idx); } } @@ -887,7 +887,7 @@ void I2CPositionEncodersMgr::M863() { if (I2CPE_idx == 0xFF) { LOOP_LOGICAL_AXES(i) { if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) { - const uint8_t idx = idx_from_axis(AxisEnum(i)); + const uint8_t idx = idx_from_axis((AxisEnum)i); if ((int8_t)idx >= 0) calibrate_steps_mm(idx, iterations); } } @@ -963,7 +963,7 @@ void I2CPositionEncodersMgr::M865() { if (!I2CPE_addr) { LOOP_LOGICAL_AXES(i) { if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) { - const uint8_t idx = idx_from_axis(AxisEnum(i)); + const uint8_t idx = idx_from_axis((AxisEnum)i); if ((int8_t)idx >= 0) report_module_firmware(encoders[idx].get_address()); } } @@ -994,12 +994,12 @@ void I2CPositionEncodersMgr::M866() { if (I2CPE_idx == 0xFF) { LOOP_LOGICAL_AXES(i) { if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) { - const uint8_t idx = idx_from_axis(AxisEnum(i)); + const uint8_t idx = idx_from_axis((AxisEnum)i); if ((int8_t)idx >= 0) { if (hasR) - reset_error_count(idx, AxisEnum(i)); + reset_error_count(idx, (AxisEnum)i); else - report_error_count(idx, AxisEnum(i)); + report_error_count(idx, (AxisEnum)i); } } } @@ -1032,10 +1032,10 @@ void I2CPositionEncodersMgr::M867() { if (I2CPE_idx == 0xFF) { LOOP_LOGICAL_AXES(i) { if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) { - const uint8_t idx = idx_from_axis(AxisEnum(i)); + const uint8_t idx = idx_from_axis((AxisEnum)i); if ((int8_t)idx >= 0) { const bool ena = onoff == -1 ? !encoders[I2CPE_idx].get_ec_enabled() : !!onoff; - enable_ec(idx, ena, AxisEnum(i)); + enable_ec(idx, ena, (AxisEnum)i); } } } @@ -1068,7 +1068,7 @@ void I2CPositionEncodersMgr::M868() { if (I2CPE_idx == 0xFF) { LOOP_LOGICAL_AXES(i) { if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) { - const uint8_t idx = idx_from_axis(AxisEnum(i)); + const uint8_t idx = idx_from_axis((AxisEnum)i); if ((int8_t)idx >= 0) { if (newThreshold != -9999) set_ec_threshold(idx, newThreshold, encoders[idx].get_axis()); @@ -1102,7 +1102,7 @@ void I2CPositionEncodersMgr::M869() { if (I2CPE_idx == 0xFF) { LOOP_LOGICAL_AXES(i) { if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) { - const uint8_t idx = idx_from_axis(AxisEnum(i)); + const uint8_t idx = idx_from_axis((AxisEnum)i); if ((int8_t)idx >= 0) report_error(idx); } } 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/fancheck.cpp b/Marlin/src/feature/fancheck.cpp index 844191e7e4..d0582ed97a 100644 --- a/Marlin/src/feature/fancheck.cpp +++ b/Marlin/src/feature/fancheck.cpp @@ -42,62 +42,18 @@ bool FanCheck::enabled; void FanCheck::init() { #define _TACHINIT(N) TERN(E##N##_FAN_TACHO_PULLUP, SET_INPUT_PULLUP, TERN(E##N##_FAN_TACHO_PULLDOWN, SET_INPUT_PULLDOWN, SET_INPUT))(E##N##_FAN_TACHO_PIN) - #if HAS_E0_FAN_TACHO - _TACHINIT(0); - #endif - #if HAS_E1_FAN_TACHO - _TACHINIT(1); - #endif - #if HAS_E2_FAN_TACHO - _TACHINIT(2); - #endif - #if HAS_E3_FAN_TACHO - _TACHINIT(3); - #endif - #if HAS_E4_FAN_TACHO - _TACHINIT(4); - #endif - #if HAS_E5_FAN_TACHO - _TACHINIT(5); - #endif - #if HAS_E6_FAN_TACHO - _TACHINIT(6); - #endif - #if HAS_E7_FAN_TACHO - _TACHINIT(7); - #endif + #define _EN_TACHINIT(N) TERF(HAS_E##N##_FAN_TACHO, _TACHINIT)(N); + REPEAT(8, _EN_TACHINIT); } void FanCheck::update_tachometers() { bool status; - #define _TACHO_CASE(N) case N: status = READ(E##N##_FAN_TACHO_PIN); break; + #define __TACHO_GET_STATUS(N) case N: status = READ(E##N##_FAN_TACHO_PIN); break; + #define _TACHO_GET_STATUS(N) TERF(HAS_E##N##_FAN_TACHO, __TACHO_GET_STATUS)(N) for (uint8_t f = 0; f < TACHO_COUNT; ++f) { switch (f) { - #if HAS_E0_FAN_TACHO - _TACHO_CASE(0) - #endif - #if HAS_E1_FAN_TACHO - _TACHO_CASE(1) - #endif - #if HAS_E2_FAN_TACHO - _TACHO_CASE(2) - #endif - #if HAS_E3_FAN_TACHO - _TACHO_CASE(3) - #endif - #if HAS_E4_FAN_TACHO - _TACHO_CASE(4) - #endif - #if HAS_E5_FAN_TACHO - _TACHO_CASE(5) - #endif - #if HAS_E6_FAN_TACHO - _TACHO_CASE(6) - #endif - #if HAS_E7_FAN_TACHO - _TACHO_CASE(7) - #endif + REPEAT(8, _TACHO_GET_STATUS) default: continue; } @@ -115,14 +71,8 @@ void FanCheck::compute_speed(uint16_t elapsedTime) { uint8_t fan_error_msk = 0; for (uint8_t f = 0; f < TACHO_COUNT; ++f) { switch (f) { - TERN_(HAS_E0_FAN_TACHO, case 0:) - TERN_(HAS_E1_FAN_TACHO, case 1:) - TERN_(HAS_E2_FAN_TACHO, case 2:) - TERN_(HAS_E3_FAN_TACHO, case 3:) - TERN_(HAS_E4_FAN_TACHO, case 4:) - TERN_(HAS_E5_FAN_TACHO, case 5:) - TERN_(HAS_E6_FAN_TACHO, case 6:) - TERN_(HAS_E7_FAN_TACHO, case 7:) + #define _EN_COMPUTE_FAN_CASE(N) TERN_(HAS_E##N##_FAN_TACHO, case N:) + REPEAT(8, _EN_COMPUTE_FAN_CASE) // Compute fan speed rps[f] = edge_counter[f] * float(250) / elapsedTime; edge_counter[f] = 0; @@ -143,7 +93,7 @@ void FanCheck::compute_speed(uint16_t elapsedTime) { // Drop the error when all fans are ok if (!fan_error_msk && error == TachoError::REPORTED) error = TachoError::FIXED; - if (error == TachoError::FIXED && !printJobOngoing() && !printingIsPaused()) { + if (error == TachoError::FIXED && !marlin.printJobOngoing() && !marlin.printingIsPaused()) { error = TachoError::NONE; // if the issue has been fixed while the printer is idle, reenable immediately ui.reset_alert_level(); } @@ -156,17 +106,17 @@ void FanCheck::compute_speed(uint16_t elapsedTime) { } void FanCheck::report_speed_error(uint8_t fan) { - if (printJobOngoing()) { + if (marlin.printJobOngoing()) { if (error == TachoError::NONE) { if (thermalManager.degTargetHotend(fan) != 0) { - kill(GET_TEXT_F(MSG_FAN_SPEED_FAULT)); + marlin.kill(GET_TEXT_F(MSG_FAN_SPEED_FAULT)); error = TachoError::REPORTED; } else error = TachoError::DETECTED; // Plans error for next processed command } } - else if (!printingIsPaused()) { + else if (!marlin.printingIsPaused()) { thermalManager.setTargetHotend(0, fan); // Always disable heating if (error == TachoError::NONE) error = TachoError::REPORTED; } @@ -179,14 +129,8 @@ void FanCheck::print_fan_states() { for (uint8_t s = 0; s < 2; ++s) { for (uint8_t f = 0; f < TACHO_COUNT; ++f) { switch (f) { - TERN_(HAS_E0_FAN_TACHO, case 0:) - TERN_(HAS_E1_FAN_TACHO, case 1:) - TERN_(HAS_E2_FAN_TACHO, case 2:) - TERN_(HAS_E3_FAN_TACHO, case 3:) - TERN_(HAS_E4_FAN_TACHO, case 4:) - TERN_(HAS_E5_FAN_TACHO, case 5:) - TERN_(HAS_E6_FAN_TACHO, case 6:) - TERN_(HAS_E7_FAN_TACHO, case 7:) + #define _EN_PRINT_FAN_CASE(N) TERN_(HAS_E##N##_FAN_TACHO, case N:) + REPEAT(8, _EN_PRINT_FAN_CASE) SERIAL_ECHOPGM("E", f); if (s == 0) SERIAL_ECHOPGM(":", 60 * rps[f], " RPM "); diff --git a/Marlin/src/feature/fancheck.h b/Marlin/src/feature/fancheck.h index 3c295b3020..fed6a798e1 100644 --- a/Marlin/src/feature/fancheck.h +++ b/Marlin/src/feature/fancheck.h @@ -25,7 +25,6 @@ #if HAS_FANCHECK -#include "../MarlinCore.h" #include "../lcd/marlinui.h" #if ENABLED(AUTO_REPORT_FANS) @@ -74,7 +73,11 @@ class FanCheck { static void check_deferred_error() { if (error == TachoError::DETECTED) { error = TachoError::REPORTED; - TERN(PARK_HEAD_ON_PAUSE, queue.inject(F("M125")), kill(GET_TEXT_F(MSG_FAN_SPEED_FAULT))); + #if ENABLED(PARK_HEAD_ON_PAUSE) + queue.inject(F("M125")); + #else + marlin.kill(GET_TEXT_F(MSG_FAN_SPEED_FAULT)); + #endif } } diff --git a/Marlin/src/feature/filwidth.h b/Marlin/src/feature/filwidth.h index ab50fe0af3..a16240936a 100644 --- a/Marlin/src/feature/filwidth.h +++ b/Marlin/src/feature/filwidth.h @@ -67,7 +67,7 @@ public: } // Convert raw measurement to mm - static float raw_to_mm(const uint16_t v) { return v * (float(ADC_VREF_MV) / 1000.0f) * RECIPROCAL(float(MAX_RAW_THERMISTOR_VALUE)); } + static float raw_to_mm(const uint16_t v) { return v * (float(ADC_VREF_MV) * 0.001f) * RECIPROCAL(float(MAX_RAW_THERMISTOR_VALUE)); } static float raw_to_mm() { return raw_to_mm(raw); } // A scaled reading is ready @@ -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/fwretract.cpp b/Marlin/src/feature/fwretract.cpp index 8944d2bd35..5ea20401ea 100644 --- a/Marlin/src/feature/fwretract.cpp +++ b/Marlin/src/feature/fwretract.cpp @@ -164,9 +164,8 @@ void FWRetract::retract(const bool retracting E_OPTARG(bool swapping/*=false*/)) current_retract[active_extruder] = 0; // Recover E, set_current_to_destination - prepare_internal_move_to_destination( - MUL_TERN(RETRACT_SYNC_MIXING, swapping ? settings.swap_retract_recover_feedrate_mm_s : settings.retract_recover_feedrate_mm_s, MIXING_STEPPERS) - ); + const feedRate_t fr_mm_s = swapping ? settings.swap_retract_recover_feedrate_mm_s : settings.retract_recover_feedrate_mm_s; + prepare_internal_move_to_destination(MUL_TERN(RETRACT_SYNC_MIXING, fr_mm_s, MIXING_STEPPERS)); } TERN_(RETRACT_SYNC_MIXING, mixer.T(old_mixing_tool)); // Restore original mixing tool diff --git a/Marlin/src/feature/host_actions.cpp b/Marlin/src/feature/host_actions.cpp index 538aa92e91..94bc4db011 100644 --- a/Marlin/src/feature/host_actions.cpp +++ b/Marlin/src/feature/host_actions.cpp @@ -87,10 +87,6 @@ void HostUI::action(FSTR_P const fstr, const bool eol) { PGMSTR(CONTINUE_STR, "Continue"); PGMSTR(DISMISS_STR, "Dismiss"); - #if HAS_RESUME_CONTINUE - extern bool wait_for_user; - #endif - void HostUI::notify(const char * const cstr) { PORT_REDIRECT(SerialMask::All); action(F("notification "), false); @@ -205,7 +201,7 @@ void HostUI::action(FSTR_P const fstr, const bool eol) { } break; case PROMPT_USER_CONTINUE: - TERN_(HAS_RESUME_CONTINUE, wait_for_user = false); + TERN_(HAS_RESUME_CONTINUE, marlin.user_resume()); break; case PROMPT_PAUSE_RESUME: #if ALL(ADVANCED_PAUSE_FEATURE, HAS_MEDIA) diff --git a/Marlin/src/feature/hotend_idle.cpp b/Marlin/src/feature/hotend_idle.cpp index eb16781fdd..a779efeaff 100644 --- a/Marlin/src/feature/hotend_idle.cpp +++ b/Marlin/src/feature/hotend_idle.cpp @@ -43,7 +43,7 @@ millis_t HotendIdleProtection::next_protect_ms = 0; hotend_idle_settings_t HotendIdleProtection::cfg; // Initialized by settings.load void HotendIdleProtection::check_hotends(const millis_t &ms) { - const bool busy = (TERN0(HAS_RESUME_CONTINUE, wait_for_user) || planner.has_blocks_queued()); + const bool busy = (TERN0(HAS_RESUME_CONTINUE, marlin.wait_for_user) || planner.has_blocks_queued()); bool do_prot = false; if (!busy && cfg.timeout != 0) { HOTEND_LOOP() { diff --git a/Marlin/src/feature/joystick.cpp b/Marlin/src/feature/joystick.cpp index 29addfcf1e..cbfab1fed8 100644 --- a/Marlin/src/feature/joystick.cpp +++ b/Marlin/src/feature/joystick.cpp @@ -67,18 +67,10 @@ Joystick joystick; #if ENABLED(JOYSTICK_DEBUG) void Joystick::report() { SERIAL_ECHOPGM("Joystick"); - #if HAS_JOY_ADC_X - SERIAL_ECHOPGM_P(SP_X_STR, JOY_X(x.getraw())); - #endif - #if HAS_JOY_ADC_Y - SERIAL_ECHOPGM_P(SP_Y_STR, JOY_Y(y.getraw())); - #endif - #if HAS_JOY_ADC_Z - SERIAL_ECHOPGM_P(SP_Z_STR, JOY_Z(z.getraw())); - #endif - #if HAS_JOY_ADC_EN - SERIAL_ECHO_TERNARY(READ(JOY_EN_PIN), " EN=", "HIGH (dis", "LOW (en", "abled)"); - #endif + TERF(HAS_JOY_ADC_X, SERIAL_ECHOPGM_P)(SP_X_STR, JOY_X(x.getraw())); + TERF(HAS_JOY_ADC_Y, SERIAL_ECHOPGM_P)(SP_Y_STR, JOY_Y(y.getraw())); + TERF(HAS_JOY_ADC_Z, SERIAL_ECHOPGM_P)(SP_Z_STR, JOY_Z(z.getraw())); + TERF(HAS_JOY_ADC_EN, SERIAL_ECHO_TERNARY)(READ(JOY_EN_PIN), " EN=", "HIGH (dis", "LOW (en", "abled)"); SERIAL_EOL(); } #endif 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..9c39541a7c 100644 --- a/Marlin/src/feature/max7219.h +++ b/Marlin/src/feature/max7219.h @@ -74,14 +74,13 @@ #ifdef MAX7219_DEBUG_PROFILE // This class sums up the amount of time for which its instances exist. - // By default there is one instantiated for the duration of the idle() - // function. But an instance can be created in any code block to measure - // the time spent from the point of instantiation until the CPU leaves - // block. Be careful about having multiple instances of CodeProfiler as - // it does not guard against double counting. In general mixing ISR and - // non-ISR use will require critical sections but note that mode setting - // is atomic so the total or average times can safely be read if you set - // mode to FREEZE first. + // By default there is one instantiated for the duration of marlin.idle() + // but an instance can be created in any code block to measure time spent + // from instantiation until the CPU leaves the block. + // Be careful about having multiple instances of CodeProfiler as it does + // not guard against double counting. In general mixing ISR and non-ISR + // use will require critical sections but note that mode setting is atomic + // so the total or average times can safely be read if you set mode to FREEZE first. class CodeProfiler { public: enum Mode : uint8_t { ACCUMULATE_AVERAGE, ACCUMULATE_TOTAL, FREEZE }; @@ -166,7 +165,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/mmu.cpp b/Marlin/src/feature/mmu/mmu.cpp index 58c49ed224..b1e66cc425 100644 --- a/Marlin/src/feature/mmu/mmu.cpp +++ b/Marlin/src/feature/mmu/mmu.cpp @@ -24,7 +24,6 @@ #if HAS_PRUSA_MMU1 -#include "../../MarlinCore.h" #include "../../module/planner.h" #include "../../module/stepper.h" 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..76e2b8505f 100644 --- a/Marlin/src/feature/mmu/mmu2.cpp +++ b/Marlin/src/feature/mmu/mmu2.cpp @@ -40,7 +40,6 @@ MMU2 mmu2; #include "../../module/temperature.h" #include "../../module/planner.h" #include "../../module/stepper.h" -#include "../../MarlinCore.h" #if ENABLED(HOST_PROMPT_SUPPORT) #include "../host_actions.h" @@ -96,7 +95,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(); @@ -446,7 +445,7 @@ bool MMU2::rx_ok() { void MMU2::check_version(const uint16_t buildnr) { if (buildnr < MMU_REQUIRED_FW_BUILDNR) { SERIAL_ERROR_MSG("Invalid MMU2 firmware. Version >= " STRINGIFY(MMU_REQUIRED_FW_BUILDNR) " required."); - kill(GET_TEXT_F(MSG_KILL_MMU2_FIRMWARE)); + marlin.kill(GET_TEXT_F(MSG_KILL_MMU2_FIRMWARE)); } } @@ -786,10 +785,10 @@ void MMU2::command(const uint8_t mmu_cmd) { * Wait for response from MMU */ bool MMU2::get_response() { - while (cmd != MMU_CMD_NONE) idle(); + while (cmd != MMU_CMD_NONE) marlin.idle(); while (!ready) { - idle(); + marlin.idle(); if (state != 3) break; } @@ -985,7 +984,7 @@ bool MMU2::eject_filament(const uint8_t index, const bool recover) { mmu2_attn_buzz(); TERN_(HOST_PROMPT_SUPPORT, hostui.continue_prompt(GET_TEXT_F(MSG_MMU2_EJECT_RECOVER))); TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_MMU2_EJECT_RECOVER))); - TERN_(HAS_RESUME_CONTINUE, wait_for_user_response()); + TERN_(HAS_RESUME_CONTINUE, marlin.wait_for_user_response()); mmu2_attn_buzz(); command(MMU_CMD_R0); diff --git a/Marlin/src/feature/mmu3/mmu3.cpp b/Marlin/src/feature/mmu3/mmu3.cpp index de91916b56..9727c07829 100644 --- a/Marlin/src/feature/mmu3/mmu3.cpp +++ b/Marlin/src/feature/mmu3/mmu3.cpp @@ -255,7 +255,7 @@ namespace MMU3 { uint8_t block_index = planner.block_buffer_tail; while (block_index != planner.block_buffer_head) { block = &planner.block_buffer[block_index]; - if (block->steps[E_AXIS] != 0) e_active++; + if (block->steps.e != 0) e_active++; block_index = (block_index + 1) & (BLOCK_BUFFER_SIZE - 1); } } @@ -274,7 +274,7 @@ namespace MMU3 { */ void MMU3::checkFINDARunout() { if (!findaDetectsFilament() - //&& printJobOngoing() + //&& marlin.printJobOngoing() && parser.codenum != 600 && TERN1(HAS_LEVELING, planner.leveling_active) && xy_are_trusted() @@ -760,10 +760,10 @@ namespace MMU3 { LogEchoEvent(F("Resuming XYZ")); // Move XY to starting position, then Z - motion_do_blocking_move_to_xy(resume_position.x, resume_position.x, feedRate_t(NOZZLE_PARK_XY_FEEDRATE)); + motion_blocking_move_xy(resume_position.x, resume_position.y, feedRate_t(NOZZLE_PARK_XY_FEEDRATE)); // Move Z_AXIS to saved position - motion_do_blocking_move_to_z(resume_position.z, feedRate_t(NOZZLE_PARK_Z_FEEDRATE)); + motion_blocking_move_z(resume_position.z, feedRate_t(NOZZLE_PARK_Z_FEEDRATE)); // From this point forward, power panic should not use // the partial backup in RAM since the extruder is no @@ -857,7 +857,7 @@ namespace MMU3 { for (;;) { // in our new implementation, we know the exact state of the MMU at any moment, we do not have to wait for a timeout // So in this case we should decide if the operation is: - // - still running -> wait normally in idle() + // - still running -> wait normally in marlin.idle() // - failed -> then do the safety moves on the printer like before // - finished ok -> proceed with reading other commands safe_delay_keep_alive(0); // calls logicStep() and remembers its return status @@ -867,7 +867,7 @@ namespace MMU3 { nozzle_timer.start(); LogEchoEvent(F("Cooling Timeout started")); } - else if (nozzle_timer.duration() > (PAUSE_PARK_NOZZLE_TIMEOUT * 1000ul)) { // mins->msec. + else if (nozzle_timer.duration() > (PAUSE_PARK_NOZZLE_TIMEOUT * 1000UL)) { // mins->msec. mmu_print_saved &= ~(SavedState::CooldownPending); mmu_print_saved |= SavedState::Cooldown; thermal_setTargetHotend(0); diff --git a/Marlin/src/feature/mmu3/mmu3_marlin.h b/Marlin/src/feature/mmu3/mmu3_marlin.h index 2754a2274b..499af0f285 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(); @@ -46,8 +46,8 @@ namespace MMU3 { void planner_set_current_position_E(float e); xyz_pos_t planner_current_position(); - void motion_do_blocking_move_to_xy(float rx, float ry, float feedRate_mm_s); - void motion_do_blocking_move_to_z(float z, float feedRate_mm_s); + void motion_blocking_move_xy(float rx, float ry, float feedRate_mm_s); + void motion_blocking_move_z(float z, float feedRate_mm_s); void nozzle_park(); diff --git a/Marlin/src/feature/mmu3/mmu3_marlin1.cpp b/Marlin/src/feature/mmu3/mmu3_marlin1.cpp index be54695c74..f12d83772a 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); @@ -103,14 +103,13 @@ namespace MMU3 { return xyz_pos_t(current_position); } - void motion_do_blocking_move_to_xy(float rx, float ry, float feedRate_mm_s) { - current_position[X_AXIS] = rx; - current_position[Y_AXIS] = ry; + void motion_blocking_move_xy(float rx, float ry, float feedRate_mm_s) { + current_position.set(rx, ry); planner_line_to_current_position_sync(feedRate_mm_s); } - void motion_do_blocking_move_to_z(float z, float feedRate_mm_s) { - current_position[Z_AXIS] = z; + void motion_blocking_move_z(float z, float feedRate_mm_s) { + current_position.z = z; planner_line_to_current_position_sync(feedRate_mm_s); } @@ -123,15 +122,15 @@ namespace MMU3 { #endif } - bool marlin_printingIsActive() { return printingIsActive(); } + bool marlin_printingIsActive() { return marlin.printingIsActive(); } void marlin_manage_heater() { thermalManager.task(); } - void marlin_manage_inactivity(const bool b) { idle(b); } + void marlin_manage_inactivity(const bool b) { marlin.idle(b); } - void marlin_idle(bool b) { + void marlin_idle(const bool b) { thermalManager.task(); - idle(b); + marlin.idle(b); } void marlin_refresh_print_state_in_ram() { @@ -152,34 +151,18 @@ namespace MMU3 { #endif } - int16_t thermal_degTargetHotend() { - return thermalManager.degTargetHotend(0); - } - - int16_t thermal_degHotend() { - return thermalManager.degHotend(0); - } - - void thermal_setExtrudeMintemp(int16_t t) { - thermalManager.extrude_min_temp = t; - } - - void thermal_setTargetHotend(int16_t t) { - thermalManager.setTargetHotend(t, 0); - } + int16_t thermal_degTargetHotend() { return thermalManager.degTargetHotend(0); } + int16_t thermal_degHotend() { return thermalManager.degHotend(0); } + void thermal_setExtrudeMintemp(int16_t t) { thermalManager.extrude_min_temp = t; } + void thermal_setTargetHotend(int16_t t) { thermalManager.setTargetHotend(t, 0); } void safe_delay_keep_alive(uint16_t t) { - idle(true); + marlin.idle(true); safe_delay(t); } - void Enable_E0() { - stepper.enable_extruder(TERN_(HAS_EXTRUDERS, 0)); - } - - void Disable_E0() { - stepper.disable_extruder(TERN_(HAS_EXTRUDERS, 0)); - } + void Enable_E0() { stepper.enable_extruder(TERN_(HAS_EXTRUDERS, 0)); } + void Disable_E0() { stepper.disable_extruder(TERN_(HAS_EXTRUDERS, 0)); } bool xy_are_trusted() { return axis_is_trusted(X_AXIS) && axis_is_trusted(Y_AXIS); diff --git a/Marlin/src/feature/mmu3/mmu3_protocol_logic.cpp b/Marlin/src/feature/mmu3/mmu3_protocol_logic.cpp index cf74e669b8..4323925b6b 100644 --- a/Marlin/src/feature/mmu3/mmu3_protocol_logic.cpp +++ b/Marlin/src/feature/mmu3/mmu3_protocol_logic.cpp @@ -707,7 +707,7 @@ namespace MMU3 { } bool ProtocolLogic::Elapsed(uint32_t timeout) const { - return _millis() >= (lastUARTActivityMs + timeout); + return ELAPSED(_millis(), lastUARTActivityMs + timeout); } void ProtocolLogic::RecordUARTActivity() { @@ -716,7 +716,7 @@ namespace MMU3 { void ProtocolLogic::RecordReceivedByte(uint8_t c) { lastReceivedBytes[lrb] = c; - lrb = (lrb + 1) % lastReceivedBytes.size(); + lrb = (lrb + 1) % COUNT(lastReceivedBytes); } constexpr char NibbleToChar(uint8_t c) { @@ -728,13 +728,13 @@ namespace MMU3 { } void ProtocolLogic::FormatLastReceivedBytes(char *dst) { - for (uint8_t i = 0; i < lastReceivedBytes.size(); ++i) { - uint8_t b = lastReceivedBytes[(lrb - i - 1) % lastReceivedBytes.size()]; + for (uint8_t i = 0; i < COUNT(lastReceivedBytes); ++i) { + uint8_t b = lastReceivedBytes[(COUNT(lastReceivedBytes) - 1 + (lrb - i)) % COUNT(lastReceivedBytes)]; dst[i * 3] = NibbleToChar(b >> 4); dst[i * 3 + 1] = NibbleToChar(b & 0xf); dst[i * 3 + 2] = ' '; } - dst[(lastReceivedBytes.size() - 1) * 3 + 2] = 0; // terminate properly + dst[(COUNT(lastReceivedBytes) - 1) * 3 + 2] = 0; // terminate properly } void ProtocolLogic::FormatLastResponseMsgAndClearLRB(char *dst) { @@ -777,18 +777,18 @@ namespace MMU3 { } void ProtocolLogic::LogError(const char *reason_P) { - char lrb[lastReceivedBytes.size() * 3]; - FormatLastReceivedBytes(lrb); + char _lrb[COUNT(lastReceivedBytes) * 3]; + FormatLastReceivedBytes(_lrb); MMU2_ERROR_MSGRPGM(reason_P); SERIAL_ECHOPGM(", last bytes: "); - SERIAL_ECHOLN(lrb); + SERIAL_ECHOLN(_lrb); } void ProtocolLogic::LogResponse() { - char lrb[lastReceivedBytes.size()]; - FormatLastResponseMsgAndClearLRB(lrb); - MMU2_ECHO_MSGLN(lrb); + char _lrb[COUNT(lastReceivedBytes)]; + FormatLastResponseMsgAndClearLRB(_lrb); + MMU2_ECHO_MSGLN(_lrb); } StepStatus ProtocolLogic::SuppressShortDropOuts(const char *msg_P, StepStatus ss) { diff --git a/Marlin/src/feature/mmu3/mmu3_protocol_logic.h b/Marlin/src/feature/mmu3/mmu3_protocol_logic.h index 2fef77c276..30f9c5d0d5 100644 --- a/Marlin/src/feature/mmu3/mmu3_protocol_logic.h +++ b/Marlin/src/feature/mmu3/mmu3_protocol_logic.h @@ -36,24 +36,8 @@ #include "mmu_hw/buttons.h" #include "mmu_hw/registers.h" #include "mmu3_protocol.h" - - // #include std array is not available on AVR ... we need to "fake" it - namespace std { - template - class array { - T data[N]; - public: - array() = default; - inline constexpr T *begin() const { return data; } - inline constexpr T *end() const { return data + N; } - static constexpr uint8_t size() { return N; } - inline T &operator[](uint8_t i) { return data[i]; } - }; - } // std - #else // !__AVR__ - #include #include "mmu_hw/error_codes.h" #include "mmu_hw/progress_codes.h" @@ -351,8 +335,7 @@ namespace MMU3 { Protocol protocol; //!< protocol codec - std::array lastReceivedBytes; //!< remembers the last few bytes of incoming communication for diagnostic purposes - uint8_t lrb; + uint8_t lrb, lastReceivedBytes[16]; //!< keep the last few bytes of incoming communication for diagnostic purposes ErrorCode errorCode; //!< last received error code from the MMU ProgressCode progressCode; //!< last received progress code from the MMU diff --git a/Marlin/src/feature/mmu3/mmu3_reporting.cpp b/Marlin/src/feature/mmu3/mmu3_reporting.cpp index 426aa4d825..b0527937ea 100644 --- a/Marlin/src/feature/mmu3/mmu3_reporting.cpp +++ b/Marlin/src/feature/mmu3/mmu3_reporting.cpp @@ -213,7 +213,7 @@ namespace MMU3 { void EndReport(CommandInProgress /*cip*/, ProgressCode /*ec*/) { // clear the status msg line - let the printed filename get visible again - if (!printJobOngoing()) ui.reset_status(); + if (!marlin.printJobOngoing()) ui.reset_status(); //custom_message_type = CustomMsg::Status; } diff --git a/Marlin/src/feature/mmu3/ultralcd.cpp b/Marlin/src/feature/mmu3/ultralcd.cpp index 96e019740f..3b8f52beb3 100644 --- a/Marlin/src/feature/mmu3/ultralcd.cpp +++ b/Marlin/src/feature/mmu3/ultralcd.cpp @@ -187,7 +187,7 @@ } // Wait for 5 seconds before displaying the next text. for (uint8_t i = 0; i < 100; ++i) { - idle(true); + marlin.idle(true); safe_delay(50); if (ui.use_click()) { if (fmsg_next == nullptr) { diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp index bd86133771..025bcb8383 100644 --- a/Marlin/src/feature/pause.cpp +++ b/Marlin/src/feature/pause.cpp @@ -160,10 +160,10 @@ static bool ensure_safe_temperature(const bool wait=true, const PauseMode mode=P if (wait) return thermalManager.wait_for_hotend(active_extruder); // Allow interruption by Emergency Parser M108 - wait_for_heatup = TERN1(PREVENT_COLD_EXTRUSION, !thermalManager.allow_cold_extrude); - while (wait_for_heatup && ABS(thermalManager.wholeDegHotend(active_extruder) - thermalManager.degTargetHotend(active_extruder)) > (TEMP_WINDOW)) - idle(); - wait_for_heatup = false; + marlin.wait_for_heatup = TERN1(PREVENT_COLD_EXTRUSION, !thermalManager.allow_cold_extrude); + while (marlin.is_heating() && ABS(thermalManager.wholeDegHotend(active_extruder) - thermalManager.degTargetHotend(active_extruder)) > (TEMP_WINDOW)) + marlin.idle(); + marlin.heatup_done(); #if ENABLED(PREVENT_COLD_EXTRUSION) // A user can cancel wait-for-heating with M108 @@ -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); @@ -208,7 +206,7 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load first_impatient_beep(max_beep_count); KEEPALIVE_STATE(PAUSED_FOR_USER); - wait_for_user = true; // LCD click or M108 will clear this + marlin.wait_start(); // LCD click or M108 will clear this TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_FILAMENTLOAD))); @@ -217,19 +215,19 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load hostui.prompt_do(PROMPT_USER_CONTINUE, F("Load Filament T"), tool, FPSTR(CONTINUE_STR)); #endif - while (wait_for_user) { + while (marlin.wait_for_user) { impatient_beep(max_beep_count); #if ALL(HAS_FILAMENT_SENSOR, FILAMENT_CHANGE_RESUME_ON_INSERT) #if MULTI_FILAMENT_SENSOR - #define _CASE_INSERTED(N) case N-1: if (!FILAMENT_IS_OUT(N)) wait_for_user = false; break; + #define _CASE_INSERTED(N) case N-1: if (!FILAMENT_IS_OUT(N)) marlin.user_resume(); break; switch (active_extruder) { REPEAT_1(NUM_RUNOUT_SENSORS, _CASE_INSERTED) } #else - if (!FILAMENT_IS_OUT()) wait_for_user = false; + if (!FILAMENT_IS_OUT()) marlin.user_resume(); #endif #endif - idle_no_sleep(); + marlin.idle_no_sleep(); } } @@ -272,10 +270,10 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE))); TERN_(HOST_PROMPT_SUPPORT, hostui.continue_prompt(GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE))); - wait_for_user = true; // A click or M108 breaks the purge_length loop - for (float purge_count = purge_length; purge_count > 0 && wait_for_user; --purge_count) + marlin.wait_start(); // A click or M108 breaks the purge_length loop + for (float purge_count = purge_length; purge_count > 0 && marlin.wait_for_user; --purge_count) unscaled_e_move(1, ADVANCED_PAUSE_PURGE_FEEDRATE); - wait_for_user = false; + marlin.user_resume(); #else @@ -299,14 +297,14 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load if (show_lcd) { // Show "Purge More" / "Resume" menu and wait for reply KEEPALIVE_STATE(PAUSED_FOR_USER); - wait_for_user = false; + marlin.user_resume(); + pause_menu_response = PAUSE_RESPONSE_WAIT_FOR; #if ANY(HAS_MARLINUI_MENU, EXTENSIBLE_UI) ui.pause_show_message(PAUSE_MESSAGE_OPTION); // MarlinUI and MKS UI also set PAUSE_RESPONSE_WAIT_FOR #else - pause_menu_response = PAUSE_RESPONSE_WAIT_FOR; TERN_(SOVOL_SV06_RTS, rts.gotoPage(ID_PurgeMore_L, ID_PurgeMore_D)); #endif - while (pause_menu_response == PAUSE_RESPONSE_WAIT_FOR) idle_no_sleep(); + while (pause_menu_response == PAUSE_RESPONSE_WAIT_FOR) marlin.idle_no_sleep(); } #endif @@ -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); @@ -555,8 +553,8 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep KEEPALIVE_STATE(PAUSED_FOR_USER); TERN_(HOST_PROMPT_SUPPORT, hostui.continue_prompt(GET_TEXT_F(MSG_NOZZLE_PARKED))); TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_NOZZLE_PARKED))); - wait_for_user = true; // LCD click or M108 will clear this - while (wait_for_user) { + marlin.wait_start(); // LCD click or M108 will clear this + while (marlin.wait_for_user) { impatient_beep(max_beep_count); // If the nozzle has timed out... @@ -581,7 +579,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_HEATER_TIMEOUT)); #endif - TERN_(HAS_RESUME_CONTINUE, wait_for_user_response(0, true)); // Wait for LCD click or M108 + TERN_(HAS_RESUME_CONTINUE, marlin.wait_for_user_response(0, true)); // Wait for LCD click or M108 TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_INFO, GET_TEXT_F(MSG_REHEATING))); @@ -608,12 +606,12 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep LCD_MESSAGE(MSG_REHEATDONE); #endif - IF_DISABLED(PAUSE_REHEAT_FAST_RESUME, wait_for_user = true); + IF_DISABLED(PAUSE_REHEAT_FAST_RESUME, marlin.wait_start()); nozzle_timed_out = false; first_impatient_beep(max_beep_count); } - idle_no_sleep(); + marlin.idle_no_sleep(); } TERN_(DUAL_X_CARRIAGE, set_duplication_enabled(saved_ext_dup_mode, saved_ext)); } @@ -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/power.cpp b/Marlin/src/feature/power.cpp index a28d95d967..2068558fe9 100644 --- a/Marlin/src/feature/power.cpp +++ b/Marlin/src/feature/power.cpp @@ -119,7 +119,7 @@ void Power::power_on() { * Processes any PSU_POWEROFF_GCODE and makes a PS_OFF_SOUND if enabled. */ void Power::power_off() { - TERN_(HAS_SUICIDE, suicide()); + TERN_(HAS_SUICIDE, marlin.suicide()); if (!psu_on) return; @@ -208,7 +208,7 @@ void Power::power_off() { // If any of the stepper drivers are enabled... if (stepper.axis_enabled.bits) return true; - if (printJobOngoing() || printingIsPaused()) return true; + if (marlin.printJobOngoing() || marlin.printingIsPaused()) return true; #if ENABLED(AUTO_POWER_FANS) FANS_LOOP(i) if (thermalManager.fan_speed[i]) return true; diff --git a/Marlin/src/feature/powerloss.cpp b/Marlin/src/feature/powerloss.cpp index d4f5e04882..0dd19808bc 100644 --- a/Marlin/src/feature/powerloss.cpp +++ b/Marlin/src/feature/powerloss.cpp @@ -99,7 +99,7 @@ PrintJobRecovery recovery; /** * Clear the recovery info */ -void PrintJobRecovery::init() { info = {}; } +void PrintJobRecovery::init() { info = { 0 }; } /** * Enable or disable then call changed() @@ -141,6 +141,14 @@ bool PrintJobRecovery::check() { return success; } +/** + * Cancel recovery + */ +void PrintJobRecovery::cancel() { + TERN_(PLR_HEAT_BED_ON_REBOOT, set_bed_temp(false)); + purge(); +} + /** * Delete the recovery file and clear the recovery data */ @@ -221,7 +229,7 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW TERN_(HAS_WORKSPACE_OFFSET, info.workspace_offset = workspace_offset); E_TERN_(info.active_extruder = active_extruder); - #if DISABLED(NO_VOLUMETRICS) + #if HAS_VOLUMETRIC_EXTRUSION info.flag.volumetric_enabled = parser.volumetric_enabled; #if HAS_MULTI_EXTRUDER COPY(info.filament_size, planner.filament_size); @@ -270,7 +278,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 @@ -313,7 +321,7 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW void PrintJobRecovery::_outage(TERN_(DEBUG_POWER_LOSS_RECOVERY, const bool simulated/*=false*/)) { #if ENABLED(BACKUP_POWER_SUPPLY) static bool lock = false; - if (lock) return; // No re-entrance from idle() during retract_and_lift() + if (lock) return; // No re-entrance from marlin.idle() during retract_and_lift() lock = true; #endif @@ -347,7 +355,7 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW sync_plan_position(); } else - kill(GET_TEXT_F(MSG_OUTAGE_RECOVERY)); + marlin.kill(GET_TEXT_F(MSG_OUTAGE_RECOVERY)); } #endif // POWER_LOSS_PIN || DEBUG_POWER_LOSS_RECOVERY @@ -366,6 +374,13 @@ void PrintJobRecovery::write() { if (!file.close()) DEBUG_ECHOLNPGM("Power-loss file close failed."); } +#if ENABLED(PLR_HEAT_BED_ON_REBOOT) + // Set bed temperature and wait. Called from M1000 to resume bed heating. + void PrintJobRecovery::set_bed_temp(const bool on) { + PROCESS_SUBCOMMANDS_NOW(TS(F("M190S"), on ? info.target_temperature_bed + PLR_HEAT_BED_EXTRA : 0)); + } +#endif + /** * Resume the saved print job */ @@ -496,7 +511,7 @@ void PrintJobRecovery::resume() { #endif // Recover volumetric extrusion state - #if DISABLED(NO_VOLUMETRICS) + #if HAS_VOLUMETRIC_EXTRUSION #if HAS_MULTI_EXTRUDER EXTRUDER_LOOP() PROCESS_SUBCOMMANDS_NOW(TS(F("M200T"), e, F("D"), p_float_t(info.filament_size[e], 3))); @@ -659,7 +674,7 @@ void PrintJobRecovery::resume() { DEBUG_ECHOLNPGM("active_extruder: ", info.active_extruder); #endif - #if DISABLED(NO_VOLUMETRICS) + #if HAS_VOLUMETRIC_EXTRUSION DEBUG_ECHOPGM("filament_size:"); EXTRUDER_LOOP() DEBUG_ECHOLNPGM(" ", info.filament_size[e]); DEBUG_EOL(); @@ -725,7 +740,7 @@ void PrintJobRecovery::resume() { DEBUG_ECHOLNPGM("flag.dryrun: ", AS_DIGIT(info.flag.dryrun)); DEBUG_ECHOLNPGM("flag.allow_cold_extrusion: ", AS_DIGIT(info.flag.allow_cold_extrusion)); - #if DISABLED(NO_VOLUMETRICS) + #if HAS_VOLUMETRIC_EXTRUSION DEBUG_ECHOLNPGM("flag.volumetric_enabled: ", AS_DIGIT(info.flag.volumetric_enabled)); #endif } diff --git a/Marlin/src/feature/powerloss.h b/Marlin/src/feature/powerloss.h index 8e1e299ac0..bfa5b4717f 100644 --- a/Marlin/src/feature/powerloss.h +++ b/Marlin/src/feature/powerloss.h @@ -88,7 +88,7 @@ typedef struct { uint8_t active_extruder; #endif - #if DISABLED(NO_VOLUMETRICS) + #if HAS_VOLUMETRIC_EXTRUSION float filament_size[EXTRUDERS]; #endif @@ -140,7 +140,7 @@ typedef struct { #if HAS_LEVELING bool leveling:1; // M420 S #endif - #if DISABLED(NO_VOLUMETRICS) + #if HAS_VOLUMETRIC_EXTRUSION bool volumetric_enabled:1; // M200 S D #endif } flag; @@ -201,10 +201,15 @@ class PrintJobRecovery { static void close() { file.close(); } static bool check(); + + #if ENABLED(PLR_HEAT_BED_ON_REBOOT) + static void set_bed_temp(const bool turn_on); + #endif + static void resume(); static void purge(); - static void cancel() { purge(); } + static void cancel(); static void load(); static void save(const bool force=ENABLED(SAVE_EACH_CMD_MODE), const float zraise=POWER_LOSS_ZRAISE, const bool raised=false); @@ -237,7 +242,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..7dfa28f4b9 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); }; @@ -212,7 +212,7 @@ void ProbeTempComp::compensate_measurement(const TempSensorID tsi, const celsius } // convert offset to mm and apply it - meas_z -= offset / 1000.0f; + meas_z -= offset * 0.001f; } bool ProbeTempComp::linear_regression(const TempSensorID tsi, float &k, float &d) { 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..7881af4e38 100644 --- a/Marlin/src/feature/runout.h +++ b/Marlin/src/feature/runout.h @@ -31,7 +31,6 @@ #include "../module/stepper.h" // for block_t #include "../gcode/queue.h" #include "pause.h" // for did_pause_print -#include "../MarlinCore.h" // for printingIsActive() #include "../inc/MarlinConfig.h" @@ -64,7 +63,7 @@ typedef Flags< > runout_flags_t; void event_filament_runout(const uint8_t extruder); -inline bool should_monitor_runout() { return did_pause_print || printingIsActive(); } +inline bool should_monitor_runout() { return did_pause_print || marlin.printingIsActive(); } template class TFilamentMonitor; @@ -123,12 +122,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 +142,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 +374,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 +385,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 +417,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 +486,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 +499,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.cpp b/Marlin/src/feature/spindle_laser.cpp index 5f0ea7dd7b..dd8d859bde 100644 --- a/Marlin/src/feature/spindle_laser.cpp +++ b/Marlin/src/feature/spindle_laser.cpp @@ -112,7 +112,7 @@ void SpindleLaser::init() { const millis_t duration = (float(SPEED_POWER_MAX) * (60000.f / 2550.f) / float(acceleration_spindle_deg_per_s2)) * abs_diff; millis_t next_ocr_change = millis() + duration; while (current_ocr != ocr) { - while (PENDING(millis(), next_ocr_change)) idle(); + while (PENDING(millis(), next_ocr_change)) marlin.idle(); current_ocr += diff > 0 ? 1 : -1; hal.set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), current_ocr ^ SPINDLE_LASER_PWM_OFF); next_ocr_change += duration; diff --git a/Marlin/src/feature/spindle_laser.h b/Marlin/src/feature/spindle_laser.h index a283f0786d..8305c1fec4 100644 --- a/Marlin/src/feature/spindle_laser.h +++ b/Marlin/src/feature/spindle_laser.h @@ -54,13 +54,13 @@ 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 static constexpr cutter_cpower_t power_floor = TERN(CUTTER_POWER_RELATIVE, SPEED_POWER_MIN, 0); static constexpr uint8_t cpwr_to_pct(const cutter_cpower_t cpwr) { - return cpwr ? round(100.0f * (cpwr - power_floor) / (SPEED_POWER_MAX - power_floor)) : 0; + return cpwr ? LROUND(100.0f * (cpwr - power_floor) / (SPEED_POWER_MAX - power_floor)) : 0; } // Convert config defines from RPM to %, angle or PWM when in Spindle mode @@ -164,7 +164,7 @@ public: */ static cutter_power_t power_to_range(const cutter_power_t pwr, const uint8_t pwrUnit=_CUTTER_POWER(CUTTER_POWER_UNIT)) { static constexpr float - min_pct = TERN(CUTTER_POWER_RELATIVE, 0, TERN(SPINDLE_FEATURE, round(100.0f * (SPEED_POWER_MIN) / (SPEED_POWER_MAX)), SPEED_POWER_MIN)), + min_pct = TERN(CUTTER_POWER_RELATIVE, 0, TERN(SPINDLE_FEATURE, roundf(100.0f * (SPEED_POWER_MIN) / (SPEED_POWER_MAX)), SPEED_POWER_MIN)), max_pct = TERN(SPINDLE_FEATURE, 100, SPEED_POWER_MAX); if (pwr <= 0) return 0; cutter_power_t upwr; 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/tmc_util.cpp b/Marlin/src/feature/tmc_util.cpp index 06ee4c9e93..a91d435355 100644 --- a/Marlin/src/feature/tmc_util.cpp +++ b/Marlin/src/feature/tmc_util.cpp @@ -31,7 +31,6 @@ */ #include "tmc_util.h" -#include "../MarlinCore.h" #include "../module/stepper/indirection.h" #include "../module/printcounter.h" @@ -283,7 +282,7 @@ if (data.is_s2g) SERIAL_ECHOLNPGM("coil short circuit"); TERN_(TMC_DEBUG, tmc_report_all()); TERN_(SOVOL_SV06_RTS, rts.gotoPage(ID_DriverError_L, ID_DriverError_D)); - kill(F("Driver error")); + marlin.kill(F("Driver error")); } #endif @@ -973,14 +972,14 @@ TMC_REPORT("[mm/s]\t", TMC_TPWMTHRS_MMS); TMC_REPORT("OT prewarn", TMC_DEBUG_OTPW); #if ENABLED(MONITOR_DRIVER_STATUS) - TMC_REPORT("triggered\n OTP\t", TMC_OTPW_TRIGGERED); + TMC_REPORT("OTPW trig.\t", TMC_OTPW_TRIGGERED); #endif #if HAS_TMC220x - TMC_REPORT("pwm scale sum", TMC_PWM_SCALE_SUM); - TMC_REPORT("pwm scale auto", TMC_PWM_SCALE_AUTO); - TMC_REPORT("pwm offset auto", TMC_PWM_OFS_AUTO); - TMC_REPORT("pwm grad auto", TMC_PWM_GRAD_AUTO); + TMC_REPORT("pwm scale sum", TMC_PWM_SCALE_SUM); + TMC_REPORT("pwm scale auto", TMC_PWM_SCALE_AUTO); + TMC_REPORT("pwm offset auto", TMC_PWM_OFS_AUTO); + TMC_REPORT("pwm grad auto", TMC_PWM_GRAD_AUTO); #endif TMC_REPORT("off time", TMC_TOFF); diff --git a/Marlin/src/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..899498faae 100644 --- a/Marlin/src/gcode/bedlevel/G26.cpp +++ b/Marlin/src/gcode/bedlevel/G26.cpp @@ -105,7 +105,6 @@ #include "../gcode.h" #include "../../feature/bedlevel/bedlevel.h" -#include "../../MarlinCore.h" #include "../../module/planner.h" #include "../../module/motion.h" #include "../../module/tool_change.h" @@ -170,7 +169,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 +195,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, @@ -663,7 +662,7 @@ void GcodeSuite::G26() { do_z_clearance(Z_CLEARANCE_BETWEEN_PROBES); - #if DISABLED(NO_VOLUMETRICS) + #if HAS_VOLUMETRIC_EXTRUSION bool volumetric_was_enabled = parser.volumetric_enabled; parser.volumetric_enabled = false; planner.calculate_volumetric_multipliers(); @@ -856,7 +855,7 @@ void GcodeSuite::G26() { destination.z = Z_CLEARANCE_BETWEEN_PROBES; move_to(destination, 0); // Raise the nozzle - #if DISABLED(NO_VOLUMETRICS) + #if HAS_VOLUMETRIC_EXTRUSION parser.volumetric_enabled = volumetric_was_enabled; planner.calculate_volumetric_multipliers(); #endif diff --git a/Marlin/src/gcode/bedlevel/G42.cpp b/Marlin/src/gcode/bedlevel/G42.cpp index 44f5ceada8..4b9b028419 100644 --- a/Marlin/src/gcode/bedlevel/G42.cpp +++ b/Marlin/src/gcode/bedlevel/G42.cpp @@ -25,7 +25,6 @@ #if HAS_MESH #include "../gcode.h" -#include "../../MarlinCore.h" // for IsRunning() #include "../../module/motion.h" #include "../../feature/bedlevel/bedlevel.h" diff --git a/Marlin/src/gcode/bedlevel/abl/G29.cpp b/Marlin/src/gcode/bedlevel/abl/G29.cpp index 840614ad51..e4e6afc5be 100644 --- a/Marlin/src/gcode/bedlevel/abl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/abl/G29.cpp @@ -51,7 +51,7 @@ #if ENABLED(EXTENSIBLE_UI) #include "../../../lcd/extui/ui_api.h" #elif ENABLED(DWIN_CREALITY_LCD) - #include "../../../lcd/e3v2/creality/dwin.h" + #include "../../../lcd/dwin/creality/dwin.h" #elif ENABLED(SOVOL_SV06_RTS) #include "../../../lcd/sovol_rts/sovol_rts.h" #endif @@ -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) + // Potentially disable Fixed-Time Motion for probing + TERN_(FT_MOTION, FTM_DISABLE_IN_SCOPE()); #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) { @@ -758,7 +759,7 @@ G29_TYPE GcodeSuite::G29() { for (;;) { pos = planner.get_axis_position_mm(axis); if (inInc > 0 ? (pos >= cmp) : (pos <= cmp)) break; - idle_no_sleep(); + marlin.idle_no_sleep(); } //if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM_P(axis == Y_AXIS ? PSTR("Y=") : PSTR("X=", pos); @@ -802,7 +803,7 @@ G29_TYPE GcodeSuite::G29() { #endif abl.reenable = false; // Don't re-enable after modifying the mesh - idle_no_sleep(); + marlin.idle_no_sleep(); } // inner } // outer @@ -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 0a46301edb..2986d77d46 100644 --- a/Marlin/src/gcode/bedlevel/mbl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/mbl/G29.cpp @@ -45,8 +45,8 @@ #define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) #include "../../../core/debug_out.h" -#if FT_MOTION_DISABLE_FOR_PROBING - #include "../../module/ft_motion.h" +#if ENABLED(FT_MOTION) + #include "../../../module/ft_motion.h" #endif // Save 130 bytes with non-duplication of PSTR @@ -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, FTM_DISABLE_IN_SCOPE()); DEBUG_SECTION(log_G29, "G29", true); @@ -229,7 +228,7 @@ void GcodeSuite::G29() { } } else - return echo_not_entered('J'); + return echo_not_entered('I'); if (parser.seenval('J')) { iy = parser.value_int(); @@ -264,7 +263,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..4a0ecffc4b 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 @@ -61,7 +61,7 @@ #if ENABLED(EXTENSIBLE_UI) #include "../../lcd/extui/ui_api.h" #elif ENABLED(DWIN_CREALITY_LCD) - #include "../../lcd/e3v2/creality/dwin.h" + #include "../../lcd/dwin/creality/dwin.h" #elif ENABLED(SOVOL_SV06_RTS) #include "../../lcd/sovol_rts/sovol_rts.h" #endif @@ -129,16 +129,14 @@ #if ENABLED(Z_SAFE_HOMING) inline void home_z_safely() { - - #if FT_MOTION_DISABLE_FOR_PROBING - FTMotionDisableInScope FT_Disabler; // Disable Fixed-Time Motion for homing - #endif - DEBUG_SECTION(log_G28, "home_z_safely", DEBUGGING(LEVELING)); // Disallow Z homing if X or Y homing is needed if (homing_needed_error(_BV(X_AXIS) | _BV(Y_AXIS))) return; + // Potentially disable Fixed-Time Motion for homing + TERN_(FT_MOTION, FTM_DISABLE_IN_SCOPE()); + sync_plan_position(); /** @@ -290,9 +288,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, FTM_DISABLE_IN_SCOPE()); // 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..0a8dd459ca 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); } @@ -154,7 +154,7 @@ static float std_dev_points(float z_pt[NPP + 1], const bool _0p_cal, const bool S2 += sq(z_pt[rad]); N++; } - return LROUND(SQRT(S2 / N) * 1000.0f) / 1000.0f + 0.00001f; + return LROUND(SQRT(S2 / N) * 1000.0f) * 0.001f + 0.00001f; } } return 0.00001f; @@ -315,7 +315,7 @@ static void calc_kinematics_diff_probe_points(float z_pt[NPP + 1], const float d static float auto_tune_h(const float dcr) { const float r_quot = dcr / delta_radius; - return RECIPROCAL(r_quot / (2.0f / 3.0f)); // (2/3)/CR + return RECIPROCAL(r_quot * (3.0f / 2.0f)); // (2/3)/CR } static float auto_tune_r(const float dcr) { @@ -380,9 +380,9 @@ static float auto_tune_a(const float dcr) { * With HAS_DELTA_SENSORLESS_PROBING: * Use these flags to calibrate stall sensitivity: * Example: G33 P1 Y Z - to calibrate X only - * X Don't activate stallguard on X - * Y Don't activate stallguard on Y - * Z Don't activate stallguard on Z + * X Don't activate StallGuard on X + * Y Don't activate StallGuard on Y + * Z Don't activate StallGuard on Z * S Save offset_sensorless_adj */ void GcodeSuite::G33() { @@ -490,7 +490,7 @@ void GcodeSuite::G33() { float z_at_pt[NPP + 1] = { 0.0f }; - test_precision = zero_std_dev_old != 999.0f ? (zero_std_dev + zero_std_dev_old) / 2.0f : zero_std_dev; + test_precision = zero_std_dev_old != 999.0f ? (zero_std_dev + zero_std_dev_old) * 0.5f : zero_std_dev; iterations++; // Probe the points @@ -527,7 +527,7 @@ void GcodeSuite::G33() { * - Definition of the matrix scaling parameters * - Matrices for 4 and 7 point calibration */ - #define ZP(N,I) ((N) * z_at_pt[I] / 4.0f) // 4.0 = divider to normalize to integers + #define ZP(N,I) ((N) * z_at_pt[I] * 0.25f) // 4.0 = divider to normalize to integers #define Z12(I) ZP(12, I) #define Z4(I) ZP(4, I) #define Z2(I) ZP(2, I) diff --git a/Marlin/src/gcode/calibrate/G34_M422.cpp b/Marlin/src/gcode/calibrate/G34_M422.cpp index fc22b354eb..6c367ad882 100644 --- a/Marlin/src/gcode/calibrate/G34_M422.cpp +++ b/Marlin/src/gcode/calibrate/G34_M422.cpp @@ -236,10 +236,8 @@ void GcodeSuite::G34() { Z_TWEEN_SAFE_CLEARANCE // z_clearance ); - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOLNPGM_P(PSTR("Probing X"), ppos.x, SP_Y_STR, ppos.y); - DEBUG_ECHOLNPGM("Height = ", z_probed_height); - } + if (DEBUGGING(LEVELING)) + DEBUG_ECHOLN(F("Probing X"), ppos.x, FPSTR(SP_Y_STR), ppos.y, F(" Height = "), z_probed_height); if (isnan(z_probed_height)) { SERIAL_ECHOLNPGM(STR_ERR_PROBING_FAILED); @@ -323,7 +321,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); @@ -392,7 +390,7 @@ void GcodeSuite::G34() { // Decreasing accuracy was detected so move was inverted. // Will match reversed Z steppers on dual steppers. Triple will need more work to map. if (adjustment_reverse) { - z_align_move = -z_align_move; + z_align_move *= -1; if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> Z", zstepper + 1, " correction reversed to ", z_align_move); } #endif diff --git a/Marlin/src/gcode/calibrate/G425.cpp b/Marlin/src/gcode/calibrate/G425.cpp index 338c776885..883d7b4b6f 100644 --- a/Marlin/src/gcode/calibrate/G425.cpp +++ b/Marlin/src/gcode/calibrate/G425.cpp @@ -468,102 +468,54 @@ inline void probe_sides(measurements_t &m, const float uncertainty) { inline void report_measured_center(const measurements_t &m) { SERIAL_ECHOLNPGM("Center:"); - #if HAS_X_CENTER - SERIAL_ECHOLNPGM_P(SP_X_STR, m.obj_center.x); - #endif - #if HAS_Y_CENTER - SERIAL_ECHOLNPGM_P(SP_Y_STR, m.obj_center.y); - #endif + TERF(HAS_X_CENTER, SERIAL_ECHOLNPGM_P)(SP_X_STR, m.obj_center.x); + TERF(HAS_Y_CENTER, SERIAL_ECHOLNPGM_P)(SP_Y_STR, m.obj_center.y); SERIAL_ECHOLNPGM_P(SP_Z_STR, m.obj_center.z); - #if HAS_I_CENTER - SERIAL_ECHOLNPGM_P(SP_I_STR, m.obj_center.i); - #endif - #if HAS_J_CENTER - SERIAL_ECHOLNPGM_P(SP_J_STR, m.obj_center.j); - #endif - #if HAS_K_CENTER - SERIAL_ECHOLNPGM_P(SP_K_STR, m.obj_center.k); - #endif - #if HAS_U_CENTER - SERIAL_ECHOLNPGM_P(SP_U_STR, m.obj_center.u); - #endif - #if HAS_V_CENTER - SERIAL_ECHOLNPGM_P(SP_V_STR, m.obj_center.v); - #endif - #if HAS_W_CENTER - SERIAL_ECHOLNPGM_P(SP_W_STR, m.obj_center.w); - #endif + TERF(HAS_I_CENTER, SERIAL_ECHOLNPGM_P)(SP_I_STR, m.obj_center.i); + TERF(HAS_J_CENTER, SERIAL_ECHOLNPGM_P)(SP_J_STR, m.obj_center.j); + TERF(HAS_K_CENTER, SERIAL_ECHOLNPGM_P)(SP_K_STR, m.obj_center.k); + TERF(HAS_U_CENTER, SERIAL_ECHOLNPGM_P)(SP_U_STR, m.obj_center.u); + TERF(HAS_V_CENTER, SERIAL_ECHOLNPGM_P)(SP_V_STR, m.obj_center.v); + TERF(HAS_W_CENTER, SERIAL_ECHOLNPGM_P)(SP_W_STR, m.obj_center.w); SERIAL_EOL(); } inline void report_measured_backlash(const measurements_t &m) { SERIAL_ECHOLNPGM("Backlash:"); #if AXIS_CAN_CALIBRATE(X) - #if ENABLED(CALIBRATION_MEASURE_LEFT) - SERIAL_ECHOLNPGM(" Left: ", m.backlash[LEFT]); - #endif - #if ENABLED(CALIBRATION_MEASURE_RIGHT) - SERIAL_ECHOLNPGM(" Right: ", m.backlash[RIGHT]); - #endif + TERF(CALIBRATION_MEASURE_LEFT, SERIAL_ECHOLNPGM)(" Left: ", m.backlash[LEFT]); + TERF(CALIBRATION_MEASURE_RIGHT, SERIAL_ECHOLNPGM)(" Right: ", m.backlash[RIGHT]); #endif #if AXIS_CAN_CALIBRATE(Y) - #if ENABLED(CALIBRATION_MEASURE_FRONT) - SERIAL_ECHOLNPGM(" Front: ", m.backlash[FRONT]); - #endif - #if ENABLED(CALIBRATION_MEASURE_BACK) - SERIAL_ECHOLNPGM(" Back: ", m.backlash[BACK]); - #endif + TERF(CALIBRATION_MEASURE_FRONT, SERIAL_ECHOLNPGM)(" Front: ", m.backlash[FRONT]); + TERF(CALIBRATION_MEASURE_BACK, SERIAL_ECHOLNPGM)(" Back: ", m.backlash[BACK]); #endif #if AXIS_CAN_CALIBRATE(Z) SERIAL_ECHOLNPGM(" Top: ", m.backlash[TOP]); #endif #if AXIS_CAN_CALIBRATE(I) - #if ENABLED(CALIBRATION_MEASURE_IMIN) - SERIAL_ECHOLNPGM(" " STR_I_MIN ": ", m.backlash[IMINIMUM]); - #endif - #if ENABLED(CALIBRATION_MEASURE_IMAX) - SERIAL_ECHOLNPGM(" " STR_I_MAX ": ", m.backlash[IMAXIMUM]); - #endif + TERF(CALIBRATION_MEASURE_IMIN, SERIAL_ECHOLNPGM)(" " STR_I_MIN ": ", m.backlash[IMINIMUM]); + TERF(CALIBRATION_MEASURE_IMAX, SERIAL_ECHOLNPGM)(" " STR_I_MAX ": ", m.backlash[IMAXIMUM]); #endif #if AXIS_CAN_CALIBRATE(J) - #if ENABLED(CALIBRATION_MEASURE_JMIN) - SERIAL_ECHOLNPGM(" " STR_J_MIN ": ", m.backlash[JMINIMUM]); - #endif - #if ENABLED(CALIBRATION_MEASURE_JMAX) - SERIAL_ECHOLNPGM(" " STR_J_MAX ": ", m.backlash[JMAXIMUM]); - #endif + TERF(CALIBRATION_MEASURE_JMIN, SERIAL_ECHOLNPGM)(" " STR_J_MIN ": ", m.backlash[JMINIMUM]); + TERF(CALIBRATION_MEASURE_JMAX, SERIAL_ECHOLNPGM)(" " STR_J_MAX ": ", m.backlash[JMAXIMUM]); #endif #if AXIS_CAN_CALIBRATE(K) - #if ENABLED(CALIBRATION_MEASURE_KMIN) - SERIAL_ECHOLNPGM(" " STR_K_MIN ": ", m.backlash[KMINIMUM]); - #endif - #if ENABLED(CALIBRATION_MEASURE_KMAX) - SERIAL_ECHOLNPGM(" " STR_K_MAX ": ", m.backlash[KMAXIMUM]); - #endif + TERF(CALIBRATION_MEASURE_KMIN, SERIAL_ECHOLNPGM)(" " STR_K_MIN ": ", m.backlash[KMINIMUM]); + TERF(CALIBRATION_MEASURE_KMAX, SERIAL_ECHOLNPGM)(" " STR_K_MAX ": ", m.backlash[KMAXIMUM]); #endif #if AXIS_CAN_CALIBRATE(U) - #if ENABLED(CALIBRATION_MEASURE_UMIN) - SERIAL_ECHOLNPGM(" " STR_U_MIN ": ", m.backlash[UMINIMUM]); - #endif - #if ENABLED(CALIBRATION_MEASURE_UMAX) - SERIAL_ECHOLNPGM(" " STR_U_MAX ": ", m.backlash[UMAXIMUM]); - #endif + TERF(CALIBRATION_MEASURE_UMIN, SERIAL_ECHOLNPGM)(" " STR_U_MIN ": ", m.backlash[UMINIMUM]); + TERF(CALIBRATION_MEASURE_UMAX, SERIAL_ECHOLNPGM)(" " STR_U_MAX ": ", m.backlash[UMAXIMUM]); #endif #if AXIS_CAN_CALIBRATE(V) - #if ENABLED(CALIBRATION_MEASURE_VMIN) - SERIAL_ECHOLNPGM(" " STR_V_MIN ": ", m.backlash[VMINIMUM]); - #endif - #if ENABLED(CALIBRATION_MEASURE_VMAX) - SERIAL_ECHOLNPGM(" " STR_V_MAX ": ", m.backlash[VMAXIMUM]); - #endif + TERF(CALIBRATION_MEASURE_VMIN, SERIAL_ECHOLNPGM)(" " STR_V_MIN ": ", m.backlash[VMINIMUM]); + TERF(CALIBRATION_MEASURE_VMAX, SERIAL_ECHOLNPGM)(" " STR_V_MAX ": ", m.backlash[VMAXIMUM]); #endif #if AXIS_CAN_CALIBRATE(W) - #if ENABLED(CALIBRATION_MEASURE_WMIN) - SERIAL_ECHOLNPGM(" " STR_W_MIN ": ", m.backlash[WMINIMUM]); - #endif - #if ENABLED(CALIBRATION_MEASURE_WMAX) - SERIAL_ECHOLNPGM(" " STR_W_MAX ": ", m.backlash[WMAXIMUM]); - #endif + TERF(CALIBRATION_MEASURE_WMIN, SERIAL_ECHOLNPGM)(" " STR_W_MIN ": ", m.backlash[WMINIMUM]); + TERF(CALIBRATION_MEASURE_WMAX, SERIAL_ECHOLNPGM)(" " STR_W_MAX ": ", m.backlash[WMAXIMUM]); #endif SERIAL_EOL(); } @@ -604,12 +556,8 @@ inline void probe_sides(measurements_t &m, const float uncertainty) { inline void report_measured_nozzle_dimensions(const measurements_t &m) { SERIAL_ECHOLNPGM("Nozzle Tip Outer Dimensions:"); - #if HAS_X_CENTER - SERIAL_ECHOLNPGM_P(SP_X_STR, m.nozzle_outer_dimension.x); - #endif - #if HAS_Y_CENTER - SERIAL_ECHOLNPGM_P(SP_Y_STR, m.nozzle_outer_dimension.y); - #endif + TERF(HAS_X_CENTER, SERIAL_ECHOLNPGM_P)(SP_X_STR, m.nozzle_outer_dimension.x); + TERF(HAS_Y_CENTER, SERIAL_ECHOLNPGM_P)(SP_Y_STR, m.nozzle_outer_dimension.y); SERIAL_EOL(); UNUSED(m); } diff --git a/Marlin/src/gcode/calibrate/G76_M871.cpp b/Marlin/src/gcode/calibrate/G76_M871.cpp index 7051540e7b..35f7ac3174 100644 --- a/Marlin/src/gcode/calibrate/G76_M871.cpp +++ b/Marlin/src/gcode/calibrate/G76_M871.cpp @@ -96,7 +96,7 @@ void GcodeSuite::G76() { auto report_temps = [](millis_t &ntr, millis_t timeout=0) { - idle_no_sleep(); + marlin.idle_no_sleep(); const millis_t ms = millis(); if (ELAPSED(ms, ntr)) { ntr = ms + 1000; @@ -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/M100.cpp b/Marlin/src/gcode/calibrate/M100.cpp index ddfed4afe1..822ce969ec 100644 --- a/Marlin/src/gcode/calibrate/M100.cpp +++ b/Marlin/src/gcode/calibrate/M100.cpp @@ -28,8 +28,6 @@ #include "../queue.h" #include "../../libs/hex_print.h" -#include "../../MarlinCore.h" // for idle() - /** * M100: Free Memory Watcher * @@ -178,7 +176,7 @@ inline int32_t count_test_bytes(const char * const start_free_memory) { SERIAL_EOL(); start_free_memory += 16; serial_delay(25); - idle(); + marlin.idle(); } } @@ -209,12 +207,12 @@ inline int check_for_free_memory_corruption(FSTR_P const title) { if (end_free_memory < start_free_memory) { SERIAL_ECHOPGM(" end_free_memory < Heap "); //SET_INPUT_PULLUP(63); // if the developer has a switch wired up to their controller board - //safe_delay(5); // this code can be enabled to pause the display as soon as the - //while ( READ(63)) // malfunction is detected. It is currently defaulting to a switch - // idle(); // being on pin-63 which is unassigend and available on most controller - //safe_delay(20); // boards. + //safe_delay(5); // this code can be enabled to pause the display as soon as the + //while ( READ(63)) // malfunction is detected. It is currently defaulting to a switch + // marlin.idle(); // being on pin-63 which is unassigend and available on most controller + //safe_delay(20); // boards. //while ( !READ(63)) - // idle(); + // marlin.idle(); serial_delay(20); #if ENABLED(M100_FREE_MEMORY_DUMPER) M100_dump_routine(F(" Memory corruption detected with end_free_memory 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); - #endif - #if HAS_Z_AXIS - if (parser.floatval('Z') > 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); - #endif - #if HAS_J_AXIS - if (parser.floatval(AXIS5_NAME) > 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); - #endif - #if HAS_U_AXIS - if (parser.floatval(AXIS7_NAME) > 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); - #endif - #if HAS_W_AXIS - if (parser.floatval(AXIS9_NAME) > 0) homing_feedrate_mm_m.w = parser.value_axis_units(W_AXIS); - #endif + NUM_AXIS_CODE( + if (parser.floatval(AXIS1_PARAM) > 0) homing_feedrate_mm_m.x = parser.value_axis_units(X_AXIS), + if (parser.floatval(AXIS2_PARAM) > 0) homing_feedrate_mm_m.y = parser.value_axis_units(Y_AXIS), + if (parser.floatval(AXIS3_PARAM) > 0) homing_feedrate_mm_m.z = parser.value_axis_units(Z_AXIS), + if (parser.floatval(AXIS4_PARAM) > 0) homing_feedrate_mm_m.i = parser.value_axis_units(I_AXIS), + if (parser.floatval(AXIS5_PARAM) > 0) homing_feedrate_mm_m.j = parser.value_axis_units(J_AXIS), + if (parser.floatval(AXIS6_PARAM) > 0) homing_feedrate_mm_m.k = parser.value_axis_units(K_AXIS), + if (parser.floatval(AXIS7_PARAM) > 0) homing_feedrate_mm_m.u = parser.value_axis_units(U_AXIS), + if (parser.floatval(AXIS8_PARAM) > 0) homing_feedrate_mm_m.v = parser.value_axis_units(V_AXIS), + if (parser.floatval(AXIS9_PARAM) > 0) homing_feedrate_mm_m.w = parser.value_axis_units(W_AXIS) + ); } void GcodeSuite::M210_report(const bool forReplay/*=true*/) { diff --git a/Marlin/src/gcode/config/M43.cpp b/Marlin/src/gcode/config/M43.cpp index a515acb241..9410fea136 100644 --- a/Marlin/src/gcode/config/M43.cpp +++ b/Marlin/src/gcode/config/M43.cpp @@ -25,7 +25,6 @@ #if ENABLED(PINS_DEBUGGING) #include "../gcode.h" -#include "../../MarlinCore.h" // for pin_is_protected, wait_for_user #include "../../pins/pinsDebug.h" #include "../../module/endstops.h" @@ -64,7 +63,7 @@ inline void toggle_pins() { for (uint8_t i = start; i <= end; ++i) { pin_t pin = GET_PIN_MAP_PIN_M43(i); if (!isValidPin(pin)) continue; - if (M43_NEVER_TOUCH(i) || (!ignore_protection && pin_is_protected(pin))) { + if (M43_NEVER_TOUCH(i) || (!ignore_protection && marlin.pin_is_protected(pin))) { printPinStateExt(pin, ignore_protection, true, F("Untouched ")); SERIAL_EOL(); } @@ -154,37 +153,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 @@ -329,7 +327,7 @@ void GcodeSuite::M43() { for (uint8_t i = first_pin; i <= last_pin; ++i) { pin_t pin = GET_PIN_MAP_PIN_M43(i); if (!isValidPin(pin)) continue; - if (M43_NEVER_TOUCH(i) || (!ignore_protection && pin_is_protected(pin))) continue; + if (M43_NEVER_TOUCH(i) || (!ignore_protection && marlin.pin_is_protected(pin))) continue; can_watch = true; pinMode(pin, INPUT_PULLUP); delay(1); @@ -359,7 +357,7 @@ void GcodeSuite::M43() { #if HAS_RESUME_CONTINUE KEEPALIVE_STATE(PAUSED_FOR_USER); - wait_for_user = true; + marlin.wait_start(); TERN_(HOST_PROMPT_SUPPORT, hostui.continue_prompt(F("M43 Waiting..."))); #if ENABLED(EXTENSIBLE_UI) ExtUI::onUserConfirmRequired(F("M43 Waiting...")); @@ -372,7 +370,7 @@ void GcodeSuite::M43() { for (uint8_t i = first_pin; i <= last_pin; ++i) { const pin_t pin = GET_PIN_MAP_PIN_M43(i); if (!isValidPin(pin)) continue; - if (M43_NEVER_TOUCH(i) || (!ignore_protection && pin_is_protected(pin))) continue; + if (M43_NEVER_TOUCH(i) || (!ignore_protection && marlin.pin_is_protected(pin))) continue; const byte val = /* isAnalogPin(pin) @@ -388,7 +386,7 @@ void GcodeSuite::M43() { #if HAS_RESUME_CONTINUE ui.update(); - if (!wait_for_user) break; + if (!marlin.wait_for_user) break; #endif safe_delay(200); diff --git a/Marlin/src/gcode/config/M550.cpp b/Marlin/src/gcode/config/M550.cpp index 88712786da..ed7dc49159 100644 --- a/Marlin/src/gcode/config/M550.cpp +++ b/Marlin/src/gcode/config/M550.cpp @@ -25,7 +25,6 @@ #if ENABLED(CONFIGURABLE_MACHINE_NAME) #include "../gcode.h" -#include "../../MarlinCore.h" #include "../../lcd/marlinui.h" /** @@ -39,20 +38,20 @@ void GcodeSuite::M550() { bool did_set = true; if (parser.seenval('P')) - machine_name = parser.value_string(); + marlin.machine_name = parser.value_string(); else if (TERN(GCODE_QUOTED_STRINGS, false, parser.seen('P'))) - machine_name = parser.string_arg[0] == 'P' ? &parser.string_arg[1] : parser.string_arg; + marlin.machine_name = parser.string_arg[0] == 'P' ? &parser.string_arg[1] : parser.string_arg; else if (parser.has_string()) - machine_name = parser.string_arg; + marlin.machine_name = parser.string_arg; else did_set = false; if (did_set) { - machine_name.trim(); + marlin.machine_name.trim(); ui.reset_status(false); } else - SERIAL_ECHOLNPGM("RepRap name: ", &machine_name); + SERIAL_ECHOLNPGM("RepRap name: ", &marlin.machine_name); } diff --git a/Marlin/src/gcode/config/M575.cpp b/Marlin/src/gcode/config/M575.cpp index 2c12428d98..dd8f8addb5 100644 --- a/Marlin/src/gcode/config/M575.cpp +++ b/Marlin/src/gcode/config/M575.cpp @@ -51,25 +51,25 @@ void GcodeSuite::M575() { switch (baud) { case 2400: case 9600: case 19200: case 38400: case 57600: case 115200: case 250000: case 500000: case 1000000: { + SERIAL_FLUSH(); + const int8_t port = parser.intval('P', -99); const bool set1 = (port == -99 || port == 0); - if (set1) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(0), " baud rate set to ", baud); + if (set1) { MYSERIAL1.end(); MYSERIAL1.begin(baud); } #if HAS_MULTI_SERIAL const bool set2 = (port == -99 || port == 1); - if (set2) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(1), " baud rate set to ", baud); + if (set2) { MYSERIAL2.end(); MYSERIAL2.begin(baud); } #ifdef SERIAL_PORT_3 const bool set3 = (port == -99 || port == 2); - if (set3) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(2), " baud rate set to ", baud); + if (set3) { MYSERIAL3.end(); MYSERIAL3.begin(baud); } #endif #endif - SERIAL_FLUSH(); - - if (set1) { MYSERIAL1.end(); MYSERIAL1.begin(baud); } + if (set1) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(0), " baud rate set to ", baud); #if HAS_MULTI_SERIAL - if (set2) { MYSERIAL2.end(); MYSERIAL2.begin(baud); } + if (set2) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(1), " baud rate set to ", baud); #ifdef SERIAL_PORT_3 - if (set3) { MYSERIAL3.end(); MYSERIAL3.begin(baud); } + if (set3) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(2), " baud rate set to ", baud); #endif #endif diff --git a/Marlin/src/gcode/control/M108_M112_M410.cpp b/Marlin/src/gcode/control/M108_M112_M410.cpp index 39f9c04e19..e2ca9b2247 100644 --- a/Marlin/src/gcode/control/M108_M112_M410.cpp +++ b/Marlin/src/gcode/control/M108_M112_M410.cpp @@ -21,26 +21,21 @@ */ #include "../../inc/MarlinConfig.h" - -#if DISABLED(EMERGENCY_PARSER) - #include "../gcode.h" -#include "../../MarlinCore.h" // for wait_for_heatup, kill, M112_KILL_STR #include "../../module/motion.h" // for quickstop_stepper /** * M108: Stop the waiting for heaters in M109, M190, M303. Does not affect the target temperature. */ void GcodeSuite::M108() { - TERN_(HAS_RESUME_CONTINUE, wait_for_user = false); - wait_for_heatup = false; + marlin.end_waiting(); } /** * M112: Full Shutdown */ void GcodeSuite::M112() { - kill(FPSTR(M112_KILL_STR), nullptr, true); + marlin.kill(FPSTR(M112_KILL_STR), nullptr, true); } /** @@ -52,5 +47,3 @@ void GcodeSuite::M112() { void GcodeSuite::M410() { quickstop_stepper(); } - -#endif // !EMERGENCY_PARSER diff --git a/Marlin/src/gcode/control/M17_M18_M84.cpp b/Marlin/src/gcode/control/M17_M18_M84.cpp index 1742d288b3..90563889f3 100644 --- a/Marlin/src/gcode/control/M17_M18_M84.cpp +++ b/Marlin/src/gcode/control/M17_M18_M84.cpp @@ -78,7 +78,7 @@ void do_enable(const stepper_flags_t to_enable) { // Enable all flagged axes LOOP_NUM_AXES(a) { if (TEST(shall_enable, a)) { - stepper.enable_axis(AxisEnum(a)); // Mark and enable the requested axis + stepper.enable_axis((AxisEnum)a); // Mark and enable the requested axis DEBUG_ECHOLNPGM("Enabled ", AXIS_CHAR(a), " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... Enabled: ", hex_word(stepper.axis_enabled.bits)); also_enabled |= enable_overlap[a]; } @@ -153,7 +153,7 @@ void try_to_disable(const stepper_flags_t to_disable) { LOOP_NUM_AXES(a) if (TEST(to_disable.bits, a)) { DEBUG_ECHOPGM("Try to disable ", AXIS_CHAR(a), " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... "); - if (stepper.disable_axis(AxisEnum(a))) { // Mark the requested axis and request to disable + if (stepper.disable_axis((AxisEnum)a)) { // Mark the requested axis and request to disable DEBUG_ECHOPGM("OK"); still_enabled &= ~(_BV(a) | enable_overlap[a]); // If actually disabled, clear one or more tracked bits } diff --git a/Marlin/src/gcode/control/M226.cpp b/Marlin/src/gcode/control/M226.cpp index 4eb3db4bc3..921ce0d4c2 100644 --- a/Marlin/src/gcode/control/M226.cpp +++ b/Marlin/src/gcode/control/M226.cpp @@ -25,7 +25,6 @@ #if ENABLED(DIRECT_PIN_CONTROL) #include "../gcode.h" -#include "../../MarlinCore.h" // for pin_is_protected and idle() #include "../../module/planner.h" void protected_pin_err(); @@ -40,7 +39,7 @@ void GcodeSuite::M226() { const pin_t pin = GET_PIN_MAP_PIN(pin_number); if (WITHIN(pin_state, -1, 1) && pin > -1) { - if (pin_is_protected(pin)) + if (marlin.pin_is_protected(pin)) protected_pin_err(); else { int target = LOW; @@ -51,7 +50,7 @@ void GcodeSuite::M226() { case 0: target = LOW; break; case -1: target = !extDigitalRead(pin); break; } - while (int(extDigitalRead(pin)) != target) idle(); + while (int(extDigitalRead(pin)) != target) marlin.idle(); } } // pin_state -1 0 1 && pin > -1 } // parser.seen('P') diff --git a/Marlin/src/gcode/control/M350_M351.cpp b/Marlin/src/gcode/control/M350_M351.cpp index 425abad529..76753b2ea9 100644 --- a/Marlin/src/gcode/control/M350_M351.cpp +++ b/Marlin/src/gcode/control/M350_M351.cpp @@ -27,7 +27,7 @@ #include "../gcode.h" #include "../../module/stepper.h" -#if NUM_AXES == XYZ && EXTRUDERS >= 1 +#if NUM_AXES == 3 && EXTRUDERS >= 1 #define HAS_M350_B_PARAM 1 // "5th axis" (after E0) for an original XYZEB setup. #endif diff --git a/Marlin/src/gcode/control/M42.cpp b/Marlin/src/gcode/control/M42.cpp index 4ac7834f90..717b0695a4 100644 --- a/Marlin/src/gcode/control/M42.cpp +++ b/Marlin/src/gcode/control/M42.cpp @@ -37,8 +37,6 @@ #define OUTPUT_OPEN_DRAIN OUTPUT_OPEN_DRAIN #endif -bool pin_is_protected(const pin_t pin); - void protected_pin_err() { SERIAL_ERROR_MSG(STR_ERR_PROTECTED_PIN); } @@ -63,7 +61,7 @@ void GcodeSuite::M42() { const pin_t pin = GET_PIN_MAP_PIN(pin_index); - if (!parser.boolval('I') && pin_is_protected(pin)) return protected_pin_err(); + if (!parser.boolval('I') && marlin.pin_is_protected(pin)) return protected_pin_err(); bool avoidWrite = false; if (parser.seenval('T')) { diff --git a/Marlin/src/gcode/control/M80_M81.cpp b/Marlin/src/gcode/control/M80_M81.cpp index a37b0af680..a7653a4037 100644 --- a/Marlin/src/gcode/control/M80_M81.cpp +++ b/Marlin/src/gcode/control/M80_M81.cpp @@ -93,7 +93,7 @@ void GcodeSuite::M81() { safe_delay(1000); // Wait 1 second before switching off #if ENABLED(CONFIGURABLE_MACHINE_NAME) - ui.set_status(&MString<30>(&machine_name, ' ', F(STR_OFF), '.')); + ui.set_status(&MString<30>(&marlin.machine_name, ' ', F(STR_OFF), '.')); #else LCD_MESSAGE_F(MACHINE_NAME " " STR_OFF "."); #endif @@ -125,6 +125,6 @@ void GcodeSuite::M81() { #if ENABLED(PSU_CONTROL) powerManager.power_off_soon(); #elif HAS_SUICIDE - suicide(); + marlin.suicide(); #endif } diff --git a/Marlin/src/gcode/control/M999.cpp b/Marlin/src/gcode/control/M999.cpp index b4278fccad..863ab8eb90 100644 --- a/Marlin/src/gcode/control/M999.cpp +++ b/Marlin/src/gcode/control/M999.cpp @@ -23,7 +23,7 @@ #include "../gcode.h" #include "../../lcd/marlinui.h" // for ui.reset_alert_level -#include "../../MarlinCore.h" // for marlin_state +#include "../../MarlinCore.h" // for setState #include "../queue.h" // for flush_and_request_resend /** @@ -36,7 +36,7 @@ * existing command buffer. */ void GcodeSuite::M999() { - marlin_state = MarlinState::MF_RUNNING; + marlin.setState(MF_RUNNING); ui.reset_alert_level(); if (parser.boolval('S')) return; diff --git a/Marlin/src/gcode/feature/advance/M900.cpp b/Marlin/src/gcode/feature/advance/M900.cpp index 7b92cad9d2..7631cd0e8c 100644 --- a/Marlin/src/gcode/feature/advance/M900.cpp +++ b/Marlin/src/gcode/feature/advance/M900.cpp @@ -22,7 +22,7 @@ #include "../../../inc/MarlinConfig.h" -#if ENABLED(LIN_ADVANCE) +#if HAS_LIN_ADVANCE_K #include "../../gcode.h" #include "../../../module/planner.h" @@ -41,6 +41,9 @@ * With ADVANCE_K_EXTRA: * S<0/1> Activate slot 0 or 1. * L Set secondary advance K factor (Slot 1). + * + * With SMOOTH_LIN_ADVANCE: + * U Set a tau value for LA smoothing */ void GcodeSuite::M900() { @@ -191,4 +194,4 @@ void GcodeSuite::M900_report(const bool forReplay/*=true*/) { } } -#endif // LIN_ADVANCE +#endif // HAS_LIN_ADVANCE_K diff --git a/Marlin/src/gcode/feature/camera/M240.cpp b/Marlin/src/gcode/feature/camera/M240.cpp index bb1d3f9eee..8bf0f5d539 100644 --- a/Marlin/src/gcode/feature/camera/M240.cpp +++ b/Marlin/src/gcode/feature/camera/M240.cpp @@ -31,10 +31,6 @@ millis_t chdk_timeout; // = 0 #endif -#if defined(PHOTO_POSITION) && PHOTO_DELAY_MS > 0 - #include "../../../MarlinCore.h" // for idle() -#endif - #ifdef PHOTO_RETRACT_MM #define _PHOTO_RETRACT_MM (PHOTO_RETRACT_MM + 0) @@ -47,7 +43,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); } @@ -185,7 +181,7 @@ void GcodeSuite::M240() { #ifdef PHOTO_POSITION #if PHOTO_DELAY_MS > 0 const millis_t timeout = millis() + parser.intval('P', PHOTO_DELAY_MS); - while (PENDING(millis(), timeout)) idle(); + while (PENDING(millis(), timeout)) marlin.idle(); #endif do_blocking_move_to(old_pos, fr_mm_s); #ifdef PHOTO_RETRACT_MM 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/filwidth/M404-M407.cpp b/Marlin/src/gcode/feature/filwidth/M404-M407.cpp index ff174ecf13..5b906760ed 100644 --- a/Marlin/src/gcode/feature/filwidth/M404-M407.cpp +++ b/Marlin/src/gcode/feature/filwidth/M404-M407.cpp @@ -26,7 +26,6 @@ #include "../../../feature/filwidth.h" #include "../../../module/planner.h" -#include "../../../MarlinCore.h" #include "../../gcode.h" /** diff --git a/Marlin/src/gcode/feature/ft_motion/M493.cpp b/Marlin/src/gcode/feature/ft_motion/M493.cpp index fe57de6ac8..85e2fc9d3b 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,49 +42,36 @@ 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() { + const ft_config_t &c = ftMotion.cfg; + // FT Enabled - SERIAL_ECHO_TERNARY(ftMotion.cfg.active, "Fixed-Time Motion ", "en", "dis", "abled"); + SERIAL_ECHO_TERNARY(c.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 + 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(); - SERIAL_ECHOLNPGM("."); - - 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), + const bool z_based = TERN0(HAS_DYNAMIC_FREQ_MM, c.dynFreqMode == dynFreqMode_Z_BASED), + g_based = TERN0(HAS_DYNAMIC_FREQ_G, c.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) { + switch (c.dynFreqMode) { default: case dynFreqMode_DISABLED: SERIAL_ECHOPGM("disabled"); break; #if HAS_DYNAMIC_FREQ_MM @@ -97,31 +85,35 @@ void say_shaping() { #endif #if HAS_X_AXIS - SERIAL_ECHO_TERNARY(dynamic, AXIS_0_NAME " ", "base dynamic", "static", " shaper frequency: "); - SERIAL_ECHO(p_float_t(ftMotion.cfg.baseFreq.x, 2), F("Hz")); + SERIAL_CHAR(STEPPER_A_NAME); + SERIAL_ECHO_TERNARY(dynamic, " ", "base dynamic", "static", " shaper frequency: "); + SERIAL_ECHO(p_float_t(c.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")); + if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(c.dynFreqK.x, 2), F("Hz/"), z_based ? F("mm") : F("g")); #endif SERIAL_EOL(); #endif #if HAS_Y_AXIS - SERIAL_ECHO_TERNARY(dynamic, AXIS_1_NAME " ", "base dynamic", "static", " shaper frequency: "); - SERIAL_ECHO(p_float_t(ftMotion.cfg.baseFreq.y, 2), F(" Hz")); + SERIAL_CHAR(STEPPER_B_NAME); + SERIAL_ECHO_TERNARY(dynamic, " ", "base dynamic", "static", " shaper frequency: "); + SERIAL_ECHO(p_float_t(c.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")); + if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(c.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(c.baseFreq.z, 2), F(" Hz")); + #if HAS_DYNAMIC_FREQ + if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(c.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) - SERIAL_ECHOLNPGM(". Gain: ", ftMotion.cfg.linearAdvK); - else - SERIAL_EOL(); - #endif } void GcodeSuite::M493_report(const bool forReplay/*=true*/) { @@ -129,37 +121,62 @@ 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); + + SERIAL_ECHOLNPGM( + " M493 S", c.active + #if HAS_DYNAMIC_FREQ + , " D", c.dynFreqMode #endif - #endif + // Axis Synchronization + , " H", c.axis_sync_enabled + ); + #if HAS_DYNAMIC_FREQ - SERIAL_ECHOPGM(" D", c.dynFreqMode); - #if HAS_X_AXIS - SERIAL_ECHOPGM(" F", c.dynFreqK.x); - #if HAS_Y_AXIS - SERIAL_ECHOPGM(" H", c.dynFreqK.y); - #endif - #endif + #define F_REPORT(A) , F(" F"), c.dynFreqK.A + #else + #define F_REPORT(A) #endif - #if HAS_EXTRUDERS - SERIAL_ECHOPGM(" P", c.linearAdvEna, " K", c.linearAdvK); + #if HAS_FTM_EI_SHAPING + #define Q_REPORT(A) , F(" Q"), c.vtol.A + #else + #define Q_REPORT(A) #endif - SERIAL_EOL(); + #define _REPORT_M493_AXIS(A) \ + SERIAL_ECHOLN(F(" M493 "), C(AXIS_CHAR(_AXIS(A))) \ + , F(" C"), c.shaper.A \ + , F(" A"), c.baseFreq.A \ + F_REPORT(A) \ + , F(" I"), c.zeta.A \ + Q_REPORT(A) \ + ); + // Shaper type for each axis + SHAPED_MAP(_REPORT_M493_AXIS); } /** * M493: Set Fixed-time Motion Control parameters * - * S Set Fixed-Time motion mode on or off. + * S Set Fixed-Time motion mode on or off. Ignored with NO_STANDARD_MOTION. * 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! + * V Flag to request version (Version 2+). (No reply = Version < 2) + * + * H Enable (1) or Disable (0) Axis Synchronization. + * + * Linear / Pressure Advance: + * + * P Enable (1) or Disable (0) Linear Advance pressure control + * + * Specifying Axes (for A,C,F,I,Q): + * + * X/Y/Z/E : Flag the axes (or core steppers) on which to apply the given parameters + * If none are given then XY is assumed. + * + * Compensator / Input Shaper: + * + * C Set Compensator Mode (Input Shaper) for the specified axes + * 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 @@ -170,252 +187,341 @@ void GcodeSuite::M493_report(const bool forReplay/*=true*/) { * 7: 3HEI : 3-Hump Extra-Intensive * 8: MZV : Mass-based Zero Vibration * - * P Enable (1) or Disable (0) Linear Advance pressure control + * A Set static/base frequency for the specified axes + * I Set damping ratio for the specified axes + * Q Set vibration tolerance (vtol) for the specified axes * - * K Set Linear Advance gain + * Dynamic Frequency Mode: * - * D Set Dynamic Frequency mode + * D Set Dynamic Frequency mode (for all axis compensators) * 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 + * F Set frequency scaling for the specified axes * - * 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() { + // Request version of FTM. (No response = Version < 2) + if (parser.seen('V') && !parser.has_value()) { + SERIAL_ECHOLNPGM("FTM V" STRINGIFY(FTM_VERSION)); + return; + } + struct { bool update:1, report:1; } flag = { false }; if (!parser.seen_any()) flag.report = true; - // Parse 'S' mode parameter. - if (parser.seen('S')) { - const bool active = parser.value_bool(); - if (active != ftMotion.cfg.active) { - stepper.ftMotion_syncPosition(); - ftMotion.cfg.active = active; + ft_config_t &c = ftMotion.cfg; + + #if HAS_STANDARD_MOTION + // Parse 'S' mode parameter. + if (parser.seen('S')) { + const bool active = parser.value_bool(); + if (active != c.active) { + ftMotion.toggle(); + flag.report = true; + } + } + #endif + + #if NUM_AXES_SHAPED > 0 + + const bool seenC = parser.seenval('C'); + const ftMotionShaper_t shaperVal = seenC ? (ftMotionShaper_t)parser.value_byte() : ftMotionShaper_NONE; + const bool goodShaper = WITHIN(shaperVal, ftMotionShaper_NONE, ftMotionShaper_MZV); + if (seenC && !goodShaper) { + SERIAL_ECHOLN(F("?Invalid "), F("(C)ompensator value. (0-"), int(ftMotionShaper_MZV)); + return; + } + auto set_shaper = [&](const AxisEnum axis, ftMotionShaper_t newsh) { + if (newsh != c.shaper[axis]) { + c.shaper[axis] = newsh; + flag.update = flag.report = true; + } + }; + if (seenC) { + #define _SET_SHAPER(A) set_shaper(_AXIS(A), shaperVal); + SHAPED_MAP(_SET_SHAPER); + } + + #endif // NUM_AXES_SHAPED > 0 + + // Parse 'H' Axis Synchronization parameter. + if (parser.seenval('H')) { + const bool enabled = parser.value_bool(); + if (enabled != c.axis_sync_enabled) { + c.axis_sync_enabled = enabled; flag.report = true; } } - #if HAS_X_AXIS - auto set_shaper = [&](const AxisEnum axis, const char c) { - const ftMotionShaper_t newsh = (ftMotionShaper_t)parser.value_byte(); - if (newsh != ftMotion.cfg.shaper[axis]) { - switch (newsh) { - default: SERIAL_ECHOLNPGM("?Invalid [", C(c), "] shaper."); return true; - case ftMotionShaper_NONE: - case ftMotionShaper_ZV: - case ftMotionShaper_ZVD: - case ftMotionShaper_ZVDD: - case ftMotionShaper_ZVDDD: - case ftMotionShaper_EI: - case ftMotionShaper_2HEI: - case ftMotionShaper_3HEI: - case ftMotionShaper_MZV: - ftMotion.cfg.shaper[axis] = newsh; - flag.update = flag.report = true; - break; - } - } - return false; - }; - - if (parser.seenval('X') && set_shaper(X_AXIS, 'X')) return; // Parse 'X' mode parameter - - #if HAS_Y_AXIS - if (parser.seenval('Y') && set_shaper(Y_AXIS, 'Y')) return; // Parse 'Y' mode parameter - #endif - - #endif // HAS_X_AXIS - - #if HAS_EXTRUDERS - - // Pressure control (linear advance) parameter. - if (parser.seen('P')) { - 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) { - ftMotion.cfg.linearAdvK = val; - flag.report = true; - } - else // Value out of range. - SERIAL_ECHOLNPGM("Linear Advance gain out of range."); - } - - #endif // HAS_EXTRUDERS - #if HAS_DYNAMIC_FREQ // Dynamic frequency mode parameter. if (parser.seenval('D')) { - if (AXIS_IS_SHAPING(X) || AXIS_IS_SHAPING(Y)) { - const dynFreqMode_t val = dynFreqMode_t(parser.value_byte()); - switch (val) { - #if HAS_DYNAMIC_FREQ_MM - case dynFreqMode_Z_BASED: - #endif - #if HAS_DYNAMIC_FREQ_G - case dynFreqMode_MASS_BASED: - #endif - case dynFreqMode_DISABLED: - ftMotion.cfg.dynFreqMode = val; - flag.report = true; - break; - default: - SERIAL_ECHOLNPGM("?Invalid Dynamic Frequency Mode [D] value."); - break; + if (AXIS_IS_SHAPING(X) || AXIS_IS_SHAPING(Y) || AXIS_IS_SHAPING(Z) || AXIS_IS_SHAPING(E)) { + switch (c.setDynFreqMode(parser.value_byte())) { + case 0: break; // Same value, no update + case 1: flag.report = true; break; // New value, updated + default: SERIAL_ECHOLN(F("?Invalid "), F("(D)ynamic Frequency Mode value.")); break; } } - else { - SERIAL_ECHOLNPGM("?Wrong shaper for [D] Dynamic Frequency mode."); - } + else + SERIAL_ECHOLNPGM("?Shaper required for (D)ynamic Frequency Mode ", c.dynFreqMode, "."); } - const bool modeUsesDynFreq = ( - TERN0(HAS_DYNAMIC_FREQ_MM, ftMotion.cfg.dynFreqMode == dynFreqMode_Z_BASED) - || TERN0(HAS_DYNAMIC_FREQ_G, ftMotion.cfg.dynFreqMode == dynFreqMode_MASS_BASED) - ); + const bool modeUsesDynFreq = c.modeUsesDynFreq(); #endif // HAS_DYNAMIC_FREQ + // Frequency parameter + const bool seenA = parser.seenval('A'); + const float baseFreqVal = seenA ? parser.value_float() : 0.0f; + const bool goodBaseFreq = seenA && c.goodBaseFreq(baseFreqVal); + if (seenA && !goodBaseFreq) + SERIAL_ECHOLN(F("?Invalid "), F("(A) Base Frequency value. ("), int(FTM_MIN_SHAPE_FREQ), C('-'), int((FTM_FS) / 2), C(')')); + + #if HAS_DYNAMIC_FREQ + // Dynamic Frequency parameter + const bool seenF = parser.seenval('F'); + const float baseDynFreqVal = seenF ? parser.value_float() : 0.0f; + if (seenF && !modeUsesDynFreq) + SERIAL_ECHOLNPGM("?Wrong mode for (F)requency scaling."); + #endif + + // Zeta parameter + const bool seenI = parser.seenval('I'); + const float zetaVal = seenI ? parser.value_float() : 0.0f; + const bool goodZeta = seenI && c.goodZeta(zetaVal); + if (seenI && !goodZeta) + SERIAL_ECHOLN(F("?Invalid "), F("(I) Zeta value. (0.01-1.0)")); // Zeta out of range + + #if HAS_FTM_EI_SHAPING + // Vibration Tolerance parameter + const bool seenQ = parser.seenval('Q'); + const float vtolVal = seenQ ? parser.value_float() : 0.0f; + const bool goodVtol = seenQ && c.goodVtol(vtolVal); + if (seenQ && !goodVtol) + SERIAL_ECHOLN(F("?Invalid "), F("(Q) Vibration Tolerance value. (0.0-1.0)")); // VTol out of range + #endif + + const bool apply_xy = !parser.seen("XYZE"); + #if HAS_X_AXIS - // Parse frequency parameter (X axis). - if (parser.seenval('A')) { - if (AXIS_IS_SHAPING(X)) { - const float val = parser.value_float(); - // TODO: Frequency minimum is dependent on the shaper used; the above check isn't always correct. - if (WITHIN(val, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2)) { - ftMotion.cfg.baseFreq.x = val; - flag.update = flag.report = true; - } - else // Frequency out of range. - SERIAL_ECHOLNPGM("Invalid [", C('A'), "] frequency value."); - } - else // Mode doesn't use frequency. - SERIAL_ECHOLNPGM("Wrong mode for [", C('A'), "] frequency."); - } + if (apply_xy || parser.seen_test('X')) { - #if HAS_DYNAMIC_FREQ - // Parse frequency scaling parameter (X axis). - if (parser.seenval('F')) { - if (modeUsesDynFreq) { - ftMotion.cfg.dynFreqK.x = parser.value_float(); + // Parse X frequency parameter + if (seenA) { + if (AXIS_IS_SHAPING(X)) { + // TODO: Frequency minimum is dependent on the shaper used; the above check isn't always correct. + if (goodBaseFreq) { + c.baseFreq.x = baseFreqVal; + flag.update = flag.report = true; + } + } + else // Mode doesn't use frequency. + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " (A) frequency."); + } + + #if HAS_DYNAMIC_FREQ + // Parse X frequency scaling parameter + if (seenF && modeUsesDynFreq) { + c.dynFreqK.x = baseDynFreqVal; flag.report = true; } - else - SERIAL_ECHOLNPGM("Wrong mode for [", C('F'), "] frequency scaling."); - } - #endif + #endif - // Parse zeta parameter (X axis). - 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; - flag.update = true; + // Parse X zeta parameter + if (seenI) { + if (AXIS_IS_SHAPING(X)) { + if (goodZeta) { + c.zeta.x = zetaVal; + flag.update = true; + } } else - SERIAL_ECHOLNPGM("Invalid X zeta [", C('I'), "] value."); // Zeta out of range. + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " (I) zeta parameter."); } - else - SERIAL_ECHOLNPGM("Wrong mode for zeta parameter."); - } - // Parse vtol parameter (X axis). - 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; - flag.update = true; + #if HAS_FTM_EI_SHAPING + // Parse X vtol parameter + if (seenQ) { + if (AXIS_IS_EISHAPING(X)) { + if (goodVtol) { + c.vtol.x = vtolVal; + flag.update = true; + } + } + else + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " (Q) vtol parameter."); } - else - SERIAL_ECHOLNPGM("Invalid X vtol [", C('Q'), "] value."); // VTol out of range. - } - else - SERIAL_ECHOLNPGM("Wrong mode for vtol parameter."); + #endif } #endif // HAS_X_AXIS #if HAS_Y_AXIS - // Parse frequency parameter (Y axis). - if (parser.seenval('B')) { - if (AXIS_IS_SHAPING(Y)) { - const float val = parser.value_float(); - if (WITHIN(val, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2)) { - ftMotion.cfg.baseFreq.y = val; - flag.update = flag.report = true; - } - else // Frequency out of range. - SERIAL_ECHOLNPGM("Invalid frequency [", C('B'), "] value."); - } - else // Mode doesn't use frequency. - SERIAL_ECHOLNPGM("Wrong mode for [", C('B'), "] frequency."); - } + if (apply_xy || parser.seen_test('Y')) { - #if HAS_DYNAMIC_FREQ - // Parse frequency scaling parameter (Y axis). - if (parser.seenval('H')) { - if (modeUsesDynFreq) { - ftMotion.cfg.dynFreqK.y = parser.value_float(); + // Parse Y frequency parameter + if (seenA) { + if (AXIS_IS_SHAPING(Y)) { + if (goodBaseFreq) { + c.baseFreq.y = baseFreqVal; + flag.update = flag.report = true; + } + } + else // Mode doesn't use frequency. + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " (A) frequency."); + } + + #if HAS_DYNAMIC_FREQ + // Parse Y frequency scaling parameter + if (seenF && modeUsesDynFreq) { + c.dynFreqK.y = baseDynFreqVal; flag.report = true; } - else - SERIAL_ECHOLNPGM("Wrong mode for [", C('H'), "] frequency scaling."); - } - #endif + #endif - // Parse zeta parameter (Y axis). - 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; - flag.update = true; + // Parse Y zeta parameter + if (seenI) { + if (AXIS_IS_SHAPING(Y)) { + if (goodZeta) { + c.zeta.y = zetaVal; + flag.update = true; + } } else - SERIAL_ECHOLNPGM("Invalid Y zeta [", C('J'), "] value."); // Zeta Out of range + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " (I) zeta parameter."); } - else - SERIAL_ECHOLNPGM("Wrong mode for zeta parameter."); - } - // Parse vtol parameter (Y axis). - 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; - flag.update = true; + // Parse Y vtol parameter + #if HAS_FTM_EI_SHAPING + if (seenQ) { + if (AXIS_IS_EISHAPING(Y)) { + if (goodVtol) { + c.vtol.y = vtolVal; + flag.update = true; + } + } + else + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " (Q) vtol parameter."); } - else - SERIAL_ECHOLNPGM("Invalid Y vtol [", C('R'), "] value."); // VTol out of range. - } - else - SERIAL_ECHOLNPGM("Wrong mode for vtol parameter."); + #endif } #endif // HAS_Y_AXIS + #if ENABLED(FTM_SHAPER_Z) + + if (parser.seen_test('Z')) { + + // Parse Z frequency parameter + if (seenA) { + if (AXIS_IS_SHAPING(Z)) { + if (goodBaseFreq) { + c.baseFreq.z = baseFreqVal; + flag.update = flag.report = true; + } + } + else // Mode doesn't use frequency. + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " (A) frequency."); + } + + #if HAS_DYNAMIC_FREQ + // Parse Z frequency scaling parameter + if (seenF && modeUsesDynFreq) { + c.dynFreqK.z = baseDynFreqVal; + flag.report = true; + } + #endif + + // Parse Z zeta parameter + if (seenI) { + if (AXIS_IS_SHAPING(Z)) { + if (goodZeta) { + c.zeta.z = zetaVal; + flag.update = true; + } + } + else + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " (I) zeta parameter."); + } + + // Parse Z vtol parameter + #if HAS_FTM_EI_SHAPING + if (seenQ) { + if (AXIS_IS_EISHAPING(Z)) { + if (goodVtol) { + c.vtol.z = vtolVal; + flag.update = true; + } + } + else + SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " (Q) vtol parameter."); + } + #endif + } + + #endif // FTM_SHAPER_Z + + #if ENABLED(FTM_SHAPER_E) + + if (parser.seen_test('E')) { + + // Parse E frequency parameter + if (seenA) { + if (AXIS_IS_SHAPING(E)) { + if (goodBaseFreq) { + c.baseFreq.e = baseFreqVal; + flag.update = flag.report = true; + } + } + else // Mode doesn't use frequency. + SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " (A) frequency."); + } + + #if HAS_DYNAMIC_FREQ + // Parse E frequency scaling parameter + if (seenF && modeUsesDynFreq) { + c.dynFreqK.e = baseDynFreqVal; + flag.report = true; + } + #endif + + // Parse E zeta parameter + if (seenI) { + if (AXIS_IS_SHAPING(E)) { + if (goodZeta) { + c.zeta.e = zetaVal; + flag.update = true; + } + } + else + SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " (I) zeta parameter."); + } + + // Parse E vtol parameter + #if HAS_FTM_EI_SHAPING + if (seenQ) { + if (AXIS_IS_EISHAPING(E)) { + if (goodVtol) { + c.vtol.e = vtolVal; + flag.update = true; + } + } + else + SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " (Q) vtol parameter."); + } + #endif + } + + #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..212a69c0a2 --- /dev/null +++ b/Marlin/src/gcode/feature/ft_motion/M494.cpp @@ -0,0 +1,130 @@ +/** + * 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" + +void say_ftm_settings() { + #if ANY(FTM_POLYS, FTM_SMOOTHING) + const ft_config_t &c = ftMotion.cfg; + #endif + + #if ENABLED(FTM_POLYS) + SERIAL_ECHOLN(F(" Trajectory: "), ftMotion.getTrajectoryName(), C('('), (uint8_t)ftMotion.getTrajectoryType(), C(')')); + if (ftMotion.getTrajectoryType() == TrajectoryType::POLY6) + SERIAL_ECHOLNPGM(" Poly6 Overshoot: ", p_float_t(c.poly6_acceleration_overshoot, 3)); + #endif + + #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 ENABLED(FTM_POLYS) + if (ftMotion.getTrajectoryType() == TrajectoryType::POLY6) + SERIAL_ECHOPGM(" O", c.poly6_acceleration_overshoot); + #endif + + 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