Merge branch 'bugfix-2.1.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.1.x-February2

This commit is contained in:
Andrew 2025-11-25 07:17:55 -05:00
commit dc30718cfa
199 changed files with 4200 additions and 2613 deletions

View file

@ -41,11 +41,11 @@
]
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// , "forwardPorts": []
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "pip3 install --user -r requirements.txt",
// , "postCreateCommand": "pip3 install --user -r requirements.txt"
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
// "remoteUser": "vscode"
// , "remoteUser": "vscode"
}

View file

@ -58,7 +58,7 @@ jobs:
- at90usb1286_dfu
# AVR Extended
- FYSETC_F6
- mega2560ext
- melzi_optiboot
- rambo
- sanguino1284p

View file

@ -305,6 +305,18 @@
#endif
/**
* Differential Extruder
*
* The X and E steppers work together to create a differential drive system.
* Simple : E steps = X + E ; X steps = X (E drives a loop, X stays the same)
* Balanced: E steps = X + E/2 ; X steps = X - E/2 (Dual loop system)
*/
//#define DIFFERENTIAL_EXTRUDER
#if ENABLED(DIFFERENTIAL_EXTRUDER)
//#define BALANCED_DIFFERENTIAL_EXTRUDER
#endif
/**
* Switching Toolhead
*
@ -1053,7 +1065,8 @@
// Delta radius and diagonal rod adjustments
//#define DELTA_RADIUS_TRIM_TOWER { 0.0, 0.0, 0.0 } // (mm)
//#define DELTA_DIAGONAL_ROD_TRIM_TOWER { 0.0, 0.0, 0.0 } // (mm)
#endif
#endif // DELTA
// @section scara
@ -1109,17 +1122,37 @@
#define TPARA_LINKAGE_1 120 // (mm)
#define TPARA_LINKAGE_2 120 // (mm)
// TPARA tower offset (position of Tower relative to bed zero position)
// Height of the Shoulder axis (pivot) relative to the tower floor
#define TPARA_SHOULDER_AXIS_HEIGHT 135.0 // (mm)
// The position of the last linkage relative to the robot arm origin
// (intersection of the base axis and floor) when at the home position
#define TPARA_ARM_X_HOME_POS 28.75 // (mm) Measured from shoulder axis to tool holder axis in home position
#define TPARA_ARM_Y_HOME_POS 0 // (mm)
#define TPARA_ARM_Z_HOME_POS 250.00 // (mm) Measured from tool holder axis to the floor
// TPARA Workspace offset relative to the tower (position of workspace origin relative to robot Tower origin )
// This needs to be reasonably accurate as it defines the printbed position in the TPARA space.
#define TPARA_OFFSET_X 0 // (mm)
#define TPARA_OFFSET_Y 0 // (mm)
#define TPARA_OFFSET_Z 0 // (mm)
#define TPARA_OFFSET_X 127.0 // (mm) to coincide with minimum radius MIDDLE_DEAD_ZONE_R, and W(0,0,0) is reachable
#define TPARA_OFFSET_Y 0.0 // (mm)
#define TPARA_OFFSET_Z 0.0 // (mm)
// TPARA tool connection point offset, relative to the tool moving frame origin which is in the last linkage axis,
// (TCP: tool center/connection point) of the robot,
// the plane of measured offset must be alligned with home position plane
#define TPARA_TCP_OFFSET_X 27.0 // (mm) Tool flange: 27 (distance from pivot to bolt holes), extruder tool: 50.0,
#define TPARA_TCP_OFFSET_Y 0.0 // (mm)
#define TPARA_TCP_OFFSET_Z -65.0 // (mm) Tool flange (bottom): -6 (caution as Z 0 posiion will crash second linkage to the floor, -35 is safe for testing with no tool), extruder tool (depends on extruder): -65.0
#define FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly
// Radius around the center where the arm cannot reach
#define MIDDLE_DEAD_ZONE_R 0 // (mm)
#endif
// For now use a hardcoded uniform limit, although it should be calculated, or fix a limit for each axis angle
#define MIDDLE_DEAD_ZONE_R 100 // (mm)
// Max angle between L1 and L2
#define TPARA_MAX_L1L2_ANGLE 140.0f // (degrees)
#endif // AXEL_TPARA
// @section polar
@ -1395,6 +1428,11 @@
* See https://github.com/synthetos/TinyG/wiki/Jerk-Controlled-Motion-Explained
*/
//#define S_CURVE_ACCELERATION
#if ENABLED(S_CURVE_ACCELERATION)
// Define to use 4th instead of 6th order motion curve
//#define S_CURVE_FACTOR 0.25 // Initial and final acceleration factor, ideally 0.1 to 0.4.
// Shouldn't generally require tuning.
#endif
//===========================================================================
//============================= Z Probe Options =============================
@ -1667,6 +1705,8 @@
//#define PROBE_TOOLCHANGE_NO_MOVE // Suppress motion on probe tool-change
#endif
//#define PROBE_WAKEUP_TIME_MS 30 // (ms) Time for the probe to wake up
// Most probes should stay away from the edges of the bed, but
// with NOZZLE_AS_PROBE this can be negative for a wider probing area.
#define PROBING_MARGIN 10

View file

@ -1154,9 +1154,6 @@
#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_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
@ -1180,6 +1177,8 @@
#define FTM_SHAPING_ZETA_E 0.03f // Zeta used by input shapers for E axis
#define FTM_SHAPING_V_TOL_E 0.05f // Vibration tolerance used by EI input shapers for E axis
//#define FTM_RESONANCE_TEST // Sine sweep motion for resonance study
//#define FTM_SMOOTHING // Smoothing can reduce artifacts and make steppers quieter
// on sharp corners, but too much will round corners.
#if ENABLED(FTM_SMOOTHING)
@ -1194,7 +1193,7 @@
#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.
// POLY5: Like POLY6 with 1.5x but uses less CPU.
// POLY6: Continuous Acceleration (aka S_CURVE).
// POLY trajectories not only reduce resonances without rounding corners, but also
// reduce extruder strain due to linear advance.
@ -1204,30 +1203,12 @@
/**
* Advanced configuration
*/
#define FTM_UNIFIED_BWS // DON'T DISABLE unless you use Ulendo FBS (not implemented)
#if ENABLED(FTM_UNIFIED_BWS)
#define FTM_BW_SIZE 100 // Unified Window and Batch size with a ratio of 2
#else
#define FTM_WINDOW_SIZE 200 // Custom Window size for trajectory generation needed by Ulendo FBS
#define FTM_BATCH_SIZE 100 // Custom Batch size for trajectory generation needed by Ulendo FBS
#endif
#define FTM_BUFFER_SIZE 128 // Window size for trajectory generation, must be a power of 2 (e.g 64, 128, 256, ...)
// The total buffered time in seconds is (FTM_BUFFER_SIZE/FTM_FS)
#define FTM_FS 1000 // (Hz) Frequency for trajectory generation.
#define FTM_STEPPER_FS 2'000'000 // (Hz) Time resolution of stepper I/O update. Shouldn't affect CPU much (slower board testing needed)
#define FTM_MIN_SHAPE_FREQ 20 // (Hz) Minimum shaping frequency, lower consumes more RAM
#define FTM_FS 1000 // (Hz) Frequency for trajectory generation
#if DISABLED(COREXY)
#define FTM_STEPPER_FS 20000 // (Hz) Frequency for stepper I/O update
// Use this to adjust the time required to consume the command buffer.
// Try increasing this value if stepper motion is choppy.
#define FTM_STEPPERCMD_BUFF_SIZE 3000 // Size of the stepper command buffers
#else
// CoreXY motion needs a larger buffer size. These values are based on our testing.
#define FTM_STEPPER_FS 30000
#define FTM_STEPPERCMD_BUFF_SIZE 6000
#endif
#define FTM_MIN_SHAPE_FREQ 10 // (Hz) Minimum shaping frequency, lower consumes more RAM
#endif // FT_MOTION
/**
@ -1647,7 +1628,7 @@
#if HAS_MARLINUI_U8GLIB
//#define BOOT_MARLIN_LOGO_ANIMATED // Animated Marlin logo. Costs ~3260 (or ~940) bytes of flash.
#endif
#if ANY(HAS_MARLINUI_U8GLIB, TOUCH_UI_FTDI_EVE, HAS_MARLINUI_HD44780)
#if ANY(HAS_MARLINUI_U8GLIB, TOUCH_UI_FTDI_EVE, HAS_MARLINUI_HD44780, HAS_GRAPHICAL_TFT)
//#define SHOW_CUSTOM_BOOTSCREEN // Show the bitmap in Marlin/_Bootscreen.h on startup.
#endif
#endif
@ -2389,13 +2370,17 @@
* See https://marlinfw.org/docs/features/lin_advance.html for full instructions.
*/
//#define LIN_ADVANCE
#if ENABLED(LIN_ADVANCE)
#if ANY(LIN_ADVANCE, FT_MOTION)
#if ENABLED(DISTINCT_E_FACTORS)
#define ADVANCE_K { 0.22 } // (mm) Compression length per 1mm/s extruder speed, per extruder
#define ADVANCE_K { 0.22 } // (mm) Compression length per 1mm/s extruder speed, per extruder. Override with 'M900 T<tool> K<mm>'.
#else
#define ADVANCE_K 0.22 // (mm) Compression length applying to all extruders
#define ADVANCE_K 0.22 // (mm) Compression length for all extruders. Override with 'M900 K<mm>'.
#endif
//#define ADVANCE_K_EXTRA // Add a second linear advance constant, configurable with M900 L.
//#define ADVANCE_K_EXTRA // Add a second linear advance constant, configurable with 'M900 L'.
#endif
#if ENABLED(LIN_ADVANCE)
//#define LA_DEBUG // Print debug information to serial during operation. Disable for production use.
//#define EXPERIMENTAL_I2S_LA // Allow I2S_STEPPER_STREAM to be used with LA. Performance degrades as the LA step rate reaches ~20kHz.
@ -4107,13 +4092,17 @@
/**
* G-code Macros
*
* Add G-codes M810-M819 to define and run G-code macros.
* Macros are not saved to EEPROM.
* Add G-codes M810-M819 to define and run G-code macros
* and M820 to report the current set of macros.
* Macros are not saved to EEPROM unless enabled below.
*/
//#define GCODE_MACROS
#if ENABLED(GCODE_MACROS)
#define GCODE_MACROS_SLOTS 5 // Up to 10 may be used
#define GCODE_MACROS_SLOT_SIZE 50 // Maximum length of a single macro
#if ENABLED(EEPROM_SETTINGS)
//#define GCODE_MACROS_IN_EEPROM // Include macros in EEPROM
#endif
#endif
/**
@ -4135,22 +4124,27 @@
#define MAIN_MENU_ITEM_1_DESC "Home & UBL Info"
#define MAIN_MENU_ITEM_1_GCODE "G28\nG29 W"
//#define MAIN_MENU_ITEM_1_CONFIRM // Show a confirmation dialog before this action
//#define MAIN_MENU_ITEM_1_IMMEDIATE // Skip the queue and execute immediately. Rarely needed.
#define MAIN_MENU_ITEM_2_DESC "Preheat for " PREHEAT_1_LABEL
#define MAIN_MENU_ITEM_2_GCODE "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND)
//#define MAIN_MENU_ITEM_2_CONFIRM
//#define MAIN_MENU_ITEM_2_IMMEDIATE
//#define MAIN_MENU_ITEM_3_DESC "Preheat for " PREHEAT_2_LABEL
//#define MAIN_MENU_ITEM_3_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND)
//#define MAIN_MENU_ITEM_3_CONFIRM
//#define MAIN_MENU_ITEM_3_IMMEDIATE
//#define MAIN_MENU_ITEM_4_DESC "Heat Bed/Home/Level"
//#define MAIN_MENU_ITEM_4_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29"
//#define MAIN_MENU_ITEM_4_CONFIRM
//#define MAIN_MENU_ITEM_4_IMMEDIATE
//#define MAIN_MENU_ITEM_5_DESC "Home & Info"
//#define MAIN_MENU_ITEM_5_GCODE "G28\nM503"
//#define MAIN_MENU_ITEM_5_CONFIRM
//#define MAIN_MENU_ITEM_5_IMMEDIATE
#endif
// @section custom config menu
@ -4167,22 +4161,27 @@
#define CONFIG_MENU_ITEM_1_DESC "Wifi ON"
#define CONFIG_MENU_ITEM_1_GCODE "M118 [ESP110] WIFI-STA pwd=12345678"
//#define CONFIG_MENU_ITEM_1_CONFIRM // Show a confirmation dialog before this action
//#define CONFIG_MENU_ITEM_1_IMMEDIATE // Skip the queue and execute immediately. Rarely needed.
#define CONFIG_MENU_ITEM_2_DESC "Bluetooth ON"
#define CONFIG_MENU_ITEM_2_GCODE "M118 [ESP110] BT pwd=12345678"
//#define CONFIG_MENU_ITEM_2_CONFIRM
//#define CONFIG_MENU_ITEM_2_IMMEDIATE
//#define CONFIG_MENU_ITEM_3_DESC "Radio OFF"
//#define CONFIG_MENU_ITEM_3_GCODE "M118 [ESP110] OFF pwd=12345678"
//#define CONFIG_MENU_ITEM_3_CONFIRM
//#define CONFIG_MENU_ITEM_3_IMMEDIATE
//#define CONFIG_MENU_ITEM_4_DESC "Wifi ????"
//#define CONFIG_MENU_ITEM_4_GCODE "M118 ????"
//#define CONFIG_MENU_ITEM_4_CONFIRM
//#define CONFIG_MENU_ITEM_4_IMMEDIATE
//#define CONFIG_MENU_ITEM_5_DESC "Wifi ????"
//#define CONFIG_MENU_ITEM_5_GCODE "M118 ????"
//#define CONFIG_MENU_ITEM_5_CONFIRM
//#define CONFIG_MENU_ITEM_5_IMMEDIATE
#endif
// @section custom buttons
@ -4199,6 +4198,7 @@
#define BUTTON1_WHEN_PRINTING false // Button allowed to trigger during printing?
#define BUTTON1_GCODE "G28"
#define BUTTON1_DESC "Homing" // Optional string to set the LCD status
//#define BUTTON1_IMMEDIATE // Skip the queue and run the G-code immediately. Rarely needed.
#endif
//#define BUTTON2_PIN -1
@ -4207,6 +4207,7 @@
#define BUTTON2_WHEN_PRINTING false
#define BUTTON2_GCODE "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND)
#define BUTTON2_DESC "Preheat for " PREHEAT_1_LABEL
//#define BUTTON2_IMMEDIATE
#endif
//#define BUTTON3_PIN -1
@ -4215,6 +4216,7 @@
#define BUTTON3_WHEN_PRINTING false
#define BUTTON3_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND)
#define BUTTON3_DESC "Preheat for " PREHEAT_2_LABEL
//#define BUTTON3_IMMEDIATE
#endif
#endif

View file

@ -188,15 +188,15 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1033)
else ifeq ($(HARDWARE_MOTHERBOARD),1034)
# RAMPS 1.6+ (Power outputs: Hotend, Fan, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1035)
else ifeq ($(HARDWARE_MOTHERBOARD),1040)
# RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1036)
else ifeq ($(HARDWARE_MOTHERBOARD),1041)
# RAMPS 1.6+ (Power outputs: Hotend, Fan0, Fan1)
else ifeq ($(HARDWARE_MOTHERBOARD),1037)
else ifeq ($(HARDWARE_MOTHERBOARD),1042)
# RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Fan)
else ifeq ($(HARDWARE_MOTHERBOARD),1038)
else ifeq ($(HARDWARE_MOTHERBOARD),1043)
# RAMPS 1.6+ (Power outputs: Spindle, Controller Fan)
else ifeq ($(HARDWARE_MOTHERBOARD),1039)
else ifeq ($(HARDWARE_MOTHERBOARD),1044)
#
# RAMPS Derivatives - ATmega1280, ATmega2560
@ -286,60 +286,62 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1138)
else ifeq ($(HARDWARE_MOTHERBOARD),1139)
# Creality: CR10S, CR20, CR-X
else ifeq ($(HARDWARE_MOTHERBOARD),1140)
# Dagoma F5
# Creality CR-10 V2, CR-10 V3
else ifeq ($(HARDWARE_MOTHERBOARD),1141)
# Dagoma D6 (as found in the Dagoma DiscoUltimate V2 TMC)
# Dagoma F5
else ifeq ($(HARDWARE_MOTHERBOARD),1142)
# FYSETC F6 1.3
# Dagoma D6 (as found in the Dagoma DiscoUltimate V2 TMC)
else ifeq ($(HARDWARE_MOTHERBOARD),1143)
# FYSETC F6 1.4
# FYSETC F6 1.3
else ifeq ($(HARDWARE_MOTHERBOARD),1144)
# Wanhao Duplicator i3 Plus
# FYSETC F6 1.4
else ifeq ($(HARDWARE_MOTHERBOARD),1145)
# VORON Design
# Wanhao Duplicator i3 Plus
else ifeq ($(HARDWARE_MOTHERBOARD),1146)
# Tronxy TRONXY-V3-1.0
# VORON Design
else ifeq ($(HARDWARE_MOTHERBOARD),1147)
# Z-Bolt X Series
# Tronxy TRONXY-V3-1.0
else ifeq ($(HARDWARE_MOTHERBOARD),1148)
# TT OSCAR
# Z-Bolt X Series
else ifeq ($(HARDWARE_MOTHERBOARD),1149)
# BIQU Tango V1
# TT OSCAR
else ifeq ($(HARDWARE_MOTHERBOARD),1150)
# MKS GEN L V2
# BIQU Tango V1
else ifeq ($(HARDWARE_MOTHERBOARD),1151)
# MKS GEN L V2.1
# MKS GEN L V2
else ifeq ($(HARDWARE_MOTHERBOARD),1152)
# Copymaster 3D
# MKS GEN L V2.1
else ifeq ($(HARDWARE_MOTHERBOARD),1153)
# Ortur 4
# Copymaster 3D
else ifeq ($(HARDWARE_MOTHERBOARD),1154)
# Tenlog D3 Hero IDEX printer
# Ortur 4
else ifeq ($(HARDWARE_MOTHERBOARD),1155)
# Tenlog D3, D5, D6 IDEX Printer
# Tenlog D3 Hero IDEX printer
else ifeq ($(HARDWARE_MOTHERBOARD),1156)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Fan, Bed)
# Tenlog D3, D5, D6 IDEX Printer
else ifeq ($(HARDWARE_MOTHERBOARD),1157)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Hotend2, Bed)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Fan, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1158)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend, Fan0, Fan1, Bed)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Hotend2, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1159)
# Longer LK1 PRO / Alfawise U20 Pro (PRO version)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend, Fan0, Fan1, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1160)
# Longer LKx PRO / Alfawise Uxx Pro (PRO version)
# Longer LK1 PRO / Alfawise U20 Pro (PRO version)
else ifeq ($(HARDWARE_MOTHERBOARD),1161)
# Pxmalion Core I3
# Longer LKx PRO / Alfawise Uxx Pro (PRO version)
else ifeq ($(HARDWARE_MOTHERBOARD),1162)
# Panowin Cutlass (as found in the Panowin F1)
# Pxmalion Core I3
else ifeq ($(HARDWARE_MOTHERBOARD),1163)
# Kodama Bardo V1.x (as found in the Kodama Trinus)
# Panowin Cutlass (as found in the Panowin F1)
else ifeq ($(HARDWARE_MOTHERBOARD),1164)
# XTLW MFF V1.0
# Kodama Bardo V1.x (as found in the Kodama Trinus)
else ifeq ($(HARDWARE_MOTHERBOARD),1165)
# XTLW MFF V2.0
# XTLW MFF V1.0
else ifeq ($(HARDWARE_MOTHERBOARD),1166)
# E3D Rumba BigBox
# XTLW MFF V2.0
else ifeq ($(HARDWARE_MOTHERBOARD),1167)
# E3D Rumba BigBox
else ifeq ($(HARDWARE_MOTHERBOARD),1168)
#
# RAMBo and derivatives
@ -408,32 +410,34 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1319)
else ifeq ($(HARDWARE_MOTHERBOARD),1320)
# Geeetech GT2560 Rev B for A20(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1321)
# Einstart retrofit
else ifeq ($(HARDWARE_MOTHERBOARD),1322)
# Wanhao 0ne+ i3 Mini
else ifeq ($(HARDWARE_MOTHERBOARD),1323)
# Overlord/Overlord Pro
else ifeq ($(HARDWARE_MOTHERBOARD),1324)
# ADIMLab Gantry v1
else ifeq ($(HARDWARE_MOTHERBOARD),1325)
# ADIMLab Gantry v2
else ifeq ($(HARDWARE_MOTHERBOARD),1326)
# Leapfrog Xeed 2015
else ifeq ($(HARDWARE_MOTHERBOARD),1327)
# PICA Shield (original version)
else ifeq ($(HARDWARE_MOTHERBOARD),1328)
# PICA Shield (rev C or later)
else ifeq ($(HARDWARE_MOTHERBOARD),1329)
# Intamsys 4.0 (Funmat HT)
else ifeq ($(HARDWARE_MOTHERBOARD),1330)
# Malyan M180 Mainboard Version 2 (no display function, direct G-code only)
else ifeq ($(HARDWARE_MOTHERBOARD),1331)
# Mega controller & Protoneer CNC Shield V3.00
else ifeq ($(HARDWARE_MOTHERBOARD),1332)
# WEEDO 62A board (TINA2, Monoprice Cadet, etc.)
else ifeq ($(HARDWARE_MOTHERBOARD),1333)
# Geeetech GT2560 V4.1B for A10(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1322)
# Einstart retrofit
else ifeq ($(HARDWARE_MOTHERBOARD),1323)
# Wanhao 0ne+ i3 Mini
else ifeq ($(HARDWARE_MOTHERBOARD),1324)
# Wanhao D9 MK2
else ifeq ($(HARDWARE_MOTHERBOARD),1325)
# Overlord/Overlord Pro
else ifeq ($(HARDWARE_MOTHERBOARD),1326)
# ADIMLab Gantry v1
else ifeq ($(HARDWARE_MOTHERBOARD),1327)
# ADIMLab Gantry v2
else ifeq ($(HARDWARE_MOTHERBOARD),1328)
# Leapfrog Xeed 2015
else ifeq ($(HARDWARE_MOTHERBOARD),1329)
# PICA Shield (original version)
else ifeq ($(HARDWARE_MOTHERBOARD),1330)
# PICA Shield (rev C or later)
else ifeq ($(HARDWARE_MOTHERBOARD),1331)
# Intamsys 4.0 (Funmat HT)
else ifeq ($(HARDWARE_MOTHERBOARD),1332)
# Malyan M180 Mainboard Version 2
else ifeq ($(HARDWARE_MOTHERBOARD),1333)
# Mega controller & Protoneer CNC Shield V3.00
else ifeq ($(HARDWARE_MOTHERBOARD),1334)
# WEEDO 62A board (TINA2, Monoprice Cadet, etc.)
else ifeq ($(HARDWARE_MOTHERBOARD),1335)
#
# ATmega1281, ATmega2561
@ -513,7 +517,7 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1511)
MCU ?= atmega1284p
PROG_MCU ?= m1284p
# ZoneStar ZMIB V2
else ifeq ($(HARDWARE_MOTHERBOARD),1511)
else ifeq ($(HARDWARE_MOTHERBOARD),1512)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
PROG_MCU ?= m1284p
@ -627,6 +631,10 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1707)
MCU ?= at90usb1286
PROG_MCU ?= usb1286
#
# SAM3X8E ARM Cortex-M3
#
# UltiMachine Archim1 (with DRV8825 drivers)
else ifeq ($(HARDWARE_MOTHERBOARD),3023)
HARDWARE_VARIANT ?= archim

View file

@ -41,7 +41,7 @@
* here we define this default string as the date where the latest release
* version was tagged.
*/
//#define STRING_DISTRIBUTION_DATE "2025-10-30"
//#define STRING_DISTRIBUTION_DATE "2025-11-25"
/**
* The protocol for communication to the host. Protocol indicates communication

View file

@ -111,8 +111,8 @@ FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) {
* (otherwise, characters will be lost due to UART overflow).
* Then: Stepper, Endstops, Temperature, and -finally- all others.
*/
#define HAL_timer_isr_prologue(T) NOOP
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_prologue(const uint8_t) {}
inline void HAL_timer_isr_epilogue(const uint8_t) {}
#ifndef HAL_STEP_TIMER_ISR

View file

@ -127,4 +127,4 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_SR;
}
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -135,5 +135,5 @@ void HAL_timer_enable_interrupt(const uint8_t timer_num);
void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
#define HAL_timer_isr_prologue(T) NOOP
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_prologue(const uint8_t) {}
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -53,12 +53,15 @@ uint16_t MarlinHAL::adc_result;
// Initializes the Marlin HAL
void MarlinHAL::init() {
// Ensure F_CPU is a constant expression.
// If the compiler breaks here, it means that delay code that should compute at compile time will not work.
// So better safe than sorry here.
constexpr unsigned int cpuFreq = F_CPU;
UNUSED(cpuFreq);
#if PIN_EXISTS(LED)
OUT_WRITE(LED_PIN, LOW);
#endif
#if PIN_EXISTS(LED)
OUT_WRITE(LED_PIN, LOW);
#endif
SetTimerInterruptPriorities();

View file

@ -141,5 +141,5 @@ FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_number, const
}
}
#define HAL_timer_isr_prologue(T) NOOP
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_prologue(const uint8_t) {}
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -83,7 +83,7 @@
#error "POSTMORTEM_DEBUGGING requires CORE_DISABLE_FAULT_HANDLER to be set."
#endif
#if defined(PANIC_ENABLE)
#ifdef PANIC_ENABLE
#if defined(PANIC_USART1_TX_PIN) || defined(PANIC_USART2_TX_PIN) || defined(PANIC_USART3_TX_PIN) || defined(PANIC_USART3_TX_PIN)
#error "HC32 HAL uses a custom panic handler. Do not define PANIC_USARTx_TX_PIN."
#endif

View file

@ -171,7 +171,7 @@ void core_hook_sysclock_init() {
panic("HRC is not 16 MHz");
}
#if defined(BOARD_XTAL_FREQUENCY)
#ifdef BOARD_XTAL_FREQUENCY
#warning "No valid XTAL frequency defined, falling back to HRC."
#endif

View file

@ -35,19 +35,19 @@ Timer0 temp_timer(&TIMER02A_config, &Temp_Handler);
*/
Timer0 step_timer(&TIMER02B_config, &Step_Handler);
void HAL_timer_start(const timer_channel_t timer_num, const uint32_t frequency) {
if (timer_num == TEMP_TIMER_NUM) {
void HAL_timer_start(const timer_channel_t timer_ch, const uint32_t frequency) {
if (timer_ch == MF_TIMER_TEMP) {
CORE_DEBUG_PRINTF("HAL_timer_start: temp timer, f=%ld\n", long(frequency));
timer_num->start(frequency, TEMP_TIMER_PRESCALE);
timer_num->setCallbackPriority(TEMP_TIMER_PRIORITY);
timer_ch->start(frequency, TEMP_TIMER_PRESCALE);
timer_ch->setCallbackPriority(TEMP_TIMER_PRIORITY);
}
else if (timer_num == STEP_TIMER_NUM) {
else if (timer_ch == MF_TIMER_STEP) {
CORE_DEBUG_PRINTF("HAL_timer_start: step timer, f=%ld\n", long(frequency));
timer_num->start(frequency, STEPPER_TIMER_PRESCALE);
timer_num->setCallbackPriority(STEP_TIMER_PRIORITY);
timer_ch->start(frequency, STEPPER_TIMER_PRESCALE);
timer_ch->setCallbackPriority(STEP_TIMER_PRIORITY);
}
else {
CORE_ASSERT_FAIL("HAL_timer_start: invalid timer_num")
CORE_ASSERT_FAIL("HAL_timer_start: invalid timer_ch")
}
}

View file

@ -54,75 +54,68 @@ extern Timer0 step_timer;
#define HAL_TIMER_RATE F_PCLK1
// Temperature timer
#define TEMP_TIMER_NUM (&temp_timer)
#define MF_TIMER_TEMP (&temp_timer)
#define TEMP_TIMER_PRIORITY DDL_IRQ_PRIORITY_02
#define TEMP_TIMER_PRESCALE 16UL // 12.5MHz
#define TEMP_TIMER_PRESCALE 16UL // 12.5MHz
#define TEMP_TIMER_RATE 1000 // 1kHz
#define TEMP_TIMER_FREQUENCY TEMP_TIMER_RATE // 1kHz also
// Stepper timer
#define STEP_TIMER_NUM (&step_timer)
#define MF_TIMER_STEP (&step_timer)
#define STEP_TIMER_PRIORITY DDL_IRQ_PRIORITY_00 // Top priority, nothing else uses it
#define STEPPER_TIMER_PRESCALE 16UL // 12.5MHz
#define STEPPER_TIMER_PRESCALE 16UL // 12.5MHz
#define STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // 50MHz / 16 = 3.125MHz
#define STEPPER_TIMER_TICKS_PER_US (STEPPER_TIMER_RATE / 1000000UL) // Integer 3
// Pulse timer (== stepper timer)
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#define MF_TIMER_PULSE MF_TIMER_STEP
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
//
// Channel aliases
//
#define MF_TIMER_TEMP TEMP_TIMER_NUM
#define MF_TIMER_STEP STEP_TIMER_NUM
#define MF_TIMER_PULSE PULSE_TIMER_NUM
//
// HAL functions
//
void HAL_timer_start(const timer_channel_t timer_num, const uint32_t frequency);
void HAL_timer_start(const timer_channel_t timer_ch, const uint32_t frequency);
// Inlined since they are somewhat critical
#define MARLIN_HAL_TIMER_INLINE_ATTR __attribute__((always_inline)) inline
MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_enable_interrupt(const timer_channel_t timer_num) {
timer_num->resume();
MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_enable_interrupt(const timer_channel_t timer_ch) {
timer_ch->resume();
}
MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_disable_interrupt(const timer_channel_t timer_num) {
timer_num->pause();
MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_disable_interrupt(const timer_channel_t timer_ch) {
timer_ch->pause();
}
MARLIN_HAL_TIMER_INLINE_ATTR bool HAL_timer_interrupt_enabled(const timer_channel_t timer_num) {
return timer_num->isPaused();
MARLIN_HAL_TIMER_INLINE_ATTR bool HAL_timer_interrupt_enabled(const timer_channel_t timer_ch) {
return timer_ch->isPaused();
}
MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_set_compare(const timer_channel_t timer_num, const hal_timer_t compare) {
timer_num->setCompareValue(compare);
MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_set_compare(const timer_channel_t timer_ch, const hal_timer_t compare) {
timer_ch->setCompareValue(compare);
}
MARLIN_HAL_TIMER_INLINE_ATTR hal_timer_t HAL_timer_get_count(const timer_channel_t timer_num) {
return timer_num->getCount();
MARLIN_HAL_TIMER_INLINE_ATTR hal_timer_t HAL_timer_get_count(const timer_channel_t timer_ch) {
return timer_ch->getCount();
}
MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_isr_prologue(const timer_channel_t timer_num) {
timer_num->clearInterruptFlag();
MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_isr_prologue(const timer_channel_t timer_ch) {
timer_ch->clearInterruptFlag();
}
MARLIN_HAL_TIMER_INLINE_ATTR void HAL_timer_isr_epilogue(const timer_channel_t timer_num) {}
inline void HAL_timer_isr_epilogue(const timer_channel_t) {}
//
// HAL function aliases
//
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM);
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP);
//
// HAL ISR callbacks
@ -131,8 +124,8 @@ void Step_Handler();
void Temp_Handler();
#ifndef HAL_STEP_TIMER_ISR
#define HAL_STEP_TIMER_ISR() void Step_Handler()
#define HAL_STEP_TIMER_ISR() void Step_Handler()
#endif
#ifndef HAL_TEMP_TIMER_ISR
#define HAL_TEMP_TIMER_ISR() void Temp_Handler()
#define HAL_TEMP_TIMER_ISR() void Temp_Handler()
#endif

View file

@ -93,5 +93,5 @@ void HAL_timer_enable_interrupt(const uint8_t timer_num);
void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
#define HAL_timer_isr_prologue(T) NOOP
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_prologue(const uint8_t) {}
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -171,4 +171,4 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
}
}
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -28,6 +28,8 @@
#include "../shared/Marduino.h"
#include <pinmapping.h>
#define NO_COMPILE_TIME_PWM
#define SET_DIR_INPUT(IO) Gpio::setDir(IO, 1)
#define SET_DIR_OUTPUT(IO) Gpio::setDir(IO, 0)

View file

@ -88,5 +88,5 @@ void HAL_timer_enable_interrupt(const uint8_t timer_num);
void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
#define HAL_timer_isr_prologue(T) NOOP
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_prologue(const uint8_t) {}
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -56,7 +56,7 @@ void MarlinHAL::init() {
// Ensure F_CPU is a constant expression.
// If the compiler breaks here, it means that delay code that should compute at compile time will not work.
// So better safe than sorry here.
constexpr int cpuFreq = F_CPU;
constexpr unsigned int cpuFreq = F_CPU;
UNUSED(cpuFreq);
#if HAS_MEDIA && DISABLED(ONBOARD_SDIO) && PIN_EXISTS(SD_SS)

View file

@ -86,10 +86,10 @@ typedef uint64_t hal_timer_t;
//#define STEP_TIMER_PTR _HAL_TIMER(MF_TIMER_STEP)
//#define TEMP_TIMER_PTR _HAL_TIMER(MF_TIMER_TEMP)
extern alarm_pool_t* HAL_timer_pool_0;
extern alarm_pool_t* HAL_timer_pool_1;
extern alarm_pool_t* HAL_timer_pool_2;
extern alarm_pool_t* HAL_timer_pool_3;
extern alarm_pool_t *HAL_timer_pool_0;
extern alarm_pool_t *HAL_timer_pool_1;
extern alarm_pool_t *HAL_timer_pool_2;
extern alarm_pool_t *HAL_timer_pool_3;
extern struct repeating_timer HAL_timer_0;
@ -120,28 +120,23 @@ void HAL_timer_stop(const uint8_t timer_num);
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, hal_timer_t compare) {
if (timer_num == MF_TIMER_STEP){
if (compare == HAL_TIMER_TYPE_MAX){
HAL_timer_stop(timer_num);
return;
}
if (timer_num == MF_TIMER_STEP && compare == HAL_TIMER_TYPE_MAX) {
HAL_timer_stop(timer_num);
return;
}
compare = compare *10; //Dirty fix, figure out a proper way
compare *= 10; // Dirty fix, figure out a proper way
switch (timer_num) {
case 0:
alarm_pool_add_alarm_in_us(HAL_timer_pool_0, compare, HAL_timer_alarm_pool_0_callback, 0, false);
break;
case 1:
alarm_pool_add_alarm_in_us(HAL_timer_pool_1, compare, HAL_timer_alarm_pool_1_callback, 0, false);
break;
case 2:
alarm_pool_add_alarm_in_us(HAL_timer_pool_2, compare, HAL_timer_alarm_pool_2_callback, 0, false);
break;
case 3:
alarm_pool_add_alarm_in_us(HAL_timer_pool_3, compare, HAL_timer_alarm_pool_3_callback, 0, false);
break;
@ -151,27 +146,20 @@ FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, hal_time
FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
return 0;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
if (timer_num == MF_TIMER_STEP) return 0ull;
return time_us_64();
}
FORCE_INLINE static void HAL_timer_enable_interrupt(const uint8_t timer_num) {
HAL_timer_irq_en[timer_num] = 1;
}
FORCE_INLINE static void HAL_timer_disable_interrupt(const uint8_t timer_num) {
HAL_timer_irq_en[timer_num] = 0;
}
FORCE_INLINE static bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
return HAL_timer_irq_en[timer_num]; //lucky coincidence that timer_num and rp2040 irq num matches
return HAL_timer_irq_en[timer_num]; // Lucky coincidence that timer_num and rp2040 IRQ num matches
}
FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
return;
}
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_prologue(const uint8_t) {}
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -165,7 +165,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
tc->COUNT32.INTENCLR.reg = TC_INTENCLR_OVF; // disable overflow interrupt
// TCn clock setup
GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC4_TC5)) ;
GCLK->CLKCTRL.reg = uint16_t(GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC4_TC5));
SYNC (GCLK->STATUS.bit.SYNCBUSY);
tcReset(tc); // reset TC

View file

@ -157,4 +157,4 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
}
}
#define HAL_timer_isr_epilogue(timer_num)
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -145,4 +145,4 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
}
}
#define HAL_timer_isr_epilogue(timer_num)
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -66,7 +66,7 @@ void MarlinHAL::init() {
// Ensure F_CPU is a constant expression.
// If the compiler breaks here, it means that delay code that should compute at compile time will not work.
// So better safe than sorry here.
constexpr int cpuFreq = F_CPU;
constexpr unsigned int cpuFreq = F_CPU;
UNUSED(cpuFreq);
#if HAS_MEDIA && DISABLED(ONBOARD_SDIO) && PIN_EXISTS(SD_SS)
@ -114,7 +114,7 @@ void MarlinHAL::idletask() {
void MarlinHAL::reboot() { NVIC_SystemReset(); }
uint8_t MarlinHAL::get_reset_source() {
return
return (
#ifdef RCC_FLAG_IWDGRST // Some sources may not exist...
RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) ? RST_WATCHDOG :
#endif
@ -134,7 +134,7 @@ uint8_t MarlinHAL::get_reset_source() {
RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) ? RST_POWER_ON :
#endif
0
;
);
}
void MarlinHAL::clear_reset_source() { __HAL_RCC_CLEAR_RESET_FLAGS(); }

View file

@ -116,5 +116,5 @@ FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const ha
}
}
#define HAL_timer_isr_prologue(T) NOOP
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_prologue(const uint8_t) {}
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -47,14 +47,14 @@ static uint8_t ram_eeprom[MARLIN_EEPROM_SIZE] __attribute__((aligned(4))) = {0};
static bool eeprom_dirty = false;
bool PersistentStore::access_start() {
const uint32_t *source = reinterpret_cast<const uint32_t*>(EEPROM_PAGE0_BASE);
uint32_t *destination = reinterpret_cast<uint32_t*>(ram_eeprom);
const uint32_t *src = reinterpret_cast<const uint32_t*>(EEPROM_PAGE0_BASE);
uint32_t *dst = reinterpret_cast<uint32_t*>(ram_eeprom);
static_assert(0 == (MARLIN_EEPROM_SIZE) % 4, "MARLIN_EEPROM_SIZE is corrupted. (Must be a multiple of 4.)"); // Ensure copying as uint32_t is safe
constexpr size_t eeprom_size_u32 = (MARLIN_EEPROM_SIZE) / 4;
for (size_t i = 0; i < eeprom_size_u32; ++i, ++destination, ++source)
*destination = *source;
for (size_t i = 0; i < eeprom_size_u32; ++i, ++dst, ++src)
*dst = *src;
eeprom_dirty = false;
return true;
@ -80,9 +80,9 @@ bool PersistentStore::access_finish() {
status = FLASH_ErasePage(EEPROM_PAGE1_BASE);
if (status != FLASH_COMPLETE) ACCESS_FINISHED(true);
const uint16_t *source = reinterpret_cast<const uint16_t*>(ram_eeprom);
for (size_t i = 0; i < long(MARLIN_EEPROM_SIZE); i += 2, ++source) {
if (FLASH_ProgramHalfWord(EEPROM_PAGE0_BASE + i, *source) != FLASH_COMPLETE)
const uint16_t *src = reinterpret_cast<const uint16_t*>(ram_eeprom);
for (size_t i = 0; i < long(MARLIN_EEPROM_SIZE); i += 2, ++src) {
if (FLASH_ProgramHalfWord(EEPROM_PAGE0_BASE + i, *src) != FLASH_COMPLETE)
ACCESS_FINISHED(false);
}

View file

@ -188,7 +188,7 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
}
}
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_epilogue(const uint8_t) {}
// No command is available in framework to turn off ARPE bit, which is turned on by default in libmaple.
// Needed here to reset ARPE=0 for stepper timer

View file

@ -74,10 +74,10 @@ typedef uint32_t hal_timer_t;
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#ifndef HAL_STEP_TIMER_ISR
#define HAL_STEP_TIMER_ISR() extern "C" void ftm0_isr() //void TC3_Handler()
#define HAL_STEP_TIMER_ISR() extern "C" void ftm0_isr()
#endif
#ifndef HAL_TEMP_TIMER_ISR
#define HAL_TEMP_TIMER_ISR() extern "C" void ftm1_isr() //void TC4_Handler()
#define HAL_TEMP_TIMER_ISR() extern "C" void ftm1_isr()
#endif
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
@ -110,4 +110,4 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
void HAL_timer_isr_prologue(const uint8_t timer_num);
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -110,4 +110,4 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
void HAL_timer_isr_prologue(const uint8_t timer_num);
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -30,41 +30,82 @@
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
switch (timer_num) {
//
// Step Timer GPT1 - Compare Interrupt OCR1 - Reset Mode
//
case MF_TIMER_STEP:
CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL; // turn off 24mhz mode
// 24MHz mode off Use peripheral clock (150MHz)
CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL;
// Enable GPT1 clock gating
CCM_CCGR1 |= CCM_CCGR1_GPT1_BUS(CCM_CCGR_ON);
GPT1_CR = 0; // disable timer
GPT1_SR = 0x3F; // clear all prior status
GPT1_PR = GPT1_TIMER_PRESCALE - 1;
GPT1_CR |= GPT_CR_CLKSRC(1); //clock selection #1 (peripheral clock = 150 MHz)
GPT1_CR |= GPT_CR_ENMOD; //reset count to zero before enabling
GPT1_CR |= GPT_CR_OM1(1); // toggle mode
GPT1_OCR1 = (GPT1_TIMER_RATE / frequency) -1; // Initial compare value
GPT1_IR = GPT_IR_OF1IE; // Compare3 value
GPT1_CR |= GPT_CR_EN; //enable GPT2 counting at 150 MHz
// Disable timer, clear all status bits
GPT1_CR = 0; // Disable timer
GPT1_SR = 0x3F; // Clear all prior status
OUT_WRITE(15, HIGH);
// Prescaler = 2 => 75MHz counting clock
GPT1_PR = GPT1_TIMER_PRESCALE - 1;
GPT1_CR = GPT_CR_CLKSRC(1) // Clock selection #1 (peripheral clock = 150 MHz)
| GPT_CR_ENMOD // Reset count to zero before enabling
| GPT_CR_OM2(TERN(MARLIN_DEV_MODE, 1, 0)); // 0 = edge compare, 1 = toggle
// Compare value the number of clocks between edges
GPT1_OCR1 = (GPT1_TIMER_RATE / frequency) - 1;
// Enable compareevent interrupt
GPT1_IR = GPT_IR_OF1IE; // OF1 interrupt enabled
// Pull Pin 15 HIGH (logichigh is the “idle” state)
TERN_(MARLIN_DEV_MODE, OUT_WRITE(15, HIGH));
// Attach and enable Stepper IRQ
// Note: UART priority is 16
attachInterruptVector(IRQ_GPT1, &stepTC_Handler);
NVIC_SET_PRIORITY(IRQ_GPT1, 16);
NVIC_SET_PRIORITY(IRQ_GPT1, 16); // Priority 16 (higher than Temp Timer)
// Start GPT1 counting at 150 MHz
GPT1_CR |= GPT_CR_EN;
break;
//
// Temperature Timer GPT2 - Compare Interrupt OCR1 - Reset Mode
//
case MF_TIMER_TEMP:
CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL; // turn off 24mhz mode
// 24MHz mode off Use peripheral clock (150MHz)
CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL;
// Enable GPT2 clock gating
CCM_CCGR0 |= CCM_CCGR0_GPT2_BUS(CCM_CCGR_ON);
GPT2_CR = 0; // disable timer
GPT2_SR = 0x3F; // clear all prior status
GPT2_PR = GPT2_TIMER_PRESCALE - 1;
GPT2_CR |= GPT_CR_CLKSRC(1); //clock selection #1 (peripheral clock = 150 MHz)
GPT2_CR |= GPT_CR_ENMOD; //reset count to zero before enabling
GPT2_CR |= GPT_CR_OM1(1); // toggle mode
GPT2_OCR1 = (GPT2_TIMER_RATE / frequency) -1; // Initial compare value
GPT2_IR = GPT_IR_OF1IE; // Compare3 value
GPT2_CR |= GPT_CR_EN; //enable GPT2 counting at 150 MHz
// Disable timer, clear all status bits
GPT2_CR = 0; // Disable timer
GPT2_SR = 0x3F; // Clear all prior status
OUT_WRITE(14, HIGH);
// Prescaler = 10 => 15MHz counting clock
GPT2_PR = GPT2_TIMER_PRESCALE - 1;
GPT2_CR = GPT_CR_CLKSRC(1) // Clock selection #1 (peripheral clock = 150 MHz)
| GPT_CR_ENMOD // and reset count to zero before enabling
| GPT_CR_OM2(TERN(MARLIN_DEV_MODE, 1, 0)); // 0 = edge compare, 1 = toggle
// Compare value the number of clocks between edges
GPT2_OCR1 = (GPT2_TIMER_RATE / frequency) - 1;
// Enable compareevent interrupt
GPT2_IR = GPT_IR_OF1IE; // OF1 interrupt enabled
// Pull Pin 14 HIGH (logichigh is the “idle” state)
TERN_(MARLIN_DEV_MODE, OUT_WRITE(14, HIGH));
// Attach Temperature ISR
attachInterruptVector(IRQ_GPT2, &tempTC_Handler);
NVIC_SET_PRIORITY(IRQ_GPT2, 32);
NVIC_SET_PRIORITY(IRQ_GPT2, 32); // Priority 32 (lower than Step Timer)
// Start GPT2 counting at 150 MHz
GPT2_CR |= GPT_CR_EN;
break;
}
}
@ -82,6 +123,7 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num) {
case MF_TIMER_TEMP: NVIC_DISABLE_IRQ(IRQ_GPT2); break;
}
// Ensure the CPU actually stops servicing the IRQ
// We NEED memory barriers to ensure Interrupts are actually disabled!
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
asm volatile("dsb");
@ -97,8 +139,8 @@ bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
void HAL_timer_isr_prologue(const uint8_t timer_num) {
switch (timer_num) {
case MF_TIMER_STEP: GPT1_SR = GPT_IR_OF1IE; break; // clear OF3 bit
case MF_TIMER_TEMP: GPT2_SR = GPT_IR_OF1IE; break; // clear OF3 bit
case MF_TIMER_STEP: GPT1_SR = GPT_IR_OF1IE; break; // clear OF1
case MF_TIMER_TEMP: GPT2_SR = GPT_IR_OF1IE; break;
}
asm volatile("dsb");
}

View file

@ -60,7 +60,7 @@ typedef uint32_t hal_timer_t;
#define HAL_TIMER_RATE GPT1_TIMER_RATE
#define STEPPER_TIMER_RATE HAL_TIMER_RATE
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000)
#define STEPPER_TIMER_PRESCALE ((GPT_TIMER_RATE / 1000000) / STEPPER_TIMER_TICKS_PER_US)
#define STEPPER_TIMER_PRESCALE (GPT_TIMER_RATE / STEPPER_TIMER_RATE)
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
@ -89,8 +89,16 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
switch (timer_num) {
case MF_TIMER_STEP: GPT1_OCR1 = compare - 1; break;
case MF_TIMER_TEMP: GPT2_OCR1 = compare - 1; break;
case MF_TIMER_STEP:
GPT1_CR |= GPT_CR_FRR; // Free Run Mode (setting OCRx preserves CNT)
GPT1_OCR1 = compare - 1;
GPT1_CR &= ~GPT_CR_FRR; // Reset Mode (CNT resets on trigger)
break;
case MF_TIMER_TEMP:
GPT2_CR |= GPT_CR_FRR; // Free Run Mode (setting OCRx preserves CNT)
GPT2_OCR1 = compare - 1;
GPT2_CR &= ~GPT_CR_FRR; // Reset Mode (CNT resets on trigger)
break;
}
}
@ -115,5 +123,4 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
void HAL_timer_isr_prologue(const uint8_t timer_num);
//void HAL_timer_isr_epilogue(const uint8_t timer_num) {}
#define HAL_timer_isr_epilogue(T) NOOP
inline void HAL_timer_isr_epilogue(const uint8_t) {}

View file

@ -531,11 +531,15 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
constexpr millis_t CUB_DEBOUNCE_DELAY_##N = 250UL; \
static millis_t next_cub_ms_##N; \
if (BUTTON##N##_HIT_STATE == READ(BUTTON##N##_PIN) \
&& (ENABLED(BUTTON##N##_WHEN_PRINTING) || printer_not_busy)) { \
&& (ENABLED(BUTTON##N##_WHEN_PRINTING) || printer_not_busy) \
) { \
if (ELAPSED(ms, next_cub_ms_##N)) { \
next_cub_ms_##N = ms + CUB_DEBOUNCE_DELAY_##N; \
CODE; \
queue.inject(F(BUTTON##N##_GCODE)); \
if (ENABLED(BUTTON##N##_IMMEDIATE)) \
gcode.process_subcommands_now(F(BUTTON##N##_GCODE)); \
else \
queue.inject(F(BUTTON##N##_GCODE)); \
TERN_(HAS_MARLINUI_MENU, ui.quick_feedback()); \
} \
} \

View file

@ -55,11 +55,11 @@
#define BOARD_RAMPS_PLUS_EEF 1033 // RAMPS Plus 3DYMY (Power outputs: Hotend0, Hotend1, Fan)
#define BOARD_RAMPS_PLUS_SF 1034 // RAMPS Plus 3DYMY (Power outputs: Spindle, Controller Fan)
#define BOARD_RAMPS_BTT_16_PLUS_EFB 1035 // RAMPS 1.6+ (Power outputs: Hotend, Fan, Bed)
#define BOARD_RAMPS_BTT_16_PLUS_EEB 1036 // RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Bed)
#define BOARD_RAMPS_BTT_16_PLUS_EFF 1037 // RAMPS 1.6+ (Power outputs: Hotend, Fan0, Fan1)
#define BOARD_RAMPS_BTT_16_PLUS_EEF 1038 // RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Fan)
#define BOARD_RAMPS_BTT_16_PLUS_SF 1039 // RAMPS 1.6+ (Power outputs: Spindle, Controller Fan)
#define BOARD_RAMPS_BTT_16_PLUS_EFB 1040 // RAMPS 1.6+ (Power outputs: Hotend, Fan, Bed)
#define BOARD_RAMPS_BTT_16_PLUS_EEB 1041 // RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Bed)
#define BOARD_RAMPS_BTT_16_PLUS_EFF 1042 // RAMPS 1.6+ (Power outputs: Hotend, Fan0, Fan1)
#define BOARD_RAMPS_BTT_16_PLUS_EEF 1043 // RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Fan)
#define BOARD_RAMPS_BTT_16_PLUS_SF 1044 // RAMPS 1.6+ (Power outputs: Spindle, Controller Fan)
//
// RAMPS Derivatives - ATmega1280, ATmega2560
@ -431,67 +431,68 @@
// STM32 ARM Cortex-M4F
//
#define BOARD_ARMED 5200 // Arm'ed STM32F4-based controller
#define BOARD_RUMBA32_V1_0 5201 // RUMBA32 STM32F446VE based controller from Aus3D
#define BOARD_RUMBA32_V1_1 5202 // RUMBA32 STM32F446VE based controller from Aus3D
#define BOARD_RUMBA32_MKS 5203 // RUMBA32 STM32F446VE based controller from Makerbase
#define BOARD_RUMBA32_BTT 5204 // RUMBA32 STM32F446VE based controller from BIGTREETECH
#define BOARD_BLACK_STM32F407VE 5205 // Black STM32F407VE development board
#define BOARD_BLACK_STM32F407ZE 5206 // Black STM32F407ZE development board
#define BOARD_BTT_SKR_MINI_E3_V3_0_1 5207 // BigTreeTech SKR Mini E3 V3.0.1 (STM32F401RC)
#define BOARD_BTT_SKR_PRO_V1_1 5208 // BigTreeTech SKR Pro v1.1 (STM32F407ZG)
#define BOARD_BTT_SKR_PRO_V1_2 5209 // BigTreeTech SKR Pro v1.2 (STM32F407ZG)
#define BOARD_BTT_BTT002_V1_0 5210 // BigTreeTech BTT002 v1.0 (STM32F407VG)
#define BOARD_BTT_E3_RRF 5211 // BigTreeTech E3 RRF (STM32F407VG)
#define BOARD_BTT_SKR_V2_0_REV_A 5212 // BigTreeTech SKR v2.0 Rev A (STM32F407VG)
#define BOARD_BTT_SKR_V2_0_REV_B 5213 // BigTreeTech SKR v2.0 Rev B (STM32F407VG/STM32F429VG)
#define BOARD_BTT_GTR_V1_0 5214 // BigTreeTech GTR v1.0 (STM32F407IGT)
#define BOARD_BTT_OCTOPUS_V1_0 5215 // BigTreeTech Octopus v1.0 (STM32F446ZE)
#define BOARD_BTT_OCTOPUS_V1_1 5216 // BigTreeTech Octopus v1.1 (STM32F446ZE)
#define BOARD_BTT_OCTOPUS_PRO_V1_0 5217 // BigTreeTech Octopus Pro v1.0 (STM32F446ZE / STM32F429ZG)
#define BOARD_LERDGE_K 5218 // Lerdge K (STM32F407ZG)
#define BOARD_LERDGE_S 5219 // Lerdge S (STM32F407VE)
#define BOARD_LERDGE_X 5220 // Lerdge X (STM32F407VE)
#define BOARD_FYSETC_S6 5221 // FYSETC S6 (STM32F446VE)
#define BOARD_FYSETC_S6_V2_0 5222 // FYSETC S6 v2.0 (STM32F446VE)
#define BOARD_FYSETC_SPIDER 5223 // FYSETC Spider (STM32F446VE)
#define BOARD_FYSETC_SPIDER_V2_2 5224 // FYSETC Spider V2.2 (STM32F446VE)
#define BOARD_FLYF407ZG 5225 // FLYmaker FLYF407ZG (STM32F407ZG)
#define BOARD_MKS_ROBIN2 5226 // MKS Robin2 V1.0 (STM32F407ZE)
#define BOARD_MKS_ROBIN_PRO_V2 5227 // MKS Robin Pro V2 (STM32F407VE)
#define BOARD_MKS_ROBIN_NANO_V3 5228 // MKS Robin Nano V3 (STM32F407VG)
#define BOARD_MKS_ROBIN_NANO_V3_1 5229 // MKS Robin Nano V3.1 (STM32F407VE)
#define BOARD_MKS_MONSTER8_V1 5230 // MKS Monster8 V1 (STM32F407VE)
#define BOARD_MKS_MONSTER8_V2 5231 // MKS Monster8 V2 (STM32F407VE)
#define BOARD_ANET_ET4 5232 // ANET ET4 V1.x (STM32F407VG)
#define BOARD_ANET_ET4P 5233 // ANET ET4P V1.x (STM32F407VG)
#define BOARD_FYSETC_CHEETAH_V20 5234 // FYSETC Cheetah V2.0 (STM32F401RC)
#define BOARD_FYSETC_CHEETAH_V30 5235 // FYSETC Cheetah V3.0 (STM32F446RC)
#define BOARD_TH3D_EZBOARD_V2 5236 // TH3D EZBoard v2.0 (STM32F405RG)
#define BOARD_OPULO_LUMEN_REV3 5237 // Opulo Lumen PnP Controller REV3 (STM32F407VE / STM32F407VG)
#define BOARD_OPULO_LUMEN_REV4 5238 // Opulo Lumen PnP Controller REV4 (STM32F407VE / STM32F407VG)
#define BOARD_MKS_ROBIN_NANO_V1_3_F4 5239 // MKS Robin Nano V1.3 and MKS Robin Nano-S V1.3 (STM32F407VE)
#define BOARD_MKS_EAGLE 5240 // MKS Eagle (STM32F407VE)
#define BOARD_ARTILLERY_RUBY 5241 // Artillery Ruby (STM32F401RC)
#define BOARD_CREALITY_V24S1_301F4 5242 // Creality v2.4.S1_301F4 (STM32F401RC) as found in the Ender-3 S1 F4
#define BOARD_CREALITY_CR4NTXXC10 5243 // Creality E3 Free-runs Silent Motherboard (STM32F401RET6)
#define BOARD_FYSETC_SPIDER_KING407 5244 // FYSETC Spider King407 (STM32F407ZG)
#define BOARD_MKS_SKIPR_V1 5245 // MKS SKIPR v1.0 all-in-one board (STM32F407VE)
#define BOARD_TRONXY_CXY_446_V10 5246 // TRONXY CXY-446-V10-220413/CXY-V6-191121 (STM32F446ZE)
#define BOARD_CREALITY_F401RE 5247 // Creality CR4NS200141C13 (STM32F401RE) as found in the Ender-5 S1
#define BOARD_BLACKPILL_CUSTOM 5248 // Custom board based on STM32F401CDU6.
#define BOARD_I3DBEEZ9_V1 5249 // I3DBEEZ9 V1 (STM32F407ZG)
#define BOARD_MELLOW_FLY_E3_V2 5250 // Mellow Fly E3 V2 (STM32F407VG)
#define BOARD_BLACKBEEZMINI_V1 5251 // BlackBeezMini V1 (STM32F401CCU6)
#define BOARD_XTLW_CLIMBER_8TH 5252 // XTLW Climber-8th (STM32F407VGT6)
#define BOARD_FLY_RRF_E3_V1 5253 // Fly RRF E3 V1.0 (STM32F407VG)
#define BOARD_FLY_SUPER8 5254 // Fly SUPER8 (STM32F407ZGT6)
#define BOARD_FLY_D8 5255 // FLY D8 (STM32F407VG)
#define BOARD_FLY_CDY_V3 5256 // FLY CDY V3 (STM32F407VGT6)
#define BOARD_ZNP_ROBIN_NANO 5257 // Elegoo Neptune 2 v1.2 board
#define BOARD_ZNP_ROBIN_NANO_V1_3 5258 // Elegoo Neptune 2 v1.3 board
#define BOARD_MKS_NEPTUNE_X 5259 // Elegoo Neptune X
#define BOARD_MKS_NEPTUNE_3 5260 // Elegoo Neptune 3
#define BOARD_ARMED 5200 // Arm'ed STM32F4-based controller
#define BOARD_RUMBA32_V1_0 5201 // RUMBA32 STM32F446VE based controller from Aus3D
#define BOARD_RUMBA32_V1_1 5202 // RUMBA32 STM32F446VE based controller from Aus3D
#define BOARD_RUMBA32_MKS 5203 // RUMBA32 STM32F446VE based controller from Makerbase
#define BOARD_RUMBA32_BTT 5204 // RUMBA32 STM32F446VE based controller from BIGTREETECH
#define BOARD_BLACK_STM32F407VE 5205 // Black STM32F407VE development board
#define BOARD_BLACK_STM32F407ZE 5206 // Black STM32F407ZE development board
#define BOARD_BTT_SKR_MINI_E3_V3_0_1 5207 // BigTreeTech SKR Mini E3 V3.0.1 (STM32F401RC)
#define BOARD_BTT_SKR_PRO_V1_1 5208 // BigTreeTech SKR Pro v1.1 (STM32F407ZG)
#define BOARD_BTT_SKR_PRO_V1_2 5209 // BigTreeTech SKR Pro v1.2 (STM32F407ZG)
#define BOARD_BTT_BTT002_V1_0 5210 // BigTreeTech BTT002 v1.0 (STM32F407VG)
#define BOARD_BTT_E3_RRF 5211 // BigTreeTech E3 RRF (STM32F407VG)
#define BOARD_BTT_SKR_V2_0_REV_A 5212 // BigTreeTech SKR v2.0 Rev A (STM32F407VG)
#define BOARD_BTT_SKR_V2_0_REV_B 5213 // BigTreeTech SKR v2.0 Rev B (STM32F407VG/STM32F429VG)
#define BOARD_BTT_GTR_V1_0 5214 // BigTreeTech GTR v1.0 (STM32F407IGT)
#define BOARD_BTT_OCTOPUS_V1_0 5215 // BigTreeTech Octopus v1.0 (STM32F446ZE)
#define BOARD_BTT_OCTOPUS_V1_1 5216 // BigTreeTech Octopus v1.1 (STM32F446ZE)
#define BOARD_BTT_OCTOPUS_PRO_V1_0 5217 // BigTreeTech Octopus Pro v1.0 (STM32F446ZE / STM32F429ZG)
#define BOARD_LERDGE_K 5218 // Lerdge K (STM32F407ZG)
#define BOARD_LERDGE_S 5219 // Lerdge S (STM32F407VE)
#define BOARD_LERDGE_X 5220 // Lerdge X (STM32F407VE)
#define BOARD_FYSETC_S6 5221 // FYSETC S6 (STM32F446VE)
#define BOARD_FYSETC_S6_V2_0 5222 // FYSETC S6 v2.0 (STM32F446VE)
#define BOARD_FYSETC_SPIDER 5223 // FYSETC Spider (STM32F446VE)
#define BOARD_FYSETC_SPIDER_V2_2 5224 // FYSETC Spider V2.2 (STM32F446VE)
#define BOARD_FLYF407ZG 5225 // FLYmaker FLYF407ZG (STM32F407ZG)
#define BOARD_MKS_ROBIN2 5226 // MKS Robin2 V1.0 (STM32F407ZE)
#define BOARD_MKS_ROBIN_PRO_V2 5227 // MKS Robin Pro V2 (STM32F407VE)
#define BOARD_MKS_ROBIN_NANO_V3 5228 // MKS Robin Nano V3 (STM32F407VG)
#define BOARD_MKS_ROBIN_NANO_V3_1 5229 // MKS Robin Nano V3.1 (STM32F407VE)
#define BOARD_MKS_MONSTER8_V1 5230 // MKS Monster8 V1 (STM32F407VE)
#define BOARD_MKS_MONSTER8_V2 5231 // MKS Monster8 V2 (STM32F407VE)
#define BOARD_ANET_ET4 5232 // ANET ET4 V1.x (STM32F407VG)
#define BOARD_ANET_ET4P 5233 // ANET ET4P V1.x (STM32F407VG)
#define BOARD_FYSETC_CHEETAH_V20 5234 // FYSETC Cheetah V2.0 (STM32F401RC)
#define BOARD_FYSETC_CHEETAH_V30 5235 // FYSETC Cheetah V3.0 (STM32F446RC)
#define BOARD_TH3D_EZBOARD_V2 5236 // TH3D EZBoard v2.0 (STM32F405RG)
#define BOARD_OPULO_LUMEN_REV3 5237 // Opulo Lumen PnP Controller REV3 (STM32F407VE / STM32F407VG)
#define BOARD_OPULO_LUMEN_REV4 5238 // Opulo Lumen PnP Controller REV4 (STM32F407VE / STM32F407VG)
#define BOARD_MKS_ROBIN_NANO_V1_3_F4 5239 // MKS Robin Nano V1.3 and MKS Robin Nano-S V1.3 (STM32F407VE)
#define BOARD_MKS_EAGLE 5240 // MKS Eagle (STM32F407VE)
#define BOARD_ARTILLERY_RUBY 5241 // Artillery Ruby (STM32F401RC)
#define BOARD_CREALITY_V24S1_301F4 5242 // Creality v2.4.S1_301F4 (STM32F401RC) as found in the Ender-3 S1 F4
#define BOARD_CREALITY_CR4NTXXC10 5243 // Creality E3 Free-runs Silent Motherboard (STM32F401RET6)
#define BOARD_FYSETC_SPIDER_KING_V1_F407 5244 // FYSETC Spider King v1 (STM32F407ZG)
#define BOARD_FYSETC_SPIDER_KING_V1_1_F407 5245 // FYSETC Spider King v1.1 (STM32F407ZG)
#define BOARD_MKS_SKIPR_V1 5246 // MKS SKIPR v1.0 all-in-one board (STM32F407VE)
#define BOARD_TRONXY_CXY_446_V10 5247 // TRONXY CXY-446-V10-220413/CXY-V6-191121 (STM32F446ZE)
#define BOARD_CREALITY_F401RE 5248 // Creality CR4NS200141C13 (STM32F401RE) as found in the Ender-5 S1
#define BOARD_BLACKPILL_CUSTOM 5249 // Custom board based on STM32F401CDU6.
#define BOARD_I3DBEEZ9_V1 5250 // I3DBEEZ9 V1 (STM32F407ZG)
#define BOARD_MELLOW_FLY_E3_V2 5251 // Mellow Fly E3 V2 (STM32F407VG)
#define BOARD_BLACKBEEZMINI_V1 5252 // BlackBeezMini V1 (STM32F401CCU6)
#define BOARD_XTLW_CLIMBER_8TH 5253 // XTLW Climber-8th (STM32F407VGT6)
#define BOARD_FLY_RRF_E3_V1 5254 // Fly RRF E3 V1.0 (STM32F407VG)
#define BOARD_FLY_SUPER8 5255 // Fly SUPER8 (STM32F407ZGT6)
#define BOARD_FLY_D8 5256 // FLY D8 (STM32F407VG)
#define BOARD_FLY_CDY_V3 5257 // FLY CDY V3 (STM32F407VGT6)
#define BOARD_ZNP_ROBIN_NANO 5258 // Elegoo Neptune 2 v1.2 board
#define BOARD_ZNP_ROBIN_NANO_V1_3 5259 // Elegoo Neptune 2 v1.3 board
#define BOARD_MKS_NEPTUNE_X 5260 // Elegoo Neptune X
#define BOARD_MKS_NEPTUNE_3 5261 // Elegoo Neptune 3
//
// Other ARM Cortex-M4
@ -502,22 +503,24 @@
// ARM Cortex-M7
//
#define BOARD_REMRAM_V1 6000 // RemRam v1
#define BOARD_NUCLEO_F767ZI 6001 // ST NUCLEO-F767ZI Dev Board
#define BOARD_BTT_SKR_SE_BX_V2 6002 // BigTreeTech SKR SE BX V2.0 (STM32H743II)
#define BOARD_BTT_SKR_SE_BX_V3 6003 // BigTreeTech SKR SE BX V3.0 (STM32H743II)
#define BOARD_BTT_SKR_V3_0 6004 // BigTreeTech SKR V3.0 (STM32H743VI / STM32H723VG)
#define BOARD_BTT_SKR_V3_0_EZ 6005 // BigTreeTech SKR V3.0 EZ (STM32H743VI / STM32H723VG)
#define BOARD_BTT_OCTOPUS_MAX_EZ_V1_0 6006 // BigTreeTech Octopus Max EZ V1.0 (STM32H723ZE)
#define BOARD_BTT_OCTOPUS_PRO_V1_0_1 6007 // BigTreeTech Octopus Pro v1.0.1 (STM32H723ZE)
#define BOARD_BTT_OCTOPUS_PRO_V1_1 6008 // BigTreeTech Octopus Pro v1.1 (STM32H723ZE)
#define BOARD_BTT_MANTA_M8P_V2_0 6009 // BigTreeTech Manta M8P V2.0 (STM32H723ZE)
#define BOARD_BTT_KRAKEN_V1_0 6010 // BigTreeTech Kraken v1.0 (STM32H723ZG)
#define BOARD_TEENSY40 6011 // Teensy 4.0
#define BOARD_TEENSY41 6012 // Teensy 4.1
#define BOARD_T41U5XBB 6013 // T41U5XBB Teensy 4.1 breakout board
#define BOARD_FLY_D8_PRO 6014 // FLY_D8_PRO (STM32H723VG)
#define BOARD_FLY_SUPER8_PRO 6015 // FLY SUPER8 PRO (STM32H723ZG)
#define BOARD_REMRAM_V1 6000 // RemRam v1
#define BOARD_NUCLEO_F767ZI 6001 // ST NUCLEO-F767ZI Dev Board
#define BOARD_BTT_SKR_SE_BX_V2 6002 // BigTreeTech SKR SE BX V2.0 (STM32H743II)
#define BOARD_BTT_SKR_SE_BX_V3 6003 // BigTreeTech SKR SE BX V3.0 (STM32H743II)
#define BOARD_BTT_SKR_V3_0 6004 // BigTreeTech SKR V3.0 (STM32H743VI / STM32H723VG)
#define BOARD_BTT_SKR_V3_0_EZ 6005 // BigTreeTech SKR V3.0 EZ (STM32H743VI / STM32H723VG)
#define BOARD_BTT_OCTOPUS_MAX_EZ_V1_0 6006 // BigTreeTech Octopus Max EZ V1.0 (STM32H723ZE)
#define BOARD_BTT_OCTOPUS_PRO_V1_0_1 6007 // BigTreeTech Octopus Pro v1.0.1 (STM32H723ZE)
#define BOARD_BTT_OCTOPUS_PRO_V1_1 6008 // BigTreeTech Octopus Pro v1.1 (STM32H723ZE)
#define BOARD_BTT_MANTA_M8P_V2_0 6009 // BigTreeTech Manta M8P V2.0 (STM32H723ZE)
#define BOARD_BTT_KRAKEN_V1_0 6010 // BigTreeTech Kraken v1.0 (STM32H723ZG)
#define BOARD_TEENSY40 6011 // Teensy 4.0
#define BOARD_TEENSY41 6012 // Teensy 4.1
#define BOARD_T41U5XBB 6013 // T41U5XBB Teensy 4.1 breakout board
#define BOARD_FLY_D8_PRO 6014 // FLY_D8_PRO (STM32H723VG)
#define BOARD_FLY_SUPER8_PRO 6015 // FLY SUPER8 PRO (STM32H723ZG)
#define BOARD_FYSETC_SPIDER_KING_V1_H723 6016 // FYSETC Spider King v1 (STM32H723ZG)
#define BOARD_FYSETC_SPIDER_KING_V1_1_H723 6017 // FYSETC Spider King v1.1 (STM32H723ZG)
//
// Espressif ESP32 WiFi

View file

@ -296,6 +296,7 @@
#define STR_TOOL_CHANGING "Tool-changing"
#define STR_HOTEND_OFFSETS "Hotend offsets"
#define STR_SERVO_ANGLES "Servo Angles"
#define STR_AUTOTEMP "Auto Temp Control"
#define STR_HOTEND_PID "Hotend PID"
#define STR_BED_PID "Bed PID"
#define STR_CHAMBER_PID "Chamber PID"

View file

@ -25,12 +25,6 @@
#define __has_include(...) 1
#endif
#define ABCE 4
#define XYZE 4
#define ABC 3
#define XYZ 3
#define XY 2
#define _AXIS(A) (A##_AXIS)
#define _FORCE_INLINE_ __attribute__((__always_inline__)) __inline__

View file

@ -280,12 +280,11 @@ public:
// Quick hash to detect change (e.g., to avoid expensive drawing)
typedef IF<ENABLED(DJB2_HASH), uint32_t, uint16_t>::type hash_t;
hash_t hash() const {
const int sz = length();
#if ENABLED(DJB2_HASH)
hash_t hval = 5381;
char c;
while ((c = *str++)) hval += (hval << 5) + c; // = hval * 33 + c
for (int i = 0; i < sz; i++) hval += (hval << 5) + str[i]; // = hval * 33 + c
#else
const int sz = length();
hash_t hval = hash_t(sz);
for (int i = 0; i < sz; i++) hval = ((hval << 1) | (hval >> 15)) ^ str[i]; // ROL, XOR
#endif

View file

@ -238,6 +238,24 @@ struct Flags<N, false> {
FI bool operator[](const int n) const { return test(n); }
FI int size() const { return sizeof(b); }
FI operator bool() const { return b != 0; }
FI Flags<N>& operator|=(Flags<N> &p) const { b |= p.b; return *this; }
FI Flags<N>& operator&=(Flags<N> &p) const { b &= p.b; return *this; }
FI Flags<N>& operator^=(Flags<N> &p) const { b ^= p.b; return *this; }
FI Flags<N>& operator|=(const flagbits_t &p) { b |= flagbits_t(p); return *this; }
FI Flags<N>& operator&=(const flagbits_t &p) { b &= flagbits_t(p); return *this; }
FI Flags<N>& operator^=(const flagbits_t &p) { b ^= flagbits_t(p); return *this; }
FI Flags<N> operator|(Flags<N> &p) const { return Flags<N>(b | p.b); }
FI Flags<N> operator&(Flags<N> &p) const { return Flags<N>(b & p.b); }
FI Flags<N> operator^(Flags<N> &p) const { return Flags<N>(b ^ p.b); }
FI Flags<N> operator~() const { return Flags<N>(~b); }
FI flagbits_t operator|(const flagbits_t &p) const { return b | flagbits_t(p); }
FI flagbits_t operator&(const flagbits_t &p) const { return b & flagbits_t(p); }
FI flagbits_t operator^(const flagbits_t &p) const { return b ^ flagbits_t(p); }
};
// Flag bits for more than 64 states
@ -492,7 +510,7 @@ typedef ab_float_t ab_pos_t;
typedef abc_float_t abc_pos_t;
typedef abce_float_t abce_pos_t;
// External conversion methods
// External conversion methods (motion.h)
void toLogical(xy_pos_t &raw);
void toLogical(xyz_pos_t &raw);
void toLogical(xyze_pos_t &raw);
@ -523,9 +541,9 @@ struct XYval {
#endif
#if HAS_Y_AXIS
FI void set(const T px, const T py) { x = px; y = py; }
FI void set(const T (&arr)[XY]) { x = arr[0]; y = arr[1]; }
FI void set(const T (&arr)[2]) { x = arr[0]; y = arr[1]; }
#endif
#if NUM_AXES > XY
#if NUM_AXES > 2
FI void set(const T (&arr)[NUM_AXES]) { x = arr[0]; y = arr[1]; }
#endif
#if LOGICAL_AXES > NUM_AXES
@ -635,6 +653,21 @@ struct XYval {
FI bool operator==(const T &p) const { return x == p && y == p; }
FI bool operator!=(const T &p) const { return !operator==(p); }
FI bool operator< (const XYval<T> &rs) const { return x < rs.x && y < rs.y; }
FI bool operator<=(const XYval<T> &rs) const { return x <= rs.x && y <= rs.y; }
FI bool operator> (const XYval<T> &rs) const { return x > rs.x && y > rs.y; }
FI bool operator>=(const XYval<T> &rs) const { return x >= rs.x && y >= rs.y; }
FI bool operator< (const XYZval<T> &rs) const { return true XY_GANG(&& x < rs.x, && y < rs.y); }
FI bool operator<=(const XYZval<T> &rs) const { return true XY_GANG(&& x <= rs.x, && y <= rs.y); }
FI bool operator> (const XYZval<T> &rs) const { return true XY_GANG(&& x > rs.x, && y > rs.y); }
FI bool operator>=(const XYZval<T> &rs) const { return true XY_GANG(&& x >= rs.x, && y >= rs.y); }
FI bool operator< (const XYZEval<T> &rs) const { return true XY_GANG(&& x < rs.x, && y < rs.y); }
FI bool operator<=(const XYZEval<T> &rs) const { return true XY_GANG(&& x <= rs.x, && y <= rs.y); }
FI bool operator> (const XYZEval<T> &rs) const { return true XY_GANG(&& x > rs.x, && y > rs.y); }
FI bool operator>=(const XYZEval<T> &rs) const { return true XY_GANG(&& x >= rs.x, && y >= rs.y); }
};
//
@ -794,6 +827,16 @@ struct XYZval {
FI bool operator==(const T &p) const { return ENABLED(HAS_X_AXIS) NUM_AXIS_GANG(&& x == p, && y == p, && z == p, && i == p, && j == p, && k == p, && u == p, && v == p, && w == p); }
FI bool operator!=(const T &p) const { return !operator==(p); }
FI bool operator< (const XYZval<T> &rs) const { return true NUM_AXIS_GANG(&& x < rs.x, && y < rs.y, && z < rs.z, && i < rs.i, && j < rs.j, && k < rs.k, && u < rs.u, && v < rs.v, && w < rs.w); }
FI bool operator<=(const XYZval<T> &rs) const { return true NUM_AXIS_GANG(&& x <= rs.x, && y <= rs.y, && z <= rs.z, && i <= rs.i, && j <= rs.j, && k <= rs.k, && u <= rs.u, && v <= rs.v, && w <= rs.w); }
FI bool operator> (const XYZval<T> &rs) const { return true NUM_AXIS_GANG(&& x > rs.x, && y > rs.y, && z > rs.z, && i > rs.i, && j > rs.j, && k > rs.k, && u > rs.u, && v > rs.v, && w > rs.w); }
FI bool operator>=(const XYZval<T> &rs) const { return true NUM_AXIS_GANG(&& x >= rs.x, && y >= rs.y, && z >= rs.z, && i >= rs.i, && j >= rs.j, && k >= rs.k, && u >= rs.u, && v >= rs.v, && w >= rs.w); }
FI bool operator< (const XYZEval<T> &rs) const { return true NUM_AXIS_GANG(&& x < rs.x, && y < rs.y, && z < rs.z, && i < rs.i, && j < rs.j, && k < rs.k, && u < rs.u, && v < rs.v, && w < rs.w); }
FI bool operator<=(const XYZEval<T> &rs) const { return true NUM_AXIS_GANG(&& x <= rs.x, && y <= rs.y, && z <= rs.z, && i <= rs.i, && j <= rs.j, && k <= rs.k, && u <= rs.u, && v <= rs.v, && w <= rs.w); }
FI bool operator> (const XYZEval<T> &rs) const { return true NUM_AXIS_GANG(&& x > rs.x, && y > rs.y, && z > rs.z, && i > rs.i, && j > rs.j, && k > rs.k, && u > rs.u, && v > rs.v, && w > rs.w); }
FI bool operator>=(const XYZEval<T> &rs) const { return true NUM_AXIS_GANG(&& x >= rs.x, && y >= rs.y, && z >= rs.z, && i >= rs.i, && j >= rs.j, && k >= rs.k, && u >= rs.u, && v >= rs.v, && w >= rs.w); }
};
//
@ -824,7 +867,7 @@ struct XYZEval {
FI void set(const XYZval<T> &pxyz, const T pe) { set(pxyz); e = pe; }
FI void set(LOGICAL_AXIS_ARGS_LC(const T)) { LOGICAL_AXIS_CODE(_e = e, a = x, b = y, c = z, _i = i, _j = j, _k = k, _u = u, _v = v, _w = w); }
#if DISTINCT_AXES > LOGICAL_AXES
FI void set(const T (&arr)[DISTINCT_AXES]) { LOGICAL_AXIS_CODE(e = arr[LOGICAL_AXES-1], x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5], u = arr[6], v = arr[7], w = arr[8]); }
FI void set(const T (&arr)[DISTINCT_AXES], const uint8_t eindex) { LOGICAL_AXIS_CODE(e = arr[LOGICAL_AXES-1 + eindex], x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5], u = arr[6], v = arr[7], w = arr[8]); }
#endif
#endif
@ -957,6 +1000,16 @@ struct XYZEval {
FI bool operator==(const T &p) const { return ENABLED(HAS_X_AXIS) LOGICAL_AXIS_GANG(&& e == p, && x == p, && y == p, && z == p, && i == p, && j == p, && k == p, && u == p, && v == p, && w == p); }
FI bool operator!=(const T &p) const { return !operator==(p); }
FI bool operator< (const XYZEval<T> &rs) const { return true LOGICAL_AXIS_GANG(&& e < rs.e, && x < rs.x, && y < rs.y, && z < rs.z, && i < rs.i, && j < rs.j, && k < rs.k, && u < rs.u, && v < rs.v, && w < rs.w); }
FI bool operator<=(const XYZEval<T> &rs) const { return true LOGICAL_AXIS_GANG(&& e <= rs.e, && x <= rs.x, && y <= rs.y, && z <= rs.z, && i <= rs.i, && j <= rs.j, && k <= rs.k, && u <= rs.u, && v <= rs.v, && w <= rs.w); }
FI bool operator> (const XYZEval<T> &rs) const { return true LOGICAL_AXIS_GANG(&& e > rs.e, && x > rs.x, && y > rs.y, && z > rs.z, && i > rs.i, && j > rs.j, && k > rs.k, && u > rs.u, && v > rs.v, && w > rs.w); }
FI bool operator>=(const XYZEval<T> &rs) const { return true LOGICAL_AXIS_GANG(&& e >= rs.e, && x >= rs.x, && y >= rs.y, && z >= rs.z, && i >= rs.i, && j >= rs.j, && k >= rs.k, && u >= rs.u, && v >= rs.v, && w >= rs.w); }
FI bool operator< (const XYZval<T> &rs) const { return true NUM_AXIS_GANG(&& x < rs.x, && y < rs.y, && z < rs.z, && i < rs.i, && j < rs.j, && k < rs.k, && u < rs.u, && v < rs.v, && w < rs.w); }
FI bool operator<=(const XYZval<T> &rs) const { return true NUM_AXIS_GANG(&& x <= rs.x, && y <= rs.y, && z <= rs.z, && i <= rs.i, && j <= rs.j, && k <= rs.k, && u <= rs.u, && v <= rs.v, && w <= rs.w); }
FI bool operator> (const XYZval<T> &rs) const { return true NUM_AXIS_GANG(&& x > rs.x, && y > rs.y, && z > rs.z, && i > rs.i, && j > rs.j, && k > rs.k, && u > rs.u, && v > rs.v, && w > rs.w); }
FI bool operator>=(const XYZval<T> &rs) const { return true NUM_AXIS_GANG(&& x >= rs.x, && y >= rs.y, && z >= rs.z, && i >= rs.i, && j >= rs.j, && k >= rs.k, && u >= rs.u, && v >= rs.v, && w >= rs.w); }
};
#include <string.h> // for memset
@ -1263,6 +1316,7 @@ public:
FI AxisBits operator|(const AxisBits &p) const { return AxisBits(bits | p.bits); }
FI AxisBits operator&(const AxisBits &p) const { return AxisBits(bits & p.bits); }
FI AxisBits operator^(const AxisBits &p) const { return AxisBits(bits ^ p.bits); }
FI AxisBits operator~() const { return AxisBits(~bits); }
FI operator bool() const { return !!bits; }
FI operator uint16_t() const { return uint16_t(bits & 0xFFFF); }
@ -1280,7 +1334,7 @@ public:
// Axis names for G-code parsing, reports, etc.
constexpr xyze_char_t axis_codes LOGICAL_AXIS_ARRAY('E', 'X', 'Y', 'Z', AXIS4_NAME, AXIS5_NAME, AXIS6_NAME, AXIS7_NAME, AXIS8_NAME, AXIS9_NAME);
#if NUM_AXES <= XYZ && !HAS_EXTRUDERS
#if NUM_AXES <= 3 && !HAS_EXTRUDERS
#define AXIS_CHAR(A) ((char)('X' + A))
#define IAXIS_CHAR AXIS_CHAR
#else

View file

@ -143,7 +143,7 @@ void safe_delay(millis_t ms) {
SERIAL_ECHOPGM("ABL Adjustment");
LOOP_NUM_AXES(a) {
SERIAL_ECHOPGM_P((PGM_P)pgm_read_ptr(&SP_AXIS_STR[a]));
serial_offset(planner.get_axis_position_mm(AxisEnum(a)) - current_position[a]);
serial_offset(planner.get_axis_position_mm((AxisEnum)a) - current_position[a]);
}
#else
#if ENABLED(AUTO_BED_LEVELING_UBL)

View file

@ -26,7 +26,7 @@
#include "babystep.h"
#include "../MarlinCore.h"
#include "../module/motion.h" // for axes_should_home(), BABYSTEP_ALLOWED
#include "../module/motion.h" // for axis_should_home(), BABYSTEP_ALLOWED
#include "../module/planner.h" // for axis_steps_per_mm[]
#include "../module/stepper.h"
@ -49,7 +49,7 @@ int16_t Babystep::accum;
void Babystep::step_axis(const AxisEnum axis) {
const int16_t curTodo = steps[BS_AXIS_IND(axis)]; // get rid of volatile for performance
if (curTodo) {
stepper.do_babystep((AxisEnum)axis, curTodo > 0);
stepper.do_babystep(axis, curTodo > 0);
if (curTodo > 0) steps[BS_AXIS_IND(axis)]--; else steps[BS_AXIS_IND(axis)]++;
}
}

View file

@ -314,7 +314,7 @@ void unified_bed_leveling::G29() {
const bool may_move = p_val == 1 || p_val == 2 || p_val == 4 || parser.seen_test('J');
// Potentially disable Fixed-Time Motion for probing
TERN_(FT_MOTION, FTMotionDisableInScope FT_Disabler);
TERN_(FT_MOTION, FTM_DISABLE_IN_SCOPE());
// Check for commands that require the printer to be homed
if (may_move) {
@ -397,7 +397,7 @@ void unified_bed_leveling::G29() {
if (parser.seen('Q')) {
const int16_t test_pattern = parser.has_value() ? parser.value_int() : -99;
if (!WITHIN(test_pattern, TERN0(UBL_DEVEL_DEBUGGING, -1), 2)) {
SERIAL_ECHOLNPGM("?Invalid (Q) test pattern. (" TERN(UBL_DEVEL_DEBUGGING, "-1", "0") " to 2)\n");
SERIAL_ECHOLN(F("?Invalid "), F("(Q) test pattern. (" TERN(UBL_DEVEL_DEBUGGING, "-1", "0") " to 2)\n"));
return;
}
SERIAL_ECHOLNPGM("Applying test pattern.\n");
@ -648,7 +648,7 @@ void unified_bed_leveling::G29() {
}
if (!WITHIN(param.KLS_storage_slot, 0, a - 1)) {
SERIAL_ECHOLNPGM("?Invalid storage slot.\n?Use 0 to ", a - 1);
SERIAL_ECHOLN(F("?Invalid "), F("storage slot.\n?Use 0 to "), a - 1);
return;
}
@ -676,7 +676,7 @@ void unified_bed_leveling::G29() {
}
if (!WITHIN(param.KLS_storage_slot, 0, a - 1)) {
SERIAL_ECHOLNPGM("?Invalid storage slot.\n?Use 0 to ", a - 1);
SERIAL_ECHOLN(F("?Invalid "), F("storage slot.\n?Use 0 to "), a - 1);
goto LEAVE;
}
@ -1161,16 +1161,16 @@ bool unified_bed_leveling::G29_parse_parameters() {
}
if (parser.seen('P')) {
const uint8_t pv = parser.value_byte();
const uint8_t pval = parser.value_byte();
#if !HAS_BED_PROBE
if (pv == 1) {
if (pval == 1) {
SERIAL_ECHOLNPGM("G29 P1 requires a probe.\n");
err_flag = true;
}
else
#endif
{
param.P_phase = pv;
param.P_phase = pval;
if (!WITHIN(param.P_phase, 0, 6)) {
SERIAL_ECHOLNPGM("?(P)hase value invalid (0-6).\n");
err_flag = true;
@ -1182,7 +1182,7 @@ bool unified_bed_leveling::G29_parse_parameters() {
#if HAS_BED_PROBE
param.J_grid_size = parser.value_byte();
if (param.J_grid_size && !WITHIN(param.J_grid_size, 2, 9)) {
SERIAL_ECHOLNPGM("?Invalid grid size (J) specified (2-9).\n");
SERIAL_ECHOLN(F("?Invalid "), F("grid size (J) specified (2-9).\n"));
err_flag = true;
}
#else
@ -1851,7 +1851,7 @@ void unified_bed_leveling::smart_fill_mesh() {
}
if (!parser.has_value() || !WITHIN(parser.value_int(), 0, a - 1)) {
SERIAL_ECHOLNPGM("?Invalid storage slot.\n?Use 0 to ", a - 1);
SERIAL_ECHOLN(F("?Invalid "), F("storage slot.\n?Use 0 to "), a - 1);
return;
}

View file

@ -71,11 +71,9 @@ void BLTouch::init(const bool set_voltage/*=false*/) {
#else
#ifdef DEBUG_OUT
if (DEBUGGING(LEVELING))
DEBUG_ECHOLN( F("BLTouch Mode: "), bltouch.od_5v_mode ? F("5V") : F("OD"),
F(" (Default " TERN(BLTOUCH_SET_5V_MODE, "5V", "OD") ")"));
#endif
if (DEBUGGING(LEVELING))
DEBUG_ECHOLN( F("BLTouch Mode: "), bltouch.od_5v_mode ? F("5V") : F("OD"),
F(" (Default " TERN(BLTOUCH_SET_5V_MODE, "5V", "OD") ")"));
const bool should_set = od_5v_mode != ENABLED(BLTOUCH_SET_5V_MODE);

View file

@ -87,7 +87,7 @@ void StepperDAC::print_values() {
LOOP_LOGICAL_AXES(a) {
SERIAL_CHAR(' ', IAXIS_CHAR(a), ':');
SERIAL_ECHO(dac_perc(a));
SERIAL_ECHOPGM_P(PSTR(" ("), dac_amps(AxisEnum(a)), PSTR(")"));
SERIAL_ECHOPGM_P(PSTR(" ("), dac_amps((AxisEnum)a), PSTR(")"));
}
#if HAS_EXTRUDERS
SERIAL_ECHOLNPGM_P(SP_E_LBL, dac_perc(E_AXIS), PSTR(" ("), dac_amps(E_AXIS), PSTR(")"));

View file

@ -33,6 +33,9 @@
// Static data members
bool EmergencyParser::killed_by_M112, // = false
EmergencyParser::quickstop_by_M410,
#if ENABLED(FTM_RESONANCE_TEST)
EmergencyParser::rt_stop_by_M496, // = false
#endif
#if HAS_MEDIA
EmergencyParser::sd_abort_by_M524,
#endif
@ -147,9 +150,22 @@ void EmergencyParser::update(EmergencyParser::State &state, const uint8_t c) {
case EP_M10: state = (c == '8') ? EP_M108 : EP_IGNORE; break;
case EP_M11: state = (c == '2') ? EP_M112 : EP_IGNORE; break;
case EP_M4: state = (c == '1') ? EP_M41 : EP_IGNORE; break;
case EP_M4:
switch (c) {
case '1' :state = EP_M41; break;
#if ENABLED(FT_MOTION_RESONANCE_TEST)
case '9': state = EP_M49; break;
#endif
default: state = EP_IGNORE;
}
break;
case EP_M41: state = (c == '0') ? EP_M410 : EP_IGNORE; break;
#if ENABLED(FTM_RESONANCE_TEST)
case EP_M49: state = (c == '6') ? EP_M496 : EP_IGNORE; break;
#endif
#if HAS_MEDIA
case EP_M5: state = (c == '2') ? EP_M52 : EP_IGNORE; break;
case EP_M52: state = (c == '4') ? EP_M524 : EP_IGNORE; break;
@ -195,6 +211,9 @@ void EmergencyParser::update(EmergencyParser::State &state, const uint8_t c) {
case EP_M108: wait_for_user = wait_for_heatup = false; break;
case EP_M112: killed_by_M112 = true; break;
case EP_M410: quickstop_by_M410 = true; break;
#if ENABLED(FTM_RESONANCE_TEST)
case EP_M496: rt_stop_by_M496 = true; break;
#endif
#if ENABLED(EP_BABYSTEPPING)
case EP_M293: babystep.ep_babysteps++; break;
case EP_M294: babystep.ep_babysteps--; break;

View file

@ -43,6 +43,9 @@ public:
#if HAS_MEDIA
EP_M5, EP_M52, EP_M524,
#endif
#if ENABLED(FTM_RESONANCE_TEST)
EP_M49, EP_M496,
#endif
#if ENABLED(EP_BABYSTEPPING)
EP_M2, EP_M29, EP_M293, EP_M294,
#endif
@ -64,6 +67,10 @@ public:
static bool killed_by_M112;
static bool quickstop_by_M410;
#if ENABLED(FTM_RESONANCE_TEST)
static bool rt_stop_by_M496;
#endif
#if HAS_MEDIA
static bool sd_abort_by_M524;
#endif

View file

@ -801,7 +801,7 @@ void I2CPositionEncodersMgr::M860() {
if (I2CPE_idx == 0xFF) {
LOOP_LOGICAL_AXES(i) {
if (!I2CPE_anyaxis || parser.seen_test(AXIS_CHAR(i))) {
const uint8_t idx = idx_from_axis(AxisEnum(i));
const uint8_t idx = idx_from_axis((AxisEnum)i);
if ((int8_t)idx >= 0) report_position(idx, hasU, hasO);
}
}
@ -828,7 +828,7 @@ void I2CPositionEncodersMgr::M861() {
if (I2CPE_idx == 0xFF) {
LOOP_LOGICAL_AXES(i) {
if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) {
const uint8_t idx = idx_from_axis(AxisEnum(i));
const uint8_t idx = idx_from_axis((AxisEnum)i);
if ((int8_t)idx >= 0) report_status(idx);
}
}
@ -856,7 +856,7 @@ void I2CPositionEncodersMgr::M862() {
if (I2CPE_idx == 0xFF) {
LOOP_LOGICAL_AXES(i) {
if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) {
const uint8_t idx = idx_from_axis(AxisEnum(i));
const uint8_t idx = idx_from_axis((AxisEnum)i);
if ((int8_t)idx >= 0) test_axis(idx);
}
}
@ -887,7 +887,7 @@ void I2CPositionEncodersMgr::M863() {
if (I2CPE_idx == 0xFF) {
LOOP_LOGICAL_AXES(i) {
if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) {
const uint8_t idx = idx_from_axis(AxisEnum(i));
const uint8_t idx = idx_from_axis((AxisEnum)i);
if ((int8_t)idx >= 0) calibrate_steps_mm(idx, iterations);
}
}
@ -963,7 +963,7 @@ void I2CPositionEncodersMgr::M865() {
if (!I2CPE_addr) {
LOOP_LOGICAL_AXES(i) {
if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) {
const uint8_t idx = idx_from_axis(AxisEnum(i));
const uint8_t idx = idx_from_axis((AxisEnum)i);
if ((int8_t)idx >= 0) report_module_firmware(encoders[idx].get_address());
}
}
@ -994,12 +994,12 @@ void I2CPositionEncodersMgr::M866() {
if (I2CPE_idx == 0xFF) {
LOOP_LOGICAL_AXES(i) {
if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) {
const uint8_t idx = idx_from_axis(AxisEnum(i));
const uint8_t idx = idx_from_axis((AxisEnum)i);
if ((int8_t)idx >= 0) {
if (hasR)
reset_error_count(idx, AxisEnum(i));
reset_error_count(idx, (AxisEnum)i);
else
report_error_count(idx, AxisEnum(i));
report_error_count(idx, (AxisEnum)i);
}
}
}
@ -1032,10 +1032,10 @@ void I2CPositionEncodersMgr::M867() {
if (I2CPE_idx == 0xFF) {
LOOP_LOGICAL_AXES(i) {
if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) {
const uint8_t idx = idx_from_axis(AxisEnum(i));
const uint8_t idx = idx_from_axis((AxisEnum)i);
if ((int8_t)idx >= 0) {
const bool ena = onoff == -1 ? !encoders[I2CPE_idx].get_ec_enabled() : !!onoff;
enable_ec(idx, ena, AxisEnum(i));
enable_ec(idx, ena, (AxisEnum)i);
}
}
}
@ -1068,7 +1068,7 @@ void I2CPositionEncodersMgr::M868() {
if (I2CPE_idx == 0xFF) {
LOOP_LOGICAL_AXES(i) {
if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) {
const uint8_t idx = idx_from_axis(AxisEnum(i));
const uint8_t idx = idx_from_axis((AxisEnum)i);
if ((int8_t)idx >= 0) {
if (newThreshold != -9999)
set_ec_threshold(idx, newThreshold, encoders[idx].get_axis());
@ -1102,7 +1102,7 @@ void I2CPositionEncodersMgr::M869() {
if (I2CPE_idx == 0xFF) {
LOOP_LOGICAL_AXES(i) {
if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(i))) {
const uint8_t idx = idx_from_axis(AxisEnum(i));
const uint8_t idx = idx_from_axis((AxisEnum)i);
if ((int8_t)idx >= 0) report_error(idx);
}
}

View file

@ -164,9 +164,8 @@ void FWRetract::retract(const bool retracting E_OPTARG(bool swapping/*=false*/))
current_retract[active_extruder] = 0;
// Recover E, set_current_to_destination
prepare_internal_move_to_destination(
MUL_TERN(RETRACT_SYNC_MIXING, swapping ? settings.swap_retract_recover_feedrate_mm_s : settings.retract_recover_feedrate_mm_s, MIXING_STEPPERS)
);
const feedRate_t fr_mm_s = swapping ? settings.swap_retract_recover_feedrate_mm_s : settings.retract_recover_feedrate_mm_s;
prepare_internal_move_to_destination(MUL_TERN(RETRACT_SYNC_MIXING, fr_mm_s, MIXING_STEPPERS));
}
TERN_(RETRACT_SYNC_MIXING, mixer.T(old_mixing_tool)); // Restore original mixing tool

View file

@ -255,7 +255,7 @@ namespace MMU3 {
uint8_t block_index = planner.block_buffer_tail;
while (block_index != planner.block_buffer_head) {
block = &planner.block_buffer[block_index];
if (block->steps[E_AXIS] != 0) e_active++;
if (block->steps.e != 0) e_active++;
block_index = (block_index + 1) & (BLOCK_BUFFER_SIZE - 1);
}
}
@ -760,10 +760,10 @@ namespace MMU3 {
LogEchoEvent(F("Resuming XYZ"));
// Move XY to starting position, then Z
motion_do_blocking_move_to_xy(resume_position.x, resume_position.x, feedRate_t(NOZZLE_PARK_XY_FEEDRATE));
motion_blocking_move_xy(resume_position.x, resume_position.y, feedRate_t(NOZZLE_PARK_XY_FEEDRATE));
// Move Z_AXIS to saved position
motion_do_blocking_move_to_z(resume_position.z, feedRate_t(NOZZLE_PARK_Z_FEEDRATE));
motion_blocking_move_z(resume_position.z, feedRate_t(NOZZLE_PARK_Z_FEEDRATE));
// From this point forward, power panic should not use
// the partial backup in RAM since the extruder is no

View file

@ -46,8 +46,8 @@ namespace MMU3 {
void planner_set_current_position_E(float e);
xyz_pos_t planner_current_position();
void motion_do_blocking_move_to_xy(float rx, float ry, float feedRate_mm_s);
void motion_do_blocking_move_to_z(float z, float feedRate_mm_s);
void motion_blocking_move_xy(float rx, float ry, float feedRate_mm_s);
void motion_blocking_move_z(float z, float feedRate_mm_s);
void nozzle_park();

View file

@ -103,14 +103,13 @@ namespace MMU3 {
return xyz_pos_t(current_position);
}
void motion_do_blocking_move_to_xy(float rx, float ry, float feedRate_mm_s) {
current_position[X_AXIS] = rx;
current_position[Y_AXIS] = ry;
void motion_blocking_move_xy(float rx, float ry, float feedRate_mm_s) {
current_position.set(rx, ry);
planner_line_to_current_position_sync(feedRate_mm_s);
}
void motion_do_blocking_move_to_z(float z, float feedRate_mm_s) {
current_position[Z_AXIS] = z;
void motion_blocking_move_z(float z, float feedRate_mm_s) {
current_position.z = z;
planner_line_to_current_position_sync(feedRate_mm_s);
}
@ -152,34 +151,18 @@ namespace MMU3 {
#endif
}
int16_t thermal_degTargetHotend() {
return thermalManager.degTargetHotend(0);
}
int16_t thermal_degHotend() {
return thermalManager.degHotend(0);
}
void thermal_setExtrudeMintemp(int16_t t) {
thermalManager.extrude_min_temp = t;
}
void thermal_setTargetHotend(int16_t t) {
thermalManager.setTargetHotend(t, 0);
}
int16_t thermal_degTargetHotend() { return thermalManager.degTargetHotend(0); }
int16_t thermal_degHotend() { return thermalManager.degHotend(0); }
void thermal_setExtrudeMintemp(int16_t t) { thermalManager.extrude_min_temp = t; }
void thermal_setTargetHotend(int16_t t) { thermalManager.setTargetHotend(t, 0); }
void safe_delay_keep_alive(uint16_t t) {
idle(true);
safe_delay(t);
}
void Enable_E0() {
stepper.enable_extruder(TERN_(HAS_EXTRUDERS, 0));
}
void Disable_E0() {
stepper.disable_extruder(TERN_(HAS_EXTRUDERS, 0));
}
void Enable_E0() { stepper.enable_extruder(TERN_(HAS_EXTRUDERS, 0)); }
void Disable_E0() { stepper.disable_extruder(TERN_(HAS_EXTRUDERS, 0)); }
bool xy_are_trusted() {
return axis_is_trusted(X_AXIS) && axis_is_trusted(Y_AXIS);

View file

@ -99,7 +99,7 @@ PrintJobRecovery recovery;
/**
* Clear the recovery info
*/
void PrintJobRecovery::init() { info = {}; }
void PrintJobRecovery::init() { info = { 0 }; }
/**
* Enable or disable then call changed()
@ -221,7 +221,7 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW
TERN_(HAS_WORKSPACE_OFFSET, info.workspace_offset = workspace_offset);
E_TERN_(info.active_extruder = active_extruder);
#if DISABLED(NO_VOLUMETRICS)
#if HAS_VOLUMETRIC_EXTRUSION
info.flag.volumetric_enabled = parser.volumetric_enabled;
#if HAS_MULTI_EXTRUDER
COPY(info.filament_size, planner.filament_size);
@ -496,7 +496,7 @@ void PrintJobRecovery::resume() {
#endif
// Recover volumetric extrusion state
#if DISABLED(NO_VOLUMETRICS)
#if HAS_VOLUMETRIC_EXTRUSION
#if HAS_MULTI_EXTRUDER
EXTRUDER_LOOP()
PROCESS_SUBCOMMANDS_NOW(TS(F("M200T"), e, F("D"), p_float_t(info.filament_size[e], 3)));
@ -659,7 +659,7 @@ void PrintJobRecovery::resume() {
DEBUG_ECHOLNPGM("active_extruder: ", info.active_extruder);
#endif
#if DISABLED(NO_VOLUMETRICS)
#if HAS_VOLUMETRIC_EXTRUSION
DEBUG_ECHOPGM("filament_size:");
EXTRUDER_LOOP() DEBUG_ECHOLNPGM(" ", info.filament_size[e]);
DEBUG_EOL();
@ -725,7 +725,7 @@ void PrintJobRecovery::resume() {
DEBUG_ECHOLNPGM("flag.dryrun: ", AS_DIGIT(info.flag.dryrun));
DEBUG_ECHOLNPGM("flag.allow_cold_extrusion: ", AS_DIGIT(info.flag.allow_cold_extrusion));
#if DISABLED(NO_VOLUMETRICS)
#if HAS_VOLUMETRIC_EXTRUSION
DEBUG_ECHOLNPGM("flag.volumetric_enabled: ", AS_DIGIT(info.flag.volumetric_enabled));
#endif
}

View file

@ -88,7 +88,7 @@ typedef struct {
uint8_t active_extruder;
#endif
#if DISABLED(NO_VOLUMETRICS)
#if HAS_VOLUMETRIC_EXTRUSION
float filament_size[EXTRUDERS];
#endif
@ -140,7 +140,7 @@ typedef struct {
#if HAS_LEVELING
bool leveling:1; // M420 S
#endif
#if DISABLED(NO_VOLUMETRICS)
#if HAS_VOLUMETRIC_EXTRUSION
bool volumetric_enabled:1; // M200 S D
#endif
} flag;

View file

@ -663,7 +663,7 @@ void GcodeSuite::G26() {
do_z_clearance(Z_CLEARANCE_BETWEEN_PROBES);
#if DISABLED(NO_VOLUMETRICS)
#if HAS_VOLUMETRIC_EXTRUSION
bool volumetric_was_enabled = parser.volumetric_enabled;
parser.volumetric_enabled = false;
planner.calculate_volumetric_multipliers();
@ -856,7 +856,7 @@ void GcodeSuite::G26() {
destination.z = Z_CLEARANCE_BETWEEN_PROBES;
move_to(destination, 0); // Raise the nozzle
#if DISABLED(NO_VOLUMETRICS)
#if HAS_VOLUMETRIC_EXTRUSION
parser.volumetric_enabled = volumetric_was_enabled;
planner.calculate_volumetric_multipliers();
#endif

View file

@ -275,9 +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) && ENABLED(FT_MOTION)
#if DISABLED(PROBE_MANUALLY)
// Potentially disable Fixed-Time Motion for probing
FTMotionDisableInScope FT_Disabler;
TERN_(FT_MOTION, FTM_DISABLE_IN_SCOPE());
#endif
/**

View file

@ -46,7 +46,7 @@
#include "../../../core/debug_out.h"
#if ENABLED(FT_MOTION)
#include "../../module/ft_motion.h"
#include "../../../module/ft_motion.h"
#endif
// Save 130 bytes with non-duplication of PSTR
@ -68,7 +68,7 @@ inline void echo_not_entered(const char c) { SERIAL_CHAR(c); SERIAL_ECHOLNPGM("
void GcodeSuite::G29() {
// Potentially disable Fixed-Time Motion for probing
TERN_(FT_MOTION, FTMotionDisableInScope FT_Disabler);
TERN_(FT_MOTION, FTM_DISABLE_IN_SCOPE());
DEBUG_SECTION(log_G29, "G29", true);
@ -225,7 +225,7 @@ void GcodeSuite::G29() {
}
}
else
return echo_not_entered('J');
return echo_not_entered('I');
if (parser.seenval('J')) {
iy = parser.value_int();

View file

@ -131,7 +131,7 @@
inline void home_z_safely() {
// Potentially disable Fixed-Time Motion for homing
TERN_(FT_MOTION, FTMotionDisableInScope FT_Disabler);
TERN_(FT_MOTION, FTM_DISABLE_IN_SCOPE());
DEBUG_SECTION(log_G28, "home_z_safely", DEBUGGING(LEVELING));
@ -290,7 +290,7 @@ void GcodeSuite::G28() {
#endif
// Potentially disable Fixed-Time Motion for homing
TERN_(FT_MOTION, FTMotionDisableInScope FT_Disabler);
TERN_(FT_MOTION, FTM_DISABLE_IN_SCOPE());
// Always home with tool 0 active
#if HAS_MULTI_HOTEND

View file

@ -380,9 +380,9 @@ static float auto_tune_a(const float dcr) {
* With HAS_DELTA_SENSORLESS_PROBING:
* Use these flags to calibrate stall sensitivity:
* Example: G33 P1 Y Z - to calibrate X only
* X Don't activate stallguard on X
* Y Don't activate stallguard on Y
* Z Don't activate stallguard on Z
* X Don't activate StallGuard on X
* Y Don't activate StallGuard on Y
* Z Don't activate StallGuard on Z
* S Save offset_sensorless_adj
*/
void GcodeSuite::G33() {

View file

@ -94,7 +94,7 @@ void GcodeSuite::M425() {
#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
SERIAL_ECHOPGM(" Average measured backlash (mm):");
if (backlash.has_any_measurement()) {
LOOP_NUM_AXES(a) if (axis_can_calibrate(a) && backlash.has_measurement(AxisEnum(a))) {
LOOP_NUM_AXES(a) if (axis_can_calibrate(a) && backlash.has_measurement((AxisEnum)a)) {
SERIAL_ECHOPGM_P((PGM_P)pgm_read_ptr(&SP_AXIS_STR[a]), backlash.get_measurement((AxisEnum)a));
}
}

View file

@ -24,7 +24,7 @@
#include "../../MarlinCore.h"
#include "../../module/planner.h"
#if DISABLED(NO_VOLUMETRICS)
#if HAS_VOLUMETRIC_EXTRUSION
/**
* M200: Set filament diameter and set E axis units to cubic units
@ -107,7 +107,7 @@
#endif
}
#endif // !NO_VOLUMETRICS
#endif // HAS_VOLUMETRIC_EXTRUSION
/**
* M201: Set max acceleration in units/s^2 for print moves.

View file

@ -51,25 +51,25 @@ void GcodeSuite::M575() {
switch (baud) {
case 2400: case 9600: case 19200: case 38400: case 57600:
case 115200: case 250000: case 500000: case 1000000: {
SERIAL_FLUSH();
const int8_t port = parser.intval('P', -99);
const bool set1 = (port == -99 || port == 0);
if (set1) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(0), " baud rate set to ", baud);
if (set1) { MYSERIAL1.end(); MYSERIAL1.begin(baud); }
#if HAS_MULTI_SERIAL
const bool set2 = (port == -99 || port == 1);
if (set2) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(1), " baud rate set to ", baud);
if (set2) { MYSERIAL2.end(); MYSERIAL2.begin(baud); }
#ifdef SERIAL_PORT_3
const bool set3 = (port == -99 || port == 2);
if (set3) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(2), " baud rate set to ", baud);
if (set3) { MYSERIAL3.end(); MYSERIAL3.begin(baud); }
#endif
#endif
SERIAL_FLUSH();
if (set1) { MYSERIAL1.end(); MYSERIAL1.begin(baud); }
if (set1) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(0), " baud rate set to ", baud);
#if HAS_MULTI_SERIAL
if (set2) { MYSERIAL2.end(); MYSERIAL2.begin(baud); }
if (set2) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(1), " baud rate set to ", baud);
#ifdef SERIAL_PORT_3
if (set3) { MYSERIAL3.end(); MYSERIAL3.begin(baud); }
if (set3) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(2), " baud rate set to ", baud);
#endif
#endif

View file

@ -78,7 +78,7 @@ void do_enable(const stepper_flags_t to_enable) {
// Enable all flagged axes
LOOP_NUM_AXES(a) {
if (TEST(shall_enable, a)) {
stepper.enable_axis(AxisEnum(a)); // Mark and enable the requested axis
stepper.enable_axis((AxisEnum)a); // Mark and enable the requested axis
DEBUG_ECHOLNPGM("Enabled ", AXIS_CHAR(a), " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... Enabled: ", hex_word(stepper.axis_enabled.bits));
also_enabled |= enable_overlap[a];
}
@ -153,7 +153,7 @@ void try_to_disable(const stepper_flags_t to_disable) {
LOOP_NUM_AXES(a)
if (TEST(to_disable.bits, a)) {
DEBUG_ECHOPGM("Try to disable ", AXIS_CHAR(a), " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... ");
if (stepper.disable_axis(AxisEnum(a))) { // Mark the requested axis and request to disable
if (stepper.disable_axis((AxisEnum)a)) { // Mark the requested axis and request to disable
DEBUG_ECHOPGM("OK");
still_enabled &= ~(_BV(a) | enable_overlap[a]); // If actually disabled, clear one or more tracked bits
}

View file

@ -27,7 +27,7 @@
#include "../gcode.h"
#include "../../module/stepper.h"
#if NUM_AXES == XYZ && EXTRUDERS >= 1
#if NUM_AXES == 3 && EXTRUDERS >= 1
#define HAS_M350_B_PARAM 1 // "5th axis" (after E0) for an original XYZEB setup.
#endif

View file

@ -22,7 +22,7 @@
#include "../../../inc/MarlinConfig.h"
#if ENABLED(LIN_ADVANCE)
#if HAS_LIN_ADVANCE_K
#include "../../gcode.h"
#include "../../../module/planner.h"
@ -194,4 +194,4 @@ void GcodeSuite::M900_report(const bool forReplay/*=true*/) {
}
}
#endif // LIN_ADVANCE
#endif // HAS_LIN_ADVANCE_K

View file

@ -46,8 +46,10 @@ void say_shaper_type(const AxisEnum a, bool &sep, const char axis_name) {
}
void say_shaping() {
const ft_config_t &c = ftMotion.cfg;
// FT Enabled
SERIAL_ECHO_TERNARY(ftMotion.cfg.active, "Fixed-Time Motion ", "en", "dis", "abled");
SERIAL_ECHO_TERNARY(c.active, "Fixed-Time Motion ", "en", "dis", "abled");
// FT Shaping
const bool is_shaping = AXIS_IS_SHAPING(X) || AXIS_IS_SHAPING(Y) || AXIS_IS_SHAPING(Z) || AXIS_IS_SHAPING(E);
@ -61,15 +63,15 @@ void say_shaping() {
}
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),
const bool z_based = TERN0(HAS_DYNAMIC_FREQ_MM, c.dynFreqMode == dynFreqMode_Z_BASED),
g_based = TERN0(HAS_DYNAMIC_FREQ_G, c.dynFreqMode == dynFreqMode_MASS_BASED),
dynamic = z_based || g_based;
// FT Dynamic Frequency Mode
if (is_shaping) {
#if HAS_DYNAMIC_FREQ
SERIAL_ECHOPGM("Dynamic Frequency Mode ");
switch (ftMotion.cfg.dynFreqMode) {
switch (c.dynFreqMode) {
default:
case dynFreqMode_DISABLED: SERIAL_ECHOPGM("disabled"); break;
#if HAS_DYNAMIC_FREQ_MM
@ -85,9 +87,9 @@ void say_shaping() {
#if HAS_X_AXIS
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"));
SERIAL_ECHO(p_float_t(c.baseFreq.x, 2), F("Hz"));
#if HAS_DYNAMIC_FREQ
if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(ftMotion.cfg.dynFreqK.x, 2), F("Hz/"), z_based ? F("mm") : F("g"));
if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(c.dynFreqK.x, 2), F("Hz/"), z_based ? F("mm") : F("g"));
#endif
SERIAL_EOL();
#endif
@ -95,9 +97,9 @@ void say_shaping() {
#if HAS_Y_AXIS
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"));
SERIAL_ECHO(p_float_t(c.baseFreq.y, 2), F(" Hz"));
#if HAS_DYNAMIC_FREQ
if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(ftMotion.cfg.dynFreqK.y, 2), F("Hz/"), z_based ? F("mm") : F("g"));
if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(c.dynFreqK.y, 2), F("Hz/"), z_based ? F("mm") : F("g"));
#endif
SERIAL_EOL();
#endif
@ -105,20 +107,13 @@ void say_shaping() {
#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"));
SERIAL_ECHO(p_float_t(c.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"));
if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(c.dynFreqK.z, 2), F("Hz/"), z_based ? F("mm") : F("g"));
#endif
SERIAL_EOL();
#endif
}
#if HAS_EXTRUDERS
if (ftMotion.cfg.active) {
SERIAL_ECHO_TERNARY(ftMotion.cfg.linearAdvEna, "Linear Advance ", "en", "dis", "abled");
SERIAL_ECHOLNPGM(". Gain: ", ftMotion.cfg.linearAdvK);
}
#endif
}
void GcodeSuite::M493_report(const bool forReplay/*=true*/) {
@ -126,44 +121,31 @@ void GcodeSuite::M493_report(const bool forReplay/*=true*/) {
report_heading_etc(forReplay, F(STR_FT_MOTION));
const ft_config_t &c = ftMotion.cfg;
SERIAL_ECHOLNPGM(
" M493 S", c.active
#if HAS_X_AXIS
, " 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
, " 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
, " G", c.axis_sync_enabled
#if HAS_EXTRUDERS
, " P", c.linearAdvEna, " K", c.linearAdvK
#endif
// Axis Synchronization
, " H", c.axis_sync_enabled
);
#if HAS_DYNAMIC_FREQ
#define F_REPORT(A) , F(" F"), c.dynFreqK.A
#else
#define F_REPORT(A)
#endif
#define _REPORT_M493_AXIS(A) \
SERIAL_ECHOLN(F(" M493 "), C(AXIS_CHAR(_AXIS(A))) \
, F(" C"), c.shaper.A \
, F(" A"), c.baseFreq.A \
F_REPORT(A) \
, F(" I"), c.zeta.A \
, F(" Q"), c.vtol.A \
);
// Shaper type for each axis
SHAPED_MAP(_REPORT_M493_AXIS);
}
/**
@ -173,7 +155,22 @@ void GcodeSuite::M493_report(const bool forReplay/*=true*/) {
* 0: Fixed-Time Motion OFF (Standard Motion)
* 1: Fixed-Time Motion ON
*
* X/Y/Z/E<mode> Set the vibration compensator [input shaper] mode for an axis.
* V Flag to request version (Version 2+). (No reply = Version < 2)
*
* H<bool> Enable (1) or Disable (0) Axis Synchronization.
*
* Linear / Pressure Advance:
*
* P<bool> Enable (1) or Disable (0) Linear Advance pressure control
*
* Specifying Axes (for A,C,F,I,Q):
*
* X/Y/Z/E : Flag the axes (or core steppers) on which to apply the given parameters
* If none are given then XY is assumed.
*
* Compensator / Input Shaper:
*
* C<mode> Set Compensator Mode (Input Shaper) for the specified axes
* Users / slicers must remember to set the mode for all relevant axes!
* 0: NONE : No input shaper
* 1: ZV : Zero Vibration
@ -185,41 +182,27 @@ void GcodeSuite::M493_report(const bool forReplay/*=true*/) {
* 7: 3HEI : 3-Hump Extra-Intensive
* 8: MZV : Mass-based Zero Vibration
*
* P<bool> Enable (1) or Disable (0) Linear Advance pressure control
* A<Hz> Set static/base frequency for the specified axes
* I<flt> Set damping ratio for the specified axes
* Q<flt> Set vibration tolerance (vtol) for the specified axes
*
* K<gain> Set Linear Advance gain
* Dynamic Frequency Mode:
*
* G<bool> Enable (1) or Disable (0) axis synchronization.
*
* D<mode> Set Dynamic Frequency mode
* D<mode> Set Dynamic Frequency mode (for all axis compensators)
* 0: DISABLED
* 1: Z-based (Requires a Z axis)
* 2: Mass-based (Requires X and E axes)
*
* A<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
* F<Hz> Set frequency scaling for the specified axes
*
*/
void GcodeSuite::M493() {
// Request version of FTM. (No response = Version < 2)
if (parser.seen('V') && !parser.has_value()) {
SERIAL_ECHOLNPGM("FTM V" STRINGIFY(FTM_VERSION));
return;
}
struct { bool update:1, report:1; } flag = { false };
if (!parser.seen_any())
@ -237,57 +220,28 @@ void GcodeSuite::M493() {
#if NUM_AXES_SHAPED > 0
auto set_shaper = [&](const AxisEnum axis, const char c) {
const ftMotionShaper_t newsh = (ftMotionShaper_t)parser.value_byte();
const bool seenC = parser.seenval('C');
const ftMotionShaper_t shaperVal = seenC ? (ftMotionShaper_t)parser.value_byte() : ftMotionShaper_NONE;
const bool goodShaper = WITHIN(shaperVal, ftMotionShaper_NONE, ftMotionShaper_MZV);
if (seenC && !goodShaper) {
SERIAL_ECHOLN(F("?Invalid "), F("(C)ompensator value. (0-"), int(ftMotionShaper_MZV));
return;
}
auto set_shaper = [&](const AxisEnum axis, ftMotionShaper_t newsh) {
if (newsh != ftMotion.cfg.shaper[axis]) {
switch (newsh) {
default: SERIAL_ECHOLNPGM("?Invalid [", C(c), "] shaper."); return true;
case ftMotionShaper_NONE:
case ftMotionShaper_ZV:
case ftMotionShaper_ZVD:
case ftMotionShaper_ZVDD:
case ftMotionShaper_ZVDDD:
case ftMotionShaper_EI:
case ftMotionShaper_2HEI:
case ftMotionShaper_3HEI:
case ftMotionShaper_MZV:
ftMotion.cfg.shaper[axis] = newsh;
flag.update = flag.report = true;
break;
}
ftMotion.cfg.shaper[axis] = newsh;
flag.update = flag.report = true;
}
return false;
};
#define _SET_SHAPER(A) if (parser.seenval(CHARIFY(A)) && set_shaper(_AXIS(A), CHARIFY(A))) return;
SHAPED_MAP(_SET_SHAPER);
if (seenC) {
#define _SET_SHAPER(A) set_shaper(_AXIS(A), shaperVal);
SHAPED_MAP(_SET_SHAPER);
}
#endif // NUM_AXES_SHAPED > 0
#if HAS_EXTRUDERS
// Pressure control (linear advance) parameter.
if (parser.seen('P')) {
const bool val = parser.value_bool();
ftMotion.cfg.linearAdvEna = val;
flag.report = true;
}
// Pressure control (linear advance) gain parameter.
if (parser.seenval('K')) {
const float val = parser.value_float();
if (WITHIN(val, 0.0f, 10.0f)) {
ftMotion.cfg.linearAdvK = val;
flag.report = true;
}
else // Value out of range.
SERIAL_ECHOLNPGM("Linear Advance gain out of range.");
}
#endif // HAS_EXTRUDERS
// Parse '?' axis synchronization parameter.
if (parser.seen('?')) {
// Parse 'H' Axis Synchronization parameter.
if (parser.seenval('H')) {
const bool enabled = parser.value_bool();
if (enabled != ftMotion.cfg.axis_sync_enabled) {
ftMotion.cfg.axis_sync_enabled = enabled;
@ -313,12 +267,12 @@ void GcodeSuite::M493() {
flag.report = true;
break;
default:
SERIAL_ECHOLNPGM("?Invalid Dynamic Frequency Mode [D] value.");
SERIAL_ECHOLN(F("?Invalid "), F("(D)ynamic Frequency Mode value."));
break;
}
}
else {
SERIAL_ECHOLNPGM("?Wrong shaper for [D] Dynamic Frequency mode.");
SERIAL_ECHOLNPGM("?Wrong shaper for (D)ynamic Frequency Mode ", ftMotion.cfg.dynFreqMode, ".");
}
}
@ -329,247 +283,238 @@ void GcodeSuite::M493() {
#endif // HAS_DYNAMIC_FREQ
// Frequency parameter
const bool seenA = parser.seenval('A');
const float baseFreqVal = seenA ? parser.value_float() : 0.0f;
const bool goodBaseFreq = seenA && WITHIN(baseFreqVal, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2);
if (seenA && !goodBaseFreq)
SERIAL_ECHOLN(F("?Invalid "), F("(A) Base Frequency value. ("), int(FTM_MIN_SHAPE_FREQ), C('-'), int((FTM_FS) / 2), C(')'));
#if HAS_DYNAMIC_FREQ
// Dynamic Frequency parameter
const bool seenF = parser.seenval('F');
const float baseDynFreqVal = seenF ? parser.value_float() : 0.0f;
if (seenF && !modeUsesDynFreq)
SERIAL_ECHOLNPGM("?Wrong mode for (F)requency scaling.");
#endif
// Zeta parameter
const bool seenI = parser.seenval('I');
const float zetaVal = seenI ? parser.value_float() : 0.0f;
const bool goodZeta = seenI && WITHIN(zetaVal, 0.01f, 1.0f);
if (seenI && !goodZeta)
SERIAL_ECHOLN(F("?Invalid "), F("(I) Zeta value. (0.01-1.0)")); // Zeta out of range
// Vibration Tolerance parameter
const bool seenQ = parser.seenval('Q');
const float vtolVal = seenQ ? parser.value_float() : 0.0f;
const bool goodVtol = seenQ && WITHIN(vtolVal, 0.00f, 1.0f);
if (seenQ && !goodVtol)
SERIAL_ECHOLN(F("?Invalid "), F("(Q) Vibration Tolerance value. (0.0-1.0)")); // VTol out of range
const bool apply_xy = !parser.seen("XYZE");
#if HAS_X_AXIS
// Parse X frequency parameter
if (parser.seenval('A')) {
if (AXIS_IS_SHAPING(X)) {
const float val = parser.value_float();
// TODO: Frequency minimum is dependent on the shaper used; the above check isn't always correct.
if (WITHIN(val, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2)) {
ftMotion.cfg.baseFreq.x = val;
flag.update = flag.report = true;
}
else // Frequency out of range.
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_A_NAME), " [", C('A'), "] frequency value.");
}
else // Mode doesn't use frequency.
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " [", C('A'), "] frequency.");
}
if (apply_xy || parser.seen_test('X')) {
#if HAS_DYNAMIC_FREQ
// Parse X frequency scaling parameter
if (parser.seenval('F')) {
if (modeUsesDynFreq) {
ftMotion.cfg.dynFreqK.x = parser.value_float();
// Parse X frequency parameter
if (seenA) {
if (AXIS_IS_SHAPING(X)) {
// TODO: Frequency minimum is dependent on the shaper used; the above check isn't always correct.
if (goodBaseFreq) {
ftMotion.cfg.baseFreq.x = baseFreqVal;
flag.update = flag.report = true;
}
}
else // Mode doesn't use frequency.
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " [A] frequency.");
}
#if HAS_DYNAMIC_FREQ
// Parse X frequency scaling parameter
if (seenF && modeUsesDynFreq) {
ftMotion.cfg.dynFreqK.x = baseDynFreqVal;
flag.report = true;
}
else
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " [", C('F'), "] frequency scaling.");
}
#endif
#endif
// 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.x = val;
flag.update = true;
// Parse X zeta parameter
if (seenI) {
if (AXIS_IS_SHAPING(X)) {
if (goodZeta) {
ftMotion.cfg.zeta.x = zetaVal;
flag.update = true;
}
}
else
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_A_NAME), " zeta [", C('I'), "] value."); // Zeta out of range
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " zeta parameter.");
}
else
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " zeta parameter.");
}
// 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.x = val;
flag.update = true;
// Parse X vtol parameter
if (seenQ) {
if (AXIS_IS_EISHAPING(X)) {
if (goodVtol) {
ftMotion.cfg.vtol.x = vtolVal;
flag.update = true;
}
}
else
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_A_NAME), " vtol [", C('Q'), "] value."); // VTol out of range.
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " vtol parameter.");
}
else
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " vtol parameter.");
}
#endif // HAS_X_AXIS
#if HAS_Y_AXIS
// Parse Y frequency parameter
if (parser.seenval('B')) {
if (AXIS_IS_SHAPING(Y)) {
const float val = parser.value_float();
if (WITHIN(val, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2)) {
ftMotion.cfg.baseFreq.y = val;
flag.update = flag.report = true;
}
else // Frequency out of range.
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_B_NAME), " frequency [", C('B'), "] value.");
}
else // Mode doesn't use frequency.
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " [", C('B'), "] frequency.");
}
if (apply_xy || parser.seen_test('Y')) {
#if HAS_DYNAMIC_FREQ
// Parse Y frequency scaling parameter
if (parser.seenval('H')) {
if (modeUsesDynFreq) {
ftMotion.cfg.dynFreqK.y = parser.value_float();
// Parse Y frequency parameter
if (seenA) {
if (AXIS_IS_SHAPING(Y)) {
if (goodBaseFreq) {
ftMotion.cfg.baseFreq.y = baseFreqVal;
flag.update = flag.report = true;
}
}
else // Mode doesn't use frequency.
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " [A] frequency.");
}
#if HAS_DYNAMIC_FREQ
// Parse Y frequency scaling parameter
if (seenF && modeUsesDynFreq) {
ftMotion.cfg.dynFreqK.y = baseDynFreqVal;
flag.report = true;
}
else
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " [", C('H'), "] frequency scaling.");
}
#endif
#endif
// 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.y = val;
flag.update = true;
// Parse Y zeta parameter
if (seenI) {
if (AXIS_IS_SHAPING(Y)) {
if (goodZeta) {
ftMotion.cfg.zeta.y = zetaVal;
flag.update = true;
}
}
else
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_B_NAME), " zeta [", C('J'), "] value."); // Zeta out of range
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " zeta parameter.");
}
else
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " zeta parameter.");
}
// 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.y = val;
flag.update = true;
// Parse Y vtol parameter
if (seenQ) {
if (AXIS_IS_EISHAPING(Y)) {
if (goodVtol) {
ftMotion.cfg.vtol.y = vtolVal;
flag.update = true;
}
}
else
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_B_NAME), " vtol [", C('R'), "] value."); // VTol out of range.
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " vtol parameter.");
}
else
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 (parser.seen_test('Z')) {
#if HAS_DYNAMIC_FREQ
// Parse Z frequency scaling parameter
if (parser.seenval('L')) {
if (modeUsesDynFreq) {
ftMotion.cfg.dynFreqK.z = parser.value_float();
// Parse Z frequency parameter
if (seenA) {
if (AXIS_IS_SHAPING(Z)) {
if (goodBaseFreq) {
ftMotion.cfg.baseFreq.z = baseFreqVal;
flag.update = flag.report = true;
}
}
else // Mode doesn't use frequency.
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " [A] frequency.");
}
#if HAS_DYNAMIC_FREQ
// Parse Z frequency scaling parameter
if (seenF && modeUsesDynFreq) {
ftMotion.cfg.dynFreqK.z = baseDynFreqVal;
flag.report = true;
}
else
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " [", C('L'), "] frequency scaling.");
}
#endif
#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;
// Parse Z zeta parameter
if (seenI) {
if (AXIS_IS_SHAPING(Z)) {
if (goodZeta) {
ftMotion.cfg.zeta.z = zetaVal;
flag.update = true;
}
}
else
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_C_NAME), " zeta [", C('O'), "] value."); // Zeta out of range
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " zeta parameter.");
}
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;
// Parse Z vtol parameter
if (seenQ) {
if (AXIS_IS_EISHAPING(Z)) {
if (goodVtol) {
ftMotion.cfg.vtol.z = vtolVal;
flag.update = true;
}
}
else
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_C_NAME), " vtol [", C('M'), "] value."); // VTol out of range.
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " vtol parameter.");
}
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 (parser.seen_test('E')) {
#if HAS_DYNAMIC_FREQ
// Parse E frequency scaling parameter
if (parser.seenval('O')) {
if (modeUsesDynFreq) {
ftMotion.cfg.dynFreqK.e = parser.value_float();
// Parse E frequency parameter
if (seenA) {
if (AXIS_IS_SHAPING(E)) {
if (goodBaseFreq) {
ftMotion.cfg.baseFreq.e = baseFreqVal;
flag.update = flag.report = true;
}
}
else // Mode doesn't use frequency.
SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " [A] frequency.");
}
#if HAS_DYNAMIC_FREQ
// Parse E frequency scaling parameter
if (seenF && modeUsesDynFreq) {
ftMotion.cfg.dynFreqK.e = baseDynFreqVal;
flag.report = true;
}
else
SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " [", C('O'), "] frequency scaling.");
}
#endif
#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;
// Parse E zeta parameter
if (seenI) {
if (AXIS_IS_SHAPING(E)) {
if (goodZeta) {
ftMotion.cfg.zeta.e = zetaVal;
flag.update = true;
}
}
else
SERIAL_ECHOLNPGM("?Invalid ", C('E'), " zeta [", C('U'), "] value."); // Zeta out of range
SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " zeta parameter.");
}
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;
// Parse E vtol parameter
if (seenQ) {
if (AXIS_IS_EISHAPING(E)) {
if (goodVtol) {
ftMotion.cfg.vtol.e = vtolVal;
flag.update = true;
}
}
else
SERIAL_ECHOLNPGM("?Invalid ", C('E'), " vtol [", C('V'), "] value."); // VTol out of range.
SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " vtol parameter.");
}
else
SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " vtol parameter.");
}
#endif // FTM_SHAPER_E

View file

@ -97,7 +97,7 @@ void GcodeSuite::M494() {
report = true;
}
else
SERIAL_ECHOLNPGM("?Invalid trajectory type [T] value. Use 0=TRAPEZOIDAL, 1=POLY5, 2=POLY6");
SERIAL_ECHOLN(F("?Invalid "), F("trajectory type [T] value. Use 0=TRAPEZOIDAL, 1=POLY5, 2=POLY6"));
}
// Parse overshoot parameter.
@ -108,7 +108,7 @@ void GcodeSuite::M494() {
report = true;
}
else
SERIAL_ECHOLNPGM("?Invalid overshoot [O] value. Range 1.25-1.875");
SERIAL_ECHOLN(F("?Invalid "), F("overshoot [O] value. Range 1.25-1.875"));
}
#if ENABLED(FTM_SMOOTHING)

View file

@ -0,0 +1,186 @@
/**
* 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(FTM_RESONANCE_TEST)
#include "../../gcode.h"
#include "../../../module/ft_motion.h"
#include "../../../module/ft_motion/resonance_generator.h"
void say_resonance_test() {
const ftm_resonance_test_params_t &p = ftMotion.rtg.rt_params;
SERIAL_ECHO_START();
SERIAL_ECHOLN(F("M495 "), F("Resonance Test"));
SERIAL_ECHOLNPGM(" Axis: ", p.axis == NO_AXIS_ENUM ? C('-') : C(AXIS_CHAR(p.axis)));
SERIAL_ECHOLNPGM(" Freq Range (F..T): ", p.min_freq, " .. ", p.max_freq, " Hz");
SERIAL_ECHOLNPGM(" Octave Duration (O): ", p.octave_duration, " s");
SERIAL_ECHOLNPGM(" Accel/Hz (A): ", p.accel_per_hz);
}
/**
* M495: Configure and run the resonance test.
* With no parameters report the current settings.
*
* Parameters:
* A<accel/Hz> Accel per Hz. (Default 60)
* F<Hz> Start frequency. (Default 5.0)
* S Start the test.
* T<Hz> End frequency. (Default 100.0f)
* O<float> Octave duration for logarithmic progression
* C<int> Amplitude correction factor. (Default 5)
* X Flag to select the X axis.
* Y Flag to select the Y axis.
* Z Flag to select the Z axis.
* H<float> Get the Resonance Frequency from Timeline value. (Default 0)
*
* Examples:
* M495 S : Start the test with default or last-used parameters
* M495 X S : Start the test on the X axis with default or last-used parameters
* M495 H<val> : Get Resonance Frequency from Timeline value
*
*/
void GcodeSuite::M495() {
if (!parser.seen_any()) return say_resonance_test();
ftm_resonance_test_params_t &p = ftMotion.rtg.rt_params;
const bool seenX = parser.seen_test('X'), seenY = parser.seen_test('Y'), seenZ = parser.seen_test('Z');
if (seenX + seenY + seenZ == 1) {
const AxisEnum a = seenX ? X_AXIS : seenY ? Y_AXIS : Z_AXIS;
p.axis = a;
SERIAL_ECHOLN(C(AXIS_CHAR(a)), F("-axis selected"), F(" for "), F("Resonance Test"));
}
else if (seenX + seenY + seenZ > 1) {
SERIAL_ECHOLN(F("?Specify X, Y, or Z axis"), F(" for "), F("Resonance Test"));
return;
}
if (parser.seenval('A')) {
const float val = parser.value_float();
if (p.axis == Z_AXIS && val > 15.0f) {
p.accel_per_hz = 15.0f;
SERIAL_ECHOLNPGM("Accel/Hz set to max 15 mm/s for Z Axis");
}
else {
p.accel_per_hz = val;
SERIAL_ECHOLNPGM("Accel/Hz set to ", p.accel_per_hz);
}
}
if (parser.seenval('F')) {
const float val = parser.value_float();
if (val >= 5.0f) {
p.min_freq = val;
SERIAL_ECHOLNPGM("Start Frequency set to ", p.min_freq, " Hz");
}
else {
SERIAL_ECHOLN(F("?Invalid "), F("Start [F]requency. (minimum 5.0 Hz)"));
}
}
if (parser.seenval('T')) {
const float val = parser.value_float();
if (val > p.min_freq && val <= 200.0f) {
p.max_freq = val;
SERIAL_ECHOLNPGM("End Frequency set to ", p.max_freq, " Hz");
}
else {
SERIAL_ECHOLN(F("?Invalid "), F("End Frequency [T]. (StartFreq .. 200 Hz)"));
}
}
if (parser.seenval('O')) {
const float val = parser.value_float();
if (WITHIN(val, 20, 60)) {
p.octave_duration = val;
SERIAL_ECHOLNPGM("Octave Duration set to ",p.octave_duration, " s");
}
else {
SERIAL_ECHOLN(F("?Invalid "), F("octave duration [O]. (20..60 s)"));
}
}
if (parser.seenval('C')) {
const int val = parser.value_int();
if (WITHIN(val, 1, 8)) {
p.amplitude_correction = val;
SERIAL_ECHOLNPGM("Amplitude Correction Factor set to ", p.amplitude_correction);
}
else {
SERIAL_ECHOLN(F("?Invalid "), F("Amplitude [C]orrection Factor. (1..8)"));
}
}
if (parser.seenval('G')) {
const float val = parser.value_float();
if (WITHIN(val, 0, 100)) {
ftMotion.rtg.timeline = val;
SERIAL_ECHOLNPGM("Resonance Frequency set to ", ftMotion.rtg.getFrequencyFromTimeline(), " Hz");
}
else {
SERIAL_ECHOLN(F("?Invalid "), F("Timeline value (0..100 s)"));
}
}
if (parser.seen_test('S')) {
if (ftMotion.cfg.active) {
if (p.axis != NO_AXIS_ENUM) {
if (p.max_freq > p.min_freq) {
SERIAL_ECHOLN(F("Starting "), F("Resonance Test"));
ftMotion.start_resonance_test();
// The function returns immediately, the test runs in the background.
}
else {
SERIAL_ECHOLNPGM("?End Frequency must be greater than Start Frequency");
}
}
else {
SERIAL_ECHOLN(F("?Specify X, Y, or Z axis"), F(" first"));
}
}
else {
SERIAL_ECHOLN(F("?Activate FT Motion to run the "), F("Resonance Test"));
}
}
}
/**
* M496: Abort the resonance test (via Emergency Parser)
*/
void GcodeSuite::M496() {
if (ftMotion.rtg.isActive()) {
ftMotion.rtg.abort();
EmergencyParser::rt_stop_by_M496 = false;
#if DISABLED(MARLIN_SMALL_BUILD)
SERIAL_ECHOLN(F("Resonance Test"), F(" aborted."));
#endif
return;
}
#if DISABLED(MARLIN_SMALL_BUILD)
SERIAL_ECHOLN(F("No active "), F("Resonance Test"), F(" to abort."));
#endif
}
#endif // FTM_RESONANCE_TEST

View file

@ -28,10 +28,8 @@
#include "../../queue.h"
#include "../../parser.h"
char gcode_macros[GCODE_MACROS_SLOTS][GCODE_MACROS_SLOT_SIZE + 1] = {{ 0 }};
/**
* M810_819: Set/execute a G-code macro.
* M810 - M819: Set/execute a G-code macro.
*
* Usage:
* M810 <command>|... Set Macro 0 to the given commands, separated by the pipe character
@ -48,7 +46,7 @@ void GcodeSuite::M810_819() {
if (len > GCODE_MACROS_SLOT_SIZE)
SERIAL_ERROR_MSG("Macro too long.");
else {
char c, *s = parser.string_arg, *d = gcode_macros[index];
char c, *s = parser.string_arg, *d = gcode.macros[index];
do {
c = *s++;
*d++ = c == '|' ? '\n' : c;
@ -57,9 +55,13 @@ void GcodeSuite::M810_819() {
}
else {
// Execute a macro
char * const cmd = gcode_macros[index];
char * const cmd = gcode.macros[index];
if (strlen(cmd)) process_subcommands_now(cmd);
}
}
void GcodeSuite::M810_819_report(const bool forReplay/*=true*/) {
M820(forReplay);
}
#endif // GCODE_MACROS

View file

@ -28,17 +28,16 @@
#include "../../queue.h"
#include "../../parser.h"
extern char gcode_macros[GCODE_MACROS_SLOTS][GCODE_MACROS_SLOT_SIZE + 1];
/**
* M820: List defined M810 - M819 macros
*/
void GcodeSuite::M820() {
SERIAL_ECHOLNPGM(STR_STORED_MACROS);
void GcodeSuite::M820(const bool withoutEcho/*=true*/) {
report_heading(withoutEcho, F(STR_STORED_MACROS));
bool some = false;
for (uint8_t i = 0; i < GCODE_MACROS_SLOTS; ++i) {
const char *cmd = gcode_macros[i];
const char *cmd = gcode.macros[i];
if (*cmd) {
report_echo_start(withoutEcho);
SERIAL_ECHO(F("M81"), i, C(' '));
char c;
while ((c = *cmd++)) SERIAL_CHAR(c == '\n' ? '|' : c);

View file

@ -44,8 +44,13 @@
void GcodeSuite::G27() {
// Don't allow nozzle parking without homing first
if (homing_needed_error()) return;
nozzle.park(parser.ushortval('P'));
TERN_(SOVOL_SV06_RTS, RTS_MoveAxisHoming());
const int16_t pval = parser.intval('P');
if (WITHIN(pval, 0, 4)) {
nozzle.park(pval);
TERN_(SOVOL_SV06_RTS, RTS_MoveAxisHoming());
}
else
SERIAL_ECHOLN(F("?Invalid "), F("[P]arking style (0..4)."));
}
#endif // NOZZLE_PARK_FEATURE

View file

@ -1,103 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../../../inc/MarlinConfig.h"
#if SAVED_POSITIONS
#include "../../gcode.h"
#include "../../../module/motion.h"
#define DEBUG_OUT ENABLED(SAVED_POSITIONS_DEBUG)
#include "../../../core/debug_out.h"
bool report_stored_position(const uint8_t slot) {
if (!did_save_position[slot]) return false;
const xyze_pos_t &pos = stored_position[slot];
SERIAL_ECHO(STR_SAVED_POSITION, slot, C(':'));
#if NUM_AXES
SERIAL_ECHOPGM_P(LOGICAL_AXIS_PAIRED_LIST(
SP_E_LBL, pos.e,
SP_X_LBL, pos.x, SP_Y_LBL, pos.y, SP_Z_LBL, pos.z,
SP_I_LBL, pos.i, SP_J_LBL, pos.j, SP_K_LBL, pos.k,
SP_U_LBL, pos.u, SP_V_LBL, pos.v, SP_W_LBL, pos.w
));
#endif
SERIAL_EOL();
return true;
}
/**
* G60: Saved Positions
*
* S<slot> - Save to a memory slot. (default 0)
* Q<slot> - Restore from a memory slot. (default 0)
* D<slot> - Delete a memory slot. With no number, delete all.
*/
void GcodeSuite::G60() {
// With no parameters report any saved positions
if (!parser.seen_any()) {
uint8_t count = 0;
for (uint8_t s = 0; s < SAVED_POSITIONS; ++s)
if (report_stored_position(s)) ++count;
if (!count) SERIAL_ECHOLNPGM("No Saved Positions");
return;
}
// Only one of these parameters is permitted
const uint8_t seenD = parser.seen_test('D'),
seenQ = parser.seen_test('Q'),
seenS = parser.seen_test('S');
if (seenD + seenQ + seenS > 1) return;
// G60 D : Delete all saved positions
if (seenD && !parser.seenval('D')) {
did_save_position.reset();
return;
}
// G60 Dn / Q / S : Get the slot value
const uint8_t slot = parser.byteval(seenD ? 'D' : seenQ ? 'Q' : 'S');
// G60 Q : Redirect to G61(slot)
if (seenQ) return G61(slot);
// Valid slot number?
if (SAVED_POSITIONS < 256 && slot >= SAVED_POSITIONS) {
SERIAL_ERROR_MSG(STR_INVALID_POS_SLOT STRINGIFY(SAVED_POSITIONS));
return;
}
// G60 Dn
if (seenD) {
SERIAL_ECHOLNPGM(STR_SAVED_POSITION, slot, ": DELETED");
did_save_position.clear(slot);
return;
}
// G60 S
stored_position[slot] = current_position;
did_save_position.set(slot);
report_stored_position(slot);
}
#endif // SAVED_POSITIONS

View file

@ -24,7 +24,6 @@
#if SAVED_POSITIONS
#include "../../../module/planner.h"
#include "../../gcode.h"
#include "../../../module/motion.h"
#include "../../../module/planner.h"
@ -32,6 +31,79 @@
#define DEBUG_OUT ENABLED(SAVED_POSITIONS_DEBUG)
#include "../../../core/debug_out.h"
Flags<SAVED_POSITIONS> did_save_position;
xyze_pos_t stored_position[SAVED_POSITIONS];
bool report_stored_position(const uint8_t slot) {
if (!did_save_position[slot]) return false;
const xyze_pos_t &pos = stored_position[slot];
SERIAL_ECHO(STR_SAVED_POSITION, slot, C(':'));
#if NUM_AXES
SERIAL_ECHOPGM_P(LOGICAL_AXIS_PAIRED_LIST(
SP_E_LBL, pos.e,
SP_X_LBL, pos.x, SP_Y_LBL, pos.y, SP_Z_LBL, pos.z,
SP_I_LBL, pos.i, SP_J_LBL, pos.j, SP_K_LBL, pos.k,
SP_U_LBL, pos.u, SP_V_LBL, pos.v, SP_W_LBL, pos.w
));
#endif
SERIAL_EOL();
return true;
}
/**
* G60: Saved Positions
*
* S<slot> - Save to a memory slot. (default 0)
* Q<slot> - Restore from a memory slot. (default 0)
* D<slot> - Delete a memory slot. With no number, delete all.
*/
void GcodeSuite::G60() {
// With no parameters report any saved positions
if (!parser.seen_any()) {
uint8_t count = 0;
for (uint8_t s = 0; s < SAVED_POSITIONS; ++s)
if (report_stored_position(s)) ++count;
if (!count) SERIAL_ECHOLNPGM("No Saved Positions");
return;
}
// Only one of these parameters is permitted
const uint8_t seenD = parser.seen_test('D'),
seenQ = parser.seen_test('Q'),
seenS = parser.seen_test('S');
if (seenD + seenQ + seenS > 1) return;
// G60 D : Delete all saved positions
if (seenD && !parser.seenval('D')) {
did_save_position.reset();
return;
}
// G60 Dn / Q / S : Get the slot value
const uint8_t slot = parser.byteval(seenD ? 'D' : seenQ ? 'Q' : 'S');
// G60 Q : Redirect to G61(slot)
if (seenQ) return G61(slot);
// Valid slot number?
if (SAVED_POSITIONS < 256 && slot >= SAVED_POSITIONS) {
SERIAL_ERROR_MSG(STR_INVALID_POS_SLOT STRINGIFY(SAVED_POSITIONS));
return;
}
// G60 Dn
if (seenD) {
SERIAL_ECHOLNPGM(STR_SAVED_POSITION, slot, ": DELETED");
did_save_position.clear(slot);
return;
}
// G60 S
stored_position[slot] = current_position;
did_save_position.set(slot);
report_stored_position(slot);
}
/**
* G61: Return to saved position
*

View file

@ -104,6 +104,10 @@ relative_t GcodeSuite::axis_relative; // Init in constructor
xyz_pos_t GcodeSuite::coordinate_system[MAX_COORDINATE_SYSTEMS];
#endif
#if ENABLED(GCODE_MACROS)
char GcodeSuite::macros[GCODE_MACROS_SLOTS][GCODE_MACROS_SLOT_SIZE + 1] = {{ 0 }};
#endif
void GcodeSuite::report_echo_start(const bool forReplay) { if (!forReplay) SERIAL_ECHO_START(); }
void GcodeSuite::report_heading(const bool forReplay, FSTR_P const fstr, const bool eol/*=true*/) {
if (forReplay) return;
@ -179,7 +183,7 @@ void GcodeSuite::get_destination_from_command() {
if (skip_move)
destination[i] = current_position[i];
else
destination[i] = axis_is_relative(AxisEnum(i)) ? current_position[i] + v : LOGICAL_TO_NATIVE(v, i);
destination[i] = axis_is_relative((AxisEnum)i) ? current_position[i] + v : LOGICAL_TO_NATIVE(v, i);
}
else
destination[i] = current_position[i];
@ -717,7 +721,7 @@ void GcodeSuite::process_parsed_command(bool no_ok/*=false*/) {
#endif
#endif
#if DISABLED(NO_VOLUMETRICS)
#if HAS_VOLUMETRIC_EXTRUSION
case 200: M200(); break; // M200: Set filament diameter, E to cubic units
#endif
@ -926,6 +930,10 @@ void GcodeSuite::process_parsed_command(bool no_ok/*=false*/) {
#if ENABLED(FTM_SMOOTHING)
case 494: M494(); break; // M494: Fixed-Time Motion extras
#endif
#if ENABLED(FTM_RESONANCE_TEST)
case 495: M495(); break; // M495: Resonance test for Input Shaping
case 496: M496(); break; // M496: Abort resonance test
#endif
#endif
case 500: M500(); break; // M500: Store settings in EEPROM
@ -1038,7 +1046,7 @@ void GcodeSuite::process_parsed_command(bool no_ok/*=false*/) {
case 871: M871(); break; // M871: Print/reset/clear first layer temperature offset values
#endif
#if ENABLED(LIN_ADVANCE)
#if HAS_LIN_ADVANCE_K
case 900: M900(); break; // M900: Set advance K factor.
#endif

View file

@ -252,6 +252,8 @@
* M485 - Send RS485 packets (Requires RS485_SERIAL_PORT)
* M486 - Identify and cancel objects. (Requires CANCEL_OBJECTS)
* M493 - Set / Report input FT Motion/Shaping parameters. (Requires FT_MOTION)
* M495 - Set / Start resonance test. (Requires FTM_RESONANCE_TEST)
* M496 - Abort resonance test. (Requires FTM_RESONANCE_TEST)
* M500 - Store parameters in EEPROM. (Requires EEPROM_SETTINGS)
* M501 - Restore parameters from EEPROM. (Requires EEPROM_SETTINGS)
* M502 - Revert to the default "factory settings". ** Does not write them to EEPROM! **
@ -309,7 +311,7 @@
*
* M871 - Print/Reset/Clear first layer temperature offset values. (Requires PTC_PROBE, PTC_BED, or PTC_HOTEND)
* M876 - Handle Prompt Response. (Requires HOST_PROMPT_SUPPORT and not EMERGENCY_PARSER)
* M900 - Set / Report Linear Advance K-factor. (Requires LIN_ADVANCE)
* M900 - Set / Report Linear Advance K-factor (Requires LIN_ADVANCE or FT_MOTION) and Smoothing Tau factor (Requires SMOOTH_LIN_ADVANCE).
* M906 - Set / Report motor current in milliamps using axis codes XYZE, etc. Report values if no axis codes given. (Requires *_DRIVER_TYPE TMC(2130|2160|5130|5160|2208|2209|2240|2660))
* M907 - Set digital trimpot motor current using axis codes. (Requires a board with digital trimpots)
* M908 - Control digital trimpot directly. (Requires HAS_MOTOR_CURRENT_DAC or DIGIPOTSS_PIN)
@ -508,6 +510,11 @@ public:
static void dwell(const millis_t time);
#if ENABLED(GCODE_MACROS)
static char macros[GCODE_MACROS_SLOTS][GCODE_MACROS_SLOT_SIZE + 1];
static void reset_macros() { for (uint8_t i = 0; i < GCODE_MACROS_SLOTS; ++i) macros[i][0] = '\0'; }
#endif
private:
friend class MarlinSettings;
@ -766,6 +773,9 @@ private:
static void M104_M109(const bool isM109);
FORCE_INLINE static void M104() { M104_M109(false); }
FORCE_INLINE static void M109() { M104_M109(true); }
#if ENABLED(AUTOTEMP)
static void M104_report(const bool forReplay=true);
#endif
#endif
static void M105();
@ -878,7 +888,7 @@ private:
#endif
#endif
#if DISABLED(NO_VOLUMETRICS)
#if HAS_VOLUMETRIC_EXTRUSION
static void M200();
static void M200_report(const bool forReplay=true);
#endif
@ -1112,6 +1122,11 @@ private:
static void M493_report(const bool forReplay=true);
static void M494();
static void M494_report(const bool forReplay=true);
#if ENABLED(FTM_RESONANCE_TEST)
static void M495();
static void M495_report(const bool forReplay=true);
static void M496();
#endif
#endif
static void M500();
@ -1219,7 +1234,8 @@ private:
#if ENABLED(GCODE_MACROS)
static void M810_819();
static void M820();
static void M810_819_report(const bool forReplay=true);
static void M820(const bool withoutEcho=true);
#endif
#if HAS_BED_PROBE
@ -1249,7 +1265,7 @@ private:
static void M871();
#endif
#if ENABLED(LIN_ADVANCE)
#if HAS_LIN_ADVANCE_K
static void M900();
static void M900_report(const bool forReplay=true);
#endif

View file

@ -36,7 +36,7 @@
}
SERIAL_EOL();
}
inline void report_linear_axis_pos(const xyze_pos_t &pos) { report_all_axis_pos(pos, XYZ); }
inline void report_linear_axis_pos(const xyze_pos_t &pos) { report_all_axis_pos(pos, 3); }
void report_linear_axis_pos(const xyz_pos_t &pos, const uint8_t precision=3) {
LOOP_NUM_AXES(a) SERIAL_ECHO(FPSTR(pgm_read_ptr(&SP_AXIS_LBL[a])), p_float_t(pos[a], precision));

View file

@ -85,7 +85,7 @@ void GcodeSuite::M115() {
" MACHINE_TYPE:" MACHINE_NAME
" KINEMATICS:" MACHINE_KINEMATICS
" EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS)
#if NUM_AXES != XYZ
#if NUM_AXES != 3
" AXIS_COUNT:" STRINGIFY(NUM_AXES)
#endif
#if defined(MACHINE_UUID) || ENABLED(HAS_STM32_UID)
@ -139,7 +139,7 @@ void GcodeSuite::M115() {
cap_line(F("EEPROM"), ENABLED(EEPROM_SETTINGS));
// Volumetric Extrusion (M200)
cap_line(F("VOLUMETRIC"), DISABLED(NO_VOLUMETRICS));
cap_line(F("VOLUMETRIC"), ENABLED(HAS_VOLUMETRIC_EXTRUSION));
// AUTOREPORT_POS (M154)
cap_line(F("AUTOREPORT_POS"), ENABLED(AUTO_REPORT_POSITION));

View file

@ -242,7 +242,7 @@ void GcodeSuite::M360() {
#endif
config_line_e(e, F("Acceleration"), planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(e)]);
config_line_e(e, F("MaxSpeed"), planner.settings.max_feedrate_mm_s[E_AXIS_N(e)]);
config_line_e(e, F("Diameter"), TERN(NO_VOLUMETRICS, DEFAULT_NOMINAL_FILAMENT_DIA, planner.filament_size[e]));
config_line_e(e, F("Diameter"), TERN(HAS_VOLUMETRIC_EXTRUSION, planner.filament_size[e], DEFAULT_NOMINAL_FILAMENT_DIA));
config_line_e(e, F("MaxTemp"), thermalManager.hotend_maxtemp[e]);
}
#endif

View file

@ -281,7 +281,7 @@ public:
// Reduce to fewer bits
static int16_t value_int() { return (int16_t)value_long(); }
static uint16_t value_ushort() { return (uint16_t)value_long(); }
static uint16_t value_ushort() { return (uint16_t)value_ulong(); }
static uint8_t value_byte() { return (uint8_t)constrain(value_long(), 0, 255); }
// Bool is true with no value or non-zero
@ -324,7 +324,7 @@ public:
return linear_unit_factor;
}
static float linear_value_to_mm(const float 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); }
@ -420,19 +420,19 @@ 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 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 float linearval(const char c, const float dval=0) { return seenval(c) ? value_linear_units() : 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 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; }
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; }
{ 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; }
#if ENABLED(MARLIN_DEV_MODE)

View file

@ -81,7 +81,7 @@ void GcodeSuite::G30() {
TERN_(HAS_PTC, ptc.set_enabled(parser.boolval('C', true)));
// Potentially disable Fixed-Time Motion for probing
TERN_(FT_MOTION, FTMotionDisableInScope FT_Disabler);
TERN_(FT_MOTION, FTM_DISABLE_IN_SCOPE());
// Probe the bed, optionally raise, and return the measured height
const float measured_z = probe.probe_at_point(probepos, raise_after);

View file

@ -70,6 +70,9 @@
* (used by printingIsActive, etc.) and turning off heaters will stop the timer.
*/
void GcodeSuite::M104_M109(const bool isM109) {
#if ENABLED(AUTOTEMP)
if (!isM109 && !parser.seen_any()) return M104_report();
#endif
if (DEBUGGING(DRYRUN)) return;
@ -125,10 +128,22 @@ void GcodeSuite::M104_M109(const bool isM109) {
thermalManager.set_heating_message(target_extruder, !isM109 && got_temp);
}
TERN_(AUTOTEMP, planner.autotemp_M104_M109());
TERN_(AUTOTEMP, thermalManager.autotemp_M104_M109());
if (isM109 && got_temp)
(void)thermalManager.wait_for_hotend(target_extruder, no_wait_for_cooling);
}
#if ENABLED(AUTOTEMP)
//
// Report AUTOTEMP settings saved to EEPROM
//
void GcodeSuite::M104_report(const bool forReplay/*=true*/) {
TERN_(MARLIN_SMALL_BUILD, return);
report_heading_etc(forReplay, F(STR_AUTOTEMP));
const autotemp_cfg_t &c = thermalManager.autotemp.cfg;
SERIAL_ECHOLNPGM(" M104 S", c.min, " B", c.max, " F", c.factor);
}
#endif
#endif // HAS_HOTEND

View file

@ -745,6 +745,10 @@
#error "FTM_SHAPING_DEFAULT_[XY]_FREQ is now FTM_SHAPING_DEFAULT_FREQ_[XY]."
#elif defined(SDSS)
#error "SDSS is now SD_SS_PIN."
#elif defined(FTM_LINEAR_ADV_DEFAULT_ENA)
#error "FTM_LINEAR_ADV_DEFAULT_ENA is obsolete and should be removed."
#elif defined(FTM_LINEAR_ADV_DEFAULT_K)
#error "FTM_LINEAR_ADV_DEFAULT_K is now set with ADVANCE_K and should be removed."
#endif
// SDSS renamed to SD_SS_PIN

View file

@ -258,7 +258,7 @@
#if NUM_AXES >= XY
#define HAS_Y_AXIS 1
#define HAS_B_AXIS 1
#if NUM_AXES >= XYZ
#if NUM_AXES >= 3
#define HAS_Z_AXIS 1
#define HAS_C_AXIS 1
#if NUM_AXES >= 4

View file

@ -245,6 +245,10 @@
#undef STEALTHCHOP_E
#endif
#if DISABLED(NO_VOLUMETRICS)
#define HAS_VOLUMETRIC_EXTRUSION 1
#endif
#if !TEMP_SENSOR_CHAMBER
#undef CHAMBER_CHECK_INTERVAL
#undef CHAMBER_AUTO_FAN_PIN
@ -346,11 +350,12 @@
#if ALL(FT_MOTION, HAS_EXTRUDERS)
#define FTM_HAS_LIN_ADVANCE 1
#endif
#if HAS_JUNCTION_DEVIATION && ANY(LIN_ADVANCE, FTM_HAS_LIN_ADVANCE)
#if ANY(FTM_HAS_LIN_ADVANCE, LIN_ADVANCE)
#define HAS_LIN_ADVANCE_K 1
#endif
#if HAS_JUNCTION_DEVIATION && ENABLED(LIN_ADVANCE)
#define HAS_LINEAR_E_JERK 1
#endif
#if ENABLED(LIN_ADVANCE) && DISABLED(SMOOTH_LIN_ADVANCE)
#define HAS_ROUGH_LIN_ADVANCE 1
#endif
@ -1536,10 +1541,6 @@
#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
#endif
// Multi-Stepping Limit

View file

@ -313,10 +313,24 @@
/**
* SCARA cannot use SLOWDOWN and requires QUICKHOME
* Printable radius assumes joints can fully extend
*
* TPARA cannot use SLOWDOWN nor QUICKHOME
* Printable radius assumes joints can't fully extend
* AXEL_TPARA is assigned a default Home Position unless overridden
*/
#if IS_SCARA
#if ENABLED(AXEL_TPARA)
#define PRINTABLE_RADIUS (TPARA_LINKAGE_1 + TPARA_LINKAGE_2)
#define PRINTABLE_RADIUS_2 HYPOT2(TPARA_LINKAGE_1, TPARA_LINKAGE_2) - 2 * (TPARA_LINKAGE_1) * (TPARA_LINKAGE_2) * cosf(TPARA_MAX_L1L2_ANGLE)
#define PRINTABLE_RADIUS SQRT(PRINTABLE_RADIUS_2)
#ifndef MANUAL_X_HOME_POS
#define MANUAL_X_HOME_POS (TPARA_ARM_X_HOME_POS + TPARA_TCP_OFFSET_X - TPARA_OFFSET_X)
#endif
#ifndef MANUAL_Y_HOME_POS
#define MANUAL_Y_HOME_POS (TPARA_ARM_Y_HOME_POS + TPARA_TCP_OFFSET_Y - TPARA_OFFSET_Y)
#endif
#ifndef MANUAL_Z_HOME_POS
#define MANUAL_Z_HOME_POS (TPARA_ARM_Z_HOME_POS + TPARA_TCP_OFFSET_Z - TPARA_OFFSET_Z)
#endif
#else
#define QUICK_HOME
#define PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2)
@ -352,10 +366,12 @@
#endif
#endif
#ifdef MANUAL_Z_HOME_POS
#define Z_HOME_POS MANUAL_Z_HOME_POS
#else
#define Z_HOME_POS TERN(Z_HOME_TO_MIN, Z_MIN_POS, Z_MAX_POS)
#if HAS_Z_AXIS
#ifdef MANUAL_Z_HOME_POS
#define Z_HOME_POS MANUAL_Z_HOME_POS
#else
#define Z_HOME_POS TERN(Z_HOME_TO_MIN, Z_MIN_POS, Z_MAX_POS)
#endif
#endif
#if HAS_I_AXIS
@ -3303,6 +3319,9 @@
#if ANY(ADVANCED_PAUSE_FEATURE, PROBING_HEATERS_OFF)
#define HEATER_IDLE_HANDLER 1
#endif
#if ENABLED(DELTA)
#undef PROBING_STEPPERS_OFF
#endif
#if HAS_BED_PROBE && (ANY(PROBING_HEATERS_OFF, PROBING_STEPPERS_OFF, PROBING_ESTEPPERS_OFF, PROBING_FANS_OFF) || DELAY_BEFORE_PROBING > 0)
#define HAS_QUIET_PROBING 1
#endif
@ -3680,4 +3699,14 @@
// 2HEI : FTM_RATIO * 3 / 2
// 3HEI : FTM_RATIO * 2
#define FTM_SMOOTHING_ORDER 5 // 3 to 5 is closest to gaussian
#ifndef FTM_BUFFER_SIZE
#define FTM_BUFFER_SIZE 128
#endif
#define FTM_BUFFER_MASK (FTM_BUFFER_SIZE - 1u)
#if ANY(BIQU_MICROPROBE_V1, BIQU_MICROPROBE_V2)
#ifndef PROBE_WAKEUP_TIME_MS
#define PROBE_WAKEUP_TIME_MS 30
#define PROBE_WAKEUP_TIME_WARNING 1
#endif
#endif
#endif

View file

@ -399,8 +399,8 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L
/**
* Custom Boot and Status screens
*/
#if ENABLED(SHOW_CUSTOM_BOOTSCREEN) && NONE(HAS_MARLINUI_HD44780, HAS_MARLINUI_U8GLIB, TOUCH_UI_FTDI_EVE, IS_DWIN_MARLINUI)
#error "SHOW_CUSTOM_BOOTSCREEN requires Character LCD, Graphical LCD, or TOUCH_UI_FTDI_EVE."
#if ENABLED(SHOW_CUSTOM_BOOTSCREEN) && NONE(TFT_COLOR_UI, HAS_MARLINUI_HD44780, HAS_MARLINUI_U8GLIB, TOUCH_UI_FTDI_EVE, IS_DWIN_MARLINUI)
#error "SHOW_CUSTOM_BOOTSCREEN requires Character LCD, Graphical LCD, TOUCH_UI_FTDI_EVE, or TFT_COLOR_UI."
#elif ENABLED(SHOW_CUSTOM_BOOTSCREEN) && DISABLED(SHOW_BOOTSCREEN)
#error "SHOW_CUSTOM_BOOTSCREEN requires SHOW_BOOTSCREEN."
#elif ENABLED(CUSTOM_STATUS_SCREEN_IMAGE) && !HAS_MARLINUI_U8GLIB
@ -600,7 +600,7 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L
#if ENABLED(NOZZLE_PARK_FEATURE)
constexpr float npp[] = NOZZLE_PARK_POINT;
static_assert(COUNT(npp) == _MIN(NUM_AXES, XYZ), "NOZZLE_PARK_POINT requires coordinates for enabled axes, but only up to X,Y,Z.");
static_assert(COUNT(npp) == _MIN(NUM_AXES, 3), "NOZZLE_PARK_POINT requires coordinates for enabled axes, but only up to X,Y,Z.");
constexpr xyz_pos_t npp_xyz = NOZZLE_PARK_POINT;
static_assert(WITHIN(npp_xyz.x, X_MIN_POS, X_MAX_POS), "NOZZLE_PARK_POINT.X is out of bounds (X_MIN_POS, X_MAX_POS).");
static_assert(TERN1(HAS_Y_AXIS, WITHIN(npp_xyz.y, Y_MIN_POS, Y_MAX_POS)), "NOZZLE_PARK_POINT.Y is out of bounds (Y_MIN_POS, Y_MAX_POS).");
@ -848,26 +848,15 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L
#endif
/**
* Linear Advance 1.5 - Check K value range
* Linear Advance requirements
*/
#if ENABLED(LIN_ADVANCE)
#if ENABLED(DISTINCT_E_FACTORS)
constexpr float lak[] = ADVANCE_K;
static_assert(COUNT(lak) <= DISTINCT_E, "The ADVANCE_K array has too many elements (i.e., more than " STRINGIFY(DISTINCT_E) ").");
#define _LIN_ASSERT(N) static_assert(N >= COUNT(lak) || WITHIN(lak[N], 0, 10), "ADVANCE_K values must be from 0 to 10 (Changed in LIN_ADVANCE v1.5, Marlin 1.1.9).");
REPEAT(DISTINCT_E, _LIN_ASSERT)
#undef _LIN_ASSERT
#else
static_assert(WITHIN(ADVANCE_K, 0, 10), "ADVANCE_K must be from 0 to 10 (Changed in LIN_ADVANCE v1.5, Marlin 1.1.9).");
#endif
// Incompatible with Direct Stepping
#if ENABLED(DIRECT_STEPPING)
#error "DIRECT_STEPPING is incompatible with LIN_ADVANCE. (Extrusion is controlled externally by the Step Daemon.)"
#endif
/**
* Smooth Linear Advance
*/
// Smooth Linear Advance
#if ENABLED(SMOOTH_LIN_ADVANCE)
#ifndef CPU_32_BIT
#error "SMOOTH_LIN_ADVANCE requires a 32-bit CPU."
@ -875,9 +864,33 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L
#error "INPUT_SHAPING_E_SYNC requires INPUT_SHAPING_X or INPUT_SHAPING_Y."
#endif
#endif
#endif // LIN_ADVANCE
/**
* S_CURVE_ACCELERATION
*/
#if ENABLED(S_CURVE_ACCELERATION) && defined(S_CURVE_FACTOR)
#ifdef __AVR__
#error "S_CURVE_FACTOR is not yet implemented for AVR. Disable it to continue."
#endif
static_assert(WITHIN(S_CURVE_FACTOR, 0, 1), "S_CURVE_FACTOR must be between 0.0 and 1.0.");
#endif
/**
* Linear Advance and FT Motion - Check K value range
*/
#if HAS_LIN_ADVANCE_K
#if ENABLED(DISTINCT_E_FACTORS)
constexpr float lak[] = ADVANCE_K;
static_assert(COUNT(lak) <= DISTINCT_E, "The ADVANCE_K array has too many elements (i.e., more than " STRINGIFY(DISTINCT_E) ").");
#define _LIN_ASSERT(N) static_assert(N >= COUNT(lak) || WITHIN(lak[N], 0, 10), "ADVANCE_K values must be from 0 to 10.");
REPEAT(DISTINCT_E, _LIN_ASSERT)
#undef _LIN_ASSERT
#else
static_assert(WITHIN(ADVANCE_K, 0, 10), "ADVANCE_K must be from 0 to 10.");
#endif
#endif
/**
* Nonlinear Extrusion requirements
*/
@ -921,6 +934,19 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L
#endif
#endif
/**
* Differential Extruder requirements
*/
#if ENABLED(DIFFERENTIAL_EXTRUDER)
#if EXTRUDERS != 1
#error "DIFFERENTIAL EXTRUDER currently requires a single extruder (EXTRUDERS = 1)."
#elif !IS_FULL_CARTESIAN
#error "DIFFERENTIAL EXTRUDER requires standard Cartesian kinematics."
#elif !defined(CPU_32_BIT)
#error "DIFFERENTIAL EXTRUDER requires a 32-bit CPU."
#endif
#endif
/**
* Generic Switching Toolhead requirements
*/
@ -1109,7 +1135,7 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i
#error "Leveling in Marlin requires three or more axes, with Z as the vertical axis."
#elif ENABLED(CNC_WORKSPACE_PLANES) && !HAS_Z_AXIS
#error "CNC_WORKSPACE_PLANES currently requires a Z axis"
#elif ENABLED(DIRECT_STEPPING) && NUM_AXES > XYZ
#elif ENABLED(DIRECT_STEPPING) && NUM_AXES > 3
#error "DIRECT_STEPPING does not currently support more than 3 axes (i.e., XYZ)."
#elif ENABLED(FOAMCUTTER_XYUV) && !(HAS_I_AXIS && HAS_J_AXIS)
#error "FOAMCUTTER_XYUV requires I and J steppers to be enabled."
@ -1239,6 +1265,13 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i
#endif
#endif
/**
* Axel TPARA requirements
*/
#if ENABLED(AXEL_TPARA) && !ALL(HOME_Z_FIRST, HOME_Y_BEFORE_X)
#error "AXEL_TPARA requires both HOME_Z_FIRST and HOME_Y_BEFORE_X to be enabled."
#endif
/**
* Junction deviation is incompatible with kinematic systems.
*/
@ -1264,53 +1297,22 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i
+ (DISABLED(BLTOUCH) && HAS_Z_SERVO_PROBE) \
+ COUNT_ENABLED(PROBE_MANUALLY, BLTOUCH, BD_SENSOR, FIX_MOUNTED_PROBE, NOZZLE_AS_PROBE, TOUCH_MI_PROBE, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, RACK_AND_PINION_PROBE, SENSORLESS_PROBING, MAGLEV4, MAG_MOUNTED_PROBE, BIQU_MICROPROBE_V1, BIQU_MICROPROBE_V2)
#error "Please enable only one probe option. See the following errors:"
#if ENABLED(BLTOUCH)
#error "(BLTOUCH is enabled.)"
#elif HAS_Z_SERVO_PROBE
#error "(Z_SERVO_PROBE is enabled.)"
#endif
#if ENABLED(PROBE_MANUALLY)
#error "(PROBE_MANUALLY is enabled.)"
#endif
#if ENABLED(BD_SENSOR)
#error "(BD_SENSOR is enabled.)"
#endif
#if ENABLED(FIX_MOUNTED_PROBE)
#error "(FIX_MOUNTED_PROBE is enabled.)"
#endif
#if ENABLED(NOZZLE_AS_PROBE)
#error "(NOZZLE_AS_PROBE is enabled.)"
#endif
#if ENABLED(TOUCH_MI_PROBE)
#error "(TOUCH_MI_PROBE is enabled.)"
#endif
#if ENABLED(SOLENOID_PROBE)
#error "(SOLENOID_PROBE is enabled.)"
#endif
#if ENABLED(Z_PROBE_ALLEN_KEY)
#error "(Z_PROBE_ALLEN_KEY is enabled.)"
#endif
#if ENABLED(Z_PROBE_SLED)
#error "(Z_PROBE_SLED is enabled.)"
#endif
#if ENABLED(RACK_AND_PINION_PROBE)
#error "(RACK_AND_PINION_PROBE is enabled.)"
#endif
#if ENABLED(SENSORLESS_PROBING)
#error "(SENSORLESS_PROBING is enabled.)"
#endif
#if ENABLED(MAGLEV4)
#error "(MAGLEV4 is enabled.)"
#endif
#if ENABLED(MAG_MOUNTED_PROBE)
#error "(MAG_MOUNTED_PROBE is enabled.)"
#endif
#if ENABLED(BIQU_MICROPROBE_V1)
#error "(BIQU_MICROPROBE_V1 is enabled.)"
#endif
#if ENABLED(BIQU_MICROPROBE_V2)
#error "(BIQU_MICROPROBE_V2 is enabled.)"
#endif
static_assert(DISABLED(BLTOUCH), "(BLTOUCH is enabled.)");
static_assert(ENABLED(BLTOUCH) || DISABLED(HAS_Z_SERVO_PROBE), "(Z_SERVO_PROBE is enabled.)");
static_assert(DISABLED(PROBE_MANUALLY), "(PROBE_MANUALLY is enabled.)");
static_assert(DISABLED(BD_SENSOR), "(BD_SENSOR is enabled.)");
static_assert(DISABLED(FIX_MOUNTED_PROBE), "(FIX_MOUNTED_PROBE is enabled.)");
static_assert(DISABLED(NOZZLE_AS_PROBE), "(NOZZLE_AS_PROBE is enabled.)");
static_assert(DISABLED(TOUCH_MI_PROBE), "(TOUCH_MI_PROBE is enabled.)");
static_assert(DISABLED(SOLENOID_PROBE), "(SOLENOID_PROBE is enabled.)");
static_assert(DISABLED(Z_PROBE_ALLEN_KEY), "(Z_PROBE_ALLEN_KEY is enabled.)");
static_assert(DISABLED(Z_PROBE_SLED), "(Z_PROBE_SLED is enabled.)");
static_assert(DISABLED(RACK_AND_PINION_PROBE), "(RACK_AND_PINION_PROBE is enabled.)");
static_assert(DISABLED(SENSORLESS_PROBING), "(SENSORLESS_PROBING is enabled.)");
static_assert(DISABLED(MAGLEV4), "(MAGLEV4 is enabled.)");
static_assert(DISABLED(MAG_MOUNTED_PROBE), "(MAG_MOUNTED_PROBE is enabled.)");
static_assert(DISABLED(BIQU_MICROPROBE_V1), "(BIQU_MICROPROBE_V1 is enabled.)");
static_assert(DISABLED(BIQU_MICROPROBE_V2), "(BIQU_MICROPROBE_V2 is enabled.)");
#endif
#if HAS_BED_PROBE
@ -1487,7 +1489,6 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i
#elif !PIN_EXISTS(PROBE_ENABLE)
#error "BIQU MicroProbe requires a PROBE_ENABLE_PIN."
#endif
#if ENABLED(BIQU_MICROPROBE_V1)
#if ENABLED(INVERTED_PROBE_STATE)
#if Z_MIN_PROBE_ENDSTOP_HIT_STATE != LOW
@ -1505,6 +1506,13 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i
#error "BIQU_MICROPROBE_V1 requires Z_MIN_ENDSTOP_HIT_STATE HIGH."
#endif
#endif
#if NONE(ONBOARD_ENDSTOPPULLUPS, ENDSTOPPULLUPS, ENDSTOPPULLUP_ZMIN, ENDSTOPPULLUP_ZMIN_PROBE)
#if USE_Z_MIN_PROBE
#error "BIQU_MICROPROBE_V1 on Z_MIN_PROBE_PIN requires ENDSTOPPULLUP_ZMIN_PROBE, or ENDSTOPPULLUPS."
#else
#error "BIQU_MICROPROBE_V1 on Z_MIN_PIN requires ENDSTOPPULLUP_ZMIN, or ENDSTOPPULLUPS."
#endif
#endif
#elif ENABLED(BIQU_MICROPROBE_V2)
#if ENABLED(INVERTED_PROBE_STATE)
#if Z_MIN_PROBE_ENDSTOP_HIT_STATE != HIGH
@ -1523,6 +1531,13 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i
#endif
#endif
#endif
#if NONE(ONBOARD_ENDSTOPPULLUPS, ENDSTOPPULLUPS, ENDSTOPPULLUP_ZMIN, ENDSTOPPULLUP_ZMIN_PROBE)
#if USE_Z_MIN_PROBE
#error "BIQU_MICROPROBE_V2 on Z_MIN_PROBE_PIN requires ENDSTOPPULLUP_ZMIN_PROBE, or ENDSTOPPULLUPS."
#else
#error "BIQU_MICROPROBE_V2 on Z_MIN_PIN requires ENDSTOPPULLUP_ZMIN, or ENDSTOPPULLUPS."
#endif
#endif
#endif // BIQU_MICROPROBE_V1 || BIQU_MICROPROBE_V2
/**
@ -4488,10 +4503,9 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive."
* Fixed-Time Motion limitations
*/
#if ENABLED(FT_MOTION)
static_assert(FTM_BUFFER_SIZE >= 4 && (FTM_BUFFER_SIZE & FTM_BUFFER_MASK) == 0, "FTM_BUFFER_SIZE must be a power of two (128, 256, 512, ...).");
#if ENABLED(MIXING_EXTRUDER)
#error "FT_MOTION does not currently support MIXING_EXTRUDER."
#elif DISABLED(FTM_UNIFIED_BWS)
#error "FT_MOTION requires FTM_UNIFIED_BWS to be enabled because FBS is not yet implemented."
#endif
#if !HAS_X_AXIS
static_assert(FTM_DEFAULT_SHAPER_X != ftMotionShaper_NONE, "Without any linear axes FTM_DEFAULT_SHAPER_X must be ftMotionShaper_NONE.");
@ -4508,6 +4522,9 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive."
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
#if ENABLED(FTM_RESONANCE_TEST) && DISABLED(EMERGENCY_PARSER)
#error "EMERGENCY_PARSER is required with FTM_RESONANCE_TEST (to cancel the test)."
#endif
#endif
// Multi-Stepping Limit

View file

@ -42,7 +42,7 @@
* version was tagged.
*/
#ifndef STRING_DISTRIBUTION_DATE
#define STRING_DISTRIBUTION_DATE "2025-10-30"
#define STRING_DISTRIBUTION_DATE "2025-11-25"
#endif
/**

View file

@ -31,6 +31,10 @@
// Warnings! Located here so they will appear just once in the build output.
//
#if __cplusplus < 201703L
#warning "This build does not have access to >= c++17 features."
#endif
// static_warning works like a static_assert but only emits a (messy) warning.
#ifdef __GNUC__
namespace mfwarn {
@ -724,6 +728,10 @@
#warning "BIQU MicroProbe V2 detect signal requires a strong pull-up. Some processors have weak internal pull-up capabilities, so we recommended connecting MicroProbe SIGNAL / GND to Z-MIN / Z-STOP instead of the dedicated PROBE port. (Define NO_MICROPROBE_WARNING to suppress this warning.)"
#endif
#if PROBE_WAKEUP_TIME_WARNING
#warning "PROBE_WAKEUP_TIME_MS has been set to the default 30ms."
#endif
//
// Warn users of potential endstop/DIAG pin conflicts to prevent homing issues when not using sensorless homing
//
@ -919,6 +927,13 @@
#warning "The BEEPER cannot produce tones so you can disable SPEAKER."
#endif
/**
* Delay for probes that need time to boot up when enabled
*/
#if defined(DELAY_BEFORE_PROBING) && DELAY_BEFORE_PROBING < 25
#warning "The actual DELAY_BEFORE_PROBING will be the minimum 25 ms. Leave DELAY_BEFORE_PROBING disabled to use the minimum."
#endif
/**
* Fixed-Time Motion
*/
@ -926,17 +941,28 @@
#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
#if ENABLED(NONLINEAR_EXTRUSION)
#warning "NONLINEAR_EXTRUSION does not (currently) operate when FT_MOTION is the active motion system."
#endif
#if ENABLED(LIN_ADVANCE)
#warning "Be aware that FT_MOTION K factor (M493 K) is a separate setting from LIN_ADVANCE K factor (M900 K)."
#warning "Be aware that FT_MOTION K factor is now set with M900 K (same as LIN_ADVANCE)."
#if DISABLED(FTM_SMOOTHING)
#warning "For higher print quality enable FTM_SMOOTHING with FTM_SMOOTHING_TIME_E to tame Linear Advance accelerations."
#endif
#endif
#if DISABLED(FTM_SHAPER_E)
#warning "For higher print quality enable FTM_SHAPER_E (even if shaper is NONE) to allow axis synchronization."
#endif
#endif
#if ENABLED(FTM_HOME_AND_PROBE)
#if ANY(BIQU_MICROPROBE_V1, BIQU_MICROPROBE_V2)
#warning "Let us know if you experience any issues with BIQU Microprobe and FT_MOTION."
#if PROBE_WAKEUP_TIME_MS <= 25
#warning "A PROBE_WAKEUP_TIME_MS over 25 ms is recommended with FT_MOTION and BIQU_MICROPROBE_V1 or BIQU_MICROPROBE_V2."
#endif
#endif
#if PROBE_WAKEUP_TIME_MS < 30
#warning "A PROBE_WAKEUP_TIME_MS over 30 ms is recommended with FT_MOTION."
#endif
#endif
@ -964,8 +990,6 @@
/**
* Smooth Linear Advance with Mixing Extruder, S-Curve Acceleration
*/
#if ENABLED(SMOOTH_LIN_ADVANCE)
#if ENABLED(MIXING_EXTRUDER)
#warning "SMOOTH_LIN_ADVANCE with MIXING_EXTRUDER is untested. Use with caution."
#endif
#if ALL(SMOOTH_LIN_ADVANCE, MIXING_EXTRUDER)
#warning "SMOOTH_LIN_ADVANCE with MIXING_EXTRUDER is untested. Use with caution."
#endif

View file

@ -452,11 +452,11 @@ bool MarlinUI::detected() {
#if ENABLED(LCD_I2C_TYPE_MCP23017)
// Reading these buttons is too slow for interrupt context
// so they are read during LCD update in the main loop.
uint8_t slow_bits = lcd.readButtons()
uint8_t slow_bits = (lcd.readButtons()
#if !BUTTON_EXISTS(ENC)
<< B_I2C_BTN_OFFSET
#endif
;
);
#if ENABLED(LCD_I2C_VIKI)
if ((slow_bits & (B_MI | B_RI)) && PENDING(millis(), next_button_update_ms)) // LCD clicked
slow_bits &= ~(B_MI | B_RI); // Disable LCD clicked buttons if screen is updated
@ -1124,7 +1124,7 @@ void MarlinUI::draw_status_screen() {
rotate_progress();
#else
char c;
uint16_t per;
uint16_t pct;
#if HAS_FAN0
if (true
#if ALL(HAS_EXTRUDERS, ADAPTIVE_FAN_SLOWING)
@ -1136,18 +1136,18 @@ void MarlinUI::draw_status_screen() {
#if ENABLED(ADAPTIVE_FAN_SLOWING)
else { c = '*'; spd = thermalManager.scaledFanSpeed(0, spd); }
#endif
per = thermalManager.pwmToPercent(spd);
pct = thermalManager.pwmToPercent(spd);
}
else
#endif
{
#if HAS_EXTRUDERS
c = 'E';
per = planner.flow_percentage[0];
pct = planner.flow_percentage[0];
#endif
}
lcd_put_lchar(c);
lcd_put_u8str(i16tostr3rj(per));
lcd_put_u8str(i16tostr3rj(pct));
lcd_put_u8str(F("%"));
#endif
#endif

View file

@ -144,7 +144,7 @@ uint8_t u8g_dev_ssd1309_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void
return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg);
}
uint8_t u8g_dev_ssd1309_buf[WIDTH*2] U8G_NOCOMMON ;
uint8_t u8g_dev_ssd1309_buf[WIDTH*2] U8G_NOCOMMON;
u8g_pb_t u8g_dev_ssd1309_pb = { {8, HEIGHT, 0, 0, 0}, WIDTH, u8g_dev_ssd1309_buf};
u8g_dev_t u8g_dev_ssd1309_sw_spi = { u8g_dev_ssd1309_128x64_fn, &u8g_dev_ssd1309_pb, U8G_COM_HAL_SW_SPI_FN };

View file

@ -230,7 +230,7 @@ uint8_t u8g_dev_st7565_64128n_HAL_2x_fn(u8g_t *u8g, u8g_dev_t *dev, const uint8_
U8G_PB_DEV(u8g_dev_st7565_64128n_HAL_sw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_st7565_64128n_HAL_fn, U8G_COM_HAL_SW_SPI_FN);
uint8_t u8g_dev_st7565_64128n_HAL_2x_buf[WIDTH*2] U8G_NOCOMMON ;
uint8_t u8g_dev_st7565_64128n_HAL_2x_buf[WIDTH*2] U8G_NOCOMMON;
u8g_pb_t u8g_dev_st7565_64128n_HAL_2x_pb = { {16, HEIGHT, 0, 0, 0}, WIDTH, u8g_dev_st7565_64128n_HAL_2x_buf};
u8g_dev_t u8g_dev_st7565_64128n_HAL_2x_sw_spi = { u8g_dev_st7565_64128n_HAL_2x_fn, &u8g_dev_st7565_64128n_HAL_2x_pb, U8G_COM_HAL_SW_SPI_FN };

View file

@ -192,7 +192,7 @@ uint8_t u8g_dev_st7920_128x64_HAL_4x_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg,
U8G_PB_DEV(u8g_dev_st7920_128x64_HAL_sw_spi, LCD_PIXEL_WIDTH, LCD_PIXEL_HEIGHT, PAGE_HEIGHT, u8g_dev_st7920_128x64_HAL_fn, U8G_COM_ST7920_HAL_SW_SPI);
#define QWIDTH ((LCD_PIXEL_WIDTH) * 4)
uint8_t u8g_dev_st7920_128x64_HAL_4x_buf[QWIDTH] U8G_NOCOMMON ;
uint8_t u8g_dev_st7920_128x64_HAL_4x_buf[QWIDTH] U8G_NOCOMMON;
u8g_pb_t u8g_dev_st7920_128x64_HAL_4x_pb = { { 32, LCD_PIXEL_HEIGHT, 0, 0, 0 }, LCD_PIXEL_WIDTH, u8g_dev_st7920_128x64_HAL_4x_buf};
u8g_dev_t u8g_dev_st7920_128x64_HAL_4x_sw_spi = { u8g_dev_st7920_128x64_HAL_4x_fn, &u8g_dev_st7920_128x64_HAL_4x_pb, U8G_COM_ST7920_HAL_SW_SPI };

View file

@ -205,7 +205,7 @@ uint8_t u8g_dev_uc1701_mini12864_HAL_2x_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t m
U8G_PB_DEV(u8g_dev_uc1701_mini12864_HAL_sw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_uc1701_mini12864_HAL_fn, U8G_COM_HAL_SW_SPI_FN);
U8G_PB_DEV(u8g_dev_uc1701_mini12864_HAL_hw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_uc1701_mini12864_HAL_fn, U8G_COM_HAL_HW_SPI_FN);
uint8_t u8g_dev_uc1701_mini12864_HAL_2x_buf[WIDTH*2] U8G_NOCOMMON ;
uint8_t u8g_dev_uc1701_mini12864_HAL_2x_buf[WIDTH*2] U8G_NOCOMMON;
u8g_pb_t u8g_dev_uc1701_mini12864_HAL_2x_pb = { {16, HEIGHT, 0, 0, 0}, WIDTH, u8g_dev_uc1701_mini12864_HAL_2x_buf};
u8g_dev_t u8g_dev_uc1701_mini12864_HAL_2x_sw_spi = { u8g_dev_uc1701_mini12864_HAL_2x_fn, &u8g_dev_uc1701_mini12864_HAL_2x_pb, U8G_COM_HAL_SW_SPI_FN };
u8g_dev_t u8g_dev_uc1701_mini12864_HAL_2x_hw_spi = { u8g_dev_uc1701_mini12864_HAL_2x_fn, &u8g_dev_uc1701_mini12864_HAL_2x_pb, U8G_COM_HAL_HW_SPI_FN };

View file

@ -1978,7 +1978,7 @@ void hmiSDCardUpdate() {
if (hmiFlag.home_flag) return;
if (DWIN_lcd_sd_status != card.isMounted()) {
DWIN_lcd_sd_status = card.isMounted();
//SERIAL_ECHOLNPGM("HMI_SDCardUpdate: ", DWIN_lcd_sd_status);
//SERIAL_ECHOLNPGM("hmiSDCardUpdate: ", DWIN_lcd_sd_status);
if (DWIN_lcd_sd_status) {
if (checkkey == ID_SelectFile)
redrawSDList();
@ -4170,6 +4170,61 @@ void eachMomentUpdate() {
drawPrintProgressBar();
}
}
// Estimate remaining time every 20 seconds
static millis_t next_remain_time_update = 0;
if (_card_percent > 1 && ELAPSED(ms, next_remain_time_update) && !hmiFlag.heat_flag) {
_remain_time = (elapsed.value - dwin_heat_time) / (_card_percent * 0.01f) - (elapsed.value - dwin_heat_time);
next_remain_time_update += DWIN_REMAIN_TIME_UPDATE_INTERVAL;
drawPrintProgressRemain();
}
}
else if (dwin_abort_flag && !hmiFlag.home_flag) { // Print Stop
dwin_abort_flag = false;
hmiValues.printSpeed = feedrate_percentage = 100;
dwin_zoffset = BABY_Z_VAR;
select_page.set(0);
gotoMainMenu();
}
#if ENABLED(POWER_LOSS_RECOVERY)
else if (DWIN_lcd_sd_status && recovery.ui_flag_resume) { // Resume interrupted print
recovery.ui_flag_resume = false;
auto update_selection = [&](const bool sel) {
hmiFlag.select_flag = sel;
const uint16_t c1 = sel ? COLOR_BG_WINDOW : COLOR_SELECT;
dwinDrawRectangle(0, c1, 25, 306, 126, 345);
dwinDrawRectangle(0, c1, 24, 305, 127, 346);
const uint16_t c2 = sel ? COLOR_SELECT : COLOR_BG_WINDOW;
dwinDrawRectangle(0, c2, 145, 306, 246, 345);
dwinDrawRectangle(0, c2, 144, 305, 247, 346);
};
popupWindowResume();
update_selection(true);
char * const name = card.longest_filename();
const int8_t npos = _MAX(0U, DWIN_WIDTH - strlen(name) * (MENU_CHR_W)) / 2;
dwinDrawString(true, font8x16, COLOR_POPUP_TEXT, COLOR_BG_WINDOW, npos, 252, name);
dwinUpdateLCD();
bool recovery_flag = true;
while (recovery_flag) {
EncoderState encoder_diffState = encoderReceiveAnalyze();
if (encoder_diffState != ENCODER_DIFF_NO) {
if (encoder_diffState == ENCODER_DIFF_ENTER) {
recovery_flag = false;
if (hmiFlag.select_flag) break;
TERN_(POWER_LOSS_RECOVERY, queue.inject(F("M1000C")));
hmiStartFrame(true);
return;
}
else
update_selection(encoder_diffState == ENCODER_DIFF_CW);
dwinUpdateLCD();
}
}
// Print time so far
duration_t elapsed = print_job_timer.duration();

View file

@ -265,13 +265,6 @@ private:
#if ENABLED(AUTO_BED_LEVELING_UBL)
uint8_t tilt_grid = 1;
void manualValueUpdate(bool undefined=false) {
gcode.process_subcommands_now(
TS(F("M421I"), mesh_x, 'J', mesh_y, 'Z', p_float_t(current_position.z, 3), undefined ? "N" : "")
);
planner.synchronize();
}
bool createPlaneFromMesh() {
struct linear_fit_data lsf_results;
incremental_LSF_reset(&lsf_results);
@ -310,17 +303,14 @@ private:
return false;
}
#else
void manualValueUpdate() {
gcode.process_subcommands_now(
TS(F("G29I"), mesh_x, 'J', mesh_y, 'Z', p_float_t(current_position.z, 3))
);
planner.synchronize();
}
#endif
void manualValueUpdate(const bool reset=false) {
const float zval = reset ? 0.0f : current_position.z;
queue.inject(TS(F("M421I"), mesh_x, F("J"), mesh_y, F("Z"), p_float_t(zval, 3)));
planner.synchronize();
}
void manual_mesh_move(const bool zmove=false) {
if (zmove) {
planner.synchronize();
@ -1172,7 +1162,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
thermalManager.wait_for_hotend(0);
}
popupHandler(Popup_FilChange);
gcode.process_subcommands_now(TS(F("M600 B1 R"), thermalManager.degTargetHotend(0)));
queue.inject(TS(F("M600 B1 R"), thermalManager.degTargetHotend(0)));
}
#endif
}
@ -1221,7 +1211,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
drawMenuItem(row, ICON_MoveX, GET_TEXT_F(MSG_AUTO_HOME_X));
else {
popupHandler(Popup_Home);
gcode.process_subcommands_now(F("G28X"));
queue.inject(F("G28X"));
planner.synchronize();
redrawMenu();
}
@ -1231,7 +1221,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
drawMenuItem(row, ICON_MoveY, GET_TEXT_F(MSG_AUTO_HOME_X));
else {
popupHandler(Popup_Home);
gcode.process_subcommands_now(F("G28Y"));
queue.inject(F("G28Y"));
planner.synchronize();
redrawMenu();
}
@ -1241,7 +1231,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
drawMenuItem(row, ICON_MoveZ, GET_TEXT_F(MSG_AUTO_HOME_X));
else {
popupHandler(Popup_Home);
gcode.process_subcommands_now(F("G28Z"));
queue.inject(F("G28Z"));
planner.synchronize();
redrawMenu();
}
@ -1250,7 +1240,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
if (draw)
drawMenuItem(row, ICON_SetHome, F("Set Home Here"));
else {
gcode.process_subcommands_now(F("G92X0Y0Z0"));
queue.inject(F("G92X0Y0Z0"));
audioFeedback();
}
break;
@ -1572,7 +1562,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
drawMenuItem(row, ICON_Homing, GET_TEXT_F(MSG_AUTO_HOME_Z));
else {
popupHandler(Popup_Home);
gcode.process_subcommands_now(F("G28Z"));
queue.inject(F("G28Z"));
popupHandler(Popup_MoveWait);
#if ENABLED(Z_SAFE_HOMING)
planner.synchronize();
@ -1803,8 +1793,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
drawMenuItem(row, ICON_Info, F(CONFIG_MENU_ITEM_1_DESC));
else {
popupHandler(Popup_Custom);
//queue.inject(F(CONFIG_MENU_ITEM_1_GCODE)); // Old code
gcode.process_subcommands_now(F(CONFIG_MENU_ITEM_1_GCODE));
TERN(CONFIG_MENU_ITEM_1_IMMEDIATE, gcode.process_subcommands_now, queue.inject)(F(CONFIG_MENU_ITEM_1_GCODE));
planner.synchronize();
redrawMenu();
#if ENABLED(CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK)
@ -1823,7 +1812,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
drawMenuItem(row, ICON_Info, F(CONFIG_MENU_ITEM_2_DESC));
else {
popupHandler(Popup_Custom);
gcode.process_subcommands_now(F(CONFIG_MENU_ITEM_2_GCODE));
TERN(CONFIG_MENU_ITEM_1_IMMEDIATE, gcode.process_subcommands_now, queue.inject)(F(CONFIG_MENU_ITEM_2_GCODE));
planner.synchronize();
redrawMenu();
#if ENABLED(CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK)
@ -1842,7 +1831,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
drawMenuItem(row, ICON_Info, F(CONFIG_MENU_ITEM_3_DESC));
else {
popupHandler(Popup_Custom);
gcode.process_subcommands_now(F(CONFIG_MENU_ITEM_3_GCODE));
TERN(CONFIG_MENU_ITEM_1_IMMEDIATE, gcode.process_subcommands_now, queue.inject)(F(CONFIG_MENU_ITEM_3_GCODE));
planner.synchronize();
redrawMenu();
#if ENABLED(CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK)
@ -1861,7 +1850,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
drawMenuItem(row, ICON_Info, F(CONFIG_MENU_ITEM_4_DESC));
else {
popupHandler(Popup_Custom);
gcode.process_subcommands_now(F(CONFIG_MENU_ITEM_4_GCODE));
TERN(CONFIG_MENU_ITEM_1_IMMEDIATE, gcode.process_subcommands_now, queue.inject)(F(CONFIG_MENU_ITEM_4_GCODE));
planner.synchronize();
redrawMenu();
#if ENABLED(CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK)
@ -1880,7 +1869,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
drawMenuItem(row, ICON_Info, F(CONFIG_MENU_ITEM_5_DESC));
else {
popupHandler(Popup_Custom);
gcode.process_subcommands_now(F(CONFIG_MENU_ITEM_5_GCODE));
TERN(CONFIG_MENU_ITEM_1_IMMEDIATE, gcode.process_subcommands_now, queue.inject)(F(CONFIG_MENU_ITEM_5_GCODE));
planner.synchronize();
redrawMenu();
#if ENABLED(CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK)
@ -2121,7 +2110,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
drawMenuItem(row, ICON_HotendTemp, GET_TEXT_F(MSG_PID_AUTOTUNE));
else {
popupHandler(Popup_PIDWait);
gcode.process_subcommands_now(TS(F("M303E0C"), PID_cycles, 'S', PID_e_temp, 'U'));
queue.inject(TS(F("M303E0C"), PID_cycles, 'S', PID_e_temp, 'U'));
planner.synchronize();
redrawMenu();
}
@ -2187,7 +2176,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
drawMenuItem(row, ICON_HotendTemp, GET_TEXT_F(MSG_PID_AUTOTUNE));
else {
popupHandler(Popup_PIDWait);
gcode.process_subcommands_now(TS(F("M303E-1C"), PID_cycles, 'S', PID_bed_temp, 'U'));
queue.inject(TS(F("M303E-1C"), PID_cycles, 'S', PID_bed_temp, 'U'));
planner.synchronize();
redrawMenu();
}
@ -3031,7 +3020,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
if (draw)
drawMenuItem(row, ICON_StepY, F("M48 Probe Test"));
else {
gcode.process_subcommands_now(
queue.inject(
TS(F("G28O\nM48X"), p_float_t((X_BED_SIZE + X_MIN_POS) / 2.0f, 3), 'Y', p_float_t((Y_BED_SIZE + Y_MIN_POS) / 2.0f, 3), 'P', testcount)
);
}
@ -3225,9 +3214,9 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
gcode.home_all_axes(true);
popupHandler(Popup_Level);
if (mesh_conf.tilt_grid > 1)
gcode.process_subcommands_now(TS(F("G29J"), mesh_conf.tilt_grid));
queue.inject(TS(F("G29J"), mesh_conf.tilt_grid));
else
gcode.process_subcommands_now(F("G29J"));
queue.inject(F("G29J"));
planner.synchronize();
redrawMenu();
}
@ -3262,7 +3251,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
#endif
#elif HAS_BED_PROBE
popupHandler(Popup_Level);
gcode.process_subcommands_now(F("G29"));
queue.inject(F("G29"));
planner.synchronize();
popupHandler(Popup_SaveLevel);
#else
@ -3270,7 +3259,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
set_bed_leveling_enabled(false);
gridpoint = 1;
popupHandler(Popup_MoveWait);
gcode.process_subcommands_now(F("G29"));
queue.inject(F("G29"));
planner.synchronize();
drawMenu(ID_ManualMesh);
#endif
@ -3353,7 +3342,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
popupHandler(Popup_MeshSlot);
break;
}
gcode.process_subcommands_now(F("G29 L"));
queue.inject(F("G29 L"));
planner.synchronize();
audioFeedback(true);
}
@ -3366,7 +3355,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
popupHandler(Popup_MeshSlot);
break;
}
gcode.process_subcommands_now(F("G29 S"));
queue.inject(F("G29 S"));
planner.synchronize();
audioFeedback(true);
}
@ -3510,8 +3499,8 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
#define LEVELING_M_UP (LEVELING_M_OFFSET + 1)
#define LEVELING_M_DOWN (LEVELING_M_UP + 1)
#define LEVELING_M_GOTO_VALUE (LEVELING_M_DOWN + 1)
#define LEVELING_M_UNDEF (LEVELING_M_GOTO_VALUE + ENABLED(AUTO_BED_LEVELING_UBL))
#define LEVELING_M_TOTAL LEVELING_M_UNDEF
#define LEVELING_M_ZERO (LEVELING_M_GOTO_VALUE + 1)
#define LEVELING_M_TOTAL LEVELING_M_ZERO
switch (item) {
case LEVELING_M_BACK:
@ -3570,7 +3559,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
drawMenuItem(row, ICON_Axis, F("+0.01mm Up"));
else if (bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y] < MAX_Z_OFFSET) {
bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y] += 0.01;
gcode.process_subcommands_now(F("M290 Z0.01"));
queue.inject(F("M290 Z0.01"));
planner.synchronize();
current_position.z += 0.01f;
sync_plan_position();
@ -3582,7 +3571,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
drawMenuItem(row, ICON_AxisD, F("-0.01mm Down"));
else if (bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y] > MIN_Z_OFFSET) {
bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y] -= 0.01;
gcode.process_subcommands_now(F("M290 Z-0.01"));
queue.inject(F("M290 Z-0.01"));
planner.synchronize();
current_position.z -= 0.01f;
sync_plan_position();
@ -3601,16 +3590,14 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
drawCheckbox(row, mesh_conf.goto_mesh_value);
}
break;
#if ENABLED(AUTO_BED_LEVELING_UBL)
case LEVELING_M_UNDEF:
if (draw)
drawMenuItem(row, ICON_ResetEEPROM, F("Clear Point Value"));
else {
mesh_conf.manualValueUpdate(true);
redrawMenu(false);
}
break;
#endif
case LEVELING_M_ZERO:
if (draw)
drawMenuItem(row, ICON_ResetEEPROM, GET_TEXT_F(MSG_ZERO_MESH_POINT));
else {
mesh_conf.manualValueUpdate(true);
redrawMenu(false);
}
break;
}
break;
#endif // HAS_MESH
@ -3653,7 +3640,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
mesh_conf.manual_mesh_move();
}
else {
gcode.process_subcommands_now(F("G29 S"));
queue.inject(F("G29 S"));
planner.synchronize();
audioFeedback(true);
drawMenu(ID_Leveling, LEVELING_GET_MESH);
@ -3691,7 +3678,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
drawMenuItem(row, ICON_Axis, F("+0.01mm Up"));
else if (bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y] < MAX_Z_OFFSET) {
bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y] += 0.01;
gcode.process_subcommands_now(F("M290 Z0.01"));
queue.inject(F("M290 Z0.01"));
planner.synchronize();
current_position.z += 0.01f;
sync_plan_position();
@ -3703,7 +3690,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
drawMenuItem(row, ICON_Axis, F("-0.01mm Down"));
else if (bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y] > MIN_Z_OFFSET) {
bedlevel.z_values[mesh_conf.mesh_x][mesh_conf.mesh_y] -= 0.01;
gcode.process_subcommands_now(F("M290 Z-0.01"));
queue.inject(F("M290 Z-0.01"));
planner.synchronize();
current_position.z -= 0.01f;
sync_plan_position();
@ -3745,13 +3732,13 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
}
else if (gridpoint < GRID_MAX_POINTS) {
popupHandler(Popup_MoveWait);
gcode.process_subcommands_now(F("G29"));
queue.inject(F("G29"));
planner.synchronize();
gridpoint++;
redrawMenu();
}
else {
gcode.process_subcommands_now(F("G29"));
queue.inject(F("G29"));
planner.synchronize();
audioFeedback(settings.save());
drawMenu(ID_Leveling, LEVELING_GET_MESH);
@ -4014,26 +4001,26 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
switch (last_menu) {
case ID_Prepare:
popupHandler(Popup_FilChange);
gcode.process_subcommands_now(TS(F("M600 B1 R"), thermalManager.degTargetHotend(0)));
queue.inject(TS(F("M600 B1 R"), thermalManager.degTargetHotend(0)));
break;
#if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES)
case ID_ChangeFilament:
switch (last_selection) {
case CHANGEFIL_LOAD:
popupHandler(Popup_FilLoad);
gcode.process_subcommands_now(F("M701"));
queue.inject(F("M701"));
planner.synchronize();
redrawMenu(true, true, true);
break;
case CHANGEFIL_UNLOAD:
popupHandler(Popup_FilLoad, true);
gcode.process_subcommands_now(F("M702"));
queue.inject(F("M702"));
planner.synchronize();
redrawMenu(true, true, true);
break;
case CHANGEFIL_CHANGE:
popupHandler(Popup_FilChange);
gcode.process_subcommands_now(TS(F("M600 B1 R"), thermalManager.degTargetHotend(0)));
queue.inject(TS(F("M600 B1 R"), thermalManager.degTargetHotend(0)));
break;
}
break;
@ -4608,10 +4595,10 @@ void JyersDWIN::printScreenControl() {
TERN_(POWER_LOSS_RECOVERY, recovery.prepare());
#else
#if HAS_HEATED_BED
gcode.process_subcommands_now(TS(F("M140 S"), pausebed));
queue.inject(TS(F("M140 S"), pausebed));
#endif
#if HAS_EXTRUDERS
gcode.process_subcommands_now(TS(F("M109 S"), pausetemp));
queue.inject(TS(F("M109 S"), pausetemp));
#endif
TERN_(HAS_FAN, thermalManager.fan_speed[0] = pausefan);
planner.synchronize();
@ -4731,7 +4718,7 @@ void JyersDWIN::popupControl() {
thermalManager.wait_for_hotend(0);
}
popupHandler(Popup_FilChange);
gcode.process_subcommands_now(TS(F("M600B1R"), thermalManager.degTargetHotend(0)));
queue.inject(TS(F("M600B1R"), thermalManager.degTargetHotend(0)));
}
}
else
@ -4754,7 +4741,7 @@ void JyersDWIN::popupControl() {
case Popup_SaveLevel:
if (selection == 0) {
#if ENABLED(AUTO_BED_LEVELING_UBL)
gcode.process_subcommands_now(F("G29 S"));
queue.inject(F("G29 S"));
planner.synchronize();
audioFeedback(true);
#else

View file

@ -126,6 +126,7 @@ enum colorID : uint8_t {
};
#define Custom_Colors 10
#define COLOR_AQUA RGB(0x00, 0x3F, 0x1F)
#define COLOR_LIGHT_WHITE 0xBDD7
#define COLOR_GREEN RGB(0x00, 0x3F, 0x00)
#define COLOR_LIGHT_GREEN 0x3460

View file

@ -75,14 +75,6 @@ bool drawing_mesh = false;
#if ENABLED(AUTO_BED_LEVELING_UBL)
void BedLevelTools::manualValueUpdate(const uint8_t mesh_x, const uint8_t mesh_y, bool undefined/*=false*/) {
MString<MAX_CMD_SIZE> cmd;
cmd.set(F("M421 I"), mesh_x, 'J', mesh_y, 'Z', p_float_t(current_position.z, 3));
if (undefined) cmd += F(" N");
gcode.process_subcommands_now(cmd);
planner.synchronize();
}
bool BedLevelTools::createPlaneFromMesh() {
struct linear_fit_data lsf_results;
incremental_LSF_reset(&lsf_results);
@ -122,17 +114,14 @@ bool drawing_mesh = false;
return false;
}
#else
void BedLevelTools::manualValueUpdate(const uint8_t mesh_x, const uint8_t mesh_y) {
gcode.process_subcommands_now(
TS(F("G29 I"), mesh_x, 'J', mesh_y, 'Z', p_float_t(current_position.z, 3))
);
planner.synchronize();
}
#endif
void BedLevelTools::manualValueUpdate(const uint8_t mesh_x, const uint8_t mesh_y, const bool reset/*=false*/) {
const float zval = reset ? 0.0f : current_position.z;
queue.inject(TS(F("M421I"), mesh_x, F("J"), mesh_y, F("Z"), p_float_t(zval, 3)));
planner.synchronize();
}
void BedLevelTools::manualMove(const uint8_t mesh_x, const uint8_t mesh_y, bool zmove/*=false*/) {
gcode.process_subcommands_now(F("G28O"));
if (!zmove) {

View file

@ -55,11 +55,9 @@ public:
static uint8_t tilt_grid;
#if ENABLED(AUTO_BED_LEVELING_UBL)
static void manualValueUpdate(const uint8_t mesh_x, const uint8_t mesh_y, bool undefined=false);
static bool createPlaneFromMesh();
#else
static void manualValueUpdate(const uint8_t mesh_x, const uint8_t mesh_y);
#endif
static void manualValueUpdate(const uint8_t mesh_x, const uint8_t mesh_y, const bool reset=false);
static void manualMove(const uint8_t mesh_x, const uint8_t mesh_y, bool zmove=false);
static void moveToXYZ();
static void moveToXY();

View file

@ -200,7 +200,7 @@ typedef struct {
select_t select_page{0}, select_print{0};
#if ENABLED(LCD_BED_TRAMMING)
constexpr float bed_tramming_inset_lfbr[] = BED_TRAMMING_INSET_LFRB;
constexpr float bed_tramming_inset_lfrb[] = BED_TRAMMING_INSET_LFRB;
#endif
bool hash_changed = true; // Flag to know if message status was changed
@ -466,8 +466,8 @@ void popupPauseOrStop() {
FSTR_P errorstr;
uint8_t icon;
switch (state) {
case 0: errorstr = GET_TEXT_F(MSG_TEMP_TOO_LOW); icon = ICON_TempTooLow; break;
case 1: errorstr = GET_TEXT_F(MSG_TEMP_TOO_HIGH); icon = ICON_TempTooHigh; break;
case 0: errorstr = GET_TEXT_F(DGUS_MSG_TEMP_TOO_LOW); icon = ICON_TempTooLow; break;
case 1: errorstr = GET_TEXT_F(DGUS_MSG_TEMP_TOO_HIGH); icon = ICON_TempTooHigh; break;
default: errorstr = GET_TEXT_F(MSG_ERR_HEATING_FAILED); icon = ICON_Temperature; break; // May be thermal runaway, temp malfunction, etc.
}
dwinShowPopup(icon, heaterstr, errorstr, BTN_Continue);
@ -1744,7 +1744,7 @@ void dwinLevelingDone() {
break;
case PID_TEMP_TOO_HIGH:
checkkey = last_checkkey;
dwinPopupConfirm(ICON_TempTooHigh, GET_TEXT_F(MSG_PID_AUTOTUNE_FAILED), GET_TEXT_F(MSG_TEMP_TOO_HIGH));
dwinPopupConfirm(ICON_TempTooHigh, GET_TEXT_F(MSG_PID_AUTOTUNE_FAILED), GET_TEXT_F(DGUS_MSG_TEMP_TOO_HIGH));
break;
case AUTOTUNE_DONE:
checkkey = last_checkkey;
@ -2435,23 +2435,23 @@ void setFlow() { setPIntOnClick(FLOW_EDIT_MIN, FLOW_EDIT_MAX, []{ planner.refres
switch (point) {
case 0:
LCD_MESSAGE(MSG_TRAM_FL);
x = bed_tramming_inset_lfbr[0];
y = bed_tramming_inset_lfbr[1];
x = bed_tramming_inset_lfrb[0];
y = bed_tramming_inset_lfrb[1];
break;
case 1:
LCD_MESSAGE(MSG_TRAM_FR);
x = X_BED_SIZE - bed_tramming_inset_lfbr[2];
y = bed_tramming_inset_lfbr[1];
x = X_BED_SIZE - bed_tramming_inset_lfrb[2];
y = bed_tramming_inset_lfrb[1];
break;
case 2:
LCD_MESSAGE(MSG_TRAM_BR);
x = X_BED_SIZE - bed_tramming_inset_lfbr[2];
y = Y_BED_SIZE - bed_tramming_inset_lfbr[3];
x = X_BED_SIZE - bed_tramming_inset_lfrb[2];
y = Y_BED_SIZE - bed_tramming_inset_lfrb[3];
break;
case 3:
LCD_MESSAGE(MSG_TRAM_BL);
x = bed_tramming_inset_lfbr[0];
y = Y_BED_SIZE - bed_tramming_inset_lfbr[3];
x = bed_tramming_inset_lfrb[0];
y = Y_BED_SIZE - bed_tramming_inset_lfrb[3];
break;
#if ENABLED(BED_TRAMMING_INCLUDE_CENTER)
case 4:
@ -2686,13 +2686,13 @@ void applyMaxAccel() { planner.set_max_acceleration(hmiValue.axis, menuData.valu
void setJDmm() { setPFloatOnClick(MIN_JD_MM, MAX_JD_MM, 3, applyJDmm); }
#endif
#if ENABLED(LIN_ADVANCE)
#if HAS_LIN_ADVANCE_K
#define LA_FDIGITS 3
void applyLA_K() { planner.set_advance_k(menuData.value / POW(10, LA_FDIGITS)); }
void setLA_K() { setFloatOnClick(0, 10, LA_FDIGITS, planner.extruder_advance_K[0], applyLA_K); }
void setLA_K() { setFloatOnClick(0, 10, LA_FDIGITS, planner.get_advance_k(), applyLA_K); }
void onDrawLA_K(MenuItem* menuitem, int8_t line) { onDrawFloatMenu(menuitem, line, LA_FDIGITS, planner.get_advance_k()); }
#if ENABLED(SMOOTH_LIN_ADVANCE)
void applySmoothLA() { Stepper::set_advance_tau(menuData.value / POW(10, 2)); }
void applySmoothLA() { stepper.set_advance_tau(menuData.value / POW(10, 2)); }
void setSmoothLA() { setPFloatOnClick(0, 0.5, 2, applySmoothLA); }
#endif
#endif
@ -3551,11 +3551,13 @@ void drawTuneMenu() {
#if ENABLED(PROUI_ITEM_JD)
EDIT_ITEM(ICON_JDmm, MSG_JUNCTION_DEVIATION, onDrawPFloat3Menu, setJDmm, &planner.junction_deviation_mm);
#endif
#if ALL(PROUI_ITEM_ADVK, LIN_ADVANCE)
static float editable_k = planner.get_advance_k();
#if PROUI_ITEM_ADVK
static float editable_k;
editable_k = planner.get_advance_k();
EDIT_ITEM(ICON_MaxAccelerated, MSG_ADVANCE_K, onDrawLA_K, setLA_K, &editable_k);
#if ENABLED(SMOOTH_LIN_ADVANCE)
static float editable_u = Stepper::get_advance_tau();
static float editable_u;
editable_u = stepper.get_advance_tau();
EDIT_ITEM(ICON_MaxSpeed, MSG_ADVANCE_TAU, onDrawPFloat2Menu, setSmoothLA, &editable_u);
#endif
#endif
@ -3675,7 +3677,7 @@ void drawTuneMenu() {
void drawMotionMenu() {
constexpr uint8_t items = (4
+ COUNT_ENABLED(EDITABLE_STEPS_PER_UNIT, EDITABLE_HOMING_FEEDRATE, LIN_ADVANCE, SHAPING_MENU, ADAPTIVE_STEP_SMOOTHING_TOGGLE)
+ COUNT_ENABLED(EDITABLE_STEPS_PER_UNIT, EDITABLE_HOMING_FEEDRATE, HAS_LIN_ADVANCE_K, SMOOTH_LIN_ADVANCE, SHAPING_MENU, ADAPTIVE_STEP_SMOOTHING_TOGGLE)
+ 2
);
checkkey = ID_Menu;
@ -3694,11 +3696,13 @@ void drawMotionMenu() {
#if ENABLED(EDITABLE_HOMING_FEEDRATE)
MENU_ITEM(ICON_Homing, MSG_HOMING_FEEDRATE, onDrawSubMenu, drawHomingFRMenu);
#endif
#if ENABLED(LIN_ADVANCE)
static float editable_k = planner.get_advance_k();
#if HAS_LIN_ADVANCE_K
static float editable_k;
editable_k = planner.get_advance_k();
EDIT_ITEM(ICON_MaxAccelerated, MSG_ADVANCE_K, onDrawLA_K, setLA_K, &editable_k);
#if ENABLED(SMOOTH_LIN_ADVANCE)
static float editable_u = Stepper::get_advance_tau();
static float editable_u;
editable_u = stepper.get_advance_tau();
EDIT_ITEM(ICON_MaxSpeed, MSG_ADVANCE_TAU, onDrawPFloat2Menu, setSmoothLA, &editable_u);
#endif
#endif
@ -4312,6 +4316,7 @@ void drawMaxAccelMenu() {
void applyEditMeshX() { bedLevelTools.mesh_x = menuData.value; }
void applyEditMeshY() { bedLevelTools.mesh_y = menuData.value; }
void resetMesh() { bedLevelTools.meshReset(); LCD_MESSAGE(MSG_MESH_RESET); }
void zeroPoint() { bedLevelTools.manualValueUpdate(bedLevelTools.mesh_x, bedLevelTools.mesh_y, true); editZValueItem->redraw(); LCD_MESSAGE(MSG_ZERO_MESH_POINT); }
void setEditMeshX() { hmiValue.select = 0; setIntOnClick(0, GRID_MAX_POINTS_X - 1, bedLevelTools.mesh_x, applyEditMeshX, liveEditMesh); }
void setEditMeshY() { hmiValue.select = 1; setIntOnClick(0, GRID_MAX_POINTS_Y - 1, bedLevelTools.mesh_y, applyEditMeshY, liveEditMesh); }
void setEditZValue() { setPFloatOnClick(Z_OFFSET_MIN, Z_OFFSET_MAX, 3); }
@ -4413,6 +4418,7 @@ void drawMaxAccelMenu() {
EDIT_ITEM(ICON_MeshEditX, MSG_MESH_X, onDrawPInt8Menu, setEditMeshX, &bedLevelTools.mesh_x);
EDIT_ITEM(ICON_MeshEditY, MSG_MESH_Y, onDrawPInt8Menu, setEditMeshY, &bedLevelTools.mesh_y);
editZValueItem = EDIT_ITEM(ICON_MeshEditZ, MSG_MESH_EDIT_Z, onDrawPFloat2Menu, setEditZValue, &bedlevel.z_values[bedLevelTools.mesh_x][bedLevelTools.mesh_y]);
MENU_ITEM(ICON_SetZOffset, MSG_ZERO_MESH_POINT, onDrawMenuItem, zeroPoint);
}
updateMenu(editMeshMenu);
}

View file

@ -121,11 +121,11 @@
#if ENABLED(POWER_LOSS_RECOVERY)
#define PROUI_ITEM_PLR // Tune > Power-loss Recovery
#endif
#if ENABLED(HAS_JUNCTION_DEVIATION)
#if HAS_JUNCTION_DEVIATION
#define PROUI_ITEM_JD // Tune > Junction Deviation
#endif
#if ENABLED(LIN_ADVANCE)
#define PROUI_ITEM_ADVK // Tune > Linear Advance
#if HAS_LIN_ADVANCE_K
#define PROUI_ITEM_ADVK 1 // Tune > Linear Advance
#endif
#if ANY(HAS_PID_HEATING, MPC_AUTOTUNE) && DISABLED(DISABLE_TUNING_GRAPH)
#define PROUI_TUNING_GRAPH 1

View file

@ -238,7 +238,7 @@ namespace ExtUI {
void onSteppersDisabled() {}
void onSteppersEnabled() {}
void onAxisDisabled(const axis_t axis) {
set_axis_untrusted(AxisEnum(axis)); // MRISCOC workaround: https://github.com/MarlinFirmware/Marlin/issues/23095
set_axis_untrusted((AxisEnum)axis); // MRISCOC workaround: https://github.com/MarlinFirmware/Marlin/issues/23095
}
void onAxisEnabled(const axis_t) {}

View file

@ -1967,14 +1967,14 @@ namespace Anycubic {
setSoftEndstopState(false);
z_off = getZOffset_mm() - 0.01f;
z_off = getZOffset_mm() - BABYSTEP_SIZE_Z;
setZOffset_mm(z_off);
sendTxtToTFT(ftostr52sprj(getZOffset_mm()) + 2, TXT_LEVEL_OFFSET);
if (isAxisPositionKnown(Z)) {
const float currZpos = getAxisPosition_mm(Z);
setAxisPosition_mm(currZpos - 0.01f, Z);
setAxisPosition_mm(currZpos - BABYSTEP_SIZE_Z, Z);
}
setSoftEndstopState(true);
@ -1985,14 +1985,14 @@ namespace Anycubic {
setSoftEndstopState(false);
z_off = getZOffset_mm() + 0.01f;
z_off = getZOffset_mm() + BABYSTEP_SIZE_Z;
setZOffset_mm(z_off);
sendTxtToTFT(ftostr52sprj(getZOffset_mm()) + 2, TXT_LEVEL_OFFSET);
if (isAxisPositionKnown(Z)) { // Move Z axis
const float currZpos = getAxisPosition_mm(Z);
setAxisPosition_mm(currZpos + 0.01f, Z);
setAxisPosition_mm(currZpos + BABYSTEP_SIZE_Z, Z);
}
setSoftEndstopState(true);

Some files were not shown because too many files have changed in this diff Show more