mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2025-12-29 19:00:37 -07:00
Merge branch 'bugfix-2.1.x' into bugfix-2.1.x-March3
This commit is contained in:
commit
d416686da7
268 changed files with 3936 additions and 1909 deletions
63
Makefile
63
Makefile
|
|
@ -4,6 +4,31 @@ CONTAINER_RT_OPTS := --rm -v $(PWD):/code -v platformio-cache:/root/.platformio
|
|||
CONTAINER_IMAGE := marlin-dev
|
||||
UNIT_TEST_CONFIG ?= default
|
||||
|
||||
# Find a Python 3 interpreter
|
||||
ifeq ($(OS),Windows_NT)
|
||||
# Windows: use `where` – fall back through the three common names
|
||||
PYTHON := $(shell where python 2>nul || where python3 2>nul || where py 2>nul)
|
||||
# Windows: Use cmd tools to find pins files
|
||||
PINS_RAW := $(shell cmd //c "dir /s /b Marlin\src\pins\*.h 2>nul | findstr /r ".*Marlin\\\\src\\\\pins\\\\.*\\\\pins_.*\.h"")
|
||||
PINS := $(subst \,/,$(PINS_RAW))
|
||||
else
|
||||
# POSIX: use `command -v` – prefer python3 over python
|
||||
PYTHON := $(shell command -v python3 2>/dev/null || command -v python 2>/dev/null)
|
||||
# Unix/Linux: Use find command
|
||||
PINS := $(shell find Marlin/src/pins -mindepth 2 -name 'pins_*.h')
|
||||
endif
|
||||
|
||||
# Check that the found interpreter is Python 3
|
||||
# Error if there's no Python 3 available
|
||||
ifneq ($(strip $(PYTHON)),)
|
||||
PYTHON_VERSION := $(shell $(PYTHON) -c "import sys; print(sys.version_info[0])" 2>/dev/null)
|
||||
ifneq ($(PYTHON_VERSION),3)
|
||||
$(error $(PYTHON) is not Python 3 – install a Python‑3.x interpreter or adjust your PATH)
|
||||
endif
|
||||
else
|
||||
$(error No Python executable found – install Python 3.x and make sure it is in your PATH)
|
||||
endif
|
||||
|
||||
help:
|
||||
@echo "Tasks for local development:"
|
||||
@echo "make marlin : Build Marlin for the configured board"
|
||||
|
|
@ -20,7 +45,7 @@ help:
|
|||
@echo "make unit-test-single-local-docker : Run unit tests for a single config locally, using docker"
|
||||
@echo "make unit-test-all-local : Run all code tests locally"
|
||||
@echo "make unit-test-all-local-docker : Run all code tests locally, using docker"
|
||||
@echo "make setup-local-docker : Setup local docker using buildx"
|
||||
@echo "make setup-local-docker : Setup local docker"
|
||||
@echo ""
|
||||
@echo "Options for testing:"
|
||||
@echo " TEST_TARGET Set when running tests-single-*, to select the"
|
||||
|
|
@ -57,10 +82,10 @@ tests-single-local-docker:
|
|||
$(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) make tests-single-local TEST_TARGET=$(TEST_TARGET) VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD) ONLY_TEST="$(ONLY_TEST)"
|
||||
|
||||
tests-all-local:
|
||||
@python -c "import yaml" 2>/dev/null || (echo 'pyyaml module is not installed. Install it with "python -m pip install pyyaml"' && exit 1)
|
||||
@$(PYTHON) -c "import yaml" 2>/dev/null || (echo 'pyyaml module is not installed. Install it with "$(PYTHON) -m pip install pyyaml"' && exit 1)
|
||||
export PATH="./buildroot/bin/:./buildroot/tests/:${PATH}" \
|
||||
&& export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \
|
||||
&& for TEST_TARGET in $$(python $(SCRIPTS_DIR)/get_test_targets.py) ; do \
|
||||
&& for TEST_TARGET in $$($(PYTHON) $(SCRIPTS_DIR)/get_test_targets.py) ; do \
|
||||
if [ "$$TEST_TARGET" = "linux_native" ] && [ "$$(uname)" = "Darwin" ]; then \
|
||||
echo "Skipping tests for $$TEST_TARGET on macOS" ; \
|
||||
continue ; \
|
||||
|
|
@ -88,18 +113,36 @@ unit-test-all-local-docker:
|
|||
@if ! $(CONTAINER_RT_BIN) images -q $(CONTAINER_IMAGE) > /dev/null ; then $(MAKE) setup-local-docker ; fi
|
||||
$(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) make unit-test-all-local
|
||||
|
||||
setup-local-docker:
|
||||
$(CONTAINER_RT_BIN) buildx build -t $(CONTAINER_IMAGE) -f docker/Dockerfile .
|
||||
USERNAME := $(shell whoami)
|
||||
USER_ID := $(shell id -u)
|
||||
GROUP_ID := $(shell id -g)
|
||||
|
||||
PINS := $(shell find Marlin/src/pins -mindepth 2 -name '*.h')
|
||||
.PHONY: setup-local-docker setup-local-docker-old
|
||||
|
||||
setup-local-docker:
|
||||
@echo "Building marlin-dev Docker image..."
|
||||
$(CONTAINER_RT_BIN) build -t $(CONTAINER_IMAGE) \
|
||||
--build-arg USERNAME=$(USERNAME) \
|
||||
--build-arg USER_ID=$(USER_ID) \
|
||||
--build-arg GROUP_ID=$(GROUP_ID) \
|
||||
-f docker/Dockerfile .
|
||||
@echo
|
||||
@echo "To run all tests in Docker:"
|
||||
@echo " make tests-all-local-docker"
|
||||
@echo "To run a single test in Docker:"
|
||||
@echo " make tests-single-local-docker TEST_TARGET=mega2560"
|
||||
|
||||
setup-local-docker-old:
|
||||
$(CONTAINER_RT_BIN) buildx build -t $(CONTAINER_IMAGE) -f docker/Dockerfile .
|
||||
|
||||
.PHONY: $(PINS) format-pins validate-pins
|
||||
|
||||
$(PINS): %:
|
||||
@echo "Formatting pins $@"
|
||||
@python $(SCRIPTS_DIR)/pinsformat.py $< $@
|
||||
@$(PYTHON) $(SCRIPTS_DIR)/pinsformat.py $< $@
|
||||
|
||||
format-pins: $(PINS)
|
||||
@echo "Processed $(words $(PINS)) pins files"
|
||||
|
||||
validate-pins: format-pins
|
||||
@echo "Validating pins files"
|
||||
|
|
@ -109,8 +152,8 @@ validate-pins: format-pins
|
|||
|
||||
format-lines:
|
||||
@echo "Formatting all sources"
|
||||
@python $(SCRIPTS_DIR)/linesformat.py buildroot
|
||||
@python $(SCRIPTS_DIR)/linesformat.py Marlin
|
||||
@$(PYTHON) $(SCRIPTS_DIR)/linesformat.py buildroot
|
||||
@$(PYTHON) $(SCRIPTS_DIR)/linesformat.py Marlin
|
||||
|
||||
validate-lines:
|
||||
@echo "Validating text formatting"
|
||||
|
|
@ -122,4 +165,4 @@ BOARDS_FILE := Marlin/src/core/boards.h
|
|||
|
||||
validate-boards:
|
||||
@echo "Validating boards.h file"
|
||||
@python $(SCRIPTS_DIR)/validate_boards.py $(BOARDS_FILE) || (echo "\nError: boards.h file is not valid. Please check and correct it.\n" && exit 1)
|
||||
@$(PYTHON) $(SCRIPTS_DIR)/validate_boards.py $(BOARDS_FILE) || (echo "\nError: boards.h file is not valid. Please check and correct it.\n" && exit 1)
|
||||
|
|
|
|||
|
|
@ -942,7 +942,7 @@
|
|||
* protect against a broken or disconnected thermistor wire.
|
||||
*
|
||||
* The issue: If a thermistor falls out, it will report the much lower
|
||||
* temperature of the air in the room, and the the firmware will keep
|
||||
* temperature of the air in the room, and the firmware will keep
|
||||
* the heater on.
|
||||
*
|
||||
* If you get "Thermal Runaway" or "Heating failed" errors the
|
||||
|
|
@ -3468,6 +3468,7 @@
|
|||
* NOTOSANS - Default font with anti-aliasing. Supports Latin Extended and non-Latin characters.
|
||||
* UNIFONT - Lightweight font, no anti-aliasing. Supports Latin Extended and non-Latin characters.
|
||||
* HELVETICA - Lightweight font, no anti-aliasing. Supports Basic Latin (0x0020-0x007F) and Latin-1 Supplement (0x0080-0x00FF) characters only.
|
||||
* :['NOTOSANS', 'UNIFONT', 'HELVETICA']
|
||||
*/
|
||||
#define TFT_FONT NOTOSANS
|
||||
|
||||
|
|
@ -3477,6 +3478,7 @@
|
|||
* BLUE_MARLIN - Default theme with 'midnight blue' background
|
||||
* BLACK_MARLIN - Theme with 'black' background
|
||||
* ANET_BLACK - Theme used for Anet ET4/5
|
||||
* :['BLUE_MARLIN', 'BLACK_MARLIN', 'ANET_BLACK']
|
||||
*/
|
||||
#define TFT_THEME BLACK_MARLIN
|
||||
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@
|
|||
* protect against a broken or disconnected thermistor wire.
|
||||
*
|
||||
* The issue: If a thermistor falls out, it will report the much lower
|
||||
* temperature of the air in the room, and the the firmware will keep
|
||||
* temperature of the air in the room, and the firmware will keep
|
||||
* the heater on.
|
||||
*
|
||||
* The solution: Once the temperature reaches the target, start observing.
|
||||
|
|
@ -778,7 +778,7 @@
|
|||
|
||||
// @section endstops
|
||||
|
||||
// If you want endstops to stay on (by default) even when not homing
|
||||
// If you want endstops to stay on (by default) even when not homing,
|
||||
// enable this option. Override at any time with M120, M121.
|
||||
//#define ENDSTOPS_ALWAYS_ON_DEFAULT
|
||||
|
||||
|
|
@ -1143,49 +1143,83 @@
|
|||
|
||||
/**
|
||||
* Fixed-time-based Motion Control -- BETA FEATURE
|
||||
* Enable/disable and set parameters with G-code M493.
|
||||
* Enable/disable and set parameters with G-code M493 and M494.
|
||||
* See ft_types.h for named values used by FTM options.
|
||||
*/
|
||||
//#define FT_MOTION
|
||||
#if ENABLED(FT_MOTION)
|
||||
//#define FTM_IS_DEFAULT_MOTION // Use FT Motion as the factory default?
|
||||
//#define FTM_IS_DEFAULT_MOTION // Use FT Motion as the factory default?
|
||||
//#define FT_MOTION_MENU // Provide a MarlinUI menu to set M493 and M494 parameters
|
||||
//#define FTM_HOME_AND_PROBE // Use FT Motion for homing / probing. Disable if FT Motion breaks these functions.
|
||||
|
||||
#define FTM_DEFAULT_DYNFREQ_MODE dynFreqMode_DISABLED // Default mode of dynamic frequency calculation. (DISABLED, Z_BASED, MASS_BASED)
|
||||
|
||||
#define FTM_LINEAR_ADV_DEFAULT_ENA false // Default linear advance enable (true) or disable (false)
|
||||
#define FTM_LINEAR_ADV_DEFAULT_K 0.0f // Default linear advance gain. (Acceleration-based scaling factor.)
|
||||
#define FTM_LINEAR_ADV_DEFAULT_ENA false // Default linear advance enable (true) or disable (false)
|
||||
#define FTM_LINEAR_ADV_DEFAULT_K 0.0f // Default linear advance gain. (Acceleration-based scaling factor.)
|
||||
|
||||
#define FTM_DEFAULT_SHAPER_X ftMotionShaper_NONE // Default shaper mode on X axis (NONE, ZV, ZVD, ZVDD, ZVDDD, EI, 2HEI, 3HEI, MZV)
|
||||
#define FTM_SHAPING_DEFAULT_FREQ_X 37.0f // (Hz) Default peak frequency used by input shapers
|
||||
#define FTM_SHAPING_ZETA_X 0.1f // Zeta used by input shapers for X axis
|
||||
#define FTM_SHAPING_V_TOL_X 0.05f // Vibration tolerance used by EI input shapers for X axis
|
||||
#define FTM_SHAPING_DEFAULT_FREQ_X 37.0f // (Hz) Default peak frequency used by input shapers
|
||||
#define FTM_SHAPING_ZETA_X 0.1f // Zeta used by input shapers for X axis
|
||||
#define FTM_SHAPING_V_TOL_X 0.05f // Vibration tolerance used by EI input shapers for X axis
|
||||
|
||||
#define FTM_DEFAULT_SHAPER_Y ftMotionShaper_NONE // Default shaper mode on Y axis
|
||||
#define FTM_SHAPING_DEFAULT_FREQ_Y 37.0f // (Hz) Default peak frequency used by input shapers
|
||||
#define FTM_SHAPING_ZETA_Y 0.1f // Zeta used by input shapers for Y axis
|
||||
#define FTM_SHAPING_V_TOL_Y 0.05f // Vibration tolerance used by EI input shapers for Y axis
|
||||
#define FTM_SHAPING_DEFAULT_FREQ_Y 37.0f // (Hz) Default peak frequency used by input shapers
|
||||
#define FTM_SHAPING_ZETA_Y 0.1f // Zeta used by input shapers for Y axis
|
||||
#define FTM_SHAPING_V_TOL_Y 0.05f // Vibration tolerance used by EI input shapers for Y axis
|
||||
|
||||
//#define FT_MOTION_MENU // Provide a MarlinUI menu to set M493 parameters
|
||||
//#define FTM_SHAPER_Z // Include Z shaping support
|
||||
#define FTM_DEFAULT_SHAPER_Z ftMotionShaper_NONE // Default shaper mode on Z axis
|
||||
#define FTM_SHAPING_DEFAULT_FREQ_Z 21.0f // (Hz) Default peak frequency used by input shapers
|
||||
#define FTM_SHAPING_ZETA_Z 0.03f // Zeta used by input shapers for Z axis
|
||||
#define FTM_SHAPING_V_TOL_Z 0.05f // Vibration tolerance used by EI input shapers for Z axis
|
||||
|
||||
//#define FTM_SHAPER_E // Include E shaping support
|
||||
// Required to synchronize extruder with XYZ (better quality)
|
||||
#define FTM_DEFAULT_SHAPER_E ftMotionShaper_NONE // Default shaper mode on Extruder axis
|
||||
#define FTM_SHAPING_DEFAULT_FREQ_E 21.0f // (Hz) Default peak frequency used by input shapers
|
||||
#define FTM_SHAPING_ZETA_E 0.03f // Zeta used by input shapers for E axis
|
||||
#define FTM_SHAPING_V_TOL_E 0.05f // Vibration tolerance used by EI input shapers for E axis
|
||||
|
||||
//#define FTM_SMOOTHING // Smoothing can reduce artifacts and make steppers quieter
|
||||
// on sharp corners, but too much will round corners.
|
||||
#if ENABLED(FTM_SMOOTHING)
|
||||
#define FTM_MAX_SMOOTHING_TIME 0.10f // (s) Maximum smoothing time. Higher values consume more RAM.
|
||||
// Increase smoothing time to reduce jerky motion, ghosting and noises.
|
||||
#define FTM_SMOOTHING_TIME_X 0.00f // (s) Smoothing time for X axis. Zero means disabled.
|
||||
#define FTM_SMOOTHING_TIME_Y 0.00f // (s) Smoothing time for Y axis
|
||||
#define FTM_SMOOTHING_TIME_Z 0.00f // (s) Smoothing time for Z axis
|
||||
#define FTM_SMOOTHING_TIME_E 0.02f // (s) Smoothing time for E axis. Prevents noise/skipping from LA by
|
||||
// smoothing acceleration peaks, which may also smooth curved surfaces.
|
||||
#endif
|
||||
|
||||
#define FTM_TRAJECTORY_TYPE TRAPEZOIDAL // Block acceleration profile (TRAPEZOIDAL, POLY5, POLY6)
|
||||
// TRAPEZOIDAL: Continuous Velocity. Max acceleration is respected.
|
||||
// POLY5: Like POLY6 with 1.5x but cpu cheaper.
|
||||
// POLY6: Continuous Acceleration (aka S_CURVE).
|
||||
// POLY trajectories not only reduce resonances without rounding corners, but also
|
||||
// reduce extruder strain due to linear advance.
|
||||
|
||||
#define FTM_POLY6_ACCELERATION_OVERSHOOT 1.875f // Max acceleration overshoot factor for POLY6 (1.25 to 1.875)
|
||||
|
||||
/**
|
||||
* Advanced configuration
|
||||
*/
|
||||
#define FTM_UNIFIED_BWS // DON'T DISABLE unless you use Ulendo FBS (not implemented)
|
||||
#define FTM_UNIFIED_BWS // DON'T DISABLE unless you use Ulendo FBS (not implemented)
|
||||
#if ENABLED(FTM_UNIFIED_BWS)
|
||||
#define FTM_BW_SIZE 100 // Unified Window and Batch size with a ratio of 2
|
||||
#define FTM_BW_SIZE 100 // Unified Window and Batch size with a ratio of 2
|
||||
#else
|
||||
#define FTM_WINDOW_SIZE 200 // Custom Window size for trajectory generation needed by Ulendo FBS
|
||||
#define FTM_BATCH_SIZE 100 // Custom Batch size for trajectory generation needed by Ulendo FBS
|
||||
#define FTM_WINDOW_SIZE 200 // Custom Window size for trajectory generation needed by Ulendo FBS
|
||||
#define FTM_BATCH_SIZE 100 // Custom Batch size for trajectory generation needed by Ulendo FBS
|
||||
#endif
|
||||
|
||||
#define FTM_FS 1000 // (Hz) Frequency for trajectory generation. (Reciprocal of FTM_TS)
|
||||
#define FTM_TS 0.001f // (s) Time step for trajectory generation. (Reciprocal of FTM_FS)
|
||||
#define FTM_FS 1000 // (Hz) Frequency for trajectory generation. (Reciprocal of FTM_TS)
|
||||
|
||||
#if DISABLED(COREXY)
|
||||
#define FTM_STEPPER_FS 20000 // (Hz) Frequency for stepper I/O update
|
||||
#define FTM_STEPPER_FS 20000 // (Hz) Frequency for stepper I/O update
|
||||
|
||||
// Use this to adjust the time required to consume the command buffer.
|
||||
// Try increasing this value if stepper motion is choppy.
|
||||
#define FTM_STEPPERCMD_BUFF_SIZE 3000 // Size of the stepper command buffers
|
||||
#define FTM_STEPPERCMD_BUFF_SIZE 3000 // Size of the stepper command buffers
|
||||
|
||||
#else
|
||||
// CoreXY motion needs a larger buffer size. These values are based on our testing.
|
||||
|
|
@ -1193,17 +1227,7 @@
|
|||
#define FTM_STEPPERCMD_BUFF_SIZE 6000
|
||||
#endif
|
||||
|
||||
#define FTM_STEPS_PER_UNIT_TIME (FTM_STEPPER_FS / FTM_FS) // Interpolated stepper commands per unit time
|
||||
#define FTM_MIN_TICKS ((STEPPER_TIMER_RATE) / (FTM_STEPPER_FS)) // Minimum stepper ticks between steps
|
||||
|
||||
#define FTM_MIN_SHAPE_FREQ 10 // Minimum shaping frequency
|
||||
#define FTM_RATIO (FTM_FS / FTM_MIN_SHAPE_FREQ) // Factor for use in FTM_ZMAX. DON'T CHANGE.
|
||||
#define FTM_ZMAX (FTM_RATIO * 2) // Maximum delays for shaping functions (even numbers only!)
|
||||
// Calculate as:
|
||||
// ZV : FTM_RATIO / 2
|
||||
// ZVD, MZV : FTM_RATIO
|
||||
// 2HEI : FTM_RATIO * 3 / 2
|
||||
// 3HEI : FTM_RATIO * 2
|
||||
#define FTM_MIN_SHAPE_FREQ 10 // (Hz) Minimum shaping frequency, lower consumes more RAM
|
||||
#endif // FT_MOTION
|
||||
|
||||
/**
|
||||
|
|
@ -1853,6 +1877,7 @@
|
|||
#define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
|
||||
#define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting.
|
||||
// Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
|
||||
#define SDSORT_QUICK true // Use Quick Sort as a sorting algorithm. Otherwise use Bubble Sort.
|
||||
#endif
|
||||
|
||||
// Allow international symbols in long filenames. To display correctly, the
|
||||
|
|
@ -4261,7 +4286,7 @@
|
|||
//#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper
|
||||
// steps per full revolution (motor steps/rev * microstepping)
|
||||
//#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel.
|
||||
#define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_MICROSTEP // Type of error error correction.
|
||||
#define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_MICROSTEP // Type of error correction.
|
||||
#define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the
|
||||
// printer will attempt to correct the error; errors
|
||||
// smaller than this are ignored to minimize effects of
|
||||
|
|
@ -4693,6 +4718,11 @@
|
|||
//
|
||||
//#define PINS_DEBUGGING
|
||||
|
||||
//
|
||||
// M265 - I2C Scanner
|
||||
//
|
||||
//#define I2C_SCANNER
|
||||
|
||||
// Enable Tests that will run at startup and produce a report
|
||||
//#define MARLIN_TEST_BUILD
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
* here we define this default string as the date where the latest release
|
||||
* version was tagged.
|
||||
*/
|
||||
//#define STRING_DISTRIBUTION_DATE "2025-09-15"
|
||||
//#define STRING_DISTRIBUTION_DATE "2025-10-19"
|
||||
|
||||
/**
|
||||
* The protocol for communication to the host. Protocol indicates communication
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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__
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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__
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -132,6 +132,9 @@ void TFT_FSMC::init() {
|
|||
DMAtx.Init.Priority = DMA_PRIORITY_HIGH;
|
||||
|
||||
LCD = (LCD_CONTROLLER_TypeDef *)controllerAddress;
|
||||
|
||||
DMAtx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
HAL_DMA_Init(&DMAtx);
|
||||
}
|
||||
|
||||
uint32_t TFT_FSMC::getID() {
|
||||
|
|
@ -179,15 +182,19 @@ void TFT_FSMC::abort() {
|
|||
}
|
||||
|
||||
void TFT_FSMC::transmitDMA(uint32_t memoryIncrease, uint16_t *data, uint16_t count) {
|
||||
DMAtx.Init.PeriphInc = memoryIncrease;
|
||||
HAL_DMA_Init(&DMAtx);
|
||||
if (DMAtx.Init.PeriphInc != memoryIncrease) {
|
||||
DMAtx.Init.PeriphInc = memoryIncrease;
|
||||
HAL_DMA_Init(&DMAtx);
|
||||
}
|
||||
HAL_DMA_Start(&DMAtx, (uint32_t)data, (uint32_t)&(LCD->RAM), count);
|
||||
TERN_(TFT_SHARED_IO, while (isBusy()));
|
||||
}
|
||||
|
||||
void TFT_FSMC::transmit(uint32_t memoryIncrease, uint16_t *data, uint16_t count) {
|
||||
DMAtx.Init.PeriphInc = memoryIncrease;
|
||||
HAL_DMA_Init(&DMAtx);
|
||||
if (DMAtx.Init.PeriphInc != memoryIncrease) {
|
||||
DMAtx.Init.PeriphInc = memoryIncrease;
|
||||
HAL_DMA_Init(&DMAtx);
|
||||
}
|
||||
dataTransferBegin();
|
||||
HAL_DMA_Start(&DMAtx, (uint32_t)data, (uint32_t)&(LCD->RAM), count);
|
||||
HAL_DMA_PollForTransfer(&DMAtx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
194
Marlin/src/HAL/STM32/u8g/u8g_com_stm32duino_ssd_i2c.cpp
Normal file
194
Marlin/src/HAL/STM32/u8g/u8g_com_stm32duino_ssd_i2c.cpp
Normal file
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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 <U8glib-HAL.h>
|
||||
|
||||
#if ENABLED(U8G_USES_HW_I2C)
|
||||
#include <Wire.h>
|
||||
#ifndef MASTER_ADDRESS
|
||||
#define MASTER_ADDRESS 0x01
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ENABLED(U8G_USES_SW_I2C)
|
||||
#include <SlowSoftI2CMaster.h>
|
||||
#include <SlowSoftWire.h>
|
||||
#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
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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__ (
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "macros.h"
|
||||
|
||||
#define BOARD_ERROR -2
|
||||
#define BOARD_UNKNOWN -1
|
||||
|
||||
//
|
||||
|
|
@ -175,16 +176,17 @@
|
|||
#define BOARD_GT2560_V41B 1322 // Geeetech GT2560 V4.1B for A10(M/T/D)
|
||||
#define BOARD_EINSTART_S 1323 // Einstart retrofit
|
||||
#define BOARD_WANHAO_ONEPLUS 1324 // Wanhao 0ne+ i3 Mini
|
||||
#define BOARD_OVERLORD 1325 // Overlord/Overlord Pro
|
||||
#define BOARD_HJC2560C_REV1 1326 // ADIMLab Gantry v1
|
||||
#define BOARD_HJC2560C_REV2 1327 // ADIMLab Gantry v2
|
||||
#define BOARD_LEAPFROG_XEED2015 1328 // Leapfrog Xeed 2015
|
||||
#define BOARD_PICA_REVB 1329 // PICA Shield (original version)
|
||||
#define BOARD_PICA 1330 // PICA Shield (rev C or later)
|
||||
#define BOARD_INTAMSYS40 1331 // Intamsys 4.0 (Funmat HT)
|
||||
#define BOARD_MALYAN_M180 1332 // Malyan M180 Mainboard Version 2 (no display function, direct G-code only)
|
||||
#define BOARD_PROTONEER_CNC_SHIELD_V3 1333 // Mega controller & Protoneer CNC Shield V3.00
|
||||
#define BOARD_WEEDO_62A 1334 // WEEDO 62A board (TINA2, Monoprice Cadet, etc.)
|
||||
#define BOARD_WANHAO_D9 1325 // Wanhao D9 MK2
|
||||
#define BOARD_OVERLORD 1326 // Overlord/Overlord Pro
|
||||
#define BOARD_HJC2560C_REV1 1327 // ADIMLab Gantry v1
|
||||
#define BOARD_HJC2560C_REV2 1328 // ADIMLab Gantry v2
|
||||
#define BOARD_LEAPFROG_XEED2015 1329 // Leapfrog Xeed 2015
|
||||
#define BOARD_PICA_REVB 1330 // PICA Shield (original version)
|
||||
#define BOARD_PICA 1331 // PICA Shield (rev C or later)
|
||||
#define BOARD_INTAMSYS40 1332 // Intamsys 4.0 (Funmat HT)
|
||||
#define BOARD_MALYAN_M180 1333 // Malyan M180 Mainboard Version 2 (no display function, direct G-code only)
|
||||
#define BOARD_PROTONEER_CNC_SHIELD_V3 1334 // Mega controller & Protoneer CNC Shield V3.00
|
||||
#define BOARD_WEEDO_62A 1335 // WEEDO 62A board (TINA2, Monoprice Cadet, etc.)
|
||||
|
||||
//
|
||||
// ATmega1281, ATmega2561
|
||||
|
|
|
|||
|
|
@ -358,6 +358,21 @@
|
|||
#define STR_Z2 STR_C "2"
|
||||
#define STR_Z3 STR_C "3"
|
||||
#define STR_Z4 STR_C "4"
|
||||
#if CORE_IS_XY || CORE_IS_XZ
|
||||
#define STEPPER_A_NAME 'A'
|
||||
#else
|
||||
#define STEPPER_A_NAME 'X'
|
||||
#endif
|
||||
#if CORE_IS_XY || CORE_IS_YZ
|
||||
#define STEPPER_B_NAME 'B'
|
||||
#else
|
||||
#define STEPPER_B_NAME 'Y'
|
||||
#endif
|
||||
#if CORE_IS_XZ || CORE_IS_YZ
|
||||
#define STEPPER_C_NAME 'C'
|
||||
#else
|
||||
#define STEPPER_C_NAME 'Z'
|
||||
#endif
|
||||
|
||||
//
|
||||
// Endstop Names used by Endstops::report_states
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
// Macros to make a string from a macro
|
||||
#define STRINGIFY_(M) #M
|
||||
#define STRINGIFY(M) STRINGIFY_(M)
|
||||
#define CHARIFY(M) STRINGIFY(M)[0]
|
||||
|
||||
#define A(CODE) " " CODE "\n\t"
|
||||
#define L(CODE) CODE ":\n\t"
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,6 +167,21 @@ template <class L, class R> struct IF<true, L, R> { typedef L type; };
|
|||
#define GANG_ITEM_E(N)
|
||||
#endif
|
||||
|
||||
// Emitters for code that only cares about XYZE and not IJKUVW
|
||||
#define CARTES_COUNT TERN(HAS_EXTRUDERS, INCREMENT(XYZ_COUNT), XYZ_COUNT)
|
||||
#define CARTES_LIST(x,y,z,e) XYZ_LIST(x,y,z) LIST_ITEM_E(e)
|
||||
#define CARTES_PAIRED_LIST(V...) LIST_N(DOUBLE(CARTES_COUNT), V)
|
||||
#define CARTES_ARRAY(x,y,z,e) { CARTES_LIST(x,y,z,e) }
|
||||
#define CARTES_CODE(x,y,z,e) XYZ_CODE(x,y,z) CODE_ITEM_E(e)
|
||||
#define CARTES_GANG(x,y,z,e) XYZ_GANG(x,y,z) GANG_ITEM_E(e)
|
||||
#define CARTES_AXIS_NAMES CARTES_LIST(X,Y,Z,E)
|
||||
#define CARTES_MAP(F) MAP(F, CARTES_AXIS_NAMES)
|
||||
#if CARTES_COUNT
|
||||
#define CARTES_COMMA ,
|
||||
#else
|
||||
#define CARTES_COMMA
|
||||
#endif
|
||||
|
||||
#define AXIS_COLLISION(L) (AXIS4_NAME == L || AXIS5_NAME == L || AXIS6_NAME == L || AXIS7_NAME == L || AXIS8_NAME == L || AXIS9_NAME == L)
|
||||
|
||||
// Helpers
|
||||
|
|
@ -363,17 +378,6 @@ typedef uint16_t raw_adc_t;
|
|||
typedef int16_t celsius_t;
|
||||
typedef float celsius_float_t;
|
||||
|
||||
//
|
||||
// On AVR pointers are only 2 bytes so use 'const float &' for 'const float'
|
||||
//
|
||||
#ifdef __AVR__
|
||||
typedef const float & const_float_t;
|
||||
#else
|
||||
typedef const float const_float_t;
|
||||
#endif
|
||||
typedef const_float_t const_feedRate_t;
|
||||
typedef const_float_t const_celsius_float_t;
|
||||
|
||||
// Type large enough to count leveling grid points
|
||||
typedef IF<TERN0(ABL_USES_GRID, (GRID_MAX_POINTS > 255)), uint16_t, uint8_t>::type grid_count_t;
|
||||
|
||||
|
|
@ -382,7 +386,7 @@ typedef IF<TERN0(ABL_USES_GRID, (GRID_MAX_POINTS > 255)), uint16_t, uint8_t>::ty
|
|||
#define MMS_TO_MMM(MM_S) (static_cast<float>(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
|
||||
|
|
|
|||
|
|
@ -54,12 +54,12 @@ void Babystep::step_axis(const AxisEnum axis) {
|
|||
}
|
||||
}
|
||||
|
||||
void Babystep::add_mm(const AxisEnum axis, const_float_t mm) {
|
||||
void Babystep::add_mm(const AxisEnum axis, const float mm) {
|
||||
add_steps(axis, mm * planner.settings.axis_steps_per_mm[axis]);
|
||||
}
|
||||
|
||||
#if ENABLED(BD_SENSOR)
|
||||
void Babystep::set_mm(const AxisEnum axis, const_float_t mm) {
|
||||
void Babystep::set_mm(const AxisEnum axis, const float mm) {
|
||||
//if (DISABLED(BABYSTEP_WITHOUT_HOMING) && axis_should_home(axis)) return;
|
||||
const int16_t distance = mm * planner.settings.axis_steps_per_mm[axis];
|
||||
accum = distance; // Count up babysteps for the UI
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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) };
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ void unified_bed_leveling::invalidate() {
|
|||
set_all_mesh_points_to_value(NAN);
|
||||
}
|
||||
|
||||
void unified_bed_leveling::set_all_mesh_points_to_value(const_float_t value) {
|
||||
void unified_bed_leveling::set_all_mesh_points_to_value(const float value) {
|
||||
GRID_LOOP(x, y) {
|
||||
z_values[x][y] = value;
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, value));
|
||||
|
|
@ -115,7 +115,7 @@ void unified_bed_leveling::set_all_mesh_points_to_value(const_float_t value) {
|
|||
constexpr int16_t Z_STEPS_NAN = INT16_MAX;
|
||||
|
||||
void unified_bed_leveling::set_store_from_mesh(const bed_mesh_t &in_values, mesh_store_t &stored_values) {
|
||||
auto z_to_store = [](const_float_t z) {
|
||||
auto z_to_store = [](const float z) {
|
||||
if (isnan(z)) return Z_STEPS_NAN;
|
||||
const int32_t z_scaled = TRUNC(z * mesh_store_scaling);
|
||||
if (z_scaled == Z_STEPS_NAN || !WITHIN(z_scaled, INT16_MIN, INT16_MAX))
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
#include "../hilbert_curve.h"
|
||||
#endif
|
||||
|
||||
#if FT_MOTION_DISABLE_FOR_PROBING
|
||||
#if ENABLED(FT_MOTION)
|
||||
#include "../../../module/ft_motion.h"
|
||||
#endif
|
||||
|
||||
|
|
@ -313,9 +313,8 @@ void unified_bed_leveling::G29() {
|
|||
const uint8_t p_val = parser.byteval('P');
|
||||
const bool may_move = p_val == 1 || p_val == 2 || p_val == 4 || parser.seen_test('J');
|
||||
|
||||
#if FT_MOTION_DISABLE_FOR_PROBING
|
||||
FTMotionDisableInScope FT_Disabler; // Disable Fixed-Time Motion for probing
|
||||
#endif
|
||||
// Potentially disable Fixed-Time Motion for probing
|
||||
TERN_(FT_MOTION, FTMotionDisableInScope FT_Disabler);
|
||||
|
||||
// Check for commands that require the printer to be homed
|
||||
if (may_move) {
|
||||
|
|
@ -612,7 +611,7 @@ void unified_bed_leveling::G29() {
|
|||
|
||||
case 5: adjust_mesh_to_mean(param.C_seen, param.C_constant); break;
|
||||
|
||||
case 6: shift_mesh_height(); break;
|
||||
case 6: shift_mesh_height(param.C_constant); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -716,7 +715,7 @@ void unified_bed_leveling::G29() {
|
|||
* G29 P5 C<value> : Adjust Mesh To Mean (and subtract the given offset).
|
||||
* Find the mean average and shift the mesh to center on that value.
|
||||
*/
|
||||
void unified_bed_leveling::adjust_mesh_to_mean(const bool cflag, const_float_t offset) {
|
||||
void unified_bed_leveling::adjust_mesh_to_mean(const bool cflag, const float offset) {
|
||||
float sum = 0;
|
||||
uint8_t n = 0;
|
||||
GRID_LOOP(x, y)
|
||||
|
|
@ -752,10 +751,10 @@ void unified_bed_leveling::adjust_mesh_to_mean(const bool cflag, const_float_t o
|
|||
/**
|
||||
* G29 P6 C<offset> : Shift Mesh Height by a uniform constant.
|
||||
*/
|
||||
void unified_bed_leveling::shift_mesh_height() {
|
||||
void unified_bed_leveling::shift_mesh_height(const float zoffs) {
|
||||
GRID_LOOP(x, y)
|
||||
if (!isnan(z_values[x][y])) {
|
||||
z_values[x][y] += param.C_constant;
|
||||
z_values[x][y] += zoffs;
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y]));
|
||||
}
|
||||
}
|
||||
|
|
@ -782,7 +781,7 @@ void unified_bed_leveling::shift_mesh_height() {
|
|||
|
||||
const grid_count_t point_num = (GRID_MAX_POINTS - count) + 1;
|
||||
SERIAL_ECHOLNPGM("Probing mesh point ", point_num, "/", GRID_MAX_POINTS, ".");
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT_F(MSG_PROBING_POINT), point_num, int(GRID_MAX_POINTS)));
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), point_num, int(GRID_MAX_POINTS)));
|
||||
TERN_(HAS_BACKLIGHT_TIMEOUT, ui.refresh_backlight_timeout());
|
||||
|
||||
#if HAS_MARLINUI_MENU
|
||||
|
|
@ -870,7 +869,7 @@ void set_message_with_feedback(FSTR_P const fstr) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void unified_bed_leveling::move_z_with_encoder(const_float_t multiplier) {
|
||||
void unified_bed_leveling::move_z_with_encoder(const float multiplier) {
|
||||
ui.wait_for_release();
|
||||
while (!ui.button_pressed()) {
|
||||
idle();
|
||||
|
|
@ -953,7 +952,7 @@ void set_message_with_feedback(FSTR_P const fstr) {
|
|||
* Move to INVALID points and
|
||||
* NOTE: Blocks the G-code queue and captures Marlin UI during use.
|
||||
*/
|
||||
void unified_bed_leveling::manually_probe_remaining_mesh(const xy_pos_t &pos, const_float_t z_clearance, const_float_t thick, const bool do_ubl_mesh_map) {
|
||||
void unified_bed_leveling::manually_probe_remaining_mesh(const xy_pos_t &pos, const float z_clearance, const float thick, const bool do_ubl_mesh_map) {
|
||||
ui.capture();
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onLevelingStart());
|
||||
|
||||
|
|
@ -1511,7 +1510,7 @@ void unified_bed_leveling::smart_fill_mesh() {
|
|||
|
||||
for (uint8_t i = 0; i < 3; ++i) {
|
||||
SERIAL_ECHOLNPGM("Tilting mesh (", i + 1, "/3)");
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), GET_TEXT_F(MSG_LCD_TILTING_MESH), i + 1));
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), GET_TEXT(MSG_LCD_TILTING_MESH), i + 1));
|
||||
|
||||
measured_z = probe.probe_at_point(points[i], i < 2 ? PROBE_PT_RAISE : PROBE_PT_LAST_STOW, param.V_verbosity);
|
||||
if ((abort_flag = isnan(measured_z))) break;
|
||||
|
|
@ -1567,7 +1566,7 @@ void unified_bed_leveling::smart_fill_mesh() {
|
|||
#endif
|
||||
|
||||
SERIAL_ECHOLNPGM("Tilting mesh point ", point_num, "/", total_points, "\n");
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT_F(MSG_LCD_TILTING_MESH), point_num, total_points));
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_LCD_TILTING_MESH), point_num, total_points));
|
||||
|
||||
measured_z = probe.probe_at_point(rpos, parser.seen_test('E') ? PROBE_PT_STOW : PROBE_PT_RAISE, param.V_verbosity); // TODO: Needs error handling
|
||||
|
||||
|
|
@ -1661,10 +1660,10 @@ void unified_bed_leveling::smart_fill_mesh() {
|
|||
*/
|
||||
#if ENABLED(VALIDATE_MESH_TILT)
|
||||
auto d_from = []{ DEBUG_ECHOPGM("D from "); };
|
||||
auto normed = [&](const xy_pos_t &pos, const_float_t zadd) {
|
||||
auto normed = [&](const xy_pos_t &pos, const float zadd) {
|
||||
return normal.x * pos.x + normal.y * pos.y + zadd;
|
||||
};
|
||||
auto debug_pt = [](const int num, const xy_pos_t &pos, const_float_t zadd) {
|
||||
auto debug_pt = [](const int num, const xy_pos_t &pos, const float zadd) {
|
||||
d_from();
|
||||
DEBUG_ECHOLN(F("Point "), num, C(':'), p_float_t(normed(pos, zadd), 6), F(" Z error = "), p_float_t(zadd - get_z_correction(pos), 6));
|
||||
};
|
||||
|
|
@ -1685,7 +1684,7 @@ void unified_bed_leveling::smart_fill_mesh() {
|
|||
#endif // HAS_BED_PROBE
|
||||
|
||||
#if ENABLED(UBL_G29_P31)
|
||||
void unified_bed_leveling::smart_fill_wlsf(const_float_t weight_factor) {
|
||||
void unified_bed_leveling::smart_fill_wlsf(const float weight_factor) {
|
||||
|
||||
// For each undefined mesh point, compute a distance-weighted least squares fit
|
||||
// from all the originally populated mesh points, weighted toward the point
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
// corners of cells. To fix the issue, simply check if the start/end of the line
|
||||
// is very close to a cell boundary in advance and don't split the line there.
|
||||
|
||||
void unified_bed_leveling::line_to_destination_cartesian(const_feedRate_t scaled_fr_mm_s, const uint8_t extruder) {
|
||||
void unified_bed_leveling::line_to_destination_cartesian(const feedRate_t scaled_fr_mm_s, const uint8_t extruder) {
|
||||
/**
|
||||
* Much of the nozzle movement will be within the same cell. So we will do as little computation
|
||||
* as possible to determine if this is the case. If this move is within the same cell, we will
|
||||
|
|
@ -351,7 +351,7 @@
|
|||
* Returns true if did NOT move, false if moved (requires current_position update).
|
||||
*/
|
||||
|
||||
bool __O2 unified_bed_leveling::line_to_destination_segmented(const_feedRate_t scaled_fr_mm_s) {
|
||||
bool __O2 unified_bed_leveling::line_to_destination_segmented(const feedRate_t scaled_fr_mm_s) {
|
||||
|
||||
if (!position_is_reachable(destination)) // fail if moving outside reachable boundary
|
||||
return true; // did not move, so current_position still accurate
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ public:
|
|||
// Draw an integer with optional leading zeros and optional decimal point
|
||||
void print(const uint8_t start, int16_t value, uint8_t size, const bool leadzero=false, bool dec=false);
|
||||
// Draw a float with a decimal point and optional digits
|
||||
void print(const uint8_t start, const_float_t value, const uint8_t pre_size, const uint8_t post_size, const bool leadzero=false);
|
||||
void print(const uint8_t start, const float value, const uint8_t pre_size, const uint8_t post_size, const bool leadzero=false);
|
||||
#endif
|
||||
|
||||
// Set a single LED by XY coordinate
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ struct E_Step {
|
|||
feedRate_t feedRate; //!< feed rate in mm/s
|
||||
};
|
||||
|
||||
inline void unscaled_mmu2_e_move(const float &dist, const feedRate_t fr_mm_s, const bool sync=true) {
|
||||
inline void unscaled_mmu2_e_move(const float dist, const feedRate_t fr_mm_s, const bool sync=true) {
|
||||
current_position.e += dist / planner.e_factor[active_extruder];
|
||||
line_to_current_position(fr_mm_s);
|
||||
if (sync) planner.synchronize();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -188,10 +188,8 @@ static bool ensure_safe_temperature(const bool wait=true, const PauseMode mode=P
|
|||
*
|
||||
* Returns 'true' if load was completed, 'false' for abort
|
||||
*/
|
||||
bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load_length/*=0*/, const_float_t purge_length/*=0*/, const int8_t max_beep_count/*=0*/,
|
||||
const bool show_lcd/*=false*/, const bool pause_for_user/*=false*/,
|
||||
const PauseMode mode/*=PAUSE_MODE_PAUSE_PRINT*/
|
||||
DXC_ARGS
|
||||
bool load_filament(const float slow_load_length/*=0*/, const float fast_load_length/*=0*/, const float purge_length/*=0*/, const int8_t max_beep_count/*=0*/,
|
||||
const bool show_lcd/*=false*/, const bool pause_for_user/*=false*/, const PauseMode mode/*=PAUSE_MODE_PAUSE_PRINT*/ DXC_ARGS
|
||||
) {
|
||||
DEBUG_SECTION(lf, "load_filament", true);
|
||||
DEBUG_ECHOLNPGM("... slowlen:", slow_load_length, " fastlen:", fast_load_length, " purgelen:", purge_length, " maxbeep:", max_beep_count, " showlcd:", show_lcd, " pauseforuser:", pause_for_user, " pausemode:", mode DXC_SAY);
|
||||
|
|
@ -344,10 +342,10 @@ inline void disable_active_extruder() {
|
|||
*
|
||||
* Returns 'true' if unload was completed, 'false' for abort
|
||||
*/
|
||||
bool unload_filament(const_float_t unload_length, const bool show_lcd/*=false*/,
|
||||
bool unload_filament(const float unload_length, const bool show_lcd/*=false*/,
|
||||
const PauseMode mode/*=PAUSE_MODE_PAUSE_PRINT*/
|
||||
#if ALL(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER)
|
||||
, const_float_t mix_multiplier/*=1.0*/
|
||||
, const float mix_multiplier/*=1.0*/
|
||||
#endif
|
||||
) {
|
||||
DEBUG_SECTION(uf, "unload_filament", true);
|
||||
|
|
@ -418,7 +416,7 @@ bool unload_filament(const_float_t unload_length, const bool show_lcd/*=false*/,
|
|||
*/
|
||||
uint8_t did_pause_print = 0;
|
||||
|
||||
bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool show_lcd/*=false*/, const_float_t unload_length/*=0*/ DXC_ARGS) {
|
||||
bool pause_print(const float retract, const xyz_pos_t &park_point, const bool show_lcd/*=false*/, const float unload_length/*=0*/ DXC_ARGS) {
|
||||
DEBUG_SECTION(pp, "pause_print", true);
|
||||
DEBUG_ECHOLNPGM("... park.x:", park_point.x, " y:", park_point.y, " z:", park_point.z, " unloadlen:", unload_length, " showlcd:", show_lcd DXC_SAY);
|
||||
|
||||
|
|
@ -639,9 +637,9 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
|
|||
* - Resume the current SD print job, if any
|
||||
*/
|
||||
void resume_print(
|
||||
const_float_t slow_load_length/*=0*/,
|
||||
const_float_t fast_load_length/*=0*/,
|
||||
const_float_t purge_length/*=ADVANCED_PAUSE_PURGE_LENGTH*/,
|
||||
const float slow_load_length/*=0*/,
|
||||
const float fast_load_length/*=0*/,
|
||||
const float purge_length/*=ADVANCED_PAUSE_PURGE_LENGTH*/,
|
||||
const int8_t max_beep_count/*=0*/,
|
||||
const celsius_t targetTemp/*=0*/,
|
||||
const bool show_lcd/*=true*/,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW
|
|||
|
||||
#if ENABLED(BACKUP_POWER_SUPPLY)
|
||||
|
||||
void PrintJobRecovery::retract_and_lift(const_float_t zraise) {
|
||||
void PrintJobRecovery::retract_and_lift(const float zraise) {
|
||||
#if POWER_LOSS_RETRACT_LEN || POWER_LOSS_ZRAISE
|
||||
|
||||
gcode.set_relative_mode(true); // Use relative coordinates
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ class PrintJobRecovery {
|
|||
static void write();
|
||||
|
||||
#if ENABLED(BACKUP_POWER_SUPPLY)
|
||||
static void retract_and_lift(const_float_t zraise);
|
||||
static void retract_and_lift(const float zraise);
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(POWER_LOSS) || ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
||||
|
|
|
|||
|
|
@ -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<int16_t>((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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -123,12 +123,12 @@ class TFilamentMonitor : public FilamentMonitorBase {
|
|||
response.filament_motion_present(extruder);
|
||||
}
|
||||
static float& motion_distance() { return response.motion_distance_mm; }
|
||||
static void set_motion_distance(const_float_t mm) { response.motion_distance_mm = mm; }
|
||||
static void set_motion_distance(const float mm) { response.motion_distance_mm = mm; }
|
||||
#endif
|
||||
|
||||
#if HAS_FILAMENT_RUNOUT_DISTANCE
|
||||
static float& runout_distance() { return response.runout_distance_mm; }
|
||||
static void set_runout_distance(const_float_t mm) { response.runout_distance_mm = mm; }
|
||||
static void set_runout_distance(const float mm) { response.runout_distance_mm = mm; }
|
||||
#endif
|
||||
|
||||
// Handle a block completion. RunoutResponseDelayed uses this to
|
||||
|
|
@ -143,38 +143,37 @@ class TFilamentMonitor : public FilamentMonitorBase {
|
|||
|
||||
// Give the response a chance to update its counter.
|
||||
static void run() {
|
||||
if (enabled && !filament_ran_out && should_monitor_runout()) {
|
||||
TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, cli()); // Prevent RunoutResponseDelayed::block_completed from accumulating here
|
||||
response.run();
|
||||
sensor.run();
|
||||
const runout_flags_t runout_flags = response.has_run_out();
|
||||
TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, sei());
|
||||
#if MULTI_FILAMENT_SENSOR
|
||||
#if ENABLED(WATCH_ALL_RUNOUT_SENSORS)
|
||||
const bool ran_out = bool(runout_flags); // any sensor triggers
|
||||
uint8_t extruder = 0;
|
||||
if (ran_out) while (!runout_flags.test(extruder)) extruder++;
|
||||
#else
|
||||
const bool ran_out = runout_flags[active_extruder]; // suppress non active extruders
|
||||
uint8_t extruder = active_extruder;
|
||||
#endif
|
||||
if (!enabled || filament_ran_out || !should_monitor_runout()) return;
|
||||
TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, cli()); // Prevent RunoutResponseDelayed::block_completed from accumulating here
|
||||
response.run();
|
||||
sensor.run();
|
||||
const runout_flags_t runout_flags = response.has_run_out();
|
||||
TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, sei());
|
||||
#if MULTI_FILAMENT_SENSOR
|
||||
#if ENABLED(WATCH_ALL_RUNOUT_SENSORS)
|
||||
const bool ran_out = bool(runout_flags); // any sensor triggers
|
||||
uint8_t extruder = 0;
|
||||
if (ran_out) while (!runout_flags.test(extruder)) extruder++;
|
||||
#else
|
||||
const bool ran_out = bool(runout_flags);
|
||||
const bool ran_out = runout_flags[active_extruder]; // suppress non active extruders
|
||||
uint8_t extruder = active_extruder;
|
||||
#endif
|
||||
#else
|
||||
const bool ran_out = bool(runout_flags);
|
||||
uint8_t extruder = active_extruder;
|
||||
#endif
|
||||
|
||||
if (ran_out) {
|
||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
||||
SERIAL_ECHOPGM("Runout Sensors: ");
|
||||
for (uint8_t i = 0; i < 8; ++i) SERIAL_CHAR('0' + char(runout_flags[i]));
|
||||
SERIAL_ECHOLNPGM(" -> ", extruder, " RUN OUT");
|
||||
#endif
|
||||
if (!ran_out) return;
|
||||
|
||||
filament_ran_out = true;
|
||||
event_filament_runout(extruder);
|
||||
planner.synchronize();
|
||||
}
|
||||
}
|
||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
||||
SERIAL_ECHOPGM("Runout Sensors: ");
|
||||
for (uint8_t i = 0; i < 8; ++i) SERIAL_CHAR('0' + char(runout_flags[i]));
|
||||
SERIAL_ECHOLNPGM(" -> ", extruder, " RUN OUT");
|
||||
#endif
|
||||
|
||||
filament_ran_out = true;
|
||||
event_filament_runout(extruder);
|
||||
planner.synchronize();
|
||||
}
|
||||
|
||||
// Reset after a filament runout or upon resuming a job
|
||||
|
|
@ -376,7 +375,9 @@ class FilamentSensorBase {
|
|||
class RunoutResponseDelayed {
|
||||
private:
|
||||
static countdown_t mm_countdown;
|
||||
static bool ignore_motion; // Flag to ignore the encoder
|
||||
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
|
||||
static bool ignore_motion; // Flag to ignore the encoder
|
||||
#endif
|
||||
|
||||
public:
|
||||
static float runout_distance_mm;
|
||||
|
|
@ -385,13 +386,17 @@ class FilamentSensorBase {
|
|||
static float motion_distance_mm;
|
||||
#endif
|
||||
|
||||
static void set_ignore_motion(const bool ignore=true) { ignore_motion = ignore; }
|
||||
static void set_ignore_motion(const bool ignore=true) {
|
||||
UNUSED(ignore);
|
||||
TERN_(FILAMENT_SWITCH_AND_MOTION, ignore_motion = ignore);
|
||||
}
|
||||
|
||||
static void reset() {
|
||||
for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) filament_present(i);
|
||||
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
|
||||
for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i) filament_motion_present(i);
|
||||
#endif
|
||||
set_ignore_motion(false);
|
||||
}
|
||||
|
||||
static void run() {
|
||||
|
|
@ -413,13 +418,24 @@ class FilamentSensorBase {
|
|||
// Get runout status for all presence sensors and motion sensors
|
||||
static runout_flags_t has_run_out() {
|
||||
runout_flags_t runout_flags{0};
|
||||
// Runout based on filament presence
|
||||
for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) if (mm_countdown.runout[i] < 0) runout_flags.set(i);
|
||||
// Runout based on filament motion
|
||||
|
||||
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
|
||||
if (!ignore_motion)
|
||||
for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i) if (mm_countdown.motion[i] < 0) runout_flags.set(i);
|
||||
// Runout based on filament motion
|
||||
if (!ignore_motion) {
|
||||
for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i) {
|
||||
if (mm_countdown.motion[i] < 0) {
|
||||
runout_flags.set(i);
|
||||
mm_countdown.runout[i] = -1; // For a filament jam don't wait for runout_distance_mm!
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Runout based on filament presence
|
||||
for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i)
|
||||
if (mm_countdown.runout[i] < 0)
|
||||
runout_flags.set(i);
|
||||
|
||||
return runout_flags;
|
||||
}
|
||||
|
||||
|
|
@ -471,8 +487,8 @@ class FilamentSensorBase {
|
|||
if (mm_countdown.runout_reset[e]) filament_present(e); // Reset pending. Try to reset.
|
||||
}
|
||||
|
||||
// Apply E distance to motion countdown, reset if flagged
|
||||
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
|
||||
// Apply E distance to motion countdown, reset if flagged
|
||||
if (!ignore_motion && e < NUM_MOTION_SENSORS) {
|
||||
mm_countdown.motion[e] -= mm;
|
||||
if (mm_countdown.motion_reset[e]) filament_motion_present(e); // Reset pending. Try to reset.
|
||||
|
|
@ -484,7 +500,7 @@ class FilamentSensorBase {
|
|||
static void init_for_restart(const bool onoff=true) {
|
||||
UNUSED(onoff);
|
||||
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
|
||||
reset();
|
||||
reset(); // also calls set_ignore_motion(false)
|
||||
set_ignore_motion(!onoff);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class SpindleLaser {
|
|||
public:
|
||||
static CutterMode cutter_mode;
|
||||
|
||||
static constexpr uint8_t pct_to_ocr(const_float_t pct) { return uint8_t(PCT_TO_PWM(pct)); }
|
||||
static constexpr uint8_t pct_to_ocr(const float pct) { return uint8_t(PCT_TO_PWM(pct)); }
|
||||
|
||||
// cpower = configured values (e.g., SPEED_POWER_MAX)
|
||||
// Convert configured power range to a percentage
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ float g26_random_deviation = 0.0;
|
|||
|
||||
#endif
|
||||
|
||||
void move_to(const_float_t rx, const_float_t ry, const_float_t z, const_float_t e_delta) {
|
||||
void move_to(const float rx, const float ry, const float z, const float e_delta) {
|
||||
static float last_z = -999.99;
|
||||
|
||||
const xy_pos_t dest = { rx, ry };
|
||||
|
|
@ -196,7 +196,7 @@ void move_to(const_float_t rx, const_float_t ry, const_float_t z, const_float_t
|
|||
prepare_internal_move_to_destination(fr_mm_s);
|
||||
}
|
||||
|
||||
void move_to(const xyz_pos_t &where, const_float_t de) { move_to(where.x, where.y, where.z, de); }
|
||||
void move_to(const xyz_pos_t &where, const float de) { move_to(where.x, where.y, where.z, de); }
|
||||
|
||||
typedef struct {
|
||||
float extrusion_multiplier = EXTRUSION_MULTIPLIER,
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@
|
|||
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
|
||||
#include "../../../core/debug_out.h"
|
||||
|
||||
#if DISABLED(PROBE_MANUALLY) && FT_MOTION_DISABLE_FOR_PROBING
|
||||
#if DISABLED(PROBE_MANUALLY) && ENABLED(FT_MOTION)
|
||||
#include "../../../module/ft_motion.h"
|
||||
#endif
|
||||
|
||||
|
|
@ -275,8 +275,9 @@ G29_TYPE GcodeSuite::G29() {
|
|||
// Set and report "probing" state to host
|
||||
TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_PROBE, false));
|
||||
|
||||
#if DISABLED(PROBE_MANUALLY) && FT_MOTION_DISABLE_FOR_PROBING
|
||||
FTMotionDisableInScope FT_Disabler; // Disable Fixed-Time Motion for probing
|
||||
#if DISABLED(PROBE_MANUALLY) && ENABLED(FT_MOTION)
|
||||
// Potentially disable Fixed-Time Motion for probing
|
||||
FTMotionDisableInScope FT_Disabler;
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
@ -708,7 +709,7 @@ G29_TYPE GcodeSuite::G29() {
|
|||
if (TERN0(IS_KINEMATIC, !probe.can_reach(abl.probePos))) continue;
|
||||
|
||||
if (abl.verbose_level) SERIAL_ECHOLNPGM("Probing mesh point ", pt_index, "/", abl.abl_points, ".");
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT_F(MSG_PROBING_POINT), int(pt_index), int(abl.abl_points)));
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), int(pt_index), int(abl.abl_points)));
|
||||
|
||||
#if ENABLED(BD_SENSOR_PROBE_NO_STOP)
|
||||
if (PR_INNER_VAR == inStart) {
|
||||
|
|
@ -813,7 +814,7 @@ G29_TYPE GcodeSuite::G29() {
|
|||
|
||||
for (uint8_t i = 0; i < 3; ++i) {
|
||||
if (abl.verbose_level) SERIAL_ECHOLNPGM("Probing point ", i + 1, "/3.");
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), GET_TEXT_F(MSG_PROBING_POINT), int(i + 1)));
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), GET_TEXT(MSG_PROBING_POINT), int(i + 1)));
|
||||
|
||||
// Retain the last probe position
|
||||
abl.probePos = xy_pos_t(points[i]);
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
|
||||
#include "../../../core/debug_out.h"
|
||||
|
||||
#if FT_MOTION_DISABLE_FOR_PROBING
|
||||
#if ENABLED(FT_MOTION)
|
||||
#include "../../module/ft_motion.h"
|
||||
#endif
|
||||
|
||||
|
|
@ -67,9 +67,8 @@ inline void echo_not_entered(const char c) { SERIAL_CHAR(c); SERIAL_ECHOLNPGM("
|
|||
*/
|
||||
void GcodeSuite::G29() {
|
||||
|
||||
#if FT_MOTION_DISABLE_FOR_PROBING
|
||||
FTMotionDisableInScope FT_Disabler; // Disable Fixed-Time Motion for probing
|
||||
#endif
|
||||
// Potentially disable Fixed-Time Motion for probing
|
||||
TERN_(FT_MOTION, FTMotionDisableInScope FT_Disabler);
|
||||
|
||||
DEBUG_SECTION(log_G29, "G29", true);
|
||||
|
||||
|
|
@ -261,7 +260,7 @@ void GcodeSuite::G29() {
|
|||
|
||||
if (state == MeshNext) {
|
||||
SERIAL_ECHOLNPGM("MBL G29 point ", _MIN(mbl_probe_index, GRID_MAX_POINTS), " of ", GRID_MAX_POINTS);
|
||||
if (mbl_probe_index > 0) TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT_F(MSG_PROBING_POINT), _MIN(mbl_probe_index, GRID_MAX_POINTS), int(GRID_MAX_POINTS)));
|
||||
if (mbl_probe_index > 0) TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), _MIN(mbl_probe_index, GRID_MAX_POINTS), int(GRID_MAX_POINTS)));
|
||||
}
|
||||
|
||||
report_current_position();
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
#include "../../feature/bltouch.h"
|
||||
#endif
|
||||
|
||||
#if FT_MOTION_DISABLE_FOR_PROBING
|
||||
#if ENABLED(FT_MOTION)
|
||||
#include "../../module/ft_motion.h"
|
||||
#endif
|
||||
|
||||
|
|
@ -130,9 +130,8 @@
|
|||
|
||||
inline void home_z_safely() {
|
||||
|
||||
#if FT_MOTION_DISABLE_FOR_PROBING
|
||||
FTMotionDisableInScope FT_Disabler; // Disable Fixed-Time Motion for homing
|
||||
#endif
|
||||
// Potentially disable Fixed-Time Motion for homing
|
||||
TERN_(FT_MOTION, FTMotionDisableInScope FT_Disabler);
|
||||
|
||||
DEBUG_SECTION(log_G28, "home_z_safely", DEBUGGING(LEVELING));
|
||||
|
||||
|
|
@ -290,9 +289,8 @@ void GcodeSuite::G28() {
|
|||
motion_state_t saved_motion_state = begin_slow_homing();
|
||||
#endif
|
||||
|
||||
#if FT_MOTION_DISABLE_FOR_PROBING
|
||||
FTMotionDisableInScope FT_Disabler; // Disable Fixed-Time Motion for homing
|
||||
#endif
|
||||
// Potentially disable Fixed-Time Motion for homing
|
||||
TERN_(FT_MOTION, FTMotionDisableInScope FT_Disabler);
|
||||
|
||||
// Always home with tool 0 active
|
||||
#if HAS_MULTI_HOTEND
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -323,7 +323,7 @@ void GcodeSuite::G34() {
|
|||
msg.echoln();
|
||||
ui.set_status(msg);
|
||||
|
||||
auto decreasing_accuracy = [](const_float_t v1, const_float_t v2) {
|
||||
auto decreasing_accuracy = [](const float v1, const float v2) {
|
||||
if (v1 < v2 * 0.7f) {
|
||||
SERIAL_ECHOLNPGM("Decreasing Accuracy Detected.");
|
||||
LCD_MESSAGE(MSG_DECREASING_ACCURACY);
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ void GcodeSuite::M48() {
|
|||
max = -99999.9, // Largest value sampled so far
|
||||
sample_set[n_samples]; // Storage for sampled values
|
||||
|
||||
auto dev_report = [](const bool verbose, const_float_t mean, const_float_t sigma, const_float_t min, const_float_t max, const bool final=false) {
|
||||
auto dev_report = [](const bool verbose, const float mean, const float sigma, const float min, const float max, const bool final=false) {
|
||||
if (verbose) {
|
||||
SERIAL_ECHOPGM("Mean: ", p_float_t(mean, 6));
|
||||
if (!final) SERIAL_ECHOPGM(" Sigma: ", p_float_t(sigma, 6));
|
||||
|
|
@ -149,7 +149,7 @@ void GcodeSuite::M48() {
|
|||
for (uint8_t n = 0; n < n_samples; ++n) {
|
||||
#if HAS_STATUS_MESSAGE
|
||||
// Display M48 progress in the status bar
|
||||
ui.status_printf(0, F(S_FMT ": %d/%d"), GET_TEXT_F(MSG_M48_POINT), int(n + 1), int(n_samples));
|
||||
ui.status_printf(0, F(S_FMT ": %d/%d"), GET_TEXT(MSG_M48_POINT), int(n + 1), int(n_samples));
|
||||
#endif
|
||||
|
||||
// When there are "legs" of movement move around the point before probing
|
||||
|
|
|
|||
|
|
@ -48,31 +48,31 @@ void GcodeSuite::M210() {
|
|||
return M210_report();
|
||||
|
||||
#if HAS_X_AXIS
|
||||
if (parser.floatval('X') > 0) homing_feedrate_mm_m.x = parser.value_axis_units(X_AXIS);
|
||||
if (parser.floatval(AXIS1_PARAM) > 0) homing_feedrate_mm_m.x = parser.value_axis_units(X_AXIS);
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
if (parser.floatval('Y') > 0) homing_feedrate_mm_m.y = parser.value_axis_units(Y_AXIS);
|
||||
if (parser.floatval(AXIS2_PARAM) > 0) homing_feedrate_mm_m.y = parser.value_axis_units(Y_AXIS);
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
if (parser.floatval('Z') > 0) homing_feedrate_mm_m.z = parser.value_axis_units(Z_AXIS);
|
||||
if (parser.floatval(AXIS3_PARAM) > 0) homing_feedrate_mm_m.z = parser.value_axis_units(Z_AXIS);
|
||||
#endif
|
||||
#if HAS_I_AXIS
|
||||
if (parser.floatval(AXIS4_NAME) > 0) homing_feedrate_mm_m.i = parser.value_axis_units(I_AXIS);
|
||||
if (parser.floatval(AXIS4_PARAM) > 0) homing_feedrate_mm_m.i = parser.value_axis_units(I_AXIS);
|
||||
#endif
|
||||
#if HAS_J_AXIS
|
||||
if (parser.floatval(AXIS5_NAME) > 0) homing_feedrate_mm_m.j = parser.value_axis_units(J_AXIS);
|
||||
if (parser.floatval(AXIS5_PARAM) > 0) homing_feedrate_mm_m.j = parser.value_axis_units(J_AXIS);
|
||||
#endif
|
||||
#if HAS_K_AXIS
|
||||
if (parser.floatval(AXIS6_NAME) > 0) homing_feedrate_mm_m.k = parser.value_axis_units(K_AXIS);
|
||||
if (parser.floatval(AXIS6_PARAM) > 0) homing_feedrate_mm_m.k = parser.value_axis_units(K_AXIS);
|
||||
#endif
|
||||
#if HAS_U_AXIS
|
||||
if (parser.floatval(AXIS7_NAME) > 0) homing_feedrate_mm_m.u = parser.value_axis_units(U_AXIS);
|
||||
if (parser.floatval(AXIS7_PARAM) > 0) homing_feedrate_mm_m.u = parser.value_axis_units(U_AXIS);
|
||||
#endif
|
||||
#if HAS_V_AXIS
|
||||
if (parser.floatval(AXIS8_NAME) > 0) homing_feedrate_mm_m.v = parser.value_axis_units(V_AXIS);
|
||||
if (parser.floatval(AXIS8_PARAM) > 0) homing_feedrate_mm_m.v = parser.value_axis_units(V_AXIS);
|
||||
#endif
|
||||
#if HAS_W_AXIS
|
||||
if (parser.floatval(AXIS9_NAME) > 0) homing_feedrate_mm_m.w = parser.value_axis_units(W_AXIS);
|
||||
if (parser.floatval(AXIS9_PARAM) > 0) homing_feedrate_mm_m.w = parser.value_axis_units(W_AXIS);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -154,37 +154,36 @@ inline void servo_probe_test() {
|
|||
|
||||
SET_INPUT_PULLUP(PROBE_TEST_PIN);
|
||||
|
||||
// First, check for a probe that recognizes an advanced BLTouch sequence.
|
||||
// In addition to STOW and DEPLOY, it uses SW MODE (and RESET in the beginning)
|
||||
// to see if this is one of the following: BLTOUCH Classic 1.2, 1.3, or
|
||||
// BLTouch Smart 1.0, 2.0, 2.2, 3.0, 3.1. But only if the user has actually
|
||||
// configured a BLTouch as being present. If the user has not configured this,
|
||||
// the BLTouch will be detected in the last phase of these tests (see further on).
|
||||
bool blt = false;
|
||||
// This code will try to detect a BLTouch probe or clone
|
||||
/**
|
||||
* This code will try to detect a BLTouch probe or clone.
|
||||
* First, check for a probe that recognizes an advanced BLTouch sequence.
|
||||
* In addition to STOW and DEPLOY, it uses SW MODE (and RESET in the beginning)
|
||||
* to see if this is one of the following: BLTOUCH Classic 1.2, 1.3, or
|
||||
* BLTouch Smart 1.0, 2.0, 2.2, 3.0, 3.1. But only if the user has actually
|
||||
* configured a BLTouch as being present. If the user has not configured this,
|
||||
* the BLTouch will be detected in the last phase of these tests (see further on).
|
||||
*/
|
||||
#if ENABLED(BLTOUCH)
|
||||
SERIAL_ECHOLNPGM(". Check for BLTOUCH");
|
||||
bltouch._reset();
|
||||
bltouch._stow();
|
||||
if (!PROBE_TRIGGERED()) {
|
||||
bltouch._set_SW_mode();
|
||||
if (PROBE_TRIGGERED()) {
|
||||
bltouch._deploy();
|
||||
if (!PROBE_TRIGGERED()) {
|
||||
bltouch._stow();
|
||||
SERIAL_ECHOLNPGM("= BLTouch Classic 1.2, 1.3, Smart 1.0, 2.0, 2.2, 3.0, 3.1 detected.");
|
||||
// Check for a 3.1 by letting the user trigger it, later
|
||||
blt = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool blt = false;
|
||||
do {
|
||||
SERIAL_ECHOLNPGM(". Check for BLTOUCH");
|
||||
bltouch._reset();
|
||||
bltouch._stow(); if ( PROBE_TRIGGERED()) break;
|
||||
bltouch._set_SW_mode(); if (!PROBE_TRIGGERED()) break;
|
||||
bltouch._deploy(); if ( PROBE_TRIGGERED()) break;
|
||||
bltouch._stow();
|
||||
SERIAL_ECHOLNPGM("= BLTouch Classic 1.2, 1.3, Smart 1.0, 2.0, 2.2, 3.0, 3.1 detected.");
|
||||
blt = true; // Check for a 3.1 by letting the user trigger it, later
|
||||
} while(0);
|
||||
#else
|
||||
static constexpr bool blt = false;
|
||||
#endif
|
||||
|
||||
// The following code is common to all kinds of servo probes.
|
||||
// Since it could be a real servo or a BLTouch (any kind) or a clone,
|
||||
// use only "common" functions - i.e. SERVO_MOVE. No bltouch.xxxx stuff.
|
||||
|
||||
// If it is already recognised as a being a BLTouch, no need for this test
|
||||
// If it is already recognized as a being a BLTouch, no need for this test
|
||||
if (!blt) {
|
||||
// DEPLOY and STOW 4 times and see if the signal follows
|
||||
// Then it is a mechanical switch
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
#endif
|
||||
|
||||
#ifdef PHOTO_RETRACT_MM
|
||||
inline void e_move_m240(const float length, const_feedRate_t fr_mm_s) {
|
||||
inline void e_move_m240(const float length, const feedRate_t fr_mm_s) {
|
||||
if (length && thermalManager.hotEnoughToExtrude(active_extruder))
|
||||
unscaled_e_move(length, fr_mm_s);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,9 @@
|
|||
#include "../../../module/ft_motion.h"
|
||||
#include "../../../module/stepper.h"
|
||||
|
||||
void say_shaper_type(const AxisEnum a) {
|
||||
SERIAL_ECHOPGM(" axis ");
|
||||
void say_shaper_type(const AxisEnum a, bool &sep, const char axis_name) {
|
||||
if (sep) SERIAL_ECHOPGM(" ; ");
|
||||
SERIAL_CHAR(axis_name, '=');
|
||||
switch (ftMotion.cfg.shaper[a]) {
|
||||
default: break;
|
||||
case ftMotionShaper_ZV: SERIAL_ECHOPGM("ZV"); break;
|
||||
|
|
@ -41,46 +42,31 @@ void say_shaper_type(const AxisEnum a) {
|
|||
case ftMotionShaper_3HEI: SERIAL_ECHOPGM("3 Hump EI"); break;
|
||||
case ftMotionShaper_MZV: SERIAL_ECHOPGM("MZV"); break;
|
||||
}
|
||||
SERIAL_ECHOPGM(" shaping");
|
||||
sep = true;
|
||||
}
|
||||
|
||||
#if CORE_IS_XY || CORE_IS_XZ
|
||||
#define AXIS_0_NAME "A"
|
||||
#else
|
||||
#define AXIS_0_NAME "X"
|
||||
#endif
|
||||
#if CORE_IS_XY || CORE_IS_YZ
|
||||
#define AXIS_1_NAME "B"
|
||||
#else
|
||||
#define AXIS_1_NAME "Y"
|
||||
#endif
|
||||
|
||||
void say_shaping() {
|
||||
// FT Enabled
|
||||
SERIAL_ECHO_TERNARY(ftMotion.cfg.active, "Fixed-Time Motion ", "en", "dis", "abled");
|
||||
|
||||
// FT Shaping
|
||||
#if HAS_X_AXIS
|
||||
if (AXIS_IS_SHAPING(X)) {
|
||||
SERIAL_ECHOPGM(" with " AXIS_0_NAME);
|
||||
say_shaper_type(X_AXIS);
|
||||
}
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
if (AXIS_IS_SHAPING(Y)) {
|
||||
SERIAL_ECHOPGM(" and with " AXIS_1_NAME);
|
||||
say_shaper_type(Y_AXIS);
|
||||
}
|
||||
#endif
|
||||
|
||||
SERIAL_ECHOLNPGM(".");
|
||||
const bool is_shaping = AXIS_IS_SHAPING(X) || AXIS_IS_SHAPING(Y) || AXIS_IS_SHAPING(Z) || AXIS_IS_SHAPING(E);
|
||||
bool sep = false;
|
||||
if (is_shaping) {
|
||||
#define STEPPER_E_NAME 'E'
|
||||
#define _SAY_SHAPER(A) if (AXIS_IS_SHAPING(A)) say_shaper_type(_AXIS(A), sep, STEPPER_##A##_NAME);
|
||||
SERIAL_ECHOPGM(" (");
|
||||
SHAPED_CODE(_SAY_SHAPER(A), _SAY_SHAPER(B), _SAY_SHAPER(C), _SAY_SHAPER(E));
|
||||
SERIAL_CHAR(')');
|
||||
}
|
||||
SERIAL_EOL();
|
||||
|
||||
const bool z_based = TERN0(HAS_DYNAMIC_FREQ_MM, ftMotion.cfg.dynFreqMode == dynFreqMode_Z_BASED),
|
||||
g_based = TERN0(HAS_DYNAMIC_FREQ_G, ftMotion.cfg.dynFreqMode == dynFreqMode_MASS_BASED),
|
||||
dynamic = z_based || g_based;
|
||||
|
||||
// FT Dynamic Frequency Mode
|
||||
if (AXIS_IS_SHAPING(X) || AXIS_IS_SHAPING(Y)) {
|
||||
if (is_shaping) {
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
SERIAL_ECHOPGM("Dynamic Frequency Mode ");
|
||||
switch (ftMotion.cfg.dynFreqMode) {
|
||||
|
|
@ -97,7 +83,8 @@ void say_shaping() {
|
|||
#endif
|
||||
|
||||
#if HAS_X_AXIS
|
||||
SERIAL_ECHO_TERNARY(dynamic, AXIS_0_NAME " ", "base dynamic", "static", " shaper frequency: ");
|
||||
SERIAL_CHAR(STEPPER_A_NAME);
|
||||
SERIAL_ECHO_TERNARY(dynamic, " ", "base dynamic", "static", " shaper frequency: ");
|
||||
SERIAL_ECHO(p_float_t(ftMotion.cfg.baseFreq.x, 2), F("Hz"));
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(ftMotion.cfg.dynFreqK.x, 2), F("Hz/"), z_based ? F("mm") : F("g"));
|
||||
|
|
@ -106,21 +93,31 @@ void say_shaping() {
|
|||
#endif
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
SERIAL_ECHO_TERNARY(dynamic, AXIS_1_NAME " ", "base dynamic", "static", " shaper frequency: ");
|
||||
SERIAL_CHAR(STEPPER_B_NAME);
|
||||
SERIAL_ECHO_TERNARY(dynamic, " ", "base dynamic", "static", " shaper frequency: ");
|
||||
SERIAL_ECHO(p_float_t(ftMotion.cfg.baseFreq.y, 2), F(" Hz"));
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(ftMotion.cfg.dynFreqK.y, 2), F("Hz/"), z_based ? F("mm") : F("g"));
|
||||
#endif
|
||||
SERIAL_EOL();
|
||||
#endif
|
||||
|
||||
#if ENABLED(FTM_SHAPER_Z)
|
||||
SERIAL_CHAR(STEPPER_C_NAME);
|
||||
SERIAL_ECHO_TERNARY(dynamic, " ", "base dynamic", "static", " shaper frequency: ");
|
||||
SERIAL_ECHO(p_float_t(ftMotion.cfg.baseFreq.z, 2), F(" Hz"));
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(ftMotion.cfg.dynFreqK.z, 2), F("Hz/"), z_based ? F("mm") : F("g"));
|
||||
#endif
|
||||
SERIAL_EOL();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
SERIAL_ECHO_TERNARY(ftMotion.cfg.linearAdvEna, "Linear Advance ", "en", "dis", "abled");
|
||||
if (ftMotion.cfg.linearAdvEna)
|
||||
if (ftMotion.cfg.active) {
|
||||
SERIAL_ECHO_TERNARY(ftMotion.cfg.linearAdvEna, "Linear Advance ", "en", "dis", "abled");
|
||||
SERIAL_ECHOLNPGM(". Gain: ", ftMotion.cfg.linearAdvK);
|
||||
else
|
||||
SERIAL_EOL();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -129,26 +126,44 @@ void GcodeSuite::M493_report(const bool forReplay/*=true*/) {
|
|||
|
||||
report_heading_etc(forReplay, F(STR_FT_MOTION));
|
||||
const ft_config_t &c = ftMotion.cfg;
|
||||
SERIAL_ECHOPGM(" M493 S", c.active);
|
||||
#if HAS_X_AXIS
|
||||
SERIAL_ECHOPGM(" A", c.baseFreq.x);
|
||||
#if HAS_Y_AXIS
|
||||
SERIAL_ECHOPGM(" B", c.baseFreq.y);
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
SERIAL_ECHOPGM(" D", c.dynFreqMode);
|
||||
SERIAL_ECHOLNPGM(
|
||||
" M493 S", c.active
|
||||
#if HAS_X_AXIS
|
||||
SERIAL_ECHOPGM(" F", c.dynFreqK.x);
|
||||
, " A", c.baseFreq.x
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
, " B", c.baseFreq.y
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_Z)
|
||||
, " C", c.baseFreq.z
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_E)
|
||||
, " E", c.baseFreq.e
|
||||
#endif
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
, " D", c.dynFreqMode
|
||||
#if HAS_X_AXIS
|
||||
, " F", c.dynFreqK.x
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
SERIAL_ECHOPGM(" H", c.dynFreqK.y);
|
||||
, " H", c.dynFreqK.y
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_Z)
|
||||
, " L", c.dynFreqK.z
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_E)
|
||||
, " O", c.dynFreqK.e
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_EXTRUDERS
|
||||
SERIAL_ECHOPGM(" P", c.linearAdvEna, " K", c.linearAdvK);
|
||||
#endif
|
||||
SERIAL_EOL();
|
||||
|
||||
, " G", c.axis_sync_enabled
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
, " P", c.linearAdvEna, " K", c.linearAdvK
|
||||
#endif
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -158,8 +173,8 @@ void GcodeSuite::M493_report(const bool forReplay/*=true*/) {
|
|||
* 0: Fixed-Time Motion OFF (Standard Motion)
|
||||
* 1: Fixed-Time Motion ON
|
||||
*
|
||||
* X/Y<mode> Set the vibration compensator [input shaper] mode for X / Y axis.
|
||||
* Users / slicers must remember to set the mode for both axes!
|
||||
* X/Y/Z/E<mode> Set the vibration compensator [input shaper] mode for an axis.
|
||||
* Users / slicers must remember to set the mode for all relevant axes!
|
||||
* 0: NONE : No input shaper
|
||||
* 1: ZV : Zero Vibration
|
||||
* 2: ZVD : Zero Vibration and Derivative
|
||||
|
|
@ -174,20 +189,35 @@ void GcodeSuite::M493_report(const bool forReplay/*=true*/) {
|
|||
*
|
||||
* K<gain> Set Linear Advance gain
|
||||
*
|
||||
* G<bool> Enable (1) or Disable (0) axis synchronization.
|
||||
*
|
||||
* D<mode> Set Dynamic Frequency mode
|
||||
* 0: DISABLED
|
||||
* 1: Z-based (Requires a Z axis)
|
||||
* 2: Mass-based (Requires X and E axes)
|
||||
*
|
||||
* A<Hz> Set static/base frequency for the X axis
|
||||
* F<Hz> Set frequency scaling for the X axis
|
||||
* I 0.0 Set damping ratio for the X axis
|
||||
* Q 0.00 Set the vibration tolerance for the X axis
|
||||
* A<Hz> Set X static/base frequency
|
||||
* F<Hz> Set X frequency scaling
|
||||
* I<flt> Set X damping ratio
|
||||
* Q<flt> Set X vibration tolerance
|
||||
*
|
||||
* B<Hz> Set Y static/base frequency
|
||||
* H<Hz> Set Y frequency scaling
|
||||
* J<flt> Set Y damping ratio
|
||||
* R<flt> Set Y vibration tolerance
|
||||
*
|
||||
* With FTM_SHAPING_Z:
|
||||
* C<Hz> Set Z static/base frequency
|
||||
* L<Hz> Set Z frequency scaling
|
||||
* O<flt> Set Z damping ratio
|
||||
* M<flt> Set Z vibration tolerance
|
||||
*
|
||||
* With FTM_SHAPING_E:
|
||||
* W<Hz> Set E static/base frequency
|
||||
* O<Hz> Set E frequency scaling
|
||||
* U<flt> Set E damping ratio
|
||||
* V<flt> Set E vibration tolerance
|
||||
*
|
||||
* B<Hz> Set static/base frequency for the Y axis
|
||||
* H<Hz> Set frequency scaling for the Y axis
|
||||
* J 0.0 Set damping ratio for the Y axis
|
||||
* R 0.00 Set the vibration tolerance for the Y axis
|
||||
*/
|
||||
void GcodeSuite::M493() {
|
||||
struct { bool update:1, report:1; } flag = { false };
|
||||
|
|
@ -205,7 +235,8 @@ void GcodeSuite::M493() {
|
|||
}
|
||||
}
|
||||
|
||||
#if HAS_X_AXIS
|
||||
#if NUM_AXES_SHAPED > 0
|
||||
|
||||
auto set_shaper = [&](const AxisEnum axis, const char c) {
|
||||
const ftMotionShaper_t newsh = (ftMotionShaper_t)parser.value_byte();
|
||||
if (newsh != ftMotion.cfg.shaper[axis]) {
|
||||
|
|
@ -228,13 +259,10 @@ void GcodeSuite::M493() {
|
|||
return false;
|
||||
};
|
||||
|
||||
if (parser.seenval('X') && set_shaper(X_AXIS, 'X')) return; // Parse 'X' mode parameter
|
||||
#define _SET_SHAPER(A) if (parser.seenval(CHARIFY(A)) && set_shaper(_AXIS(A), CHARIFY(A))) return;
|
||||
SHAPED_MAP(_SET_SHAPER);
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
if (parser.seenval('Y') && set_shaper(Y_AXIS, 'Y')) return; // Parse 'Y' mode parameter
|
||||
#endif
|
||||
|
||||
#endif // HAS_X_AXIS
|
||||
#endif // NUM_AXES_SHAPED > 0
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
|
||||
|
|
@ -243,13 +271,12 @@ void GcodeSuite::M493() {
|
|||
const bool val = parser.value_bool();
|
||||
ftMotion.cfg.linearAdvEna = val;
|
||||
flag.report = true;
|
||||
SERIAL_ECHO_TERNARY(val, "Linear Advance ", "en", "dis", "abled.\n");
|
||||
}
|
||||
|
||||
// Pressure control (linear advance) gain parameter.
|
||||
if (parser.seenval('K')) {
|
||||
const float val = parser.value_float();
|
||||
if (val >= 0.0f) {
|
||||
if (WITHIN(val, 0.0f, 10.0f)) {
|
||||
ftMotion.cfg.linearAdvK = val;
|
||||
flag.report = true;
|
||||
}
|
||||
|
|
@ -259,11 +286,20 @@ void GcodeSuite::M493() {
|
|||
|
||||
#endif // HAS_EXTRUDERS
|
||||
|
||||
// Parse '?' axis synchronization parameter.
|
||||
if (parser.seen('?')) {
|
||||
const bool enabled = parser.value_bool();
|
||||
if (enabled != ftMotion.cfg.axis_sync_enabled) {
|
||||
ftMotion.cfg.axis_sync_enabled = enabled;
|
||||
flag.report = true;
|
||||
}
|
||||
}
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
|
||||
// Dynamic frequency mode parameter.
|
||||
if (parser.seenval('D')) {
|
||||
if (AXIS_IS_SHAPING(X) || AXIS_IS_SHAPING(Y)) {
|
||||
if (AXIS_IS_SHAPING(X) || AXIS_IS_SHAPING(Y) || AXIS_IS_SHAPING(Z) || AXIS_IS_SHAPING(E)) {
|
||||
const dynFreqMode_t val = dynFreqMode_t(parser.value_byte());
|
||||
switch (val) {
|
||||
#if HAS_DYNAMIC_FREQ_MM
|
||||
|
|
@ -295,7 +331,7 @@ void GcodeSuite::M493() {
|
|||
|
||||
#if HAS_X_AXIS
|
||||
|
||||
// Parse frequency parameter (X axis).
|
||||
// Parse X frequency parameter
|
||||
if (parser.seenval('A')) {
|
||||
if (AXIS_IS_SHAPING(X)) {
|
||||
const float val = parser.value_float();
|
||||
|
|
@ -305,59 +341,59 @@ void GcodeSuite::M493() {
|
|||
flag.update = flag.report = true;
|
||||
}
|
||||
else // Frequency out of range.
|
||||
SERIAL_ECHOLNPGM("Invalid [", C('A'), "] frequency value.");
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_A_NAME), " [", C('A'), "] frequency value.");
|
||||
}
|
||||
else // Mode doesn't use frequency.
|
||||
SERIAL_ECHOLNPGM("Wrong mode for [", C('A'), "] frequency.");
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " [", C('A'), "] frequency.");
|
||||
}
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
// Parse frequency scaling parameter (X axis).
|
||||
// Parse X frequency scaling parameter
|
||||
if (parser.seenval('F')) {
|
||||
if (modeUsesDynFreq) {
|
||||
ftMotion.cfg.dynFreqK.x = parser.value_float();
|
||||
flag.report = true;
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("Wrong mode for [", C('F'), "] frequency scaling.");
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " [", C('F'), "] frequency scaling.");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Parse zeta parameter (X axis).
|
||||
// Parse X zeta parameter
|
||||
if (parser.seenval('I')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_IS_SHAPING(X)) {
|
||||
if (WITHIN(val, 0.01f, 1.0f)) {
|
||||
ftMotion.cfg.zeta[0] = val;
|
||||
ftMotion.cfg.zeta.x = val;
|
||||
flag.update = true;
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("Invalid X zeta [", C('I'), "] value."); // Zeta out of range.
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_A_NAME), " zeta [", C('I'), "] value."); // Zeta out of range
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("Wrong mode for zeta parameter.");
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " zeta parameter.");
|
||||
}
|
||||
|
||||
// Parse vtol parameter (X axis).
|
||||
// Parse X vtol parameter
|
||||
if (parser.seenval('Q')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_IS_EISHAPING(X)) {
|
||||
if (WITHIN(val, 0.00f, 1.0f)) {
|
||||
ftMotion.cfg.vtol[0] = val;
|
||||
ftMotion.cfg.vtol.x = val;
|
||||
flag.update = true;
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("Invalid X vtol [", C('Q'), "] value."); // VTol out of range.
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_A_NAME), " vtol [", C('Q'), "] value."); // VTol out of range.
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("Wrong mode for vtol parameter.");
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " vtol parameter.");
|
||||
}
|
||||
|
||||
#endif // HAS_X_AXIS
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
|
||||
// Parse frequency parameter (Y axis).
|
||||
// Parse Y frequency parameter
|
||||
if (parser.seenval('B')) {
|
||||
if (AXIS_IS_SHAPING(Y)) {
|
||||
const float val = parser.value_float();
|
||||
|
|
@ -366,56 +402,178 @@ void GcodeSuite::M493() {
|
|||
flag.update = flag.report = true;
|
||||
}
|
||||
else // Frequency out of range.
|
||||
SERIAL_ECHOLNPGM("Invalid frequency [", C('B'), "] value.");
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_B_NAME), " frequency [", C('B'), "] value.");
|
||||
}
|
||||
else // Mode doesn't use frequency.
|
||||
SERIAL_ECHOLNPGM("Wrong mode for [", C('B'), "] frequency.");
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " [", C('B'), "] frequency.");
|
||||
}
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
// Parse frequency scaling parameter (Y axis).
|
||||
// Parse Y frequency scaling parameter
|
||||
if (parser.seenval('H')) {
|
||||
if (modeUsesDynFreq) {
|
||||
ftMotion.cfg.dynFreqK.y = parser.value_float();
|
||||
flag.report = true;
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("Wrong mode for [", C('H'), "] frequency scaling.");
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " [", C('H'), "] frequency scaling.");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Parse zeta parameter (Y axis).
|
||||
// Parse Y zeta parameter
|
||||
if (parser.seenval('J')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_IS_SHAPING(Y)) {
|
||||
if (WITHIN(val, 0.01f, 1.0f)) {
|
||||
ftMotion.cfg.zeta[1] = val;
|
||||
ftMotion.cfg.zeta.y = val;
|
||||
flag.update = true;
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("Invalid Y zeta [", C('J'), "] value."); // Zeta Out of range
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_B_NAME), " zeta [", C('J'), "] value."); // Zeta out of range
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("Wrong mode for zeta parameter.");
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " zeta parameter.");
|
||||
}
|
||||
|
||||
// Parse vtol parameter (Y axis).
|
||||
// Parse Y vtol parameter
|
||||
if (parser.seenval('R')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_IS_EISHAPING(Y)) {
|
||||
if (WITHIN(val, 0.00f, 1.0f)) {
|
||||
ftMotion.cfg.vtol[1] = val;
|
||||
ftMotion.cfg.vtol.y = val;
|
||||
flag.update = true;
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("Invalid Y vtol [", C('R'), "] value."); // VTol out of range.
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_B_NAME), " vtol [", C('R'), "] value."); // VTol out of range.
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("Wrong mode for vtol parameter.");
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " vtol parameter.");
|
||||
}
|
||||
|
||||
#endif // HAS_Y_AXIS
|
||||
|
||||
#if ENABLED(FTM_SHAPER_Z)
|
||||
|
||||
// Parse Z frequency parameter
|
||||
if (parser.seenval('C')) {
|
||||
if (AXIS_IS_SHAPING(Z)) {
|
||||
const float val = parser.value_float();
|
||||
if (WITHIN(val, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2)) {
|
||||
ftMotion.cfg.baseFreq.z = val;
|
||||
flag.update = flag.report = true;
|
||||
}
|
||||
else // Frequency out of range.
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_C_NAME), " frequency [", C('C'), "] value.");
|
||||
}
|
||||
else // Mode doesn't use frequency.
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " [", C('C'), "] frequency.");
|
||||
}
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
// Parse Z frequency scaling parameter
|
||||
if (parser.seenval('L')) {
|
||||
if (modeUsesDynFreq) {
|
||||
ftMotion.cfg.dynFreqK.z = parser.value_float();
|
||||
flag.report = true;
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " [", C('L'), "] frequency scaling.");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Parse Z zeta parameter
|
||||
if (parser.seenval('O')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_IS_SHAPING(Z)) {
|
||||
if (WITHIN(val, 0.01f, 1.0f)) {
|
||||
ftMotion.cfg.zeta.z = val;
|
||||
flag.update = true;
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_C_NAME), " zeta [", C('O'), "] value."); // Zeta out of range
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " zeta parameter.");
|
||||
}
|
||||
|
||||
// Parse Z vtol parameter
|
||||
if (parser.seenval('M')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_IS_EISHAPING(Z)) {
|
||||
if (WITHIN(val, 0.00f, 1.0f)) {
|
||||
ftMotion.cfg.vtol.z = val;
|
||||
flag.update = true;
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_C_NAME), " vtol [", C('M'), "] value."); // VTol out of range.
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " vtol parameter.");
|
||||
}
|
||||
|
||||
#endif // FTM_SHAPER_Z
|
||||
|
||||
#if ENABLED(FTM_SHAPER_E)
|
||||
|
||||
// Parse E frequency parameter
|
||||
if (parser.seenval('W')) {
|
||||
if (AXIS_IS_SHAPING(E)) {
|
||||
const float val = parser.value_float();
|
||||
if (WITHIN(val, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2)) {
|
||||
ftMotion.cfg.baseFreq.e = val;
|
||||
flag.update = flag.report = true;
|
||||
}
|
||||
else // Frequency out of range.
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C('E'), " frequency [", C('W'), "] value.");
|
||||
}
|
||||
else // Mode doesn't use frequency.
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " [", C('W'), "] frequency.");
|
||||
}
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
// Parse E frequency scaling parameter
|
||||
if (parser.seenval('O')) {
|
||||
if (modeUsesDynFreq) {
|
||||
ftMotion.cfg.dynFreqK.e = parser.value_float();
|
||||
flag.report = true;
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " [", C('O'), "] frequency scaling.");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Parse E zeta parameter
|
||||
if (parser.seenval('U')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_IS_SHAPING(E)) {
|
||||
if (WITHIN(val, 0.01f, 1.0f)) {
|
||||
ftMotion.cfg.zeta.e = val;
|
||||
flag.update = true;
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C('E'), " zeta [", C('U'), "] value."); // Zeta out of range
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " zeta parameter.");
|
||||
}
|
||||
|
||||
// Parse E vtol parameter
|
||||
if (parser.seenval('V')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_IS_EISHAPING(E)) {
|
||||
if (WITHIN(val, 0.00f, 1.0f)) {
|
||||
ftMotion.cfg.vtol.e = val;
|
||||
flag.update = true;
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C('E'), " vtol [", C('V'), "] value."); // VTol out of range.
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " vtol parameter.");
|
||||
}
|
||||
|
||||
#endif // FTM_SHAPER_E
|
||||
|
||||
if (flag.update) ftMotion.update_shaping_params();
|
||||
|
||||
if (flag.report) say_shaping();
|
||||
|
|
|
|||
137
Marlin/src/gcode/feature/ft_motion/M494.cpp
Normal file
137
Marlin/src/gcode/feature/ft_motion/M494.cpp
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2025 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#include "../../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if ENABLED(FT_MOTION)
|
||||
|
||||
#include "../../gcode.h"
|
||||
#include "../../../module/ft_motion.h"
|
||||
#include "../../../module/stepper.h"
|
||||
#include "../../../module/planner.h"
|
||||
|
||||
static FSTR_P get_trajectory_type_name() {
|
||||
switch (ftMotion.getTrajectoryType()) {
|
||||
default:
|
||||
case TrajectoryType::TRAPEZOIDAL: return GET_TEXT_F(MSG_FTM_TRAPEZOIDAL);
|
||||
case TrajectoryType::POLY5: return GET_TEXT_F(MSG_FTM_POLY5);
|
||||
case TrajectoryType::POLY6: return GET_TEXT_F(MSG_FTM_POLY6);
|
||||
}
|
||||
}
|
||||
|
||||
void say_ftm_settings() {
|
||||
SERIAL_ECHOLN(F(" Trajectory: "), get_trajectory_type_name(), C('('), (uint8_t)ftMotion.getTrajectoryType(), C(')'));
|
||||
|
||||
const ft_config_t &c = ftMotion.cfg;
|
||||
|
||||
if (ftMotion.getTrajectoryType() == TrajectoryType::POLY6)
|
||||
SERIAL_ECHOLNPGM(" Poly6 Overshoot: ", p_float_t(c.poly6_acceleration_overshoot, 3));
|
||||
|
||||
#if ENABLED(FTM_SMOOTHING)
|
||||
#define _SMOO_REPORT(A) SERIAL_ECHOLN(F(" "), C(IAXIS_CHAR(_AXIS(A))), F(" smoothing time: "), p_float_t(c.smoothingTime.A, 3), C('s'));
|
||||
CARTES_MAP(_SMOO_REPORT);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GcodeSuite::M494_report(const bool forReplay/*=true*/) {
|
||||
TERN_(MARLIN_SMALL_BUILD, return);
|
||||
|
||||
const ft_config_t &c = ftMotion.cfg;
|
||||
|
||||
report_heading_etc(forReplay, F("FT Motion"));
|
||||
SERIAL_ECHOPGM(" M494 T", (uint8_t)ftMotion.getTrajectoryType());
|
||||
|
||||
#if ENABLED(FTM_SMOOTHING)
|
||||
SERIAL_ECHOPGM(
|
||||
CARTES_PAIRED_LIST(
|
||||
" X", c.smoothingTime.X, " Y", c.smoothingTime.Y,
|
||||
" Z", c.smoothingTime.Z, " E", c.smoothingTime.E
|
||||
)
|
||||
);
|
||||
#endif
|
||||
|
||||
if (ftMotion.getTrajectoryType() == TrajectoryType::POLY6)
|
||||
SERIAL_ECHOPGM(" O", c.poly6_acceleration_overshoot);
|
||||
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
||||
/**
|
||||
* M494: Set Fixed-time Motion Control parameters
|
||||
*
|
||||
* Parameters:
|
||||
* T<type> Set trajectory generator type (0=TRAPEZOIDAL, 1=POLY5, 2=POLY6)
|
||||
* O<overshoot> Set acceleration overshoot for POLY6 (1.25-1.875)
|
||||
* X<time> Set smoothing time for the X axis
|
||||
* Y<time> Set smoothing time for the Y axis
|
||||
* Z<time> Set smoothing time for the Z axis
|
||||
* E<time> Set smoothing time for the E axis
|
||||
*/
|
||||
void GcodeSuite::M494() {
|
||||
bool report = !parser.seen_any();
|
||||
|
||||
// Parse trajectory type parameter.
|
||||
if (parser.seenval('T')) {
|
||||
const int val = parser.value_int();
|
||||
if (WITHIN(val, 0, 2)) {
|
||||
planner.synchronize();
|
||||
ftMotion.setTrajectoryType((TrajectoryType)val);
|
||||
report = true;
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Invalid trajectory type [T] value. Use 0=TRAPEZOIDAL, 1=POLY5, 2=POLY6");
|
||||
}
|
||||
|
||||
// Parse overshoot parameter.
|
||||
if (parser.seenval('O')) {
|
||||
const float val = parser.value_float();
|
||||
if (WITHIN(val, 1.25f, 1.875f)) {
|
||||
ftMotion.cfg.poly6_acceleration_overshoot = val;
|
||||
report = true;
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Invalid overshoot [O] value. Range 1.25-1.875");
|
||||
}
|
||||
|
||||
#if ENABLED(FTM_SMOOTHING)
|
||||
|
||||
#define SMOOTH_SET(A,N) \
|
||||
if (parser.seenval(CHARIFY(A))) { \
|
||||
const float val = parser.value_float(); \
|
||||
if (WITHIN(val, 0.0f, FTM_MAX_SMOOTHING_TIME)) { \
|
||||
ftMotion.set_smoothing_time(_AXIS(A), val); \
|
||||
report = true; \
|
||||
} \
|
||||
else \
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C(N), " smoothing time [", C(CHARIFY(A)), "] value."); \
|
||||
}
|
||||
|
||||
CARTES_GANG(
|
||||
SMOOTH_SET(X, STEPPER_A_NAME), SMOOTH_SET(Y, STEPPER_B_NAME),
|
||||
SMOOTH_SET(Z, STEPPER_C_NAME), SMOOTH_SET(E, 'E')
|
||||
);
|
||||
|
||||
#endif // FTM_SMOOTHING
|
||||
|
||||
if (report) say_ftm_settings();
|
||||
}
|
||||
|
||||
#endif // FT_MOTION
|
||||
|
|
@ -40,8 +40,8 @@
|
|||
* M260 B<byte-2 value in base 10>
|
||||
* M260 B<byte-3 value in base 10>
|
||||
*
|
||||
* M260 S1 ; Send the buffered data and reset the buffer
|
||||
* M260 R1 ; Reset the buffer without sending data
|
||||
* M260 S ; Send the buffered data and reset the buffer
|
||||
* M260 R ; Reset the buffer without sending data
|
||||
*/
|
||||
void GcodeSuite::M260() {
|
||||
// Set the target address
|
||||
|
|
@ -51,10 +51,10 @@ void GcodeSuite::M260() {
|
|||
if (parser.seenval('B')) i2c.addbyte(parser.value_byte());
|
||||
|
||||
// Flush the buffer to the bus
|
||||
if (parser.seen('S')) i2c.send();
|
||||
if (parser.seen_test('S')) i2c.send();
|
||||
|
||||
// Reset and rewind the buffer
|
||||
else if (parser.seen('R')) i2c.reset();
|
||||
else if (parser.seen_test('R')) i2c.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
69
Marlin/src/gcode/feature/i2c/M265.cpp
Normal file
69
Marlin/src/gcode/feature/i2c/M265.cpp
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(I2C_SCANNER)
|
||||
|
||||
#include "../../../libs/hex_print.h"
|
||||
#include "../../gcode.h"
|
||||
#include <Wire.h> // Include Wire library for I2C communication
|
||||
|
||||
/**
|
||||
* M265: I2C Scanner - Scan for I2C devices on DOGLCD I2C pins
|
||||
*
|
||||
* Usage: M265
|
||||
*
|
||||
* Scans I2C addresses 0x08 to 0x77 and reports any responding devices.
|
||||
*/
|
||||
void GcodeSuite::M265() {
|
||||
Wire.begin();
|
||||
int device_count = 0;
|
||||
|
||||
SERIAL_ECHOLNPGM("Scanning I2C (0x08-0x77)...");
|
||||
for (uint8_t address = 0x08; address <= 0x77; address++) {
|
||||
Wire.beginTransmission(address);
|
||||
const uint8_t error = Wire.endTransmission();
|
||||
|
||||
if (error == 0) {
|
||||
// Device found
|
||||
device_count++;
|
||||
SERIAL_ECHOLNPGM("I2C device found at address 0x", hex_byte(address));
|
||||
}
|
||||
else if (error == 4)
|
||||
SERIAL_ECHOLNPGM("Unknown error at address 0x", hex_byte(address));
|
||||
|
||||
safe_delay(5); // Small delay between scans
|
||||
}
|
||||
|
||||
SERIAL_ECHOPGM("I2C scan complete. ");
|
||||
if (device_count == 0)
|
||||
SERIAL_ECHOLNPGM("No I2C devices found");
|
||||
else {
|
||||
SERIAL_ECHOLN("Found ", device_count, " device");
|
||||
if (device_count > 1) SERIAL_CHAR('s');
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // I2C_SCANNER
|
||||
|
|
@ -33,7 +33,7 @@ inline void echo_mix() {
|
|||
SERIAL_ECHOPGM(" (", mixer.mix[0], "%|", mixer.mix[1], "%)");
|
||||
}
|
||||
|
||||
inline void echo_zt(const int t, const_float_t z) {
|
||||
inline void echo_zt(const int t, const float z) {
|
||||
mixer.update_mix_from_vtool(t);
|
||||
SERIAL_ECHOPGM_P(SP_Z_STR, z, SP_T_STR, t);
|
||||
echo_mix();
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ void GcodeSuite::M701() {
|
|||
tool_change(target_extruder);
|
||||
#endif
|
||||
|
||||
auto move_z_by = [](const_float_t zdist) {
|
||||
auto move_z_by = [](const float zdist) {
|
||||
if (zdist) {
|
||||
destination = current_position;
|
||||
destination.z += zdist;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@
|
|||
* S<bool> : Reset and enable/disable the runout sensor
|
||||
* H<bool> : Enable/disable host handling of filament runout
|
||||
* D<linear> : Extra distance to continue after runout is triggered
|
||||
*
|
||||
* With FILAMENT_SWITCH_AND_MOTION:
|
||||
* L<linear> : Missing motion length to consider a jam
|
||||
*/
|
||||
void GcodeSuite::M412() {
|
||||
if (parser.seen("RS"
|
||||
|
|
@ -51,7 +54,7 @@ void GcodeSuite::M412() {
|
|||
if (parser.seenval('D')) runout.set_runout_distance(parser.value_linear_units());
|
||||
#endif
|
||||
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
|
||||
if (parser.seenval('M')) runout.set_motion_distance(parser.value_linear_units());
|
||||
if (parser.seenval('L')) runout.set_motion_distance(parser.value_linear_units());
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
|
|
@ -80,7 +83,7 @@ void GcodeSuite::M412_report(const bool forReplay/*=true*/) {
|
|||
, " D", LINEAR_UNIT(runout.runout_distance())
|
||||
#endif
|
||||
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
|
||||
, " M", LINEAR_UNIT(runout.motion_distance())
|
||||
, " L", LINEAR_UNIT(runout.motion_distance())
|
||||
#endif
|
||||
, " ; Sensor ", ON_OFF(runout.enabled)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -126,16 +126,13 @@ void GcodeSuite::say_units() {
|
|||
* Return -1 if the T parameter is out of range
|
||||
*/
|
||||
int8_t GcodeSuite::get_target_extruder_from_command() {
|
||||
#if HAS_TOOLCHANGE
|
||||
if (parser.seenval('T')) {
|
||||
const int8_t e = parser.value_byte();
|
||||
if (e < EXTRUDERS) return e;
|
||||
SERIAL_ECHO_START();
|
||||
SERIAL_CHAR('M'); SERIAL_ECHO(parser.codenum);
|
||||
SERIAL_ECHOLNPGM(" " STR_INVALID_EXTRUDER " ", e);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
if (parser.seenval('T')) {
|
||||
const int8_t e = parser.value_byte();
|
||||
if (e < EXTRUDERS) return e;
|
||||
SERIAL_ECHO_START();
|
||||
SERIAL_ECHOLN(C('M'), parser.codenum, F(" " STR_INVALID_EXTRUDER " "), e);
|
||||
return -1;
|
||||
}
|
||||
return active_extruder;
|
||||
}
|
||||
|
||||
|
|
@ -151,7 +148,7 @@ int8_t GcodeSuite::get_target_e_stepper_from_command(const int8_t dval/*=-1*/) {
|
|||
if (dval == -2) return dval;
|
||||
|
||||
SERIAL_ECHO_START();
|
||||
SERIAL_CHAR('M'); SERIAL_ECHO(parser.codenum);
|
||||
SERIAL_ECHO(C('M'), parser.codenum);
|
||||
if (e == -1)
|
||||
SERIAL_ECHOLNPGM(" " STR_E_STEPPER_NOT_SPECIFIED);
|
||||
else
|
||||
|
|
@ -829,6 +826,10 @@ void GcodeSuite::process_parsed_command(bool no_ok/*=false*/) {
|
|||
case 261: M261(); break; // M261: Request data from an i2c slave
|
||||
#endif
|
||||
|
||||
#if ENABLED(I2C_SCANNER)
|
||||
case 265: M265(); break; // M265: I2C Scanner
|
||||
#endif
|
||||
|
||||
#if ENABLED(PREVENT_COLD_EXTRUSION)
|
||||
case 302: M302(); break; // M302: Allow cold extrudes (set the minimum extrude temperature)
|
||||
#endif
|
||||
|
|
@ -922,6 +923,9 @@ void GcodeSuite::process_parsed_command(bool no_ok/*=false*/) {
|
|||
|
||||
#if ENABLED(FT_MOTION)
|
||||
case 493: M493(); break; // M493: Fixed-Time Motion control
|
||||
#if ENABLED(FTM_SMOOTHING)
|
||||
case 494: M494(); break; // M494: Fixed-Time Motion extras
|
||||
#endif
|
||||
#endif
|
||||
|
||||
case 500: M500(); break; // M500: Store settings in EEPROM
|
||||
|
|
|
|||
|
|
@ -211,6 +211,7 @@
|
|||
* M256 - Set LCD brightness: 'M256 B<brightness>' (0-255). (Requires an LCD with brightness control)
|
||||
* M260 - i2c Send Data (Requires EXPERIMENTAL_I2CBUS)
|
||||
* M261 - i2c Request Data (Requires EXPERIMENTAL_I2CBUS)
|
||||
* M265 - i2c Scanner - Scan for I2C devices. (Requires I2C_SCANNER)
|
||||
* M280 - Set servo position absolute: 'M280 P<index> S<angle|µs>'. (Requires servos)
|
||||
* M281 - Set servo min|max position: 'M281 P<index> L<min> U<max>'. (Requires EDITABLE_SERVO_ANGLES)
|
||||
* M282 - Detach servo: 'M282 P<index>'. (Requires SERVO_DETACH_GCODE)
|
||||
|
|
@ -965,6 +966,10 @@ private:
|
|||
static void M261();
|
||||
#endif
|
||||
|
||||
#if ENABLED(I2C_SCANNER)
|
||||
static void M265();
|
||||
#endif
|
||||
|
||||
#if HAS_SERVOS
|
||||
static void M280();
|
||||
#if ENABLED(EDITABLE_SERVO_ANGLES)
|
||||
|
|
@ -1050,6 +1055,7 @@ private:
|
|||
|
||||
#if HAS_BED_PROBE
|
||||
static void M401();
|
||||
static void M401_report(const bool forReplay=true);
|
||||
static void M402();
|
||||
#endif
|
||||
|
||||
|
|
@ -1104,6 +1110,8 @@ private:
|
|||
#if ENABLED(FT_MOTION)
|
||||
static void M493();
|
||||
static void M493_report(const bool forReplay=true);
|
||||
static void M494();
|
||||
static void M494_report(const bool forReplay=true);
|
||||
#endif
|
||||
|
||||
static void M500();
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ struct ProgStr {
|
|||
constexpr explicit operator bool() const { return ptr != nullptr; }
|
||||
};
|
||||
|
||||
static void config_prefix(ProgStr name, ProgStr pref=nullptr, int8_t ind=-1) {
|
||||
static void config_prefix(ProgStr name, ProgStr pref=nullptr, const int8_t ind=-1) {
|
||||
SERIAL_ECHOPGM("Config:");
|
||||
if (pref) SERIAL_ECHOPGM_P(static_cast<PGM_P>(pref));
|
||||
if (ind >= 0) { SERIAL_ECHO(ind); SERIAL_CHAR(':'); }
|
||||
|
|
@ -57,15 +57,16 @@ static void config_prefix(ProgStr name, ProgStr pref=nullptr, int8_t ind=-1) {
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
static void config_line(ProgStr name, const T val, ProgStr pref=nullptr, int8_t ind=-1) {
|
||||
static void config_line(ProgStr name, const T val, ProgStr pref=nullptr, const int8_t ind=-1) {
|
||||
config_prefix(name, pref, ind);
|
||||
SERIAL_ECHOLN(val);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void config_line_e(int8_t e, ProgStr name, const T val) {
|
||||
static void config_line_e(const int8_t e, ProgStr name, const T val) {
|
||||
config_line(name, val, PSTR("Extr."), e + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* M360: Report Firmware configuration
|
||||
* in RepRapFirmware-compatible format
|
||||
|
|
@ -138,8 +139,7 @@ void GcodeSuite::M360() {
|
|||
if (TERN0(HAS_Y_AXIS, planner.max_jerk.x == planner.max_jerk.y))
|
||||
config_line(F("XY"), planner.max_jerk.x, JERK_STR);
|
||||
else {
|
||||
TERN_(HAS_X_AXIS, _REPORT_JERK(X));
|
||||
TERN_(HAS_Y_AXIS, _REPORT_JERK(Y));
|
||||
XY_MAP(_REPORT_JERK);
|
||||
}
|
||||
TERN_(HAS_Z_AXIS, config_line(Z_STR, planner.max_jerk.z, JERK_STR));
|
||||
SECONDARY_AXIS_MAP(_REPORT_JERK);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
#if ENABLED(BABYSTEP_ZPROBE_OFFSET)
|
||||
|
||||
FORCE_INLINE void mod_probe_offset(const_float_t offs) {
|
||||
FORCE_INLINE void mod_probe_offset(const float offs) {
|
||||
if (TERN1(BABYSTEP_HOTEND_Z_OFFSET, active_extruder == 0)) {
|
||||
probe.offset.z += offs;
|
||||
SERIAL_ECHO_MSG(STR_PROBE_OFFSET " " STR_Z, probe.offset.z);
|
||||
|
|
|
|||
|
|
@ -301,8 +301,8 @@ public:
|
|||
// Units modes: Inches, Fahrenheit, Kelvin
|
||||
|
||||
#if ENABLED(INCH_MODE_SUPPORT)
|
||||
static float mm_to_linear_unit(const_float_t mm) { return mm / linear_unit_factor; }
|
||||
static float mm_to_volumetric_unit(const_float_t mm) { return mm / (volumetric_enabled ? volumetric_unit_factor : linear_unit_factor); }
|
||||
static float mm_to_linear_unit(const float mm) { return mm / linear_unit_factor; }
|
||||
static float mm_to_volumetric_unit(const float mm) { return mm / (volumetric_enabled ? volumetric_unit_factor : linear_unit_factor); }
|
||||
|
||||
// Init linear units by constructor
|
||||
GCodeParser() { set_input_linear_units(LINEARUNIT_MM); }
|
||||
|
|
@ -324,16 +324,16 @@ public:
|
|||
return linear_unit_factor;
|
||||
}
|
||||
|
||||
static float linear_value_to_mm(const_float_t v) { return v * linear_unit_factor; }
|
||||
static float linear_value_to_mm(const float v) { return v * linear_unit_factor; }
|
||||
static float axis_value_to_mm(const AxisEnum axis, const float v) { return v * axis_unit_factor(axis); }
|
||||
static float per_axis_value(const AxisEnum axis, const float v) { return v / axis_unit_factor(axis); }
|
||||
|
||||
#else
|
||||
|
||||
static constexpr float mm_to_linear_unit(const_float_t mm) { return mm; }
|
||||
static constexpr float mm_to_volumetric_unit(const_float_t mm) { return mm; }
|
||||
static constexpr float mm_to_linear_unit(const float mm) { return mm; }
|
||||
static constexpr float mm_to_volumetric_unit(const float mm) { return mm; }
|
||||
|
||||
static constexpr float linear_value_to_mm(const_float_t v) { return v; }
|
||||
static constexpr float linear_value_to_mm(const float v) { return v; }
|
||||
static constexpr float axis_value_to_mm(const AxisEnum, const float v) { return v; }
|
||||
static constexpr float per_axis_value(const AxisEnum, const float v) { return v; }
|
||||
|
||||
|
|
@ -420,17 +420,17 @@ public:
|
|||
void unknown_command_warning();
|
||||
|
||||
// Provide simple value accessors with default option
|
||||
static char* stringval(const char c, char * const dval=nullptr) { return seenval(c) ? value_string() : dval; }
|
||||
static char* stringval(const char c, char * const dval=nullptr) { return seenval(c) ? value_string() : dval; }
|
||||
static float floatval(const char c, const float dval=0.0) { return seenval(c) ? value_float() : dval; }
|
||||
static bool boolval(const char c, const bool dval=false) { return seenval(c) ? value_bool() : (seen(c) ? true : dval); }
|
||||
static uint8_t byteval(const char c, const uint8_t dval=0) { return seenval(c) ? value_byte() : dval; }
|
||||
static int16_t intval(const char c, const int16_t dval=0) { return seenval(c) ? value_int() : dval; }
|
||||
static uint16_t ushortval(const char c, const uint16_t dval=0) { return seenval(c) ? value_ushort() : dval; }
|
||||
static int32_t longval(const char c, const int32_t dval=0) { return seenval(c) ? value_long() : dval; }
|
||||
static uint32_t ulongval(const char c, const uint32_t dval=0) { return seenval(c) ? value_ulong() : dval; }
|
||||
static bool boolval(const char c, const bool dval=false) { return seenval(c) ? value_bool() : (seen(c) ? true : dval); }
|
||||
static uint8_t byteval(const char c, const uint8_t dval=0) { return seenval(c) ? value_byte() : dval; }
|
||||
static int16_t intval(const char c, const int16_t dval=0) { return seenval(c) ? value_int() : dval; }
|
||||
static uint16_t ushortval(const char c, const uint16_t dval=0) { return seenval(c) ? value_ushort() : dval; }
|
||||
static int32_t longval(const char c, const int32_t dval=0) { return seenval(c) ? value_long() : dval; }
|
||||
static uint32_t ulongval(const char c, const uint32_t dval=0) { return seenval(c) ? value_ulong() : dval; }
|
||||
static float linearval(const char c, const float dval=0) { return seenval(c) ? value_linear_units() : dval; }
|
||||
static float axisunitsval(const char c, const AxisEnum a, const float dval=0)
|
||||
{ return seenval(c) ? value_axis_units(a) : dval; }
|
||||
{ return seenval(c) ? value_axis_units(a) : dval; }
|
||||
static celsius_t celsiusval(const char c, const celsius_t dval=0) { return seenval(c) ? value_celsius() : dval; }
|
||||
static feedRate_t feedrateval(const char c, const feedRate_t dval=0) { return seenval(c) ? value_feedrate() : dval; }
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
#include "../../feature/probe_temp_comp.h"
|
||||
#endif
|
||||
|
||||
#if FT_MOTION_DISABLE_FOR_PROBING
|
||||
#if ENABLED(FT_MOTION)
|
||||
#include "../../module/ft_motion.h"
|
||||
#endif
|
||||
|
||||
|
|
@ -80,9 +80,8 @@ void GcodeSuite::G30() {
|
|||
// Use 'C' to set Probe Temperature Compensation ON/OFF (on by default)
|
||||
TERN_(HAS_PTC, ptc.set_enabled(parser.boolval('C', true)));
|
||||
|
||||
#if FT_MOTION_DISABLE_FOR_PROBING
|
||||
FTMotionDisableInScope FT_Disabler; // Disable Fixed-Time Motion for probing
|
||||
#endif
|
||||
// Potentially disable Fixed-Time Motion for probing
|
||||
TERN_(FT_MOTION, FTMotionDisableInScope FT_Disabler);
|
||||
|
||||
// Probe the bed, optionally raise, and return the measured height
|
||||
const float measured_z = probe.probe_at_point(probepos, raise_after);
|
||||
|
|
|
|||
|
|
@ -57,6 +57,17 @@ void GcodeSuite::M401() {
|
|||
report_current_position();
|
||||
}
|
||||
|
||||
void GcodeSuite::M401_report(const bool forReplay/*=true*/) {
|
||||
TERN_(MARLIN_SMALL_BUILD, return);
|
||||
|
||||
#if HAS_BLTOUCH_HS_MODE
|
||||
if (!forReplay) {
|
||||
report_heading_etc(forReplay, F("BLTouch HS mode"));
|
||||
SERIAL_ECHOLNPGM(" M401 S", bltouch.high_speed_mode, " ; ", ON_OFF(bltouch.high_speed_mode));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* M402: Deactivate and stow the Z probe
|
||||
* R<bool> Remain in place after stowing (and before deactivating) the probe
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
*/
|
||||
#if EXTRUDERS
|
||||
#define HAS_EXTRUDERS 1
|
||||
#define HAS_E_AXIS 1
|
||||
#if EXTRUDERS > 1
|
||||
#define HAS_MULTI_EXTRUDER 1
|
||||
#endif
|
||||
|
|
@ -70,8 +71,11 @@
|
|||
#undef HOTEND_OVERSHOOT
|
||||
#undef DISABLE_E
|
||||
#undef PREVENT_LENGTHY_EXTRUDE
|
||||
#undef FILAMENT_SWITCH_AND_MOTION
|
||||
#undef FILAMENT_RUNOUT_SENSOR
|
||||
#undef FILAMENT_RUNOUT_DISTANCE_MM
|
||||
#undef FILAMENT_MOTION_SENSOR
|
||||
#undef FILAMENT_MOTION_DISTANCE_MM
|
||||
#undef DISABLE_OTHER_EXTRUDERS
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -99,8 +99,9 @@
|
|||
*
|
||||
* DOGLCD : Run a Graphical LCD through U8GLib (with MarlinUI)
|
||||
* IS_ULTIPANEL : Define LCD_PINS_D5/6/7 for direct-connected "Ultipanel" LCDs
|
||||
* IS_NEWPANEL : A panel with encoder pins: ENC EN1 EN2 BEEPER.
|
||||
* HAS_WIRED_LCD : Ultra LCD, not necessarily Ultipanel.
|
||||
* IS_RRD_SC : Common RRD Smart Controller digital interface pins
|
||||
* IS_RRD_SC : Common RRD Smart Controller digital interface pins: RS EN D4 D5 D6 D7.
|
||||
* IS_RRD_FG_SC : Common RRD Full Graphical Smart Controller digital interface pins
|
||||
* IS_U8GLIB_ST7920 : Most common DOGM display SPI interface, supporting a "lightweight" display mode.
|
||||
* U8GLIB_SH1106 : SH1106 OLED with I2C interface via U8GLib
|
||||
|
|
@ -354,7 +355,22 @@
|
|||
// ...and 128x64 SPI OLED LCDs (SSD1306 / SH1106)
|
||||
#if ANY(U8GLIB_SSD1306, U8GLIB_SSD1309, U8GLIB_SH1106)
|
||||
#define HAS_U8GLIB_I2C_OLED 1
|
||||
|
||||
// Define this to reduce build size and optimize performance
|
||||
//#define COMPILE_TIME_I2C_IS_HARDWARE true // true: Hardware false: Software undefined: Solve at runtime
|
||||
|
||||
#ifdef COMPILE_TIME_I2C_IS_HARDWARE
|
||||
#if COMPILE_TIME_I2C_IS_HARDWARE
|
||||
#define U8G_USES_HW_I2C
|
||||
#else
|
||||
#define U8G_USES_SW_I2C
|
||||
#endif
|
||||
#else
|
||||
#define U8G_USES_HW_I2C
|
||||
#define U8G_USES_SW_I2C
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ANY(HAS_U8GLIB_I2C_OLED, U8GLIB_SSD1306_SPI, U8GLIB_SH1106_SPI)
|
||||
#define HAS_WIRED_LCD 1
|
||||
#define DOGLCD
|
||||
|
|
@ -875,3 +891,78 @@
|
|||
#if LED_POWEROFF_TIMEOUT > 0
|
||||
#define HAS_LED_POWEROFF_TIMEOUT 1
|
||||
#endif
|
||||
|
||||
#define LCD_ENABLED_COUNT 0 \
|
||||
+ ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) \
|
||||
+ ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) \
|
||||
+ (ENABLED(U8GLIB_SSD1306) && DISABLED(IS_U8GLIB_SSD1306)) \
|
||||
+ (ENABLED(MINIPANEL) && NONE(MKS_MINI_12864, ENDER2_STOCKDISPLAY)) \
|
||||
+ (ENABLED(MKS_MINI_12864) && NONE(MKS_LCD12864A, MKS_LCD12864B)) \
|
||||
+ (ENABLED(FYSETC_MINI_12864_2_1) && NONE(MKS_MINI_12864_V3, BTT_MINI_12864, BEEZ_MINI_12864)) \
|
||||
+ COUNT_ENABLED(MKS_MINI_12864_V3, BTT_MINI_12864, BEEZ_MINI_12864) \
|
||||
+ (ENABLED(EXTENSIBLE_UI) && DISABLED(IS_EXTUI)) \
|
||||
+ (DISABLED(IS_LEGACY_TFT) && ENABLED(TFT_GENERIC)) \
|
||||
+ (ENABLED(IS_LEGACY_TFT) && COUNT_ENABLED(TFT_320x240, TFT_320x240_SPI, TFT_480x320, TFT_480x320_SPI)) \
|
||||
+ COUNT_ENABLED(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON, ANYCUBIC_TFT35, ANYCUBIC_LCD_VYPER) \
|
||||
+ DGUS_UI_IS(ORIGIN) + DGUS_UI_IS(FYSETC) + DGUS_UI_IS(HIPRECY) + DGUS_UI_IS(MKS) + DGUS_UI_IS(RELOADED) + DGUS_UI_IS(IA_CREALITY) \
|
||||
+ COUNT_ENABLED(ENDER2_STOCKDISPLAY, CR10_STOCKDISPLAY) \
|
||||
+ COUNT_ENABLED(DWIN_CREALITY_LCD, DWIN_LCD_PROUI, DWIN_CREALITY_LCD_JYERSUI, DWIN_MARLINUI_PORTRAIT, DWIN_MARLINUI_LANDSCAPE, SOVOL_SV06_RTS) \
|
||||
+ COUNT_ENABLED(FYSETC_MINI_12864_X_X, FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0, FYSETC_GENERIC_12864_1_1) \
|
||||
+ COUNT_ENABLED(LCD_SAINSMART_I2C_1602, LCD_SAINSMART_I2C_2004) \
|
||||
+ COUNT_ENABLED(MKS_12864OLED, MKS_12864OLED_SSD1306) \
|
||||
+ COUNT_ENABLED(MKS_TS35_V2_0, MKS_ROBIN_TFT24, MKS_ROBIN_TFT28, MKS_ROBIN_TFT32, MKS_ROBIN_TFT35, MKS_ROBIN_TFT43, \
|
||||
MKS_ROBIN_TFT_V1_1R, ANET_ET4_TFT28, ANET_ET5_TFT35, BIQU_BX_TFT70, BTT_TFT35_SPI_V1_0) \
|
||||
+ COUNT_ENABLED(TFTGLCD_PANEL_SPI, TFTGLCD_PANEL_I2C) \
|
||||
+ COUNT_ENABLED(VIKI2, miniVIKI) \
|
||||
+ ENABLED(WYH_L12864) \
|
||||
+ COUNT_ENABLED(ZONESTAR_12864LCD, ZONESTAR_12864OLED, ZONESTAR_12864OLED_SSD1306) \
|
||||
+ COUNT_ENABLED(ANET_FULL_GRAPHICS_LCD, CTC_A10S_A13) \
|
||||
+ ENABLED(AZSMZ_12864) \
|
||||
+ ENABLED(BQ_LCD_SMART_CONTROLLER) \
|
||||
+ ENABLED(CARTESIO_UI) \
|
||||
+ ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) \
|
||||
+ ENABLED(FF_INTERFACEBOARD) \
|
||||
+ ENABLED(FYSETC_242_OLED_12864) \
|
||||
+ ENABLED(G3D_PANEL) \
|
||||
+ ENABLED(LCD_FOR_MELZI) \
|
||||
+ ENABLED(LCD_I2C_PANELOLU2) \
|
||||
+ ENABLED(LCD_I2C_VIKI) \
|
||||
+ ENABLED(LCM1602) \
|
||||
+ ENABLED(LONGER_LK_TFT28) \
|
||||
+ ENABLED(MAKEBOARD_MINI_2_LINE_DISPLAY_1602) \
|
||||
+ ENABLED(MAKRPANEL) \
|
||||
+ ENABLED(MALYAN_LCD) \
|
||||
+ ENABLED(NEXTION_TFT) \
|
||||
+ ENABLED(MKS_LCD12864A) \
|
||||
+ ENABLED(MKS_LCD12864B) \
|
||||
+ ENABLED(OLED_PANEL_TINYBOY2) \
|
||||
+ ENABLED(OVERLORD_OLED) \
|
||||
+ ENABLED(PANEL_ONE) \
|
||||
+ ENABLED(RA_CONTROL_PANEL) \
|
||||
+ ENABLED(RADDS_DISPLAY) \
|
||||
+ ENABLED(REPRAPWORLD_GRAPHICAL_LCD) \
|
||||
+ ENABLED(RIGIDBOT_PANEL) \
|
||||
+ ENABLED(SAV_3DGLCD) \
|
||||
+ ENABLED(SAV_3DLCD) \
|
||||
+ ENABLED(SILVER_GATE_GLCD_CONTROLLER) \
|
||||
+ ENABLED(TFT_TRONXY_X5SA) \
|
||||
+ ENABLED(TOUCH_UI_FTDI_EVE) \
|
||||
+ ENABLED(U8GLIB_SH1106_EINSTART) \
|
||||
+ ENABLED(ULTI_CONTROLLER) \
|
||||
+ ENABLED(ULTIMAKERCONTROLLER) \
|
||||
+ ENABLED(ULTIPANEL) \
|
||||
+ ENABLED(ULTRA_LCD) \
|
||||
+ ENABLED(YHCB2004) \
|
||||
+ ENABLED(ZONESTAR_LCD) \
|
||||
+ ENABLED(K3D_FULL_GRAPHIC_SMART_CONTROLLER) \
|
||||
+ ENABLED(K3D_242_OLED_CONTROLLER)
|
||||
|
||||
#if LCD_ENABLED_COUNT > 0
|
||||
#define HAS_LCD_SELECTED 1
|
||||
#if LCD_ENABLED_COUNT > 1
|
||||
#error "Please select only one LCD controller option."
|
||||
#endif
|
||||
#endif
|
||||
#undef LCD_ENABLED_COUNT
|
||||
#undef IS_U8GLIB_SSD1306
|
||||
#undef IS_EXTUI
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@
|
|||
#if !HAS_BED_PROBE
|
||||
#undef BABYSTEP_ZPROBE_OFFSET
|
||||
#undef PROBING_USE_CURRENT_HOME
|
||||
#undef FTM_HOME_AND_PROBE
|
||||
#endif
|
||||
#if !HAS_STOWABLE_PROBE
|
||||
#undef PROBE_DEPLOY_STOW_MENU
|
||||
|
|
@ -237,6 +238,8 @@
|
|||
#undef LIN_ADVANCE
|
||||
#undef SMOOTH_LIN_ADVANCE
|
||||
#undef MANUAL_E_MOVES_RELATIVE
|
||||
#undef MPCTEMP
|
||||
#undef MPC_AUTOTUNE
|
||||
#undef PID_EXTRUSION_SCALING
|
||||
#undef SHOW_TEMP_ADC_VALUES
|
||||
#undef STEALTHCHOP_E
|
||||
|
|
@ -340,7 +343,11 @@
|
|||
#endif
|
||||
|
||||
// Linear advance uses Jerk since E is an isolated axis
|
||||
#if ALL(HAS_JUNCTION_DEVIATION, LIN_ADVANCE)
|
||||
#if ALL(FT_MOTION, HAS_EXTRUDERS)
|
||||
#define FTM_HAS_LIN_ADVANCE 1
|
||||
#endif
|
||||
|
||||
#if HAS_JUNCTION_DEVIATION && ANY(LIN_ADVANCE, FTM_HAS_LIN_ADVANCE)
|
||||
#define HAS_LINEAR_E_JERK 1
|
||||
#endif
|
||||
|
||||
|
|
@ -1518,14 +1525,21 @@
|
|||
#if ENABLED(FT_MOTION)
|
||||
#if HAS_X_AXIS
|
||||
#define HAS_FTM_SHAPING 1
|
||||
#define FTM_SHAPER_X
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
#define FTM_SHAPER_Y
|
||||
#endif
|
||||
#if !HAS_Z_AXIS
|
||||
#undef FTM_SHAPER_Z
|
||||
#endif
|
||||
#if !HAS_EXTRUDERS
|
||||
#undef FTM_SHAPER_E
|
||||
#endif
|
||||
#if ENABLED(FTM_UNIFIED_BWS)
|
||||
#define FTM_WINDOW_SIZE FTM_BW_SIZE
|
||||
#define FTM_BATCH_SIZE FTM_BW_SIZE
|
||||
#endif
|
||||
#if ANY(BIQU_MICROPROBE_V1, BIQU_MICROPROBE_V2)
|
||||
#define FT_MOTION_DISABLE_FOR_PROBING 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Multi-Stepping Limit
|
||||
|
|
|
|||
|
|
@ -102,6 +102,35 @@
|
|||
#define AXIS9_NAME 'W'
|
||||
#endif
|
||||
|
||||
// G-code parameters where XYZ are invariant but IJKUVW can be renamed
|
||||
#ifndef AXIS1_PARAM
|
||||
#define AXIS1_PARAM 'X'
|
||||
#endif
|
||||
#ifndef AXIS2_PARAM
|
||||
#define AXIS2_PARAM 'Y'
|
||||
#endif
|
||||
#ifndef AXIS3_PARAM
|
||||
#define AXIS3_PARAM 'Z'
|
||||
#endif
|
||||
#ifndef AXIS4_PARAM
|
||||
#define AXIS4_PARAM AXIS4_NAME
|
||||
#endif
|
||||
#ifndef AXIS5_PARAM
|
||||
#define AXIS5_PARAM AXIS5_NAME
|
||||
#endif
|
||||
#ifndef AXIS6_PARAM
|
||||
#define AXIS6_PARAM AXIS6_NAME
|
||||
#endif
|
||||
#ifndef AXIS7_PARAM
|
||||
#define AXIS7_PARAM AXIS7_NAME
|
||||
#endif
|
||||
#ifndef AXIS8_PARAM
|
||||
#define AXIS8_PARAM AXIS8_NAME
|
||||
#endif
|
||||
#ifndef AXIS9_PARAM
|
||||
#define AXIS9_PARAM AXIS9_NAME
|
||||
#endif
|
||||
|
||||
#if HAS_X_AXIS
|
||||
#define X_MAX_LENGTH (X_MAX_POS - (X_MIN_POS))
|
||||
#endif
|
||||
|
|
@ -3622,7 +3651,7 @@
|
|||
#endif
|
||||
|
||||
// Flag whether hex_print.cpp is needed
|
||||
#if ANY(AUTO_BED_LEVELING_UBL, M100_FREE_MEMORY_WATCHER, DEBUG_GCODE_PARSER, TMC_DEBUG, MARLIN_DEV_MODE, DEBUG_CARDREADER, M20_TIMESTAMP_SUPPORT, HAS_STM32_UID)
|
||||
#if ANY(AUTO_BED_LEVELING_UBL, M100_FREE_MEMORY_WATCHER, DEBUG_GCODE_PARSER, TMC_DEBUG, MARLIN_DEV_MODE, DEBUG_CARDREADER, M20_TIMESTAMP_SUPPORT, HAS_STM32_UID, I2C_SCANNER)
|
||||
#define NEED_HEX_PRINT 1
|
||||
#endif
|
||||
|
||||
|
|
@ -3630,3 +3659,19 @@
|
|||
#if ALL(SPI_FLASH, HAS_MEDIA, MARLIN_DEV_MODE)
|
||||
#define SPI_FLASH_BACKUP 1
|
||||
#endif
|
||||
|
||||
// Fixed-Time Motion
|
||||
#if ENABLED(FT_MOTION)
|
||||
#define FTM_TS (1.0f / FTM_FS) // (s) Time step for trajectory generation. (Reciprocal of FTM_FS)
|
||||
#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_RATIO (FTM_FS / FTM_MIN_SHAPE_FREQ) // Factor for use in FTM_ZMAX. DON'T CHANGE.
|
||||
#define FTM_SMOOTH_MAX_I uint32_t(TERN0(FTM_SMOOTHING, CEIL(FTM_FS * FTM_MAX_SMOOTHING_TIME))) // Max delays for smoothing
|
||||
#define FTM_ZMAX (FTM_RATIO * 2 + FTM_SMOOTH_MAX_I) // Maximum delays for shaping functions (even numbers only!)
|
||||
// Calculate as:
|
||||
// ZV : FTM_RATIO / 2
|
||||
// ZVD, MZV : FTM_RATIO
|
||||
// 2HEI : FTM_RATIO * 3 / 2
|
||||
// 3HEI : FTM_RATIO * 2
|
||||
#define FTM_SMOOTHING_ORDER 5 // 3 to 5 is closest to gaussian
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -41,7 +41,11 @@
|
|||
#include "../core/boards.h"
|
||||
|
||||
#if USE_STD_CONFIGS
|
||||
#include "../../Configuration.h"
|
||||
#if __has_include("../../Configuration.h")
|
||||
#include "../../Configuration.h"
|
||||
#else
|
||||
#define MOTHERBOARD BOARD_ERROR
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CUSTOM_VERSION_FILE
|
||||
|
|
|
|||
|
|
@ -21,14 +21,16 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "Conditionals-3-etc.h"
|
||||
|
||||
#ifndef __MARLIN_DEPS__
|
||||
#include HAL_PATH(.., inc/Conditionals_LCD.h)
|
||||
#endif
|
||||
|
||||
#include "Conditionals-3-etc.h"
|
||||
|
||||
#include "../core/drivers.h"
|
||||
|
||||
#if USE_STD_CONFIGS
|
||||
#include "../../Configuration_adv.h"
|
||||
#if __has_include("../../Configuration_adv.h")
|
||||
#include "../../Configuration_adv.h"
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2803,79 +2803,6 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Make sure only one display is enabled
|
||||
*/
|
||||
#if 1 < 0 \
|
||||
+ ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) \
|
||||
+ ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) \
|
||||
+ (ENABLED(U8GLIB_SSD1306) && DISABLED(IS_U8GLIB_SSD1306)) \
|
||||
+ (ENABLED(MINIPANEL) && NONE(MKS_MINI_12864, ENDER2_STOCKDISPLAY)) \
|
||||
+ (ENABLED(MKS_MINI_12864) && NONE(MKS_LCD12864A, MKS_LCD12864B)) \
|
||||
+ (ENABLED(FYSETC_MINI_12864_2_1) && NONE(MKS_MINI_12864_V3, BTT_MINI_12864, BEEZ_MINI_12864)) \
|
||||
+ COUNT_ENABLED(MKS_MINI_12864_V3, BTT_MINI_12864, BEEZ_MINI_12864) \
|
||||
+ (ENABLED(EXTENSIBLE_UI) && DISABLED(IS_EXTUI)) \
|
||||
+ (DISABLED(IS_LEGACY_TFT) && ENABLED(TFT_GENERIC)) \
|
||||
+ (ENABLED(IS_LEGACY_TFT) && COUNT_ENABLED(TFT_320x240, TFT_320x240_SPI, TFT_480x320, TFT_480x320_SPI)) \
|
||||
+ COUNT_ENABLED(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON, ANYCUBIC_TFT35, ANYCUBIC_LCD_VYPER) \
|
||||
+ DGUS_UI_IS(ORIGIN) + DGUS_UI_IS(FYSETC) + DGUS_UI_IS(HIPRECY) + DGUS_UI_IS(MKS) + DGUS_UI_IS(RELOADED) + DGUS_UI_IS(IA_CREALITY) \
|
||||
+ COUNT_ENABLED(ENDER2_STOCKDISPLAY, CR10_STOCKDISPLAY) \
|
||||
+ COUNT_ENABLED(DWIN_CREALITY_LCD, DWIN_LCD_PROUI, DWIN_CREALITY_LCD_JYERSUI, DWIN_MARLINUI_PORTRAIT, DWIN_MARLINUI_LANDSCAPE, SOVOL_SV06_RTS) \
|
||||
+ COUNT_ENABLED(FYSETC_MINI_12864_X_X, FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0, FYSETC_GENERIC_12864_1_1) \
|
||||
+ COUNT_ENABLED(LCD_SAINSMART_I2C_1602, LCD_SAINSMART_I2C_2004) \
|
||||
+ COUNT_ENABLED(MKS_12864OLED, MKS_12864OLED_SSD1306) \
|
||||
+ COUNT_ENABLED(MKS_TS35_V2_0, MKS_ROBIN_TFT24, MKS_ROBIN_TFT28, MKS_ROBIN_TFT32, MKS_ROBIN_TFT35, MKS_ROBIN_TFT43, \
|
||||
MKS_ROBIN_TFT_V1_1R, ANET_ET4_TFT28, ANET_ET5_TFT35, BIQU_BX_TFT70, BTT_TFT35_SPI_V1_0) \
|
||||
+ COUNT_ENABLED(TFTGLCD_PANEL_SPI, TFTGLCD_PANEL_I2C) \
|
||||
+ COUNT_ENABLED(VIKI2, miniVIKI) \
|
||||
+ ENABLED(WYH_L12864) \
|
||||
+ COUNT_ENABLED(ZONESTAR_12864LCD, ZONESTAR_12864OLED, ZONESTAR_12864OLED_SSD1306) \
|
||||
+ COUNT_ENABLED(ANET_FULL_GRAPHICS_LCD, CTC_A10S_A13) \
|
||||
+ ENABLED(AZSMZ_12864) \
|
||||
+ ENABLED(BQ_LCD_SMART_CONTROLLER) \
|
||||
+ ENABLED(CARTESIO_UI) \
|
||||
+ ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) \
|
||||
+ ENABLED(FF_INTERFACEBOARD) \
|
||||
+ ENABLED(FYSETC_242_OLED_12864) \
|
||||
+ ENABLED(G3D_PANEL) \
|
||||
+ ENABLED(LCD_FOR_MELZI) \
|
||||
+ ENABLED(LCD_I2C_PANELOLU2) \
|
||||
+ ENABLED(LCD_I2C_VIKI) \
|
||||
+ ENABLED(LCM1602) \
|
||||
+ ENABLED(LONGER_LK_TFT28) \
|
||||
+ ENABLED(MAKEBOARD_MINI_2_LINE_DISPLAY_1602) \
|
||||
+ ENABLED(MAKRPANEL) \
|
||||
+ ENABLED(MALYAN_LCD) \
|
||||
+ ENABLED(NEXTION_TFT) \
|
||||
+ ENABLED(MKS_LCD12864A) \
|
||||
+ ENABLED(MKS_LCD12864B) \
|
||||
+ ENABLED(OLED_PANEL_TINYBOY2) \
|
||||
+ ENABLED(OVERLORD_OLED) \
|
||||
+ ENABLED(PANEL_ONE) \
|
||||
+ ENABLED(RA_CONTROL_PANEL) \
|
||||
+ ENABLED(RADDS_DISPLAY) \
|
||||
+ ENABLED(REPRAPWORLD_GRAPHICAL_LCD) \
|
||||
+ ENABLED(RIGIDBOT_PANEL) \
|
||||
+ ENABLED(SAV_3DGLCD) \
|
||||
+ ENABLED(SAV_3DLCD) \
|
||||
+ ENABLED(SILVER_GATE_GLCD_CONTROLLER) \
|
||||
+ ENABLED(TFT_TRONXY_X5SA) \
|
||||
+ ENABLED(TOUCH_UI_FTDI_EVE) \
|
||||
+ ENABLED(U8GLIB_SH1106_EINSTART) \
|
||||
+ ENABLED(ULTI_CONTROLLER) \
|
||||
+ ENABLED(ULTIMAKERCONTROLLER) \
|
||||
+ ENABLED(ULTIPANEL) \
|
||||
+ ENABLED(ULTRA_LCD) \
|
||||
+ ENABLED(YHCB2004) \
|
||||
+ ENABLED(ZONESTAR_LCD) \
|
||||
+ ENABLED(K3D_FULL_GRAPHIC_SMART_CONTROLLER) \
|
||||
+ ENABLED(K3D_242_OLED_CONTROLLER)
|
||||
#error "Please select only one LCD controller option."
|
||||
#endif
|
||||
|
||||
#undef IS_U8GLIB_SSD1306
|
||||
#undef IS_EXTUI
|
||||
|
||||
/**
|
||||
* Make sure LCD language settings are distinct
|
||||
*/
|
||||
|
|
@ -3754,33 +3681,11 @@ static_assert(COUNT(sanity_arr_3) <= DISTINCT_AXES, "DEFAULT_MAX_ACCELERATION ha
|
|||
static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive.");
|
||||
|
||||
#if MAXIMUM_STEPPER_RATE
|
||||
static_assert(TERN1(HAS_X_AXIS, sanity_arr_1[X_AXIS] * sanity_arr_2[X_AXIS] <= MAXIMUM_STEPPER_RATE),
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[X] * DEFAULT_AXIS_STEPS_PER_UNIT[X] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")."
|
||||
);
|
||||
static_assert(TERN1(HAS_Y_AXIS, sanity_arr_1[Y_AXIS] * sanity_arr_2[Y_AXIS] <= MAXIMUM_STEPPER_RATE),
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[Y] * DEFAULT_AXIS_STEPS_PER_UNIT[Y] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")."
|
||||
);
|
||||
static_assert(TERN1(HAS_Z_AXIS, sanity_arr_1[Z_AXIS] * sanity_arr_2[Z_AXIS] <= MAXIMUM_STEPPER_RATE),
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[Z] * DEFAULT_AXIS_STEPS_PER_UNIT[Z] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")."
|
||||
);
|
||||
static_assert(TERN1(HAS_I_AXIS, sanity_arr_1[I_AXIS] * sanity_arr_2[I_AXIS] <= MAXIMUM_STEPPER_RATE),
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[I] * DEFAULT_AXIS_STEPS_PER_UNIT[I] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")."
|
||||
);
|
||||
static_assert(TERN1(HAS_J_AXIS, sanity_arr_1[J_AXIS] * sanity_arr_2[J_AXIS] <= MAXIMUM_STEPPER_RATE),
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[J] * DEFAULT_AXIS_STEPS_PER_UNIT[J] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")."
|
||||
);
|
||||
static_assert(TERN1(HAS_K_AXIS, sanity_arr_1[K_AXIS] * sanity_arr_2[K_AXIS] <= MAXIMUM_STEPPER_RATE),
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[K] * DEFAULT_AXIS_STEPS_PER_UNIT[K] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")."
|
||||
);
|
||||
static_assert(TERN1(HAS_U_AXIS, sanity_arr_1[U_AXIS] * sanity_arr_2[U_AXIS] <= MAXIMUM_STEPPER_RATE),
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[U] * DEFAULT_AXIS_STEPS_PER_UNIT[U] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")."
|
||||
);
|
||||
static_assert(TERN1(HAS_V_AXIS, sanity_arr_1[V_AXIS] * sanity_arr_2[V_AXIS] <= MAXIMUM_STEPPER_RATE),
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[V] * DEFAULT_AXIS_STEPS_PER_UNIT[V] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")."
|
||||
);
|
||||
static_assert(TERN1(HAS_W_AXIS, sanity_arr_1[W_AXIS] * sanity_arr_2[W_AXIS] <= MAXIMUM_STEPPER_RATE),
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[W] * DEFAULT_AXIS_STEPS_PER_UNIT[W] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")."
|
||||
#define _RATE_ASSERT(A) static_assert(sanity_arr_1[_AXIS(A)] * sanity_arr_2[_AXIS(A)] <= MAXIMUM_STEPPER_RATE, \
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[" STRINGIFY(A) "] * DEFAULT_AXIS_STEPS_PER_UNIT[" STRINGIFY(A) "] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")." \
|
||||
);
|
||||
LOGICAL_AXIS_MAP(_RATE_ASSERT)
|
||||
#undef _RATE_ASSERT
|
||||
#if ALL(HAS_EXTRUDERS, SANITY_CHECK_E_STEPPER_RATES)
|
||||
#if DISABLED(DISTINCT_E_FACTORS)
|
||||
static_assert(sanity_arr_1[E_AXIS] * sanity_arr_2[E_AXIS] <= MAXIMUM_STEPPER_RATE,
|
||||
|
|
@ -4594,6 +4499,12 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive."
|
|||
#if HAS_DYNAMIC_FREQ_G
|
||||
static_assert(FTM_DEFAULT_DYNFREQ_MODE != dynFreqMode_MASS_BASED, "dynFreqMode_MASS_BASED requires an X axis and an extruder.");
|
||||
#endif
|
||||
#if ENABLED(FTM_SMOOTHING)
|
||||
static_assert(FTM_SMOOTHING_TIME_X <= FTM_MAX_SMOOTHING_TIME, "FTM_SMOOTHING_TIME_X must be <= FTM_MAX_SMOOTHING_TIME.");
|
||||
static_assert(FTM_SMOOTHING_TIME_Y <= FTM_MAX_SMOOTHING_TIME, "FTM_SMOOTHING_TIME_Y must be <= FTM_MAX_SMOOTHING_TIME.");
|
||||
static_assert(FTM_SMOOTHING_TIME_Z <= FTM_MAX_SMOOTHING_TIME, "FTM_SMOOTHING_TIME_Z must be <= FTM_MAX_SMOOTHING_TIME.");
|
||||
static_assert(FTM_SMOOTHING_TIME_E <= FTM_MAX_SMOOTHING_TIME, "FTM_SMOOTHING_TIME_E must be <= FTM_MAX_SMOOTHING_TIME.");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Multi-Stepping Limit
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
* version was tagged.
|
||||
*/
|
||||
#ifndef STRING_DISTRIBUTION_DATE
|
||||
#define STRING_DISTRIBUTION_DATE "2025-09-15"
|
||||
#define STRING_DISTRIBUTION_DATE "2025-10-19"
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -922,8 +922,16 @@
|
|||
/**
|
||||
* Fixed-Time Motion
|
||||
*/
|
||||
#if ALL(FT_MOTION, I2S_STEPPER_STREAM)
|
||||
#warning "FT_MOTION has not been tested with I2S_STEPPER_STREAM."
|
||||
#if ENABLED(FT_MOTION)
|
||||
#if ENABLED(I2S_STEPPER_STREAM)
|
||||
#warning "FT_MOTION has not been tested with I2S_STEPPER_STREAM."
|
||||
#endif
|
||||
#if ENABLED(FTM_HOME_AND_PROBE) && ANY(BIQU_MICROPROBE_V1, BIQU_MICROPROBE_V2)
|
||||
#warning "FT_MOTION in known to have issues with BIQU Microprobe."
|
||||
#endif
|
||||
#if ENABLED(FTM_HOME_AND_PROBE) && DELAY_BEFORE_PROBING <= 25
|
||||
#warning "A longer DELAY_BEFORE_PROBING is recommended when using a probe with FT_MOTION."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include <U8glib-HAL.h>
|
||||
|
||||
#if defined(__AVR__) && ENABLED(NOT_EXTENDED_ISO10646_1_5X7)
|
||||
#if ALL(__AVR__, NOT_EXTENDED_ISO10646_1_5X7)
|
||||
// reduced font (only symbols 1 - 127) - saves about 1278 bytes of FLASH
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -310,7 +310,22 @@ void MarlinUI::init_lcd() {
|
|||
#endif
|
||||
|
||||
#if ANY(MKS_12864OLED, MKS_12864OLED_SSD1306, FYSETC_242_OLED_12864, ZONESTAR_12864OLED, K3D_242_OLED_CONTROLLER)
|
||||
SET_OUTPUT(LCD_PINS_DC);
|
||||
|
||||
#if defined(LCD_PINS_DC) && LCD_PINS_DC != -1
|
||||
#if IS_I2C_LCD
|
||||
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);
|
||||
const bool isSoftI2C = !(i2cInstance1 && (i2cInstance1 == i2cInstance2)); // Using software I2C driver for LCD
|
||||
#else
|
||||
constexpr bool isSoftI2C = false;
|
||||
#endif
|
||||
if (!isSoftI2C) SET_OUTPUT(LCD_PINS_DC); // For these LCDs, set as output if not using software I2C driver
|
||||
#endif
|
||||
|
||||
#ifndef LCD_RESET_PIN
|
||||
#define LCD_RESET_PIN LCD_PINS_RS
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(LCD_RESET)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue