diff --git a/.github/workflows/test-builds.yml b/.github/workflows/test-builds.yml
index c6afaffebf7a2..f5ce466d9051f 100644
--- a/.github/workflows/test-builds.yml
+++ b/.github/workflows/test-builds.yml
@@ -97,6 +97,7 @@ jobs:
- REMRAM_V1
- BTT_SKR_SE_BX
- chitu_f103
+ - Index_Mobo_Rev03
# Put lengthy tests last
diff --git a/.gitignore b/.gitignore
old mode 100755
new mode 100644
index bb899d9e271f3..a83bfa4265a6a
--- a/.gitignore
+++ b/.gitignore
@@ -27,7 +27,7 @@ bdf2u8g
# OS
#
applet/
-*.DS_Store
+.DS_Store
#
# Misc
@@ -167,8 +167,3 @@ __pycache__
# IOLogger logs
*_log.csv
-
-# Simulation / Native
-eeprom.dat
-imgui.ini
-platformio.ini
diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 85e22aae940c3..4334f01393cd8 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -35,8 +35,7 @@
*
* Advanced settings can be found in Configuration_adv.h
*/
-//Modify Date = 8-29-2021
-#define CONFIGURATION_H_VERSION 02000901
+#define CONFIGURATION_H_VERSION 02000903
//===========================================================================
//============================= Getting Started =============================
@@ -257,7 +256,6 @@
#define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders
#define PARKING_EXTRUDER_GRAB_DISTANCE 1 // (mm) Distance to move beyond the parking point to grab the extruder
- //#define MANUAL_SOLENOID_CONTROL // Manual control of docking solenoids with M380 S / M381
#if ENABLED(PARKING_EXTRUDER)
@@ -758,6 +756,16 @@
//#define COREZY
//#define MARKFORGED_XY // MarkForged. See https://reprap.org/forum/read.php?152,504042
+// Enable for a belt style printer with endless "Z" motion
+//#define BELTPRINTER
+
+// Enable for Polargraph Kinematics
+//#define POLARGRAPH
+#if ENABLED(POLARGRAPH)
+ #define POLARGRAPH_MAX_BELT_LEN 1035.0
+ #define POLAR_SEGMENTS_PER_SECOND 5
+#endif
+
//===========================================================================
//============================== Endstop Settings ===========================
//===========================================================================
@@ -784,18 +792,18 @@
#define ENDSTOPPULLUPS
#if DISABLED(ENDSTOPPULLUPS)
// Disable ENDSTOPPULLUPS to set pullups individually
- //#define ENDSTOPPULLUP_XMAX
- //#define ENDSTOPPULLUP_YMAX
- //#define ENDSTOPPULLUP_ZMAX
- //#define ENDSTOPPULLUP_IMAX
- //#define ENDSTOPPULLUP_JMAX
- //#define ENDSTOPPULLUP_KMAX
//#define ENDSTOPPULLUP_XMIN
//#define ENDSTOPPULLUP_YMIN
//#define ENDSTOPPULLUP_ZMIN
//#define ENDSTOPPULLUP_IMIN
//#define ENDSTOPPULLUP_JMIN
//#define ENDSTOPPULLUP_KMIN
+ //#define ENDSTOPPULLUP_XMAX
+ //#define ENDSTOPPULLUP_YMAX
+ //#define ENDSTOPPULLUP_ZMAX
+ //#define ENDSTOPPULLUP_IMAX
+ //#define ENDSTOPPULLUP_JMAX
+ //#define ENDSTOPPULLUP_KMAX
//#define ENDSTOPPULLUP_ZMIN_PROBE
#endif
@@ -803,18 +811,18 @@
//#define ENDSTOPPULLDOWNS
#if DISABLED(ENDSTOPPULLDOWNS)
// Disable ENDSTOPPULLDOWNS to set pulldowns individually
- //#define ENDSTOPPULLDOWN_XMAX
- //#define ENDSTOPPULLDOWN_YMAX
- //#define ENDSTOPPULLDOWN_ZMAX
- //#define ENDSTOPPULLDOWN_IMAX
- //#define ENDSTOPPULLDOWN_JMAX
- //#define ENDSTOPPULLDOWN_KMAX
//#define ENDSTOPPULLDOWN_XMIN
//#define ENDSTOPPULLDOWN_YMIN
//#define ENDSTOPPULLDOWN_ZMIN
//#define ENDSTOPPULLDOWN_IMIN
//#define ENDSTOPPULLDOWN_JMIN
//#define ENDSTOPPULLDOWN_KMIN
+ //#define ENDSTOPPULLDOWN_XMAX
+ //#define ENDSTOPPULLDOWN_YMAX
+ //#define ENDSTOPPULLDOWN_ZMAX
+ //#define ENDSTOPPULLDOWN_IMAX
+ //#define ENDSTOPPULLDOWN_JMAX
+ //#define ENDSTOPPULLDOWN_KMAX
//#define ENDSTOPPULLDOWN_ZMIN_PROBE
#endif
@@ -2037,10 +2045,10 @@
*
* Select the language to display on the LCD. These languages are available:
*
- * en, an, bg, ca, cz, da, de, el, el_gr, es, eu, fi, fr, gl, hr, hu, it,
- * jp_kana, ko_KR, nl, pl, pt, pt_br, ro, ru, sk, tr, uk, vi, zh_CN, zh_TW, test
+ * en, an, bg, ca, cz, da, de, el, el_CY, es, eu, fi, fr, gl, hr, hu, it,
+ * jp_kana, ko_KR, nl, pl, pt, pt_br, ro, ru, sk, sv, tr, uk, vi, zh_CN, zh_TW
*
- * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cz':'Czech', 'da':'Danish', 'de':'German', 'el':'Greek', 'el_gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'hu':'Hungarian', 'it':'Italian', 'jp_kana':'Japanese', 'ko_KR':'Korean (South Korea)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt_br':'Portuguese (Brazilian)', 'ro':'Romanian', 'ru':'Russian', 'sk':'Slovak', 'tr':'Turkish', 'uk':'Ukrainian', 'vi':'Vietnamese', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Traditional)', 'test':'TEST' }
+ * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cz':'Czech', 'da':'Danish', 'de':'German', 'el':'Greek (Greece)', 'el_CY':'Greek (Cyprus)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'hu':'Hungarian', 'it':'Italian', 'jp_kana':'Japanese', 'ko_KR':'Korean (South Korea)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt_br':'Portuguese (Brazilian)', 'ro':'Romanian', 'ru':'Russian', 'sk':'Slovak', 'sv':'Swedish', 'tr':'Turkish', 'uk':'Ukrainian', 'vi':'Vietnamese', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Traditional)' }
*/
#define LCD_LANGUAGE en
@@ -2152,6 +2160,7 @@
// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu.
//
//#define INDIVIDUAL_AXIS_HOMING_MENU
+//#define INDIVIDUAL_AXIS_HOMING_SUBMENU
//
// SPEAKER/BUZZER
@@ -2353,6 +2362,11 @@
//#define VIKI2
//#define miniVIKI
+//
+// Alfawise Ex8 printer LCD marked as WYH L12864 COG
+//
+//#define WYH_L12864
+
//
// MakerLab Mini Panel with graphic
// controller and SD support - https://reprap.org/wiki/Mini_panel
@@ -2549,10 +2563,15 @@
// - Download https://github.com/makerbase-mks/MKS-H43
// - Copy the downloaded DWIN_SET folder to the SD card.
//
+// RELOADED (T5UID1)
+// - Download https://github.com/Desuuuu/DGUS-reloaded/releases
+// - Copy the downloaded DWIN_SET folder to the SD card.
+//
//#define DGUS_LCD_UI_ORIGIN
//#define DGUS_LCD_UI_FYSETC
//#define DGUS_LCD_UI_HIPRECY
//#define DGUS_LCD_UI_MKS
+//#define DGUS_LCD_UI_RELOADED
#if ENABLED(DGUS_LCD_UI_MKS)
#define USE_MKS_GREEN_UI
#endif
@@ -2609,32 +2628,32 @@
*/
//
-// 480x320, 3.5", SPI Display From MKS
-// Normally used in MKS Robin Nano V2
+// 480x320, 3.5", SPI Display with Rotary Encoder from MKS
+// Usually paired with MKS Robin Nano V2 & V3
//
//#define MKS_TS35_V2_0
//
// 320x240, 2.4", FSMC Display From MKS
-// Normally used in MKS Robin Nano V1.2
+// Usually paired with MKS Robin Nano V1.2
//
//#define MKS_ROBIN_TFT24
//
// 320x240, 2.8", FSMC Display From MKS
-// Normally used in MKS Robin Nano V1.2
+// Usually paired with MKS Robin Nano V1.2
//
//#define MKS_ROBIN_TFT28
//
// 320x240, 3.2", FSMC Display From MKS
-// Normally used in MKS Robin Nano V1.2
+// Usually paired with MKS Robin Nano V1.2
//
//#define MKS_ROBIN_TFT32
//
// 480x320, 3.5", FSMC Display From MKS
-// Normally used in MKS Robin Nano V1.2
+// Usually paired with MKS Robin Nano V1.2
//
//#define MKS_ROBIN_TFT35
@@ -2645,7 +2664,7 @@
//
// 320x240, 3.2", FSMC Display From MKS
-// Normally used in MKS Robin
+// Usually paired with MKS Robin
//
//#define MKS_ROBIN_TFT_V1_1R
@@ -2675,10 +2694,15 @@
//#define ANET_ET5_TFT35
//
-// 1024x600, 7", RGB Stock Display from BIQU-BX
+// 1024x600, 7", RGB Stock Display with Rotary Encoder from BIQU-BX
//
//#define BIQU_BX_TFT70
+//
+// 480x320, 3.5", SPI Stock Display with Rotary Encoder from BIQU B1 SE Series
+//
+//#define BTT_TFT35_SPI_V1_0
+
//
// Generic TFT with detailed options
//
@@ -2695,6 +2719,7 @@
//#define TFT_RES_320x240
//#define TFT_RES_480x272
//#define TFT_RES_480x320
+ //#define TFT_RES_1024x600
#endif
/**
@@ -2732,13 +2757,11 @@
//
// Ender-3 v2 OEM display. A DWIN display with Rotary Encoder.
//
-//#define DWIN_CREALITY_LCD
-
-//
-// MarlinUI for Creality's DWIN display (and others)
-//
-//#define DWIN_MARLINUI_PORTRAIT
-//#define DWIN_MARLINUI_LANDSCAPE
+//#define DWIN_CREALITY_LCD // Creality UI
+//#define DWIN_CREALITY_LCD_ENHANCED // Enhanced UI
+//#define DWIN_CREALITY_LCD_JYERSUI // Jyers UI by Jacob Myers
+//#define DWIN_MARLINUI_PORTRAIT // MarlinUI (portrait orientation)
+//#define DWIN_MARLINUI_LANDSCAPE // MarlinUI (landscape orientation)
//
// Touch Screen Settings
@@ -2748,6 +2771,8 @@
#define BUTTON_DELAY_EDIT 50 // (ms) Button repeat delay for edit screens
#define BUTTON_DELAY_MENU 250 // (ms) Button repeat delay for menus
+ //#define TOUCH_IDLE_SLEEP 300 // (secs) Turn off the TFT backlight if set (5mn)
+
#define TOUCH_SCREEN_CALIBRATION
//#define TOUCH_CALIBRATION_X 12316
@@ -2898,9 +2923,9 @@
* Set this manually if there are extra servos needing manual control.
* Set to 0 to turn off servo support.
*/
-#define NUM_SERVOS 1 // Servo index starts with 0 for M280 command
+#define NUM_SERVOS 1 // Note: Servo index starts with 0 for M280-M282 commands
-// (ms) Delay before the next move will start, to give the servo time to reach its target angle.
+// (ms) Delay before the next move will start, to give the servo time to reach its target angle.
// 300ms is a good value but you can try less delay.
// If the servo can't reach the requested position, increase it.
#define SERVO_DELAY { 300 }
@@ -2910,3 +2935,6 @@
// Edit servo angles with M281 and save to EEPROM with M500
//#define EDITABLE_SERVO_ANGLES
+
+// Disable servo with M282 to reduce power consumption, noise, and heat when not in use
+//#define SERVO_DETACH_GCODE
diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index a4ee1328759a2..9619dea5ea2bd 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -30,8 +30,7 @@
*
* Basic settings can be found in Configuration.h
*/
-//Modify Date = 8-29-2021
-#define CONFIGURATION_ADV_H_VERSION 02000901
+#define CONFIGURATION_ADV_H_VERSION 02000903
//===========================================================================
//============================= Thermal Settings ============================
@@ -415,7 +414,7 @@
*/
#define AUTOTEMP
#if ENABLED(AUTOTEMP)
- #define AUTOTEMP_OLDWEIGHT 0.98
+ #define AUTOTEMP_OLDWEIGHT 0.98 // Factor used to weight previous readings (0.0 < value < 1.0)
// Turn on AUTOTEMP on M104/M109 by default using proportions set here
#define AUTOTEMP_PROPORTIONAL
#if ENABLED(AUTOTEMP_PROPORTIONAL)
@@ -1200,7 +1199,7 @@
// @section lcd
-#if EITHER(IS_ULTIPANEL, EXTENSIBLE_UI)
+#if ANY(HAS_LCD_MENU, EXTENSIBLE_UI, HAS_DWIN_E3V2)
#define MANUAL_FEEDRATE { 50*60, 50*60, 4*60, 2*60 } // (mm/min) Feedrates for manual moves along X, Y, Z, E from panel
#define FINE_MANUAL_MOVE 0.025 // (mm) Smallest manual move (< 0.1mm) applying to Z on most machines
#if IS_ULTIPANEL
@@ -1310,7 +1309,7 @@
// LCD Print Progress options
#if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY)
- #if ANY(HAS_MARLINUI_U8GLIB, EXTENSIBLE_UI, HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL, IS_DWIN_MARLINUI)
+ #if CAN_SHOW_REMAINING_TIME
//#define SHOW_REMAINING_TIME // Display estimated time to completion
#if ENABLED(SHOW_REMAINING_TIME)
//#define USE_M73_REMAINING_TIME // Use remaining time from M73 command instead of estimation
@@ -1607,7 +1606,7 @@
* Set STATUS_EXPIRE_SECONDS to zero to never clear the status.
* This will prevent position updates from being displayed.
*/
- #if ENABLED(U8GLIB_ST7920)
+ #if IS_U8GLIB_ST7920
// Enable this option and reduce the value to optimize screen updates.
// The normal delay is 10µs. Use the lowest value that still gives a reliable display.
//#define DOGM_SPI_DELAY_US 5
@@ -1924,6 +1923,7 @@
#define LIN_ADVANCE_K 0.16 // Unit: mm compression per 1mm/s extruder speed
//#define LA_DEBUG // If enabled, this will generate debug information output over USB.
#define EXPERIMENTAL_SCURVE // Enable this option to permit S-Curve Acceleration
+ //#define ALLOW_LOW_EJERK // Allow a DEFAULT_EJERK value of <10. Recommended for direct drive hotends.
#endif
// @section leveling
@@ -2004,59 +2004,69 @@
/**
* Thermal Probe Compensation
- * Probe measurements are adjusted to compensate for temperature distortion.
- * Use G76 to calibrate this feature. Use M871 to set values manually.
- * For a more detailed explanation of the process see G76_M871.cpp.
+ *
+ * Adjust probe measurements to compensate for distortion associated with the temperature
+ * of the probe, bed, and/or hotend.
+ * Use G76 to automatically calibrate this feature for probe and bed temperatures.
+ * (Extruder temperature/offset values must be calibrated manually.)
+ * Use M871 to set temperature/offset values manually.
+ * For more details see https://marlinfw.org/docs/features/probe_temp_compensation.html
*/
-#if HAS_BED_PROBE && TEMP_SENSOR_PROBE && TEMP_SENSOR_BED
- // Enable thermal first layer compensation using bed and probe temperatures
- #define PROBE_TEMP_COMPENSATION
+//#define PTC_PROBE // Compensate based on probe temperature
+//#define PTC_BED // Compensate based on bed temperature
+//#define PTC_HOTEND // Compensate based on hotend temperature
+
+#if ANY(PTC_PROBE, PTC_BED, PTC_HOTEND)
+ /**
+ * If the probe is outside the defined range, use linear extrapolation with the closest
+ * point and the point with index PTC_LINEAR_EXTRAPOLATION. e.g., If set to 4 it will use the
+ * linear extrapolation between data[0] and data[4] for values below PTC_PROBE_START.
+ */
+ //#define PTC_LINEAR_EXTRAPOLATION 4
+
+ #if ENABLED(PTC_PROBE)
+ // Probe temperature calibration generates a table of values starting at PTC_PROBE_START
+ // (e.g., 30), in steps of PTC_PROBE_RES (e.g., 5) with PTC_PROBE_COUNT (e.g., 10) samples.
+ #define PTC_PROBE_START 30 // (°C)
+ #define PTC_PROBE_RES 5 // (°C)
+ #define PTC_PROBE_COUNT 10
+ #define PTC_PROBE_ZOFFS { 0 } // (µm) Z adjustments per sample
+ #endif
+
+ #if ENABLED(PTC_BED)
+ // Bed temperature calibration builds a similar table.
+ #define PTC_BED_START 60 // (°C)
+ #define PTC_BED_RES 5 // (°C)
+ #define PTC_BED_COUNT 10
+ #define PTC_BED_ZOFFS { 0 } // (µm) Z adjustments per sample
+ #endif
+
+ #if ENABLED(PTC_HOTEND)
+ // Note: There is no automatic calibration for the hotend. Use M871.
+ #define PTC_HOTEND_START 180 // (°C)
+ #define PTC_HOTEND_RES 5 // (°C)
+ #define PTC_HOTEND_COUNT 20
+ #define PTC_HOTEND_ZOFFS { 0 } // (µm) Z adjustments per sample
+ #endif
- // Add additional compensation depending on hotend temperature
- // Note: this values cannot be calibrated and have to be set manually
- #if ENABLED(PROBE_TEMP_COMPENSATION)
+ // G76 options
+ #if BOTH(PTC_PROBE, PTC_BED)
// Park position to wait for probe cooldown
#define PTC_PARK_POS { 0, 0, 100 }
// Probe position to probe and wait for probe to reach target temperature
+ //#define PTC_PROBE_POS { 12.0f, 7.3f } // Example: MK52 magnetic heatbed
#define PTC_PROBE_POS { 90, 100 }
- // Enable additional compensation using hotend temperature
- // Note: this values cannot be calibrated automatically but have to be set manually
- //#define USE_TEMP_EXT_COMPENSATION
-
- // Probe temperature calibration generates a table of values starting at PTC_SAMPLE_START
- // (e.g., 30), in steps of PTC_SAMPLE_RES (e.g., 5) with PTC_SAMPLE_COUNT (e.g., 10) samples.
-
- //#define PTC_SAMPLE_START 30 // (°C)
- //#define PTC_SAMPLE_RES 5 // (°C)
- //#define PTC_SAMPLE_COUNT 10
-
- // Bed temperature calibration builds a similar table.
-
- //#define BTC_SAMPLE_START 60 // (°C)
- //#define BTC_SAMPLE_RES 5 // (°C)
- //#define BTC_SAMPLE_COUNT 10
-
- // The temperature the probe should be at while taking measurements during bed temperature
- // calibration.
- //#define BTC_PROBE_TEMP 30 // (°C)
+ // The temperature the probe should be at while taking measurements during
+ // bed temperature calibration.
+ #define PTC_PROBE_TEMP 30 // (°C)
// Height above Z=0.0 to raise the nozzle. Lowering this can help the probe to heat faster.
- // Note: the Z=0.0 offset is determined by the probe offset which can be set using M851.
- //#define PTC_PROBE_HEATING_OFFSET 0.5
-
- // Height to raise the Z-probe between heating and taking the next measurement. Some probes
- // may fail to untrigger if they have been triggered for a long time, which can be solved by
- // increasing the height the probe is raised to.
- //#define PTC_PROBE_RAISE 15
-
- // If the probe is outside of the defined range, use linear extrapolation using the closest
- // point and the PTC_LINEAR_EXTRAPOLATION'th next point. E.g. if set to 4 it will use data[0]
- // and data[4] to perform linear extrapolation for values below PTC_SAMPLE_START.
- //#define PTC_LINEAR_EXTRAPOLATION 4
+ // Note: The Z=0.0 offset is determined by the probe Z offset (e.g., as set with M851 Z).
+ #define PTC_PROBE_HEATING_OFFSET 0.5
#endif
-#endif
+#endif // PTC_PROBE || PTC_BED || PTC_HOTEND
// @section extras
@@ -2068,20 +2078,23 @@
//
// G2/G3 Arc Support
//
-#define ARC_SUPPORT // Disable this feature to save ~3226 bytes
+#define ARC_SUPPORT // Requires ~3226 bytes
#if ENABLED(ARC_SUPPORT)
- #define MM_PER_ARC_SEGMENT 1 // (mm) Length (or minimum length) of each arc segment
- //#define ARC_SEGMENTS_PER_R 1 // Max segment length, MM_PER = Min
- #define MIN_ARC_SEGMENTS 24 // Minimum number of segments in a complete circle
- //#define ARC_SEGMENTS_PER_SEC 50 // Use feedrate to choose segment length (with MM_PER_ARC_SEGMENT as the minimum)
- #define N_ARC_CORRECTION 25 // Number of interpolated segments between corrections
- //#define ARC_P_CIRCLES // Enable the 'P' parameter to specify complete circles
- //#define CNC_WORKSPACE_PLANES // Allow G2/G3 to operate in XY, ZX, or YZ planes
- //#define SF_ARC_FIX // Enable only if using SkeinForge with "Arc Point" fillet procedure
+ #define MIN_ARC_SEGMENT_MM 0.1 // (mm) Minimum length of each arc segment
+ #define MAX_ARC_SEGMENT_MM 1.0 // (mm) Maximum length of each arc segment
+ #define MIN_CIRCLE_SEGMENTS 72 // Minimum number of segments in a complete circle
+ //#define ARC_SEGMENTS_PER_SEC 50 // Use the feedrate to choose the segment length
+ #define N_ARC_CORRECTION 25 // Number of interpolated segments between corrections
+ //#define ARC_P_CIRCLES // Enable the 'P' parameter to specify complete circles
+ //#define SF_ARC_FIX // Enable only if using SkeinForge with "Arc Point" fillet procedure
#endif
-// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes.
-//#define BEZIER_CURVE_SUPPORT
+// G5 Bézier Curve Support with XYZE destination and IJPQ offsets
+//#define BEZIER_CURVE_SUPPORT // Requires ~2666 bytes
+
+#if EITHER(ARC_SUPPORT, BEZIER_CURVE_SUPPORT)
+ //#define CNC_WORKSPACE_PLANES // Allow G2/G3/G5 to operate in XY, ZX, or YZ planes
+#endif
/**
* Direct Stepping
@@ -2326,6 +2339,7 @@
*/
//#define EVENT_GCODE_TOOLCHANGE_T0 "G28 A\nG1 A0" // Extra G-code to run while executing tool-change command T0
//#define EVENT_GCODE_TOOLCHANGE_T1 "G1 A10" // Extra G-code to run while executing tool-change command T1
+ //#define EVENT_GCODE_TOOLCHANGE_ALWAYS_RUN // Always execute above G-code sequences. Use with caution!
/**
* Tool Sensors detect when tools have been picked up or dropped.
@@ -2438,6 +2452,8 @@
#define PAUSE_PARK_NOZZLE_TIMEOUT 45 // (seconds) Time limit before the nozzle is turned off for safety.
#define FILAMENT_CHANGE_ALERT_BEEPS 10 // Number of alert beeps to play when a response is needed.
#define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable for XYZ steppers to stay powered on during filament change.
+ //#define FILAMENT_CHANGE_RESUME_ON_INSERT // Automatically continue / load filament when runout sensor is triggered again.
+ //#define PAUSE_REHEAT_FAST_RESUME // Reduce number of waits by not prompting again post-timeout before continuing.
#define PARK_HEAD_ON_PAUSE // Park the nozzle during pause and filament change.
//#define HOME_BEFORE_FILAMENT_CHANGE // If needed, home before parking for filament change
@@ -3333,11 +3349,13 @@
//#define SPINDLE_FEATURE
//#define LASER_FEATURE
#if EITHER(SPINDLE_FEATURE, LASER_FEATURE)
- #define SPINDLE_LASER_ACTIVE_STATE LOW // Set to "HIGH" if the on/off function is active HIGH
- #define SPINDLE_LASER_PWM true // Set to "true" if your controller supports setting the speed/power
- #define SPINDLE_LASER_PWM_INVERT false // Set to "true" if the speed/power goes up when you want it to go slower
+ #define SPINDLE_LASER_ACTIVE_STATE LOW // Set to "HIGH" if SPINDLE_LASER_ENA_PIN is active HIGH
- #define SPINDLE_LASER_FREQUENCY 2500 // (Hz) Spindle/laser frequency (only on supported HALs: AVR and LPC)
+ #define SPINDLE_LASER_USE_PWM // Enable if your controller supports setting the speed/power
+ #if ENABLED(SPINDLE_LASER_USE_PWM)
+ #define SPINDLE_LASER_PWM_INVERT false // Set to "true" if the speed/power goes up when you want it to go slower
+ #define SPINDLE_LASER_FREQUENCY 2500 // (Hz) Spindle/laser frequency (only on supported HALs: AVR and LPC)
+ #endif
//#define AIR_EVACUATION // Cutter Vacuum / Laser Blower motor control with G-codes M10-M11
#if ENABLED(AIR_EVACUATION)
@@ -3393,17 +3411,21 @@
* Speed/Power = (PWMDC / 255 * 100 - SPEED_POWER_INTERCEPT) / SPEED_POWER_SLOPE
* PWMDC = (spdpwr - SPEED_POWER_MIN) / (SPEED_POWER_MAX - SPEED_POWER_MIN) / SPEED_POWER_SLOPE
*/
- #define SPEED_POWER_INTERCEPT 0 // (%) 0-100 i.e., Minimum power percentage
- #define SPEED_POWER_MIN 5000 // (RPM)
- #define SPEED_POWER_MAX 30000 // (RPM) SuperPID router controller 0 - 30,000 RPM
- #define SPEED_POWER_STARTUP 25000 // (RPM) M3/M4 speed/power default (with no arguments)
+ #if ENABLED(SPINDLE_LASER_USE_PWM)
+ #define SPEED_POWER_INTERCEPT 0 // (%) 0-100 i.e., Minimum power percentage
+ #define SPEED_POWER_MIN 5000 // (RPM)
+ #define SPEED_POWER_MAX 30000 // (RPM) SuperPID router controller 0 - 30,000 RPM
+ #define SPEED_POWER_STARTUP 25000 // (RPM) M3/M4 speed/power default (with no arguments)
+ #endif
#else
- #define SPEED_POWER_INTERCEPT 0 // (%) 0-100 i.e., Minimum power percentage
- #define SPEED_POWER_MIN 0 // (%) 0-100
- #define SPEED_POWER_MAX 100 // (%) 0-100
- #define SPEED_POWER_STARTUP 80 // (%) M3/M4 speed/power default (with no arguments)
+ #if ENABLED(SPINDLE_LASER_USE_PWM)
+ #define SPEED_POWER_INTERCEPT 0 // (%) 0-100 i.e., Minimum power percentage
+ #define SPEED_POWER_MIN 0 // (%) 0-100
+ #define SPEED_POWER_MAX 100 // (%) 0-100
+ #define SPEED_POWER_STARTUP 80 // (%) M3/M4 speed/power default (with no arguments)
+ #endif
// Define the minimum and maximum test pulse time values for a laser test fire function
#define LASER_TEST_PULSE_MIN 1 // Used with Laser Control Menu
@@ -3838,7 +3860,8 @@
#if ENABLED(HOST_ACTION_COMMANDS)
//#define HOST_PAUSE_M76
#define HOST_PROMPT_SUPPORT
- //#define HOST_START_MENU_ITEM // Add a menu item that tells the host to start
+ //#define HOST_START_MENU_ITEM // Add a menu item that tells the host to start
+ //#define HOST_SHUTDOWN_MENU_ITEM // Add a menu item that tells the host to shut down
#endif
/**
@@ -4212,3 +4235,6 @@
*/
//#define SOFT_RESET_VIA_SERIAL // 'KILL' and '^X' commands will soft-reset the controller
//#define SOFT_RESET_ON_KILL // Use a digital button to soft-reset the controller after KILL
+
+// Report uncleaned reset reason from register r2 instead of MCUSR. Supported by Optiboot on AVR.
+//#define OPTIBOOT_RESET_REASON
diff --git a/Marlin/Version.h b/Marlin/Version.h
index a9ecab7bbf49d..ce8acbbc3e2c3 100644
--- a/Marlin/Version.h
+++ b/Marlin/Version.h
@@ -41,7 +41,7 @@
* here we define this default string as the date where the latest release
* version was tagged.
*/
-//#define STRING_DISTRIBUTION_DATE "2021-08-29"
+//#define STRING_DISTRIBUTION_DATE "2021-11-07"
/**
* Defines a generic printer name to be output to the LCD after booting Marlin.
diff --git a/Marlin/src/HAL/AVR/HAL.cpp b/Marlin/src/HAL/AVR/HAL.cpp
index 708583b262a62..d7bf2a6f6fbb8 100644
--- a/Marlin/src/HAL/AVR/HAL.cpp
+++ b/Marlin/src/HAL/AVR/HAL.cpp
@@ -35,12 +35,31 @@
// Public Variables
// ------------------------
-//uint8_t MCUSR;
+// Don't initialize/override variable (which would happen in .init4)
+uint8_t reset_reason __attribute__((section(".noinit")));
// ------------------------
// Public functions
// ------------------------
+__attribute__((naked)) // Don't output function pro- and epilogue
+__attribute__((used)) // Output the function, even if "not used"
+__attribute__((section(".init3"))) // Put in an early user definable section
+void HAL_save_reset_reason() {
+ #if ENABLED(OPTIBOOT_RESET_REASON)
+ __asm__ __volatile__(
+ A("STS %0, r2")
+ : "=m"(reset_reason)
+ );
+ #else
+ reset_reason = MCUSR;
+ #endif
+
+ // Clear within 16ms since WDRF bit enables a 16ms watchdog timer -> Boot loop
+ MCUSR = 0;
+ wdt_disable();
+}
+
void HAL_init() {
// Init Servo Pins
#define INIT_SERVO(N) OUT_WRITE(SERVO##N##_PIN, LOW)
diff --git a/Marlin/src/HAL/AVR/HAL.h b/Marlin/src/HAL/AVR/HAL.h
index dc0a4f2074be3..2217f239d64ea 100644
--- a/Marlin/src/HAL/AVR/HAL.h
+++ b/Marlin/src/HAL/AVR/HAL.h
@@ -43,13 +43,13 @@
// Default graphical display delays
//
#if F_CPU >= 20000000
- #define CPU_ST7920_DELAY_1 DELAY_NS(150)
- #define CPU_ST7920_DELAY_2 DELAY_NS( 0)
- #define CPU_ST7920_DELAY_3 DELAY_NS(150)
+ #define CPU_ST7920_DELAY_1 150
+ #define CPU_ST7920_DELAY_2 0
+ #define CPU_ST7920_DELAY_3 150
#elif F_CPU == 16000000
- #define CPU_ST7920_DELAY_1 DELAY_NS(125)
- #define CPU_ST7920_DELAY_2 DELAY_NS( 0)
- #define CPU_ST7920_DELAY_3 DELAY_NS(188)
+ #define CPU_ST7920_DELAY_1 125
+ #define CPU_ST7920_DELAY_2 0
+ #define CPU_ST7920_DELAY_3 188
#endif
#ifndef pgm_read_ptr
@@ -91,7 +91,7 @@ typedef int8_t pin_t;
// Public Variables
// ------------------------
-//extern uint8_t MCUSR;
+extern uint8_t reset_reason;
// Serial ports
#ifdef USBCON
@@ -152,21 +152,19 @@ void HAL_init();
//void _delay_ms(const int delay);
-inline void HAL_clear_reset_source() { MCUSR = 0; }
-inline uint8_t HAL_get_reset_source() { return MCUSR; }
+inline void HAL_clear_reset_source() { }
+inline uint8_t HAL_get_reset_source() { return reset_reason; }
void HAL_reboot();
+#pragma GCC diagnostic push
#if GCC_VERSION <= 50000
- #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
extern "C" int freeMemory();
-#if GCC_VERSION <= 50000
- #pragma GCC diagnostic pop
-#endif
+#pragma GCC diagnostic pop
// ADC
#ifdef DIDR2
@@ -223,7 +221,7 @@ void set_pwm_frequency(const pin_t pin, int f_desired);
/**
* set_pwm_duty
- * Sets the PWM duty cycle of the provided pin to the provided value
+ * Set the PWM duty cycle of the provided pin to the provided value
* Optionally allows inverting the duty cycle [default = false]
* Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
*/
diff --git a/Marlin/src/HAL/AVR/HAL_SPI.cpp b/Marlin/src/HAL/AVR/HAL_SPI.cpp
index 1a1b98b3dd2a0..8784bb07b30e9 100644
--- a/Marlin/src/HAL/AVR/HAL_SPI.cpp
+++ b/Marlin/src/HAL/AVR/HAL_SPI.cpp
@@ -34,7 +34,9 @@
#include "../../inc/MarlinConfig.h"
void spiBegin() {
- OUT_WRITE(SD_SS_PIN, HIGH);
+ #if PIN_EXISTS(SD_SS)
+ OUT_WRITE(SD_SS_PIN, HIGH);
+ #endif
SET_OUTPUT(SD_SCK_PIN);
SET_INPUT(SD_MISO_PIN);
SET_OUTPUT(SD_MOSI_PIN);
@@ -74,7 +76,8 @@ void spiBegin() {
#elif defined(PRR0)
PRR0
#endif
- , PRSPI);
+ , PRSPI
+ );
SPCR = _BV(SPE) | _BV(MSTR) | (spiRate >> 1);
SPSR = spiRate & 1 || spiRate == 6 ? 0 : _BV(SPI2X);
diff --git a/Marlin/src/HAL/AVR/MarlinSPI.h b/Marlin/src/HAL/AVR/MarlinSPI.h
new file mode 100644
index 0000000000000..0c447ba4cb3dc
--- /dev/null
+++ b/Marlin/src/HAL/AVR/MarlinSPI.h
@@ -0,0 +1,26 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include
+
+using MarlinSPI = SPIClass;
diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp
index 238c1124adeb6..2556fa0441212 100644
--- a/Marlin/src/HAL/AVR/fast_pwm.cpp
+++ b/Marlin/src/HAL/AVR/fast_pwm.cpp
@@ -22,11 +22,10 @@
#ifdef __AVR__
#include "../../inc/MarlinConfigPre.h"
+#include "HAL.h"
#if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM
-#include "HAL.h"
-
struct Timer {
volatile uint8_t* TCCRnQ[3]; // max 3 TCCR registers per timer
volatile uint16_t* OCRnQ[3]; // max 3 OCR registers per timer
@@ -153,7 +152,7 @@ Timer get_pwm_timer(const pin_t pin) {
void set_pwm_frequency(const pin_t pin, int f_desired) {
Timer timer = get_pwm_timer(pin);
- if (timer.n == 0) return; // Don't proceed if protected timer or not recognised
+ if (timer.n == 0) return; // Don't proceed if protected timer or not recognized
uint16_t size;
if (timer.n == 2) size = 255; else size = 65535;
@@ -243,40 +242,39 @@ void set_pwm_frequency(const pin_t pin, int f_desired) {
_SET_ICRn(timer.ICRn, res); // Set ICRn value (TOP) = res
}
+#endif // NEEDS_HARDWARE_PWM
+
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
- // If v is 0 or v_size (max), digitalWrite to LOW or HIGH.
- // Note that digitalWrite also disables pwm output for us (sets COM bit to 0)
- if (v == 0)
- digitalWrite(pin, invert);
- else if (v == v_size)
- digitalWrite(pin, !invert);
- else {
- Timer timer = get_pwm_timer(pin);
- if (timer.n == 0) return; // Don't proceed if protected timer or not recognised
- // Set compare output mode to CLEAR -> SET or SET -> CLEAR (if inverted)
- _SET_COMnQ(timer.TCCRnQ, (timer.q
- #ifdef TCCR2
- + (timer.q == 2) // COM20 is on bit 4 of TCCR2, thus requires q + 1 in the macro
- #endif
- ), COM_CLEAR_SET + invert
- );
+ #if NEEDS_HARDWARE_PWM
- uint16_t top;
- if (timer.n == 2) { // if TIMER2
- top = (
- #if ENABLED(USE_OCR2A_AS_TOP)
- *timer.OCRnQ[0] // top = OCR2A
- #else
- 255 // top = 0xFF (max)
- #endif
+ // If v is 0 or v_size (max), digitalWrite to LOW or HIGH.
+ // Note that digitalWrite also disables pwm output for us (sets COM bit to 0)
+ if (v == 0)
+ digitalWrite(pin, invert);
+ else if (v == v_size)
+ digitalWrite(pin, !invert);
+ else {
+ Timer timer = get_pwm_timer(pin);
+ if (timer.n == 0) return; // Don't proceed if protected timer or not recognized
+ // Set compare output mode to CLEAR -> SET or SET -> CLEAR (if inverted)
+ _SET_COMnQ(timer.TCCRnQ, (timer.q
+ #ifdef TCCR2
+ + (timer.q == 2) // COM20 is on bit 4 of TCCR2, thus requires q + 1 in the macro
+ #endif
+ ), COM_CLEAR_SET + invert
);
+
+ uint16_t top = (timer.n == 2) ? TERN(USE_OCR2A_AS_TOP, *timer.OCRnQ[0], 255) : *timer.ICRn;
+ _SET_OCRnQ(timer.OCRnQ, timer.q, (v * top + v_size / 2) / v_size); // Scale 8/16-bit v to top value
}
- else
- top = *timer.ICRn; // top = ICRn
- _SET_OCRnQ(timer.OCRnQ, timer.q, v * float(top) / float(v_size)); // Scale 8/16-bit v to top value
- }
+ #else
+
+ analogWrite(pin, v);
+ UNUSED(v_size);
+ UNUSED(invert);
+
+ #endif
}
-#endif // NEEDS_HARDWARE_PWM
#endif // __AVR__
diff --git a/Marlin/src/HAL/AVR/fastio.cpp b/Marlin/src/HAL/AVR/fastio.cpp
index 70132e71ee54a..8af3ef805efa7 100644
--- a/Marlin/src/HAL/AVR/fastio.cpp
+++ b/Marlin/src/HAL/AVR/fastio.cpp
@@ -267,11 +267,11 @@ uint16_t set_pwm_frequency_hz(const_float_t hz, const float dca, const float dcb
SET_WGM(5, FAST_PWM_ICRn); // Fast PWM with ICR5 as TOP
//SERIAL_ECHOLNPGM("Timer 5 Settings:");
- //SERIAL_ECHOLNPAIR(" Prescaler=", prescaler);
- //SERIAL_ECHOLNPAIR(" TOP=", ICR5);
- //SERIAL_ECHOLNPAIR(" OCR5A=", OCR5A);
- //SERIAL_ECHOLNPAIR(" OCR5B=", OCR5B);
- //SERIAL_ECHOLNPAIR(" OCR5C=", OCR5C);
+ //SERIAL_ECHOLNPGM(" Prescaler=", prescaler);
+ //SERIAL_ECHOLNPGM(" TOP=", ICR5);
+ //SERIAL_ECHOLNPGM(" OCR5A=", OCR5A);
+ //SERIAL_ECHOLNPGM(" OCR5B=", OCR5B);
+ //SERIAL_ECHOLNPGM(" OCR5C=", OCR5C);
}
else {
// Restore the default for Timer 5
diff --git a/Marlin/src/HAL/AVR/inc/SanityCheck.h b/Marlin/src/HAL/AVR/inc/SanityCheck.h
index 51ba247953b45..79809b8f618d1 100644
--- a/Marlin/src/HAL/AVR/inc/SanityCheck.h
+++ b/Marlin/src/HAL/AVR/inc/SanityCheck.h
@@ -35,7 +35,7 @@
/**
* Sanity checks for Spindle / Laser PWM
*/
-#if ENABLED(SPINDLE_LASER_PWM)
+#if ENABLED(SPINDLE_LASER_USE_PWM)
#include "../ServoTimers.h" // Needed to check timer availability (_useTimer3)
#if SPINDLE_LASER_PWM_PIN == 4 || WITHIN(SPINDLE_LASER_PWM_PIN, 11, 13)
#error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by a system interrupt."
@@ -43,7 +43,7 @@
#error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by the servo system."
#endif
#elif defined(SPINDLE_LASER_FREQUENCY)
- #error "SPINDLE_LASER_FREQUENCY requires SPINDLE_LASER_PWM."
+ #error "SPINDLE_LASER_FREQUENCY requires SPINDLE_LASER_USE_PWM."
#endif
/**
diff --git a/Marlin/src/HAL/AVR/pinsDebug.h b/Marlin/src/HAL/AVR/pinsDebug.h
index 6923e1f902f35..fcbb7af3e17e3 100644
--- a/Marlin/src/HAL/AVR/pinsDebug.h
+++ b/Marlin/src/HAL/AVR/pinsDebug.h
@@ -2,6 +2,9 @@
* 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
@@ -235,9 +238,9 @@ static void print_is_also_tied() { SERIAL_ECHOPGM(" is also tied to this pin");
inline void com_print(const uint8_t N, const uint8_t Z) {
const uint8_t *TCCRA = (uint8_t*)TCCR_A(N);
- SERIAL_ECHOPAIR(" COM", AS_CHAR('0' + N));
+ SERIAL_ECHOPGM(" COM", AS_DIGIT(N));
SERIAL_CHAR(Z);
- SERIAL_ECHOPAIR(": ", int((*TCCRA >> (6 - Z * 2)) & 0x03));
+ SERIAL_ECHOPGM(": ", int((*TCCRA >> (6 - Z * 2)) & 0x03));
}
void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N - WGM bit layout
@@ -247,7 +250,7 @@ void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N -
uint8_t WGM = (((*TCCRB & _BV(WGM_2)) >> 1) | (*TCCRA & (_BV(WGM_0) | _BV(WGM_1))));
if (N == 4) WGM |= ((*TCCRB & _BV(WGM_3)) >> 1);
- SERIAL_ECHOPAIR(" TIMER", AS_CHAR(T + '0'));
+ SERIAL_ECHOPGM(" TIMER", AS_DIGIT(T));
SERIAL_CHAR(L);
SERIAL_ECHO_SP(3);
@@ -259,14 +262,14 @@ void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N -
const uint16_t *OCRVAL16 = (uint16_t*)OCR_VAL(T, L - 'A');
PWM_PRINT(*OCRVAL16);
}
- SERIAL_ECHOPAIR(" WGM: ", WGM);
+ SERIAL_ECHOPGM(" WGM: ", WGM);
com_print(T,L);
- SERIAL_ECHOPAIR(" CS: ", (*TCCRB & (_BV(CS_0) | _BV(CS_1) | _BV(CS_2)) ));
- SERIAL_ECHOPAIR(" TCCR", AS_CHAR(T + '0'), "A: ", *TCCRA);
- SERIAL_ECHOPAIR(" TCCR", AS_CHAR(T + '0'), "B: ", *TCCRB);
+ SERIAL_ECHOPGM(" CS: ", (*TCCRB & (_BV(CS_0) | _BV(CS_1) | _BV(CS_2)) ));
+ SERIAL_ECHOPGM(" TCCR", AS_DIGIT(T), "A: ", *TCCRA);
+ SERIAL_ECHOPGM(" TCCR", AS_DIGIT(T), "B: ", *TCCRB);
const uint8_t *TMSK = (uint8_t*)TIMSK(T);
- SERIAL_ECHOPAIR(" TIMSK", AS_CHAR(T + '0'), ": ", *TMSK);
+ SERIAL_ECHOPGM(" TIMSK", AS_DIGIT(T), ": ", *TMSK);
const uint8_t OCIE = L - 'A' + 1;
if (N == 3) { if (WGM == 0 || WGM == 2 || WGM == 4 || WGM == 6) err_is_counter(); }
diff --git a/Marlin/src/HAL/AVR/pinsDebug_Teensyduino.h b/Marlin/src/HAL/AVR/pinsDebug_Teensyduino.h
index 051972a861ad9..582ae79ba7872 100644
--- a/Marlin/src/HAL/AVR/pinsDebug_Teensyduino.h
+++ b/Marlin/src/HAL/AVR/pinsDebug_Teensyduino.h
@@ -2,6 +2,9 @@
* 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
diff --git a/Marlin/src/HAL/AVR/pinsDebug_plus_70.h b/Marlin/src/HAL/AVR/pinsDebug_plus_70.h
index db3fdf1f767bf..d9aa44c3cb15b 100644
--- a/Marlin/src/HAL/AVR/pinsDebug_plus_70.h
+++ b/Marlin/src/HAL/AVR/pinsDebug_plus_70.h
@@ -2,6 +2,9 @@
* 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
diff --git a/Marlin/src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp b/Marlin/src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp
index 9d928e7af3b01..45b54379dba78 100644
--- a/Marlin/src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp
+++ b/Marlin/src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp
@@ -64,8 +64,8 @@
#include
-uint8_t u8g_bitData, u8g_bitNotData, u8g_bitClock, u8g_bitNotClock;
-volatile uint8_t *u8g_outData, *u8g_outClock;
+static uint8_t u8g_bitData, u8g_bitNotData, u8g_bitClock, u8g_bitNotClock;
+static volatile uint8_t *u8g_outData, *u8g_outClock;
static void u8g_com_arduino_init_shift_out(uint8_t dataPin, uint8_t clockPin) {
u8g_outData = portOutputRegister(digitalPinToPort(dataPin));
diff --git a/Marlin/src/HAL/DUE/HAL.h b/Marlin/src/HAL/DUE/HAL.h
index 92e26bcf43626..96ab5d9808ac1 100644
--- a/Marlin/src/HAL/DUE/HAL.h
+++ b/Marlin/src/HAL/DUE/HAL.h
@@ -144,6 +144,11 @@ inline void HAL_adc_init() {}//todo
void HAL_adc_start_conversion(const uint8_t ch);
uint16_t HAL_adc_get_result();
+//
+// PWM
+//
+inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
+
//
// Pin Map
//
@@ -168,16 +173,14 @@ void HAL_init();
//
void _delay_ms(const int delay);
+#pragma GCC diagnostic push
#if GCC_VERSION <= 50000
- #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
-#if GCC_VERSION <= 50000
- #pragma GCC diagnostic pop
-#endif
+#pragma GCC diagnostic pop
#ifdef __cplusplus
extern "C" {
diff --git a/Marlin/src/HAL/DUE/MarlinSPI.h b/Marlin/src/HAL/DUE/MarlinSPI.h
new file mode 100644
index 0000000000000..0c447ba4cb3dc
--- /dev/null
+++ b/Marlin/src/HAL/DUE/MarlinSPI.h
@@ -0,0 +1,26 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include
+
+using MarlinSPI = SPIClass;
diff --git a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp
index fcfcef88beb1f..68f6a5c1a7cbf 100644
--- a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp
+++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp
@@ -20,7 +20,6 @@
*
*/
-
/**
* Based on u8g_com_msp430_hw_spi.c
*
diff --git a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp
index 65bfd4f4e2d4a..8268cf307e083 100644
--- a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp
+++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp
@@ -57,7 +57,7 @@
#include "../../../inc/MarlinConfigPre.h"
-#if ENABLED(U8GLIB_ST7920)
+#if IS_U8GLIB_ST7920
#include "../../../inc/MarlinConfig.h"
#include "../../shared/Delay.h"
@@ -182,5 +182,5 @@ uint8_t u8g_com_HAL_DUE_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_va
}
#endif // LIGHTWEIGHT_UI
-#endif // U8GLIB_ST7920
+#endif // IS_U8GLIB_ST7920
#endif // ARDUINO_ARCH_SAM
diff --git a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp
index 2b13c182d023a..68e3e74a45a0a 100644
--- a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp
+++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp
@@ -57,7 +57,7 @@
#include "../../../inc/MarlinConfigPre.h"
-#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920)
+#if HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920
#include "u8g_com_HAL_DUE_sw_spi_shared.h"
@@ -141,5 +141,5 @@ uint8_t u8g_com_HAL_DUE_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void
return 1;
}
-#endif // HAS_MARLINUI_U8GLIB && !U8GLIB_ST7920
+#endif // HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920
#endif // ARDUINO_ARCH_SAM
diff --git a/Marlin/src/HAL/DUE/eeprom_flash.cpp b/Marlin/src/HAL/DUE/eeprom_flash.cpp
index b4cb9912b24f7..7ce4a84df531c 100644
--- a/Marlin/src/HAL/DUE/eeprom_flash.cpp
+++ b/Marlin/src/HAL/DUE/eeprom_flash.cpp
@@ -200,9 +200,9 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
pageContents[i] = (((uint32_t*)data)[i]) | (~(pageContents[i] ^ ((uint32_t*)data)[i]));
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM PageWrite ", page);
- DEBUG_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash);
- DEBUG_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0));
+ DEBUG_ECHOLNPGM("EEPROM PageWrite ", page);
+ DEBUG_ECHOLNPGM(" in FLASH address ", (uint32_t)addrflash);
+ DEBUG_ECHOLNPGM(" base address ", (uint32_t)getFlashStorage(0));
DEBUG_FLUSH();
// Get the page relative to the start of the EFC controller, and the EFC controller to use
@@ -246,7 +246,7 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
__enable_irq();
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Unlock failure for page ", page);
+ DEBUG_ECHOLNPGM("EEPROM Unlock failure for page ", page);
return false;
}
@@ -271,7 +271,7 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
__enable_irq();
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Write failure for page ", page);
+ DEBUG_ECHOLNPGM("EEPROM Write failure for page ", page);
return false;
}
@@ -287,7 +287,7 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
#ifdef EE_EMU_DEBUG
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Verify Write failure for page ", page);
+ DEBUG_ECHOLNPGM("EEPROM Verify Write failure for page ", page);
ee_Dump( page, (uint32_t *)addrflash);
ee_Dump(-page, data);
@@ -306,7 +306,7 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
}
}
}
- DEBUG_ECHOLNPAIR("--> Differing bits: ", count);
+ DEBUG_ECHOLNPGM("--> Differing bits: ", count);
#endif
return false;
@@ -326,9 +326,9 @@ static bool ee_PageErase(uint16_t page) {
uint32_t addrflash = uint32_t(getFlashStorage(page));
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM PageErase ", page);
- DEBUG_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash);
- DEBUG_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0));
+ DEBUG_ECHOLNPGM("EEPROM PageErase ", page);
+ DEBUG_ECHOLNPGM(" in FLASH address ", (uint32_t)addrflash);
+ DEBUG_ECHOLNPGM(" base address ", (uint32_t)getFlashStorage(0));
DEBUG_FLUSH();
// Get the page relative to the start of the EFC controller, and the EFC controller to use
@@ -371,7 +371,7 @@ static bool ee_PageErase(uint16_t page) {
__enable_irq();
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Unlock failure for page ",page);
+ DEBUG_ECHOLNPGM("EEPROM Unlock failure for page ",page);
return false;
}
@@ -395,7 +395,7 @@ static bool ee_PageErase(uint16_t page) {
__enable_irq();
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Erase failure for page ",page);
+ DEBUG_ECHOLNPGM("EEPROM Erase failure for page ",page);
return false;
}
@@ -411,7 +411,7 @@ static bool ee_PageErase(uint16_t page) {
for (i = 0; i < PageSize >> 2; i++) {
if (*aligned_src++ != 0xFFFFFFFF) {
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Verify Erase failure for page ",page);
+ DEBUG_ECHOLNPGM("EEPROM Verify Erase failure for page ",page);
ee_Dump(page, (uint32_t *)addrflash);
return false;
}
@@ -922,7 +922,7 @@ static void ee_Init() {
if (curGroup >= GroupCount) curGroup = 0;
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Current Group: ",curGroup);
+ DEBUG_ECHOLNPGM("EEPROM Current Group: ",curGroup);
DEBUG_FLUSH();
// Now, validate that all the other group pages are empty
@@ -932,7 +932,7 @@ static void ee_Init() {
for (int page = 0; page < PagesPerGroup; page++) {
if (!ee_IsPageClean(grp * PagesPerGroup + page)) {
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Page ", page, " not clean on group ", grp);
+ DEBUG_ECHOLNPGM("EEPROM Page ", page, " not clean on group ", grp);
DEBUG_FLUSH();
ee_PageErase(grp * PagesPerGroup + page);
}
@@ -949,14 +949,14 @@ static void ee_Init() {
}
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Active page: ", curPage);
+ DEBUG_ECHOLNPGM("EEPROM Active page: ", curPage);
DEBUG_FLUSH();
// Make sure the pages following the first clean one are also clean
for (int page = curPage + 1; page < PagesPerGroup; page++) {
if (!ee_IsPageClean(curGroup * PagesPerGroup + page)) {
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Page ", page, " not clean on active group ", curGroup);
+ DEBUG_ECHOLNPGM("EEPROM Page ", page, " not clean on active group ", curGroup);
DEBUG_FLUSH();
ee_Dump(curGroup * PagesPerGroup + page, getFlashStorage(curGroup * PagesPerGroup + page));
ee_PageErase(curGroup * PagesPerGroup + page);
diff --git a/Marlin/src/HAL/DUE/pinsDebug.h b/Marlin/src/HAL/DUE/pinsDebug.h
index 02a5e6646f38a..f01c53c8ce067 100644
--- a/Marlin/src/HAL/DUE/pinsDebug.h
+++ b/Marlin/src/HAL/DUE/pinsDebug.h
@@ -2,6 +2,9 @@
* 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
@@ -87,7 +90,7 @@ bool GET_PINMODE(int8_t pin) { // 1: output, 0: input
void pwm_details(int32_t pin) {
if (pwm_status(pin)) {
uint32_t chan = g_APinDescription[pin].ulPWMChannel;
- SERIAL_ECHOPAIR("PWM = ", PWM_INTERFACE->PWM_CH_NUM[chan].PWM_CDTY);
+ SERIAL_ECHOPGM("PWM = ", PWM_INTERFACE->PWM_CH_NUM[chan].PWM_CDTY);
}
}
diff --git a/Marlin/src/HAL/DUE/upload_extra_script.py b/Marlin/src/HAL/DUE/upload_extra_script.py
index d52a0a3642b45..4f7a494512b2e 100644
--- a/Marlin/src/HAL/DUE/upload_extra_script.py
+++ b/Marlin/src/HAL/DUE/upload_extra_script.py
@@ -4,15 +4,16 @@
# Windows: bossac.exe
# Other: leave unchanged
#
+import pioutil
+if pioutil.is_pio_build():
+ import platform
+ current_OS = platform.system()
-import platform
-current_OS = platform.system()
+ if current_OS == 'Windows':
-if current_OS == 'Windows':
+ Import("env")
- Import("env")
-
- # Use bossac.exe on Windows
- env.Replace(
- UPLOADCMD="bossac --info --unlock --write --verify --reset --erase -U false --boot $SOURCE"
- )
+ # Use bossac.exe on Windows
+ env.Replace(
+ UPLOADCMD="bossac --info --unlock --write --verify --reset --erase -U false --boot $SOURCE"
+ )
diff --git a/Marlin/src/HAL/ESP32/HAL.cpp b/Marlin/src/HAL/ESP32/HAL.cpp
index 7818dbdd87ea2..6a66d519b33cd 100644
--- a/Marlin/src/HAL/ESP32/HAL.cpp
+++ b/Marlin/src/HAL/ESP32/HAL.cpp
@@ -28,6 +28,10 @@
#include
#include
+#if ENABLED(USE_ESP32_TASK_WDT)
+ #include
+#endif
+
#if ENABLED(WIFISUPPORT)
#include
#include "wifi.h"
@@ -90,8 +94,24 @@ volatile int numPWMUsed = 0,
#endif
-void HAL_init_board() {
+#if ENABLED(USE_ESP32_EXIO)
+ HardwareSerial YSerial2(2);
+
+ void Write_EXIO(uint8_t IO, uint8_t v) {
+ if (ISRS_ENABLED()) {
+ DISABLE_ISRS();
+ YSerial2.write(0x80 | (((char)v) << 5) | (IO - 100));
+ ENABLE_ISRS();
+ }
+ else
+ YSerial2.write(0x80 | (((char)v) << 5) | (IO - 100));
+ }
+#endif
+void HAL_init_board() {
+ #if ENABLED(USE_ESP32_TASK_WDT)
+ esp_task_wdt_init(10, true);
+ #endif
#if ENABLED(ESP3D_WIFISUPPORT)
esp3dlib.init();
#elif ENABLED(WIFISUPPORT)
@@ -127,7 +147,11 @@ void HAL_init_board() {
// Initialize the i2s peripheral only if the I2S stepper stream is enabled.
// The following initialization is performed after Serial1 and Serial2 are defined as
// their native pins might conflict with the i2s stream even when they are remapped.
- TERN_(I2S_STEPPER_STREAM, i2s_init());
+ #if ENABLED(USE_ESP32_EXIO)
+ YSerial2.begin(460800 * 3, SERIAL_8N1, 16, 17);
+ #elif ENABLED(I2S_STEPPER_STREAM)
+ i2s_init();
+ #endif
}
void HAL_idletask() {
diff --git a/Marlin/src/HAL/ESP32/HAL.h b/Marlin/src/HAL/ESP32/HAL.h
index 0f920520306f8..8473e3c4e4693 100644
--- a/Marlin/src/HAL/ESP32/HAL.h
+++ b/Marlin/src/HAL/ESP32/HAL.h
@@ -105,16 +105,14 @@ void HAL_reboot();
void _delay_ms(int delay);
+#pragma GCC diagnostic push
#if GCC_VERSION <= 50000
- #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
-#if GCC_VERSION <= 50000
- #pragma GCC diagnostic pop
-#endif
+#pragma GCC diagnostic pop
void analogWrite(pin_t pin, int value);
@@ -131,6 +129,10 @@ void HAL_adc_init();
void HAL_adc_start_conversion(const uint8_t adc_pin);
+// PWM
+inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
+
+// Pin Map
#define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
@@ -142,6 +144,10 @@ void HAL_idletask();
inline void HAL_init() {}
void HAL_init_board();
+#if ENABLED(USE_ESP32_EXIO)
+ void Write_EXIO(uint8_t IO, uint8_t v);
+#endif
+
//
// Delay in cycles (used by DELAY_NS / DELAY_US)
//
diff --git a/Marlin/src/HAL/ESP32/HAL_SPI.cpp b/Marlin/src/HAL/ESP32/HAL_SPI.cpp
index 8743ac5be215a..868ab1b6712da 100644
--- a/Marlin/src/HAL/ESP32/HAL_SPI.cpp
+++ b/Marlin/src/HAL/ESP32/HAL_SPI.cpp
@@ -53,11 +53,9 @@ static SPISettings spiConfig;
// ------------------------
void spiBegin() {
- #if !PIN_EXISTS(SD_SS)
- #error "SD_SS_PIN not defined!"
+ #if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_SS)
+ OUT_WRITE(SD_SS_PIN, HIGH);
#endif
-
- OUT_WRITE(SD_SS_PIN, HIGH);
}
void spiInit(uint8_t spiRate) {
diff --git a/Marlin/src/HAL/ESP32/MarlinSPI.h b/Marlin/src/HAL/ESP32/MarlinSPI.h
new file mode 100644
index 0000000000000..0c447ba4cb3dc
--- /dev/null
+++ b/Marlin/src/HAL/ESP32/MarlinSPI.h
@@ -0,0 +1,26 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include
+
+using MarlinSPI = SPIClass;
diff --git a/Marlin/src/HAL/ESP32/esp32.csv b/Marlin/src/HAL/ESP32/esp32.csv
new file mode 100644
index 0000000000000..8f6e101f02eae
--- /dev/null
+++ b/Marlin/src/HAL/ESP32/esp32.csv
@@ -0,0 +1,6 @@
+# Name, Type, SubType, Offset, Size, Flags
+nvs, data, nvs, 0x9000, 0x5000,
+otadata, data, ota, 0xe000, 0x2000,
+app0, app, ota_0, 0x10000, 0x180000,
+app1, app, ota_1, 0x190000, 0x180000,
+spiffs, data, spiffs, 0x310000, 0xF0000,
diff --git a/Marlin/src/HAL/ESP32/fastio.h b/Marlin/src/HAL/ESP32/fastio.h
index 8db89dca12a1c..c8e3f7e343e97 100644
--- a/Marlin/src/HAL/ESP32/fastio.h
+++ b/Marlin/src/HAL/ESP32/fastio.h
@@ -40,13 +40,19 @@
// Set pin as input with pullup mode
#define _PULLUP(IO, v) pinMode(IO, v ? INPUT_PULLUP : INPUT)
-// Read a pin wrapper
-#define READ(IO) (IS_I2S_EXPANDER_PIN(IO) ? i2s_state(I2S_EXPANDER_PIN_INDEX(IO)) : digitalRead(IO))
-
-// Write to a pin wrapper
-#define WRITE(IO, v) (IS_I2S_EXPANDER_PIN(IO) ? i2s_write(I2S_EXPANDER_PIN_INDEX(IO), v) : digitalWrite(IO, v))
-
-// Set pin as input wrapper
+#if ENABLED(USE_ESP32_EXIO)
+ // Read a pin wrapper
+ #define READ(IO) digitalRead(IO)
+ // Write to a pin wrapper
+ #define WRITE(IO, v) (IO >= 100 ? Write_EXIO(IO, v) : digitalWrite(IO, v))
+#else
+ // Read a pin wrapper
+ #define READ(IO) (IS_I2S_EXPANDER_PIN(IO) ? i2s_state(I2S_EXPANDER_PIN_INDEX(IO)) : digitalRead(IO))
+ // Write to a pin wrapper
+ #define WRITE(IO, v) (IS_I2S_EXPANDER_PIN(IO) ? i2s_write(I2S_EXPANDER_PIN_INDEX(IO), v) : digitalWrite(IO, v))
+#endif
+
+// Set pin as input wrapper (0x80 | (v << 5) | (IO - 100))
#define SET_INPUT(IO) _SET_INPUT(IO)
// Set pin as input with pullup wrapper
diff --git a/Marlin/src/HAL/ESP32/i2s.cpp b/Marlin/src/HAL/ESP32/i2s.cpp
index c28c008793903..3e77b658360bd 100644
--- a/Marlin/src/HAL/ESP32/i2s.cpp
+++ b/Marlin/src/HAL/ESP32/i2s.cpp
@@ -23,6 +23,8 @@
#include "../../inc/MarlinConfigPre.h"
+#if DISABLED(USE_ESP32_EXIO)
+
#include "i2s.h"
#include "../shared/Marduino.h"
@@ -62,12 +64,9 @@ uint32_t i2s_port_data = 0;
#define I2S_EXIT_CRITICAL() portEXIT_CRITICAL(&i2s_spinlock[i2s_num])
static inline void gpio_matrix_out_check(uint32_t gpio, uint32_t signal_idx, bool out_inv, bool oen_inv) {
- //if pin = -1, do not need to configure
- if (gpio != -1) {
- PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO);
- gpio_set_direction((gpio_num_t)gpio, (gpio_mode_t)GPIO_MODE_DEF_OUTPUT);
- gpio_matrix_out(gpio, signal_idx, out_inv, oen_inv);
- }
+ PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO);
+ gpio_set_direction((gpio_num_t)gpio, (gpio_mode_t)GPIO_MODE_DEF_OUTPUT);
+ gpio_matrix_out(gpio, signal_idx, out_inv, oen_inv);
}
static esp_err_t i2s_reset_fifo(i2s_port_t i2s_num) {
@@ -254,13 +253,7 @@ int i2s_init() {
I2S0.fifo_conf.dscr_en = 0;
- I2S0.conf_chan.tx_chan_mod = (
- #if ENABLED(I2S_STEPPER_SPLIT_STREAM)
- 4
- #else
- 0
- #endif
- );
+ I2S0.conf_chan.tx_chan_mod = TERN(I2S_STEPPER_SPLIT_STREAM, 4, 0);
I2S0.fifo_conf.tx_fifo_mod = 0;
I2S0.conf.tx_mono = 0;
@@ -311,9 +304,16 @@ int i2s_init() {
xTaskCreatePinnedToCore(stepperTask, "StepperTask", 10000, nullptr, 1, nullptr, CONFIG_ARDUINO_RUNNING_CORE); // run I2S stepper task on same core as rest of Marlin
// Route the i2s pins to the appropriate GPIO
- gpio_matrix_out_check(I2S_DATA, I2S0O_DATA_OUT23_IDX, 0, 0);
- gpio_matrix_out_check(I2S_BCK, I2S0O_BCK_OUT_IDX, 0, 0);
- gpio_matrix_out_check(I2S_WS, I2S0O_WS_OUT_IDX, 0, 0);
+ // If a pin is not defined, no need to configure
+ #if defined(I2S_DATA) && I2S_DATA >= 0
+ gpio_matrix_out_check(I2S_DATA, I2S0O_DATA_OUT23_IDX, 0, 0);
+ #endif
+ #if defined(I2S_BCK) && I2S_BCK >= 0
+ gpio_matrix_out_check(I2S_BCK, I2S0O_BCK_OUT_IDX, 0, 0);
+ #endif
+ #if defined(I2S_WS) && I2S_WS >= 0
+ gpio_matrix_out_check(I2S_WS, I2S0O_WS_OUT_IDX, 0, 0);
+ #endif
// Start the I2S peripheral
return i2s_start(I2S_NUM_0);
@@ -340,4 +340,5 @@ void i2s_push_sample() {
dma.current[dma.rw_pos++] = i2s_port_data;
}
+#endif // !USE_ESP32_EXIO
#endif // ARDUINO_ARCH_ESP32
diff --git a/Marlin/src/HAL/ESP32/spi_pins.h b/Marlin/src/HAL/ESP32/spi_pins.h
index cfe71eee4a758..58881f0ea7ec9 100644
--- a/Marlin/src/HAL/ESP32/spi_pins.h
+++ b/Marlin/src/HAL/ESP32/spi_pins.h
@@ -2,6 +2,9 @@
* 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
diff --git a/Marlin/src/HAL/ESP32/watchdog.h b/Marlin/src/HAL/ESP32/watchdog.h
index b6c169e347426..43db8130763f5 100644
--- a/Marlin/src/HAL/ESP32/watchdog.h
+++ b/Marlin/src/HAL/ESP32/watchdog.h
@@ -25,7 +25,7 @@
extern "C" {
#endif
- esp_err_t esp_task_wdt_reset();
+ esp_err_t esp_task_wdt_reset();
#ifdef __cplusplus
}
diff --git a/Marlin/src/HAL/ESP32/wifi.cpp b/Marlin/src/HAL/ESP32/wifi.cpp
index f4cf5a606a031..060f3bdb4874e 100644
--- a/Marlin/src/HAL/ESP32/wifi.cpp
+++ b/Marlin/src/HAL/ESP32/wifi.cpp
@@ -59,7 +59,7 @@ void wifi_init() {
MDNS.addService("http", "tcp", 80);
- SERIAL_ECHOLNPAIR("Successfully connected to WiFi with SSID '" WIFI_SSID "', hostname: '" WIFI_HOSTNAME "', IP address: ", WiFi.localIP().toString().c_str());
+ SERIAL_ECHOLNPGM("Successfully connected to WiFi with SSID '" WIFI_SSID "', hostname: '" WIFI_HOSTNAME "', IP address: ", WiFi.localIP().toString().c_str());
}
#endif // WIFISUPPORT
diff --git a/Marlin/src/HAL/LINUX/HAL.h b/Marlin/src/HAL/LINUX/HAL.h
index 07ab85a9a0908..d7d3a92b73b95 100644
--- a/Marlin/src/HAL/LINUX/HAL.h
+++ b/Marlin/src/HAL/LINUX/HAL.h
@@ -63,9 +63,9 @@ uint8_t _getc();
extern MSerialT usb_serial;
#define MYSERIAL1 usb_serial
-#define CPU_ST7920_DELAY_1 DELAY_NS(600)
-#define CPU_ST7920_DELAY_2 DELAY_NS(750)
-#define CPU_ST7920_DELAY_3 DELAY_NS(750)
+#define CPU_ST7920_DELAY_1 600
+#define CPU_ST7920_DELAY_2 750
+#define CPU_ST7920_DELAY_3 750
//
// Interrupts
@@ -79,16 +79,14 @@ extern MSerialT usb_serial;
inline void HAL_init() {}
// Utility functions
+#pragma GCC diagnostic push
#if GCC_VERSION <= 50000
- #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
-#if GCC_VERSION <= 50000
- #pragma GCC diagnostic pop
-#endif
+#pragma GCC diagnostic pop
// ADC
#define HAL_ADC_VREF 5.0
@@ -103,6 +101,9 @@ void HAL_adc_enable_channel(const uint8_t ch);
void HAL_adc_start_conversion(const uint8_t ch);
uint16_t HAL_adc_get_result();
+// PWM
+inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
+
// Reset source
inline void HAL_clear_reset_source(void) {}
inline uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; }
diff --git a/Marlin/src/HAL/LINUX/MarlinSPI.h b/Marlin/src/HAL/LINUX/MarlinSPI.h
new file mode 100644
index 0000000000000..0c447ba4cb3dc
--- /dev/null
+++ b/Marlin/src/HAL/LINUX/MarlinSPI.h
@@ -0,0 +1,26 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include
+
+using MarlinSPI = SPIClass;
diff --git a/Marlin/src/HAL/LINUX/inc/SanityCheck.h b/Marlin/src/HAL/LINUX/inc/SanityCheck.h
index 45bb2662ace59..36d3190a3e086 100644
--- a/Marlin/src/HAL/LINUX/inc/SanityCheck.h
+++ b/Marlin/src/HAL/LINUX/inc/SanityCheck.h
@@ -26,7 +26,7 @@
*/
// Emulating RAMPS
-#if ENABLED(SPINDLE_LASER_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11)
+#if ENABLED(SPINDLE_LASER_USE_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11)
#error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector"
#endif
diff --git a/Marlin/src/HAL/LINUX/main.cpp b/Marlin/src/HAL/LINUX/main.cpp
index 31f6de98ee8ee..f2af2ff33f528 100644
--- a/Marlin/src/HAL/LINUX/main.cpp
+++ b/Marlin/src/HAL/LINUX/main.cpp
@@ -2,6 +2,9 @@
* 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
@@ -16,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#ifdef __PLAT_LINUX__
//#define GPIO_LOGGING // Full GPIO and Positional Logging
diff --git a/Marlin/src/HAL/LINUX/pinsDebug.h b/Marlin/src/HAL/LINUX/pinsDebug.h
index 9803c5d362e1e..7bfd97d024f73 100644
--- a/Marlin/src/HAL/LINUX/pinsDebug.h
+++ b/Marlin/src/HAL/LINUX/pinsDebug.h
@@ -2,6 +2,9 @@
* 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
diff --git a/Marlin/src/HAL/LPC1768/HAL.h b/Marlin/src/HAL/LPC1768/HAL.h
index f0a1185ff2460..348ea6b21a040 100644
--- a/Marlin/src/HAL/LPC1768/HAL.h
+++ b/Marlin/src/HAL/LPC1768/HAL.h
@@ -50,9 +50,9 @@ extern "C" volatile uint32_t _millis;
//
// Default graphical display delays
//
-#define CPU_ST7920_DELAY_1 DELAY_NS(600)
-#define CPU_ST7920_DELAY_2 DELAY_NS(750)
-#define CPU_ST7920_DELAY_3 DELAY_NS(750)
+#define CPU_ST7920_DELAY_1 600
+#define CPU_ST7920_DELAY_2 750
+#define CPU_ST7920_DELAY_3 750
typedef ForwardSerial1Class< decltype(UsbSerial) > DefaultSerial1;
extern DefaultSerial1 USBSerial;
@@ -107,7 +107,7 @@ extern DefaultSerial1 USBSerial;
#error "LCD_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#if HAS_DGUS_LCD
- #define SERIAL_GET_TX_BUFFER_FREE() MSerial0.available()
+ #define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.available()
#endif
#endif
@@ -123,16 +123,14 @@ extern DefaultSerial1 USBSerial;
//
// Utility functions
//
+#pragma GCC diagnostic push
#if GCC_VERSION <= 50000
- #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
-#if GCC_VERSION <= 50000
- #pragma GCC diagnostic pop
-#endif
+#pragma GCC diagnostic pop
//
// ADC API
@@ -156,17 +154,17 @@ int freeMemory();
using FilteredADC = LPC176x::ADC;
extern uint32_t HAL_adc_reading;
-[[gnu::always_inline]] inline void HAL_start_adc(const pin_t pin) {
+[[gnu::always_inline]] inline void HAL_adc_start_conversion(const pin_t pin) {
HAL_adc_reading = FilteredADC::read(pin) >> (16 - HAL_ADC_RESOLUTION); // returns 16bit value, reduce to required bits
}
-[[gnu::always_inline]] inline uint16_t HAL_read_adc() {
+[[gnu::always_inline]] inline uint16_t HAL_adc_get_result() {
return HAL_adc_reading;
}
#define HAL_adc_init()
#define HAL_ANALOG_SELECT(pin) FilteredADC::enable_channel(pin)
-#define HAL_START_ADC(pin) HAL_start_adc(pin)
-#define HAL_READ_ADC() HAL_read_adc()
+#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
+#define HAL_READ_ADC() HAL_adc_get_result()
#define HAL_ADC_READY() (true)
// Test whether the pin is valid
diff --git a/Marlin/src/HAL/LPC1768/MarlinSerial.h b/Marlin/src/HAL/LPC1768/MarlinSerial.h
index 808d19f8c52a7..3e6848a1e3d03 100644
--- a/Marlin/src/HAL/LPC1768/MarlinSerial.h
+++ b/Marlin/src/HAL/LPC1768/MarlinSerial.h
@@ -46,6 +46,8 @@ class MarlinSerial : public HardwareSerial {
void end() {}
+ uint8_t availableForWrite(void) { /* flushTX(); */ return TX_BUFFER_SIZE; }
+
#if ENABLED(EMERGENCY_PARSER)
bool recv_callback(const char c) override;
#endif
diff --git a/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp b/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp
index 70395251df25b..1991d79719599 100644
--- a/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp
+++ b/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp
@@ -1,10 +1,9 @@
/**
* Marlin 3D Printer Firmware
- *
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
- * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
- * Copyright (c) 2016 Victor Perez victor_pv@hotmail.com
+ *
+ * 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
@@ -20,12 +19,19 @@
* along with this program. If not, see .
*
*/
+
+/**
+ * Implementation of EEPROM settings in SD Card
+ */
+
#ifdef TARGET_LPC1768
#include "../../inc/MarlinConfig.h"
#if ENABLED(SDCARD_EEPROM_EMULATION)
+//#define DEBUG_SD_EEPROM_EMULATION
+
#include "../shared/eeprom_api.h"
#include
@@ -38,9 +44,11 @@ FATFS fat_fs;
FIL eeprom_file;
bool eeprom_file_open = false;
+#define EEPROM_FILENAME "eeprom.dat"
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE size_t(0x1000) // 4KiB of Emulated EEPROM
#endif
+
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
bool PersistentStore::access_start() {
@@ -50,7 +58,7 @@ bool PersistentStore::access_start() {
MSC_Release_Lock();
return false;
}
- FRESULT res = f_open(&eeprom_file, "eeprom.dat", FA_OPEN_ALWAYS | FA_WRITE | FA_READ);
+ FRESULT res = f_open(&eeprom_file, EEPROM_FILENAME, FA_OPEN_ALWAYS | FA_WRITE | FA_READ);
if (res) MSC_Release_Lock();
if (res == FR_OK) {
@@ -81,18 +89,20 @@ bool PersistentStore::access_finish() {
// This extra chit-chat goes away soon, but is helpful for now
// to see errors that are happening in read_data / write_data
static void debug_rw(const bool write, int &pos, const uint8_t *value, const size_t size, const FRESULT s, const size_t total=0) {
- PGM_P const rw_str = write ? PSTR("write") : PSTR("read");
- SERIAL_CHAR(' ');
- SERIAL_ECHOPGM_P(rw_str);
- SERIAL_ECHOLNPAIR("_data(", pos, ",", value, ",", size, ", ...)");
- if (total) {
- SERIAL_ECHOPGM(" f_");
- SERIAL_ECHOPGM_P(rw_str);
- SERIAL_ECHOPAIR("()=", s, "\n size=", size, "\n bytes_");
- SERIAL_ECHOLNPAIR_P(write ? PSTR("written=") : PSTR("read="), total);
- }
- else
- SERIAL_ECHOLNPAIR(" f_lseek()=", s);
+ #if ENABLED(DEBUG_SD_EEPROM_EMULATION)
+ FSTR_P const rw_str = write ? F("write") : F("read");
+ SERIAL_CHAR(' ');
+ SERIAL_ECHOF(rw_str);
+ SERIAL_ECHOLNPGM("_data(", pos, ",", *value, ",", size, ", ...)");
+ if (total) {
+ SERIAL_ECHOPGM(" f_");
+ SERIAL_ECHOF(rw_str);
+ SERIAL_ECHOPGM("()=", s, "\n size=", size, "\n bytes_");
+ SERIAL_ECHOLNF(write ? F("written=") : F("read="), total);
+ }
+ else
+ SERIAL_ECHOLNPGM(" f_lseek()=", s);
+ #endif
}
// File function return codes for type FRESULT. This goes away soon, but
diff --git a/Marlin/src/HAL/LPC1768/fast_pwm.cpp b/Marlin/src/HAL/LPC1768/fast_pwm.cpp
index dd440b5e77307..70fc0e333d115 100644
--- a/Marlin/src/HAL/LPC1768/fast_pwm.cpp
+++ b/Marlin/src/HAL/LPC1768/fast_pwm.cpp
@@ -22,18 +22,18 @@
#ifdef TARGET_LPC1768
#include "../../inc/MarlinConfigPre.h"
-
-#if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM
-
#include
-void set_pwm_frequency(const pin_t pin, int f_desired) {
- LPC176x::pwm_set_frequency(pin, f_desired);
-}
-
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
LPC176x::pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size);
}
-#endif // NEEDS_HARDWARE_PWM
+#if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM
+
+ void set_pwm_frequency(const pin_t pin, int f_desired) {
+ LPC176x::pwm_set_frequency(pin, f_desired);
+ }
+
+#endif
+
#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/LPC1768/inc/SanityCheck.h b/Marlin/src/HAL/LPC1768/inc/SanityCheck.h
index 23d797b2ab76c..3ea054589ec35 100644
--- a/Marlin/src/HAL/LPC1768/inc/SanityCheck.h
+++ b/Marlin/src/HAL/LPC1768/inc/SanityCheck.h
@@ -67,7 +67,7 @@ static_assert(!(NUM_SERVOS && ENABLED(FAST_PWM_FAN)), "BLTOUCH and Servos are in
* Test LPC176x-specific configuration values for errors at compile-time.
*/
-//#if ENABLED(SPINDLE_LASER_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11)
+//#if ENABLED(SPINDLE_LASER_USE_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11)
// #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector"
//#endif
diff --git a/Marlin/src/HAL/LPC1768/pinsDebug.h b/Marlin/src/HAL/LPC1768/pinsDebug.h
index c622a2622ed15..a2f5c123a260a 100644
--- a/Marlin/src/HAL/LPC1768/pinsDebug.h
+++ b/Marlin/src/HAL/LPC1768/pinsDebug.h
@@ -2,6 +2,9 @@
* 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
@@ -35,7 +38,7 @@
#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0)
#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("P%d_%02d"), LPC176x::pin_port(p), LPC176x::pin_bit(p)); SERIAL_ECHO(buffer); }while(0)
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR("_A%d "), LPC176x::pin_get_adc_channel(pin)); SERIAL_ECHO(buffer); }while(0)
-#define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin
+#define MULTI_NAME_PAD 17 // space needed to be pretty if not first name assigned to a pin
// pins that will cause hang/reset/disconnect in M43 Toggle and Watch utilities
#ifndef M43_NEVER_TOUCH
diff --git a/Marlin/src/HAL/LPC1768/tft/tft_spi.cpp b/Marlin/src/HAL/LPC1768/tft/tft_spi.cpp
index a2cb66ab5bfd8..a9847b2d2fa0e 100644
--- a/Marlin/src/HAL/LPC1768/tft/tft_spi.cpp
+++ b/Marlin/src/HAL/LPC1768/tft/tft_spi.cpp
@@ -26,39 +26,22 @@
#include "tft_spi.h"
-//TFT_SPI tft;
-
SPIClass TFT_SPI::SPIx(1);
-#define TFT_CS_H WRITE(TFT_CS_PIN, HIGH)
-#define TFT_CS_L WRITE(TFT_CS_PIN, LOW)
-
-#define TFT_DC_H WRITE(TFT_DC_PIN, HIGH)
-#define TFT_DC_L WRITE(TFT_DC_PIN, LOW)
-
-#define TFT_RST_H WRITE(TFT_RESET_PIN, HIGH)
-#define TFT_RST_L WRITE(TFT_RESET_PIN, LOW)
-
-#define TFT_BLK_H WRITE(TFT_BACKLIGHT_PIN, HIGH)
-#define TFT_BLK_L WRITE(TFT_BACKLIGHT_PIN, LOW)
-
void TFT_SPI::Init() {
#if PIN_EXISTS(TFT_RESET)
- SET_OUTPUT(TFT_RESET_PIN);
- TFT_RST_H;
+ OUT_WRITE(TFT_RESET_PIN, HIGH);
delay(100);
#endif
#if PIN_EXISTS(TFT_BACKLIGHT)
- SET_OUTPUT(TFT_BACKLIGHT_PIN);
- TFT_BLK_H;
+ OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
#endif
SET_OUTPUT(TFT_DC_PIN);
SET_OUTPUT(TFT_CS_PIN);
-
- TFT_DC_H;
- TFT_CS_H;
+ WRITE(TFT_DC_PIN, HIGH);
+ WRITE(TFT_CS_PIN, HIGH);
/**
* STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz
@@ -97,7 +80,7 @@ void TFT_SPI::Init() {
void TFT_SPI::DataTransferBegin(uint16_t DataSize) {
SPIx.setDataSize(DataSize);
SPIx.begin();
- TFT_CS_L;
+ WRITE(TFT_CS_PIN, LOW);
}
uint32_t TFT_SPI::GetID() {
@@ -116,7 +99,7 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
SPIx.setDataSize(DATASIZE_8BIT);
SPIx.setClock(SPI_CLOCK_DIV64);
SPIx.begin();
- TFT_CS_L;
+ WRITE(TFT_CS_PIN, LOW);
WriteReg(Reg);
LOOP_L_N(i, 4) {
@@ -131,21 +114,15 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
return data >> 7;
}
-bool TFT_SPI::isBusy() {
- return false;
-}
+bool TFT_SPI::isBusy() { return false; }
-void TFT_SPI::Abort() {
- DataTransferEnd();
-}
+void TFT_SPI::Abort() { DataTransferEnd(); }
-void TFT_SPI::Transmit(uint16_t Data) {
- SPIx.transfer(Data);
-}
+void TFT_SPI::Transmit(uint16_t Data) { SPIx.transfer(Data); }
void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
- DataTransferBegin(DATASIZE_16BIT); //16
- TFT_DC_H;
+ DataTransferBegin(DATASIZE_16BIT);
+ WRITE(TFT_DC_PIN, HIGH);
SPIx.dmaSend(Data, Count, MemoryIncrease);
DataTransferEnd();
}
diff --git a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp
index 039fa6769bbef..e159ebaa0ca8a 100644
--- a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp
+++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp
@@ -57,7 +57,7 @@
#include "../../../inc/MarlinConfigPre.h"
-#if ENABLED(U8GLIB_ST7920)
+#if IS_U8GLIB_ST7920
#include
#include
@@ -143,5 +143,5 @@ uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t ar
return 1;
}
-#endif // U8GLIB_ST7920
+#endif // IS_U8GLIB_ST7920
#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp
index 3308d03e79f90..f116a9b80aa67 100644
--- a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp
+++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp
@@ -57,7 +57,7 @@
#include "../../../inc/MarlinConfigPre.h"
-#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920)
+#if HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920
#include
#include "../../shared/HAL_SPI.h"
@@ -205,5 +205,5 @@ uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val,
return 1;
}
-#endif // HAS_MARLINUI_U8GLIB && !U8GLIB_ST7920
+#endif // HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920
#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/LPC1768/upload_extra_script.py b/Marlin/src/HAL/LPC1768/upload_extra_script.py
index fb3aaef7cd38c..7975f151f7128 100755
--- a/Marlin/src/HAL/LPC1768/upload_extra_script.py
+++ b/Marlin/src/HAL/LPC1768/upload_extra_script.py
@@ -1,123 +1,127 @@
#
-# sets output_port
+# upload_extra_script.py
+# set the output_port
# if target_filename is found then that drive is used
# else if target_drive is found then that drive is used
#
from __future__ import print_function
-target_filename = "FIRMWARE.CUR"
-target_drive = "REARM"
+import pioutil
+if pioutil.is_pio_build():
-import os,getpass,platform
+ target_filename = "FIRMWARE.CUR"
+ target_drive = "REARM"
-current_OS = platform.system()
-Import("env")
+ import os,getpass,platform
-def print_error(e):
- print('\nUnable to find destination disk (%s)\n' \
- 'Please select it in platformio.ini using the upload_port keyword ' \
- '(https://docs.platformio.org/en/latest/projectconf/section_env_upload.html) ' \
- 'or copy the firmware (.pio/build/%s/firmware.bin) manually to the appropriate disk\n' \
- %(e, env.get('PIOENV')))
+ current_OS = platform.system()
+ Import("env")
-def before_upload(source, target, env):
- try:
- #
- # Find a disk for upload
- #
- upload_disk = 'Disk not found'
- target_file_found = False
- target_drive_found = False
- if current_OS == 'Windows':
+ def print_error(e):
+ print('\nUnable to find destination disk (%s)\n' \
+ 'Please select it in platformio.ini using the upload_port keyword ' \
+ '(https://docs.platformio.org/en/latest/projectconf/section_env_upload.html) ' \
+ 'or copy the firmware (.pio/build/%s/firmware.bin) manually to the appropriate disk\n' \
+ %(e, env.get('PIOENV')))
+
+ def before_upload(source, target, env):
+ try:
+ #
+ # Find a disk for upload
#
- # platformio.ini will accept this for a Windows upload port designation: 'upload_port = L:'
- # Windows - doesn't care about the disk's name, only cares about the drive letter
- import subprocess,string
- from ctypes import windll
+ upload_disk = 'Disk not found'
+ target_file_found = False
+ target_drive_found = False
+ if current_OS == 'Windows':
+ #
+ # platformio.ini will accept this for a Windows upload port designation: 'upload_port = L:'
+ # Windows - doesn't care about the disk's name, only cares about the drive letter
+ import subprocess,string
+ from ctypes import windll
- # getting list of drives
- # https://stackoverflow.com/questions/827371/is-there-a-way-to-list-all-the-available-drive-letters-in-python
- drives = []
- bitmask = windll.kernel32.GetLogicalDrives()
- for letter in string.ascii_uppercase:
- if bitmask & 1:
- drives.append(letter)
- bitmask >>= 1
+ # getting list of drives
+ # https://stackoverflow.com/questions/827371/is-there-a-way-to-list-all-the-available-drive-letters-in-python
+ drives = []
+ bitmask = windll.kernel32.GetLogicalDrives()
+ for letter in string.ascii_uppercase:
+ if bitmask & 1:
+ drives.append(letter)
+ bitmask >>= 1
- for drive in drives:
- final_drive_name = drive + ':\\'
- # print ('disc check: {}'.format(final_drive_name))
- try:
- volume_info = str(subprocess.check_output('cmd /C dir ' + final_drive_name, stderr=subprocess.STDOUT))
- except Exception as e:
- print ('error:{}'.format(e))
- continue
- else:
- if target_drive in volume_info and not target_file_found: # set upload if not found target file yet
- target_drive_found = True
- upload_disk = final_drive_name
- if target_filename in volume_info:
- if not target_file_found:
+ for drive in drives:
+ final_drive_name = drive + ':\\'
+ # print ('disc check: {}'.format(final_drive_name))
+ try:
+ volume_info = str(subprocess.check_output('cmd /C dir ' + final_drive_name, stderr=subprocess.STDOUT))
+ except Exception as e:
+ print ('error:{}'.format(e))
+ continue
+ else:
+ if target_drive in volume_info and not target_file_found: # set upload if not found target file yet
+ target_drive_found = True
upload_disk = final_drive_name
- target_file_found = True
+ if target_filename in volume_info:
+ if not target_file_found:
+ upload_disk = final_drive_name
+ target_file_found = True
- elif current_OS == 'Linux':
- #
- # platformio.ini will accept this for a Linux upload port designation: 'upload_port = /media/media_name/drive'
- #
- drives = os.listdir(os.path.join(os.sep, 'media', getpass.getuser()))
- if target_drive in drives: # If target drive is found, use it.
- target_drive_found = True
- upload_disk = os.path.join(os.sep, 'media', getpass.getuser(), target_drive) + os.sep
- else:
+ elif current_OS == 'Linux':
+ #
+ # platformio.ini will accept this for a Linux upload port designation: 'upload_port = /media/media_name/drive'
+ #
+ drives = os.listdir(os.path.join(os.sep, 'media', getpass.getuser()))
+ if target_drive in drives: # If target drive is found, use it.
+ target_drive_found = True
+ upload_disk = os.path.join(os.sep, 'media', getpass.getuser(), target_drive) + os.sep
+ else:
+ for drive in drives:
+ try:
+ files = os.listdir(os.path.join(os.sep, 'media', getpass.getuser(), drive))
+ except:
+ continue
+ else:
+ if target_filename in files:
+ upload_disk = os.path.join(os.sep, 'media', getpass.getuser(), drive) + os.sep
+ target_file_found = True
+ break
+ #
+ # set upload_port to drive if found
+ #
+
+ if target_file_found or target_drive_found:
+ env.Replace(
+ UPLOAD_FLAGS="-P$UPLOAD_PORT"
+ )
+
+ elif current_OS == 'Darwin': # MAC
+ #
+ # platformio.ini will accept this for a OSX upload port designation: 'upload_port = /media/media_name/drive'
+ #
+ drives = os.listdir('/Volumes') # human readable names
+ if target_drive in drives and not target_file_found: # set upload if not found target file yet
+ target_drive_found = True
+ upload_disk = '/Volumes/' + target_drive + '/'
for drive in drives:
try:
- files = os.listdir(os.path.join(os.sep, 'media', getpass.getuser(), drive))
+ filenames = os.listdir('/Volumes/' + drive + '/') # will get an error if the drive is protected
except:
continue
else:
- if target_filename in files:
- upload_disk = os.path.join(os.sep, 'media', getpass.getuser(), drive) + os.sep
+ if target_filename in filenames:
+ if not target_file_found:
+ upload_disk = '/Volumes/' + drive + '/'
target_file_found = True
- break
- #
- # set upload_port to drive if found
- #
- if target_file_found or target_drive_found:
- env.Replace(
- UPLOAD_FLAGS="-P$UPLOAD_PORT"
- )
-
- elif current_OS == 'Darwin': # MAC
#
- # platformio.ini will accept this for a OSX upload port designation: 'upload_port = /media/media_name/drive'
+ # Set upload_port to drive if found
#
- drives = os.listdir('/Volumes') # human readable names
- if target_drive in drives and not target_file_found: # set upload if not found target file yet
- target_drive_found = True
- upload_disk = '/Volumes/' + target_drive + '/'
- for drive in drives:
- try:
- filenames = os.listdir('/Volumes/' + drive + '/') # will get an error if the drive is protected
- except:
- continue
- else:
- if target_filename in filenames:
- if not target_file_found:
- upload_disk = '/Volumes/' + drive + '/'
- target_file_found = True
-
- #
- # Set upload_port to drive if found
- #
- if target_file_found or target_drive_found:
- env.Replace(UPLOAD_PORT=upload_disk)
- print('\nUpload disk: ', upload_disk, '\n')
- else:
- print_error('Autodetect Error')
+ if target_file_found or target_drive_found:
+ env.Replace(UPLOAD_PORT=upload_disk)
+ print('\nUpload disk: ', upload_disk, '\n')
+ else:
+ print_error('Autodetect Error')
- except Exception as e:
- print_error(str(e))
+ except Exception as e:
+ print_error(str(e))
-env.AddPreAction("upload", before_upload)
+ env.AddPreAction("upload", before_upload)
diff --git a/Marlin/src/HAL/NATIVE_SIM/HAL.h b/Marlin/src/HAL/NATIVE_SIM/HAL.h
index 400fafd711ca5..915339468b2cd 100644
--- a/Marlin/src/HAL/NATIVE_SIM/HAL.h
+++ b/Marlin/src/HAL/NATIVE_SIM/HAL.h
@@ -99,9 +99,9 @@ extern MSerialT serial_stream_3;
#endif
-#define CPU_ST7920_DELAY_1 DELAY_NS(600)
-#define CPU_ST7920_DELAY_2 DELAY_NS(750)
-#define CPU_ST7920_DELAY_3 DELAY_NS(750)
+#define CPU_ST7920_DELAY_1 600
+#define CPU_ST7920_DELAY_2 750
+#define CPU_ST7920_DELAY_3 750
//
// Interrupts
@@ -133,6 +133,9 @@ void HAL_adc_enable_channel(const uint8_t ch);
void HAL_adc_start_conversion(const uint8_t ch);
uint16_t HAL_adc_get_result();
+// PWM
+inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
+
// Reset source
inline void HAL_clear_reset_source(void) {}
inline uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; }
diff --git a/Marlin/src/HAL/NATIVE_SIM/inc/SanityCheck.h b/Marlin/src/HAL/NATIVE_SIM/inc/SanityCheck.h
index 104af9af5b203..2d7bef23a36da 100644
--- a/Marlin/src/HAL/NATIVE_SIM/inc/SanityCheck.h
+++ b/Marlin/src/HAL/NATIVE_SIM/inc/SanityCheck.h
@@ -26,7 +26,7 @@
*/
// Emulating RAMPS
-#if ENABLED(SPINDLE_LASER_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11)
+#if ENABLED(SPINDLE_LASER_USE_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11)
#error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector"
#endif
diff --git a/Marlin/src/HAL/NATIVE_SIM/pinsDebug.h b/Marlin/src/HAL/NATIVE_SIM/pinsDebug.h
index 7e50492598556..aa90eb39a3305 100644
--- a/Marlin/src/HAL/NATIVE_SIM/pinsDebug.h
+++ b/Marlin/src/HAL/NATIVE_SIM/pinsDebug.h
@@ -20,7 +20,6 @@
/**
* Support routines for X86_64
*/
-
#pragma once
/**
diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_st7920_sw_spi.cpp b/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_st7920_sw_spi.cpp
index c77c3d30f09a3..c384cdd75185a 100644
--- a/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_st7920_sw_spi.cpp
+++ b/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_st7920_sw_spi.cpp
@@ -57,7 +57,7 @@
#include "../../../inc/MarlinConfig.h"
-#if ENABLED(U8GLIB_ST7920)
+#if IS_U8GLIB_ST7920
#include
#include "../../shared/Delay.h"
@@ -167,5 +167,5 @@ uint8_t u8g_com_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void
}
#endif
-#endif // U8GLIB_ST7920
+#endif // IS_U8GLIB_ST7920
#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_sw_spi.cpp b/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_sw_spi.cpp
index 085954803cf2e..7fd335d62eba7 100644
--- a/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_sw_spi.cpp
+++ b/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_sw_spi.cpp
@@ -57,7 +57,7 @@
#include "../../../inc/MarlinConfig.h"
-#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920)
+#if HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920
#undef SPI_SPEED
#define SPI_SPEED 2 // About 2 MHz
@@ -211,5 +211,5 @@ uint8_t u8g_com_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_pt
#elif !ANY(TFT_COLOR_UI, TFT_CLASSIC_UI, TFT_LVGL_UI, HAS_MARLINUI_HD44780) && HAS_MARLINUI_U8GLIB
#include
uint8_t u8g_com_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {return 0;}
-#endif // HAS_MARLINUI_U8GLIB && !U8GLIB_ST7920
+#endif // HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920
#endif // __PLAT_NATIVE_SIM__
diff --git a/Marlin/src/HAL/SAMD51/HAL.h b/Marlin/src/HAL/SAMD51/HAL.h
index 491c3f82c4a67..c262752a8d66a 100644
--- a/Marlin/src/HAL/SAMD51/HAL.h
+++ b/Marlin/src/HAL/SAMD51/HAL.h
@@ -127,6 +127,11 @@ void HAL_adc_init();
void HAL_adc_start_conversion(const uint8_t adc_pin);
+//
+// PWM
+//
+inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
+
//
// Pin Map
//
@@ -153,16 +158,14 @@ void HAL_idletask();
//
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
+#pragma GCC diagnostic push
#if GCC_VERSION <= 50000
- #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
-#if GCC_VERSION <= 50000
- #pragma GCC diagnostic pop
-#endif
+#pragma GCC diagnostic pop
#ifdef __cplusplus
extern "C" {
diff --git a/Marlin/src/HAL/SAMD51/MarlinSPI.h b/Marlin/src/HAL/SAMD51/MarlinSPI.h
new file mode 100644
index 0000000000000..0c447ba4cb3dc
--- /dev/null
+++ b/Marlin/src/HAL/SAMD51/MarlinSPI.h
@@ -0,0 +1,26 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include
+
+using MarlinSPI = SPIClass;
diff --git a/Marlin/src/HAL/SAMD51/QSPIFlash.h b/Marlin/src/HAL/SAMD51/QSPIFlash.h
index db4abec91caf9..58822fe05f3e5 100644
--- a/Marlin/src/HAL/SAMD51/QSPIFlash.h
+++ b/Marlin/src/HAL/SAMD51/QSPIFlash.h
@@ -25,7 +25,6 @@
*
* Derived from Adafruit_SPIFlash class with no SdFat references
*/
-
#pragma once
#include
diff --git a/Marlin/src/HAL/SAMD51/endstop_interrupts.h b/Marlin/src/HAL/SAMD51/endstop_interrupts.h
index c46b6e072f905..61a06c0d4b426 100644
--- a/Marlin/src/HAL/SAMD51/endstop_interrupts.h
+++ b/Marlin/src/HAL/SAMD51/endstop_interrupts.h
@@ -162,12 +162,14 @@ void setup_endstop_interrupts() {
#error "Z_MIN_PROBE_PIN has no EXTINT line available."
#endif
_ATTACH(Z_MIN_PROBE_PIN);
- #elif HAS_I_MAX
+ #endif
+ #if HAS_I_MAX
#if !AVAILABLE_EILINE(I_MAX_PIN)
#error "I_MAX_PIN has no EXTINT line available."
#endif
attachInterrupt(I_MAX_PIN, endstop_ISR, CHANGE);
- #elif HAS_I_MIN
+ #endif
+ #if HAS_I_MIN
#if !AVAILABLE_EILINE(I_MIN_PIN)
#error "I_MIN_PIN has no EXTINT line available."
#endif
@@ -178,7 +180,8 @@ void setup_endstop_interrupts() {
#error "J_MAX_PIN has no EXTINT line available."
#endif
attachInterrupt(J_MAX_PIN, endstop_ISR, CHANGE);
- #elif HAS_J_MIN
+ #endif
+ #if HAS_J_MIN
#if !AVAILABLE_EILINE(J_MIN_PIN)
#error "J_MIN_PIN has no EXTINT line available."
#endif
@@ -189,7 +192,8 @@ void setup_endstop_interrupts() {
#error "K_MAX_PIN has no EXTINT line available."
#endif
attachInterrupt(K_MAX_PIN, endstop_ISR, CHANGE);
- #elif HAS_K_MIN
+ #endif
+ #if HAS_K_MIN
#if !AVAILABLE_EILINE(K_MIN_PIN)
#error "K_MIN_PIN has no EXTINT line available."
#endif
diff --git a/Marlin/src/HAL/SAMD51/pinsDebug.h b/Marlin/src/HAL/SAMD51/pinsDebug.h
index 5c86d0c07179d..f0a46fd7c567c 100644
--- a/Marlin/src/HAL/SAMD51/pinsDebug.h
+++ b/Marlin/src/HAL/SAMD51/pinsDebug.h
@@ -48,7 +48,7 @@ bool GET_PINMODE(int8_t pin) { // 1: output, 0: input
void pwm_details(int32_t pin) {
if (pwm_status(pin)) {
//uint32_t chan = g_APinDescription[pin].ulPWMChannel TODO when fast pwm is operative;
- //SERIAL_ECHOPAIR("PWM = ", duty);
+ //SERIAL_ECHOPGM("PWM = ", duty);
}
}
diff --git a/Marlin/src/HAL/STM32/HAL.cpp b/Marlin/src/HAL/STM32/HAL.cpp
index a04a24c1123c0..0920a72ec1bcd 100644
--- a/Marlin/src/HAL/STM32/HAL.cpp
+++ b/Marlin/src/HAL/STM32/HAL.cpp
@@ -154,7 +154,7 @@ void HAL_adc_start_conversion(const uint8_t adc_pin) { HAL_adc_result = analogRe
uint16_t HAL_adc_get_result() { return HAL_adc_result; }
// Reset the system to initiate a firmware flash
-void flashFirmware(const int16_t) { HAL_reboot(); }
+WEAK void flashFirmware(const int16_t) { HAL_reboot(); }
// Maple Compatibility
volatile uint32_t systick_uptime_millis = 0;
diff --git a/Marlin/src/HAL/STM32/HAL.h b/Marlin/src/HAL/STM32/HAL.h
index d73f8b2d54d06..a68e8a8c0e4af 100644
--- a/Marlin/src/HAL/STM32/HAL.h
+++ b/Marlin/src/HAL/STM32/HAL.h
@@ -40,9 +40,9 @@
//
// Default graphical display delays
//
-#define CPU_ST7920_DELAY_1 DELAY_NS(300)
-#define CPU_ST7920_DELAY_2 DELAY_NS( 40)
-#define CPU_ST7920_DELAY_3 DELAY_NS(340)
+#define CPU_ST7920_DELAY_1 300
+#define CPU_ST7920_DELAY_2 40
+#define CPU_ST7920_DELAY_3 340
//
// Serial Ports
@@ -183,8 +183,13 @@ static inline int freeMemory() {
#define HAL_ANALOG_SELECT(pin) pinMode(pin, INPUT)
+#ifdef ADC_RESOLUTION
+ #define HAL_ADC_RESOLUTION ADC_RESOLUTION
+#else
+ #define HAL_ADC_RESOLUTION 12
+#endif
+
#define HAL_ADC_VREF 3.3
-#define HAL_ADC_RESOLUTION ADC_RESOLUTION // 12
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
diff --git a/Marlin/src/HAL/STM32/HAL_SPI.cpp b/Marlin/src/HAL/STM32/HAL_SPI.cpp
index 85a5238b54af9..8ee4761647856 100644
--- a/Marlin/src/HAL/STM32/HAL_SPI.cpp
+++ b/Marlin/src/HAL/STM32/HAL_SPI.cpp
@@ -47,7 +47,9 @@ static SPISettings spiConfig;
#include "../shared/Delay.h"
void spiBegin(void) {
- OUT_WRITE(SD_SS_PIN, HIGH);
+ #if PIN_EXISTS(SD_SS)
+ OUT_WRITE(SD_SS_PIN, HIGH);
+ #endif
OUT_WRITE(SD_SCK_PIN, HIGH);
SET_INPUT(SD_MISO_PIN);
OUT_WRITE(SD_MOSI_PIN, HIGH);
diff --git a/Marlin/src/HAL/STM32/MarlinSPI.cpp b/Marlin/src/HAL/STM32/MarlinSPI.cpp
index e1be50820f659..7078d210dc4c0 100644
--- a/Marlin/src/HAL/STM32/MarlinSPI.cpp
+++ b/Marlin/src/HAL/STM32/MarlinSPI.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "../platforms.h"
#if defined(HAL_STM32) && !defined(STM32H7xx)
diff --git a/Marlin/src/HAL/STM32/MarlinSerial.cpp b/Marlin/src/HAL/STM32/MarlinSerial.cpp
index 3caedc72eb26e..37a8f40fd0b15 100644
--- a/Marlin/src/HAL/STM32/MarlinSerial.cpp
+++ b/Marlin/src/HAL/STM32/MarlinSerial.cpp
@@ -2,6 +2,9 @@
* 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
@@ -16,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "../platforms.h"
#ifdef HAL_STM32
diff --git a/Marlin/src/HAL/STM32/MarlinSerial.h b/Marlin/src/HAL/STM32/MarlinSerial.h
index ab5c4260af2df..bf861fb8a79a9 100644
--- a/Marlin/src/HAL/STM32/MarlinSerial.h
+++ b/Marlin/src/HAL/STM32/MarlinSerial.h
@@ -2,6 +2,9 @@
* 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
diff --git a/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp b/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp
index 914969f10cd21..54e1820c78e6b 100644
--- a/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp
+++ b/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "../platforms.h"
#ifdef HAL_STM32
diff --git a/Marlin/src/HAL/STM32/eeprom_bl24cxx.cpp b/Marlin/src/HAL/STM32/eeprom_bl24cxx.cpp
index 5bd4c18577b40..f30b3dedb203e 100644
--- a/Marlin/src/HAL/STM32/eeprom_bl24cxx.cpp
+++ b/Marlin/src/HAL/STM32/eeprom_bl24cxx.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "../platforms.h"
#ifdef HAL_STM32
diff --git a/Marlin/src/HAL/STM32/eeprom_flash.cpp b/Marlin/src/HAL/STM32/eeprom_flash.cpp
index e785e59249888..252b057362c99 100644
--- a/Marlin/src/HAL/STM32/eeprom_flash.cpp
+++ b/Marlin/src/HAL/STM32/eeprom_flash.cpp
@@ -133,7 +133,7 @@ bool PersistentStore::access_start() {
// load current settings
uint8_t *eeprom_data = (uint8_t *)SLOT_ADDRESS(current_slot);
for (int i = 0; i < MARLIN_EEPROM_SIZE; i++) ram_eeprom[i] = eeprom_data[i];
- DEBUG_ECHOLNPAIR("EEPROM loaded from slot ", current_slot, ".");
+ DEBUG_ECHOLNPGM("EEPROM loaded from slot ", current_slot, ".");
}
eeprom_data_written = false;
}
@@ -179,9 +179,9 @@ bool PersistentStore::access_finish() {
ENABLE_ISRS();
TERN_(HAS_PAUSE_SERVO_OUTPUT, RESUME_SERVO_OUTPUT());
if (status != HAL_OK) {
- DEBUG_ECHOLNPAIR("HAL_FLASHEx_Erase=", status);
- DEBUG_ECHOLNPAIR("GetError=", HAL_FLASH_GetError());
- DEBUG_ECHOLNPAIR("SectorError=", SectorError);
+ DEBUG_ECHOLNPGM("HAL_FLASHEx_Erase=", status);
+ DEBUG_ECHOLNPGM("GetError=", HAL_FLASH_GetError());
+ DEBUG_ECHOLNPGM("SectorError=", SectorError);
LOCK_FLASH();
return false;
}
@@ -204,9 +204,9 @@ bool PersistentStore::access_finish() {
offset += sizeof(uint32_t);
}
else {
- DEBUG_ECHOLNPAIR("HAL_FLASH_Program=", status);
- DEBUG_ECHOLNPAIR("GetError=", HAL_FLASH_GetError());
- DEBUG_ECHOLNPAIR("address=", address);
+ DEBUG_ECHOLNPGM("HAL_FLASH_Program=", status);
+ DEBUG_ECHOLNPGM("GetError=", HAL_FLASH_GetError());
+ DEBUG_ECHOLNPGM("address=", address);
success = false;
break;
}
@@ -216,7 +216,7 @@ bool PersistentStore::access_finish() {
if (success) {
eeprom_data_written = false;
- DEBUG_ECHOLNPAIR("EEPROM saved to slot ", current_slot, ".");
+ DEBUG_ECHOLNPGM("EEPROM saved to slot ", current_slot, ".");
}
return success;
diff --git a/Marlin/src/HAL/STM32/eeprom_if_iic.cpp b/Marlin/src/HAL/STM32/eeprom_if_iic.cpp
index 26b3d9044e1f5..ad8712c0c0754 100644
--- a/Marlin/src/HAL/STM32/eeprom_if_iic.cpp
+++ b/Marlin/src/HAL/STM32/eeprom_if_iic.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "../platforms.h"
#ifdef HAL_STM32
diff --git a/Marlin/src/HAL/STM32/eeprom_sdcard.cpp b/Marlin/src/HAL/STM32/eeprom_sdcard.cpp
index 77563b2ae502b..473b656f9a3c0 100644
--- a/Marlin/src/HAL/STM32/eeprom_sdcard.cpp
+++ b/Marlin/src/HAL/STM32/eeprom_sdcard.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "../platforms.h"
#ifdef HAL_STM32
diff --git a/Marlin/src/HAL/STM32/fast_pwm.cpp b/Marlin/src/HAL/STM32/fast_pwm.cpp
index a8fcbe5f82b37..4d450374d32ba 100644
--- a/Marlin/src/HAL/STM32/fast_pwm.cpp
+++ b/Marlin/src/HAL/STM32/fast_pwm.cpp
@@ -19,36 +19,22 @@
* along with this program. If not, see .
*
*/
+
#include "../platforms.h"
#ifdef HAL_STM32
-#include "../../inc/MarlinConfigPre.h"
-
-#if NEEDS_HARDWARE_PWM
-
-#include "HAL.h"
+#include "../../inc/MarlinConfig.h"
#include "timers.h"
-void set_pwm_frequency(const pin_t pin, int f_desired) {
+void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
if (!PWM_PIN(pin)) return; // Don't proceed if no hardware timer
- PinName pin_name = digitalPinToPinName(pin);
- TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM); // Get HAL timer instance
-
- LOOP_S_L_N(i, 0, NUM_HARDWARE_TIMERS) // Protect used timers
- if (timer_instance[i] && timer_instance[i]->getHandle()->Instance == Instance)
- return;
-
- pwm_start(pin_name, f_desired, 0, RESOLUTION_8B_COMPARE_FORMAT);
-}
-
-void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
PinName pin_name = digitalPinToPinName(pin);
TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM);
+
uint16_t adj_val = Instance->ARR * v / v_size;
if (invert) adj_val = Instance->ARR - adj_val;
-
switch (get_pwm_channel(pin_name)) {
case TIM_CHANNEL_1: LL_TIM_OC_SetCompareCH1(Instance, adj_val); break;
case TIM_CHANNEL_2: LL_TIM_OC_SetCompareCH2(Instance, adj_val); break;
@@ -57,5 +43,21 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255
}
}
-#endif // NEEDS_HARDWARE_PWM
+#if NEEDS_HARDWARE_PWM
+
+ void set_pwm_frequency(const pin_t pin, int f_desired) {
+ if (!PWM_PIN(pin)) return; // Don't proceed if no hardware timer
+
+ PinName pin_name = digitalPinToPinName(pin);
+ TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM); // Get HAL timer instance
+
+ LOOP_S_L_N(i, 0, NUM_HARDWARE_TIMERS) // Protect used timers
+ if (timer_instance[i] && timer_instance[i]->getHandle()->Instance == Instance)
+ return;
+
+ pwm_start(pin_name, f_desired, 0, RESOLUTION_8B_COMPARE_FORMAT);
+ }
+
+#endif
+
#endif // HAL_STM32
diff --git a/Marlin/src/HAL/STM32/inc/SanityCheck.h b/Marlin/src/HAL/STM32/inc/SanityCheck.h
index 12ff2abec7ac8..0f1a2acaa41ce 100644
--- a/Marlin/src/HAL/STM32/inc/SanityCheck.h
+++ b/Marlin/src/HAL/STM32/inc/SanityCheck.h
@@ -24,7 +24,7 @@
/**
* Test STM32-specific configuration values for errors at compile-time.
*/
-//#if ENABLED(SPINDLE_LASER_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11)
+//#if ENABLED(SPINDLE_LASER_USE_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11)
// #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector"
//#endif
diff --git a/Marlin/src/HAL/STM32/pinsDebug.h b/Marlin/src/HAL/STM32/pinsDebug.h
index ff671a6ebf3f1..73d850fc43132 100644
--- a/Marlin/src/HAL/STM32/pinsDebug.h
+++ b/Marlin/src/HAL/STM32/pinsDebug.h
@@ -2,6 +2,9 @@
* 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
@@ -237,7 +240,7 @@ void pwm_details(const pin_t Ard_num) {
if (over_7) pin_number -= 8;
uint8_t alt_func = (alt_all >> (4 * pin_number)) & 0x0F;
- SERIAL_ECHOPAIR("Alt Function: ", alt_func);
+ SERIAL_ECHOPGM("Alt Function: ", alt_func);
if (alt_func < 10) SERIAL_CHAR(' ');
SERIAL_ECHOPGM(" - ");
switch (alt_func) {
diff --git a/Marlin/src/HAL/STM32/spi_pins.h b/Marlin/src/HAL/STM32/spi_pins.h
index e2052c5c77046..7f341a8c253fd 100644
--- a/Marlin/src/HAL/STM32/spi_pins.h
+++ b/Marlin/src/HAL/STM32/spi_pins.h
@@ -2,6 +2,9 @@
* 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
diff --git a/Marlin/src/HAL/STM32/tft/tft_fsmc.cpp b/Marlin/src/HAL/STM32/tft/tft_fsmc.cpp
index dacf533224fcb..e68b3c1269395 100644
--- a/Marlin/src/HAL/STM32/tft/tft_fsmc.cpp
+++ b/Marlin/src/HAL/STM32/tft/tft_fsmc.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "../../platforms.h"
#ifdef HAL_STM32
diff --git a/Marlin/src/HAL/STM32/tft/tft_ltdc.cpp b/Marlin/src/HAL/STM32/tft/tft_ltdc.cpp
index 0549dbf108450..66cfd65995ddd 100644
--- a/Marlin/src/HAL/STM32/tft/tft_ltdc.cpp
+++ b/Marlin/src/HAL/STM32/tft/tft_ltdc.cpp
@@ -183,7 +183,7 @@ void LTDC_Config() {
hltdc_F.Init.AccumulatedVBP = (LTDC_LCD_VSYNC + LTDC_LCD_VBP - 1);
hltdc_F.Init.AccumulatedActiveH = (TFT_HEIGHT + LTDC_LCD_VSYNC + LTDC_LCD_VBP - 1);
hltdc_F.Init.AccumulatedActiveW = (TFT_WIDTH + LTDC_LCD_HSYNC + LTDC_LCD_HBP - 1);
- hltdc_F.Init.TotalHeight = (TFT_HEIGHT + LTDC_LCD_VSYNC + LTDC_LCD_VBP + LTDC_LCD_VFP - 1);
+ hltdc_F.Init.TotalHeigh = (TFT_HEIGHT + LTDC_LCD_VSYNC + LTDC_LCD_VBP + LTDC_LCD_VFP - 1);
hltdc_F.Init.TotalWidth = (TFT_WIDTH + LTDC_LCD_HSYNC + LTDC_LCD_HBP + LTDC_LCD_HFP - 1);
/* Configure R,G,B component values for LCD background color : all black background */
@@ -205,7 +205,7 @@ void LTDC_Config() {
pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
/* Start Address configuration : frame buffer is located at SDRAM memory */
- pLayerCfg.FBStartAddress = (uint32_t)(FRAME_BUFFER_ADDRESS);
+ pLayerCfg.FBStartAdress = (uint32_t)(FRAME_BUFFER_ADDRESS);
/* Alpha constant (255 == totally opaque) */
pLayerCfg.Alpha = 255;
diff --git a/Marlin/src/HAL/STM32/tft/tft_spi.cpp b/Marlin/src/HAL/STM32/tft/tft_spi.cpp
index 29a309f40e7bc..790513e7edd97 100644
--- a/Marlin/src/HAL/STM32/tft/tft_spi.cpp
+++ b/Marlin/src/HAL/STM32/tft/tft_spi.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "../../platforms.h"
#ifdef HAL_STM32
diff --git a/Marlin/src/HAL/STM32/tft/xpt2046.cpp b/Marlin/src/HAL/STM32/tft/xpt2046.cpp
index 912e6c2db7618..cf4a8f18e9ac2 100644
--- a/Marlin/src/HAL/STM32/tft/xpt2046.cpp
+++ b/Marlin/src/HAL/STM32/tft/xpt2046.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "../../platforms.h"
#ifdef HAL_STM32
diff --git a/Marlin/src/HAL/STM32/usb_host.cpp b/Marlin/src/HAL/STM32/usb_host.cpp
index d2d1d69a1a8dc..d77f0b28e9641 100644
--- a/Marlin/src/HAL/STM32/usb_host.cpp
+++ b/Marlin/src/HAL/STM32/usb_host.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "../platforms.h"
#ifdef HAL_STM32
@@ -88,9 +89,9 @@ void USBHost::setUsbTaskState(uint8_t state) {
capacity = info.capacity.block_nbr / 2000;
block_size = info.capacity.block_size;
block_count = info.capacity.block_nbr;
- // SERIAL_ECHOLNPAIR("info.capacity.block_nbr : %ld\n", info.capacity.block_nbr);
- // SERIAL_ECHOLNPAIR("info.capacity.block_size: %d\n", info.capacity.block_size);
- // SERIAL_ECHOLNPAIR("capacity : %d MB\n", capacity);
+ //SERIAL_ECHOLNPGM("info.capacity.block_nbr : %ld\n", info.capacity.block_nbr);
+ //SERIAL_ECHOLNPGM("info.capacity.block_size: %d\n", info.capacity.block_size);
+ //SERIAL_ECHOLNPGM("capacity : %d MB\n", capacity);
}
};
diff --git a/Marlin/src/HAL/STM32/usb_serial.cpp b/Marlin/src/HAL/STM32/usb_serial.cpp
index 959ca4ff43191..b607275db5bb3 100644
--- a/Marlin/src/HAL/STM32/usb_serial.cpp
+++ b/Marlin/src/HAL/STM32/usb_serial.cpp
@@ -2,6 +2,9 @@
* 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
@@ -16,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "../platforms.h"
#ifdef HAL_STM32
diff --git a/Marlin/src/HAL/STM32/usb_serial.h b/Marlin/src/HAL/STM32/usb_serial.h
index ca61b9ed239f5..3edb6fd6185cc 100644
--- a/Marlin/src/HAL/STM32/usb_serial.h
+++ b/Marlin/src/HAL/STM32/usb_serial.h
@@ -2,6 +2,9 @@
* 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
diff --git a/Marlin/src/HAL/STM32/watchdog.cpp b/Marlin/src/HAL/STM32/watchdog.cpp
index 72c74a2e3b5b6..1eccdec4985dc 100644
--- a/Marlin/src/HAL/STM32/watchdog.cpp
+++ b/Marlin/src/HAL/STM32/watchdog.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "../platforms.h"
#ifdef HAL_STM32
diff --git a/Marlin/src/HAL/STM32F1/HAL.cpp b/Marlin/src/HAL/STM32F1/HAL.cpp
index 73014945a156f..f29b30536146e 100644
--- a/Marlin/src/HAL/STM32F1/HAL.cpp
+++ b/Marlin/src/HAL/STM32F1/HAL.cpp
@@ -437,7 +437,7 @@ void HAL_adc_start_conversion(const uint8_t adc_pin) {
case POWER_MONITOR_VOLTAGE_PIN: pin_index = POWERMON_VOLTS; break;
#endif
}
- HAL_adc_result = (HAL_adc_results[(int)pin_index] >> 2) & 0x3FF; // shift to get 10 bits only.
+ HAL_adc_result = HAL_adc_results[(int)pin_index] >> (12 - HAL_ADC_RESOLUTION); // shift out unused bits
}
uint16_t HAL_adc_get_result() { return HAL_adc_result; }
@@ -449,8 +449,7 @@ uint16_t analogRead(pin_t pin) {
// Wrapper to maple unprotected analogWrite
void analogWrite(pin_t pin, int pwm_val8) {
- if (PWM_PIN(pin))
- analogWrite(uint8_t(pin), pwm_val8);
+ if (PWM_PIN(pin)) analogWrite(uint8_t(pin), pwm_val8);
}
void HAL_reboot() { nvic_sys_reset(); }
diff --git a/Marlin/src/HAL/STM32F1/HAL.h b/Marlin/src/HAL/STM32F1/HAL.h
index 7efb761c2806f..3bdfb9703c643 100644
--- a/Marlin/src/HAL/STM32F1/HAL.h
+++ b/Marlin/src/HAL/STM32F1/HAL.h
@@ -54,9 +54,9 @@
//
// Default graphical display delays
//
-#define CPU_ST7920_DELAY_1 DELAY_NS(300)
-#define CPU_ST7920_DELAY_2 DELAY_NS( 40)
-#define CPU_ST7920_DELAY_3 DELAY_NS(340)
+#define CPU_ST7920_DELAY_1 300
+#define CPU_ST7920_DELAY_2 40
+#define CPU_ST7920_DELAY_3 340
#ifndef STM32_FLASH_SIZE
#if ANY(MCU_STM32F103RE, MCU_STM32F103VE, MCU_STM32F103ZE)
@@ -237,8 +237,13 @@ static inline int freeMemory() {
void HAL_adc_init();
+#ifdef ADC_RESOLUTION
+ #define HAL_ADC_RESOLUTION ADC_RESOLUTION
+#else
+ #define HAL_ADC_RESOLUTION 12
+#endif
+
#define HAL_ADC_VREF 3.3
-#define HAL_ADC_RESOLUTION 10
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
diff --git a/Marlin/src/HAL/STM32F1/build_flags.py b/Marlin/src/HAL/STM32F1/build_flags.py
index d0848d1c64383..970ca8b767f9f 100755
--- a/Marlin/src/HAL/STM32F1/build_flags.py
+++ b/Marlin/src/HAL/STM32F1/build_flags.py
@@ -30,25 +30,27 @@
# extra script for linker options
else:
- from SCons.Script import DefaultEnvironment
- env = DefaultEnvironment()
- env.Append(
+ import pioutil
+ if pioutil.is_pio_build():
+ from SCons.Script import DefaultEnvironment
+ env = DefaultEnvironment()
+ env.Append(
ARFLAGS=["rcs"],
ASFLAGS=["-x", "assembler-with-cpp"],
CXXFLAGS=[
- "-fabi-version=0",
- "-fno-use-cxa-atexit",
- "-fno-threadsafe-statics"
+ "-fabi-version=0",
+ "-fno-use-cxa-atexit",
+ "-fno-threadsafe-statics"
],
LINKFLAGS=[
- "-Os",
- "-mcpu=cortex-m3",
- "-ffreestanding",
- "-mthumb",
- "--specs=nano.specs",
- "--specs=nosys.specs",
- "-u_printf_float",
+ "-Os",
+ "-mcpu=cortex-m3",
+ "-ffreestanding",
+ "-mthumb",
+ "--specs=nano.specs",
+ "--specs=nosys.specs",
+ "-u_printf_float",
],
- )
+ )
diff --git a/Marlin/src/HAL/STM32F1/dogm/u8g_com_stm32duino_swspi.cpp b/Marlin/src/HAL/STM32F1/dogm/u8g_com_stm32duino_swspi.cpp
index f1cd6b3730529..26ea1ea19af95 100644
--- a/Marlin/src/HAL/STM32F1/dogm/u8g_com_stm32duino_swspi.cpp
+++ b/Marlin/src/HAL/STM32F1/dogm/u8g_com_stm32duino_swspi.cpp
@@ -2,6 +2,9 @@
* 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
@@ -16,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#ifdef __STM32F1__
#include "../../../inc/MarlinConfig.h"
diff --git a/Marlin/src/HAL/STM32F1/eeprom_wired.cpp b/Marlin/src/HAL/STM32F1/eeprom_wired.cpp
index 4cac36554f15d..bc48eef34fa36 100644
--- a/Marlin/src/HAL/STM32F1/eeprom_wired.cpp
+++ b/Marlin/src/HAL/STM32F1/eeprom_wired.cpp
@@ -2,6 +2,9 @@
* 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
diff --git a/Marlin/src/HAL/STM32F1/fast_pwm.cpp b/Marlin/src/HAL/STM32F1/fast_pwm.cpp
index 884d482af5f15..5171c11545f5b 100644
--- a/Marlin/src/HAL/STM32F1/fast_pwm.cpp
+++ b/Marlin/src/HAL/STM32F1/fast_pwm.cpp
@@ -23,46 +23,47 @@
#include "../../inc/MarlinConfigPre.h"
-#if NEEDS_HARDWARE_PWM
-
#include
#include "HAL.h"
#include "timers.h"
-void set_pwm_frequency(const pin_t pin, int f_desired) {
- if (!PWM_PIN(pin)) return; // Don't proceed if no hardware timer
-
- timer_dev *timer = PIN_MAP[pin].timer_device;
- uint8_t channel = PIN_MAP[pin].timer_channel;
-
- // Protect used timers
- if (timer == get_timer_dev(TEMP_TIMER_NUM)) return;
- if (timer == get_timer_dev(STEP_TIMER_NUM)) return;
- #if PULSE_TIMER_NUM != STEP_TIMER_NUM
- if (timer == get_timer_dev(PULSE_TIMER_NUM)) return;
- #endif
-
- if (!(timer->regs.bas->SR & TIMER_CR1_CEN)) // Ensure the timer is enabled
- timer_init(timer);
-
- timer_set_mode(timer, channel, TIMER_PWM);
- uint16_t preload = 255; // Lock 255 PWM resolution for high frequencies
- int32_t prescaler = (HAL_TIMER_RATE) / (preload + 1) / f_desired - 1;
- if (prescaler > 65535) { // For low frequencies increase prescaler
- prescaler = 65535;
- preload = (HAL_TIMER_RATE) / (prescaler + 1) / f_desired - 1;
- }
- if (prescaler < 0) return; // Too high frequency
- timer_set_reload(timer, preload);
- timer_set_prescaler(timer, prescaler);
-}
-
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
+ if (!PWM_PIN(pin)) return;
timer_dev *timer = PIN_MAP[pin].timer_device;
uint16_t max_val = timer->regs.bas->ARR * v / v_size;
if (invert) max_val = v_size - max_val;
pwmWrite(pin, max_val);
}
+#if NEEDS_HARDWARE_PWM
+
+ void set_pwm_frequency(const pin_t pin, int f_desired) {
+ if (!PWM_PIN(pin)) return; // Don't proceed if no hardware timer
+
+ timer_dev *timer = PIN_MAP[pin].timer_device;
+ uint8_t channel = PIN_MAP[pin].timer_channel;
+
+ // Protect used timers
+ if (timer == get_timer_dev(TEMP_TIMER_NUM)) return;
+ if (timer == get_timer_dev(STEP_TIMER_NUM)) return;
+ #if PULSE_TIMER_NUM != STEP_TIMER_NUM
+ if (timer == get_timer_dev(PULSE_TIMER_NUM)) return;
+ #endif
+
+ if (!(timer->regs.bas->SR & TIMER_CR1_CEN)) // Ensure the timer is enabled
+ timer_init(timer);
+
+ timer_set_mode(timer, channel, TIMER_PWM);
+ uint16_t preload = 255; // Lock 255 PWM resolution for high frequencies
+ int32_t prescaler = (HAL_TIMER_RATE) / (preload + 1) / f_desired - 1;
+ if (prescaler > 65535) { // For low frequencies increase prescaler
+ prescaler = 65535;
+ preload = (HAL_TIMER_RATE) / (prescaler + 1) / f_desired - 1;
+ }
+ if (prescaler < 0) return; // Too high frequency
+ timer_set_reload(timer, preload);
+ timer_set_prescaler(timer, prescaler);
+ }
+
#endif // NEEDS_HARDWARE_PWM
#endif // __STM32F1__
diff --git a/Marlin/src/HAL/STM32F1/pinsDebug.h b/Marlin/src/HAL/STM32F1/pinsDebug.h
index dcf3a51138716..27f4b6732bfb3 100644
--- a/Marlin/src/HAL/STM32F1/pinsDebug.h
+++ b/Marlin/src/HAL/STM32F1/pinsDebug.h
@@ -2,6 +2,9 @@
* 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
diff --git a/Marlin/src/HAL/STM32F1/spi_pins.h b/Marlin/src/HAL/STM32F1/spi_pins.h
index 7d650ffe373fe..3d3c8f8d2f184 100644
--- a/Marlin/src/HAL/STM32F1/spi_pins.h
+++ b/Marlin/src/HAL/STM32F1/spi_pins.h
@@ -2,6 +2,9 @@
* 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
diff --git a/Marlin/src/HAL/STM32F1/tft/tft_spi.cpp b/Marlin/src/HAL/STM32F1/tft/tft_spi.cpp
index 5edf96fe56be9..9bf6bbb32bc7f 100644
--- a/Marlin/src/HAL/STM32F1/tft/tft_spi.cpp
+++ b/Marlin/src/HAL/STM32F1/tft/tft_spi.cpp
@@ -26,36 +26,20 @@
#include "tft_spi.h"
-// TFT_SPI tft;
-
SPIClass TFT_SPI::SPIx(1);
-#define TFT_CS_H OUT_WRITE(TFT_CS_PIN, HIGH)
-#define TFT_CS_L OUT_WRITE(TFT_CS_PIN, LOW)
-
-#define TFT_DC_H OUT_WRITE(TFT_DC_PIN, HIGH)
-#define TFT_DC_L OUT_WRITE(TFT_DC_PIN, LOW)
-
-#define TFT_RST_H OUT_WRITE(TFT_RST_PIN, HIGH)
-#define TFT_RST_L OUT_WRITE(TFT_RST_PIN, LOW)
-
-#define TFT_BLK_H OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH)
-#define TFT_BLK_L OUT_WRITE(TFT_BACKLIGHT_PIN, LOW)
-
void TFT_SPI::Init() {
#if PIN_EXISTS(TFT_RESET)
- // OUT_WRITE(TFT_RESET_PIN, HIGH);
- TFT_RST_H;
+ OUT_WRITE(TFT_RST_PIN, HIGH);
delay(100);
#endif
#if PIN_EXISTS(TFT_BACKLIGHT)
- // OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
- TFT_BLK_H;
+ OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
#endif
- TFT_DC_H;
- TFT_CS_H;
+ OUT_WRITE(TFT_DC_PIN, HIGH);
+ OUT_WRITE(TFT_CS_PIN, HIGH);
/**
* STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz
@@ -87,7 +71,7 @@ void TFT_SPI::Init() {
void TFT_SPI::DataTransferBegin(uint16_t DataSize) {
SPIx.setDataSize(DataSize);
SPIx.begin();
- TFT_CS_L;
+ OUT_WRITE(TFT_CS_PIN, LOW);
}
#ifdef TFT_DEFAULT_DRIVER
@@ -129,28 +113,16 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
#endif
}
-bool TFT_SPI::isBusy() {
- return false;
-}
+bool TFT_SPI::isBusy() { return false; }
-void TFT_SPI::Abort() {
- DataTransferEnd();
-}
+void TFT_SPI::Abort() { DataTransferEnd(); }
-void TFT_SPI::Transmit(uint16_t Data) {
- SPIx.send(Data);
-}
+void TFT_SPI::Transmit(uint16_t Data) { SPIx.send(Data); }
void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
DataTransferBegin();
- TFT_DC_H;
- if (MemoryIncrease == DMA_MINC_ENABLE) {
- SPIx.dmaSend(Data, Count, true);
- }
- else {
- SPIx.dmaSend(Data, Count, false);
- }
-
+ OUT_WRITE(TFT_DC_PIN, HIGH);
+ SPIx.dmaSend(Data, Count, MemoryIncrease == DMA_MINC_ENABLE);
DataTransferEnd();
}
diff --git a/Marlin/src/HAL/TEENSY31_32/HAL.h b/Marlin/src/HAL/TEENSY31_32/HAL.h
index d4b3c0a772aa0..61d8b34604c52 100644
--- a/Marlin/src/HAL/TEENSY31_32/HAL.h
+++ b/Marlin/src/HAL/TEENSY31_32/HAL.h
@@ -36,9 +36,9 @@
#include
-#define CPU_ST7920_DELAY_1 DELAY_NS(600)
-#define CPU_ST7920_DELAY_2 DELAY_NS(750)
-#define CPU_ST7920_DELAY_3 DELAY_NS(750)
+#define CPU_ST7920_DELAY_1 600
+#define CPU_ST7920_DELAY_2 750
+#define CPU_ST7920_DELAY_3 750
//#undef MOTHERBOARD
//#define MOTHERBOARD BOARD_TEENSY31_32
@@ -98,16 +98,14 @@ void HAL_reboot();
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
+#pragma GCC diagnostic push
#if GCC_VERSION <= 50000
- #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
extern "C" int freeMemory();
-#if GCC_VERSION <= 50000
- #pragma GCC diagnostic pop
-#endif
+#pragma GCC diagnostic pop
// ADC
@@ -124,6 +122,12 @@ void HAL_adc_init();
void HAL_adc_start_conversion(const uint8_t adc_pin);
uint16_t HAL_adc_get_result();
+// PWM
+
+inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
+
+// Pin Map
+
#define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
diff --git a/Marlin/src/HAL/TEENSY31_32/HAL_SPI.cpp b/Marlin/src/HAL/TEENSY31_32/HAL_SPI.cpp
index ff84e91f79d78..415c692229861 100644
--- a/Marlin/src/HAL/TEENSY31_32/HAL_SPI.cpp
+++ b/Marlin/src/HAL/TEENSY31_32/HAL_SPI.cpp
@@ -36,10 +36,9 @@ static SPISettings spiConfig;
// Initialize SPI bus
void spiBegin() {
- #if !PIN_EXISTS(SD_SS)
- #error "SD_SS_PIN not defined!"
+ #if PIN_EXISTS(SD_SS)
+ OUT_WRITE(SD_SS_PIN, HIGH);
#endif
- OUT_WRITE(SD_SS_PIN, HIGH);
SET_OUTPUT(SD_SCK_PIN);
SET_INPUT(SD_MISO_PIN);
SET_OUTPUT(SD_MOSI_PIN);
diff --git a/Marlin/src/HAL/TEENSY31_32/MarlinSPI.h b/Marlin/src/HAL/TEENSY31_32/MarlinSPI.h
new file mode 100644
index 0000000000000..0c447ba4cb3dc
--- /dev/null
+++ b/Marlin/src/HAL/TEENSY31_32/MarlinSPI.h
@@ -0,0 +1,26 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include
+
+using MarlinSPI = SPIClass;
diff --git a/Marlin/src/HAL/TEENSY31_32/eeprom.cpp b/Marlin/src/HAL/TEENSY31_32/eeprom.cpp
index 85febebebc252..d1ff9408229f0 100644
--- a/Marlin/src/HAL/TEENSY31_32/eeprom.cpp
+++ b/Marlin/src/HAL/TEENSY31_32/eeprom.cpp
@@ -2,6 +2,9 @@
* 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
@@ -16,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#ifdef __MK20DX256__
/**
diff --git a/Marlin/src/HAL/TEENSY35_36/HAL.h b/Marlin/src/HAL/TEENSY35_36/HAL.h
index 0b82a569f9046..892eb2d3c5b8f 100644
--- a/Marlin/src/HAL/TEENSY35_36/HAL.h
+++ b/Marlin/src/HAL/TEENSY35_36/HAL.h
@@ -37,9 +37,9 @@
#include
#include
-#define CPU_ST7920_DELAY_1 DELAY_NS(600)
-#define CPU_ST7920_DELAY_2 DELAY_NS(750)
-#define CPU_ST7920_DELAY_3 DELAY_NS(750)
+#define CPU_ST7920_DELAY_1 600
+#define CPU_ST7920_DELAY_2 750
+#define CPU_ST7920_DELAY_3 750
// ------------------------
// Defines
@@ -105,16 +105,14 @@ void HAL_reboot();
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
+#pragma GCC diagnostic push
#if GCC_VERSION <= 50000
- #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
extern "C" int freeMemory();
-#if GCC_VERSION <= 50000
- #pragma GCC diagnostic pop
-#endif
+#pragma GCC diagnostic pop
// ADC
@@ -131,6 +129,12 @@ void HAL_adc_init();
void HAL_adc_start_conversion(const uint8_t adc_pin);
uint16_t HAL_adc_get_result();
+// PWM
+
+inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
+
+// Pin Map
+
#define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
diff --git a/Marlin/src/HAL/TEENSY35_36/HAL_SPI.cpp b/Marlin/src/HAL/TEENSY35_36/HAL_SPI.cpp
index e63ab1c0e3ed9..d80f57b2c4361 100644
--- a/Marlin/src/HAL/TEENSY35_36/HAL_SPI.cpp
+++ b/Marlin/src/HAL/TEENSY35_36/HAL_SPI.cpp
@@ -36,10 +36,9 @@
static SPISettings spiConfig;
void spiBegin() {
- #if !PIN_EXISTS(SD_SS)
- #error "SD_SS_PIN not defined!"
+ #if PIN_EXISTS(SD_SS)
+ OUT_WRITE(SD_SS_PIN, HIGH);
#endif
- OUT_WRITE(SD_SS_PIN, HIGH);
SET_OUTPUT(SD_SCK_PIN);
SET_INPUT(SD_MISO_PIN);
SET_OUTPUT(SD_MOSI_PIN);
diff --git a/Marlin/src/HAL/TEENSY35_36/MarlinSPI.h b/Marlin/src/HAL/TEENSY35_36/MarlinSPI.h
new file mode 100644
index 0000000000000..0c447ba4cb3dc
--- /dev/null
+++ b/Marlin/src/HAL/TEENSY35_36/MarlinSPI.h
@@ -0,0 +1,26 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include
+
+using MarlinSPI = SPIClass;
diff --git a/Marlin/src/HAL/TEENSY35_36/pinsDebug.h b/Marlin/src/HAL/TEENSY35_36/pinsDebug.h
index e529fa93be16a..7a2e1d6e592e5 100644
--- a/Marlin/src/HAL/TEENSY35_36/pinsDebug.h
+++ b/Marlin/src/HAL/TEENSY35_36/pinsDebug.h
@@ -2,6 +2,9 @@
* 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
diff --git a/Marlin/src/HAL/TEENSY40_41/HAL.cpp b/Marlin/src/HAL/TEENSY40_41/HAL.cpp
index ccc8c2659c65f..270bee0dc9d45 100644
--- a/Marlin/src/HAL/TEENSY40_41/HAL.cpp
+++ b/Marlin/src/HAL/TEENSY40_41/HAL.cpp
@@ -106,17 +106,17 @@ void HAL_adc_init() {
void HAL_clear_reset_source() {
uint32_t reset_source = SRC_SRSR;
SRC_SRSR = reset_source;
- }
+}
uint8_t HAL_get_reset_source() {
switch (SRC_SRSR & 0xFF) {
case 1: return RST_POWER_ON; break;
case 2: return RST_SOFTWARE; break;
case 4: return RST_EXTERNAL; break;
- // case 8: return RST_BROWN_OUT; break;
+ //case 8: return RST_BROWN_OUT; break;
case 16: return RST_WATCHDOG; break;
- case 64: return RST_JTAG; break;
- // case 128: return RST_OVERTEMP; break;
+ case 64: return RST_JTAG; break;
+ //case 128: return RST_OVERTEMP; break;
}
return 0;
}
@@ -168,7 +168,7 @@ uint16_t HAL_adc_get_result() {
return 0;
}
-bool is_output(uint8_t pin) {
+bool is_output(pin_t pin) {
const struct digital_pin_bitband_and_config_table_struct *p;
p = digital_pin_to_info_PGM + pin;
return (*(p->reg + 1) & p->mask);
diff --git a/Marlin/src/HAL/TEENSY40_41/HAL.h b/Marlin/src/HAL/TEENSY40_41/HAL.h
index 14f14bf446c70..2b730768a8025 100644
--- a/Marlin/src/HAL/TEENSY40_41/HAL.h
+++ b/Marlin/src/HAL/TEENSY40_41/HAL.h
@@ -41,9 +41,9 @@
#include "../../feature/ethernet.h"
#endif
-#define CPU_ST7920_DELAY_1 DELAY_NS(600)
-#define CPU_ST7920_DELAY_2 DELAY_NS(750)
-#define CPU_ST7920_DELAY_3 DELAY_NS(750)
+#define CPU_ST7920_DELAY_1 600
+#define CPU_ST7920_DELAY_2 750
+#define CPU_ST7920_DELAY_3 750
// ------------------------
// Defines
@@ -125,16 +125,14 @@ void HAL_reboot();
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
+#pragma GCC diagnostic push
#if GCC_VERSION <= 50000
- #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
extern "C" uint32_t freeMemory();
-#if GCC_VERSION <= 50000
- #pragma GCC diagnostic pop
-#endif
+#pragma GCC diagnostic pop
// ADC
@@ -152,8 +150,14 @@ void HAL_adc_init();
void HAL_adc_start_conversion(const uint8_t adc_pin);
uint16_t HAL_adc_get_result();
+// PWM
+
+inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
+
+// Pin Map
+
#define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
-bool is_output(uint8_t pin);
+bool is_output(pin_t pin);
diff --git a/Marlin/src/HAL/TEENSY40_41/HAL_SPI.cpp b/Marlin/src/HAL/TEENSY40_41/HAL_SPI.cpp
index 610765ad49c72..9dcb812faf0cb 100644
--- a/Marlin/src/HAL/TEENSY40_41/HAL_SPI.cpp
+++ b/Marlin/src/HAL/TEENSY40_41/HAL_SPI.cpp
@@ -51,12 +51,9 @@ static SPISettings spiConfig;
// ------------------------
void spiBegin() {
- #ifndef SD_SS_PIN
- #error "SD_SS_PIN is not defined!"
+ #if PIN_EXISTS(SD_SS)
+ OUT_WRITE(SD_SS_PIN, HIGH);
#endif
-
- OUT_WRITE(SD_SS_PIN, HIGH);
-
//SET_OUTPUT(SD_SCK_PIN);
//SET_INPUT(SD_MISO_PIN);
//SET_OUTPUT(SD_MOSI_PIN);
diff --git a/Marlin/src/HAL/TEENSY40_41/MarlinSPI.h b/Marlin/src/HAL/TEENSY40_41/MarlinSPI.h
new file mode 100644
index 0000000000000..0c447ba4cb3dc
--- /dev/null
+++ b/Marlin/src/HAL/TEENSY40_41/MarlinSPI.h
@@ -0,0 +1,26 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include
+
+using MarlinSPI = SPIClass;
diff --git a/Marlin/src/HAL/TEENSY40_41/pinsDebug.h b/Marlin/src/HAL/TEENSY40_41/pinsDebug.h
index 197cc6f1b243d..94b85ea56861a 100644
--- a/Marlin/src/HAL/TEENSY40_41/pinsDebug.h
+++ b/Marlin/src/HAL/TEENSY40_41/pinsDebug.h
@@ -2,6 +2,9 @@
* 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
diff --git a/Marlin/src/HAL/shared/Delay.cpp b/Marlin/src/HAL/shared/Delay.cpp
index 129698fd306d7..c64376d25d9ab 100644
--- a/Marlin/src/HAL/shared/Delay.cpp
+++ b/Marlin/src/HAL/shared/Delay.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "Delay.h"
#include "../../inc/MarlinConfig.h"
@@ -107,59 +108,61 @@
#if ENABLED(MARLIN_DEV_MODE)
void dump_delay_accuracy_check() {
- auto report_call_time = [](PGM_P const name, PGM_P const unit, const uint32_t cycles, const uint32_t total, const bool do_flush=true) {
+ auto report_call_time = [](FSTR_P const name, FSTR_P const unit, const uint32_t cycles, const uint32_t total, const bool do_flush=true) {
SERIAL_ECHOPGM("Calling ");
- SERIAL_ECHOPGM_P(name);
- SERIAL_ECHOLNPAIR(" for ", cycles);
- SERIAL_ECHOPGM_P(unit);
- SERIAL_ECHOLNPAIR(" took: ", total);
- SERIAL_ECHOPGM_P(unit);
+ SERIAL_ECHOF(name);
+ SERIAL_ECHOLNPGM(" for ", cycles);
+ SERIAL_ECHOF(unit);
+ SERIAL_ECHOLNPGM(" took: ", total);
+ SERIAL_CHAR(' ');
+ SERIAL_ECHOF(unit);
if (do_flush) SERIAL_FLUSHTX();
};
uint32_t s, e;
- SERIAL_ECHOLNPAIR("Computed delay calibration value: ", ASM_CYCLES_PER_ITERATION);
+ SERIAL_ECHOLNPGM("Computed delay calibration value: ", ASM_CYCLES_PER_ITERATION);
SERIAL_FLUSH();
// Display the results of the calibration above
constexpr uint32_t testValues[] = { 1, 5, 10, 20, 50, 100, 150, 200, 350, 500, 750, 1000 };
for (auto i : testValues) {
s = micros(); DELAY_US(i); e = micros();
- report_call_time(PSTR("delay"), PSTR("us"), i, e - s);
+ report_call_time(F("delay"), F("us"), i, e - s);
}
if (HW_REG(_DWT_CTRL)) {
+ static FSTR_P cyc = F("cycles");
+ static FSTR_P dcd = F("DELAY_CYCLES directly ");
+
for (auto i : testValues) {
s = HW_REG(_DWT_CYCCNT); DELAY_CYCLES(i); e = HW_REG(_DWT_CYCCNT);
- report_call_time(PSTR("runtime delay"), PSTR("cycles"), i, e - s);
+ report_call_time(F("runtime delay"), cyc, i, e - s);
}
// Measure the delay to call a real function compared to a function pointer
s = HW_REG(_DWT_CYCCNT); delay_dwt(1); e = HW_REG(_DWT_CYCCNT);
- report_call_time(PSTR("delay_dwt"), PSTR("cycles"), 1, e - s);
-
- static PGMSTR(dcd, "DELAY_CYCLES directly ");
+ report_call_time(F("delay_dwt"), cyc, 1, e - s);
s = HW_REG(_DWT_CYCCNT); DELAY_CYCLES( 1); e = HW_REG(_DWT_CYCCNT);
- report_call_time(dcd, PSTR("cycles"), 1, e - s, false);
+ report_call_time(dcd, cyc, 1, e - s, false);
s = HW_REG(_DWT_CYCCNT); DELAY_CYCLES( 5); e = HW_REG(_DWT_CYCCNT);
- report_call_time(dcd, PSTR("cycles"), 5, e - s, false);
+ report_call_time(dcd, cyc, 5, e - s, false);
s = HW_REG(_DWT_CYCCNT); DELAY_CYCLES(10); e = HW_REG(_DWT_CYCCNT);
- report_call_time(dcd, PSTR("cycles"), 10, e - s, false);
+ report_call_time(dcd, cyc, 10, e - s, false);
s = HW_REG(_DWT_CYCCNT); DELAY_CYCLES(20); e = HW_REG(_DWT_CYCCNT);
- report_call_time(dcd, PSTR("cycles"), 20, e - s, false);
+ report_call_time(dcd, cyc, 20, e - s, false);
s = HW_REG(_DWT_CYCCNT); DELAY_CYCLES(50); e = HW_REG(_DWT_CYCCNT);
- report_call_time(dcd, PSTR("cycles"), 50, e - s, false);
+ report_call_time(dcd, cyc, 50, e - s, false);
s = HW_REG(_DWT_CYCCNT); DELAY_CYCLES(100); e = HW_REG(_DWT_CYCCNT);
- report_call_time(dcd, PSTR("cycles"), 100, e - s, false);
+ report_call_time(dcd, cyc, 100, e - s, false);
s = HW_REG(_DWT_CYCCNT); DELAY_CYCLES(200); e = HW_REG(_DWT_CYCCNT);
- report_call_time(dcd, PSTR("cycles"), 200, e - s, false);
+ report_call_time(dcd, cyc, 200, e - s, false);
}
}
#endif // MARLIN_DEV_MODE
@@ -169,7 +172,7 @@
void calibrate_delay_loop() {}
#if ENABLED(MARLIN_DEV_MODE)
- void dump_delay_accuracy_check() { SERIAL_ECHOPGM_P(PSTR("N/A on this platform")); }
+ void dump_delay_accuracy_check() { SERIAL_ECHOPGM("N/A on this platform"); }
#endif
#endif
diff --git a/Marlin/src/HAL/shared/Delay.h b/Marlin/src/HAL/shared/Delay.h
index 04df35d88d6a6..df07881f01d90 100644
--- a/Marlin/src/HAL/shared/Delay.h
+++ b/Marlin/src/HAL/shared/Delay.h
@@ -92,6 +92,12 @@ void calibrate_delay_loop();
#define DELAY_CYCLES(X) do { SmartDelay _smrtdly_X(X); } while(0)
+ #if GCC_VERSION <= 70000
+ #define DELAY_CYCLES_VAR(X) DelayCycleFnc(X)
+ #else
+ #define DELAY_CYCLES_VAR DELAY_CYCLES
+ #endif
+
// For delay in microseconds, no smart delay selection is required, directly call the delay function
// Teensy compiler is too old and does not accept smart delay compile-time / run-time selection correctly
#define DELAY_US(x) DelayCycleFnc((x) * ((F_CPU) / 1000000UL))
@@ -200,9 +206,12 @@ void calibrate_delay_loop();
#endif
#if ENABLED(DELAY_NS_ROUND_DOWN)
- #define DELAY_NS(x) DELAY_CYCLES((x) * ((F_CPU) / 1000000UL) / 1000UL) // floor
+ #define _NS_TO_CYCLES(x) ( (x) * ((F_CPU) / 1000000UL) / 1000UL) // floor
#elif ENABLED(DELAY_NS_ROUND_CLOSEST)
- #define DELAY_NS(x) DELAY_CYCLES(((x) * ((F_CPU) / 1000000UL) + 500) / 1000UL) // round
+ #define _NS_TO_CYCLES(x) (((x) * ((F_CPU) / 1000000UL) + 500) / 1000UL) // round
#else
- #define DELAY_NS(x) DELAY_CYCLES(((x) * ((F_CPU) / 1000000UL) + 999) / 1000UL) // "ceil"
+ #define _NS_TO_CYCLES(x) (((x) * ((F_CPU) / 1000000UL) + 999) / 1000UL) // "ceil"
#endif
+
+#define DELAY_NS(x) DELAY_CYCLES(_NS_TO_CYCLES(x))
+#define DELAY_NS_VAR(x) DELAY_CYCLES_VAR(_NS_TO_CYCLES(x))
diff --git a/Marlin/src/HAL/shared/Marduino.h b/Marlin/src/HAL/shared/Marduino.h
index 56be8d72118fb..0e2a021a3c4e9 100644
--- a/Marlin/src/HAL/shared/Marduino.h
+++ b/Marlin/src/HAL/shared/Marduino.h
@@ -39,7 +39,7 @@
#define DISABLED(V...) DO(DIS,&&,V)
#undef _BV
-#define _BV(b) (1UL << (b))
+#define _BV(b) (1 << (b))
#ifndef SBI
#define SBI(A,B) (A |= _BV(B))
#endif
@@ -83,7 +83,14 @@
#endif
#ifndef FORCE_INLINE
- #define FORCE_INLINE inline __attribute__((always_inline))
+ #define FORCE_INLINE __attribute__((always_inline)) inline
#endif
#include "progmem.h"
+
+class __FlashStringHelper;
+typedef const __FlashStringHelper* FSTR_P;
+#ifndef FPSTR
+ #define FPSTR(S) (reinterpret_cast(S))
+#endif
+#define FTOP(S) (reinterpret_cast(S))
diff --git a/Marlin/src/HAL/shared/progmem.h b/Marlin/src/HAL/shared/progmem.h
index 539d02705e973..4cd7663df9afe 100644
--- a/Marlin/src/HAL/shared/progmem.h
+++ b/Marlin/src/HAL/shared/progmem.h
@@ -38,7 +38,8 @@
#define PSTR(str) (str)
#endif
#ifndef F
-#define F(str) (str)
+class __FlashStringHelper;
+#define F(str) (reinterpret_cast(PSTR(str)))
#endif
#ifndef _SFR_BYTE
#define _SFR_BYTE(n) (n)
@@ -110,7 +111,7 @@
#define strrchr_P(str, c) strrchr((str), (c))
#endif
#ifndef strsep_P
-#define strsep_P(strp, delim) strsep((strp), (delim))
+#define strsep_P(pstr, delim) strsep((pstr), (delim))
#endif
#ifndef strspn_P
#define strspn_P(str, chrs) strspn((str), (chrs))
diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp
index 6d4e0eab9054f..8b6b278f1ff05 100644
--- a/Marlin/src/MarlinCore.cpp
+++ b/Marlin/src/MarlinCore.cpp
@@ -30,10 +30,6 @@
#include "MarlinCore.h"
-#if ENABLED(MARLIN_DEV_MODE)
- #warning "WARNING! Disable MARLIN_DEV_MODE for the final build!"
-#endif
-
#include "HAL/shared/Delay.h"
#include "HAL/shared/esp_wifi.h"
#include "HAL/shared/cpu_exception/exception_hook.h"
@@ -74,13 +70,15 @@
#include
#endif
-#if ENABLED(DWIN_CREALITY_LCD)
- #include "lcd/e3v2/creality/dwin.h"
- #include "lcd/e3v2/creality/rotary_encoder.h"
-#endif
-
-#if ENABLED(EXTENSIBLE_UI)
- #include "lcd/extui/ui_api.h"
+#if HAS_DWIN_E3V2
+ #include "lcd/e3v2/common/encoder.h"
+ #if ENABLED(DWIN_CREALITY_LCD)
+ #include "lcd/e3v2/creality/dwin.h"
+ #elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
+ #include "lcd/e3v2/enhanced/dwin.h"
+ #elif ENABLED(DWIN_CREALITY_LCD_JYERSUI)
+ #include "lcd/e3v2/jyersui/dwin.h"
+ #endif
#endif
#if HAS_ETHERNET
@@ -166,6 +164,8 @@
#if ENABLED(DELTA)
#include "module/delta.h"
+#elif ENABLED(POLARGRAPH)
+ #include "module/polargraph.h"
#elif IS_SCARA
#include "module/scara.h"
#endif
@@ -216,6 +216,10 @@
#include "feature/controllerfan.h"
#endif
+#if HAS_PRUSA_MMU1
+ #include "feature/mmu/mmu.h"
+#endif
+
#if HAS_PRUSA_MMU2
#include "feature/mmu/mmu2.h"
#endif
@@ -308,48 +312,6 @@ bool pin_is_protected(const pin_t pin) {
#pragma GCC diagnostic pop
-void enable_e_steppers() {
- #define _ENA_E(N) ENABLE_AXIS_E##N();
- REPEAT(E_STEPPERS, _ENA_E)
-}
-
-void enable_all_steppers() {
- TERN_(AUTO_POWER_CONTROL, powerManager.power_on());
- ENABLE_AXIS_X();
- ENABLE_AXIS_Y();
- ENABLE_AXIS_Z();
- ENABLE_AXIS_I(); // Marlin 6-axis support by DerAndere (https://github.com/DerAndere1/Marlin/wiki)
- ENABLE_AXIS_J();
- ENABLE_AXIS_K();
- enable_e_steppers();
-
- TERN_(EXTENSIBLE_UI, ExtUI::onSteppersEnabled());
-}
-
-void disable_e_steppers() {
- #define _DIS_E(N) DISABLE_AXIS_E##N();
- REPEAT(E_STEPPERS, _DIS_E)
-}
-
-void disable_e_stepper(const uint8_t e) {
- #define _CASE_DIS_E(N) case N: DISABLE_AXIS_E##N(); break;
- switch (e) {
- REPEAT(E_STEPPERS, _CASE_DIS_E)
- }
-}
-
-void disable_all_steppers() {
- DISABLE_AXIS_X();
- DISABLE_AXIS_Y();
- DISABLE_AXIS_Z();
- DISABLE_AXIS_I();
- DISABLE_AXIS_J();
- DISABLE_AXIS_K();
- disable_e_steppers();
-
- TERN_(EXTENSIBLE_UI, ExtUI::onSteppersDisabled());
-}
-
/**
* A Print Job exists when the timer is running or SD is printing
*/
@@ -399,15 +361,15 @@ void startOrResumeJob() {
TERN_(POWER_LOSS_RECOVERY, recovery.purge());
#ifdef EVENT_GCODE_SD_ABORT
- queue.inject_P(PSTR(EVENT_GCODE_SD_ABORT));
+ queue.inject(F(EVENT_GCODE_SD_ABORT));
#endif
TERN_(PASSWORD_AFTER_SD_PRINT_ABORT, password.lock_machine());
}
inline void finishSDPrinting() {
- if (queue.enqueue_one_P(PSTR("M1001"))) { // Keep trying until it gets queued
- marlin_state = MF_RUNNING; // Signal to stop trying
+ if (queue.enqueue_one(F("M1001"))) { // Keep trying until it gets queued
+ marlin_state = MF_RUNNING; // Signal to stop trying
TERN_(PASSWORD_AFTER_SD_PRINT_END, password.lock_machine());
TERN_(DGUS_LCD_UI_MKS, ScreenHandler.SDPrintingFinished());
}
@@ -460,13 +422,13 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
already_shutdown_steppers = true; // L6470 SPI will consume 99% of free time without this
// Individual axes will be disabled if configured
- if (ENABLED(DISABLE_INACTIVE_X)) DISABLE_AXIS_X();
- if (ENABLED(DISABLE_INACTIVE_Y)) DISABLE_AXIS_Y();
- if (ENABLED(DISABLE_INACTIVE_Z)) DISABLE_AXIS_Z();
- if (ENABLED(DISABLE_INACTIVE_I)) DISABLE_AXIS_I();
- if (ENABLED(DISABLE_INACTIVE_J)) DISABLE_AXIS_J();
- if (ENABLED(DISABLE_INACTIVE_K)) DISABLE_AXIS_K();
- if (ENABLED(DISABLE_INACTIVE_E)) disable_e_steppers();
+ TERN_(DISABLE_INACTIVE_X, stepper.disable_axis(X_AXIS));
+ TERN_(DISABLE_INACTIVE_Y, stepper.disable_axis(Y_AXIS));
+ TERN_(DISABLE_INACTIVE_Z, stepper.disable_axis(Z_AXIS));
+ TERN_(DISABLE_INACTIVE_I, stepper.disable_axis(I_AXIS));
+ TERN_(DISABLE_INACTIVE_J, stepper.disable_axis(J_AXIS));
+ TERN_(DISABLE_INACTIVE_K, stepper.disable_axis(K_AXIS));
+ TERN_(DISABLE_INACTIVE_E, stepper.disable_e_steppers());
TERN_(AUTO_BED_LEVELING_UBL, ubl.steppers_were_disabled());
}
@@ -516,7 +478,7 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
if (!IS_SD_PRINTING() && !READ(HOME_PIN)) { // HOME_PIN goes LOW when pressed
if (ELAPSED(ms, next_home_key_ms)) {
next_home_key_ms = ms + HOME_DEBOUNCE_DELAY;
- LCD_MESSAGEPGM(MSG_AUTO_HOME);
+ LCD_MESSAGE(MSG_AUTO_HOME);
queue.inject_P(G28_STR);
}
}
@@ -535,13 +497,14 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
if (ELAPSED(ms, next_cub_ms_##N)) { \
next_cub_ms_##N = ms + CUB_DEBOUNCE_DELAY_##N; \
CODE; \
- queue.inject_P(PSTR(BUTTON##N##_GCODE)); \
+ queue.inject(F(BUTTON##N##_GCODE)); \
+ TERN_(HAS_LCD_MENU, ui.quick_feedback()); \
} \
} \
}while(0)
- #define CHECK_CUSTOM_USER_BUTTON(N) _CHECK_CUSTOM_USER_BUTTON(N, NOOP)
- #define CHECK_BETTER_USER_BUTTON(N) _CHECK_CUSTOM_USER_BUTTON(N, if (strlen(BUTTON##N##_DESC)) LCD_MESSAGEPGM_P(PSTR(BUTTON##N##_DESC)))
+ #define CHECK_CUSTOM_USER_BUTTON(N) _CHECK_CUSTOM_USER_BUTTON(N, NOOP)
+ #define CHECK_BETTER_USER_BUTTON(N) _CHECK_CUSTOM_USER_BUTTON(N, if (strlen(BUTTON##N##_DESC)) LCD_MESSAGE_F(BUTTON##N##_DESC))
#if HAS_BETTER_USER_BUTTON(1)
CHECK_BETTER_USER_BUTTON(1);
@@ -684,13 +647,13 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
#if ENABLED(SWITCHING_EXTRUDER)
bool oldstatus;
switch (active_extruder) {
- default: oldstatus = E0_ENABLE_READ(); ENABLE_AXIS_E0(); break;
+ default: oldstatus = stepper.AXIS_IS_ENABLED(E_AXIS, 0); stepper.ENABLE_EXTRUDER(0); break;
#if E_STEPPERS > 1
- case 2: case 3: oldstatus = E1_ENABLE_READ(); ENABLE_AXIS_E1(); break;
+ case 2: case 3: oldstatus = stepper.AXIS_IS_ENABLED(E_AXIS, 1); stepper.ENABLE_EXTRUDER(1); break;
#if E_STEPPERS > 2
- case 4: case 5: oldstatus = E2_ENABLE_READ(); ENABLE_AXIS_E2(); break;
+ case 4: case 5: oldstatus = stepper.AXIS_IS_ENABLED(E_AXIS, 2); stepper.ENABLE_EXTRUDER(2); break;
#if E_STEPPERS > 3
- case 6: case 7: oldstatus = E3_ENABLE_READ(); ENABLE_AXIS_E3(); break;
+ case 6: case 7: oldstatus = stepper.AXIS_IS_ENABLED(E_AXIS, 3); stepper.ENABLE_EXTRUDER(3); break;
#endif // E_STEPPERS > 3
#endif // E_STEPPERS > 2
#endif // E_STEPPERS > 1
@@ -699,7 +662,7 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
bool oldstatus;
switch (active_extruder) {
default:
- #define _CASE_EN(N) case N: oldstatus = E##N##_ENABLE_READ(); ENABLE_AXIS_E##N(); break;
+ #define _CASE_EN(N) case N: oldstatus = stepper.AXIS_IS_ENABLED(E_AXIS, N); stepper.ENABLE_EXTRUDER(N); break;
REPEAT(E_STEPPERS, _CASE_EN);
}
#endif
@@ -713,17 +676,17 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
#if ENABLED(SWITCHING_EXTRUDER)
switch (active_extruder) {
- default: oldstatus = E0_ENABLE_WRITE(oldstatus); break;
+ default: if (oldstatus) stepper.ENABLE_EXTRUDER(0); else stepper.DISABLE_EXTRUDER(0); break;
#if E_STEPPERS > 1
- case 2: case 3: oldstatus = E1_ENABLE_WRITE(oldstatus); break;
+ case 2: case 3: if (oldstatus) stepper.ENABLE_EXTRUDER(1); else stepper.DISABLE_EXTRUDER(1); break;
#if E_STEPPERS > 2
- case 4: case 5: oldstatus = E2_ENABLE_WRITE(oldstatus); break;
+ case 4: case 5: if (oldstatus) stepper.ENABLE_EXTRUDER(2); else stepper.DISABLE_EXTRUDER(2); break;
#endif // E_STEPPERS > 2
#endif // E_STEPPERS > 1
}
#else // !SWITCHING_EXTRUDER
switch (active_extruder) {
- #define _CASE_RESTORE(N) case N: E##N##_ENABLE_WRITE(oldstatus); break;
+ #define _CASE_RESTORE(N) case N: if (oldstatus) stepper.ENABLE_EXTRUDER(N); else stepper.DISABLE_EXTRUDER(N); break;
REPEAT(E_STEPPERS, _CASE_RESTORE);
}
#endif // !SWITCHING_EXTRUDER
@@ -792,7 +755,7 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
void idle(bool no_stepper_sleep/*=false*/) {
#if ENABLED(MARLIN_DEV_MODE)
static uint16_t idle_depth = 0;
- if (++idle_depth > 5) SERIAL_ECHOLNPAIR("idle() call depth: ", idle_depth);
+ if (++idle_depth > 5) SERIAL_ECHOLNPGM("idle() call depth: ", idle_depth);
#endif
// Core Marlin activities
@@ -846,7 +809,7 @@ void idle(bool no_stepper_sleep/*=false*/) {
TERN_(USE_BEEPER, buzzer.tick());
// Handle UI input / draw events
- TERN(DWIN_CREALITY_LCD, DWIN_Update(), ui.update());
+ TERN(HAS_DWIN_E3V2_BASIC, DWIN_Update(), ui.update());
// Run i2c Position Encoders
#if ENABLED(I2C_POSITION_ENCODERS)
@@ -893,16 +856,16 @@ void idle(bool no_stepper_sleep/*=false*/) {
* Kill all activity and lock the machine.
* After this the machine will need to be reset.
*/
-void kill(PGM_P const lcd_error/*=nullptr*/, PGM_P const lcd_component/*=nullptr*/, const bool steppers_off/*=false*/) {
+void kill(FSTR_P const lcd_error/*=nullptr*/, FSTR_P const lcd_component/*=nullptr*/, const bool steppers_off/*=false*/) {
thermalManager.disable_all_heaters();
TERN_(HAS_CUTTER, cutter.kill()); // Full cutter shutdown including ISR control
// Echo the LCD message to serial for extra context
- if (lcd_error) { SERIAL_ECHO_START(); SERIAL_ECHOLNPGM_P(lcd_error); }
+ if (lcd_error) { SERIAL_ECHO_START(); SERIAL_ECHOLNF(lcd_error); }
- #if HAS_DISPLAY
- ui.kill_screen(lcd_error ?: GET_TEXT(MSG_KILLED), lcd_component ?: NUL_STR);
+ #if EITHER(HAS_DISPLAY, DWIN_CREALITY_LCD_ENHANCED)
+ ui.kill_screen(lcd_error ?: GET_TEXT_F(MSG_KILLED), lcd_component ?: FPSTR(NUL_STR));
#else
UNUSED(lcd_error); UNUSED(lcd_component);
#endif
@@ -913,7 +876,7 @@ void kill(PGM_P const lcd_error/*=nullptr*/, PGM_P const lcd_component/*=nullptr
SERIAL_ERROR_MSG(STR_ERR_KILLED);
#ifdef ACTION_ON_KILL
- host_action_kill();
+ hostui.kill();
#endif
minkill(steppers_off);
@@ -935,7 +898,7 @@ void minkill(const bool steppers_off/*=false*/) {
TERN_(HAS_CUTTER, cutter.kill()); // Reiterate cutter shutdown
// Power off all steppers (for M112) or just the E steppers
- steppers_off ? disable_all_steppers() : disable_e_steppers();
+ steppers_off ? stepper.disable_all_steppers() : stepper.disable_e_steppers();
TERN_(PSU_CONTROL, powerManager.power_off());
@@ -976,7 +939,7 @@ void stop() {
if (!IsStopped()) {
SERIAL_ERROR_MSG(STR_ERR_STOPPED);
- LCD_MESSAGEPGM(MSG_STOPPED);
+ LCD_MESSAGE(MSG_STOPPED);
safe_delay(350); // allow enough time for messages to get out before stopping
marlin_state = MF_STOPPED;
}
@@ -1141,6 +1104,10 @@ void setup() {
tmc_standby_setup(); // TMC Low Power Standby pins must be set early or they're not usable
+ // Check startup - does nothing if bootloader sets MCUSR to 0
+ const byte mcu = HAL_get_reset_source();
+ HAL_clear_reset_source();
+
#if ENABLED(MARLIN_DEV_MODE)
auto log_current_ms = [&](PGM_P const msg) {
SERIAL_ECHO_START();
@@ -1269,15 +1236,14 @@ void setup() {
SETUP_RUN(esp_wifi_init());
- // Check startup - does nothing if bootloader sets MCUSR to 0
- const byte mcu = HAL_get_reset_source();
+ // Report Reset Reason
if (mcu & RST_POWER_ON) SERIAL_ECHOLNPGM(STR_POWERUP);
if (mcu & RST_EXTERNAL) SERIAL_ECHOLNPGM(STR_EXTERNAL_RESET);
if (mcu & RST_BROWN_OUT) SERIAL_ECHOLNPGM(STR_BROWNOUT_RESET);
if (mcu & RST_WATCHDOG) SERIAL_ECHOLNPGM(STR_WATCHDOG_RESET);
if (mcu & RST_SOFTWARE) SERIAL_ECHOLNPGM(STR_SOFTWARE_RESET);
- HAL_clear_reset_source();
+ // Identify myself as Marlin x.x.x
SERIAL_ECHOLNPGM("Marlin " SHORT_BUILD_VERSION);
#if defined(STRING_DISTRIBUTION_DATE) && defined(STRING_CONFIG_H_AUTHOR)
SERIAL_ECHO_MSG(
@@ -1312,7 +1278,7 @@ void setup() {
// UI must be initialized before EEPROM
// (because EEPROM code calls the UI).
- #if ENABLED(DWIN_CREALITY_LCD)
+ #if HAS_DWIN_E3V2_BASIC
SETUP_RUN(DWIN_Startup());
#else
SETUP_RUN(ui.init());
@@ -1348,7 +1314,7 @@ void setup() {
#endif
#if HAS_TOUCH_BUTTONS
- SETUP_RUN(touch.init());
+ SETUP_RUN(touchBt.init());
#endif
TERN_(HAS_M206_COMMAND, current_position += home_offset); // Init current position based on home_offset
@@ -1562,11 +1528,11 @@ void setup() {
#ifdef STARTUP_COMMANDS
SETUP_LOG("STARTUP_COMMANDS");
- queue.inject_P(PSTR(STARTUP_COMMANDS));
+ queue.inject(F(STARTUP_COMMANDS));
#endif
#if ENABLED(HOST_PROMPT_SUPPORT)
- SETUP_RUN(host_action_prompt_end());
+ SETUP_RUN(hostui.prompt_end());
#endif
#if HAS_TRINAMIC_CONFIG && DISABLED(PSU_DEFAULT_OFF)
@@ -1587,16 +1553,17 @@ void setup() {
SERIAL_ECHO_TERNARY(err, "BL24CXX Check ", "failed", "succeeded", "!\n");
#endif
- #if ENABLED(DWIN_CREALITY_LCD)
+ #if HAS_DWIN_E3V2_BASIC
+ SETUP_LOG("E3V2 Init");
Encoder_Configuration();
HMI_Init();
HMI_SetLanguageCache();
HMI_StartFrame(true);
- DWIN_StatusChanged_P(GET_TEXT(WELCOME_MSG));
+ DWIN_StatusChanged(GET_TEXT_F(WELCOME_MSG));
#endif
- #if HAS_SERVICE_INTERVALS && DISABLED(DWIN_CREALITY_LCD)
- ui.reset_status(true); // Show service messages or keep current status
+ #if HAS_SERVICE_INTERVALS && !HAS_DWIN_E3V2_BASIC
+ SETUP_RUN(ui.reset_status(true)); // Show service messages or keep current status
#endif
#if ENABLED(MAX7219_DEBUG)
@@ -1617,7 +1584,7 @@ void setup() {
#if BOTH(HAS_WIRED_LCD, SHOW_BOOTSCREEN)
const millis_t elapsed = millis() - bootscreen_ms;
#if ENABLED(MARLIN_DEV_MODE)
- SERIAL_ECHOLNPAIR("elapsed=", elapsed);
+ SERIAL_ECHOLNPGM("elapsed=", elapsed);
#endif
SETUP_RUN(ui.bootscreen_completion(elapsed));
#endif
@@ -1627,7 +1594,7 @@ void setup() {
#endif
#if BOTH(HAS_LCD_MENU, TOUCH_SCREEN_CALIBRATION) && EITHER(TFT_CLASSIC_UI, TFT_COLOR_UI)
- ui.check_touch_calibration();
+ SETUP_RUN(ui.check_touch_calibration());
#endif
marlin_state = MF_RUNNING;
diff --git a/Marlin/src/MarlinCore.h b/Marlin/src/MarlinCore.h
index 6147d43f177d6..7063c7e2de389 100644
--- a/Marlin/src/MarlinCore.h
+++ b/Marlin/src/MarlinCore.h
@@ -23,10 +23,6 @@
#include "inc/MarlinConfig.h"
-#ifdef DEBUG_GCODE_PARSER
- #include "gcode/parser.h"
-#endif
-
#include
#include
#include
@@ -42,16 +38,7 @@ inline void idle_no_sleep() { idle(true); }
extern bool G38_did_trigger; // Flag from the ISR to indicate the endstop changed
#endif
-/**
- * The axis order in all axis related arrays is X, Y, Z, E
- */
-void enable_e_steppers();
-void enable_all_steppers();
-void disable_e_stepper(const uint8_t e);
-void disable_e_steppers();
-void disable_all_steppers();
-
-void kill(PGM_P const lcd_error=nullptr, PGM_P const lcd_component=nullptr, const bool steppers_off=false);
+void kill(FSTR_P const lcd_error=nullptr, FSTR_P const lcd_component=nullptr, const bool steppers_off=false);
void minkill(const bool steppers_off=false);
// Global State of the firmware
diff --git a/Marlin/src/core/boards.h b/Marlin/src/core/boards.h
index 6eeed447f7274..789512c4ef717 100644
--- a/Marlin/src/core/boards.h
+++ b/Marlin/src/core/boards.h
@@ -149,10 +149,10 @@
#define BOARD_GT2560_REV_A 1314 // Geeetech GT2560 Rev A
#define BOARD_GT2560_REV_A_PLUS 1315 // Geeetech GT2560 Rev A+ (with auto level probe)
#define BOARD_GT2560_REV_B 1316 // Geeetech GT2560 Rev B
-#define BOARD_GT2560_V3 1317 // Geeetech GT2560 Rev B for A10(M/D)
-#define BOARD_GT2560_V4 1318 // Geeetech GT2560 Rev B for A10(M/D)
+#define BOARD_GT2560_V3 1317 // Geeetech GT2560 Rev B for A10(M/T/D)
+#define BOARD_GT2560_V4 1318 // Geeetech GT2560 Rev B for A10(M/T/D)
#define BOARD_GT2560_V3_MC2 1319 // Geeetech GT2560 Rev B for Mecreator2
-#define BOARD_GT2560_V3_A20 1320 // Geeetech GT2560 Rev B for A20(M/D)
+#define BOARD_GT2560_V3_A20 1320 // Geeetech GT2560 Rev B for A20(M/T/D)
#define BOARD_EINSTART_S 1321 // Einstart retrofit
#define BOARD_WANHAO_ONEPLUS 1322 // Wanhao 0ne+ i3 Mini
#define BOARD_LEAPFROG_XEED2015 1323 // Leapfrog Xeed 2015
@@ -160,6 +160,8 @@
#define BOARD_PICA 1325 // PICA Shield (rev C or later)
#define BOARD_INTAMSYS40 1326 // Intamsys 4.0 (Funmat HT)
#define BOARD_MALYAN_M180 1327 // Malyan M180 Mainboard Version 2 (no display function, direct gcode only)
+#define BOARD_GT2560_V4_A20 1328 // Geeetech GT2560 Rev B for A20(M/T/D)
+#define BOARD_PROTONEER_CNC_SHIELD_V3 1329 // Mega controller & Protoneer CNC Shield V3.00
//
// ATmega1281, ATmega2561
@@ -338,17 +340,23 @@
#define BOARD_CREALITY_V427 4040 // Creality v4.2.7 (STM32F103RE)
#define BOARD_CREALITY_V4210 4041 // Creality v4.2.10 (STM32F103RE) as found in the CR-30
#define BOARD_CREALITY_V431 4042 // Creality v4.3.1 (STM32F103RE)
-#define BOARD_CREALITY_V452 4043 // Creality v4.5.2 (STM32F103RE)
-#define BOARD_CREALITY_V453 4044 // Creality v4.5.3 (STM32F103RE)
-#define BOARD_TRIGORILLA_PRO 4045 // Trigorilla Pro (STM32F103ZET6)
-#define BOARD_FLY_MINI 4046 // FLYmaker FLY MINI (STM32F103RCT6)
-#define BOARD_FLSUN_HISPEED 4047 // FLSUN HiSpeedV1 (STM32F103VET6)
-#define BOARD_BEAST 4048 // STM32F103RET6 Libmaple-based controller
-#define BOARD_MINGDA_MPX_ARM_MINI 4049 // STM32F103ZET6 Mingda MD-16
-#define BOARD_GTM32_PRO_VD 4050 // STM32F103VET6 controller
-#define BOARD_ZONESTAR_ZM3E2 4051 // Zonestar ZM3E2 (STM32F103RCT6)
-#define BOARD_ZONESTAR_ZM3E4 4052 // Zonestar ZM3E4 V1 (STM32F103VCT6)
-#define BOARD_ZONESTAR_ZM3E4V2 4053 // Zonestar ZM3E4 V2 (STM32F103VCT6)
+#define BOARD_CREALITY_V431_A 4043 // Creality v4.3.1a (STM32F103RE)
+#define BOARD_CREALITY_V431_B 4044 // Creality v4.3.1b (STM32F103RE)
+#define BOARD_CREALITY_V431_C 4045 // Creality v4.3.1c (STM32F103RE)
+#define BOARD_CREALITY_V431_D 4046 // Creality v4.3.1d (STM32F103RE)
+#define BOARD_CREALITY_V452 4047 // Creality v4.5.2 (STM32F103RE)
+#define BOARD_CREALITY_V453 4048 // Creality v4.5.3 (STM32F103RE)
+#define BOARD_CREALITY_V24S1 4049 // Creality v2.4.S1 (STM32F103RE) v101 as found in the Ender 7
+#define BOARD_TRIGORILLA_PRO 4050 // Trigorilla Pro (STM32F103ZET6)
+#define BOARD_FLY_MINI 4051 // FLYmaker FLY MINI (STM32F103RCT6)
+#define BOARD_FLSUN_HISPEED 4052 // FLSUN HiSpeedV1 (STM32F103VET6)
+#define BOARD_BEAST 4053 // STM32F103RET6 Libmaple-based controller
+#define BOARD_MINGDA_MPX_ARM_MINI 4054 // STM32F103ZET6 Mingda MD-16
+#define BOARD_GTM32_PRO_VD 4055 // STM32F103VET6 controller
+#define BOARD_ZONESTAR_ZM3E2 4056 // Zonestar ZM3E2 (STM32F103RCT6)
+#define BOARD_ZONESTAR_ZM3E4 4057 // Zonestar ZM3E4 V1 (STM32F103VCT6)
+#define BOARD_ZONESTAR_ZM3E4V2 4058 // Zonestar ZM3E4 V2 (STM32F103VCT6)
+#define BOARD_ERYONE_ERY32_MINI 4059 // Eryone Ery32 mini (STM32F103VET6)
//
// ARM Cortex-M4F
@@ -378,22 +386,27 @@
#define BOARD_BTT_GTR_V1_0 4214 // BigTreeTech GTR v1.0 (STM32F407IGT)
#define BOARD_BTT_OCTOPUS_V1_0 4215 // BigTreeTech Octopus v1.0 (STM32F446ZET6)
#define BOARD_BTT_OCTOPUS_V1_1 4216 // BigTreeTech Octopus v1.1 (STM32F446ZET6)
-#define BOARD_LERDGE_K 4217 // Lerdge K (STM32F407ZG)
-#define BOARD_LERDGE_S 4218 // Lerdge S (STM32F407VE)
-#define BOARD_LERDGE_X 4219 // Lerdge X (STM32F407VE)
-#define BOARD_VAKE403D 4220 // VAkE 403D (STM32F446VET6)
-#define BOARD_FYSETC_S6 4221 // FYSETC S6 (STM32F446VET6)
-#define BOARD_FYSETC_S6_V2_0 4222 // FYSETC S6 v2.0 (STM32F446VET6)
-#define BOARD_FYSETC_SPIDER 4223 // FYSETC Spider (STM32F446VET6)
-#define BOARD_FLYF407ZG 4224 // FLYmaker FLYF407ZG (STM32F407ZG)
-#define BOARD_MKS_ROBIN2 4225 // MKS_ROBIN2 (STM32F407ZE)
-#define BOARD_MKS_ROBIN_PRO_V2 4226 // MKS Robin Pro V2 (STM32F407VE)
-#define BOARD_MKS_ROBIN_NANO_V3 4227 // MKS Robin Nano V3 (STM32F407VG)
-#define BOARD_MKS_MONSTER8 4228 // MKS Monster8 (STM32F407VGT6)
-#define BOARD_ANET_ET4 4229 // ANET ET4 V1.x (STM32F407VGT6)
-#define BOARD_ANET_ET4P 4230 // ANET ET4P V1.x (STM32F407VGT6)
-#define BOARD_FYSETC_CHEETAH_V20 4231 // FYSETC Cheetah V2.0
-#define BOARD_TH3D_EZBOARD_LITE_V2 4232 // TH3D EZBoard Lite v2.0
+#define BOARD_BTT_OCTOPUS_PRO_V1_0 4217 // BigTreeTech Octopus Pro v1.0 (STM32F446ZET6/STM32F429ZGT6)
+#define BOARD_LERDGE_K 4218 // Lerdge K (STM32F407ZG)
+#define BOARD_LERDGE_S 4219 // Lerdge S (STM32F407VE)
+#define BOARD_LERDGE_X 4220 // Lerdge X (STM32F407VE)
+#define BOARD_VAKE403D 4221 // VAkE 403D (STM32F446VET6)
+#define BOARD_FYSETC_S6 4222 // FYSETC S6 (STM32F446VET6)
+#define BOARD_FYSETC_S6_V2_0 4223 // FYSETC S6 v2.0 (STM32F446VET6)
+#define BOARD_FYSETC_SPIDER 4224 // FYSETC Spider (STM32F446VET6)
+#define BOARD_FLYF407ZG 4225 // FLYmaker FLYF407ZG (STM32F407ZG)
+#define BOARD_MKS_ROBIN2 4226 // MKS_ROBIN2 (STM32F407ZE)
+#define BOARD_MKS_ROBIN_PRO_V2 4227 // MKS Robin Pro V2 (STM32F407VE)
+#define BOARD_MKS_ROBIN_NANO_V3 4228 // MKS Robin Nano V3 (STM32F407VG)
+#define BOARD_MKS_MONSTER8 4229 // MKS Monster8 (STM32F407VGT6)
+#define BOARD_ANET_ET4 4230 // ANET ET4 V1.x (STM32F407VGT6)
+#define BOARD_ANET_ET4P 4231 // ANET ET4P V1.x (STM32F407VGT6)
+#define BOARD_FYSETC_CHEETAH_V20 4232 // FYSETC Cheetah V2.0
+#define BOARD_TH3D_EZBOARD_V2 4233 // TH3D EZBoard v2.0
+#define BOARD_INDEX_REV03 4234 // Index PnP Controller REV03 (STM32F407VET6/VGT6)
+#define BOARD_MKS_ROBIN_NANO_V1_3_F4 4235 // MKS Robin Nano V1.3 and MKS Robin Nano-S V1.3 (STM32F407VET6)
+#define BOARD_MKS_EAGLE 4236 // MKS Eagle (STM32F407VET6)
+#define BOARD_ARTILLERY_RUBY 4237 // Artillery Ruby (STM32F401RCT6)
//
// ARM Cortex M7
@@ -413,7 +426,10 @@
#define BOARD_MRR_ESPA 6001 // MRR ESPA based on ESP32 (native pins only)
#define BOARD_MRR_ESPE 6002 // MRR ESPE based on ESP32 (with I2S stepper stream)
#define BOARD_E4D_BOX 6003 // E4d@BOX
-#define BOARD_FYSETC_E4 6004 // FYSETC E4
+#define BOARD_RESP32_CUSTOM 6004 // Rutilea ESP32 custom board
+#define BOARD_FYSETC_E4 6005 // FYSETC E4
+#define BOARD_PANDA_ZHU 6006 // Panda_ZHU
+#define BOARD_PANDA_M4 6007 // Panda_M4
//
// SAMD51 ARM Cortex M4
diff --git a/Marlin/src/core/bug_on.h b/Marlin/src/core/bug_on.h
index cc745f259b7b9..7f1243ed40b6f 100644
--- a/Marlin/src/core/bug_on.h
+++ b/Marlin/src/core/bug_on.h
@@ -20,19 +20,19 @@
*/
#pragma once
-// We need SERIAL_ECHOPAIR and macros.h
+// We need SERIAL_ECHOPGM and macros.h
#include "serial.h"
#if ENABLED(POSTMORTEM_DEBUGGING)
// Useful macro for stopping the CPU on an unexpected condition
- // This is used like SERIAL_ECHOPAIR, that is: a key-value call of the local variables you want
+ // This is used like SERIAL_ECHOPGM, that is: a key-value call of the local variables you want
// to dump to the serial port before stopping the CPU.
- // \/ Don't replace by SERIAL_ECHOPAIR since ONLY_FILENAME cannot be transformed to a PGM string on Arduino and it breaks building
- #define BUG_ON(V...) do { SERIAL_ECHO(ONLY_FILENAME); SERIAL_ECHO(__LINE__); SERIAL_ECHOLNPGM(": "); SERIAL_ECHOLNPAIR(V); SERIAL_FLUSHTX(); *(char*)0 = 42; } while(0)
+ // \/ Don't replace by SERIAL_ECHOPGM since ONLY_FILENAME cannot be transformed to a PGM string on Arduino and it breaks building
+ #define BUG_ON(V...) do { SERIAL_ECHO(ONLY_FILENAME); SERIAL_ECHO(__LINE__); SERIAL_ECHOLNPGM(": "); SERIAL_ECHOLNPGM(V); SERIAL_FLUSHTX(); *(char*)0 = 42; } while(0)
#elif ENABLED(MARLIN_DEV_MODE)
// Don't stop the CPU here, but at least dump the bug on the serial port
- // \/ Don't replace by SERIAL_ECHOPAIR since ONLY_FILENAME cannot be transformed to a PGM string on Arduino and it breaks building
- #define BUG_ON(V...) do { SERIAL_ECHO(ONLY_FILENAME); SERIAL_ECHO(__LINE__); SERIAL_ECHOLNPGM(": BUG!"); SERIAL_ECHOLNPAIR(V); SERIAL_FLUSHTX(); } while(0)
+ // \/ Don't replace by SERIAL_ECHOPGM since ONLY_FILENAME cannot be transformed to a PGM string on Arduino and it breaks building
+ #define BUG_ON(V...) do { SERIAL_ECHO(ONLY_FILENAME); SERIAL_ECHO(__LINE__); SERIAL_ECHOLNPGM(": BUG!"); SERIAL_ECHOLNPGM(V); SERIAL_FLUSHTX(); } while(0)
#else
// Release mode, let's ignore the bug
#define BUG_ON(V...) NOOP
diff --git a/Marlin/src/core/debug_out.h b/Marlin/src/core/debug_out.h
index a7dc32622d1ed..eb1c91e507865 100644
--- a/Marlin/src/core/debug_out.h
+++ b/Marlin/src/core/debug_out.h
@@ -27,7 +27,6 @@
//
#undef DEBUG_SECTION
-#undef DEBUG_ECHOPGM_P
#undef DEBUG_ECHO_START
#undef DEBUG_ERROR_START
#undef DEBUG_CHAR
@@ -37,12 +36,12 @@
#undef DEBUG_ECHOLN
#undef DEBUG_ECHOPGM
#undef DEBUG_ECHOLNPGM
-#undef DEBUG_ECHOPAIR
-#undef DEBUG_ECHOPAIR_P
+#undef DEBUG_ECHOF
+#undef DEBUG_ECHOLNF
+#undef DEBUG_ECHOPGM_P
+#undef DEBUG_ECHOLNPGM_P
#undef DEBUG_ECHOPAIR_F
#undef DEBUG_ECHOPAIR_F_P
-#undef DEBUG_ECHOLNPAIR
-#undef DEBUG_ECHOLNPAIR_P
#undef DEBUG_ECHOLNPAIR_F
#undef DEBUG_ECHOLNPAIR_F_P
#undef DEBUG_ECHO_MSG
@@ -57,9 +56,8 @@
#if DEBUG_OUT
#include "debug_section.h"
- #define DEBUG_SECTION(N,S,D) SectionLog N(PSTR(S),D)
+ #define DEBUG_SECTION(N,S,D) SectionLog N(F(S),D)
- #define DEBUG_ECHOPGM_P(P) SERIAL_ECHOPGM_P(P)
#define DEBUG_ECHO_START SERIAL_ECHO_START
#define DEBUG_ERROR_START SERIAL_ERROR_START
#define DEBUG_CHAR SERIAL_CHAR
@@ -69,12 +67,14 @@
#define DEBUG_ECHOLN SERIAL_ECHOLN
#define DEBUG_ECHOPGM SERIAL_ECHOPGM
#define DEBUG_ECHOLNPGM SERIAL_ECHOLNPGM
- #define DEBUG_ECHOPAIR SERIAL_ECHOPAIR
- #define DEBUG_ECHOPAIR_P SERIAL_ECHOPAIR_P
+ #define DEBUG_ECHOF SERIAL_ECHOF
+ #define DEBUG_ECHOLNF SERIAL_ECHOLNF
+ #define DEBUG_ECHOPGM SERIAL_ECHOPGM
+ #define DEBUG_ECHOPGM_P SERIAL_ECHOPGM_P
#define DEBUG_ECHOPAIR_F SERIAL_ECHOPAIR_F
#define DEBUG_ECHOPAIR_F_P SERIAL_ECHOPAIR_F_P
- #define DEBUG_ECHOLNPAIR SERIAL_ECHOLNPAIR
- #define DEBUG_ECHOLNPAIR_P SERIAL_ECHOLNPAIR_P
+ #define DEBUG_ECHOLNPGM SERIAL_ECHOLNPGM
+ #define DEBUG_ECHOLNPGM_P SERIAL_ECHOLNPGM_P
#define DEBUG_ECHOLNPAIR_F SERIAL_ECHOLNPAIR_F
#define DEBUG_ECHOLNPAIR_F_P SERIAL_ECHOLNPAIR_F_P
#define DEBUG_ECHO_MSG SERIAL_ECHO_MSG
@@ -89,7 +89,6 @@
#else
#define DEBUG_SECTION(...) NOOP
- #define DEBUG_ECHOPGM_P(P) NOOP
#define DEBUG_ECHO_START() NOOP
#define DEBUG_ERROR_START() NOOP
#define DEBUG_CHAR(...) NOOP
@@ -99,12 +98,12 @@
#define DEBUG_ECHOLN(...) NOOP
#define DEBUG_ECHOPGM(...) NOOP
#define DEBUG_ECHOLNPGM(...) NOOP
- #define DEBUG_ECHOPAIR(...) NOOP
- #define DEBUG_ECHOPAIR_P(...) NOOP
+ #define DEBUG_ECHOF(...) NOOP
+ #define DEBUG_ECHOLNF(...) NOOP
+ #define DEBUG_ECHOPGM_P(...) NOOP
+ #define DEBUG_ECHOLNPGM_P(...) NOOP
#define DEBUG_ECHOPAIR_F(...) NOOP
#define DEBUG_ECHOPAIR_F_P(...) NOOP
- #define DEBUG_ECHOLNPAIR(...) NOOP
- #define DEBUG_ECHOLNPAIR_P(...) NOOP
#define DEBUG_ECHOLNPAIR_F(...) NOOP
#define DEBUG_ECHOLNPAIR_F_P(...) NOOP
#define DEBUG_ECHO_MSG(...) NOOP
diff --git a/Marlin/src/core/debug_section.h b/Marlin/src/core/debug_section.h
index ef1511e6f082a..6e23d9e4edb6c 100644
--- a/Marlin/src/core/debug_section.h
+++ b/Marlin/src/core/debug_section.h
@@ -26,22 +26,22 @@
class SectionLog {
public:
- SectionLog(PGM_P const msg=nullptr, bool inbug=true) {
- the_msg = msg;
- if ((debug = inbug)) echo_msg(PSTR(">>>"));
+ SectionLog(FSTR_P const fmsg=nullptr, bool inbug=true) {
+ the_msg = fmsg;
+ if ((debug = inbug)) echo_msg(F(">>>"));
}
- ~SectionLog() { if (debug) echo_msg(PSTR("<<<")); }
+ ~SectionLog() { if (debug) echo_msg(F("<<<")); }
private:
- PGM_P the_msg;
+ FSTR_P the_msg;
bool debug;
- void echo_msg(PGM_P const pre) {
- SERIAL_ECHOPGM_P(pre);
+ void echo_msg(FSTR_P const fpre) {
+ SERIAL_ECHOF(fpre);
if (the_msg) {
SERIAL_CHAR(' ');
- SERIAL_ECHOPGM_P(the_msg);
+ SERIAL_ECHOF(the_msg);
}
SERIAL_CHAR(' ');
print_pos(current_position);
diff --git a/Marlin/src/core/language.h b/Marlin/src/core/language.h
index 8de8397593221..03bffb8bd9ad4 100644
--- a/Marlin/src/core/language.h
+++ b/Marlin/src/core/language.h
@@ -48,8 +48,8 @@
// cz Czech
// da Danish
// de German
-// el Greek
-// el_gr Greek (Greece)
+// el Greek (Greece)
+// el_CY Greek (Cyprus)
// en English
// es Spanish
// eu Basque-Euskera
@@ -158,15 +158,14 @@
#define STR_OFF "OFF"
#define STR_ENDSTOP_HIT "TRIGGERED"
#define STR_ENDSTOP_OPEN "open"
-#define STR_HOTEND_OFFSET "Hotend offsets:"
#define STR_DUPLICATION_MODE "Duplication mode: "
-#define STR_SOFT_ENDSTOPS "Soft endstops: "
#define STR_SOFT_MIN " Min: "
#define STR_SOFT_MAX " Max: "
#define STR_SAVED_POS "Position saved"
#define STR_RESTORING_POS "Restoring position"
#define STR_INVALID_POS_SLOT "Invalid slot. Total: "
+#define STR_DONE "Done."
#define STR_SD_CANT_OPEN_SUBDIR "Cannot open subdir "
#define STR_SD_INIT_FAIL "No SD card"
@@ -262,6 +261,50 @@
#define STR_REMINDER_SAVE_SETTINGS "Remember to save!"
#define STR_PASSWORD_SET "Password is "
+// Settings Report Strings
+#define STR_Z_AUTO_ALIGN "Z Auto-Align"
+#define STR_BACKLASH_COMPENSATION "Backlash compensation"
+#define STR_S_SEG_PER_SEC "S"
+#define STR_DELTA_SETTINGS "Delta (L R H S XYZ ABC)"
+#define STR_SCARA_SETTINGS "SCARA"
+#define STR_POLARGRAPH_SETTINGS "Polargraph"
+#define STR_SCARA_P_T_Z "P T Z"
+#define STR_ENDSTOP_ADJUSTMENT "Endstop adjustment"
+#define STR_SKEW_FACTOR "Skew Factor"
+#define STR_FILAMENT_SETTINGS "Filament settings"
+#define STR_MAX_ACCELERATION "Max Acceleration (units/s2)"
+#define STR_MAX_FEEDRATES "Max feedrates (units/s)"
+#define STR_ACCELERATION_P_R_T "Acceleration (units/s2) (P R T)"
+#define STR_TOOL_CHANGING "Tool-changing"
+#define STR_HOTEND_OFFSETS "Hotend offsets"
+#define STR_SERVO_ANGLES "Servo Angles"
+#define STR_HOTEND_PID "Hotend PID"
+#define STR_BED_PID "Bed PID"
+#define STR_CHAMBER_PID "Chamber PID"
+#define STR_STEPS_PER_UNIT "Steps per unit"
+#define STR_LINEAR_ADVANCE "Linear Advance"
+#define STR_CONTROLLER_FAN "Controller Fan"
+#define STR_STEPPER_MOTOR_CURRENTS "Stepper motor currents"
+#define STR_RETRACT_S_F_Z "Retract (S F Z)"
+#define STR_RECOVER_S_F "Recover (S F)"
+#define STR_AUTO_RETRACT_S "Auto-Retract (S)"
+#define STR_FILAMENT_LOAD_UNLOAD "Filament load/unload"
+#define STR_POWER_LOSS_RECOVERY "Power-loss recovery"
+#define STR_FILAMENT_RUNOUT_SENSOR "Filament runout sensor"
+#define STR_DRIVER_STEPPING_MODE "Driver stepping mode"
+#define STR_STEPPER_DRIVER_CURRENT "Stepper driver current"
+#define STR_HYBRID_THRESHOLD "Hybrid Threshold"
+#define STR_STALLGUARD_THRESHOLD "StallGuard threshold"
+#define STR_HOME_OFFSET "Home offset"
+#define STR_SOFT_ENDSTOPS "Soft endstops"
+#define STR_MATERIAL_HEATUP "Material heatup parameters"
+#define STR_LCD_CONTRAST "LCD Contrast"
+#define STR_LCD_BRIGHTNESS "LCD Brightness"
+#define STR_UI_LANGUAGE "UI Language"
+#define STR_Z_PROBE_OFFSET "Z-Probe Offset"
+#define STR_TEMPERATURE_UNITS "Temperature Units"
+#define STR_USER_THERMISTORS "User thermistors"
+
//
// Endstop Names used by Endstops::report_states
//
@@ -290,7 +333,7 @@
#define STR_Z_PROBE "z_probe"
#define STR_PROBE_EN "probe_en"
-#define STR_FILAMENT_RUNOUT_SENSOR "filament"
+#define STR_FILAMENT "filament"
// General axis names
#define STR_X "X"
diff --git a/Marlin/src/core/macros.h b/Marlin/src/core/macros.h
index 86368bf5e7181..62675d1319721 100644
--- a/Marlin/src/core/macros.h
+++ b/Marlin/src/core/macros.h
@@ -33,32 +33,38 @@
#define _AXIS(A) (A##_AXIS)
-#define _XMIN_ 100
-#define _YMIN_ 200
-#define _ZMIN_ 300
-#define _IMIN_ 500
-#define _JMIN_ 600
-#define _KMIN_ 700
-#define _XMAX_ 101
-#define _YMAX_ 201
-#define _ZMAX_ 301
-#define _IMAX_ 501
-#define _JMAX_ 601
-#define _KMAX_ 701
-#define _XDIAG_ 102
-#define _YDIAG_ 202
-#define _ZDIAG_ 302
-#define _IDIAG_ 502
-#define _JDIAG_ 602
-#define _KDIAG_ 702
-#define _E0DIAG_ 400
-#define _E1DIAG_ 401
-#define _E2DIAG_ 402
-#define _E3DIAG_ 403
-#define _E4DIAG_ 404
-#define _E5DIAG_ 405
-#define _E6DIAG_ 406
-#define _E7DIAG_ 407
+#define _XSTOP_ 0x01
+#define _YSTOP_ 0x02
+#define _ZSTOP_ 0x03
+#define _ISTOP_ 0x04
+#define _JSTOP_ 0x05
+#define _KSTOP_ 0x06
+#define _XMIN_ 0x11
+#define _YMIN_ 0x12
+#define _ZMIN_ 0x13
+#define _IMIN_ 0x14
+#define _JMIN_ 0x15
+#define _KMIN_ 0x16
+#define _XMAX_ 0x21
+#define _YMAX_ 0x22
+#define _ZMAX_ 0x23
+#define _IMAX_ 0x24
+#define _JMAX_ 0x25
+#define _KMAX_ 0x26
+#define _XDIAG_ 0x31
+#define _YDIAG_ 0x32
+#define _ZDIAG_ 0x33
+#define _IDIAG_ 0x34
+#define _JDIAG_ 0x35
+#define _KDIAG_ 0x36
+#define _E0DIAG_ 0xE0
+#define _E1DIAG_ 0xE1
+#define _E2DIAG_ 0xE2
+#define _E3DIAG_ 0xE3
+#define _E4DIAG_ 0xE4
+#define _E5DIAG_ 0xE5
+#define _E6DIAG_ 0xE6
+#define _E7DIAG_ 0xE7
#define _FORCE_INLINE_ __attribute__((__always_inline__)) __inline__
#define FORCE_INLINE __attribute__((always_inline)) inline
@@ -160,7 +166,7 @@
#endif
-// Macros to chain up to 14 conditions
+// Macros to chain up to 40 conditions
#define _DO_1(W,C,A) (_##W##_1(A))
#define _DO_2(W,C,A,B) (_##W##_1(A) C _##W##_1(B))
#define _DO_3(W,C,A,V...) (_##W##_1(A) C _DO_2(W,C,V))
@@ -176,6 +182,31 @@
#define _DO_13(W,C,A,V...) (_##W##_1(A) C _DO_12(W,C,V))
#define _DO_14(W,C,A,V...) (_##W##_1(A) C _DO_13(W,C,V))
#define _DO_15(W,C,A,V...) (_##W##_1(A) C _DO_14(W,C,V))
+#define _DO_16(W,C,A,V...) (_##W##_1(A) C _DO_15(W,C,V))
+#define _DO_17(W,C,A,V...) (_##W##_1(A) C _DO_16(W,C,V))
+#define _DO_18(W,C,A,V...) (_##W##_1(A) C _DO_17(W,C,V))
+#define _DO_19(W,C,A,V...) (_##W##_1(A) C _DO_18(W,C,V))
+#define _DO_20(W,C,A,V...) (_##W##_1(A) C _DO_19(W,C,V))
+#define _DO_21(W,C,A,V...) (_##W##_1(A) C _DO_20(W,C,V))
+#define _DO_22(W,C,A,V...) (_##W##_1(A) C _DO_21(W,C,V))
+#define _DO_23(W,C,A,V...) (_##W##_1(A) C _DO_22(W,C,V))
+#define _DO_24(W,C,A,V...) (_##W##_1(A) C _DO_23(W,C,V))
+#define _DO_25(W,C,A,V...) (_##W##_1(A) C _DO_24(W,C,V))
+#define _DO_26(W,C,A,V...) (_##W##_1(A) C _DO_25(W,C,V))
+#define _DO_27(W,C,A,V...) (_##W##_1(A) C _DO_26(W,C,V))
+#define _DO_28(W,C,A,V...) (_##W##_1(A) C _DO_27(W,C,V))
+#define _DO_29(W,C,A,V...) (_##W##_1(A) C _DO_28(W,C,V))
+#define _DO_30(W,C,A,V...) (_##W##_1(A) C _DO_29(W,C,V))
+#define _DO_31(W,C,A,V...) (_##W##_1(A) C _DO_30(W,C,V))
+#define _DO_32(W,C,A,V...) (_##W##_1(A) C _DO_31(W,C,V))
+#define _DO_33(W,C,A,V...) (_##W##_1(A) C _DO_32(W,C,V))
+#define _DO_34(W,C,A,V...) (_##W##_1(A) C _DO_33(W,C,V))
+#define _DO_35(W,C,A,V...) (_##W##_1(A) C _DO_34(W,C,V))
+#define _DO_36(W,C,A,V...) (_##W##_1(A) C _DO_35(W,C,V))
+#define _DO_37(W,C,A,V...) (_##W##_1(A) C _DO_36(W,C,V))
+#define _DO_38(W,C,A,V...) (_##W##_1(A) C _DO_37(W,C,V))
+#define _DO_39(W,C,A,V...) (_##W##_1(A) C _DO_38(W,C,V))
+#define _DO_40(W,C,A,V...) (_##W##_1(A) C _DO_39(W,C,V))
#define __DO_N(W,C,N,V...) _DO_##N(W,C,V)
#define _DO_N(W,C,N,V...) __DO_N(W,C,N,V)
#define DO(W,C,V...) (_DO_N(W,C,NUM_ARGS(V),V))
@@ -251,6 +282,13 @@
memcpy(&a[0],&b[0],_MIN(sizeof(a),sizeof(b))); \
}while(0)
+#define CODE_16( A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,...) A; B; C; D; E; F; G; H; I; J; K; L; M; N; O; P
+#define CODE_15( A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,...) A; B; C; D; E; F; G; H; I; J; K; L; M; N; O
+#define CODE_14( A,B,C,D,E,F,G,H,I,J,K,L,M,N,...) A; B; C; D; E; F; G; H; I; J; K; L; M; N
+#define CODE_13( A,B,C,D,E,F,G,H,I,J,K,L,M,...) A; B; C; D; E; F; G; H; I; J; K; L; M
+#define CODE_12( A,B,C,D,E,F,G,H,I,J,K,L,...) A; B; C; D; E; F; G; H; I; J; K; L
+#define CODE_11( A,B,C,D,E,F,G,H,I,J,K,...) A; B; C; D; E; F; G; H; I; J; K
+#define CODE_10( A,B,C,D,E,F,G,H,I,J,...) A; B; C; D; E; F; G; H; I; J
#define CODE_9( A,B,C,D,E,F,G,H,I,...) A; B; C; D; E; F; G; H; I
#define CODE_8( A,B,C,D,E,F,G,H,...) A; B; C; D; E; F; G; H
#define CODE_7( A,B,C,D,E,F,G,...) A; B; C; D; E; F; G
@@ -260,6 +298,7 @@
#define CODE_3( A,B,C,...) A; B; C
#define CODE_2( A,B,...) A; B
#define CODE_1( A,...) A
+#define CODE_0(...)
#define _CODE_N(N,V...) CODE_##N(V)
#define CODE_N(N,V...) _CODE_N(N,V)
@@ -279,11 +318,16 @@
#define GANG_3( A,B,C,...) A B C
#define GANG_2( A,B,...) A B
#define GANG_1( A,...) A
+#define GANG_0(...)
#define _GANG_N(N,V...) GANG_##N(V)
#define GANG_N(N,V...) _GANG_N(N,V)
#define GANG_N_1(N,K) _GANG_N(N,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K)
// Macros for initializing arrays
+#define LIST_20(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T
+#define LIST_19(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S
+#define LIST_18(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R
+#define LIST_17(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q
#define LIST_16(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P
#define LIST_15(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O
#define LIST_14(A,B,C,D,E,F,G,H,I,J,K,L,M,N,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N
@@ -500,6 +544,11 @@
#define INC_13 14
#define INC_14 15
#define INC_15 16
+#define INC_16 17
+#define INC_17 18
+#define INC_18 19
+#define INC_19 20
+#define INC_20 21
#define INCREMENT_(n) INC_##n
#define INCREMENT(n) INCREMENT_(n)
diff --git a/Marlin/src/core/multi_language.h b/Marlin/src/core/multi_language.h
index 1eaef69305241..2106f946ac734 100644
--- a/Marlin/src/core/multi_language.h
+++ b/Marlin/src/core/multi_language.h
@@ -1,28 +1,35 @@
-/********************
- * multi_language.h *
- ********************/
-
-/****************************************************************************
- * Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
- * *
- * 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. *
- * *
- * To view a copy of the GNU General Public License, go to the following *
- * location: . *
- ****************************************************************************/
+/**
+ * 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 .
+ *
+ */
#pragma once
+/*******************************************************
+ * multi_language.h *
+ * By Marcio Teixeira 2019 for Aleph Objects *
+ *******************************************************/
+
#include "../inc/MarlinConfigPre.h"
typedef const char Language_Str[];
+#define LSTR PROGMEM Language_Str
#ifdef LCD_LANGUAGE_5
#define NUM_LANGUAGES 5
@@ -36,9 +43,8 @@ typedef const char Language_Str[];
#define NUM_LANGUAGES 1
#endif
-// Setting the unused languages equal to each other allows
-// the compiler to optimize away the conditionals
-
+// Set unused languages equal to each other so the
+// compiler can optimize away the conditionals.
#ifndef LCD_LANGUAGE_2
#define LCD_LANGUAGE_2 LCD_LANGUAGE
#endif
@@ -58,11 +64,11 @@ typedef const char Language_Str[];
#if NUM_LANGUAGES > 1
#define HAS_MULTI_LANGUAGE 1
#define GET_TEXT(MSG) ( \
- ui.language == 0 ? GET_LANG(LCD_LANGUAGE )::MSG : \
- ui.language == 1 ? GET_LANG(LCD_LANGUAGE_2)::MSG : \
- ui.language == 2 ? GET_LANG(LCD_LANGUAGE_3)::MSG : \
+ ui.language == 4 ? GET_LANG(LCD_LANGUAGE_5)::MSG : \
ui.language == 3 ? GET_LANG(LCD_LANGUAGE_4)::MSG : \
- GET_LANG(LCD_LANGUAGE_5)::MSG )
+ ui.language == 2 ? GET_LANG(LCD_LANGUAGE_3)::MSG : \
+ ui.language == 1 ? GET_LANG(LCD_LANGUAGE_2)::MSG : \
+ GET_LANG(LCD_LANGUAGE )::MSG )
#define MAX_LANG_CHARSIZE _MAX(GET_LANG(LCD_LANGUAGE )::CHARSIZE, \
GET_LANG(LCD_LANGUAGE_2)::CHARSIZE, \
GET_LANG(LCD_LANGUAGE_3)::CHARSIZE, \
@@ -72,7 +78,7 @@ typedef const char Language_Str[];
#define GET_TEXT(MSG) GET_LANG(LCD_LANGUAGE)::MSG
#define MAX_LANG_CHARSIZE LANG_CHARSIZE
#endif
-#define GET_TEXT_F(MSG) (const __FlashStringHelper*)GET_TEXT(MSG)
+#define GET_TEXT_F(MSG) FPSTR(GET_TEXT(MSG))
#define GET_LANGUAGE_NAME(INDEX) GET_LANG(LCD_LANGUAGE_##INDEX)::LANGUAGE
#define LANG_CHARSIZE GET_TEXT(CHARSIZE)
diff --git a/Marlin/src/core/serial.cpp b/Marlin/src/core/serial.cpp
index 50cc50ad574a7..9cd862df702c7 100644
--- a/Marlin/src/core/serial.cpp
+++ b/Marlin/src/core/serial.cpp
@@ -69,23 +69,23 @@ PGMSTR(SP_I_LBL, " " AXIS4_STR ":"); PGMSTR(SP_J_LBL, " " AXIS5_STR ":"); PGMSTR
#endif
-void serialprintPGM(PGM_P str) {
+void serial_print_P(PGM_P str) {
while (const char c = pgm_read_byte(str++)) SERIAL_CHAR(c);
}
-void serial_echo_start() { static PGMSTR(echomagic, "echo:"); serialprintPGM(echomagic); }
-void serial_error_start() { static PGMSTR(errormagic, "Error:"); serialprintPGM(errormagic); }
+void serial_echo_start() { static PGMSTR(echomagic, "echo:"); serial_print_P(echomagic); }
+void serial_error_start() { static PGMSTR(errormagic, "Error:"); serial_print_P(errormagic); }
void serial_spaces(uint8_t count) { count *= (PROPORTIONAL_FONT_RATIO); while (count--) SERIAL_CHAR(' '); }
-void serial_ternary(const bool onoff, PGM_P const pre, PGM_P const on, PGM_P const off, PGM_P const post/*=nullptr*/) {
- if (pre) serialprintPGM(pre);
- serialprintPGM(onoff ? on : off);
- if (post) serialprintPGM(post);
+void serial_ternary(const bool onoff, FSTR_P const pre, FSTR_P const on, FSTR_P const off, FSTR_P const post/*=nullptr*/) {
+ if (pre) serial_print(pre);
+ serial_print(onoff ? on : off);
+ if (post) serial_print(post);
}
-void serialprint_onoff(const bool onoff) { serialprintPGM(onoff ? PSTR(STR_ON) : PSTR(STR_OFF)); }
+void serialprint_onoff(const bool onoff) { serial_print(onoff ? F(STR_ON) : F(STR_OFF)); }
void serialprintln_onoff(const bool onoff) { serialprint_onoff(onoff); SERIAL_EOL(); }
-void serialprint_truefalse(const bool tf) { serialprintPGM(tf ? PSTR("true") : PSTR("false")); }
+void serialprint_truefalse(const bool tf) { serial_print(tf ? F("true") : F("false")); }
void print_bin(uint16_t val) {
for (uint8_t i = 16; i--;) {
@@ -94,10 +94,10 @@ void print_bin(uint16_t val) {
}
}
-void print_pos(LINEAR_AXIS_ARGS(const_float_t), PGM_P const prefix/*=nullptr*/, PGM_P const suffix/*=nullptr*/) {
- if (prefix) serialprintPGM(prefix);
- SERIAL_ECHOPAIR_P(
+void print_pos(LINEAR_AXIS_ARGS(const_float_t), FSTR_P const prefix/*=nullptr*/, FSTR_P const suffix/*=nullptr*/) {
+ if (prefix) serial_print(prefix);
+ SERIAL_ECHOPGM_P(
LIST_N(DOUBLE(LINEAR_AXES), SP_X_STR, x, SP_Y_STR, y, SP_Z_STR, z, SP_I_STR, i, SP_J_STR, j, SP_K_STR, k)
);
- if (suffix) serialprintPGM(suffix); else SERIAL_EOL();
+ if (suffix) serial_print(suffix); else SERIAL_EOL();
}
diff --git a/Marlin/src/core/serial.h b/Marlin/src/core/serial.h
index a3d640ee1a766..aee4d4d43db8f 100644
--- a/Marlin/src/core/serial.h
+++ b/Marlin/src/core/serial.h
@@ -87,7 +87,7 @@ extern uint8_t marlin_debug_flags;
// interface with the ability to output to multiple serial ports.
#if HAS_MULTI_SERIAL
#define _PORT_REDIRECT(n,p) REMEMBER(n,multiSerial.portMask,p)
- #define _PORT_RESTORE(n,p) RESTORE(n)
+ #define _PORT_RESTORE(n) RESTORE(n)
#define SERIAL_ASSERT(P) if (multiSerial.portMask!=(P)) { debugger(); }
// If we have a catchall, use that directly
#ifdef SERIAL_CATCHALL
@@ -167,13 +167,10 @@ inline void SERIAL_ECHO(serial_char_t x) { SERIAL_IMPL.write(x.c); }
#define AS_CHAR(C) serial_char_t(C)
#define AS_DIGIT(C) AS_CHAR('0' + (C))
-// SERIAL_ECHO_F prints a floating point value with optional precision
-inline void SERIAL_ECHO_F(EnsureDouble x, int digit=2) { SERIAL_IMPL.print(x, digit); }
-
template
void SERIAL_ECHOLN(T x) { SERIAL_IMPL.println(x); }
-// SERIAL_PRINT works like SERIAL_ECHO but allow to specify the encoding base of the number printed
+// SERIAL_PRINT works like SERIAL_ECHO but also takes the numeric base
template
void SERIAL_PRINT(T x, U y) { SERIAL_IMPL.print(x, y); }
@@ -184,48 +181,78 @@ void SERIAL_PRINTLN(T x, PrintBase y) { SERIAL_IMPL.println(x, y); }
inline void SERIAL_FLUSH() { SERIAL_IMPL.flush(); }
inline void SERIAL_FLUSHTX() { SERIAL_IMPL.flushTX(); }
-// Print a single PROGMEM string to serial
-void serialprintPGM(PGM_P str);
+// Serial echo and error prefixes
+#define SERIAL_ECHO_START() serial_echo_start()
+#define SERIAL_ERROR_START() serial_error_start()
+
+// Serial end-of-line
+#define SERIAL_EOL() SERIAL_CHAR('\n')
+
+// Print a single PROGMEM, PGM_P, or PSTR() string.
+void serial_print_P(PGM_P str);
+inline void serial_println_P(PGM_P str) { serial_print_P(str); SERIAL_EOL(); }
+
+// Print a single FSTR_P, F(), or FPSTR() string.
+inline void serial_print(FSTR_P const fstr) { serial_print_P(FTOP(fstr)); }
+inline void serial_println(FSTR_P const fstr) { serial_println_P(FTOP(fstr)); }
//
-// SERIAL_ECHOPAIR... macros are used to output string-value pairs.
+// SERIAL_ECHOPGM... macros are used to output string-value pairs.
//
// Print up to 20 pairs of values. Odd elements must be literal strings.
#define __SEP_N(N,V...) _SEP_##N(V)
#define _SEP_N(N,V...) __SEP_N(N,V)
#define _SEP_N_REF() _SEP_N
-#define _SEP_1(s) SERIAL_ECHOPGM(s);
-#define _SEP_2(s,v) serial_echopair_PGM(PSTR(s),v);
+#define _SEP_1(s) serial_print(F(s));
+#define _SEP_2(s,v) serial_echopair(F(s),v);
#define _SEP_3(s,v,V...) _SEP_2(s,v); DEFER2(_SEP_N_REF)()(TWO_ARGS(V),V);
-#define SERIAL_ECHOPAIR(V...) do{ EVAL(_SEP_N(TWO_ARGS(V),V)); }while(0)
+#define SERIAL_ECHOPGM(V...) do{ EVAL(_SEP_N(TWO_ARGS(V),V)); }while(0)
// Print up to 20 pairs of values followed by newline. Odd elements must be literal strings.
#define __SELP_N(N,V...) _SELP_##N(V)
#define _SELP_N(N,V...) __SELP_N(N,V)
#define _SELP_N_REF() _SELP_N
-#define _SELP_1(s) SERIAL_ECHOLNPGM(s);
-#define _SELP_2(s,v) serial_echopair_PGM(PSTR(s),v); SERIAL_EOL();
+#define _SELP_1(s) serial_print(F(s "\n"));
+#define _SELP_2(s,v) serial_echolnpair(F(s),v);
#define _SELP_3(s,v,V...) _SEP_2(s,v); DEFER2(_SELP_N_REF)()(TWO_ARGS(V),V);
-#define SERIAL_ECHOLNPAIR(V...) do{ EVAL(_SELP_N(TWO_ARGS(V),V)); }while(0)
+#define SERIAL_ECHOLNPGM(V...) do{ EVAL(_SELP_N(TWO_ARGS(V),V)); }while(0)
// Print up to 20 pairs of values. Odd elements must be PSTR pointers.
#define __SEP_N_P(N,V...) _SEP_##N##_P(V)
#define _SEP_N_P(N,V...) __SEP_N_P(N,V)
#define _SEP_N_P_REF() _SEP_N_P
-#define _SEP_1_P(s) serialprintPGM(s);
-#define _SEP_2_P(s,v) serial_echopair_PGM(s,v);
-#define _SEP_3_P(s,v,V...) _SEP_2_P(s,v); DEFER2(_SEP_N_P_REF)()(TWO_ARGS(V),V);
-#define SERIAL_ECHOPAIR_P(V...) do{ EVAL(_SEP_N_P(TWO_ARGS(V),V)); }while(0)
+#define _SEP_1_P(p) serial_print_P(p);
+#define _SEP_2_P(p,v) serial_echopair_P(p,v);
+#define _SEP_3_P(p,v,V...) _SEP_2_P(p,v); DEFER2(_SEP_N_P_REF)()(TWO_ARGS(V),V);
+#define SERIAL_ECHOPGM_P(V...) do{ EVAL(_SEP_N_P(TWO_ARGS(V),V)); }while(0)
// Print up to 20 pairs of values followed by newline. Odd elements must be PSTR pointers.
#define __SELP_N_P(N,V...) _SELP_##N##_P(V)
#define _SELP_N_P(N,V...) __SELP_N_P(N,V)
#define _SELP_N_P_REF() _SELP_N_P
-#define _SELP_1_P(s) { serialprintPGM(s); SERIAL_EOL(); }
-#define _SELP_2_P(s,v) { serial_echopair_PGM(s,v); SERIAL_EOL(); }
-#define _SELP_3_P(s,v,V...) { _SEP_2_P(s,v); DEFER2(_SELP_N_P_REF)()(TWO_ARGS(V),V); }
-#define SERIAL_ECHOLNPAIR_P(V...) do{ EVAL(_SELP_N_P(TWO_ARGS(V),V)); }while(0)
+#define _SELP_1_P(p) serial_println_P(p)
+#define _SELP_2_P(p,v) serial_echolnpair_P(p,v)
+#define _SELP_3_P(p,v,V...) { _SEP_2_P(p,v); DEFER2(_SELP_N_P_REF)()(TWO_ARGS(V),V); }
+#define SERIAL_ECHOLNPGM_P(V...) do{ EVAL(_SELP_N_P(TWO_ARGS(V),V)); }while(0)
+
+// Print up to 20 pairs of values. Odd elements must be FSTR_P, F(), or FPSTR().
+#define __SEP_N_F(N,V...) _SEP_##N##_F(V)
+#define _SEP_N_F(N,V...) __SEP_N_F(N,V)
+#define _SEP_N_F_REF() _SEP_N_F
+#define _SEP_1_F(p) serial_print(p);
+#define _SEP_2_F(p,v) serial_echopair(p,v);
+#define _SEP_3_F(p,v,V...) _SEP_2_F(p,v); DEFER2(_SEP_N_F_REF)()(TWO_ARGS(V),V);
+#define SERIAL_ECHOF(V...) do{ EVAL(_SEP_N_F(TWO_ARGS(V),V)); }while(0)
+
+// Print up to 20 pairs of values followed by newline. Odd elements must be FSTR_P, F(), or FPSTR().
+#define __SELP_N_F(N,V...) _SELP_##N##_F(V)
+#define _SELP_N_F(N,V...) __SELP_N_F(N,V)
+#define _SELP_N_F_REF() _SELP_N_F
+#define _SELP_1_F(p) serial_println(p)
+#define _SELP_2_F(p,v) serial_echolnpair(p,v)
+#define _SELP_3_F(p,v,V...) { _SEP_2_F(p,v); DEFER2(_SELP_N_F_REF)()(TWO_ARGS(V),V); }
+#define SERIAL_ECHOLNF(V...) do{ EVAL(_SELP_N_F(TWO_ARGS(V),V)); }while(0)
#ifdef AllowDifferentTypeInList
@@ -236,53 +263,49 @@ void serialprintPGM(PGM_P str);
template
void SERIAL_ECHOLIST_IMPL(T && t, Args && ... args) {
SERIAL_IMPL.print(t);
- serialprintPGM(PSTR(", "));
+ serial_print(F(", "));
SERIAL_ECHOLIST_IMPL(args...);
}
template
- void SERIAL_ECHOLIST(PGM_P const str, Args && ... args) {
- SERIAL_IMPL.print(str);
+ void SERIAL_ECHOLIST(FSTR_P const str, Args && ... args) {
+ SERIAL_IMPL.print(FTOP(str));
SERIAL_ECHOLIST_IMPL(args...);
}
#else // Optimization if the listed type are all the same (seems to be the case in the codebase so use that instead)
template
- void SERIAL_ECHOLIST(PGM_P const str, Args && ... args) {
- serialprintPGM(str);
+ void SERIAL_ECHOLIST(FSTR_P const fstr, Args && ... args) {
+ serial_print(fstr);
typename Private::first_type_of::type values[] = { args... };
constexpr size_t argsSize = sizeof...(args);
for (size_t i = 0; i < argsSize; i++) {
- if (i) serialprintPGM(PSTR(", "));
+ if (i) serial_print(F(", "));
SERIAL_IMPL.print(values[i]);
}
}
#endif
-#define SERIAL_ECHOPGM_P(P) (serialprintPGM(P))
-#define SERIAL_ECHOLNPGM_P(P) do{ serialprintPGM(P); SERIAL_EOL(); }while(0)
-
-#define SERIAL_ECHOPGM(S) (serialprintPGM(PSTR(S)))
-#define SERIAL_ECHOLNPGM(S) (serialprintPGM(PSTR(S "\n")))
+// SERIAL_ECHO_F prints a floating point value with optional precision
+inline void SERIAL_ECHO_F(EnsureDouble x, int digit=2) { SERIAL_IMPL.print(x, digit); }
-#define SERIAL_ECHOPAIR_F_P(P,V...) do{ serialprintPGM(P); SERIAL_ECHO_F(V); }while(0)
-#define SERIAL_ECHOLNPAIR_F_P(V...) do{ SERIAL_ECHOPAIR_F_P(V); SERIAL_EOL(); }while(0)
+#define SERIAL_ECHOPAIR_F_P(P,V...) do{ serial_print_P(P); SERIAL_ECHO_F(V); }while(0)
+#define SERIAL_ECHOLNPAIR_F_P(P,V...) do{ SERIAL_ECHOPAIR_F_P(P,V); SERIAL_EOL(); }while(0)
-#define SERIAL_ECHOPAIR_F(S,V...) SERIAL_ECHOPAIR_F_P(PSTR(S),V)
-#define SERIAL_ECHOLNPAIR_F(V...) do{ SERIAL_ECHOPAIR_F(V); SERIAL_EOL(); }while(0)
+#define SERIAL_ECHOPAIR_F_F(S,V...) do{ serial_print(S); SERIAL_ECHO_F(V); }while(0)
+#define SERIAL_ECHOLNPAIR_F_F(S,V...) do{ SERIAL_ECHOPAIR_F_F(S,V); SERIAL_EOL(); }while(0)
-#define SERIAL_ECHO_START() serial_echo_start()
-#define SERIAL_ERROR_START() serial_error_start()
-#define SERIAL_EOL() SERIAL_CHAR('\n')
+#define SERIAL_ECHOPAIR_F(S,V...) SERIAL_ECHOPAIR_F_F(F(S),V)
+#define SERIAL_ECHOLNPAIR_F(V...) do{ SERIAL_ECHOPAIR_F(V); SERIAL_EOL(); }while(0)
-#define SERIAL_ECHO_MSG(V...) do{ SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR(V); }while(0)
-#define SERIAL_ERROR_MSG(V...) do{ SERIAL_ERROR_START(); SERIAL_ECHOLNPAIR(V); }while(0)
+#define SERIAL_ECHO_MSG(V...) do{ SERIAL_ECHO_START(); SERIAL_ECHOLNPGM(V); }while(0)
+#define SERIAL_ERROR_MSG(V...) do{ SERIAL_ERROR_START(); SERIAL_ECHOLNPGM(V); }while(0)
-#define SERIAL_ECHO_SP(C) serial_spaces(C)
+#define SERIAL_ECHO_SP(C) serial_spaces(C)
-#define SERIAL_ECHO_TERNARY(TF, PRE, ON, OFF, POST) serial_ternary(TF, PSTR(PRE), PSTR(ON), PSTR(OFF), PSTR(POST))
+#define SERIAL_ECHO_TERNARY(TF, PRE, ON, OFF, POST) serial_ternary(TF, F(PRE), F(ON), F(OFF), F(POST))
#if SERIAL_FLOAT_PRECISION
#define SERIAL_DECIMAL(V) SERIAL_PRINT(V, SERIAL_FLOAT_PRECISION)
@@ -293,33 +316,42 @@ void serialprintPGM(PGM_P str);
//
// Functions for serial printing from PROGMEM. (Saves loads of SRAM.)
//
-inline void serial_echopair_PGM(PGM_P const s_P, serial_char_t v) { serialprintPGM(s_P); SERIAL_CHAR(v.c); }
-
-inline void serial_echopair_PGM(PGM_P const s_P, float v) { serialprintPGM(s_P); SERIAL_DECIMAL(v); }
-inline void serial_echopair_PGM(PGM_P const s_P, double v) { serialprintPGM(s_P); SERIAL_DECIMAL(v); }
-inline void serial_echopair_PGM(PGM_P const s_P, const char *v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
+inline void serial_echopair_P(PGM_P const pstr, serial_char_t v) { serial_print_P(pstr); SERIAL_CHAR(v.c); }
+inline void serial_echopair_P(PGM_P const pstr, float v) { serial_print_P(pstr); SERIAL_DECIMAL(v); }
+inline void serial_echopair_P(PGM_P const pstr, double v) { serial_print_P(pstr); SERIAL_DECIMAL(v); }
+//inline void serial_echopair_P(PGM_P const pstr, const char *v) { serial_print_P(pstr); SERIAL_ECHO(v); }
+inline void serial_echopair_P(PGM_P const pstr, FSTR_P v) { serial_print_P(pstr); SERIAL_ECHOF(v); }
// Default implementation for types without a specialization. Handles integers.
template
-void serial_echopair_PGM(PGM_P const s_P, T v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
+inline void serial_echopair_P(PGM_P const pstr, T v) { serial_print_P(pstr); SERIAL_ECHO(v); }
+
+// Add a newline.
+template
+inline void serial_echolnpair_P(PGM_P const pstr, T v) { serial_echopair_P(pstr, v); SERIAL_EOL(); }
-inline void serial_echopair_PGM(PGM_P const s_P, bool v) { serial_echopair_PGM(s_P, (int)v); }
-inline void serial_echopair_PGM(PGM_P const s_P, void *v) { serial_echopair_PGM(s_P, (uintptr_t)v); }
+// Catch-all for __FlashStringHelper *
+template
+inline void serial_echopair(FSTR_P const fstr, T v) { serial_echopair_P(FTOP(fstr), v); }
+
+// Add a newline to the serial output
+template
+inline void serial_echolnpair(FSTR_P const fstr, T v) { serial_echolnpair_P(FTOP(fstr), v); }
void serial_echo_start();
void serial_error_start();
-void serial_ternary(const bool onoff, PGM_P const pre, PGM_P const on, PGM_P const off, PGM_P const post=nullptr);
+void serial_ternary(const bool onoff, FSTR_P const pre, FSTR_P const on, FSTR_P const off, FSTR_P const post=nullptr);
void serialprint_onoff(const bool onoff);
void serialprintln_onoff(const bool onoff);
void serialprint_truefalse(const bool tf);
void serial_spaces(uint8_t count);
void print_bin(const uint16_t val);
-void print_pos(LINEAR_AXIS_ARGS(const_float_t), PGM_P const prefix=nullptr, PGM_P const suffix=nullptr);
+void print_pos(LINEAR_AXIS_ARGS(const_float_t), FSTR_P const prefix=nullptr, FSTR_P const suffix=nullptr);
-inline void print_pos(const xyz_pos_t &xyz, PGM_P const prefix=nullptr, PGM_P const suffix=nullptr) {
+inline void print_pos(const xyz_pos_t &xyz, FSTR_P const prefix=nullptr, FSTR_P const suffix=nullptr) {
print_pos(LINEAR_AXIS_ELEM(xyz), prefix, suffix);
}
-#define SERIAL_POS(SUFFIX,VAR) do { print_pos(VAR, PSTR(" " STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n")); }while(0)
-#define SERIAL_XYZ(PREFIX,V...) do { print_pos(V, PSTR(PREFIX), nullptr); }while(0)
+#define SERIAL_POS(SUFFIX,VAR) do { print_pos(VAR, F(" " STRINGIFY(VAR) "="), F(" : " SUFFIX "\n")); }while(0)
+#define SERIAL_XYZ(PREFIX,V...) do { print_pos(V, F(PREFIX)); }while(0)
diff --git a/Marlin/src/core/types.h b/Marlin/src/core/types.h
index 833167a7a1967..72099fb408737 100644
--- a/Marlin/src/core/types.h
+++ b/Marlin/src/core/types.h
@@ -26,9 +26,6 @@
#include "../inc/MarlinConfigPre.h"
-class __FlashStringHelper;
-typedef const __FlashStringHelper *progmem_str;
-
//
// Conditional type assignment magic. For example...
//
@@ -55,6 +52,8 @@ struct IF { typedef L type; };
#define LOGICAL_AXIS_ELEM(O) LOGICAL_AXIS_LIST(O.e, O.x, O.y, O.z, O.i, O.j, O.k)
#define LOGICAL_AXIS_DECL(T,V) LOGICAL_AXIS_LIST(T e=V, T x=V, T y=V, T z=V, T i=V, T j=V, T k=V)
+#define LOGICAL_AXES_STRING LOGICAL_AXIS_GANG("E", "X", "Y", "Z", AXIS4_STR, AXIS5_STR, AXIS6_STR)
+
#if HAS_EXTRUDERS
#define LIST_ITEM_E(N) , N
#define CODE_ITEM_E(N) ; N
diff --git a/Marlin/src/core/utility.cpp b/Marlin/src/core/utility.cpp
index b810855d52266..b70e2fa9a94d9 100644
--- a/Marlin/src/core/utility.cpp
+++ b/Marlin/src/core/utility.cpp
@@ -79,9 +79,9 @@ void safe_delay(millis_t ms) {
#if HAS_BED_PROBE
#if !HAS_PROBE_XY_OFFSET
- SERIAL_ECHOPAIR("Probe Offset X0 Y0 Z", probe.offset.z, " (");
+ SERIAL_ECHOPGM("Probe Offset X0 Y0 Z", probe.offset.z, " (");
#else
- SERIAL_ECHOPAIR_P(PSTR("Probe Offset X"), probe.offset_xy.x, SP_Y_STR, probe.offset_xy.y, SP_Z_STR, probe.offset.z);
+ SERIAL_ECHOPGM_P(PSTR("Probe Offset X"), probe.offset_xy.x, SP_Y_STR, probe.offset_xy.y, SP_Z_STR, probe.offset.z);
if (probe.offset_xy.x > 0)
SERIAL_ECHOPGM(" (Right");
else if (probe.offset_xy.x < 0)
@@ -92,9 +92,9 @@ void safe_delay(millis_t ms) {
SERIAL_ECHOPGM(" (Aligned With");
if (probe.offset_xy.y > 0)
- SERIAL_ECHOPGM_P(ENABLED(IS_SCARA) ? PSTR("-Distal") : PSTR("-Back"));
+ SERIAL_ECHOF(F(TERN(IS_SCARA, "-Distal", "-Back")));
else if (probe.offset_xy.y < 0)
- SERIAL_ECHOPGM_P(ENABLED(IS_SCARA) ? PSTR("-Proximal") : PSTR("-Front"));
+ SERIAL_ECHOF(F(TERN(IS_SCARA, "-Proximal", "-Front")));
else if (probe.offset_xy.x != 0)
SERIAL_ECHOPGM("-Center");
@@ -102,7 +102,7 @@ void safe_delay(millis_t ms) {
#endif
- SERIAL_ECHOPGM_P(probe.offset.z < 0 ? PSTR("Below") : probe.offset.z > 0 ? PSTR("Above") : PSTR("Same Z as"));
+ SERIAL_ECHOF(probe.offset.z < 0 ? F("Below") : probe.offset.z > 0 ? F("Above") : F("Same Z as"));
SERIAL_ECHOLNPGM(" Nozzle)");
#endif
@@ -119,7 +119,7 @@ void safe_delay(millis_t ms) {
SERIAL_ECHOLNPGM(" (enabled)");
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
if (planner.z_fade_height)
- SERIAL_ECHOLNPAIR("Z Fade: ", planner.z_fade_height);
+ SERIAL_ECHOLNPGM("Z Fade: ", planner.z_fade_height);
#endif
#if ABL_PLANAR
SERIAL_ECHOPGM("ABL Adjustment");
@@ -140,7 +140,7 @@ void safe_delay(millis_t ms) {
SERIAL_ECHO(ftostr43sign(rz, '+'));
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
if (planner.z_fade_height) {
- SERIAL_ECHOPAIR(" (", ftostr43sign(rz * planner.fade_scaling_factor_for_z(current_position.z), '+'));
+ SERIAL_ECHOPGM(" (", ftostr43sign(rz * planner.fade_scaling_factor_for_z(current_position.z), '+'));
SERIAL_CHAR(')');
}
#endif
@@ -156,10 +156,10 @@ void safe_delay(millis_t ms) {
SERIAL_ECHOPGM("Mesh Bed Leveling");
if (planner.leveling_active) {
SERIAL_ECHOLNPGM(" (enabled)");
- SERIAL_ECHOPAIR("MBL Adjustment Z", ftostr43sign(mbl.get_z(current_position), '+'));
+ SERIAL_ECHOPGM("MBL Adjustment Z", ftostr43sign(mbl.get_z(current_position), '+'));
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
if (planner.z_fade_height) {
- SERIAL_ECHOPAIR(" (", ftostr43sign(
+ SERIAL_ECHOPGM(" (", ftostr43sign(
mbl.get_z(current_position, planner.fade_scaling_factor_for_z(current_position.z)), '+'
));
SERIAL_CHAR(')');
diff --git a/Marlin/src/feature/backlash.cpp b/Marlin/src/feature/backlash.cpp
index 5ab95d157775b..b646e19f15aba 100644
--- a/Marlin/src/feature/backlash.cpp
+++ b/Marlin/src/feature/backlash.cpp
@@ -60,9 +60,9 @@ Backlash backlash;
* spread over multiple segments, smoothing out artifacts even more.
*/
-void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const int32_t &dc, const uint8_t dm, block_t * const block) {
- static uint8_t last_direction_bits;
- uint8_t changed_dir = last_direction_bits ^ dm;
+void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const int32_t &dc, const axis_bits_t dm, block_t * const block) {
+ static axis_bits_t last_direction_bits;
+ axis_bits_t changed_dir = last_direction_bits ^ dm;
// Ignore direction change unless steps are taken in that direction
#if DISABLED(CORE_BACKLASH) || ENABLED(MARKFORGED_XY)
if (!da) CBI(changed_dir, X_AXIS);
@@ -134,12 +134,12 @@ void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const
switch (axis) {
case CORE_AXIS_1:
//block->steps[CORE_AXIS_2] += influence_distance_mm[axis] * planner.settings.axis_steps_per_mm[CORE_AXIS_2];
- //SERIAL_ECHOLNPAIR("CORE_AXIS_1 dir change. distance=", distance_mm[axis], " r.err=", residual_error[axis],
+ //SERIAL_ECHOLNPGM("CORE_AXIS_1 dir change. distance=", distance_mm[axis], " r.err=", residual_error[axis],
// " da=", da, " db=", db, " block->steps[axis]=", block->steps[axis], " err_corr=", error_correction);
break;
case CORE_AXIS_2:
//block->steps[CORE_AXIS_1] += influence_distance_mm[axis] * planner.settings.axis_steps_per_mm[CORE_AXIS_1];;
- //SERIAL_ECHOLNPAIR("CORE_AXIS_2 dir change. distance=", distance_mm[axis], " r.err=", residual_error[axis],
+ //SERIAL_ECHOLNPGM("CORE_AXIS_2 dir change. distance=", distance_mm[axis], " r.err=", residual_error[axis],
// " da=", da, " db=", db, " block->steps[axis]=", block->steps[axis], " err_corr=", error_correction);
break;
case NORMAL_AXIS: break;
diff --git a/Marlin/src/feature/backlash.h b/Marlin/src/feature/backlash.h
index 500168b3804e1..4d4e2940382c2 100644
--- a/Marlin/src/feature/backlash.h
+++ b/Marlin/src/feature/backlash.h
@@ -71,7 +71,7 @@ class Backlash {
return has_measurement(X_AXIS) || has_measurement(Y_AXIS) || has_measurement(Z_AXIS);
}
- void add_correction_steps(const int32_t &da, const int32_t &db, const int32_t &dc, const uint8_t dm, block_t * const block);
+ void add_correction_steps(const int32_t &da, const int32_t &db, const int32_t &dc, const axis_bits_t dm, block_t * const block);
};
extern Backlash backlash;
diff --git a/Marlin/src/feature/bedlevel/abl/abl.cpp b/Marlin/src/feature/bedlevel/abl/abl.cpp
index 7390656563234..ece7481981955 100644
--- a/Marlin/src/feature/bedlevel/abl/abl.cpp
+++ b/Marlin/src/feature/bedlevel/abl/abl.cpp
@@ -336,11 +336,11 @@ float bilinear_z_offset(const xy_pos_t &raw) {
/*
static float last_offset = 0;
if (ABS(last_offset - offset) > 0.2) {
- SERIAL_ECHOLNPAIR("Sudden Shift at x=", rel.x, " / ", bilinear_grid_spacing.x, " -> thisg.x=", thisg.x);
- SERIAL_ECHOLNPAIR(" y=", rel.y, " / ", bilinear_grid_spacing.y, " -> thisg.y=", thisg.y);
- SERIAL_ECHOLNPAIR(" ratio.x=", ratio.x, " ratio.y=", ratio.y);
- SERIAL_ECHOLNPAIR(" z1=", z1, " z2=", z2, " z3=", z3, " z4=", z4);
- SERIAL_ECHOLNPAIR(" L=", L, " R=", R, " offset=", offset);
+ SERIAL_ECHOLNPGM("Sudden Shift at x=", rel.x, " / ", bilinear_grid_spacing.x, " -> thisg.x=", thisg.x);
+ SERIAL_ECHOLNPGM(" y=", rel.y, " / ", bilinear_grid_spacing.y, " -> thisg.y=", thisg.y);
+ SERIAL_ECHOLNPGM(" ratio.x=", ratio.x, " ratio.y=", ratio.y);
+ SERIAL_ECHOLNPGM(" z1=", z1, " z2=", z2, " z3=", z3, " z4=", z4);
+ SERIAL_ECHOLNPGM(" L=", L, " R=", R, " offset=", offset);
}
last_offset = offset;
//*/
diff --git a/Marlin/src/feature/bedlevel/ubl/ubl.cpp b/Marlin/src/feature/bedlevel/ubl/ubl.cpp
index 37c8be5bd8f53..964f1123fe421 100644
--- a/Marlin/src/feature/bedlevel/ubl/ubl.cpp
+++ b/Marlin/src/feature/bedlevel/ubl/ubl.cpp
@@ -51,7 +51,7 @@ void unified_bed_leveling::report_current_mesh() {
GRID_LOOP(x, y)
if (!isnan(z_values[x][y])) {
SERIAL_ECHO_START();
- SERIAL_ECHOPAIR(" M421 I", x, " J", y);
+ SERIAL_ECHOPGM(" M421 I", x, " J", y);
SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, z_values[x][y], 4);
serial_delay(75); // Prevent Printrun from exploding
}
@@ -180,10 +180,8 @@ void unified_bed_leveling::display_map(const uint8_t map_type) {
SERIAL_EOL();
serial_echo_column_labels(eachsp - 2);
}
- else {
- SERIAL_ECHOPGM(" for ");
- SERIAL_ECHOPGM_P(csv ? PSTR("CSV:\n") : PSTR("LCD:\n"));
- }
+ else
+ SERIAL_ECHOPGM(" for ", csv ? F("CSV:\n") : F("LCD:\n"));
// Add XY probe offset from extruder because probe.probe_at_point() subtracts them when
// moving to the XY position to be measured. This ensures better agreement between
@@ -213,7 +211,7 @@ void unified_bed_leveling::display_map(const uint8_t map_type) {
// TODO: Display on Graphical LCD
}
else if (isnan(f))
- SERIAL_ECHOPGM_P(human ? PSTR(" . ") : PSTR("NAN"));
+ SERIAL_ECHOF(human ? F(" . ") : F("NAN"));
else if (human || csv) {
if (human && f >= 0.0) SERIAL_CHAR(f > 0 ? '+' : ' '); // Display sign also for positive numbers (' ' for 0)
SERIAL_ECHO_F(f, 3); // Positive: 5 digits, Negative: 6 digits
@@ -281,10 +279,10 @@ bool unified_bed_leveling::sanity_check() {
}
#endif
- process_subcommands_now_P(G28_STR); // Home
- process_subcommands_now_P(PSTR(ALIGN_GCODE "\n" // Align multi z axis if available
- PROBE_GCODE "\n" // Build mesh with available hardware
- "G29P3\nG29P3")); // Ensure mesh is complete by running smart fill twice
+ process_subcommands_now(FPSTR(G28_STR)); // Home
+ process_subcommands_now(F(ALIGN_GCODE "\n" // Align multi z axis if available
+ PROBE_GCODE "\n" // Build mesh with available hardware
+ "G29P3\nG29P3")); // Ensure mesh is complete by running smart fill twice
if (parser.seenval('S')) {
char umw_gcode[32];
@@ -292,9 +290,9 @@ bool unified_bed_leveling::sanity_check() {
queue.inject(umw_gcode);
}
- process_subcommands_now_P(PSTR("G29A\nG29F10\n" // Set UBL Active & Fade 10
- "M140S0\nM104S0\n" // Turn off heaters
- "M500")); // Store settings
+ process_subcommands_now(F("G29A\nG29F10\n" // Set UBL Active & Fade 10
+ "M140S0\nM104S0\n" // Turn off heaters
+ "M500")); // Store settings
}
#endif // UBL_MESH_WIZARD
diff --git a/Marlin/src/feature/bedlevel/ubl/ubl.h b/Marlin/src/feature/bedlevel/ubl/ubl.h
index cf00a282cfdd1..ffabadd990b38 100644
--- a/Marlin/src/feature/bedlevel/ubl/ubl.h
+++ b/Marlin/src/feature/bedlevel/ubl/ubl.h
@@ -208,7 +208,7 @@ class unified_bed_leveling {
if (DEBUGGING(LEVELING)) {
if (WITHIN(x1_i, 0, (GRID_MAX_POINTS_X) - 1)) DEBUG_ECHOPGM("yi"); else DEBUG_ECHOPGM("x1_i");
- DEBUG_ECHOLNPAIR(" out of bounds in z_correction_for_x_on_horizontal_mesh_line(rx0=", rx0, ",x1_i=", x1_i, ",yi=", yi, ")");
+ DEBUG_ECHOLNPGM(" out of bounds in z_correction_for_x_on_horizontal_mesh_line(rx0=", rx0, ",x1_i=", x1_i, ",yi=", yi, ")");
}
// The requested location is off the mesh. Return UBL_Z_RAISE_WHEN_OFF_MESH or NAN.
@@ -231,7 +231,7 @@ class unified_bed_leveling {
if (DEBUGGING(LEVELING)) {
if (WITHIN(xi, 0, (GRID_MAX_POINTS_X) - 1)) DEBUG_ECHOPGM("y1_i"); else DEBUG_ECHOPGM("xi");
- DEBUG_ECHOLNPAIR(" out of bounds in z_correction_for_y_on_vertical_mesh_line(ry0=", ry0, ", xi=", xi, ", y1_i=", y1_i, ")");
+ DEBUG_ECHOLNPGM(" out of bounds in z_correction_for_y_on_vertical_mesh_line(ry0=", ry0, ", xi=", xi, ", y1_i=", y1_i, ")");
}
// The requested location is off the mesh. Return UBL_Z_RAISE_WHEN_OFF_MESH or NAN.
@@ -275,11 +275,11 @@ class unified_bed_leveling {
// because part of the Mesh is undefined and we don't have the
// information we need to complete the height correction.
- if (DEBUGGING(MESH_ADJUST)) DEBUG_ECHOLNPAIR("??? Yikes! NAN in ");
+ if (DEBUGGING(MESH_ADJUST)) DEBUG_ECHOLNPGM("??? Yikes! NAN in ");
}
if (DEBUGGING(MESH_ADJUST)) {
- DEBUG_ECHOPAIR("get_z_correction(", rx0, ", ", ry0);
+ DEBUG_ECHOPGM("get_z_correction(", rx0, ", ", ry0);
DEBUG_ECHOLNPAIR_F(") => ", z0, 6);
}
diff --git a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp
index f8e446cf81bea..df83923fef0a2 100644
--- a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp
+++ b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp
@@ -346,13 +346,14 @@ 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, -1, 2)) {
- SERIAL_ECHOLNPGM("Invalid test_pattern value. (-1 to 2)\n");
+ 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");
return;
}
- SERIAL_ECHOLNPGM("Loading test_pattern values.\n");
+ SERIAL_ECHOLNPGM("Applying test pattern.\n");
switch (test_pattern) {
+ default:
case -1: TERN_(UBL_DEVEL_DEBUGGING, g29_eeprom_dump()); break;
case 0:
@@ -428,7 +429,7 @@ void unified_bed_leveling::G29() {
SERIAL_ECHOLNPGM("Mesh invalidated. Probing mesh.");
}
if (param.V_verbosity > 1) {
- SERIAL_ECHOPAIR("Probing around (", param.XY_pos.x);
+ SERIAL_ECHOPGM("Probing around (", param.XY_pos.x);
SERIAL_CHAR(',');
SERIAL_DECIMAL(param.XY_pos.y);
SERIAL_ECHOLNPGM(").\n");
@@ -602,14 +603,14 @@ void unified_bed_leveling::G29() {
}
if (!WITHIN(param.KLS_storage_slot, 0, a - 1)) {
- SERIAL_ECHOLNPAIR("?Invalid storage slot.\n?Use 0 to ", a - 1);
+ SERIAL_ECHOLNPGM("?Invalid storage slot.\n?Use 0 to ", a - 1);
return;
}
settings.load_mesh(param.KLS_storage_slot);
storage_slot = param.KLS_storage_slot;
- SERIAL_ECHOLNPGM("Done.");
+ SERIAL_ECHOLNPGM(STR_DONE);
}
//
@@ -630,14 +631,14 @@ void unified_bed_leveling::G29() {
}
if (!WITHIN(param.KLS_storage_slot, 0, a - 1)) {
- SERIAL_ECHOLNPAIR("?Invalid storage slot.\n?Use 0 to ", a - 1);
+ SERIAL_ECHOLNPGM("?Invalid storage slot.\n?Use 0 to ", a - 1);
goto LEAVE;
}
settings.store_mesh(param.KLS_storage_slot);
storage_slot = param.KLS_storage_slot;
- SERIAL_ECHOLNPGM("Done.");
+ SERIAL_ECHOLNPGM(STR_DONE);
}
if (parser.seen_test('T'))
@@ -653,10 +654,10 @@ void unified_bed_leveling::G29() {
#endif
#ifdef Z_PROBE_END_SCRIPT
- if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Z Probe End Script: ", Z_PROBE_END_SCRIPT);
+ if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Z Probe End Script: ", Z_PROBE_END_SCRIPT);
if (probe_deployed) {
planner.synchronize();
- gcode.process_subcommands_now_P(PSTR(Z_PROBE_END_SCRIPT));
+ gcode.process_subcommands_now(F(Z_PROBE_END_SCRIPT));
}
#else
UNUSED(probe_deployed);
@@ -690,7 +691,7 @@ void unified_bed_leveling::adjust_mesh_to_mean(const bool cflag, const_float_t o
if (!isnan(z_values[x][y]))
sum_of_diff_squared += sq(z_values[x][y] - mean);
- SERIAL_ECHOLNPAIR("# of samples: ", n);
+ SERIAL_ECHOLNPGM("# of samples: ", n);
SERIAL_ECHOLNPAIR_F("Mean Mesh Height: ", mean, 6);
const float sigma = SQRT(sum_of_diff_squared / (n + 1));
@@ -735,8 +736,8 @@ void unified_bed_leveling::shift_mesh_height() {
if (do_ubl_mesh_map) display_map(param.T_map_type);
const uint8_t point_num = (GRID_MAX_POINTS - count) + 1;
- SERIAL_ECHOLNPAIR("Probing mesh point ", point_num, "/", GRID_MAX_POINTS, ".");
- TERN_(HAS_STATUS_MESSAGE, ui.status_printf_P(0, PSTR(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_MESH), point_num, int(GRID_MAX_POINTS)));
+ SERIAL_ECHOLNPGM("Probing mesh point ", point_num, "/", GRID_MAX_POINTS, ".");
+ TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), point_num, int(GRID_MAX_POINTS)));
#if HAS_LCD_MENU
if (ui.button_pressed()) {
@@ -789,12 +790,12 @@ void unified_bed_leveling::shift_mesh_height() {
#endif // HAS_BED_PROBE
-void set_message_with_feedback(PGM_P const msg_P) {
+void set_message_with_feedback(FSTR_P const fstr) {
#if HAS_LCD_MENU
- ui.set_status_P(msg_P);
+ ui.set_status(fstr);
ui.quick_feedback();
#else
- UNUSED(msg_P);
+ UNUSED(fstr);
#endif
}
@@ -850,7 +851,7 @@ void set_message_with_feedback(PGM_P const msg_P) {
planner.synchronize();
SERIAL_ECHOPGM("Place shim under nozzle");
- LCD_MESSAGEPGM(MSG_UBL_BC_INSERT);
+ LCD_MESSAGE(MSG_UBL_BC_INSERT);
ui.return_to_status();
echo_and_take_a_measurement();
@@ -859,7 +860,7 @@ void set_message_with_feedback(PGM_P const msg_P) {
planner.synchronize();
SERIAL_ECHOPGM("Remove shim");
- LCD_MESSAGEPGM(MSG_UBL_BC_REMOVE);
+ LCD_MESSAGE(MSG_UBL_BC_REMOVE);
echo_and_take_a_measurement();
const float z2 = measure_point_with_encoder();
@@ -905,7 +906,7 @@ void set_message_with_feedback(PGM_P const msg_P) {
if (!position_is_reachable(ppos)) break; // SHOULD NOT OCCUR (find_closest_mesh_point only returns reachable points)
- LCD_MESSAGEPGM(MSG_UBL_MOVING_TO_NEXT);
+ LCD_MESSAGE(MSG_UBL_MOVING_TO_NEXT);
do_blocking_move_to(ppos);
do_z_clearance(z_clearance);
@@ -917,11 +918,11 @@ void set_message_with_feedback(PGM_P const msg_P) {
if (parser.seen_test('B')) {
SERIAL_ECHOPGM("Place Shim & Measure");
- LCD_MESSAGEPGM(MSG_UBL_BC_INSERT);
+ LCD_MESSAGE(MSG_UBL_BC_INSERT);
}
else {
SERIAL_ECHOPGM("Measure");
- LCD_MESSAGEPGM(MSG_UBL_BC_INSERT2);
+ LCD_MESSAGE(MSG_UBL_BC_INSERT2);
}
const float z_step = 0.01f; // 0.01mm per encoder tick, occasionally step
@@ -974,7 +975,7 @@ void set_message_with_feedback(PGM_P const msg_P) {
save_ubl_active_state_and_disable();
- LCD_MESSAGEPGM(MSG_UBL_FINE_TUNE_MESH);
+ LCD_MESSAGE(MSG_UBL_FINE_TUNE_MESH);
ui.capture(); // Take over control of the LCD encoder
do_blocking_move_to_xy_z(pos, Z_CLEARANCE_BETWEEN_PROBES); // Move to the given XY with probe clearance
@@ -1039,7 +1040,7 @@ void set_message_with_feedback(PGM_P const msg_P) {
if (_click_and_hold([]{
ui.return_to_status();
do_z_clearance(Z_CLEARANCE_BETWEEN_PROBES);
- set_message_with_feedback(GET_TEXT(MSG_EDITING_STOPPED));
+ set_message_with_feedback(GET_TEXT_F(MSG_EDITING_STOPPED));
})) break;
// TODO: Disable leveling here so the Z value becomes the 'native' Z value.
@@ -1060,7 +1061,7 @@ void set_message_with_feedback(PGM_P const msg_P) {
do_blocking_move_to_xy_z(pos, Z_CLEARANCE_BETWEEN_PROBES);
- LCD_MESSAGEPGM(MSG_UBL_DONE_EDITING_MESH);
+ LCD_MESSAGE(MSG_UBL_DONE_EDITING_MESH);
SERIAL_ECHOLNPGM("Done Editing Mesh");
if (lcd_map_control)
@@ -1077,7 +1078,7 @@ void set_message_with_feedback(PGM_P const msg_P) {
bool unified_bed_leveling::G29_parse_parameters() {
bool err_flag = false;
- set_message_with_feedback(GET_TEXT(MSG_UBL_DOING_G29));
+ set_message_with_feedback(GET_TEXT_F(MSG_UBL_DOING_G29));
param.C_constant = 0;
param.R_repetition = 0;
@@ -1200,7 +1201,7 @@ void unified_bed_leveling::save_ubl_active_state_and_disable() {
ubl_state_recursion_chk++;
if (ubl_state_recursion_chk != 1) {
SERIAL_ECHOLNPGM("save_ubl_active_state_and_disabled() called multiple times in a row.");
- set_message_with_feedback(GET_TEXT(MSG_UBL_SAVE_ERROR));
+ set_message_with_feedback(GET_TEXT_F(MSG_UBL_SAVE_ERROR));
return;
}
#endif
@@ -1213,7 +1214,7 @@ void unified_bed_leveling::restore_ubl_active_state_and_leave() {
#if ENABLED(UBL_DEVEL_DEBUGGING)
if (--ubl_state_recursion_chk) {
SERIAL_ECHOLNPGM("restore_ubl_active_state_and_leave() called too many times.");
- set_message_with_feedback(GET_TEXT(MSG_UBL_RESTORE_ERROR));
+ set_message_with_feedback(GET_TEXT_F(MSG_UBL_RESTORE_ERROR));
return;
}
#endif
@@ -1438,7 +1439,7 @@ void unified_bed_leveling::smart_fill_mesh() {
if (do_3_pt_leveling) {
SERIAL_ECHOLNPGM("Tilting mesh (1/3)");
- TERN_(HAS_STATUS_MESSAGE, ui.status_printf_P(0, PSTR(S_FMT " 1/3"), GET_TEXT(MSG_LCD_TILTING_MESH)));
+ TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " 1/3"), GET_TEXT(MSG_LCD_TILTING_MESH)));
measured_z = probe.probe_at_point(points[0], PROBE_PT_RAISE, param.V_verbosity);
if (isnan(measured_z))
@@ -1450,14 +1451,14 @@ void unified_bed_leveling::smart_fill_mesh() {
#endif
if (param.V_verbosity > 3) {
serial_spaces(16);
- SERIAL_ECHOLNPAIR("Corrected_Z=", measured_z);
+ SERIAL_ECHOLNPGM("Corrected_Z=", measured_z);
}
incremental_LSF(&lsf_results, points[0], measured_z);
}
if (!abort_flag) {
SERIAL_ECHOLNPGM("Tilting mesh (2/3)");
- TERN_(HAS_STATUS_MESSAGE, ui.status_printf_P(0, PSTR(S_FMT " 2/3"), GET_TEXT(MSG_LCD_TILTING_MESH)));
+ TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " 2/3"), GET_TEXT(MSG_LCD_TILTING_MESH)));
measured_z = probe.probe_at_point(points[1], PROBE_PT_RAISE, param.V_verbosity);
#ifdef VALIDATE_MESH_TILT
@@ -1469,7 +1470,7 @@ void unified_bed_leveling::smart_fill_mesh() {
measured_z -= get_z_correction(points[1]);
if (param.V_verbosity > 3) {
serial_spaces(16);
- SERIAL_ECHOLNPAIR("Corrected_Z=", measured_z);
+ SERIAL_ECHOLNPGM("Corrected_Z=", measured_z);
}
incremental_LSF(&lsf_results, points[1], measured_z);
}
@@ -1477,9 +1478,9 @@ void unified_bed_leveling::smart_fill_mesh() {
if (!abort_flag) {
SERIAL_ECHOLNPGM("Tilting mesh (3/3)");
- TERN_(HAS_STATUS_MESSAGE, ui.status_printf_P(0, PSTR(S_FMT " 3/3"), GET_TEXT(MSG_LCD_TILTING_MESH)));
+ TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " 3/3"), GET_TEXT(MSG_LCD_TILTING_MESH)));
- measured_z = probe.probe_at_point(points[2], PROBE_PT_STOW, param.V_verbosity);
+ measured_z = probe.probe_at_point(points[2], PROBE_PT_LAST_STOW, param.V_verbosity);
#ifdef VALIDATE_MESH_TILT
z3 = measured_z;
#endif
@@ -1489,7 +1490,7 @@ void unified_bed_leveling::smart_fill_mesh() {
measured_z -= get_z_correction(points[2]);
if (param.V_verbosity > 3) {
serial_spaces(16);
- SERIAL_ECHOLNPAIR("Corrected_Z=", measured_z);
+ SERIAL_ECHOLNPGM("Corrected_Z=", measured_z);
}
incremental_LSF(&lsf_results, points[2], measured_z);
}
@@ -1517,8 +1518,8 @@ void unified_bed_leveling::smart_fill_mesh() {
rpos.y = y_min + dy * (zig_zag ? param.J_grid_size - 1 - iy : iy);
if (!abort_flag) {
- SERIAL_ECHOLNPAIR("Tilting mesh point ", point_num, "/", total_points, "\n");
- TERN_(HAS_STATUS_MESSAGE, ui.status_printf_P(0, PSTR(S_FMT " %i/%i"), GET_TEXT(MSG_LCD_TILTING_MESH), point_num, total_points));
+ SERIAL_ECHOLNPGM("Tilting mesh point ", point_num, "/", total_points, "\n");
+ TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_LCD_TILTING_MESH), point_num, total_points));
measured_z = probe.probe_at_point(rpos, parser.seen_test('E') ? PROBE_PT_STOW : PROBE_PT_RAISE, param.V_verbosity); // TODO: Needs error handling
@@ -1545,7 +1546,7 @@ void unified_bed_leveling::smart_fill_mesh() {
if (param.V_verbosity > 3) {
serial_spaces(16);
- SERIAL_ECHOLNPAIR("Corrected_Z=", measured_z);
+ SERIAL_ECHOLNPGM("Corrected_Z=", measured_z);
}
incremental_LSF(&lsf_results, rpos, measured_z);
}
@@ -1609,7 +1610,7 @@ void unified_bed_leveling::smart_fill_mesh() {
}
if (DEBUGGING(LEVELING)) {
- rotation.debug(PSTR("rotation matrix:\n"));
+ rotation.debug(F("rotation matrix:\n"));
DEBUG_ECHOPAIR_F("LSF Results A=", lsf_results.A, 7);
DEBUG_ECHOPAIR_F(" B=", lsf_results.B, 7);
DEBUG_ECHOLNPAIR_F(" D=", lsf_results.D, 7);
@@ -1636,19 +1637,19 @@ void unified_bed_leveling::smart_fill_mesh() {
auto normed = [&](const xy_pos_t &pos, const_float_t zadd) {
return normal.x * pos.x + normal.y * pos.y + zadd;
};
- auto debug_pt = [](PGM_P const pre, const xy_pos_t &pos, const_float_t zadd) {
- d_from(); SERIAL_ECHOPGM_P(pre);
+ auto debug_pt = [](FSTR_P const pre, const xy_pos_t &pos, const_float_t zadd) {
+ d_from(); SERIAL_ECHOF(pre);
DEBUG_ECHO_F(normed(pos, zadd), 6);
DEBUG_ECHOLNPAIR_F(" Z error = ", zadd - get_z_correction(pos), 6);
};
- debug_pt(PSTR("1st point: "), probe_pt[0], normal.z * z1);
- debug_pt(PSTR("2nd point: "), probe_pt[1], normal.z * z2);
- debug_pt(PSTR("3rd point: "), probe_pt[2], normal.z * z3);
+ debug_pt(F("1st point: "), probe_pt[0], normal.z * z1);
+ debug_pt(F("2nd point: "), probe_pt[1], normal.z * z2);
+ debug_pt(F("3rd point: "), probe_pt[2], normal.z * z3);
d_from(); DEBUG_ECHOPGM("safe home with Z=");
DEBUG_ECHOLNPAIR_F("0 : ", normed(safe_homing_xy, 0), 6);
d_from(); DEBUG_ECHOPGM("safe home with Z=");
DEBUG_ECHOLNPAIR_F("mesh value ", normed(safe_homing_xy, get_z_correction(safe_homing_xy)), 6);
- DEBUG_ECHOPAIR(" Z error = (", Z_SAFE_HOMING_X_POINT, ",", Z_SAFE_HOMING_Y_POINT);
+ DEBUG_ECHOPGM(" Z error = (", Z_SAFE_HOMING_X_POINT, ",", Z_SAFE_HOMING_Y_POINT);
DEBUG_ECHOLNPAIR_F(") = ", get_z_correction(safe_homing_xy), 6);
#endif
} // DEBUGGING(LEVELING)
@@ -1722,7 +1723,7 @@ void unified_bed_leveling::smart_fill_mesh() {
if (storage_slot == -1)
SERIAL_ECHOPGM("No Mesh Loaded.");
else
- SERIAL_ECHOPAIR("Mesh ", storage_slot, " Loaded.");
+ SERIAL_ECHOPGM("Mesh ", storage_slot, " Loaded.");
SERIAL_EOL();
serial_delay(50);
@@ -1736,14 +1737,14 @@ void unified_bed_leveling::smart_fill_mesh() {
SERIAL_ECHOLNPAIR_F("Probe Offset M851 Z", probe.offset.z, 7);
#endif
- SERIAL_ECHOLNPAIR("MESH_MIN_X " STRINGIFY(MESH_MIN_X) "=", MESH_MIN_X); serial_delay(50);
- SERIAL_ECHOLNPAIR("MESH_MIN_Y " STRINGIFY(MESH_MIN_Y) "=", MESH_MIN_Y); serial_delay(50);
- SERIAL_ECHOLNPAIR("MESH_MAX_X " STRINGIFY(MESH_MAX_X) "=", MESH_MAX_X); serial_delay(50);
- SERIAL_ECHOLNPAIR("MESH_MAX_Y " STRINGIFY(MESH_MAX_Y) "=", MESH_MAX_Y); serial_delay(50);
- SERIAL_ECHOLNPAIR("GRID_MAX_POINTS_X ", GRID_MAX_POINTS_X); serial_delay(50);
- SERIAL_ECHOLNPAIR("GRID_MAX_POINTS_Y ", GRID_MAX_POINTS_Y); serial_delay(50);
- SERIAL_ECHOLNPAIR("MESH_X_DIST ", MESH_X_DIST);
- SERIAL_ECHOLNPAIR("MESH_Y_DIST ", MESH_Y_DIST); serial_delay(50);
+ SERIAL_ECHOLNPGM("MESH_MIN_X " STRINGIFY(MESH_MIN_X) "=", MESH_MIN_X); serial_delay(50);
+ SERIAL_ECHOLNPGM("MESH_MIN_Y " STRINGIFY(MESH_MIN_Y) "=", MESH_MIN_Y); serial_delay(50);
+ SERIAL_ECHOLNPGM("MESH_MAX_X " STRINGIFY(MESH_MAX_X) "=", MESH_MAX_X); serial_delay(50);
+ SERIAL_ECHOLNPGM("MESH_MAX_Y " STRINGIFY(MESH_MAX_Y) "=", MESH_MAX_Y); serial_delay(50);
+ SERIAL_ECHOLNPGM("GRID_MAX_POINTS_X ", GRID_MAX_POINTS_X); serial_delay(50);
+ SERIAL_ECHOLNPGM("GRID_MAX_POINTS_Y ", GRID_MAX_POINTS_Y); serial_delay(50);
+ SERIAL_ECHOLNPGM("MESH_X_DIST ", MESH_X_DIST);
+ SERIAL_ECHOLNPGM("MESH_Y_DIST ", MESH_Y_DIST); serial_delay(50);
SERIAL_ECHOPGM("X-Axis Mesh Points at: ");
LOOP_L_N(i, GRID_MAX_POINTS_X) {
@@ -1762,27 +1763,27 @@ void unified_bed_leveling::smart_fill_mesh() {
SERIAL_EOL();
#if HAS_KILL
- SERIAL_ECHOLNPAIR("Kill pin on :", KILL_PIN, " state:", kill_state());
+ SERIAL_ECHOLNPGM("Kill pin on :", KILL_PIN, " state:", kill_state());
#endif
SERIAL_EOL();
serial_delay(50);
#if ENABLED(UBL_DEVEL_DEBUGGING)
- SERIAL_ECHOLNPAIR("ubl_state_at_invocation :", ubl_state_at_invocation, "\nubl_state_recursion_chk :", ubl_state_recursion_chk);
+ SERIAL_ECHOLNPGM("ubl_state_at_invocation :", ubl_state_at_invocation, "\nubl_state_recursion_chk :", ubl_state_recursion_chk);
serial_delay(50);
- SERIAL_ECHOLNPAIR("Meshes go from ", hex_address((void*)settings.meshes_start_index()), " to ", hex_address((void*)settings.meshes_end_index()));
+ SERIAL_ECHOLNPGM("Meshes go from ", hex_address((void*)settings.meshes_start_index()), " to ", hex_address((void*)settings.meshes_end_index()));
serial_delay(50);
- SERIAL_ECHOLNPAIR("sizeof(ubl) : ", sizeof(ubl)); SERIAL_EOL();
- SERIAL_ECHOLNPAIR("z_value[][] size: ", sizeof(z_values)); SERIAL_EOL();
+ SERIAL_ECHOLNPGM("sizeof(ubl) : ", sizeof(ubl)); SERIAL_EOL();
+ SERIAL_ECHOLNPGM("z_value[][] size: ", sizeof(z_values)); SERIAL_EOL();
serial_delay(25);
- SERIAL_ECHOLNPAIR("EEPROM free for UBL: ", hex_address((void*)(settings.meshes_end_index() - settings.meshes_start_index())));
+ SERIAL_ECHOLNPGM("EEPROM free for UBL: ", hex_address((void*)(settings.meshes_end_index() - settings.meshes_start_index())));
serial_delay(50);
- SERIAL_ECHOLNPAIR("EEPROM can hold ", settings.calc_num_meshes(), " meshes.\n");
+ SERIAL_ECHOLNPGM("EEPROM can hold ", settings.calc_num_meshes(), " meshes.\n");
serial_delay(25);
#endif // UBL_DEVEL_DEBUGGING
@@ -1829,7 +1830,7 @@ void unified_bed_leveling::smart_fill_mesh() {
}
if (!parser.has_value() || !WITHIN(parser.value_int(), 0, a - 1)) {
- SERIAL_ECHOLNPAIR("?Invalid storage slot.\n?Use 0 to ", a - 1);
+ SERIAL_ECHOLNPGM("?Invalid storage slot.\n?Use 0 to ", a - 1);
return;
}
@@ -1838,7 +1839,7 @@ void unified_bed_leveling::smart_fill_mesh() {
float tmp_z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
settings.load_mesh(param.KLS_storage_slot, &tmp_z_values);
- SERIAL_ECHOLNPAIR("Subtracting mesh in slot ", param.KLS_storage_slot, " from current mesh.");
+ SERIAL_ECHOLNPGM("Subtracting mesh in slot ", param.KLS_storage_slot, " from current mesh.");
GRID_LOOP(x, y) {
z_values[x][y] -= tmp_z_values[x][y];
diff --git a/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp b/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp
index 20408d8d1e81f..f7e98c9fa77d2 100644
--- a/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp
+++ b/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "../../../inc/MarlinConfig.h"
#if ENABLED(AUTO_BED_LEVELING_UBL)
@@ -323,6 +324,8 @@
#define DELTA_SEGMENT_MIN_LENGTH 0.25 // SCARA minimum segment size is 0.25mm
#elif ENABLED(DELTA)
#define DELTA_SEGMENT_MIN_LENGTH 0.10 // mm (still subject to DELTA_SEGMENTS_PER_SECOND)
+ #elif ENABLED(POLARGRAPH)
+ #define DELTA_SEGMENT_MIN_LENGTH 0.10 // mm (still subject to DELTA_SEGMENTS_PER_SECOND)
#else // CARTESIAN
#ifdef LEVELED_SEGMENT_LENGTH
#define DELTA_SEGMENT_MIN_LENGTH LEVELED_SEGMENT_LENGTH
diff --git a/Marlin/src/feature/binary_stream.h b/Marlin/src/feature/binary_stream.h
index cef8a3c90211d..417e39c745076 100644
--- a/Marlin/src/feature/binary_stream.h
+++ b/Marlin/src/feature/binary_stream.h
@@ -146,9 +146,9 @@ class SDFileTransferProtocol {
transfer_timeout = millis() + TIMEOUT;
switch (static_cast(packet_type)) {
case FileTransfer::QUERY:
- SERIAL_ECHOPAIR("PFT:version:", VERSION_MAJOR, ".", VERSION_MINOR, ".", VERSION_PATCH);
+ SERIAL_ECHOPGM("PFT:version:", VERSION_MAJOR, ".", VERSION_MINOR, ".", VERSION_PATCH);
#if ENABLED(BINARY_STREAM_COMPRESSION)
- SERIAL_ECHOLNPAIR(":compression:heatshrink,", HEATSHRINK_STATIC_WINDOW_BITS, ",", HEATSHRINK_STATIC_LOOKAHEAD_BITS);
+ SERIAL_ECHOLNPGM(":compression:heatshrink,", HEATSHRINK_STATIC_WINDOW_BITS, ",", HEATSHRINK_STATIC_LOOKAHEAD_BITS);
#else
SERIAL_ECHOLNPGM(":compression:none");
#endif
@@ -322,7 +322,7 @@ class BinaryStream {
if (packet.header.checksum == packet.header_checksum) {
// The SYNC control packet is a special case in that it doesn't require the stream sync to be correct
if (static_cast(packet.header.protocol()) == Protocol::CONTROL && static_cast(packet.header.type()) == ProtocolControl::SYNC) {
- SERIAL_ECHOLNPAIR("ss", sync, ",", buffer_size, ",", VERSION_MAJOR, ".", VERSION_MINOR, ".", VERSION_PATCH);
+ SERIAL_ECHOLNPGM("ss", sync, ",", buffer_size, ",", VERSION_MAJOR, ".", VERSION_MINOR, ".", VERSION_PATCH);
stream_state = StreamState::PACKET_RESET;
break;
}
@@ -337,7 +337,7 @@ class BinaryStream {
stream_state = StreamState::PACKET_PROCESS;
}
else if (packet.header.sync == sync - 1) { // ok response must have been lost
- SERIAL_ECHOLNPAIR("ok", packet.header.sync); // transmit valid packet received and drop the payload
+ SERIAL_ECHOLNPGM("ok", packet.header.sync); // transmit valid packet received and drop the payload
stream_state = StreamState::PACKET_RESET;
}
else if (packet_retries) {
@@ -393,7 +393,7 @@ class BinaryStream {
packet_retries = 0;
bytes_received += packet.header.size;
- SERIAL_ECHOLNPAIR("ok", packet.header.sync); // transmit valid packet received
+ SERIAL_ECHOLNPGM("ok", packet.header.sync); // transmit valid packet received
dispatch();
stream_state = StreamState::PACKET_RESET;
break;
@@ -402,7 +402,7 @@ class BinaryStream {
packet_retries++;
stream_state = StreamState::PACKET_RESET;
SERIAL_ECHO_MSG("Resend request ", packet_retries);
- SERIAL_ECHOLNPAIR("rs", sync);
+ SERIAL_ECHOLNPGM("rs", sync);
}
else
stream_state = StreamState::PACKET_ERROR;
@@ -412,7 +412,7 @@ class BinaryStream {
stream_state = StreamState::PACKET_RESEND;
break;
case StreamState::PACKET_ERROR:
- SERIAL_ECHOLNPAIR("fe", packet.header.sync);
+ SERIAL_ECHOLNPGM("fe", packet.header.sync);
reset(); // reset everything, resync required
stream_state = StreamState::PACKET_RESET;
break;
diff --git a/Marlin/src/feature/bltouch.cpp b/Marlin/src/feature/bltouch.cpp
index 7fccc52d05842..49a10f62b1559 100644
--- a/Marlin/src/feature/bltouch.cpp
+++ b/Marlin/src/feature/bltouch.cpp
@@ -39,7 +39,7 @@ void stop();
#include "../core/debug_out.h"
bool BLTouch::command(const BLTCommand cmd, const millis_t &ms) {
- if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPAIR("BLTouch Command :", cmd);
+ if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("BLTouch Command :", cmd);
MOVE_SERVO(Z_PROBE_SERVO_NR, cmd);
safe_delay(_MAX(ms, (uint32_t)BLTOUCH_DELAY)); // BLTOUCH_DELAY is also the *minimum* delay
return triggered();
@@ -64,7 +64,7 @@ void BLTouch::init(const bool set_voltage/*=false*/) {
#else
if (DEBUGGING(LEVELING)) {
- DEBUG_ECHOLNPAIR("last_written_mode - ", last_written_mode);
+ DEBUG_ECHOLNPGM("last_written_mode - ", last_written_mode);
DEBUG_ECHOLNPGM("config mode - "
#if ENABLED(BLTOUCH_SET_5V_MODE)
"BLTOUCH_SET_5V_MODE"
@@ -175,7 +175,7 @@ bool BLTouch::status_proc() {
_set_SW_mode(); // Incidentally, _set_SW_mode() will also RESET any active alarm
const bool tr = triggered(); // If triggered in SW mode, the pin is up, it is STOWED
- if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("BLTouch is ", tr);
+ if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("BLTouch is ", tr);
if (tr) _stow(); else _deploy(); // Turn off SW mode, reset any trigger, honor pin state
return !tr;
@@ -187,7 +187,7 @@ void BLTouch::mode_conv_proc(const bool M5V) {
* BLTOUCH V3.0: This will set the mode (twice) and sadly, a STOW is needed at the end, because of the deploy
* BLTOUCH V3.1: This will set the mode and store it in the eeprom. The STOW is not needed but does not hurt
*/
- if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("BLTouch Set Mode - ", M5V);
+ if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("BLTouch Set Mode - ", M5V);
_deploy();
if (M5V) _set_5V_mode(); else _set_OD_mode();
_mode_store();
diff --git a/Marlin/src/feature/cancel_object.cpp b/Marlin/src/feature/cancel_object.cpp
index ee5716888dc35..bffd2bb72020d 100644
--- a/Marlin/src/feature/cancel_object.cpp
+++ b/Marlin/src/feature/cancel_object.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "../inc/MarlinConfig.h"
#if ENABLED(CANCEL_OBJECTS)
@@ -45,7 +46,7 @@ void CancelObject::set_active_object(const int8_t obj) {
#if BOTH(HAS_STATUS_MESSAGE, CANCEL_OBJECTS_REPORTING)
if (active_object >= 0)
- ui.status_printf_P(0, PSTR(S_FMT " %i"), GET_TEXT(MSG_PRINTING_OBJECT), int(active_object));
+ ui.status_printf(0, F(S_FMT " %i"), GET_TEXT(MSG_PRINTING_OBJECT), int(active_object));
else
ui.reset_status();
#endif
diff --git a/Marlin/src/feature/caselight.cpp b/Marlin/src/feature/caselight.cpp
index 1baef6d46845b..7c4755d0b585b 100644
--- a/Marlin/src/feature/caselight.cpp
+++ b/Marlin/src/feature/caselight.cpp
@@ -70,7 +70,7 @@ void CaseLight::update(const bool sflag) {
#if CASELIGHT_USES_BRIGHTNESS
if (pin_is_pwm())
- analogWrite(pin_t(CASE_LIGHT_PIN), (
+ set_pwm_duty(pin_t(CASE_LIGHT_PIN), (
#if CASE_LIGHT_MAX_PWM == 255
n10ct
#else
diff --git a/Marlin/src/feature/closedloop.cpp b/Marlin/src/feature/closedloop.cpp
index 8a97f0c0cd7b0..1b9f711a6bbdb 100644
--- a/Marlin/src/feature/closedloop.cpp
+++ b/Marlin/src/feature/closedloop.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "../inc/MarlinConfig.h"
#if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER)
diff --git a/Marlin/src/feature/controllerfan.cpp b/Marlin/src/feature/controllerfan.cpp
index 35f567fa8fee8..330f3914f6c0c 100644
--- a/Marlin/src/feature/controllerfan.cpp
+++ b/Marlin/src/feature/controllerfan.cpp
@@ -25,7 +25,7 @@
#if ENABLED(USE_CONTROLLER_FAN)
#include "controllerfan.h"
-#include "../module/stepper/indirection.h"
+#include "../module/stepper.h"
#include "../module/temperature.h"
ControllerFan controllerFan;
@@ -54,33 +54,12 @@ void ControllerFan::update() {
if (ELAPSED(ms, nextMotorCheck)) {
nextMotorCheck = ms + 2500UL; // Not a time critical function, so only check every 2.5s
- #define MOTOR_IS_ON(A,B) (A##_ENABLE_READ() == bool(B##_ENABLE_ON))
- #define _OR_ENABLED_E(N) || MOTOR_IS_ON(E##N,E)
-
- const bool motor_on = (
- ( DISABLED(CONTROLLER_FAN_IGNORE_Z) &&
- ( MOTOR_IS_ON(Z,Z)
- || TERN0(HAS_Z2_ENABLE, MOTOR_IS_ON(Z2,Z))
- || TERN0(HAS_Z3_ENABLE, MOTOR_IS_ON(Z3,Z))
- || TERN0(HAS_Z4_ENABLE, MOTOR_IS_ON(Z4,Z))
- )
- ) || (
- DISABLED(CONTROLLER_FAN_USE_Z_ONLY) &&
- ( MOTOR_IS_ON(X,X) || MOTOR_IS_ON(Y,Y)
- || TERN0(HAS_X2_ENABLE, MOTOR_IS_ON(X2,X))
- || TERN0(HAS_Y2_ENABLE, MOTOR_IS_ON(Y2,Y))
- #if E_STEPPERS
- REPEAT(E_STEPPERS, _OR_ENABLED_E)
- #endif
- )
- )
- );
-
// If any triggers for the controller fan are true...
// - At least one stepper driver is enabled
// - The heated bed is enabled
// - TEMP_SENSOR_BOARD is reporting >= CONTROLLER_FAN_MIN_BOARD_TEMP
- if ( motor_on
+ const ena_mask_t axis_mask = TERN(CONTROLLER_FAN_USE_Z_ONLY, _BV(Z_AXIS), (ena_mask_t)~TERN0(CONTROLLER_FAN_IGNORE_Z, _BV(Z_AXIS)));
+ if ( (stepper.axis_enabled.bits & axis_mask)
|| TERN0(HAS_HEATED_BED, thermalManager.temp_bed.soft_pwm_amount > 0)
|| TERN0(HAS_CONTROLLER_FAN_MIN_BOARD_TEMP, thermalManager.wholeDegBoard() >= CONTROLLER_FAN_MIN_BOARD_TEMP)
) lastMotorOn = ms; //... set time to NOW so the fan will turn on
@@ -93,9 +72,10 @@ void ControllerFan::update() {
? settings.active_speed : settings.idle_speed
);
- // Allow digital or PWM fan output (see M42 handling)
- WRITE(CONTROLLER_FAN_PIN, speed);
- analogWrite(pin_t(CONTROLLER_FAN_PIN), speed);
+ if (PWM_PIN(CONTROLLER_FAN_PIN))
+ set_pwm_duty(pin_t(CONTROLLER_FAN_PIN), speed);
+ else
+ WRITE(CONTROLLER_FAN_PIN, speed);
}
}
diff --git a/Marlin/src/feature/dac/stepper_dac.cpp b/Marlin/src/feature/dac/stepper_dac.cpp
index 6d03808b82827..ff730e93c62c2 100644
--- a/Marlin/src/feature/dac/stepper_dac.cpp
+++ b/Marlin/src/feature/dac/stepper_dac.cpp
@@ -85,15 +85,15 @@ void StepperDAC::print_values() {
if (!dac_present) return;
SERIAL_ECHO_MSG("Stepper current values in % (Amps):");
SERIAL_ECHO_START();
- SERIAL_ECHOPAIR_P(SP_X_LBL, dac_perc(X_AXIS), PSTR(" ("), dac_amps(X_AXIS), PSTR(")"));
+ SERIAL_ECHOPGM_P(SP_X_LBL, dac_perc(X_AXIS), PSTR(" ("), dac_amps(X_AXIS), PSTR(")"));
#if HAS_Y_AXIS
- SERIAL_ECHOPAIR_P(SP_Y_LBL, dac_perc(Y_AXIS), PSTR(" ("), dac_amps(Y_AXIS), PSTR(")"));
+ SERIAL_ECHOPGM_P(SP_Y_LBL, dac_perc(Y_AXIS), PSTR(" ("), dac_amps(Y_AXIS), PSTR(")"));
#endif
#if HAS_Z_AXIS
- SERIAL_ECHOPAIR_P(SP_Z_LBL, dac_perc(Z_AXIS), PSTR(" ("), dac_amps(Z_AXIS), PSTR(")"));
+ SERIAL_ECHOPGM_P(SP_Z_LBL, dac_perc(Z_AXIS), PSTR(" ("), dac_amps(Z_AXIS), PSTR(")"));
#endif
#if HAS_EXTRUDERS
- SERIAL_ECHOLNPAIR_P(SP_E_LBL, dac_perc(E_AXIS), PSTR(" ("), dac_amps(E_AXIS), PSTR(")"));
+ SERIAL_ECHOLNPGM_P(SP_E_LBL, dac_perc(E_AXIS), PSTR(" ("), dac_amps(E_AXIS), PSTR(")"));
#endif
}
diff --git a/Marlin/src/feature/direct_stepping.cpp b/Marlin/src/feature/direct_stepping.cpp
index 2698b53dd6f73..b8ef04fcd9087 100644
--- a/Marlin/src/feature/direct_stepping.cpp
+++ b/Marlin/src/feature/direct_stepping.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "../inc/MarlinConfigPre.h"
#if ENABLED(DIRECT_STEPPING)
@@ -173,7 +174,7 @@ namespace DirectStepping {
template
void SerialPageManager::write_responses() {
if (fatal_error) {
- kill(GET_TEXT(MSG_BAD_PAGE));
+ kill(GET_TEXT_F(MSG_BAD_PAGE));
return;
}
diff --git a/Marlin/src/feature/e_parser.h b/Marlin/src/feature/e_parser.h
index 3723caa35eea0..1dee0cf7550c1 100644
--- a/Marlin/src/feature/e_parser.h
+++ b/Marlin/src/feature/e_parser.h
@@ -199,7 +199,7 @@ class EmergencyParser {
case EP_M112: killed_by_M112 = true; break;
case EP_M410: quickstop_by_M410 = true; break;
#if ENABLED(HOST_PROMPT_SUPPORT)
- case EP_M876SN: host_response_handler(M876_reason); break;
+ case EP_M876SN: hostui.handle_response(M876_reason); break;
#endif
#if ENABLED(REALTIME_REPORTING_COMMANDS)
case EP_GRBL_STATUS: report_current_position_moving(); break;
diff --git a/Marlin/src/feature/encoder_i2c.cpp b/Marlin/src/feature/encoder_i2c.cpp
index 283092e3447fc..87e611f86c234 100644
--- a/Marlin/src/feature/encoder_i2c.cpp
+++ b/Marlin/src/feature/encoder_i2c.cpp
@@ -49,7 +49,7 @@ void I2CPositionEncoder::init(const uint8_t address, const AxisEnum axis) {
initialized = true;
- SERIAL_ECHOLNPAIR("Setting up encoder on ", AS_CHAR(axis_codes[encoderAxis]), " axis, addr = ", address);
+ SERIAL_ECHOLNPGM("Setting up encoder on ", AS_CHAR(axis_codes[encoderAxis]), " axis, addr = ", address);
position = get_position();
}
@@ -67,7 +67,7 @@ void I2CPositionEncoder::update() {
/*
if (trusted) { //commented out as part of the note below
trusted = false;
- SERIAL_ECHOLNPAIR("Fault detected on ", AS_CHAR(axis_codes[encoderAxis]), " axis encoder. Disengaging error correction until module is trusted again.");
+ SERIAL_ECHOLNPGM("Fault detected on ", AS_CHAR(axis_codes[encoderAxis]), " axis encoder. Disengaging error correction until module is trusted again.");
}
*/
return;
@@ -92,7 +92,7 @@ void I2CPositionEncoder::update() {
if (millis() - lastErrorTime > I2CPE_TIME_TRUSTED) {
trusted = true;
- SERIAL_ECHOLNPAIR("Untrusted encoder module on ", AS_CHAR(axis_codes[encoderAxis]), " axis has been fault-free for set duration, reinstating error correction.");
+ SERIAL_ECHOLNPGM("Untrusted encoder module on ", AS_CHAR(axis_codes[encoderAxis]), " axis has been fault-free for set duration, reinstating error correction.");
//the encoder likely lost its place when the error occurred, so we'll reset and use the printer's
//idea of where it the axis is to re-initialize
@@ -103,10 +103,10 @@ void I2CPositionEncoder::update() {
zeroOffset -= (positionInTicks - get_position());
#ifdef I2CPE_DEBUG
- SERIAL_ECHOLNPAIR("Current position is ", pos);
- SERIAL_ECHOLNPAIR("Position in encoder ticks is ", positionInTicks);
- SERIAL_ECHOLNPAIR("New zero-offset of ", zeroOffset);
- SERIAL_ECHOPAIR("New position reads as ", get_position());
+ SERIAL_ECHOLNPGM("Current position is ", pos);
+ SERIAL_ECHOLNPGM("Position in encoder ticks is ", positionInTicks);
+ SERIAL_ECHOLNPGM("New zero-offset of ", zeroOffset);
+ SERIAL_ECHOPGM("New position reads as ", get_position());
SERIAL_CHAR('(');
SERIAL_DECIMAL(mm_from_count(get_position()));
SERIAL_ECHOLNPGM(")");
@@ -149,12 +149,12 @@ void I2CPositionEncoder::update() {
const int32_t error = get_axis_error_steps(false);
#endif
- //SERIAL_ECHOLNPAIR("Axis error steps: ", error);
+ //SERIAL_ECHOLNPGM("Axis error steps: ", error);
#ifdef I2CPE_ERR_THRESH_ABORT
if (ABS(error) > I2CPE_ERR_THRESH_ABORT * planner.settings.axis_steps_per_mm[encoderAxis]) {
- //kill(PSTR("Significant Error"));
- SERIAL_ECHOLNPAIR("Axis error over threshold, aborting!", error);
+ //kill(F("Significant Error"));
+ SERIAL_ECHOLNPGM("Axis error over threshold, aborting!", error);
safe_delay(5000);
}
#endif
@@ -173,7 +173,7 @@ void I2CPositionEncoder::update() {
LOOP_L_N(i, I2CPE_ERR_PRST_ARRAY_SIZE) sumP += errPrst[i];
const int32_t errorP = int32_t(sumP * RECIPROCAL(I2CPE_ERR_PRST_ARRAY_SIZE));
SERIAL_CHAR(axis_codes[encoderAxis]);
- SERIAL_ECHOLNPAIR(" : CORRECT ERR ", errorP * planner.steps_to_mm[encoderAxis], "mm");
+ SERIAL_ECHOLNPGM(" : CORRECT ERR ", errorP * planner.mm_per_step[encoderAxis], "mm");
babystep.add_steps(encoderAxis, -LROUND(errorP));
errPrstIdx = 0;
}
@@ -193,7 +193,7 @@ void I2CPositionEncoder::update() {
const millis_t ms = millis();
if (ELAPSED(ms, nextErrorCountTime)) {
SERIAL_CHAR(axis_codes[encoderAxis]);
- SERIAL_ECHOLNPAIR(" : LARGE ERR ", error, "; diffSum=", diffSum);
+ SERIAL_ECHOLNPGM(" : LARGE ERR ", error, "; diffSum=", diffSum);
errorCount++;
nextErrorCountTime = ms + I2CPE_ERR_CNT_DEBOUNCE_MS;
}
@@ -213,7 +213,7 @@ void I2CPositionEncoder::set_homed() {
#ifdef I2CPE_DEBUG
SERIAL_CHAR(axis_codes[encoderAxis]);
- SERIAL_ECHOLNPAIR(" axis encoder homed, offset of ", zeroOffset, " ticks.");
+ SERIAL_ECHOLNPGM(" axis encoder homed, offset of ", zeroOffset, " ticks.");
#endif
}
}
@@ -232,7 +232,7 @@ bool I2CPositionEncoder::passes_test(const bool report) {
if (report) {
if (H != I2CPE_MAG_SIG_GOOD) SERIAL_ECHOPGM("Warning. ");
SERIAL_CHAR(axis_codes[encoderAxis]);
- serial_ternary(H == I2CPE_MAG_SIG_BAD, PSTR(" axis "), PSTR("magnetic strip "), PSTR("encoder "));
+ serial_ternary(H == I2CPE_MAG_SIG_BAD, F(" axis "), F("magnetic strip "), F("encoder "));
switch (H) {
case I2CPE_MAG_SIG_GOOD:
case I2CPE_MAG_SIG_MID:
@@ -253,7 +253,7 @@ float I2CPositionEncoder::get_axis_error_mm(const bool report) {
if (report) {
SERIAL_CHAR(axis_codes[encoderAxis]);
- SERIAL_ECHOLNPAIR(" axis target=", target, "mm; actual=", actual, "mm; err=", error, "mm");
+ SERIAL_ECHOLNPGM(" axis target=", target, "mm; actual=", actual, "mm; err=", error, "mm");
}
return error;
@@ -288,7 +288,7 @@ int32_t I2CPositionEncoder::get_axis_error_steps(const bool report) {
if (report) {
SERIAL_CHAR(axis_codes[encoderAxis]);
- SERIAL_ECHOLNPAIR(" axis target=", target, "; actual=", encoderCountInStepperTicksScaled, "; err=", error);
+ SERIAL_ECHOLNPGM(" axis target=", target, "; actual=", encoderCountInStepperTicksScaled, "; err=", error);
}
if (suppressOutput) {
@@ -424,15 +424,15 @@ void I2CPositionEncoder::calibrate_steps_mm(const uint8_t iter) {
travelledDistance = mm_from_count(ABS(stopCount - startCount));
- SERIAL_ECHOLNPAIR("Attempted travel: ", travelDistance, "mm");
- SERIAL_ECHOLNPAIR(" Actual travel: ", travelledDistance, "mm");
+ SERIAL_ECHOLNPGM("Attempted travel: ", travelDistance, "mm");
+ SERIAL_ECHOLNPGM(" Actual travel: ", travelledDistance, "mm");
//Calculate new axis steps per unit
old_steps_mm = planner.settings.axis_steps_per_mm[encoderAxis];
new_steps_mm = (old_steps_mm * travelDistance) / travelledDistance;
- SERIAL_ECHOLNPAIR("Old steps/mm: ", old_steps_mm);
- SERIAL_ECHOLNPAIR("New steps/mm: ", new_steps_mm);
+ SERIAL_ECHOLNPGM("Old steps/mm: ", old_steps_mm);
+ SERIAL_ECHOLNPGM("New steps/mm: ", new_steps_mm);
//Save new value
planner.settings.axis_steps_per_mm[encoderAxis] = new_steps_mm;
@@ -449,7 +449,7 @@ void I2CPositionEncoder::calibrate_steps_mm(const uint8_t iter) {
if (iter > 1) {
total /= (float)iter;
- SERIAL_ECHOLNPAIR("Average steps/mm: ", total);
+ SERIAL_ECHOLNPGM("Average steps/mm: ", total);
}
ec = oldec;
@@ -675,18 +675,18 @@ void I2CPositionEncodersMgr::change_module_address(const uint8_t oldaddr, const
// First check 'new' address is not in use
Wire.beginTransmission(I2C_ADDRESS(newaddr));
if (!Wire.endTransmission()) {
- SERIAL_ECHOLNPAIR("?There is already a device with that address on the I2C bus! (", newaddr, ")");
+ SERIAL_ECHOLNPGM("?There is already a device with that address on the I2C bus! (", newaddr, ")");
return;
}
// Now check that we can find the module on the oldaddr address
Wire.beginTransmission(I2C_ADDRESS(oldaddr));
if (Wire.endTransmission()) {
- SERIAL_ECHOLNPAIR("?No module detected at this address! (", oldaddr, ")");
+ SERIAL_ECHOLNPGM("?No module detected at this address! (", oldaddr, ")");
return;
}
- SERIAL_ECHOLNPAIR("Module found at ", oldaddr, ", changing address to ", newaddr);
+ SERIAL_ECHOLNPGM("Module found at ", oldaddr, ", changing address to ", newaddr);
// Change the modules address
Wire.beginTransmission(I2C_ADDRESS(oldaddr));
@@ -722,11 +722,11 @@ void I2CPositionEncodersMgr::report_module_firmware(const uint8_t address) {
// First check there is a module
Wire.beginTransmission(I2C_ADDRESS(address));
if (Wire.endTransmission()) {
- SERIAL_ECHOLNPAIR("?No module detected at this address! (", address, ")");
+ SERIAL_ECHOLNPGM("?No module detected at this address! (", address, ")");
return;
}
- SERIAL_ECHOLNPAIR("Requesting version info from module at address ", address, ":");
+ SERIAL_ECHOLNPGM("Requesting version info from module at address ", address, ":");
Wire.beginTransmission(I2C_ADDRESS(address));
Wire.write(I2CPE_SET_REPORT_MODE);
@@ -773,13 +773,13 @@ int8_t I2CPositionEncodersMgr::parse() {
else if (parser.seenval('I')) {
if (!parser.has_value()) {
- SERIAL_ECHOLNPAIR("?I seen, but no index specified! [0-", I2CPE_ENCODER_CNT - 1, "]");
+ SERIAL_ECHOLNPGM("?I seen, but no index specified! [0-", I2CPE_ENCODER_CNT - 1, "]");
return I2CPE_PARSE_ERR;
};
I2CPE_idx = parser.value_byte();
if (I2CPE_idx >= I2CPE_ENCODER_CNT) {
- SERIAL_ECHOLNPAIR("?Index out of range. [0-", I2CPE_ENCODER_CNT - 1, "]");
+ SERIAL_ECHOLNPGM("?Index out of range. [0-", I2CPE_ENCODER_CNT - 1, "]");
return I2CPE_PARSE_ERR;
}
@@ -954,7 +954,7 @@ void I2CPositionEncodersMgr::M864() {
else return;
}
- SERIAL_ECHOLNPAIR("Changing module at address ", I2CPE_addr, " to address ", newAddress);
+ SERIAL_ECHOLNPGM("Changing module at address ", I2CPE_addr, " to address ", newAddress);
change_module_address(I2CPE_addr, newAddress);
}
diff --git a/Marlin/src/feature/encoder_i2c.h b/Marlin/src/feature/encoder_i2c.h
index 20871af98ccbf..50fb27a135cae 100644
--- a/Marlin/src/feature/encoder_i2c.h
+++ b/Marlin/src/feature/encoder_i2c.h
@@ -236,7 +236,7 @@ class I2CPositionEncodersMgr {
static void report_status(const int8_t idx) {
CHECK_IDX();
- SERIAL_ECHOLNPAIR("Encoder ", idx, ": ");
+ SERIAL_ECHOLNPGM("Encoder ", idx, ": ");
encoders[idx].get_raw_count();
encoders[idx].passes_test(true);
}
@@ -261,32 +261,32 @@ class I2CPositionEncodersMgr {
static void report_error_count(const int8_t idx, const AxisEnum axis) {
CHECK_IDX();
- SERIAL_ECHOLNPAIR("Error count on ", AS_CHAR(axis_codes[axis]), " axis is ", encoders[idx].get_error_count());
+ SERIAL_ECHOLNPGM("Error count on ", AS_CHAR(axis_codes[axis]), " axis is ", encoders[idx].get_error_count());
}
static void reset_error_count(const int8_t idx, const AxisEnum axis) {
CHECK_IDX();
encoders[idx].set_error_count(0);
- SERIAL_ECHOLNPAIR("Error count on ", AS_CHAR(axis_codes[axis]), " axis has been reset.");
+ SERIAL_ECHOLNPGM("Error count on ", AS_CHAR(axis_codes[axis]), " axis has been reset.");
}
static void enable_ec(const int8_t idx, const bool enabled, const AxisEnum axis) {
CHECK_IDX();
encoders[idx].set_ec_enabled(enabled);
- SERIAL_ECHOPAIR("Error correction on ", AS_CHAR(axis_codes[axis]));
+ SERIAL_ECHOPGM("Error correction on ", AS_CHAR(axis_codes[axis]));
SERIAL_ECHO_TERNARY(encoders[idx].get_ec_enabled(), " axis is ", "en", "dis", "abled.\n");
}
static void set_ec_threshold(const int8_t idx, const float newThreshold, const AxisEnum axis) {
CHECK_IDX();
encoders[idx].set_ec_threshold(newThreshold);
- SERIAL_ECHOLNPAIR("Error correct threshold for ", AS_CHAR(axis_codes[axis]), " axis set to ", newThreshold, "mm.");
+ SERIAL_ECHOLNPGM("Error correct threshold for ", AS_CHAR(axis_codes[axis]), " axis set to ", newThreshold, "mm.");
}
static void get_ec_threshold(const int8_t idx, const AxisEnum axis) {
CHECK_IDX();
const float threshold = encoders[idx].get_ec_threshold();
- SERIAL_ECHOLNPAIR("Error correct threshold for ", AS_CHAR(axis_codes[axis]), " axis is ", threshold, "mm.");
+ SERIAL_ECHOLNPGM("Error correct threshold for ", AS_CHAR(axis_codes[axis]), " axis is ", threshold, "mm.");
}
static int8_t idx_from_axis(const AxisEnum axis) {
diff --git a/Marlin/src/feature/fwretract.cpp b/Marlin/src/feature/fwretract.cpp
index 41dbf430e829d..4077d8d1c2098 100644
--- a/Marlin/src/feature/fwretract.cpp
+++ b/Marlin/src/feature/fwretract.cpp
@@ -36,7 +36,7 @@ FWRetract fwretract; // Single instance - this calls the constructor
#include "../module/planner.h"
#include "../module/stepper.h"
-#include "../gcode/parser.h"
+#include "../gcode/gcode.h"
#if ENABLED(RETRACT_SYNC_MIXING)
#include "mixing.h"
@@ -75,7 +75,7 @@ void FWRetract::reset() {
LOOP_L_N(i, EXTRUDERS) {
retracted[i] = false;
- TERN_(HAS_MULTI_EXTRUDER, retracted_swap[i] = false);
+ E_TERN_(retracted_swap[i] = false);
current_retract[i] = 0.0;
}
}
@@ -91,7 +91,7 @@ void FWRetract::reset() {
* Note: Auto-retract will apply the set Z hop in addition to any Z hop
* included in the G-code. Use M207 Z0 to to prevent double hop.
*/
-void FWRetract::retract(const bool retracting OPTARG(HAS_MULTI_EXTRUDER, bool swapping/*=false*/)) {
+void FWRetract::retract(const bool retracting E_OPTARG(bool swapping/*=false*/)) {
// Prevent two retracts or recovers in a row
if (retracted[active_extruder] == retracting) return;
@@ -106,20 +106,20 @@ void FWRetract::retract(const bool retracting OPTARG(HAS_MULTI_EXTRUDER, bool sw
#endif
/* // debugging
- SERIAL_ECHOLNPAIR(
+ SERIAL_ECHOLNPGM(
"retracting ", AS_DIGIT(retracting),
" swapping ", swapping,
" active extruder ", active_extruder
);
LOOP_L_N(i, EXTRUDERS) {
- SERIAL_ECHOLNPAIR("retracted[", i, "] ", AS_DIGIT(retracted[i]));
+ SERIAL_ECHOLNPGM("retracted[", i, "] ", AS_DIGIT(retracted[i]));
#if HAS_MULTI_EXTRUDER
- SERIAL_ECHOLNPAIR("retracted_swap[", i, "] ", AS_DIGIT(retracted_swap[i]));
+ SERIAL_ECHOLNPGM("retracted_swap[", i, "] ", AS_DIGIT(retracted_swap[i]));
#endif
}
- SERIAL_ECHOLNPAIR("current_position.z ", current_position.z);
- SERIAL_ECHOLNPAIR("current_position.e ", current_position.e);
- SERIAL_ECHOLNPAIR("current_hop ", current_hop);
+ SERIAL_ECHOLNPGM("current_position.z ", current_position.z);
+ SERIAL_ECHOLNPGM("current_position.e ", current_position.e);
+ SERIAL_ECHOLNPGM("current_hop ", current_hop);
//*/
const float base_retract = TERN1(RETRACT_SYNC_MIXING, (MIXING_STEPPERS))
@@ -181,18 +181,18 @@ void FWRetract::retract(const bool retracting OPTARG(HAS_MULTI_EXTRUDER, bool sw
#endif
/* // debugging
- SERIAL_ECHOLNPAIR("retracting ", AS_DIGIT(retracting));
- SERIAL_ECHOLNPAIR("swapping ", AS_DIGIT(swapping));
- SERIAL_ECHOLNPAIR("active_extruder ", active_extruder);
+ SERIAL_ECHOLNPGM("retracting ", AS_DIGIT(retracting));
+ SERIAL_ECHOLNPGM("swapping ", AS_DIGIT(swapping));
+ SERIAL_ECHOLNPGM("active_extruder ", active_extruder);
LOOP_L_N(i, EXTRUDERS) {
- SERIAL_ECHOLNPAIR("retracted[", i, "] ", AS_DIGIT(retracted[i]));
+ SERIAL_ECHOLNPGM("retracted[", i, "] ", AS_DIGIT(retracted[i]));
#if HAS_MULTI_EXTRUDER
- SERIAL_ECHOLNPAIR("retracted_swap[", i, "] ", AS_DIGIT(retracted_swap[i]));
+ SERIAL_ECHOLNPGM("retracted_swap[", i, "] ", AS_DIGIT(retracted_swap[i]));
#endif
}
- SERIAL_ECHOLNPAIR("current_position.z ", current_position.z);
- SERIAL_ECHOLNPAIR("current_position.e ", current_position.e);
- SERIAL_ECHOLNPAIR("current_hop ", current_hop);
+ SERIAL_ECHOLNPGM("current_position.z ", current_position.z);
+ SERIAL_ECHOLNPGM("current_position.e ", current_position.e);
+ SERIAL_ECHOLNPGM("current_hop ", current_hop);
//*/
}
@@ -214,9 +214,8 @@ void FWRetract::M207() {
if (parser.seenval('W')) settings.swap_retract_length = parser.value_axis_units(E_AXIS);
}
-void FWRetract::M207_report(const bool forReplay/*=false*/) {
- if (!forReplay) { SERIAL_ECHO_MSG("; Retract: S F Z"); SERIAL_ECHO_START(); }
- SERIAL_ECHOLNPAIR_P(
+void FWRetract::M207_report() {
+ SERIAL_ECHOLNPGM_P(
PSTR(" M207 S"), LINEAR_UNIT(settings.retract_length)
, PSTR(" W"), LINEAR_UNIT(settings.swap_retract_length)
, PSTR(" F"), LINEAR_UNIT(MMS_TO_MMM(settings.retract_feedrate_mm_s))
@@ -240,9 +239,8 @@ void FWRetract::M208() {
if (parser.seen('W')) settings.swap_retract_recover_extra = parser.value_axis_units(E_AXIS);
}
-void FWRetract::M208_report(const bool forReplay/*=false*/) {
- if (!forReplay) { SERIAL_ECHO_MSG("; Recover: S F"); SERIAL_ECHO_START(); }
- SERIAL_ECHOLNPAIR(
+void FWRetract::M208_report() {
+ SERIAL_ECHOLNPGM(
" M208 S", LINEAR_UNIT(settings.retract_recover_extra)
, " W", LINEAR_UNIT(settings.swap_retract_recover_extra)
, " F", LINEAR_UNIT(MMS_TO_MMM(settings.retract_recover_feedrate_mm_s))
@@ -262,9 +260,8 @@ void FWRetract::M208_report(const bool forReplay/*=false*/) {
enable_autoretract(parser.value_bool());
}
- void FWRetract::M209_report(const bool forReplay/*=false*/) {
- if (!forReplay) { SERIAL_ECHO_MSG("; Auto-Retract: S=0 to disable, 1 to interpret E-only moves as retract/recover"); SERIAL_ECHO_START(); }
- SERIAL_ECHOLNPAIR(" M209 S", AS_DIGIT(autoretract_enabled));
+ void FWRetract::M209_report() {
+ SERIAL_ECHOLNPGM(" M209 S", AS_DIGIT(autoretract_enabled));
}
#endif // FWRETRACT_AUTORETRACT
diff --git a/Marlin/src/feature/fwretract.h b/Marlin/src/feature/fwretract.h
index cd93e9cf39ede..d6d0432e3aa70 100644
--- a/Marlin/src/feature/fwretract.h
+++ b/Marlin/src/feature/fwretract.h
@@ -74,15 +74,15 @@ class FWRetract {
#endif
}
- static void retract(const bool retracting OPTARG(HAS_MULTI_EXTRUDER, bool swapping = false));
+ static void retract(const bool retracting E_OPTARG(bool swapping=false));
+ static void M207_report();
static void M207();
- static void M207_report(const bool forReplay=false);
+ static void M208_report();
static void M208();
- static void M208_report(const bool forReplay=false);
#if ENABLED(FWRETRACT_AUTORETRACT)
+ static void M209_report();
static void M209();
- static void M209_report(const bool forReplay=false);
#endif
};
diff --git a/Marlin/src/feature/host_actions.cpp b/Marlin/src/feature/host_actions.cpp
index 62e60320f7638..be7b055b55f7e 100644
--- a/Marlin/src/feature/host_actions.cpp
+++ b/Marlin/src/feature/host_actions.cpp
@@ -24,10 +24,10 @@
#if ENABLED(HOST_ACTION_COMMANDS)
-#include "host_actions.h"
-
//#define DEBUG_HOST_ACTIONS
+#include "host_actions.h"
+
#if ENABLED(ADVANCED_PAUSE_FEATURE)
#include "pause.h"
#include "../gcode/queue.h"
@@ -37,37 +37,57 @@
#include "runout.h"
#endif
-void host_action(PGM_P const pstr, const bool eol) {
+HostUI hostui;
+
+flag_t HostUI::flag;
+
+void HostUI::action(FSTR_P const fstr, const bool eol) {
+ if (!flag.bits) return;
PORT_REDIRECT(SerialMask::All);
SERIAL_ECHOPGM("//action:");
- SERIAL_ECHOPGM_P(pstr);
+ SERIAL_ECHOF(fstr);
if (eol) SERIAL_EOL();
}
#ifdef ACTION_ON_KILL
- void host_action_kill() { host_action(PSTR(ACTION_ON_KILL)); }
+ void HostUI::kill() { action(F(ACTION_ON_KILL)); }
#endif
#ifdef ACTION_ON_PAUSE
- void host_action_pause(const bool eol/*=true*/) { host_action(PSTR(ACTION_ON_PAUSE), eol); }
+ void HostUI::pause(const bool eol/*=true*/) { action(F(ACTION_ON_PAUSE), eol); }
#endif
#ifdef ACTION_ON_PAUSED
- void host_action_paused(const bool eol/*=true*/) { host_action(PSTR(ACTION_ON_PAUSED), eol); }
+ void HostUI::paused(const bool eol/*=true*/) { action(F(ACTION_ON_PAUSED), eol); }
#endif
#ifdef ACTION_ON_RESUME
- void host_action_resume() { host_action(PSTR(ACTION_ON_RESUME)); }
+ void HostUI::resume() { action(F(ACTION_ON_RESUME)); }
#endif
#ifdef ACTION_ON_RESUMED
- void host_action_resumed() { host_action(PSTR(ACTION_ON_RESUMED)); }
+ void HostUI::resumed() { action(F(ACTION_ON_RESUMED)); }
#endif
#ifdef ACTION_ON_CANCEL
- void host_action_cancel() { host_action(PSTR(ACTION_ON_CANCEL)); }
+ void HostUI::cancel() { action(F(ACTION_ON_CANCEL)); }
#endif
#ifdef ACTION_ON_START
- void host_action_start() { host_action(PSTR(ACTION_ON_START)); }
+ void HostUI::start() { action(F(ACTION_ON_START)); }
+#endif
+
+#if ENABLED(G29_RETRY_AND_RECOVER)
+ #ifdef ACTION_ON_G29_RECOVER
+ void HostUI::g29_recover() { action(F(ACTION_ON_G29_RECOVER)); }
+ #endif
+ #ifdef ACTION_ON_G29_FAILURE
+ void HostUI::g29_failure() { action(F(ACTION_ON_G29_FAILURE)); }
+ #endif
+#endif
+
+#ifdef SHUTDOWN_ACTION
+ void HostUI::shutdown() { action(F(SHUTDOWN_ACTION)); }
#endif
#if ENABLED(HOST_PROMPT_SUPPORT)
+ PromptReason HostUI::host_prompt_reason = PROMPT_NOT_DEFINED;
+
PGMSTR(CONTINUE_STR, "Continue");
PGMSTR(DISMISS_STR, "Dismiss");
@@ -75,64 +95,69 @@ void host_action(PGM_P const pstr, const bool eol) {
extern bool wait_for_user;
#endif
- PromptReason host_prompt_reason = PROMPT_NOT_DEFINED;
-
- void host_action_notify(const char * const message) {
+ void HostUI::notify(const char * const cstr) {
+ if (!flag.bits) return;
PORT_REDIRECT(SerialMask::All);
- host_action(PSTR("notification "), false);
- SERIAL_ECHOLN(message);
+ action(F("notification "), false);
+ SERIAL_ECHOLN(cstr);
}
- void host_action_notify_P(PGM_P const message) {
+ void HostUI::notify_P(PGM_P const pstr) {
+ if (!flag.bits) return;
PORT_REDIRECT(SerialMask::All);
- host_action(PSTR("notification "), false);
- SERIAL_ECHOLNPGM_P(message);
+ action(F("notification "), false);
+ SERIAL_ECHOLNPGM_P(pstr);
}
- void host_action_prompt(PGM_P const ptype, const bool eol=true) {
+ void HostUI::prompt(FSTR_P const ptype, const bool eol/*=true*/) {
+ if (!flag.bits) return;
PORT_REDIRECT(SerialMask::All);
- host_action(PSTR("prompt_"), false);
- SERIAL_ECHOPGM_P(ptype);
+ action(F("prompt_"), false);
+ SERIAL_ECHOF(ptype);
if (eol) SERIAL_EOL();
}
- void host_action_prompt_plus(PGM_P const ptype, PGM_P const pstr, const char extra_char='\0') {
- host_action_prompt(ptype, false);
+ void HostUI::prompt_plus(FSTR_P const ptype, FSTR_P const fstr, const char extra_char/*='\0'*/) {
+ if (!flag.bits) return;
+ prompt(ptype, false);
PORT_REDIRECT(SerialMask::All);
SERIAL_CHAR(' ');
- SERIAL_ECHOPGM_P(pstr);
+ SERIAL_ECHOF(fstr);
if (extra_char != '\0') SERIAL_CHAR(extra_char);
SERIAL_EOL();
}
- void host_action_prompt_begin(const PromptReason reason, PGM_P const pstr, const char extra_char/*='\0'*/) {
- host_action_prompt_end();
+ void HostUI::prompt_begin(const PromptReason reason, FSTR_P const fstr, const char extra_char/*='\0'*/) {
+ if (!flag.bits) return;
+ prompt_end();
host_prompt_reason = reason;
- host_action_prompt_plus(PSTR("begin"), pstr, extra_char);
+ prompt_plus(F("begin"), fstr, extra_char);
}
- void host_action_prompt_button(PGM_P const pstr) { host_action_prompt_plus(PSTR("button"), pstr); }
- void host_action_prompt_end() { host_action_prompt(PSTR("end")); }
- void host_action_prompt_show() { host_action_prompt(PSTR("show")); }
-
- void _host_prompt_show(PGM_P const btn1/*=nullptr*/, PGM_P const btn2/*=nullptr*/) {
- if (btn1) host_action_prompt_button(btn1);
- if (btn2) host_action_prompt_button(btn2);
- host_action_prompt_show();
+ void HostUI::prompt_button(FSTR_P const fstr) { prompt_plus(F("button"), fstr); }
+ void HostUI::prompt_end() { prompt(F("end")); }
+ void HostUI::prompt_show() { prompt(F("show")); }
+
+ void HostUI::_prompt_show(FSTR_P const btn1, FSTR_P const btn2) {
+ if (btn1) prompt_button(btn1);
+ if (btn2) prompt_button(btn2);
+ prompt_show();
}
- void host_prompt_do(const PromptReason reason, PGM_P const pstr, PGM_P const btn1/*=nullptr*/, PGM_P const btn2/*=nullptr*/) {
- host_action_prompt_begin(reason, pstr);
- _host_prompt_show(btn1, btn2);
+ void HostUI::prompt_do(const PromptReason reason, FSTR_P const fstr, FSTR_P const btn1/*=nullptr*/, FSTR_P const btn2/*=nullptr*/) {
+ prompt_begin(reason, fstr);
+ _prompt_show(btn1, btn2);
}
- void host_prompt_do(const PromptReason reason, PGM_P const pstr, const char extra_char, PGM_P const btn1/*=nullptr*/, PGM_P const btn2/*=nullptr*/) {
- host_action_prompt_begin(reason, pstr, extra_char);
- _host_prompt_show(btn1, btn2);
+ void HostUI::prompt_do(const PromptReason reason, FSTR_P const fstr, const char extra_char, FSTR_P const btn1/*=nullptr*/, FSTR_P const btn2/*=nullptr*/) {
+ prompt_begin(reason, fstr, extra_char);
+ _prompt_show(btn1, btn2);
}
- void filament_load_host_prompt() {
- const bool disable_to_continue = TERN0(HAS_FILAMENT_SENSOR, runout.filament_ran_out);
- host_prompt_do(PROMPT_FILAMENT_RUNOUT, PSTR("Paused"), PSTR("PurgeMore"),
- disable_to_continue ? PSTR("DisableRunout") : CONTINUE_STR
- );
- }
+ #if ENABLED(ADVANCED_PAUSE_FEATURE)
+ void HostUI::filament_load_prompt() {
+ const bool disable_to_continue = TERN0(HAS_FILAMENT_SENSOR, runout.filament_ran_out);
+ prompt_do(PROMPT_FILAMENT_RUNOUT, F("Paused"), F("PurgeMore"),
+ disable_to_continue ? F("DisableRunout") : FPSTR(CONTINUE_STR)
+ );
+ }
+ #endif
//
// Handle responses from the host, such as:
@@ -141,7 +166,7 @@ void host_action(PGM_P const pstr, const bool eol) {
// - Resume Print response
// - Dismissal of info
//
- void host_response_handler(const uint8_t response) {
+ void HostUI::handle_response(const uint8_t response) {
const PromptReason hpr = host_prompt_reason;
host_prompt_reason = PROMPT_NOT_DEFINED; // Reset now ahead of logic
switch (hpr) {
diff --git a/Marlin/src/feature/host_actions.h b/Marlin/src/feature/host_actions.h
index 065b59d755edd..45379afc29ec3 100644
--- a/Marlin/src/feature/host_actions.h
+++ b/Marlin/src/feature/host_actions.h
@@ -24,34 +24,13 @@
#include "../inc/MarlinConfigPre.h"
#include "../HAL/shared/Marduino.h"
-void host_action(PGM_P const pstr, const bool eol=true);
-
-#ifdef ACTION_ON_KILL
- void host_action_kill();
-#endif
-#ifdef ACTION_ON_PAUSE
- void host_action_pause(const bool eol=true);
-#endif
-#ifdef ACTION_ON_PAUSED
- void host_action_paused(const bool eol=true);
-#endif
-#ifdef ACTION_ON_RESUME
- void host_action_resume();
-#endif
-#ifdef ACTION_ON_RESUMED
- void host_action_resumed();
-#endif
-#ifdef ACTION_ON_CANCEL
- void host_action_cancel();
-#endif
-#ifdef ACTION_ON_START
- void host_action_start();
-#endif
+typedef union {
+ uint8_t bits;
+ struct { bool info:1, errors:1, debug:1; };
+} flag_t;
#if ENABLED(HOST_PROMPT_SUPPORT)
- extern const char CONTINUE_STR[], DISMISS_STR[];
-
enum PromptReason : uint8_t {
PROMPT_NOT_DEFINED,
PROMPT_FILAMENT_RUNOUT,
@@ -61,21 +40,83 @@ void host_action(PGM_P const pstr, const bool eol=true);
PROMPT_INFO
};
- extern PromptReason host_prompt_reason;
+#endif
- void host_response_handler(const uint8_t response);
- void host_action_notify(const char * const message);
- void host_action_notify_P(PGM_P const message);
- void host_action_prompt_begin(const PromptReason reason, PGM_P const pstr, const char extra_char='\0');
- void host_action_prompt_button(PGM_P const pstr);
- void host_action_prompt_end();
- void host_action_prompt_show();
- void host_prompt_do(const PromptReason reason, PGM_P const pstr, PGM_P const btn1=nullptr, PGM_P const btn2=nullptr);
- void host_prompt_do(const PromptReason reason, PGM_P const pstr, const char extra_char, PGM_P const btn1=nullptr, PGM_P const btn2=nullptr);
- inline void host_prompt_open(const PromptReason reason, PGM_P const pstr, PGM_P const btn1=nullptr, PGM_P const btn2=nullptr) {
- if (host_prompt_reason == PROMPT_NOT_DEFINED) host_prompt_do(reason, pstr, btn1, btn2);
- }
+class HostUI {
+ public:
- void filament_load_host_prompt();
+ static flag_t flag;
+ HostUI() { flag.bits = 0xFF; }
-#endif
+ static void action(FSTR_P const fstr, const bool eol=true);
+
+ #ifdef ACTION_ON_KILL
+ static void kill();
+ #endif
+ #ifdef ACTION_ON_PAUSE
+ static void pause(const bool eol=true);
+ #endif
+ #ifdef ACTION_ON_PAUSED
+ static void paused(const bool eol=true);
+ #endif
+ #ifdef ACTION_ON_RESUME
+ static void resume();
+ #endif
+ #ifdef ACTION_ON_RESUMED
+ static void resumed();
+ #endif
+ #ifdef ACTION_ON_CANCEL
+ static void cancel();
+ #endif
+ #ifdef ACTION_ON_START
+ static void start();
+ #endif
+ #ifdef SHUTDOWN_ACTION
+ static void shutdown();
+ #endif
+
+ #if ENABLED(G29_RETRY_AND_RECOVER)
+ #ifdef ACTION_ON_G29_RECOVER
+ static void g29_recover();
+ #endif
+ #ifdef ACTION_ON_G29_FAILURE
+ static void g29_failure();
+ #endif
+ #endif
+
+ #if ENABLED(HOST_PROMPT_SUPPORT)
+ private:
+ static void prompt(FSTR_P const ptype, const bool eol=true);
+ static void prompt_plus(FSTR_P const ptype, FSTR_P const fstr, const char extra_char='\0');
+ static void prompt_show();
+ static void _prompt_show(FSTR_P const btn1, FSTR_P const btn2);
+
+ public:
+ static PromptReason host_prompt_reason;
+
+ static void handle_response(const uint8_t response);
+
+ static void notify_P(PGM_P const message);
+ static inline void notify(FSTR_P const fmsg) { notify_P(FTOP(fmsg)); }
+ static void notify(const char * const message);
+
+ static void prompt_begin(const PromptReason reason, FSTR_P const fstr, const char extra_char='\0');
+ static void prompt_button(FSTR_P const fstr);
+ static void prompt_end();
+ static void prompt_do(const PromptReason reason, FSTR_P const pstr, FSTR_P const btn1=nullptr, FSTR_P const btn2=nullptr);
+ static void prompt_do(const PromptReason reason, FSTR_P const pstr, const char extra_char, FSTR_P const btn1=nullptr, FSTR_P const btn2=nullptr);
+ static inline void prompt_open(const PromptReason reason, FSTR_P const pstr, FSTR_P const btn1=nullptr, FSTR_P const btn2=nullptr) {
+ if (host_prompt_reason == PROMPT_NOT_DEFINED) prompt_do(reason, pstr, btn1, btn2);
+ }
+
+ #if ENABLED(ADVANCED_PAUSE_FEATURE)
+ static void filament_load_prompt();
+ #endif
+
+ #endif
+
+};
+
+extern HostUI hostui;
+
+extern const char CONTINUE_STR[], DISMISS_STR[];
diff --git a/Marlin/src/feature/hotend_idle.cpp b/Marlin/src/feature/hotend_idle.cpp
index b962743ed0456..4b137f42da7bd 100644
--- a/Marlin/src/feature/hotend_idle.cpp
+++ b/Marlin/src/feature/hotend_idle.cpp
@@ -77,7 +77,7 @@ void HotendIdleProtection::check() {
void HotendIdleProtection::timed_out() {
next_protect_ms = 0;
SERIAL_ECHOLNPGM("Hotend Idle Timeout");
- LCD_MESSAGEPGM(MSG_HOTEND_IDLE_TIMEOUT);
+ LCD_MESSAGE(MSG_HOTEND_IDLE_TIMEOUT);
HOTEND_LOOP() {
if ((HOTEND_IDLE_NOZZLE_TARGET) < thermalManager.degTargetHotend(e))
thermalManager.setTargetHotend(HOTEND_IDLE_NOZZLE_TARGET, e);
diff --git a/Marlin/src/feature/joystick.cpp b/Marlin/src/feature/joystick.cpp
index d8e6cef3b6d38..7f91c1549b9e1 100644
--- a/Marlin/src/feature/joystick.cpp
+++ b/Marlin/src/feature/joystick.cpp
@@ -68,13 +68,13 @@ Joystick joystick;
void Joystick::report() {
SERIAL_ECHOPGM("Joystick");
#if HAS_JOY_ADC_X
- SERIAL_ECHOPAIR_P(SP_X_STR, JOY_X(x.raw));
+ SERIAL_ECHOPGM_P(SP_X_STR, JOY_X(x.raw));
#endif
#if HAS_JOY_ADC_Y
- SERIAL_ECHOPAIR_P(SP_Y_STR, JOY_Y(y.raw));
+ SERIAL_ECHOPGM_P(SP_Y_STR, JOY_Y(y.raw));
#endif
#if HAS_JOY_ADC_Z
- SERIAL_ECHOPAIR_P(SP_Z_STR, JOY_Z(z.raw));
+ SERIAL_ECHOPGM_P(SP_Z_STR, JOY_Z(z.raw));
#endif
#if HAS_JOY_ADC_EN
SERIAL_ECHO_TERNARY(READ(JOY_EN_PIN), " EN=", "HIGH (dis", "LOW (en", "abled)");
diff --git a/Marlin/src/feature/leds/leds.cpp b/Marlin/src/feature/leds/leds.cpp
index 328daa626d462..17d790b8cc9a2 100644
--- a/Marlin/src/feature/leds/leds.cpp
+++ b/Marlin/src/feature/leds/leds.cpp
@@ -121,11 +121,11 @@ void LEDLights::set_color(const LEDColor &incol
// This variant uses 3-4 separate pins for the RGB(W) components.
// If the pins can do PWM then their intensity will be set.
- #define _UPDATE_RGBW(C,c) do { \
- if (PWM_PIN(RGB_LED_##C##_PIN)) \
- analogWrite(pin_t(RGB_LED_##C##_PIN), c); \
- else \
- WRITE(RGB_LED_##C##_PIN, c ? HIGH : LOW); \
+ #define _UPDATE_RGBW(C,c) do { \
+ if (PWM_PIN(RGB_LED_##C##_PIN)) \
+ set_pwm_duty(pin_t(RGB_LED_##C##_PIN), c); \
+ else \
+ WRITE(RGB_LED_##C##_PIN, c ? HIGH : LOW); \
}while(0)
#define UPDATE_RGBW(C,c) _UPDATE_RGBW(C, TERN1(CASE_LIGHT_USE_RGB_LED, caselight.on) ? incol.c : 0)
UPDATE_RGBW(R,r); UPDATE_RGBW(G,g); UPDATE_RGBW(B,b);
@@ -170,9 +170,9 @@ void LEDLights::set_color(const LEDColor &incol
#if ENABLED(NEO2_COLOR_PRESETS)
const LEDColor LEDLights2::defaultLEDColor = LEDColor(
- LED_USER_PRESET_RED, LED_USER_PRESET_GREEN, LED_USER_PRESET_BLUE
- OPTARG(HAS_WHITE_LED2, LED_USER_PRESET_WHITE)
- OPTARG(NEOPIXEL_LED, LED_USER_PRESET_BRIGHTNESS)
+ NEO2_USER_PRESET_RED, NEO2_USER_PRESET_GREEN, NEO2_USER_PRESET_BLUE
+ OPTARG(HAS_WHITE_LED2, NEO2_USER_PRESET_WHITE)
+ OPTARG(NEOPIXEL_LED, NEO2_USER_PRESET_BRIGHTNESS)
);
#endif
diff --git a/Marlin/src/feature/max7219.cpp b/Marlin/src/feature/max7219.cpp
index 200e6b580d5b1..474933aa1946b 100644
--- a/Marlin/src/feature/max7219.cpp
+++ b/Marlin/src/feature/max7219.cpp
@@ -124,13 +124,12 @@ uint8_t Max7219::suspended; // = 0;
#define SIG_DELAY() DELAY_NS(250)
#endif
-void Max7219::error(const char * const func, const int32_t v1, const int32_t v2/*=-1*/) {
+void Max7219::error(FSTR_P const func, const int32_t v1, const int32_t v2/*=-1*/) {
#if ENABLED(MAX7219_ERRORS)
SERIAL_ECHOPGM("??? Max7219::");
- SERIAL_ECHOPGM_P(func);
- SERIAL_CHAR('(');
+ SERIAL_ECHOF(func, AS_CHAR('('));
SERIAL_ECHO(v1);
- if (v2 > 0) SERIAL_ECHOPAIR(", ", v2);
+ if (v2 > 0) SERIAL_ECHOPGM(", ", v2);
SERIAL_CHAR(')');
SERIAL_EOL();
#else
@@ -268,24 +267,24 @@ void Max7219::set(const uint8_t line, const uint8_t bits) {
// Modify a single LED bit and send the changed line
void Max7219::led_set(const uint8_t x, const uint8_t y, const bool on) {
- if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(PSTR("led_set"), x, y);
+ if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(F("led_set"), x, y);
if (BIT_7219(x, y) == on) return;
XOR_7219(x, y);
refresh_unit_line(LED_IND(x, y));
}
void Max7219::led_on(const uint8_t x, const uint8_t y) {
- if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(PSTR("led_on"), x, y);
+ if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(F("led_on"), x, y);
led_set(x, y, true);
}
void Max7219::led_off(const uint8_t x, const uint8_t y) {
- if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(PSTR("led_off"), x, y);
+ if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(F("led_off"), x, y);
led_set(x, y, false);
}
void Max7219::led_toggle(const uint8_t x, const uint8_t y) {
- if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(PSTR("led_toggle"), x, y);
+ if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(F("led_toggle"), x, y);
led_set(x, y, !BIT_7219(x, y));
}
@@ -328,13 +327,13 @@ void Max7219::fill() {
}
void Max7219::clear_row(const uint8_t row) {
- if (row >= MAX7219_Y_LEDS) return error(PSTR("clear_row"), row);
+ if (row >= MAX7219_Y_LEDS) return error(F("clear_row"), row);
LOOP_L_N(x, MAX7219_X_LEDS) CLR_7219(x, row);
send_row(row);
}
void Max7219::clear_column(const uint8_t col) {
- if (col >= MAX7219_X_LEDS) return error(PSTR("set_column"), col);
+ if (col >= MAX7219_X_LEDS) return error(F("set_column"), col);
LOOP_L_N(y, MAX7219_Y_LEDS) CLR_7219(col, y);
send_column(col);
}
@@ -345,7 +344,7 @@ void Max7219::clear_column(const uint8_t col) {
* once with a single call to the function (if rotated 90° or 270°).
*/
void Max7219::set_row(const uint8_t row, const uint32_t val) {
- if (row >= MAX7219_Y_LEDS) return error(PSTR("set_row"), row);
+ if (row >= MAX7219_Y_LEDS) return error(F("set_row"), row);
uint32_t mask = _BV32(MAX7219_X_LEDS - 1);
LOOP_L_N(x, MAX7219_X_LEDS) {
if (val & mask) SET_7219(x, row); else CLR_7219(x, row);
@@ -360,7 +359,7 @@ void Max7219::set_row(const uint8_t row, const uint32_t val) {
* once with a single call to the function (if rotated 0° or 180°).
*/
void Max7219::set_column(const uint8_t col, const uint32_t val) {
- if (col >= MAX7219_X_LEDS) return error(PSTR("set_column"), col);
+ if (col >= MAX7219_X_LEDS) return error(F("set_column"), col);
uint32_t mask = _BV32(MAX7219_Y_LEDS - 1);
LOOP_L_N(y, MAX7219_Y_LEDS) {
if (val & mask) SET_7219(col, y); else CLR_7219(col, y);
@@ -371,56 +370,56 @@ void Max7219::set_column(const uint8_t col, const uint32_t val) {
void Max7219::set_rows_16bits(const uint8_t y, uint32_t val) {
#if MAX7219_X_LEDS == 8
- if (y > MAX7219_Y_LEDS - 2) return error(PSTR("set_rows_16bits"), y, val);
+ if (y > MAX7219_Y_LEDS - 2) return error(F("set_rows_16bits"), y, val);
set_row(y + 1, val); val >>= 8;
set_row(y + 0, val);
#else // at least 16 bits on each row
- if (y > MAX7219_Y_LEDS - 1) return error(PSTR("set_rows_16bits"), y, val);
+ if (y > MAX7219_Y_LEDS - 1) return error(F("set_rows_16bits"), y, val);
set_row(y, val);
#endif
}
void Max7219::set_rows_32bits(const uint8_t y, uint32_t val) {
#if MAX7219_X_LEDS == 8
- if (y > MAX7219_Y_LEDS - 4) return error(PSTR("set_rows_32bits"), y, val);
+ if (y > MAX7219_Y_LEDS - 4) return error(F("set_rows_32bits"), y, val);
set_row(y + 3, val); val >>= 8;
set_row(y + 2, val); val >>= 8;
set_row(y + 1, val); val >>= 8;
set_row(y + 0, val);
#elif MAX7219_X_LEDS == 16
- if (y > MAX7219_Y_LEDS - 2) return error(PSTR("set_rows_32bits"), y, val);
+ if (y > MAX7219_Y_LEDS - 2) return error(F("set_rows_32bits"), y, val);
set_row(y + 1, val); val >>= 16;
set_row(y + 0, val);
#else // at least 24 bits on each row. In the 3 matrix case, just display the low 24 bits
- if (y > MAX7219_Y_LEDS - 1) return error(PSTR("set_rows_32bits"), y, val);
+ if (y > MAX7219_Y_LEDS - 1) return error(F("set_rows_32bits"), y, val);
set_row(y, val);
#endif
}
void Max7219::set_columns_16bits(const uint8_t x, uint32_t val) {
#if MAX7219_Y_LEDS == 8
- if (x > MAX7219_X_LEDS - 2) return error(PSTR("set_columns_16bits"), x, val);
+ if (x > MAX7219_X_LEDS - 2) return error(F("set_columns_16bits"), x, val);
set_column(x + 0, val); val >>= 8;
set_column(x + 1, val);
#else // at least 16 bits in each column
- if (x > MAX7219_X_LEDS - 1) return error(PSTR("set_columns_16bits"), x, val);
+ if (x > MAX7219_X_LEDS - 1) return error(F("set_columns_16bits"), x, val);
set_column(x, val);
#endif
}
void Max7219::set_columns_32bits(const uint8_t x, uint32_t val) {
#if MAX7219_Y_LEDS == 8
- if (x > MAX7219_X_LEDS - 4) return error(PSTR("set_rows_32bits"), x, val);
+ if (x > MAX7219_X_LEDS - 4) return error(F("set_rows_32bits"), x, val);
set_column(x + 3, val); val >>= 8;
set_column(x + 2, val); val >>= 8;
set_column(x + 1, val); val >>= 8;
set_column(x + 0, val);
#elif MAX7219_Y_LEDS == 16
- if (x > MAX7219_X_LEDS - 2) return error(PSTR("set_rows_32bits"), x, val);
+ if (x > MAX7219_X_LEDS - 2) return error(F("set_rows_32bits"), x, val);
set_column(x + 1, val); val >>= 16;
set_column(x + 0, val);
#else // at least 24 bits on each row. In the 3 matrix case, just display the low 24 bits
- if (x > MAX7219_X_LEDS - 1) return error(PSTR("set_rows_32bits"), x, val);
+ if (x > MAX7219_X_LEDS - 1) return error(F("set_rows_32bits"), x, val);
set_column(x, val);
#endif
}
diff --git a/Marlin/src/feature/max7219.h b/Marlin/src/feature/max7219.h
index 3e5b62db2f75b..c25fef1730601 100644
--- a/Marlin/src/feature/max7219.h
+++ b/Marlin/src/feature/max7219.h
@@ -42,6 +42,8 @@
* a Max7219_Set_Row(). The opposite is true for rotations of 0 or 180 degrees.
*/
+#include "../inc/MarlinConfig.h"
+
#ifndef MAX7219_ROTATE
#define MAX7219_ROTATE 0
#endif
@@ -140,7 +142,7 @@ class Max7219 {
private:
static uint8_t suspended;
- static void error(const char * const func, const int32_t v1, const int32_t v2=-1);
+ static void error(FSTR_P const func, const int32_t v1, const int32_t v2=-1);
static void noop();
static void set(const uint8_t line, const uint8_t bits);
static void send_row(const uint8_t row);
diff --git a/Marlin/src/feature/meatpack.cpp b/Marlin/src/feature/meatpack.cpp
index 6803a0de7df43..b2899243b2fb5 100644
--- a/Marlin/src/feature/meatpack.cpp
+++ b/Marlin/src/feature/meatpack.cpp
@@ -140,7 +140,7 @@ void MeatPack::handle_output_char(const uint8_t c) {
#if ENABLED(MP_DEBUG)
if (chars_decoded < 1024) {
++chars_decoded;
- DEBUG_ECHOLNPAIR("RB: ", AS_CHAR(c));
+ DEBUG_ECHOLNPGM("RB: ", AS_CHAR(c));
}
#endif
}
@@ -169,10 +169,9 @@ void MeatPack::handle_command(const MeatPack_Command c) {
void MeatPack::report_state() {
// NOTE: if any configuration vars are added below, the outgoing sync text for host plugin
// should not contain the "PV' substring, as this is used to indicate protocol version
- SERIAL_ECHOPGM("[MP] ");
- SERIAL_ECHOPGM(MeatPack_ProtocolVersion " ");
+ SERIAL_ECHOPGM("[MP] " MeatPack_ProtocolVersion " ");
serialprint_onoff(TEST(state, MPConfig_Bit_Active));
- SERIAL_ECHOPGM_P(TEST(state, MPConfig_Bit_NoSpaces) ? PSTR(" NSP\n") : PSTR(" ESP\n"));
+ SERIAL_ECHOF(TEST(state, MPConfig_Bit_NoSpaces) ? F(" NSP\n") : F(" ESP\n"));
}
/**
diff --git a/Marlin/src/feature/mixing.cpp b/Marlin/src/feature/mixing.cpp
index 0013797ad5f57..9ebc90127f43f 100644
--- a/Marlin/src/feature/mixing.cpp
+++ b/Marlin/src/feature/mixing.cpp
@@ -154,11 +154,11 @@ void Mixer::refresh_collector(const float proportion/*=1.0*/, const uint8_t t/*=
cmax = _MAX(cmax, v);
csum += v;
}
- //SERIAL_ECHOPAIR("Mixer::refresh_collector(", proportion, ", ", t, ") cmax=", cmax, " csum=", csum, " color");
+ //SERIAL_ECHOPGM("Mixer::refresh_collector(", proportion, ", ", t, ") cmax=", cmax, " csum=", csum, " color");
const float inv_prop = proportion / csum;
MIXER_STEPPER_LOOP(i) {
c[i] = color[t][i] * inv_prop;
- //SERIAL_ECHOPAIR(" [", t, "][", i, "] = ", color[t][i], " (", c[i], ") ");
+ //SERIAL_ECHOPGM(" [", t, "][", i, "] = ", color[t][i], " (", c[i], ") ");
}
//SERIAL_EOL();
}
diff --git a/Marlin/src/feature/mixing.h b/Marlin/src/feature/mixing.h
index 573b61cb68f04..f700c7b65b7d6 100644
--- a/Marlin/src/feature/mixing.h
+++ b/Marlin/src/feature/mixing.h
@@ -152,7 +152,7 @@ class Mixer {
MIXER_STEPPER_LOOP(i) mix[i] = mixer_perc_t(100.0f * color[j][i] / ctot);
#ifdef MIXER_NORMALIZER_DEBUG
- SERIAL_ECHOPAIR("V-tool ", j, " [ ");
+ SERIAL_ECHOPGM("V-tool ", j, " [ ");
SERIAL_ECHOLIST_N(MIXING_STEPPERS, color[j][0], color[j][1], color[j][2], color[j][3], color[j][4], color[j][5]);
SERIAL_ECHOPGM(" ] to Mix [ ");
SERIAL_ECHOLIST_N(MIXING_STEPPERS, mix[0], mix[1], mix[2], mix[3], mix[4], mix[5]);
diff --git a/Marlin/src/feature/mmu/mmu.cpp b/Marlin/src/feature/mmu/mmu.cpp
index 718972313844e..58c49ed224541 100644
--- a/Marlin/src/feature/mmu/mmu.cpp
+++ b/Marlin/src/feature/mmu/mmu.cpp
@@ -24,8 +24,9 @@
#if HAS_PRUSA_MMU1
-#include "../MarlinCore.h"
-#include "../module/planner.h"
+#include "../../MarlinCore.h"
+#include "../../module/planner.h"
+#include "../../module/stepper.h"
void mmu_init() {
SET_OUTPUT(E_MUX0_PIN);
@@ -35,7 +36,7 @@ void mmu_init() {
void select_multiplexed_stepper(const uint8_t e) {
planner.synchronize();
- disable_e_steppers();
+ stepper.disable_e_steppers();
WRITE(E_MUX0_PIN, TEST(e, 0) ? HIGH : LOW);
WRITE(E_MUX1_PIN, TEST(e, 1) ? HIGH : LOW);
WRITE(E_MUX2_PIN, TEST(e, 2) ? HIGH : LOW);
diff --git a/Marlin/src/feature/mmu/mmu2.cpp b/Marlin/src/feature/mmu/mmu2.cpp
index 1acd26f331c3c..2813337c635b8 100644
--- a/Marlin/src/feature/mmu/mmu2.cpp
+++ b/Marlin/src/feature/mmu/mmu2.cpp
@@ -35,7 +35,7 @@ MMU2 mmu2;
#include "../../libs/nozzle.h"
#include "../../module/temperature.h"
#include "../../module/planner.h"
-#include "../../module/stepper/indirection.h"
+#include "../../module/stepper.h"
#include "../../MarlinCore.h"
#if ENABLED(HOST_PROMPT_SUPPORT)
@@ -54,7 +54,7 @@ MMU2 mmu2;
#define MMU_CMD_TIMEOUT 45000UL // 45s timeout for mmu commands (except P0)
#define MMU_P0_TIMEOUT 3000UL // Timeout for P0 command: 3seconds
-#define MMU2_COMMAND(S) tx_str_P(PSTR(S "\n"))
+#define MMU2_COMMAND(S) tx_str(F(S "\n"))
#if ENABLED(MMU_EXTRUDER_SENSOR)
uint8_t mmu_idl_sens = 0;
@@ -169,7 +169,7 @@ void MMU2::mmu_loop() {
if (rx_ok()) {
sscanf(rx_buffer, "%huok\n", &version);
- DEBUG_ECHOLNPAIR("MMU => ", version, "\nMMU <= 'S2'");
+ DEBUG_ECHOLNPGM("MMU => ", version, "\nMMU <= 'S2'");
MMU2_COMMAND("S2"); // Read Build Number
state = -3;
@@ -180,7 +180,7 @@ void MMU2::mmu_loop() {
if (rx_ok()) {
sscanf(rx_buffer, "%huok\n", &buildnr);
- DEBUG_ECHOLNPAIR("MMU => ", buildnr);
+ DEBUG_ECHOLNPGM("MMU => ", buildnr);
check_version();
@@ -217,7 +217,7 @@ void MMU2::mmu_loop() {
if (rx_ok()) {
sscanf(rx_buffer, "%hhuok\n", &finda);
- DEBUG_ECHOLNPAIR("MMU => ", finda, "\nMMU - ENABLED");
+ DEBUG_ECHOLNPGM("MMU => ", finda, "\nMMU - ENABLED");
_enabled = true;
state = 1;
@@ -229,17 +229,17 @@ void MMU2::mmu_loop() {
if (cmd) {
if (WITHIN(cmd, MMU_CMD_T0, MMU_CMD_T0 + EXTRUDERS - 1)) {
// tool change
- int filament = cmd - MMU_CMD_T0;
- DEBUG_ECHOLNPAIR("MMU <= T", filament);
- tx_printf_P(PSTR("T%d\n"), filament);
+ const int filament = cmd - MMU_CMD_T0;
+ DEBUG_ECHOLNPGM("MMU <= T", filament);
+ tx_printf(F("T%d\n"), filament);
TERN_(MMU_EXTRUDER_SENSOR, mmu_idl_sens = 1); // enable idler sensor, if any
state = 3; // wait for response
}
else if (WITHIN(cmd, MMU_CMD_L0, MMU_CMD_L0 + EXTRUDERS - 1)) {
// load
- int filament = cmd - MMU_CMD_L0;
- DEBUG_ECHOLNPAIR("MMU <= L", filament);
- tx_printf_P(PSTR("L%d\n"), filament);
+ const int filament = cmd - MMU_CMD_L0;
+ DEBUG_ECHOLNPGM("MMU <= L", filament);
+ tx_printf(F("L%d\n"), filament);
state = 3; // wait for response
}
else if (cmd == MMU_CMD_C0) {
@@ -257,9 +257,9 @@ void MMU2::mmu_loop() {
}
else if (WITHIN(cmd, MMU_CMD_E0, MMU_CMD_E0 + EXTRUDERS - 1)) {
// eject filament
- int filament = cmd - MMU_CMD_E0;
- DEBUG_ECHOLNPAIR("MMU <= E", filament);
- tx_printf_P(PSTR("E%d\n"), filament);
+ const int filament = cmd - MMU_CMD_E0;
+ DEBUG_ECHOLNPGM("MMU <= E", filament);
+ tx_printf(F("E%d\n"), filament);
state = 3; // wait for response
}
else if (cmd == MMU_CMD_R0) {
@@ -270,9 +270,9 @@ void MMU2::mmu_loop() {
}
else if (WITHIN(cmd, MMU_CMD_F0, MMU_CMD_F0 + EXTRUDERS - 1)) {
// filament type
- int filament = cmd - MMU_CMD_F0;
- DEBUG_ECHOLNPAIR("MMU <= F", filament, " ", cmd_arg);
- tx_printf_P(PSTR("F%d %d\n"), filament, cmd_arg);
+ const int filament = cmd - MMU_CMD_F0;
+ DEBUG_ECHOLNPGM("MMU <= F", filament, " ", cmd_arg);
+ tx_printf(F("F%d %d\n"), filament, cmd_arg);
state = 3; // wait for response
}
@@ -356,13 +356,15 @@ void MMU2::mmu_loop() {
*/
bool MMU2::rx_start() {
// check for start message
- return rx_str_P(PSTR("start\n"));
+ return rx_str(F("start\n"));
}
/**
* Check if the data received ends with the given string.
*/
-bool MMU2::rx_str_P(const char *str) {
+bool MMU2::rx_str(FSTR_P fstr) {
+ PGM_P pstr = FTOP(fstr);
+
uint8_t i = strlen(rx_buffer);
while (MMU2_SERIAL.available()) {
@@ -375,14 +377,14 @@ bool MMU2::rx_str_P(const char *str) {
}
rx_buffer[i] = '\0';
- uint8_t len = strlen_P(str);
+ uint8_t len = strlen_P(pstr);
if (i < len) return false;
- str += len;
+ pstr += len;
while (len--) {
- char c0 = pgm_read_byte(str--), c1 = rx_buffer[i--];
+ char c0 = pgm_read_byte(pstr--), c1 = rx_buffer[i--];
if (c0 == c1) continue;
if (c0 == '\r' && c1 == '\n') continue; // match cr as lf
if (c0 == '\n' && c1 == '\r') continue; // match lf as cr
@@ -394,19 +396,19 @@ bool MMU2::rx_str_P(const char *str) {
/**
* Transfer data to MMU, no argument
*/
-void MMU2::tx_str_P(const char *str) {
+void MMU2::tx_str(FSTR_P fstr) {
clear_rx_buffer();
- uint8_t len = strlen_P(str);
- LOOP_L_N(i, len) MMU2_SERIAL.write(pgm_read_byte(str++));
+ PGM_P pstr = FTOP(fstr);
+ while (const char c = pgm_read_byte(pstr)) { MMU2_SERIAL.write(c); pstr++; }
prev_request = millis();
}
/**
* Transfer data to MMU, single argument
*/
-void MMU2::tx_printf_P(const char *format, int argument = -1) {
+void MMU2::tx_printf(FSTR_P format, int argument = -1) {
clear_rx_buffer();
- uint8_t len = sprintf_P(tx_buffer, format, argument);
+ const uint8_t len = sprintf_P(tx_buffer, FTOP(format), argument);
LOOP_L_N(i, len) MMU2_SERIAL.write(tx_buffer[i]);
prev_request = millis();
}
@@ -414,9 +416,9 @@ void MMU2::tx_printf_P(const char *format, int argument = -1) {
/**
* Transfer data to MMU, two arguments
*/
-void MMU2::tx_printf_P(const char *format, int argument1, int argument2) {
+void MMU2::tx_printf(FSTR_P format, int argument1, int argument2) {
clear_rx_buffer();
- uint8_t len = sprintf_P(tx_buffer, format, argument1, argument2);
+ const uint8_t len = sprintf_P(tx_buffer, FTOP(format), argument1, argument2);
LOOP_L_N(i, len) MMU2_SERIAL.write(tx_buffer[i]);
prev_request = millis();
}
@@ -433,7 +435,7 @@ void MMU2::clear_rx_buffer() {
* Check if we received 'ok' from MMU
*/
bool MMU2::rx_ok() {
- if (rx_str_P(PSTR("ok\n"))) {
+ if (rx_str(F("ok\n"))) {
prev_P0_request = millis();
return true;
}
@@ -446,12 +448,12 @@ bool MMU2::rx_ok() {
void MMU2::check_version() {
if (buildnr < MMU_REQUIRED_FW_BUILDNR) {
SERIAL_ERROR_MSG("Invalid MMU2 firmware. Version >= " STRINGIFY(MMU_REQUIRED_FW_BUILDNR) " required.");
- kill(GET_TEXT(MSG_KILL_MMU2_FIRMWARE));
+ kill(GET_TEXT_F(MSG_KILL_MMU2_FIRMWARE));
}
}
static void mmu2_not_responding() {
- LCD_MESSAGEPGM(MSG_MMU2_NOT_RESPONDING);
+ LCD_MESSAGE(MSG_MMU2_NOT_RESPONDING);
BUZZ(100, 659);
BUZZ(200, 698);
BUZZ(100, 659);
@@ -486,8 +488,8 @@ static void mmu2_not_responding() {
if (index != extruder) {
- DISABLE_AXIS_E0();
- ui.status_printf_P(0, GET_TEXT(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
+ stepper.disable_extruder();
+ ui.status_printf(0, GET_TEXT_F(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
command(MMU_CMD_T0 + index);
manage_response(true, true);
@@ -495,7 +497,7 @@ static void mmu2_not_responding() {
if (load_to_gears()) {
extruder = index; // filament change is finished
active_extruder = 0;
- ENABLE_AXIS_E0();
+ stepper.enable_extruder();
SERIAL_ECHO_MSG(STR_ACTIVE_EXTRUDER, extruder);
}
ui.reset_status();
@@ -531,13 +533,13 @@ static void mmu2_not_responding() {
#if ENABLED(MMU2_MENUS)
planner.synchronize();
const uint8_t index = mmu2_choose_filament();
- DISABLE_AXIS_E0();
+ stepper.disable_extruder();
command(MMU_CMD_T0 + index);
manage_response(true, true);
if (load_to_gears()) {
mmu_loop();
- ENABLE_AXIS_E0();
+ stepper.enable_extruder();
extruder = index;
active_extruder = 0;
}
@@ -566,14 +568,14 @@ static void mmu2_not_responding() {
set_runout_valid(false);
if (index != extruder) {
- DISABLE_AXIS_E0();
+ stepper.disable_extruder();
if (FILAMENT_PRESENT()) {
DEBUG_ECHOLNPGM("Unloading\n");
mmu_loading_flag = false;
command(MMU_CMD_U0);
manage_response(true, true);
}
- ui.status_printf_P(0, GET_TEXT(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
+ ui.status_printf(0, GET_TEXT_F(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
mmu_loading_flag = true;
command(MMU_CMD_T0 + index);
manage_response(true, true);
@@ -582,7 +584,7 @@ static void mmu2_not_responding() {
extruder = index;
active_extruder = 0;
- ENABLE_AXIS_E0();
+ stepper.enable_extruder();
SERIAL_ECHO_MSG(STR_ACTIVE_EXTRUDER, extruder);
ui.reset_status();
@@ -620,14 +622,14 @@ static void mmu2_not_responding() {
#if ENABLED(MMU2_MENUS)
planner.synchronize();
uint8_t index = mmu2_choose_filament();
- DISABLE_AXIS_E0();
+ stepper.disable_extruder();
command(MMU_CMD_T0 + index);
manage_response(true, true);
mmu_continue_loading();
command(MMU_CMD_C0);
mmu_loop();
- ENABLE_AXIS_E0();
+ stepper.enable_extruder();
extruder = index;
active_extruder = 0;
#else
@@ -647,7 +649,7 @@ static void mmu2_not_responding() {
void MMU2::mmu_continue_loading() {
for (uint8_t i = 0; i < MMU_LOADING_ATTEMPTS_NR; i++) {
- DEBUG_ECHOLNPAIR("Additional load attempt #", i);
+ DEBUG_ECHOLNPGM("Additional load attempt #", i);
if (FILAMENT_PRESENT()) break;
command(MMU_CMD_C0);
manage_response(true, true);
@@ -670,14 +672,14 @@ static void mmu2_not_responding() {
set_runout_valid(false);
if (index != extruder) {
- DISABLE_AXIS_E0();
- ui.status_printf_P(0, GET_TEXT(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
+ stepper.disable_extruder();
+ ui.status_printf(0, GET_TEXT_F(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
command(MMU_CMD_T0 + index);
manage_response(true, true);
command(MMU_CMD_C0);
extruder = index; //filament change is finished
active_extruder = 0;
- ENABLE_AXIS_E0();
+ stepper.enable_extruder();
SERIAL_ECHO_MSG(STR_ACTIVE_EXTRUDER, extruder);
ui.reset_status();
}
@@ -714,13 +716,13 @@ static void mmu2_not_responding() {
#if ENABLED(MMU2_MENUS)
planner.synchronize();
uint8_t index = mmu2_choose_filament();
- DISABLE_AXIS_E0();
+ stepper.disable_extruder();
command(MMU_CMD_T0 + index);
manage_response(true, true);
command(MMU_CMD_C0);
mmu_loop();
- ENABLE_AXIS_E0();
+ stepper.enable_extruder();
extruder = index;
active_extruder = 0;
#else
@@ -808,14 +810,14 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
if (turn_off_nozzle && resume_hotend_temp) {
thermalManager.setTargetHotend(resume_hotend_temp, active_extruder);
- LCD_MESSAGEPGM(MSG_HEATING);
+ LCD_MESSAGE(MSG_HEATING);
BUZZ(200, 40);
while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(1000);
}
if (move_axes && all_axes_homed()) {
- LCD_MESSAGEPGM(MSG_MMU2_RESUMING);
+ LCD_MESSAGE(MSG_MMU2_RESUMING);
BUZZ(198, 404); BUZZ(4, 0); BUZZ(198, 404);
// Move XY to starting position, then Z
@@ -826,7 +828,7 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
}
else {
BUZZ(198, 404); BUZZ(4, 0); BUZZ(198, 404);
- LCD_MESSAGEPGM(MSG_MMU2_RESUMING);
+ LCD_MESSAGE(MSG_MMU2_RESUMING);
}
}
}
@@ -842,7 +844,7 @@ void MMU2::set_filament_type(const uint8_t index, const uint8_t filamentType) {
}
void MMU2::filament_runout() {
- queue.inject_P(PSTR(MMU2_FILAMENT_RUNOUT_SCRIPT));
+ queue.inject(F(MMU2_FILAMENT_RUNOUT_SCRIPT));
planner.synchronize();
}
@@ -853,7 +855,7 @@ void MMU2::filament_runout() {
if (cmd == MMU_CMD_NONE && last_cmd == MMU_CMD_C0) {
if (present && !mmu2s_triggered) {
DEBUG_ECHOLNPGM("MMU <= 'A'");
- tx_str_P(PSTR("A\n"));
+ tx_str(F("A\n"));
}
// Slowly spin the extruder during C0
else {
@@ -908,11 +910,11 @@ bool MMU2::load_filament_to_nozzle(const uint8_t index) {
if (thermalManager.tooColdToExtrude(active_extruder)) {
BUZZ(200, 404);
- LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD);
+ LCD_ALERTMESSAGE(MSG_HOTEND_TOO_COLD);
return false;
}
- DISABLE_AXIS_E0();
+ stepper.disable_extruder();
command(MMU_CMD_T0 + index);
manage_response(true, true);
@@ -944,13 +946,13 @@ bool MMU2::eject_filament(const uint8_t index, const bool recover) {
if (thermalManager.tooColdToExtrude(active_extruder)) {
BUZZ(200, 404);
- LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD);
+ LCD_ALERTMESSAGE(MSG_HOTEND_TOO_COLD);
return false;
}
- LCD_MESSAGEPGM(MSG_MMU2_EJECTING_FILAMENT);
+ LCD_MESSAGE(MSG_MMU2_EJECTING_FILAMENT);
- ENABLE_AXIS_E0();
+ stepper.enable_extruder();
current_position.e -= MMU2_FILAMENTCHANGE_EJECT_FEED;
line_to_current_position(MMM_TO_MMS(2500));
planner.synchronize();
@@ -958,11 +960,11 @@ bool MMU2::eject_filament(const uint8_t index, const bool recover) {
manage_response(false, false);
if (recover) {
- LCD_MESSAGEPGM(MSG_MMU2_EJECT_RECOVER);
+ LCD_MESSAGE(MSG_MMU2_EJECT_RECOVER);
BUZZ(200, 404);
- TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, PSTR("MMU2 Eject Recover"), CONTINUE_STR));
- TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("MMU2 Eject Recover")));
- wait_for_user_response();
+ TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, F("MMU2 Eject Recover"), FPSTR(CONTINUE_STR)));
+ TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(F("MMU2 Eject Recover")));
+ TERN_(HAS_RESUME_CONTINUE, wait_for_user_response());
BUZZ(200, 404);
BUZZ(200, 404);
@@ -979,7 +981,7 @@ bool MMU2::eject_filament(const uint8_t index, const bool recover) {
BUZZ(200, 404);
- DISABLE_AXIS_E0();
+ stepper.disable_extruder();
return true;
}
@@ -993,7 +995,7 @@ bool MMU2::unload() {
if (thermalManager.tooColdToExtrude(active_extruder)) {
BUZZ(200, 404);
- LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD);
+ LCD_ALERTMESSAGE(MSG_HOTEND_TOO_COLD);
return false;
}
@@ -1016,7 +1018,7 @@ bool MMU2::unload() {
void MMU2::execute_extruder_sequence(const E_Step * sequence, int steps) {
planner.synchronize();
- ENABLE_AXIS_E0();
+ stepper.enable_extruder();
const E_Step* step = sequence;
@@ -1025,7 +1027,7 @@ void MMU2::execute_extruder_sequence(const E_Step * sequence, int steps) {
const feedRate_t fr_mm_m = pgm_read_float(&(step->feedRate));
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("E step ", es, "/", fr_mm_m);
+ DEBUG_ECHOLNPGM("E step ", es, "/", fr_mm_m);
current_position.e += es;
line_to_current_position(MMM_TO_MMS(fr_mm_m));
@@ -1034,7 +1036,7 @@ void MMU2::execute_extruder_sequence(const E_Step * sequence, int steps) {
step++;
}
- DISABLE_AXIS_E0();
+ stepper.disable_extruder();
}
#endif // HAS_PRUSA_MMU2
diff --git a/Marlin/src/feature/mmu/mmu2.h b/Marlin/src/feature/mmu/mmu2.h
index 95338a518410d..9574e2217f82d 100644
--- a/Marlin/src/feature/mmu/mmu2.h
+++ b/Marlin/src/feature/mmu/mmu2.h
@@ -57,10 +57,10 @@ class MMU2 {
static bool eject_filament(const uint8_t index, const bool recover);
private:
- static bool rx_str_P(const char *str);
- static void tx_str_P(const char *str);
- static void tx_printf_P(const char *format, const int argument);
- static void tx_printf_P(const char *format, const int argument1, const int argument2);
+ static inline bool rx_str(FSTR_P fstr);
+ static inline void tx_str(FSTR_P fstr);
+ static inline void tx_printf(FSTR_P ffmt, const int argument);
+ static inline void tx_printf(FSTR_P ffmt, const int argument1, const int argument2);
static void clear_rx_buffer();
static bool rx_ok();
diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp
index 79a8af66e2a4e..d97ac2a0ac6e5 100644
--- a/Marlin/src/feature/pause.cpp
+++ b/Marlin/src/feature/pause.cpp
@@ -53,6 +53,8 @@
#if ENABLED(EXTENSIBLE_UI)
#include "../lcd/extui/ui_api.h"
+#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
+ #include "../lcd/e3v2/enhanced/dwin.h"
#endif
#include "../lcd/marlinui.h"
@@ -130,7 +132,7 @@ fil_change_settings_t fc_settings[EXTRUDERS];
*/
static bool ensure_safe_temperature(const bool wait=true, const PauseMode mode=PAUSE_MODE_SAME) {
DEBUG_SECTION(est, "ensure_safe_temperature", true);
- DEBUG_ECHOLNPAIR("... wait:", wait, " mode:", mode);
+ DEBUG_ECHOLNPGM("... wait:", wait, " mode:", mode);
#if ENABLED(PREVENT_COLD_EXTRUSION)
if (!DEBUGGING(DRYRUN) && thermalManager.targetTooColdToExtrude(active_extruder))
@@ -176,7 +178,7 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load
DXC_ARGS
) {
DEBUG_SECTION(lf, "load_filament", true);
- DEBUG_ECHOLNPAIR("... slowlen:", slow_load_length, " fastlen:", fast_load_length, " purgelen:", purge_length, " maxbeep:", max_beep_count, " showlcd:", show_lcd, " pauseforuser:", pause_for_user, " pausemode:", mode DXC_SAY);
+ DEBUG_ECHOLNPGM("... slowlen:", slow_load_length, " fastlen:", fast_load_length, " purgelen:", purge_length, " maxbeep:", max_beep_count, " showlcd:", show_lcd, " pauseforuser:", pause_for_user, " pausemode:", mode DXC_SAY);
if (!ensure_safe_temperature(false, mode)) {
if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_STATUS, mode);
@@ -192,15 +194,25 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load
KEEPALIVE_STATE(PAUSED_FOR_USER);
wait_for_user = true; // LCD click or M108 will clear this
- TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("Load Filament")));
+ TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(F("Load Filament")));
#if ENABLED(HOST_PROMPT_SUPPORT)
const char tool = '0' + TERN0(MULTI_FILAMENT_SENSOR, active_extruder);
- host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Load Filament T"), tool, CONTINUE_STR);
+ hostui.prompt_do(PROMPT_USER_CONTINUE, F("Load Filament T"), tool, FPSTR(CONTINUE_STR));
#endif
while (wait_for_user) {
impatient_beep(max_beep_count);
+ #if BOTH(FILAMENT_CHANGE_RESUME_ON_INSERT, FILAMENT_RUNOUT_SENSOR)
+ #if ENABLED(MULTI_FILAMENT_SENSOR)
+ #define _CASE_INSERTED(N) case N-1: if (READ(FIL_RUNOUT##N##_PIN) != FIL_RUNOUT##N##_STATE) wait_for_user = false; break;
+ switch (active_extruder) {
+ REPEAT_1(NUM_RUNOUT_SENSORS, _CASE_INSERTED)
+ }
+ #else
+ if (READ(FIL_RUNOUT_PIN) != FIL_RUNOUT_STATE) wait_for_user = false;
+ #endif
+ #endif
idle_no_sleep();
}
}
@@ -213,6 +225,8 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load
set_duplication_enabled(false, DXC_ext);
#endif
+ TERN_(BELTPRINTER, do_blocking_move_to_xy(0.00, 50.00));
+
// Slow Load filament
if (slow_load_length) unscaled_e_move(slow_load_length, FILAMENT_CHANGE_SLOW_LOAD_FEEDRATE);
@@ -238,8 +252,9 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load
if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_PURGE);
- TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(GET_TEXT(MSG_FILAMENT_CHANGE_PURGE)));
- TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, GET_TEXT(MSG_FILAMENT_CHANGE_PURGE), CONTINUE_STR));
+ TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE)));
+ TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE), FPSTR(CONTINUE_STR)));
+ TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_Popup_Confirm(ICON_BLTouch, GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE), FPSTR(CONTINUE_STR)));
wait_for_user = true; // A click or M108 breaks the purge_length loop
for (float purge_count = purge_length; purge_count > 0 && wait_for_user; --purge_count)
unscaled_e_move(1, ADVANCED_PAUSE_PURGE_FEEDRATE);
@@ -256,14 +271,14 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load
unscaled_e_move(purge_length, ADVANCED_PAUSE_PURGE_FEEDRATE);
}
- TERN_(HOST_PROMPT_SUPPORT, filament_load_host_prompt()); // Initiate another host prompt.
+ TERN_(HOST_PROMPT_SUPPORT, hostui.filament_load_prompt()); // Initiate another host prompt.
#if M600_PURGE_MORE_RESUMABLE
if (show_lcd) {
// Show "Purge More" / "Resume" menu and wait for reply
KEEPALIVE_STATE(PAUSED_FOR_USER);
wait_for_user = false;
- #if HAS_LCD_MENU
+ #if EITHER(HAS_LCD_MENU, DWIN_CREALITY_LCD_ENHANCED)
ui.pause_show_message(PAUSE_MESSAGE_OPTION); // Also sets PAUSE_RESPONSE_WAIT_FOR
#else
pause_menu_response = PAUSE_RESPONSE_WAIT_FOR;
@@ -276,7 +291,7 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load
} while (TERN0(M600_PURGE_MORE_RESUMABLE, pause_menu_response == PAUSE_RESPONSE_EXTRUDE_MORE));
#endif
- TERN_(HOST_PROMPT_SUPPORT, host_action_prompt_end());
+ TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_end());
return true;
}
@@ -287,8 +302,8 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load
* send current back to their board, potentially frying it.
*/
inline void disable_active_extruder() {
- #if HAS_E_STEPPER_ENABLE
- disable_e_stepper(active_extruder);
+ #if HAS_EXTRUDERS
+ stepper.DISABLE_EXTRUDER(active_extruder);
safe_delay(100);
#endif
}
@@ -310,7 +325,7 @@ bool unload_filament(const_float_t unload_length, const bool show_lcd/*=false*/,
#endif
) {
DEBUG_SECTION(uf, "unload_filament", true);
- DEBUG_ECHOLNPAIR("... unloadlen:", unload_length, " showlcd:", show_lcd, " mode:", mode
+ DEBUG_ECHOLNPGM("... unloadlen:", unload_length, " showlcd:", show_lcd, " mode:", mode
#if BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER)
, " mixmult:", mix_multiplier
#endif
@@ -374,7 +389,7 @@ uint8_t did_pause_print = 0;
bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool show_lcd/*=false*/, const_float_t unload_length/*=0*/ DXC_ARGS) {
DEBUG_SECTION(pp, "pause_print", true);
- DEBUG_ECHOLNPAIR("... park.x:", park_point.x, " y:", park_point.y, " z:", park_point.z, " unloadlen:", unload_length, " showlcd:", show_lcd DXC_SAY);
+ DEBUG_ECHOLNPGM("... park.x:", park_point.x, " y:", park_point.y, " z:", park_point.z, " unloadlen:", unload_length, " showlcd:", show_lcd DXC_SAY);
UNUSED(show_lcd);
@@ -382,13 +397,13 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool
#if ENABLED(HOST_ACTION_COMMANDS)
#ifdef ACTION_ON_PAUSED
- host_action_paused();
+ hostui.paused();
#elif defined(ACTION_ON_PAUSE)
- host_action_pause();
+ hostui.pause();
#endif
#endif
- TERN_(HOST_PROMPT_SUPPORT, host_prompt_open(PROMPT_INFO, PSTR("Pause"), DISMISS_STR));
+ TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_open(PROMPT_INFO, F("Pause"), FPSTR(DISMISS_STR)));
// Indicate that the printer is paused
++did_pause_print;
@@ -425,7 +440,7 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool
// Initial retract before move to filament change position
if (retract && thermalManager.hotEnoughToExtrude(active_extruder)) {
- DEBUG_ECHOLNPAIR("... retract:", retract);
+ DEBUG_ECHOLNPGM("... retract:", retract);
unscaled_e_move(retract, PAUSE_PARK_RETRACT_FEEDRATE);
}
@@ -467,16 +482,16 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool
void show_continue_prompt(const bool is_reload) {
DEBUG_SECTION(scp, "pause_print", true);
- DEBUG_ECHOLNPAIR("... is_reload:", is_reload);
+ DEBUG_ECHOLNPGM("... is_reload:", is_reload);
ui.pause_show_message(is_reload ? PAUSE_MESSAGE_INSERT : PAUSE_MESSAGE_WAITING);
SERIAL_ECHO_START();
- SERIAL_ECHOPGM_P(is_reload ? PSTR(_PMSG(STR_FILAMENT_CHANGE_INSERT) "\n") : PSTR(_PMSG(STR_FILAMENT_CHANGE_WAIT) "\n"));
+ SERIAL_ECHOF(is_reload ? F(_PMSG(STR_FILAMENT_CHANGE_INSERT) "\n") : F(_PMSG(STR_FILAMENT_CHANGE_WAIT) "\n"));
}
void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep_count/*=0*/ DXC_ARGS) {
DEBUG_SECTION(wfc, "wait_for_confirmation", true);
- DEBUG_ECHOLNPAIR("... is_reload:", is_reload, " maxbeep:", max_beep_count DXC_SAY);
+ DEBUG_ECHOLNPGM("... is_reload:", is_reload, " maxbeep:", max_beep_count DXC_SAY);
bool nozzle_timed_out = false;
@@ -497,8 +512,8 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
// Wait for filament insert by user and press button
KEEPALIVE_STATE(PAUSED_FOR_USER);
- TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, GET_TEXT(MSG_NOZZLE_PARKED), CONTINUE_STR));
- TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(GET_TEXT(MSG_NOZZLE_PARKED)));
+ TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, GET_TEXT_F(MSG_NOZZLE_PARKED), FPSTR(CONTINUE_STR)));
+ TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_NOZZLE_PARKED)));
wait_for_user = true; // LCD click or M108 will clear this
while (wait_for_user) {
impatient_beep(max_beep_count);
@@ -513,15 +528,17 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
ui.pause_show_message(PAUSE_MESSAGE_HEAT);
SERIAL_ECHO_MSG(_PMSG(STR_FILAMENT_CHANGE_HEAT));
- TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, GET_TEXT(MSG_HEATER_TIMEOUT), GET_TEXT(MSG_REHEAT)));
+ TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, GET_TEXT_F(MSG_HEATER_TIMEOUT), GET_TEXT_F(MSG_REHEAT)));
- TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(GET_TEXT(MSG_HEATER_TIMEOUT)));
+ TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_HEATER_TIMEOUT)));
- wait_for_user_response(0, true); // Wait for LCD click or M108
+ TERN_(HAS_RESUME_CONTINUE, wait_for_user_response(0, true)); // Wait for LCD click or M108
- TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_INFO, GET_TEXT(MSG_REHEATING)));
+ TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_INFO, GET_TEXT_F(MSG_REHEATING)));
- TERN_(EXTENSIBLE_UI, ExtUI::onStatusChanged_P(GET_TEXT(MSG_REHEATING)));
+ TERN_(EXTENSIBLE_UI, ExtUI::onStatusChanged(GET_TEXT_F(MSG_REHEATING)));
+
+ TERN_(DWIN_CREALITY_LCD_ENHANCED, LCD_MESSAGE(MSG_REHEATING));
// Re-enable the heaters if they timed out
HOTEND_LOOP() thermalManager.reset_hotend_idle_timer(e);
@@ -536,11 +553,14 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
const millis_t nozzle_timeout = SEC_TO_MS(PAUSE_PARK_NOZZLE_TIMEOUT);
HOTEND_LOOP() thermalManager.heater_idle[e].start(nozzle_timeout);
- TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, GET_TEXT(MSG_REHEATDONE), CONTINUE_STR));
- TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(GET_TEXT(MSG_REHEATDONE)));
- wait_for_user = true;
- nozzle_timed_out = false;
+ TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, GET_TEXT_F(MSG_REHEATDONE), FPSTR(CONTINUE_STR)));
+ TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_REHEATDONE)));
+ TERN_(DWIN_CREALITY_LCD_ENHANCED, LCD_MESSAGE(MSG_REHEATDONE));
+
+ IF_DISABLED(PAUSE_REHEAT_FAST_RESUME, wait_for_user = true);
+
+ nozzle_timed_out = false;
first_impatient_beep(max_beep_count);
}
idle_no_sleep();
@@ -572,10 +592,10 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
*/
void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_length/*=0*/, const_float_t purge_length/*=ADVANCED_PAUSE_PURGE_LENGTH*/, const int8_t max_beep_count/*=0*/, const celsius_t targetTemp/*=0*/ DXC_ARGS) {
DEBUG_SECTION(rp, "resume_print", true);
- DEBUG_ECHOLNPAIR("... slowlen:", slow_load_length, " fastlen:", fast_load_length, " purgelen:", purge_length, " maxbeep:", max_beep_count, " targetTemp:", targetTemp DXC_SAY);
+ DEBUG_ECHOLNPGM("... slowlen:", slow_load_length, " fastlen:", fast_load_length, " purgelen:", purge_length, " maxbeep:", max_beep_count, " targetTemp:", targetTemp DXC_SAY);
/*
- SERIAL_ECHOLNPAIR(
+ SERIAL_ECHOLNPGM(
"start of resume_print()\ndual_x_carriage_mode:", dual_x_carriage_mode,
"\nextruder_duplication_enabled:", extruder_duplication_enabled,
"\nactive_extruder:", active_extruder,
@@ -606,7 +626,7 @@ void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_
ui.pause_show_message(PAUSE_MESSAGE_RESUME);
// Check Temperature before moving hotend
- ensure_safe_temperature();
+ ensure_safe_temperature(DISABLED(BELTPRINTER));
// Retract to prevent oozing
unscaled_e_move(-(PAUSE_PARK_RETRACT_LENGTH), feedRate_t(PAUSE_PARK_RETRACT_FEEDRATE));
@@ -644,14 +664,14 @@ void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_
ui.pause_show_message(PAUSE_MESSAGE_STATUS);
#ifdef ACTION_ON_RESUMED
- host_action_resumed();
+ hostui.resumed();
#elif defined(ACTION_ON_RESUME)
- host_action_resume();
+ hostui.resume();
#endif
--did_pause_print;
- TERN_(HOST_PROMPT_SUPPORT, host_prompt_open(PROMPT_INFO, PSTR("Resuming"), DISMISS_STR));
+ TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_open(PROMPT_INFO, F("Resuming"), FPSTR(DISMISS_STR)));
// Resume the print job timer if it was running
if (print_job_timer.isPaused()) print_job_timer.start();
@@ -673,6 +693,7 @@ void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_
TERN_(HAS_STATUS_MESSAGE, ui.reset_status());
TERN_(HAS_LCD_MENU, ui.return_to_status());
+ TERN_(DWIN_CREALITY_LCD_ENHANCED, HMI_ReturnScreen());
}
#endif // ADVANCED_PAUSE_FEATURE
diff --git a/Marlin/src/feature/power.cpp b/Marlin/src/feature/power.cpp
index b86249fbc0527..fabe35b989c7e 100644
--- a/Marlin/src/feature/power.cpp
+++ b/Marlin/src/feature/power.cpp
@@ -27,7 +27,7 @@
#include "../inc/MarlinConfig.h"
#include "power.h"
-#include "../module/stepper/indirection.h"
+#include "../module/stepper.h"
#include "../MarlinCore.h"
#if ENABLED(PS_OFF_SOUND)
@@ -82,7 +82,7 @@ void Power::power_on() {
TERN_(HAS_TRINAMIC_CONFIG, safe_delay(PSU_POWERUP_DELAY));
#ifdef PSU_POWERUP_GCODE
- GcodeSuite::process_subcommands_now_P(PSTR(PSU_POWERUP_GCODE));
+ gcode.process_subcommands_now(F(PSU_POWERUP_GCODE));
#endif
}
@@ -95,7 +95,7 @@ void Power::power_off() {
if (!psu_on) return;
#ifdef PSU_POWEROFF_GCODE
- GcodeSuite::process_subcommands_now_P(PSTR(PSU_POWEROFF_GCODE));
+ gcode.process_subcommands_now(F(PSU_POWEROFF_GCODE));
#endif
#if ENABLED(PS_OFF_SOUND)
@@ -120,6 +120,9 @@ void Power::power_off() {
*/
bool Power::is_power_needed() {
+ // If any of the stepper drivers are enabled...
+ if (stepper.axis_enabled.bits) return true;
+
if (printJobOngoing() || printingIsPaused()) return true;
#if ENABLED(AUTO_POWER_FANS)
@@ -140,23 +143,6 @@ void Power::power_off() {
if (TERN0(AUTO_POWER_COOLER_FAN, thermalManager.coolerfan_speed))
return true;
- // If any of the drivers or the bed are enabled...
- if (X_ENABLE_READ() == X_ENABLE_ON || Y_ENABLE_READ() == Y_ENABLE_ON || Z_ENABLE_READ() == Z_ENABLE_ON
- #if HAS_X2_ENABLE
- || X2_ENABLE_READ() == X_ENABLE_ON
- #endif
- #if HAS_Y2_ENABLE
- || Y2_ENABLE_READ() == Y_ENABLE_ON
- #endif
- #if HAS_Z2_ENABLE
- || Z2_ENABLE_READ() == Z_ENABLE_ON
- #endif
- #if E_STEPPERS
- #define _OR_ENABLED_E(N) || E##N##_ENABLE_READ() == E_ENABLE_ON
- REPEAT(E_STEPPERS, _OR_ENABLED_E)
- #endif
- ) return true;
-
#if HAS_HOTEND
HOTEND_LOOP() if (thermalManager.degTargetHotend(e) > 0 || thermalManager.temp_hotend[e].soft_pwm_amount > 0) return true;
#endif
diff --git a/Marlin/src/feature/powerloss.cpp b/Marlin/src/feature/powerloss.cpp
index a512022320db6..723ec1903bc84 100644
--- a/Marlin/src/feature/powerloss.cpp
+++ b/Marlin/src/feature/powerloss.cpp
@@ -40,7 +40,7 @@ uint8_t PrintJobRecovery::queue_index_r;
uint32_t PrintJobRecovery::cmd_sdpos, // = 0
PrintJobRecovery::sdpos[BUFSIZE];
-#if ENABLED(DWIN_CREALITY_LCD)
+#if HAS_DWIN_E3V2_BASIC
bool PrintJobRecovery::dwin_flag; // = false
#endif
@@ -109,7 +109,7 @@ void PrintJobRecovery::check() {
if (card.isMounted()) {
load();
if (!valid()) return cancel();
- queue.inject_P(PSTR("M1000S"));
+ queue.inject(F("M1000S"));
}
}
@@ -130,7 +130,7 @@ void PrintJobRecovery::load() {
(void)file.read(&info, sizeof(info));
close();
}
- debug(PSTR("Load"));
+ debug(F("Load"));
}
/**
@@ -186,7 +186,7 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW
TERN_(GCODE_REPEAT_MARKERS, info.stored_repeat = repeat);
TERN_(HAS_HOME_OFFSET, info.home_offset = home_offset);
TERN_(HAS_POSITION_SHIFT, info.position_shift = position_shift);
- TERN_(HAS_MULTI_EXTRUDER, info.active_extruder = active_extruder);
+ E_TERN_(info.active_extruder = active_extruder);
#if DISABLED(NO_VOLUMETRICS)
info.flag.volumetric_enabled = parser.volumetric_enabled;
@@ -244,7 +244,7 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW
#if POWER_LOSS_RETRACT_LEN
// Retract filament now
- gcode.process_subcommands_now_P(PSTR("G1 F3000 E-" STRINGIFY(POWER_LOSS_RETRACT_LEN)));
+ gcode.process_subcommands_now(F("G1 F3000 E-" STRINGIFY(POWER_LOSS_RETRACT_LEN)));
#endif
#if POWER_LOSS_ZRAISE
@@ -301,7 +301,7 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW
retract_and_lift(zraise);
#endif
- kill(GET_TEXT(MSG_OUTAGE_RECOVERY));
+ kill(GET_TEXT_F(MSG_OUTAGE_RECOVERY));
}
#endif
@@ -311,7 +311,7 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW
*/
void PrintJobRecovery::write() {
- debug(PSTR("Write"));
+ debug(F("Write"));
open(false);
file.seekSet(0);
@@ -337,7 +337,7 @@ void PrintJobRecovery::resume() {
#if HAS_LEVELING
// Make sure leveling is off before any G92 and G28
- gcode.process_subcommands_now_P(PSTR("M420 S0 Z0"));
+ gcode.process_subcommands_now(F("M420 S0 Z0"));
#endif
#if HAS_HEATED_BED
@@ -373,7 +373,7 @@ void PrintJobRecovery::resume() {
// establish the current position as best we can.
//
- gcode.process_subcommands_now_P(PSTR("G92.9E0")); // Reset E to 0
+ gcode.process_subcommands_now(F("G92.9E0")); // Reset E to 0
#if Z_HOME_TO_MAX
@@ -386,7 +386,7 @@ void PrintJobRecovery::resume() {
), dtostrf(z_now, 1, 3, str_1));
gcode.process_subcommands_now(cmd);
- #else
+ #elif DISABLED(BELTPRINTER)
#if ENABLED(POWER_LOSS_RECOVER_ZHOME) && defined(POWER_LOSS_ZHOME_POS)
#define HOMING_Z_DOWN 1
@@ -410,7 +410,7 @@ void PrintJobRecovery::resume() {
}
// Home XY with no Z raise, and also home Z here if Z isn't homing down below.
- gcode.process_subcommands_now_P(PSTR("G28R0" TERN_(HOME_XY_ONLY, "XY"))); // No raise during G28
+ gcode.process_subcommands_now(F("G28R0" TERN_(HOME_XY_ONLY, "XY"))); // No raise during G28
#endif
@@ -513,7 +513,7 @@ void PrintJobRecovery::resume() {
// Un-retract if there was a retract at outage
#if ENABLED(BACKUP_POWER_SUPPLY) && POWER_LOSS_RETRACT_LEN > 0
- gcode.process_subcommands_now_P(PSTR("G1E" STRINGIFY(POWER_LOSS_RETRACT_LEN) "F3000"));
+ gcode.process_subcommands_now(F("G1E" STRINGIFY(POWER_LOSS_RETRACT_LEN) "F3000"));
#endif
// Additional purge on resume if configured
@@ -523,7 +523,7 @@ void PrintJobRecovery::resume() {
#endif
#if ENABLED(NOZZLE_CLEAN_FEATURE)
- gcode.process_subcommands_now_P(PSTR("G12"));
+ gcode.process_subcommands_now(F("G12"));
#endif
// Move back over to the saved XY
@@ -575,9 +575,9 @@ void PrintJobRecovery::resume() {
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
- void PrintJobRecovery::debug(PGM_P const prefix) {
- DEBUG_ECHOPGM_P(prefix);
- DEBUG_ECHOLNPAIR(" Job Recovery Info...\nvalid_head:", info.valid_head, " valid_foot:", info.valid_foot);
+ void PrintJobRecovery::debug(FSTR_P const prefix) {
+ DEBUG_ECHOF(prefix);
+ DEBUG_ECHOLNPGM(" Job Recovery Info...\nvalid_head:", info.valid_head, " valid_foot:", info.valid_foot);
if (info.valid_head) {
if (info.valid_head == info.valid_foot) {
DEBUG_ECHOPGM("current_position: ");
@@ -587,14 +587,14 @@ void PrintJobRecovery::resume() {
}
DEBUG_EOL();
- DEBUG_ECHOLNPAIR("feedrate: ", info.feedrate);
+ DEBUG_ECHOLNPGM("feedrate: ", info.feedrate);
- DEBUG_ECHOLNPAIR("zraise: ", info.zraise, " ", info.flag.raised ? "(before)" : "");
+ DEBUG_ECHOLNPGM("zraise: ", info.zraise, " ", info.flag.raised ? "(before)" : "");
#if ENABLED(GCODE_REPEAT_MARKERS)
- DEBUG_ECHOLNPAIR("repeat index: ", info.stored_repeat.index);
+ DEBUG_ECHOLNPGM("repeat index: ", info.stored_repeat.index);
LOOP_L_N(i, info.stored_repeat.index)
- DEBUG_ECHOLNPAIR("..... sdpos: ", info.stored_repeat.marker.sdpos, " count: ", info.stored_repeat.marker.counter);
+ DEBUG_ECHOLNPGM("..... sdpos: ", info.stored_repeat.marker.sdpos, " count: ", info.stored_repeat.marker.counter);
#endif
#if HAS_HOME_OFFSET
@@ -616,12 +616,12 @@ void PrintJobRecovery::resume() {
#endif
#if HAS_MULTI_EXTRUDER
- DEBUG_ECHOLNPAIR("active_extruder: ", info.active_extruder);
+ DEBUG_ECHOLNPGM("active_extruder: ", info.active_extruder);
#endif
#if DISABLED(NO_VOLUMETRICS)
DEBUG_ECHOPGM("filament_size:");
- LOOP_L_N(i, EXTRUDERS) DEBUG_ECHOLNPAIR(" ", info.filament_size[i]);
+ LOOP_L_N(i, EXTRUDERS) DEBUG_ECHOLNPGM(" ", info.filament_size[i]);
DEBUG_EOL();
#endif
@@ -635,7 +635,7 @@ void PrintJobRecovery::resume() {
#endif
#if HAS_HEATED_BED
- DEBUG_ECHOLNPAIR("target_temperature_bed: ", info.target_temperature_bed);
+ DEBUG_ECHOLNPGM("target_temperature_bed: ", info.target_temperature_bed);
#endif
#if HAS_FAN
@@ -648,7 +648,7 @@ void PrintJobRecovery::resume() {
#endif
#if HAS_LEVELING
- DEBUG_ECHOLNPAIR("leveling: ", info.flag.leveling ? "ON" : "OFF", " fade: ", info.fade);
+ DEBUG_ECHOLNPGM("leveling: ", info.flag.leveling ? "ON" : "OFF", " fade: ", info.fade);
#endif
#if ENABLED(FWRETRACT)
@@ -658,17 +658,17 @@ void PrintJobRecovery::resume() {
if (e < EXTRUDERS - 1) DEBUG_CHAR(',');
}
DEBUG_EOL();
- DEBUG_ECHOLNPAIR("retract_hop: ", info.retract_hop);
+ DEBUG_ECHOLNPGM("retract_hop: ", info.retract_hop);
#endif
// Mixing extruder and gradient
#if BOTH(MIXING_EXTRUDER, GRADIENT_MIX)
- DEBUG_ECHOLNPAIR("gradient: ", info.gradient.enabled ? "ON" : "OFF");
+ DEBUG_ECHOLNPGM("gradient: ", info.gradient.enabled ? "ON" : "OFF");
#endif
- DEBUG_ECHOLNPAIR("sd_filename: ", info.sd_filename);
- DEBUG_ECHOLNPAIR("sdpos: ", info.sdpos);
- DEBUG_ECHOLNPAIR("print_job_elapsed: ", info.print_job_elapsed);
+ DEBUG_ECHOLNPGM("sd_filename: ", info.sd_filename);
+ DEBUG_ECHOLNPGM("sdpos: ", info.sdpos);
+ DEBUG_ECHOLNPGM("print_job_elapsed: ", info.print_job_elapsed);
DEBUG_ECHOPGM("axis_relative:");
if (TEST(info.axis_relative, REL_X)) DEBUG_ECHOPGM(" REL_X");
@@ -679,9 +679,9 @@ void PrintJobRecovery::resume() {
if (TEST(info.axis_relative, E_MODE_REL)) DEBUG_ECHOPGM(" E_MODE_REL");
DEBUG_EOL();
- DEBUG_ECHOLNPAIR("flag.dryrun: ", AS_DIGIT(info.flag.dryrun));
- DEBUG_ECHOLNPAIR("flag.allow_cold_extrusion: ", AS_DIGIT(info.flag.allow_cold_extrusion));
- DEBUG_ECHOLNPAIR("flag.volumetric_enabled: ", AS_DIGIT(info.flag.volumetric_enabled));
+ DEBUG_ECHOLNPGM("flag.dryrun: ", AS_DIGIT(info.flag.dryrun));
+ DEBUG_ECHOLNPGM("flag.allow_cold_extrusion: ", AS_DIGIT(info.flag.allow_cold_extrusion));
+ DEBUG_ECHOLNPGM("flag.volumetric_enabled: ", AS_DIGIT(info.flag.volumetric_enabled));
}
else
DEBUG_ECHOLNPGM("INVALID DATA");
diff --git a/Marlin/src/feature/powerloss.h b/Marlin/src/feature/powerloss.h
index d3ecc6c9cc0b2..76cb398af2a14 100644
--- a/Marlin/src/feature/powerloss.h
+++ b/Marlin/src/feature/powerloss.h
@@ -145,7 +145,7 @@ class PrintJobRecovery {
static uint32_t cmd_sdpos, //!< SD position of the next command
sdpos[BUFSIZE]; //!< SD positions of queued commands
- #if ENABLED(DWIN_CREALITY_LCD)
+ #if HAS_DWIN_E3V2_BASIC
static bool dwin_flag;
#endif
@@ -204,9 +204,9 @@ class PrintJobRecovery {
static inline bool valid() { return info.valid() && interrupted_file_exists(); }
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
- static void debug(PGM_P const prefix);
+ static void debug(FSTR_P const prefix);
#else
- static inline void debug(PGM_P const) {}
+ static inline void debug(FSTR_P const) {}
#endif
private:
diff --git a/Marlin/src/feature/probe_temp_comp.cpp b/Marlin/src/feature/probe_temp_comp.cpp
index 6f2dad58b9c8f..9a975d6763fae 100644
--- a/Marlin/src/feature/probe_temp_comp.cpp
+++ b/Marlin/src/feature/probe_temp_comp.cpp
@@ -22,37 +22,53 @@
#include "../inc/MarlinConfigPre.h"
-#if ENABLED(PROBE_TEMP_COMPENSATION)
+#if HAS_PTC
+
+//#define DEBUG_PTC // Print extra debug output with 'M871'
#include "probe_temp_comp.h"
#include
-ProbeTempComp temp_comp;
+ProbeTempComp ptc;
-int16_t ProbeTempComp::z_offsets_probe[cali_info_init[TSI_PROBE].measurements], // = {0}
- ProbeTempComp::z_offsets_bed[cali_info_init[TSI_BED].measurements]; // = {0}
+#if ENABLED(PTC_PROBE)
+ constexpr int16_t z_offsets_probe_default[PTC_PROBE_COUNT] = PTC_PROBE_ZOFFS;
+ int16_t ProbeTempComp::z_offsets_probe[PTC_PROBE_COUNT] = PTC_PROBE_ZOFFS;
+#endif
-#if ENABLED(USE_TEMP_EXT_COMPENSATION)
- int16_t ProbeTempComp::z_offsets_ext[cali_info_init[TSI_EXT].measurements]; // = {0}
+#if ENABLED(PTC_BED)
+ constexpr int16_t z_offsets_bed_default[PTC_BED_COUNT] = PTC_BED_ZOFFS;
+ int16_t ProbeTempComp::z_offsets_bed[PTC_BED_COUNT] = PTC_BED_ZOFFS;
#endif
-int16_t *ProbeTempComp::sensor_z_offsets[TSI_COUNT] = {
- ProbeTempComp::z_offsets_probe, ProbeTempComp::z_offsets_bed
- OPTARG(USE_TEMP_EXT_COMPENSATION, ProbeTempComp::z_offsets_ext)
-};
+#if ENABLED(PTC_HOTEND)
+ constexpr int16_t z_offsets_hotend_default[PTC_HOTEND_COUNT] = PTC_HOTEND_ZOFFS;
+ int16_t ProbeTempComp::z_offsets_hotend[PTC_HOTEND_COUNT] = PTC_HOTEND_ZOFFS;
+#endif
-const temp_calib_t ProbeTempComp::cali_info[TSI_COUNT] = {
- cali_info_init[TSI_PROBE], cali_info_init[TSI_BED]
- OPTARG(USE_TEMP_EXT_COMPENSATION, cali_info_init[TSI_EXT])
+int16_t *ProbeTempComp::sensor_z_offsets[TSI_COUNT] = {
+ #if ENABLED(PTC_PROBE)
+ ProbeTempComp::z_offsets_probe,
+ #endif
+ #if ENABLED(PTC_BED)
+ ProbeTempComp::z_offsets_bed,
+ #endif
+ #if ENABLED(PTC_HOTEND)
+ ProbeTempComp::z_offsets_hotend,
+ #endif
};
-constexpr xyz_pos_t ProbeTempComp::park_point;
-constexpr xy_pos_t ProbeTempComp::measure_point;
-constexpr celsius_t ProbeTempComp::probe_calib_bed_temp;
+constexpr temp_calib_t ProbeTempComp::cali_info[TSI_COUNT];
uint8_t ProbeTempComp::calib_idx; // = 0
float ProbeTempComp::init_measurement; // = 0.0
+void ProbeTempComp::reset() {
+ TERN_(PTC_PROBE, LOOP_L_N(i, PTC_PROBE_COUNT) z_offsets_probe[i] = z_offsets_probe_default[i]);
+ TERN_(PTC_BED, LOOP_L_N(i, PTC_BED_COUNT) z_offsets_bed[i] = z_offsets_bed_default[i]);
+ TERN_(PTC_HOTEND, LOOP_L_N(i, PTC_HOTEND_COUNT) z_offsets_hotend[i] = z_offsets_hotend_default[i]);
+}
+
void ProbeTempComp::clear_offsets(const TempSensorID tsi) {
LOOP_L_N(i, cali_info[tsi].measurements)
sensor_z_offsets[tsi][i] = 0;
@@ -69,19 +85,26 @@ void ProbeTempComp::print_offsets() {
LOOP_L_N(s, TSI_COUNT) {
celsius_t temp = cali_info[s].start_temp;
for (int16_t i = -1; i < cali_info[s].measurements; ++i) {
- SERIAL_ECHOPGM_P(s == TSI_BED ? PSTR("Bed") :
- #if ENABLED(USE_TEMP_EXT_COMPENSATION)
- s == TSI_EXT ? PSTR("Extruder") :
- #endif
- PSTR("Probe")
+ SERIAL_ECHOF(
+ TERN_(PTC_BED, s == TSI_BED ? F("Bed") :)
+ TERN_(PTC_HOTEND, s == TSI_EXT ? F("Extruder") :)
+ F("Probe")
);
- SERIAL_ECHOLNPAIR(
+ SERIAL_ECHOLNPGM(
" temp: ", temp,
"C; Offset: ", i < 0 ? 0.0f : sensor_z_offsets[s][i], " um"
);
- temp += cali_info[s].temp_res;
+ temp += cali_info[s].temp_resolution;
}
}
+ #if ENABLED(DEBUG_PTC)
+ float meas[4] = { 0, 0, 0, 0 };
+ compensate_measurement(TSI_PROBE, 27.5, meas[0]);
+ compensate_measurement(TSI_PROBE, 32.5, meas[1]);
+ compensate_measurement(TSI_PROBE, 77.5, meas[2]);
+ compensate_measurement(TSI_PROBE, 82.5, meas[3]);
+ SERIAL_ECHOLNPGM("DEBUG_PTC 27.5:", meas[0], " 32.5:", meas[1], " 77.5:", meas[2], " 82.5:", meas[3]);
+ #endif
}
void ProbeTempComp::prepare_new_calibration(const_float_t init_meas_z) {
@@ -90,46 +113,37 @@ void ProbeTempComp::prepare_new_calibration(const_float_t init_meas_z) {
}
void ProbeTempComp::push_back_new_measurement(const TempSensorID tsi, const_float_t meas_z) {
- switch (tsi) {
- case TSI_PROBE:
- case TSI_BED:
- //case TSI_EXT:
- if (calib_idx >= cali_info[tsi].measurements) return;
- sensor_z_offsets[tsi][calib_idx++] = static_cast(meas_z * 1000.0f - init_measurement * 1000.0f);
- default: break;
- }
+ if (calib_idx >= cali_info[tsi].measurements) return;
+ sensor_z_offsets[tsi][calib_idx++] = static_cast((meas_z - init_measurement) * 1000.0f);
}
bool ProbeTempComp::finish_calibration(const TempSensorID tsi) {
- if (tsi != TSI_PROBE && tsi != TSI_BED) return false;
-
- if (calib_idx < 3) {
- SERIAL_ECHOLNPGM("!Insufficient measurements (min. 3).");
+ if (!calib_idx) {
+ SERIAL_ECHOLNPGM("!No measurements.");
clear_offsets(tsi);
return false;
}
const uint8_t measurements = cali_info[tsi].measurements;
const celsius_t start_temp = cali_info[tsi].start_temp,
- res_temp = cali_info[tsi].temp_res;
+ res_temp = cali_info[tsi].temp_resolution;
int16_t * const data = sensor_z_offsets[tsi];
// Extrapolate
float k, d;
if (calib_idx < measurements) {
- SERIAL_ECHOLNPAIR("Got ", calib_idx, " measurements. ");
+ SERIAL_ECHOLNPGM("Got ", calib_idx, " measurements. ");
if (linear_regression(tsi, k, d)) {
SERIAL_ECHOPGM("Applying linear extrapolation");
- calib_idx--;
for (; calib_idx < measurements; ++calib_idx) {
- const celsius_float_t temp = start_temp + float(calib_idx) * res_temp;
+ const celsius_float_t temp = start_temp + float(calib_idx + 1) * res_temp;
data[calib_idx] = static_cast(k * temp + d);
}
}
else {
// Simply use the last measured value for higher temperatures
SERIAL_ECHOPGM("Failed to extrapolate");
- const int16_t last_val = data[calib_idx];
+ const int16_t last_val = data[calib_idx-1];
for (; calib_idx < measurements; ++calib_idx)
data[calib_idx] = last_val;
}
@@ -147,7 +161,7 @@ bool ProbeTempComp::finish_calibration(const TempSensorID tsi) {
// Restrict the max. offset difference between two probings
if (calib_idx > 0 && ABS(data[calib_idx - 1] - data[calib_idx]) > 800) {
SERIAL_ECHOLNPGM("!Invalid Z-offset between two probings detected (0-0.8).");
- clear_offsets(TSI_PROBE);
+ clear_offsets(tsi);
return false;
}
}
@@ -156,55 +170,52 @@ bool ProbeTempComp::finish_calibration(const TempSensorID tsi) {
}
void ProbeTempComp::compensate_measurement(const TempSensorID tsi, const celsius_t temp, float &meas_z) {
- if (WITHIN(temp, cali_info[tsi].start_temp, cali_info[tsi].end_temp))
- meas_z -= get_offset_for_temperature(tsi, temp);
-}
-
-float ProbeTempComp::get_offset_for_temperature(const TempSensorID tsi, const celsius_t temp) {
const uint8_t measurements = cali_info[tsi].measurements;
const celsius_t start_temp = cali_info[tsi].start_temp,
- res_temp = cali_info[tsi].temp_res;
+ res_temp = cali_info[tsi].temp_resolution,
+ end_temp = start_temp + measurements * res_temp;
const int16_t * const data = sensor_z_offsets[tsi];
- auto point = [&](uint8_t i) -> xy_float_t {
- return xy_float_t({ static_cast(start_temp) + i * res_temp, static_cast(data[i]) });
+ // Given a data index, return { celsius, zoffset } in the form { x, y }
+ auto tpoint = [&](uint8_t i) -> xy_float_t {
+ return xy_float_t({ static_cast(start_temp) + i * res_temp, i ? static_cast(data[i - 1]) : 0.0f });
};
+ // Interpolate Z based on a temperature being within a given range
auto linear_interp = [](const_float_t x, xy_float_t p1, xy_float_t p2) {
- return (p2.y - p1.y) / (p2.x - p2.y) * (x - p1.x) + p1.y;
+ // zoffs1 + zoffset_per_toffset * toffset
+ return p1.y + (p2.y - p1.y) / (p2.x - p1.x) * (x - p1.x);
};
- // Linear interpolation
- uint8_t idx = static_cast((temp - start_temp) / res_temp);
-
// offset in µm
float offset = 0.0f;
- #if !defined(PTC_LINEAR_EXTRAPOLATION) || PTC_LINEAR_EXTRAPOLATION <= 0
- if (idx < 0)
+ #if PTC_LINEAR_EXTRAPOLATION
+ if (temp < start_temp)
+ offset = linear_interp(temp, tpoint(0), tpoint(PTC_LINEAR_EXTRAPOLATION));
+ else if (temp >= end_temp)
+ offset = linear_interp(temp, tpoint(measurements - PTC_LINEAR_EXTRAPOLATION), tpoint(measurements));
+ #else
+ if (temp < start_temp)
offset = 0.0f;
- else if (idx > measurements - 2)
+ else if (temp >= end_temp)
offset = static_cast(data[measurements - 1]);
- #else
- if (idx < 0)
- offset = linear_interp(temp, point(0), point(PTC_LINEAR_EXTRAPOLATION));
- else if (idx > measurements - 2)
- offset = linear_interp(temp, point(measurements - PTC_LINEAR_EXTRAPOLATION - 1), point(measurements - 1));
#endif
- else
- offset = linear_interp(temp, point(idx), point(idx + 1));
+ else {
+ // Linear interpolation
+ const int8_t idx = static_cast((temp - start_temp) / res_temp);
+ offset = linear_interp(temp, tpoint(idx), tpoint(idx + 1));
+ }
- // return offset in mm
- return offset / 1000.0f;
+ // convert offset to mm and apply it
+ meas_z -= offset / 1000.0f;
}
bool ProbeTempComp::linear_regression(const TempSensorID tsi, float &k, float &d) {
- if (tsi != TSI_PROBE && tsi != TSI_BED) return false;
-
- if (!WITHIN(calib_idx, 2, cali_info[tsi].measurements)) return false;
+ if (!WITHIN(calib_idx, 1, cali_info[tsi].measurements)) return false;
const celsius_t start_temp = cali_info[tsi].start_temp,
- res_temp = cali_info[tsi].temp_res;
+ res_temp = cali_info[tsi].temp_resolution;
const int16_t * const data = sensor_z_offsets[tsi];
float sum_x = start_temp,
@@ -234,4 +245,4 @@ bool ProbeTempComp::linear_regression(const TempSensorID tsi, float &k, float &d
return true;
}
-#endif // PROBE_TEMP_COMPENSATION
+#endif // HAS_PTC
diff --git a/Marlin/src/feature/probe_temp_comp.h b/Marlin/src/feature/probe_temp_comp.h
index f5f922410c171..4579f2187cd41 100644
--- a/Marlin/src/feature/probe_temp_comp.h
+++ b/Marlin/src/feature/probe_temp_comp.h
@@ -24,19 +24,22 @@
#include "../inc/MarlinConfig.h"
enum TempSensorID : uint8_t {
- TSI_PROBE,
- TSI_BED,
- #if ENABLED(USE_TEMP_EXT_COMPENSATION)
+ #if ENABLED(PTC_PROBE)
+ TSI_PROBE,
+ #endif
+ #if ENABLED(PTC_BED)
+ TSI_BED,
+ #endif
+ #if ENABLED(PTC_HOTEND)
TSI_EXT,
#endif
TSI_COUNT
};
typedef struct {
- uint8_t measurements; // Max. number of measurements to be stored (35 - 80°C)
- celsius_t temp_res, // Resolution in °C between measurements
- start_temp, // Base measurement; z-offset == 0
- end_temp;
+ uint8_t measurements; // Max. number of measurements to be stored (35 - 80°C)
+ celsius_t temp_resolution, // Resolution in °C between measurements
+ start_temp; // Base measurement; z-offset == 0
} temp_calib_t;
/**
@@ -45,79 +48,40 @@ typedef struct {
* measurement errors/shifts due to changed temperature.
*/
-// Probe temperature calibration constants
-#ifndef PTC_SAMPLE_COUNT
- #define PTC_SAMPLE_COUNT 10
-#endif
-#ifndef PTC_SAMPLE_RES
- #define PTC_SAMPLE_RES 5
-#endif
-#ifndef PTC_SAMPLE_START
- #define PTC_SAMPLE_START 30
-#endif
-#define PTC_SAMPLE_END (PTC_SAMPLE_START + (PTC_SAMPLE_COUNT) * PTC_SAMPLE_RES)
-
-// Bed temperature calibration constants
-#ifndef BTC_PROBE_TEMP
- #define BTC_PROBE_TEMP 30
-#endif
-#ifndef BTC_SAMPLE_COUNT
- #define BTC_SAMPLE_COUNT 10
-#endif
-#ifndef BTC_SAMPLE_RES
- #define BTC_SAMPLE_RES 5
-#endif
-#ifndef BTC_SAMPLE_START
- #define BTC_SAMPLE_START 60
-#endif
-#define BTC_SAMPLE_END (BTC_SAMPLE_START + (BTC_SAMPLE_COUNT) * BTC_SAMPLE_RES)
-
-#ifndef PTC_PROBE_HEATING_OFFSET
- #define PTC_PROBE_HEATING_OFFSET 0.5f
-#endif
-
-#ifndef PTC_PROBE_RAISE
- #define PTC_PROBE_RAISE 10
-#endif
-
-static constexpr temp_calib_t cali_info_init[TSI_COUNT] = {
- { PTC_SAMPLE_COUNT, PTC_SAMPLE_RES, PTC_SAMPLE_START, PTC_SAMPLE_END }, // Probe
- { BTC_SAMPLE_COUNT, BTC_SAMPLE_RES, BTC_SAMPLE_START, BTC_SAMPLE_END }, // Bed
- #if ENABLED(USE_TEMP_EXT_COMPENSATION)
- { 20, 5, 180, 180 + 5 * 20 } // Extruder
- #endif
-};
-
class ProbeTempComp {
public:
- static const temp_calib_t cali_info[TSI_COUNT];
-
- // Where to park nozzle to wait for probe cooldown
- static constexpr xyz_pos_t park_point = PTC_PARK_POS;
-
- // XY coordinates of nozzle for probing the bed
- static constexpr xy_pos_t measure_point = PTC_PROBE_POS; // Coordinates to probe
- //measure_point = { 12.0f, 7.3f }; // Coordinates for the MK52 magnetic heatbed
-
- static constexpr celsius_t probe_calib_bed_temp = BED_MAX_TARGET, // Bed temperature while calibrating probe
- bed_calib_probe_temp = BTC_PROBE_TEMP; // Probe temperature while calibrating bed
-
- static int16_t *sensor_z_offsets[TSI_COUNT],
- z_offsets_probe[cali_info_init[TSI_PROBE].measurements], // (µm)
- z_offsets_bed[cali_info_init[TSI_BED].measurements]; // (µm)
-
- #if ENABLED(USE_TEMP_EXT_COMPENSATION)
- static int16_t z_offsets_ext[cali_info_init[TSI_EXT].measurements]; // (µm)
+ static constexpr temp_calib_t cali_info[TSI_COUNT] = {
+ #if ENABLED(PTC_PROBE)
+ { PTC_PROBE_COUNT, PTC_PROBE_RES, PTC_PROBE_START }, // Probe
+ #endif
+ #if ENABLED(PTC_BED)
+ { PTC_BED_COUNT, PTC_BED_RES, PTC_BED_START }, // Bed
+ #endif
+ #if ENABLED(PTC_HOTEND)
+ { PTC_HOTEND_COUNT, PTC_HOTEND_RES, PTC_HOTEND_START }, // Extruder
+ #endif
+ };
+
+ static int16_t *sensor_z_offsets[TSI_COUNT];
+ #if ENABLED(PTC_PROBE)
+ static int16_t z_offsets_probe[PTC_PROBE_COUNT]; // (µm)
+ #endif
+ #if ENABLED(PTC_BED)
+ static int16_t z_offsets_bed[PTC_BED_COUNT]; // (µm)
+ #endif
+ #if ENABLED(PTC_HOTEND)
+ static int16_t z_offsets_hotend[PTC_HOTEND_COUNT]; // (µm)
#endif
static inline void reset_index() { calib_idx = 0; };
static inline uint8_t get_index() { return calib_idx; }
+ static void reset();
static void clear_offsets(const TempSensorID tsi);
static inline void clear_all_offsets() {
- clear_offsets(TSI_BED);
- clear_offsets(TSI_PROBE);
- TERN_(USE_TEMP_EXT_COMPENSATION, clear_offsets(TSI_EXT));
+ TERN_(PTC_PROBE, clear_offsets(TSI_PROBE));
+ TERN_(PTC_BED, clear_offsets(TSI_BED));
+ TERN_(PTC_HOTEND, clear_offsets(TSI_EXT));
}
static bool set_offset(const TempSensorID tsi, const uint8_t idx, const int16_t offset);
static void print_offsets();
@@ -135,8 +99,6 @@ class ProbeTempComp {
*/
static float init_measurement;
- static float get_offset_for_temperature(const TempSensorID tsi, const celsius_t temp);
-
/**
* Fit a linear function in measured temperature offsets
* to allow generating values of higher temperatures.
@@ -144,4 +106,4 @@ class ProbeTempComp {
static bool linear_regression(const TempSensorID tsi, float &k, float &d);
};
-extern ProbeTempComp temp_comp;
+extern ProbeTempComp ptc;
diff --git a/Marlin/src/feature/repeat.cpp b/Marlin/src/feature/repeat.cpp
index 11e4dd6a93bbe..165f71fd0fae5 100644
--- a/Marlin/src/feature/repeat.cpp
+++ b/Marlin/src/feature/repeat.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "../inc/MarlinConfig.h"
#if ENABLED(GCODE_REPEAT_MARKERS)
@@ -43,7 +44,7 @@ void Repeat::add_marker(const uint32_t sdpos, const uint16_t count) {
marker[index].sdpos = sdpos;
marker[index].counter = count ?: -1;
index++;
- DEBUG_ECHOLNPAIR("Add Marker ", index, " at ", sdpos, " (", count, ")");
+ DEBUG_ECHOLNPGM("Add Marker ", index, " at ", sdpos, " (", count, ")");
}
}
@@ -53,14 +54,14 @@ void Repeat::loop() {
else {
const uint8_t ind = index - 1; // Active marker's index
if (!marker[ind].counter) { // Did its counter run out?
- DEBUG_ECHOLNPAIR("Pass Marker ", index);
+ DEBUG_ECHOLNPGM("Pass Marker ", index);
index--; // Carry on. Previous marker on the next 'M808'.
}
else {
card.setIndex(marker[ind].sdpos); // Loop back to the marker.
if (marker[ind].counter > 0) // Ignore a negative (or zero) counter.
--marker[ind].counter; // Decrement the counter. If zero this 'M808' will be skipped next time.
- DEBUG_ECHOLNPAIR("Goto Marker ", index, " at ", marker[ind].sdpos, " (", marker[ind].counter, ")");
+ DEBUG_ECHOLNPGM("Goto Marker ", index, " at ", marker[ind].sdpos, " (", marker[ind].counter, ")");
}
}
}
@@ -69,7 +70,7 @@ void Repeat::cancel() { LOOP_L_N(i, index) marker[i].counter = 0; }
void Repeat::early_parse_M808(char * const cmd) {
if (is_command_M808(cmd)) {
- DEBUG_ECHOLNPAIR("Parsing \"", cmd, "\"");
+ DEBUG_ECHOLNPGM("Parsing \"", cmd, "\"");
parser.parse(cmd);
if (parser.seen('L'))
add_marker(card.getIndex(), parser.value_ushort());
diff --git a/Marlin/src/feature/runout.cpp b/Marlin/src/feature/runout.cpp
index 531ca1081f0bd..9317e3489a830 100644
--- a/Marlin/src/feature/runout.cpp
+++ b/Marlin/src/feature/runout.cpp
@@ -68,6 +68,8 @@ bool FilamentMonitorBase::enabled = true,
#if ENABLED(EXTENSIBLE_UI)
#include "../lcd/extui/ui_api.h"
+#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
+ #include "../lcd/e3v2/enhanced/dwin.h"
#endif
void event_filament_runout(const uint8_t extruder) {
@@ -86,6 +88,7 @@ void event_filament_runout(const uint8_t extruder) {
#endif
TERN_(EXTENSIBLE_UI, ExtUI::onFilamentRunout(ExtUI::getTool(extruder)));
+ TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_FilamentRunout(extruder));
#if ANY(HOST_PROMPT_SUPPORT, HOST_ACTION_COMMANDS, MULTI_FILAMENT_SENSOR)
const char tool = '0' + TERN0(MULTI_FILAMENT_SENSOR, extruder);
@@ -93,8 +96,7 @@ void event_filament_runout(const uint8_t extruder) {
//action:out_of_filament
#if ENABLED(HOST_PROMPT_SUPPORT)
- host_action_prompt_begin(PROMPT_FILAMENT_RUNOUT, PSTR("FilamentRunout T"), tool);
- host_action_prompt_show();
+ hostui.prompt_do(PROMPT_FILAMENT_RUNOUT, F("FilamentRunout T"), tool); //action:out_of_filament
#endif
const bool run_runout_script = !runout.host_handling;
@@ -106,18 +108,18 @@ void event_filament_runout(const uint8_t extruder) {
|| TERN0(ADVANCED_PAUSE_FEATURE, strstr(FILAMENT_RUNOUT_SCRIPT, "M25"))
)
) {
- host_action_paused(false);
+ hostui.paused(false);
}
else {
// Legacy Repetier command for use until newer version supports standard dialog
// To be removed later when pause command also triggers dialog
#ifdef ACTION_ON_FILAMENT_RUNOUT
- host_action(PSTR(ACTION_ON_FILAMENT_RUNOUT " T"), false);
+ hostui.action(F(ACTION_ON_FILAMENT_RUNOUT " T"), false);
SERIAL_CHAR(tool);
SERIAL_EOL();
#endif
- host_action_pause(false);
+ hostui.pause(false);
}
SERIAL_ECHOPGM(" " ACTION_REASON_ON_FILAMENT_RUNOUT " ");
SERIAL_CHAR(tool);
@@ -129,7 +131,7 @@ void event_filament_runout(const uint8_t extruder) {
char script[strlen(FILAMENT_RUNOUT_SCRIPT) + 1];
sprintf_P(script, PSTR(FILAMENT_RUNOUT_SCRIPT), tool);
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
- SERIAL_ECHOLNPAIR("Runout Command: ", script);
+ SERIAL_ECHOLNPGM("Runout Command: ", script);
#endif
queue.inject(script);
#else
@@ -137,7 +139,7 @@ void event_filament_runout(const uint8_t extruder) {
SERIAL_ECHOPGM("Runout Command: ");
SERIAL_ECHOLNPGM(FILAMENT_RUNOUT_SCRIPT);
#endif
- queue.inject_P(PSTR(FILAMENT_RUNOUT_SCRIPT));
+ queue.inject(F(FILAMENT_RUNOUT_SCRIPT));
#endif
}
}
diff --git a/Marlin/src/feature/runout.h b/Marlin/src/feature/runout.h
index 93eb59c2a5181..8065e515559f6 100644
--- a/Marlin/src/feature/runout.h
+++ b/Marlin/src/feature/runout.h
@@ -145,7 +145,7 @@ class TFilamentMonitor : public FilamentMonitorBase {
if (runout_flags) {
SERIAL_ECHOPGM("Runout Sensors: ");
LOOP_L_N(i, 8) SERIAL_ECHO('0' + TEST(runout_flags, i));
- SERIAL_ECHOPAIR(" -> ", extruder);
+ SERIAL_ECHOPGM(" -> ", extruder);
if (ran_out) SERIAL_ECHOPGM(" RUN OUT");
SERIAL_EOL();
}
@@ -317,7 +317,7 @@ class FilamentSensorBase {
static uint8_t was_out; // = 0
if (out != TEST(was_out, s)) {
TBI(was_out, s);
- SERIAL_ECHOLNPAIR_P(PSTR("Filament Sensor "), '0' + s, out ? PSTR(" OUT") : PSTR(" IN"));
+ SERIAL_ECHOLNF(F("Filament Sensor "), AS_DIGIT(s), out ? F(" OUT") : F(" IN"));
}
#endif
}
@@ -352,7 +352,7 @@ class FilamentSensorBase {
if (ELAPSED(ms, t)) {
t = millis() + 1000UL;
LOOP_L_N(i, NUM_RUNOUT_SENSORS)
- SERIAL_ECHOPAIR_P(i ? PSTR(", ") : PSTR("Remaining mm: "), runout_mm_countdown[i]);
+ SERIAL_ECHOF(i ? F(", ") : F("Remaining mm: "), runout_mm_countdown[i]);
SERIAL_EOL();
}
#endif
@@ -373,7 +373,7 @@ class FilamentSensorBase {
// Only trigger on extrusion with XYZ movement to allow filament change and retract/recover.
const uint8_t e = b->extruder;
const int32_t steps = b->steps.e;
- runout_mm_countdown[e] -= (TEST(b->direction_bits, E_AXIS) ? -steps : steps) * planner.steps_to_mm[E_AXIS_N(e)];
+ runout_mm_countdown[e] -= (TEST(b->direction_bits, E_AXIS) ? -steps : steps) * planner.mm_per_step[E_AXIS_N(e)];
}
}
};
diff --git a/Marlin/src/feature/solenoid.cpp b/Marlin/src/feature/solenoid.cpp
index 623f223caa1b4..b6795d1a1ef8b 100644
--- a/Marlin/src/feature/solenoid.cpp
+++ b/Marlin/src/feature/solenoid.cpp
@@ -34,28 +34,12 @@
#include "../module/tool_change.h"
#endif
-#define HAS_SOLENOID(N) (HAS_SOLENOID_##N && (ENABLED(MANUAL_SOLENOID_CONTROL) || N < EXTRUDERS))
-
// Used primarily with MANUAL_SOLENOID_CONTROL
static void set_solenoid(const uint8_t num, const bool active) {
const uint8_t value = active ? PE_MAGNET_ON_STATE : !PE_MAGNET_ON_STATE;
+ #define _SOL_CASE(N) case N: TERN_(HAS_SOLENOID_##N, OUT_WRITE(SOL##N##_PIN, value)); break;
switch (num) {
- case 0: OUT_WRITE(SOL0_PIN, value); break;
- #if HAS_SOLENOID(1)
- case 1: OUT_WRITE(SOL1_PIN, value); break;
- #endif
- #if HAS_SOLENOID(2)
- case 2: OUT_WRITE(SOL2_PIN, value); break;
- #endif
- #if HAS_SOLENOID(3)
- case 3: OUT_WRITE(SOL3_PIN, value); break;
- #endif
- #if HAS_SOLENOID(4)
- case 4: OUT_WRITE(SOL4_PIN, value); break;
- #endif
- #if HAS_SOLENOID(5)
- case 5: OUT_WRITE(SOL5_PIN, value); break;
- #endif
+ REPEAT(8, _SOL_CASE)
default: SERIAL_ECHO_MSG(STR_INVALID_SOLENOID); break;
}
@@ -67,25 +51,11 @@ static void set_solenoid(const uint8_t num, const bool active) {
void enable_solenoid(const uint8_t num) { set_solenoid(num, true); }
void disable_solenoid(const uint8_t num) { set_solenoid(num, false); }
-void enable_solenoid_on_active_extruder() { enable_solenoid(active_extruder); }
+void enable_solenoid_on_active_extruder() { }
void disable_all_solenoids() {
- disable_solenoid(0);
- #if HAS_SOLENOID(1)
- disable_solenoid(1);
- #endif
- #if HAS_SOLENOID(2)
- disable_solenoid(2);
- #endif
- #if HAS_SOLENOID(3)
- disable_solenoid(3);
- #endif
- #if HAS_SOLENOID(4)
- disable_solenoid(4);
- #endif
- #if HAS_SOLENOID(5)
- disable_solenoid(5);
- #endif
+ #define _SOL_DISABLE(N) TERN_(HAS_SOLENOID_##N, disable_solenoid(N));
+ REPEAT(8, _SOL_DISABLE)
}
#endif // EXT_SOLENOID || MANUAL_SOLENOID_CONTROL
diff --git a/Marlin/src/feature/spindle_laser.cpp b/Marlin/src/feature/spindle_laser.cpp
index 539fafeb34989..9297e9b95c8a8 100644
--- a/Marlin/src/feature/spindle_laser.cpp
+++ b/Marlin/src/feature/spindle_laser.cpp
@@ -52,9 +52,9 @@ cutter_power_t SpindleLaser::menuPower, // Power s
#endif
#define SPINDLE_LASER_PWM_OFF TERN(SPINDLE_LASER_PWM_INVERT, 255, 0)
-//
-// Init the cutter to a safe OFF state
-//
+/**
+ * Init the cutter to a safe OFF state
+ */
void SpindleLaser::init() {
#if ENABLED(SPINDLE_SERVO)
MOVE_SERVO(SPINDLE_SERVO_NR, SPINDLE_SERVO_MIN);
@@ -64,9 +64,9 @@ void SpindleLaser::init() {
#if ENABLED(SPINDLE_CHANGE_DIR)
OUT_WRITE(SPINDLE_DIR_PIN, SPINDLE_INVERT_DIR ? 255 : 0); // Init rotation to clockwise (M3)
#endif
- #if ENABLED(SPINDLE_LASER_PWM)
+ #if ENABLED(SPINDLE_LASER_USE_PWM)
SET_PWM(SPINDLE_LASER_PWM_PIN);
- analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // Set to lowest speed
+ set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // Set to lowest speed
#endif
#if ENABLED(HAL_CAN_SET_PWM_FREQ) && defined(SPINDLE_LASER_FREQUENCY)
set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_FREQUENCY);
@@ -83,17 +83,17 @@ void SpindleLaser::init() {
#endif
}
-#if ENABLED(SPINDLE_LASER_PWM)
+#if ENABLED(SPINDLE_LASER_USE_PWM)
/**
* Set the cutter PWM directly to the given ocr value
+ *
+ * @param ocr Power value
*/
void SpindleLaser::_set_ocr(const uint8_t ocr) {
#if NEEDS_HARDWARE_PWM && SPINDLE_LASER_FREQUENCY
set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), TERN(MARLIN_DEV_MODE, frequency, SPINDLE_LASER_FREQUENCY));
- set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), ocr ^ SPINDLE_LASER_PWM_OFF);
- #else
- analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), ocr ^ SPINDLE_LASER_PWM_OFF);
#endif
+ set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), ocr ^ SPINDLE_LASER_PWM_OFF);
}
void SpindleLaser::set_ocr(const uint8_t ocr) {
@@ -105,17 +105,21 @@ void SpindleLaser::init() {
WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE); // Cutter OFF
_set_ocr(0);
}
-#endif
+#endif // SPINDLE_LASER_USE_PWM
-//
-// Set cutter ON/OFF state (and PWM) to the given cutter power value
-//
+/**
+ * Apply power for laser/spindle
+ *
+ * Apply cutter power value for PWM, Servo, and on/off pin.
+ *
+ * @param opwr Power value. Range 0 to MAX. When 0 disable spindle/laser.
+ */
void SpindleLaser::apply_power(const uint8_t opwr) {
static uint8_t last_power_applied = 0;
if (opwr == last_power_applied) return;
last_power_applied = opwr;
power = opwr;
- #if ENABLED(SPINDLE_LASER_PWM)
+ #if ENABLED(SPINDLE_LASER_USE_PWM)
if (cutter.unitPower == 0 && CUTTER_UNIT_IS(RPM)) {
ocr_off();
isReady = false;
@@ -137,10 +141,10 @@ void SpindleLaser::apply_power(const uint8_t opwr) {
}
#if ENABLED(SPINDLE_CHANGE_DIR)
- //
- // Set the spindle direction and apply immediately
- // Stop on direction change if SPINDLE_STOP_ON_DIR_CHANGE is enabled
- //
+ /**
+ * Set the spindle direction and apply immediately
+ * Stop on direction change if SPINDLE_STOP_ON_DIR_CHANGE is enabled
+ */
void SpindleLaser::set_reverse(const bool reverse) {
const bool dir_state = (reverse == SPINDLE_INVERT_DIR); // Forward (M3) HIGH when not inverted
if (TERN0(SPINDLE_STOP_ON_DIR_CHANGE, enabled()) && READ(SPINDLE_DIR_PIN) != dir_state) disable();
@@ -149,25 +153,17 @@ void SpindleLaser::apply_power(const uint8_t opwr) {
#endif
#if ENABLED(AIR_EVACUATION)
-
// Enable / disable Cutter Vacuum or Laser Blower motor
void SpindleLaser::air_evac_enable() { WRITE(AIR_EVACUATION_PIN, AIR_EVACUATION_ACTIVE); } // Turn ON
-
void SpindleLaser::air_evac_disable() { WRITE(AIR_EVACUATION_PIN, !AIR_EVACUATION_ACTIVE); } // Turn OFF
-
void SpindleLaser::air_evac_toggle() { TOGGLE(AIR_EVACUATION_PIN); } // Toggle state
-
-#endif // AIR_EVACUATION
+#endif
#if ENABLED(AIR_ASSIST)
-
// Enable / disable air assist
void SpindleLaser::air_assist_enable() { WRITE(AIR_ASSIST_PIN, AIR_ASSIST_PIN); } // Turn ON
-
void SpindleLaser::air_assist_disable() { WRITE(AIR_ASSIST_PIN, !AIR_ASSIST_PIN); } // Turn OFF
-
void SpindleLaser::air_assist_toggle() { TOGGLE(AIR_ASSIST_PIN); } // Toggle state
-
-#endif // AIR_ASSIST
+#endif
#endif // HAS_CUTTER
diff --git a/Marlin/src/feature/spindle_laser.h b/Marlin/src/feature/spindle_laser.h
index da228cf8a7063..ba82c4d7319a2 100644
--- a/Marlin/src/feature/spindle_laser.h
+++ b/Marlin/src/feature/spindle_laser.h
@@ -123,7 +123,7 @@ class SpindleLaser {
FORCE_INLINE static void refresh() { apply_power(power); }
FORCE_INLINE static void set_power(const uint8_t upwr) { power = upwr; refresh(); }
- #if ENABLED(SPINDLE_LASER_PWM)
+ #if ENABLED(SPINDLE_LASER_USE_PWM)
private:
@@ -132,54 +132,50 @@ class SpindleLaser {
public:
static void set_ocr(const uint8_t ocr);
- static inline void set_ocr_power(const uint8_t ocr) { power = ocr; set_ocr(ocr); }
+ static inline void ocr_set_power(const uint8_t ocr) { power = ocr; set_ocr(ocr); }
static void ocr_off();
- // Used to update output for power->OCR translation
+
+ /**
+ * Update output for power->OCR translation
+ */
static inline uint8_t upower_to_ocr(const cutter_power_t upwr) {
- return (
+ return uint8_t(
#if CUTTER_UNIT_IS(PWM255)
- uint8_t(upwr)
+ upwr
#elif CUTTER_UNIT_IS(PERCENT)
pct_to_ocr(upwr)
#else
- uint8_t(pct_to_ocr(cpwr_to_pct(upwr)))
+ pct_to_ocr(cpwr_to_pct(upwr))
#endif
);
}
- // Correct power to configured range
+ /**
+ * Correct power to configured range
+ */
static inline cutter_power_t power_to_range(const cutter_power_t pwr) {
- return power_to_range(pwr, (
- #if CUTTER_UNIT_IS(PWM255)
- 0
- #elif CUTTER_UNIT_IS(PERCENT)
- 1
- #elif CUTTER_UNIT_IS(RPM)
- 2
- #else
- #error "CUTTER_UNIT_IS(unknown)"
- #endif
- ));
+ return power_to_range(pwr, _CUTTER_POWER(CUTTER_POWER_UNIT));
}
+
static inline cutter_power_t power_to_range(const cutter_power_t pwr, const uint8_t pwrUnit) {
if (pwr <= 0) return 0;
cutter_power_t upwr;
switch (pwrUnit) {
- case 0: // PWM
+ case _CUTTER_POWER_PWM255:
upwr = cutter_power_t(
(pwr < pct_to_ocr(min_pct)) ? pct_to_ocr(min_pct) // Use minimum if set below
: (pwr > pct_to_ocr(max_pct)) ? pct_to_ocr(max_pct) // Use maximum if set above
: pwr
);
break;
- case 1: // PERCENT
+ case _CUTTER_POWER_PERCENT:
upwr = cutter_power_t(
(pwr < min_pct) ? min_pct // Use minimum if set below
: (pwr > max_pct) ? max_pct // Use maximum if set above
: pwr // PCT
);
break;
- case 2: // RPM
+ case _CUTTER_POWER_RPM:
upwr = cutter_power_t(
(pwr < SPEED_POWER_MIN) ? SPEED_POWER_MIN // Use minimum if set below
: (pwr > SPEED_POWER_MAX) ? SPEED_POWER_MAX // Use maximum if set above
@@ -190,14 +186,34 @@ class SpindleLaser {
}
return upwr;
}
+ #endif // SPINDLE_LASER_USE_PWM
- #endif // SPINDLE_LASER_PWM
-
+ /**
+ * Enable/Disable spindle/laser
+ * @param enable true = enable; false = disable
+ */
static inline void set_enabled(const bool enable) {
- set_power(enable ? TERN(SPINDLE_LASER_PWM, (power ?: (unitPower ? upower_to_ocr(cpwr_to_upwr(SPEED_POWER_STARTUP)) : 0)), 255) : 0);
+ uint8_t value = 0;
+ if (enable) {
+ #if ENABLED(SPINDLE_LASER_USE_PWM)
+ if (power)
+ value = power;
+ else if (unitPower)
+ value = upower_to_ocr(cpwr_to_upwr(SPEED_POWER_STARTUP));
+ #else
+ value = 255;
+ #endif
+ }
+ set_power(value);
}
- // Wait for spindle to spin up or spin down
+ static inline void disable() { isReady = false; set_enabled(false); }
+
+ /**
+ * Wait for spindle to spin up or spin down
+ *
+ * @param on true = state to on; false = state to off.
+ */
static inline void power_delay(const bool on) {
#if DISABLED(LASER_POWER_INLINE)
safe_delay(on ? SPINDLE_LASER_POWERUP_DELAY : SPINDLE_LASER_POWERDOWN_DELAY);
@@ -230,12 +246,10 @@ class SpindleLaser {
}
#endif
- static inline void disable() { isReady = false; set_enabled(false); }
-
#if HAS_LCD_MENU
static inline void enable_with_dir(const bool reverse) {
isReady = true;
- const uint8_t ocr = TERN(SPINDLE_LASER_PWM, upower_to_ocr(menuPower), 255);
+ const uint8_t ocr = TERN(SPINDLE_LASER_USE_PWM, upower_to_ocr(menuPower), 255);
if (menuPower)
power = ocr;
else
@@ -248,7 +262,7 @@ class SpindleLaser {
FORCE_INLINE static void enable_reverse() { enable_with_dir(true); }
FORCE_INLINE static void enable_same_dir() { enable_with_dir(is_reverse()); }
- #if ENABLED(SPINDLE_LASER_PWM)
+ #if ENABLED(SPINDLE_LASER_USE_PWM)
static inline void update_from_mpower() {
if (isReady) power = upower_to_ocr(menuPower);
unitPower = menuPower;
@@ -294,14 +308,14 @@ class SpindleLaser {
isReady = false;
unitPower = menuPower = 0;
planner.laser_inline.status.isPlanned = false;
- TERN(SPINDLE_LASER_PWM, inline_ocr_power, inline_power)(0);
+ TERN(SPINDLE_LASER_USE_PWM, inline_ocr_power, inline_power)(0);
}
}
// Set the power for subsequent movement blocks
static void inline_power(const cutter_power_t upwr) {
unitPower = menuPower = upwr;
- #if ENABLED(SPINDLE_LASER_PWM)
+ #if ENABLED(SPINDLE_LASER_USE_PWM)
#if ENABLED(SPEED_POWER_RELATIVE) && !CUTTER_UNIT_IS(RPM) // relative mode does not turn laser off at 0, except for RPM
planner.laser_inline.status.isEnabled = true;
planner.laser_inline.power = upower_to_ocr(upwr);
@@ -318,14 +332,14 @@ class SpindleLaser {
static inline void inline_direction(const bool) { /* never */ }
- #if ENABLED(SPINDLE_LASER_PWM)
+ #if ENABLED(SPINDLE_LASER_USE_PWM)
static inline void inline_ocr_power(const uint8_t ocrpwr) {
isReady = ocrpwr > 0;
planner.laser_inline.status.isEnabled = ocrpwr > 0;
planner.laser_inline.power = ocrpwr;
}
#endif
- #endif // LASER_POWER_INLINE
+ #endif // LASER_POWER_INLINE
static inline void kill() {
TERN_(LASER_POWER_INLINE, inline_disable());
diff --git a/Marlin/src/feature/stepper_driver_safety.cpp b/Marlin/src/feature/stepper_driver_safety.cpp
index 991f5a5906b41..11b90954b4f51 100644
--- a/Marlin/src/feature/stepper_driver_safety.cpp
+++ b/Marlin/src/feature/stepper_driver_safety.cpp
@@ -28,78 +28,52 @@
static uint32_t axis_plug_backward = 0;
-void stepper_driver_backward_error(PGM_P str) {
+void stepper_driver_backward_error(FSTR_P const fstr) {
SERIAL_ERROR_START();
- SERIAL_ECHOPGM_P(str);
+ SERIAL_ECHOF(fstr);
SERIAL_ECHOLNPGM(" driver is backward!");
- ui.status_printf_P(2, PSTR(S_FMT S_FMT), str, GET_TEXT(MSG_DRIVER_BACKWARD));
+ ui.status_printf(2, F(S_FMT S_FMT), FTOP(fstr), GET_TEXT(MSG_DRIVER_BACKWARD));
}
void stepper_driver_backward_check() {
OUT_WRITE(SAFE_POWER_PIN, LOW);
- #define TEST_BACKWARD(AXIS, BIT) do { \
+ #define _TEST_BACKWARD(AXIS, BIT) do { \
SET_INPUT(AXIS##_ENABLE_PIN); \
OUT_WRITE(AXIS##_STEP_PIN, false); \
delay(20); \
if (READ(AXIS##_ENABLE_PIN) == false) { \
SBI(axis_plug_backward, BIT); \
- stepper_driver_backward_error(PSTR(STRINGIFY(AXIS))); \
+ stepper_driver_backward_error(F(STRINGIFY(AXIS))); \
} \
}while(0)
- #if HAS_X_ENABLE
- TEST_BACKWARD(X, 0);
- #endif
- #if HAS_X2_ENABLE
- TEST_BACKWARD(X2, 1);
- #endif
-
- #if HAS_Y_ENABLE
- TEST_BACKWARD(Y, 2);
- #endif
- #if HAS_Y2_ENABLE
- TEST_BACKWARD(Y2, 3);
- #endif
-
- #if HAS_Z_ENABLE
- TEST_BACKWARD(Z, 4);
- #endif
- #if HAS_Z2_ENABLE
- TEST_BACKWARD(Z2, 5);
- #endif
- #if HAS_Z3_ENABLE
- TEST_BACKWARD(Z3, 6);
- #endif
- #if HAS_Z4_ENABLE
- TEST_BACKWARD(Z4, 7);
- #endif
-
- #if HAS_E0_ENABLE
- TEST_BACKWARD(E0, 8);
- #endif
- #if HAS_E1_ENABLE
- TEST_BACKWARD(E1, 9);
- #endif
- #if HAS_E2_ENABLE
- TEST_BACKWARD(E2, 10);
- #endif
- #if HAS_E3_ENABLE
- TEST_BACKWARD(E3, 11);
- #endif
- #if HAS_E4_ENABLE
- TEST_BACKWARD(E4, 12);
- #endif
- #if HAS_E5_ENABLE
- TEST_BACKWARD(E5, 13);
- #endif
- #if HAS_E6_ENABLE
- TEST_BACKWARD(E6, 14);
- #endif
- #if HAS_E7_ENABLE
- TEST_BACKWARD(E7, 15);
- #endif
+ #define TEST_BACKWARD(AXIS, BIT) TERN_(HAS_##AXIS##_ENABLE, _TEST_BACKWARD(AXIS, BIT))
+
+ TEST_BACKWARD(X, 0);
+ TEST_BACKWARD(X2, 1);
+
+ TEST_BACKWARD(Y, 2);
+ TEST_BACKWARD(Y2, 3);
+
+ TEST_BACKWARD(Z, 4);
+ TEST_BACKWARD(Z2, 5);
+ TEST_BACKWARD(Z3, 6);
+ TEST_BACKWARD(Z4, 7);
+
+ TEST_BACKWARD(I, 8);
+ TEST_BACKWARD(J, 9);
+ TEST_BACKWARD(K, 10);
+
+ TEST_BACKWARD(E0, 11);
+ TEST_BACKWARD(E1, 12);
+ TEST_BACKWARD(E2, 13);
+ TEST_BACKWARD(E3, 14);
+ TEST_BACKWARD(E4, 15);
+ TEST_BACKWARD(E5, 16);
+ TEST_BACKWARD(E6, 17);
+ TEST_BACKWARD(E7, 18);
if (!axis_plug_backward)
WRITE(SAFE_POWER_PIN, HIGH);
@@ -108,64 +82,36 @@ void stepper_driver_backward_check() {
void stepper_driver_backward_report() {
if (!axis_plug_backward) return;
- auto _report_if_backward = [](PGM_P axis, uint8_t bit) {
+ auto _report_if_backward = [](FSTR_P const axis, uint8_t bit) {
if (TEST(axis_plug_backward, bit))
stepper_driver_backward_error(axis);
};
- #define REPORT_BACKWARD(axis, bit) _report_if_backward(PSTR(STRINGIFY(axis)), bit)
-
- #if HAS_X_ENABLE
- REPORT_BACKWARD(X, 0);
- #endif
- #if HAS_X2_ENABLE
- REPORT_BACKWARD(X2, 1);
- #endif
-
- #if HAS_Y_ENABLE
- REPORT_BACKWARD(Y, 2);
- #endif
- #if HAS_Y2_ENABLE
- REPORT_BACKWARD(Y2, 3);
- #endif
-
- #if HAS_Z_ENABLE
- REPORT_BACKWARD(Z, 4);
- #endif
- #if HAS_Z2_ENABLE
- REPORT_BACKWARD(Z2, 5);
- #endif
- #if HAS_Z3_ENABLE
- REPORT_BACKWARD(Z3, 6);
- #endif
- #if HAS_Z4_ENABLE
- REPORT_BACKWARD(Z4, 7);
- #endif
-
- #if HAS_E0_ENABLE
- REPORT_BACKWARD(E0, 8);
- #endif
- #if HAS_E1_ENABLE
- REPORT_BACKWARD(E1, 9);
- #endif
- #if HAS_E2_ENABLE
- REPORT_BACKWARD(E2, 10);
- #endif
- #if HAS_E3_ENABLE
- REPORT_BACKWARD(E3, 11);
- #endif
- #if HAS_E4_ENABLE
- REPORT_BACKWARD(E4, 12);
- #endif
- #if HAS_E5_ENABLE
- REPORT_BACKWARD(E5, 13);
- #endif
- #if HAS_E6_ENABLE
- REPORT_BACKWARD(E6, 14);
- #endif
- #if HAS_E7_ENABLE
- REPORT_BACKWARD(E7, 15);
- #endif
+ #define REPORT_BACKWARD(axis, bit) TERN_(HAS_##axis##_ENABLE, _report_if_backward(F(STRINGIFY(axis)), bit))
+
+ REPORT_BACKWARD(X, 0);
+ REPORT_BACKWARD(X2, 1);
+
+ REPORT_BACKWARD(Y, 2);
+ REPORT_BACKWARD(Y2, 3);
+
+ REPORT_BACKWARD(Z, 4);
+ REPORT_BACKWARD(Z2, 5);
+ REPORT_BACKWARD(Z3, 6);
+ REPORT_BACKWARD(Z4, 7);
+
+ REPORT_BACKWARD(I, 8);
+ REPORT_BACKWARD(J, 9);
+ REPORT_BACKWARD(K, 10);
+
+ REPORT_BACKWARD(E0, 11);
+ REPORT_BACKWARD(E1, 12);
+ REPORT_BACKWARD(E2, 13);
+ REPORT_BACKWARD(E3, 14);
+ REPORT_BACKWARD(E4, 15);
+ REPORT_BACKWARD(E5, 16);
+ REPORT_BACKWARD(E6, 17);
+ REPORT_BACKWARD(E7, 18);
}
#endif // HAS_DRIVER_SAFE_POWER_PROTECT
diff --git a/Marlin/src/feature/tmc_util.cpp b/Marlin/src/feature/tmc_util.cpp
index 99cfd996c8435..82c10e6e8ec2d 100644
--- a/Marlin/src/feature/tmc_util.cpp
+++ b/Marlin/src/feature/tmc_util.cpp
@@ -212,7 +212,7 @@
if (data.is_ot) SERIAL_ECHOLNPGM("overtemperature");
if (data.is_s2g) SERIAL_ECHOLNPGM("coil short circuit");
TERN_(TMC_DEBUG, tmc_report_all());
- kill(PSTR("Driver error"));
+ kill(F("Driver error"));
}
#endif
@@ -226,7 +226,7 @@
SERIAL_ECHO(timestamp);
SERIAL_ECHOPGM(": ");
st.printLabel();
- SERIAL_ECHOLNPAIR(" driver overtemperature warning! (", st.getMilliamps(), "mA)");
+ SERIAL_ECHOLNPGM(" driver overtemperature warning! (", st.getMilliamps(), "mA)");
}
template
@@ -271,7 +271,7 @@
st.rms_current(I_rms);
#if ENABLED(REPORT_CURRENT_CHANGE)
st.printLabel();
- SERIAL_ECHOLNPAIR(" current decreased to ", I_rms);
+ SERIAL_ECHOLNPGM(" current decreased to ", I_rms);
#endif
}
}
@@ -561,7 +561,7 @@
};
template
- static void print_vsense(TMC &st) { SERIAL_ECHOPGM_P(st.vsense() ? PSTR("1=.18") : PSTR("0=.325")); }
+ static void print_vsense(TMC &st) { SERIAL_ECHOF(st.vsense() ? F("1=.18") : F("0=.325")); }
#if HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC5130)
static void _tmc_status(TMC2130Stepper &st, const TMC_debug_enum i) {
@@ -732,7 +732,7 @@
SERIAL_ECHO(st.cs());
SERIAL_ECHOPGM("/31");
break;
- case TMC_VSENSE: SERIAL_ECHOPGM_P(st.vsense() ? PSTR("1=.165") : PSTR("0=.310")); break;
+ case TMC_VSENSE: SERIAL_ECHOF(st.vsense() ? F("1=.165") : F("0=.310")); break;
case TMC_MICROSTEPS: SERIAL_ECHO(st.microsteps()); break;
//case TMC_OTPW: serialprint_truefalse(st.otpw()); break;
//case TMC_OTPW_TRIGGERED: serialprint_truefalse(st.getOTPW()); break;
@@ -1256,15 +1256,14 @@ static bool test_connection(TMC &st) {
if (test_result > 0) SERIAL_ECHOPGM("Error: All ");
- const char *stat;
+ FSTR_P stat;
switch (test_result) {
default:
- case 0: stat = PSTR("OK"); break;
- case 1: stat = PSTR("HIGH"); break;
- case 2: stat = PSTR("LOW"); break;
+ case 0: stat = F("OK"); break;
+ case 1: stat = F("HIGH"); break;
+ case 2: stat = F("LOW"); break;
}
- SERIAL_ECHOPGM_P(stat);
- SERIAL_EOL();
+ SERIAL_ECHOLNF(stat);
return test_result;
}
@@ -1342,7 +1341,7 @@ void test_tmc_connection(LOGICAL_AXIS_ARGS(const bool)) {
#endif
}
- if (axis_connection) LCD_MESSAGEPGM(MSG_ERROR_TMC);
+ if (axis_connection) LCD_MESSAGE(MSG_ERROR_TMC);
}
#endif // HAS_TRINAMIC_CONFIG
diff --git a/Marlin/src/feature/tmc_util.h b/Marlin/src/feature/tmc_util.h
index 87780486ebaab..1f7d5cf1a5432 100644
--- a/Marlin/src/feature/tmc_util.h
+++ b/Marlin/src/feature/tmc_util.h
@@ -300,7 +300,7 @@ class TMCMarlin : public TMC266
template
void tmc_print_current(TMC &st) {
st.printLabel();
- SERIAL_ECHOLNPAIR(" driver current: ", st.getMilliamps());
+ SERIAL_ECHOLNPGM(" driver current: ", st.getMilliamps());
}
#if ENABLED(MONITOR_DRIVER_STATUS)
@@ -322,7 +322,7 @@ void tmc_print_current(TMC &st) {
template
void tmc_print_pwmthrs(TMC &st) {
st.printLabel();
- SERIAL_ECHOLNPAIR(" stealthChop max speed: ", st.get_pwm_thrs());
+ SERIAL_ECHOLNPGM(" stealthChop max speed: ", st.get_pwm_thrs());
}
#endif
#if USE_SENSORLESS
diff --git a/Marlin/src/feature/tramming.h b/Marlin/src/feature/tramming.h
index eb27fe82fe2ac..925659e29db25 100644
--- a/Marlin/src/feature/tramming.h
+++ b/Marlin/src/feature/tramming.h
@@ -28,12 +28,12 @@
#error "TRAMMING_SCREW_THREAD must be equal to 30, 31, 40, 41, 50, or 51."
#endif
-constexpr xy_pos_t screws_tilt_adjust_pos[] = TRAMMING_POINT_XY;
+constexpr xy_pos_t tramming_points[] = TRAMMING_POINT_XY;
-#define G35_PROBE_COUNT COUNT(screws_tilt_adjust_pos)
+#define G35_PROBE_COUNT COUNT(tramming_points)
static_assert(WITHIN(G35_PROBE_COUNT, 3, 6), "TRAMMING_POINT_XY requires between 3 and 6 XY positions.");
-#define VALIDATE_TRAMMING_POINT(N) static_assert(N >= G35_PROBE_COUNT || Probe::build_time::can_reach(screws_tilt_adjust_pos[N]), \
+#define VALIDATE_TRAMMING_POINT(N) static_assert(N >= G35_PROBE_COUNT || Probe::build_time::can_reach(tramming_points[N]), \
"TRAMMING_POINT_XY point " STRINGIFY(N) " is not reachable with the default NOZZLE_TO_PROBE offset and PROBING_MARGIN.")
VALIDATE_TRAMMING_POINT(0); VALIDATE_TRAMMING_POINT(1); VALIDATE_TRAMMING_POINT(2); VALIDATE_TRAMMING_POINT(3); VALIDATE_TRAMMING_POINT(4); VALIDATE_TRAMMING_POINT(5);
diff --git a/Marlin/src/feature/twibus.cpp b/Marlin/src/feature/twibus.cpp
index 755224544c6ea..e33581676c4a3 100644
--- a/Marlin/src/feature/twibus.cpp
+++ b/Marlin/src/feature/twibus.cpp
@@ -28,11 +28,17 @@
#include
+#include "../libs/hex_print.h"
+
TWIBus i2c;
TWIBus::TWIBus() {
#if I2C_SLAVE_ADDRESS == 0
- Wire.begin(); // No address joins the BUS as the master
+ Wire.begin( // No address joins the BUS as the master
+ #if PINS_EXIST(I2C_SCL, I2C_SDA) && DISABLED(SOFT_I2C_EEPROM)
+ pin_t(I2C_SDA_PIN), pin_t(I2C_SCL_PIN)
+ #endif
+ );
#else
Wire.begin(I2C_SLAVE_ADDRESS); // Join the bus as a slave
#endif
@@ -51,27 +57,27 @@ void TWIBus::address(const uint8_t adr) {
addr = adr;
- debug(PSTR("address"), adr);
+ debug(F("address"), adr);
}
void TWIBus::addbyte(const char c) {
if (buffer_s >= COUNT(buffer)) return;
buffer[buffer_s++] = c;
- debug(PSTR("addbyte"), c);
+ debug(F("addbyte"), c);
}
void TWIBus::addbytes(char src[], uint8_t bytes) {
- debug(PSTR("addbytes"), bytes);
+ debug(F("addbytes"), bytes);
while (bytes--) addbyte(*src++);
}
void TWIBus::addstring(char str[]) {
- debug(PSTR("addstring"), str);
+ debug(F("addstring"), str);
while (char c = *str++) addbyte(c);
}
void TWIBus::send() {
- debug(PSTR("send"), addr);
+ debug(F("send"), addr);
Wire.beginTransmission(I2C_ADDRESS(addr));
Wire.write(buffer, buffer_s);
@@ -81,21 +87,60 @@ void TWIBus::send() {
}
// static
-void TWIBus::echoprefix(uint8_t bytes, const char pref[], uint8_t adr) {
+void TWIBus::echoprefix(uint8_t bytes, FSTR_P const pref, uint8_t adr) {
SERIAL_ECHO_START();
- SERIAL_ECHOPGM_P(pref);
- SERIAL_ECHOPAIR(": from:", adr, " bytes:", bytes, " data:");
+ SERIAL_ECHOF(pref);
+ SERIAL_ECHOPGM(": from:", adr, " bytes:", bytes, " data:");
}
// static
-void TWIBus::echodata(uint8_t bytes, const char pref[], uint8_t adr) {
+void TWIBus::echodata(uint8_t bytes, FSTR_P const pref, uint8_t adr, const uint8_t style/*=0*/) {
+ union TwoBytesToInt16 { uint8_t bytes[2]; int16_t integervalue; };
+ TwoBytesToInt16 ConversionUnion;
+
echoprefix(bytes, pref, adr);
- while (bytes-- && Wire.available()) SERIAL_CHAR(Wire.read());
+
+ while (bytes-- && Wire.available()) {
+ int value = Wire.read();
+ switch (style) {
+
+ // Style 1, HEX DUMP
+ case 1:
+ SERIAL_CHAR(hex_nybble((value & 0xF0) >> 4));
+ SERIAL_CHAR(hex_nybble(value & 0x0F));
+ if (bytes) SERIAL_CHAR(' ');
+ break;
+
+ // Style 2, signed two byte integer (int16)
+ case 2:
+ if (bytes == 1)
+ ConversionUnion.bytes[1] = (uint8_t)value;
+ else if (bytes == 0) {
+ ConversionUnion.bytes[0] = (uint8_t)value;
+ // Output value in base 10 (standard decimal)
+ SERIAL_ECHO(ConversionUnion.integervalue);
+ }
+ break;
+
+ // Style 3, unsigned byte, base 10 (uint8)
+ case 3:
+ SERIAL_ECHO(value);
+ if (bytes) SERIAL_CHAR(' ');
+ break;
+
+ // Default style (zero), raw serial output
+ default:
+ // This can cause issues with some serial consoles, Pronterface is an example where things go wrong
+ SERIAL_CHAR(value);
+ break;
+ }
+ }
+
SERIAL_EOL();
}
-void TWIBus::echobuffer(const char pref[], uint8_t adr) {
- echoprefix(buffer_s, pref, adr);
+void TWIBus::echobuffer(FSTR_P const prefix, uint8_t adr) {
+ echoprefix(buffer_s, prefix, adr);
LOOP_L_N(i, buffer_s) SERIAL_CHAR(buffer[i]);
SERIAL_EOL();
}
@@ -103,22 +148,22 @@ void TWIBus::echobuffer(const char pref[], uint8_t adr) {
bool TWIBus::request(const uint8_t bytes) {
if (!addr) return false;
- debug(PSTR("request"), bytes);
+ debug(F("request"), bytes);
// requestFrom() is a blocking function
if (Wire.requestFrom(I2C_ADDRESS(addr), bytes) == 0) {
- debug("request fail", I2C_ADDRESS(addr));
+ debug(F("request fail"), I2C_ADDRESS(addr));
return false;
}
return true;
}
-void TWIBus::relay(const uint8_t bytes) {
- debug(PSTR("relay"), bytes);
+void TWIBus::relay(const uint8_t bytes, const uint8_t style/*=0*/) {
+ debug(F("relay"), bytes);
if (request(bytes))
- echodata(bytes, PSTR("i2c-reply"), addr);
+ echodata(bytes, F("i2c-reply"), addr, style);
}
uint8_t TWIBus::capture(char *dst, const uint8_t bytes) {
@@ -127,7 +172,7 @@ uint8_t TWIBus::capture(char *dst, const uint8_t bytes) {
while (count < bytes && Wire.available())
dst[count++] = Wire.read();
- debug(PSTR("capture"), count);
+ debug(F("capture"), count);
return count;
}
@@ -140,12 +185,12 @@ void TWIBus::flush() {
#if I2C_SLAVE_ADDRESS > 0
void TWIBus::receive(uint8_t bytes) {
- debug(PSTR("receive"), bytes);
- echodata(bytes, PSTR("i2c-receive"), 0);
+ debug(F("receive"), bytes);
+ echodata(bytes, F("i2c-receive"), 0);
}
void TWIBus::reply(char str[]/*=nullptr*/) {
- debug(PSTR("reply"), str);
+ debug(F("reply"), str);
if (str) {
reset();
@@ -170,18 +215,16 @@ void TWIBus::flush() {
#if ENABLED(DEBUG_TWIBUS)
// static
- void TWIBus::prefix(const char func[]) {
- SERIAL_ECHOPGM("TWIBus::");
- SERIAL_ECHOPGM_P(func);
- SERIAL_ECHOPGM(": ");
+ void TWIBus::prefix(FSTR_P const func) {
+ SERIAL_ECHOPGM("TWIBus::", func, ": ");
}
- void TWIBus::debug(const char func[], uint32_t adr) {
+ void TWIBus::debug(FSTR_P const func, uint32_t adr) {
if (DEBUGGING(INFO)) { prefix(func); SERIAL_ECHOLN(adr); }
}
- void TWIBus::debug(const char func[], char c) {
+ void TWIBus::debug(FSTR_P const func, char c) {
if (DEBUGGING(INFO)) { prefix(func); SERIAL_ECHOLN(c); }
}
- void TWIBus::debug(const char func[], char str[]) {
+ void TWIBus::debug(FSTR_P const func, char str[]) {
if (DEBUGGING(INFO)) { prefix(func); SERIAL_ECHOLN(str); }
}
diff --git a/Marlin/src/feature/twibus.h b/Marlin/src/feature/twibus.h
index 59391534824cd..d2c7270303c72 100644
--- a/Marlin/src/feature/twibus.h
+++ b/Marlin/src/feature/twibus.h
@@ -142,7 +142,7 @@ class TWIBus {
*
* @param bytes the number of bytes to request
*/
- static void echoprefix(uint8_t bytes, const char prefix[], uint8_t adr);
+ static void echoprefix(uint8_t bytes, FSTR_P const prefix, uint8_t adr);
/**
* @brief Echo data on the bus to serial
@@ -150,8 +150,9 @@ class TWIBus {
* to serial in a parser-friendly format.
*
* @param bytes the number of bytes to request
+ * @param style Output format for the bytes, 0 = Raw byte [default], 1 = Hex characters, 2 = uint16_t
*/
- static void echodata(uint8_t bytes, const char prefix[], uint8_t adr);
+ static void echodata(uint8_t bytes, FSTR_P const prefix, uint8_t adr, const uint8_t style=0);
/**
* @brief Echo data in the buffer to serial
@@ -160,7 +161,7 @@ class TWIBus {
*
* @param bytes the number of bytes to request
*/
- void echobuffer(const char prefix[], uint8_t adr);
+ void echobuffer(FSTR_P const prefix, uint8_t adr);
/**
* @brief Request data from the slave device and wait.
@@ -192,10 +193,11 @@ class TWIBus {
* @brief Request data from the slave device, echo to serial.
* @details Request a number of bytes from a slave device and output
* the returned data to serial in a parser-friendly format.
+ * @style Output format for the bytes, 0 = raw byte [default], 1 = Hex characters, 2 = uint16_t
*
* @param bytes the number of bytes to request
*/
- void relay(const uint8_t bytes);
+ void relay(const uint8_t bytes, const uint8_t style=0);
#if I2C_SLAVE_ADDRESS > 0
@@ -237,17 +239,16 @@ class TWIBus {
* @brief Prints a debug message
* @details Prints a simple debug message "TWIBus::function: value"
*/
- static void prefix(const char func[]);
- static void debug(const char func[], uint32_t adr);
- static void debug(const char func[], char c);
- static void debug(const char func[], char adr[]);
- static inline void debug(const char func[], uint8_t v) { debug(func, (uint32_t)v); }
+ static void prefix(FSTR_P const func);
+ static void debug(FSTR_P const func, uint32_t adr);
+ static void debug(FSTR_P const func, char c);
+ static void debug(FSTR_P const func, char adr[]);
#else
- static inline void debug(const char[], uint32_t) {}
- static inline void debug(const char[], char) {}
- static inline void debug(const char[], char[]) {}
- static inline void debug(const char[], uint8_t) {}
+ static inline void debug(FSTR_P const, uint32_t) {}
+ static inline void debug(FSTR_P const, char) {}
+ static inline void debug(FSTR_P const, char[]) {}
#endif
+ static inline void debug(FSTR_P const func, uint8_t v) { debug(func, (uint32_t)v); }
};
extern TWIBus i2c;
diff --git a/Marlin/src/gcode/bedlevel/G26.cpp b/Marlin/src/gcode/bedlevel/G26.cpp
index 882197139ee1f..728771d5809db 100644
--- a/Marlin/src/gcode/bedlevel/G26.cpp
+++ b/Marlin/src/gcode/bedlevel/G26.cpp
@@ -163,7 +163,7 @@ float g26_random_deviation = 0.0;
*/
bool user_canceled() {
if (!ui.button_pressed()) return false; // Return if the button isn't pressed
- ui.set_status_P(GET_TEXT(MSG_G26_CANCELED), 99);
+ ui.set_status(GET_TEXT_F(MSG_G26_CANCELED), 99);
TERN_(HAS_LCD_MENU, ui.quick_feedback());
ui.wait_for_release();
return true;
@@ -323,7 +323,7 @@ typedef struct {
if (bed_temp > 25) {
#if HAS_WIRED_LCD
- ui.set_status_P(GET_TEXT(MSG_G26_HEATING_BED), 99);
+ ui.set_status(GET_TEXT_F(MSG_G26_HEATING_BED), 99);
ui.quick_feedback();
TERN_(HAS_LCD_MENU, ui.capture());
#endif
@@ -342,7 +342,7 @@ typedef struct {
// Start heating the active nozzle
#if HAS_WIRED_LCD
- ui.set_status_P(GET_TEXT(MSG_G26_HEATING_NOZZLE), 99);
+ ui.set_status(GET_TEXT_F(MSG_G26_HEATING_NOZZLE), 99);
ui.quick_feedback();
#endif
thermalManager.setTargetHotend(hotend_temp, active_extruder);
@@ -372,7 +372,7 @@ typedef struct {
if (prime_flag == -1) { // The user wants to control how much filament gets purged
ui.capture();
- ui.set_status_P(GET_TEXT(MSG_G26_MANUAL_PRIME), 99);
+ ui.set_status(GET_TEXT_F(MSG_G26_MANUAL_PRIME), 99);
ui.chirp();
destination = current_position;
@@ -399,7 +399,7 @@ typedef struct {
ui.wait_for_release();
- ui.set_status_P(GET_TEXT(MSG_G26_PRIME_DONE), 99);
+ ui.set_status(GET_TEXT_F(MSG_G26_PRIME_DONE), 99);
ui.quick_feedback();
ui.release();
}
@@ -407,7 +407,7 @@ typedef struct {
#endif
{
#if HAS_WIRED_LCD
- ui.set_status_P(GET_TEXT(MSG_G26_FIXED_LENGTH), 99);
+ ui.set_status(GET_TEXT_F(MSG_G26_FIXED_LENGTH), 99);
ui.quick_feedback();
#endif
destination = current_position;
@@ -520,7 +520,7 @@ void GcodeSuite::G26() {
g26.keep_heaters_on = parser.boolval('K');
// Accept 'I' if temperature presets are defined
- #if PREHEAT_COUNT
+ #if HAS_PREHEAT
const uint8_t preset_index = parser.seenval('I') ? _MIN(parser.value_byte(), PREHEAT_COUNT - 1) + 1 : 0;
#endif
@@ -530,7 +530,7 @@ void GcodeSuite::G26() {
celsius_t bedtemp = 0;
// Use the 'I' index if temperature presets are defined
- #if PREHEAT_COUNT
+ #if HAS_PREHEAT
if (preset_index) bedtemp = ui.material_preset[preset_index - 1].bed_temp;
#endif
@@ -539,7 +539,7 @@ void GcodeSuite::G26() {
if (bedtemp) {
if (!WITHIN(bedtemp, 40, BED_MAX_TARGET)) {
- SERIAL_ECHOLNPAIR("?Specified bed temperature not plausible (40-", BED_MAX_TARGET, "C).");
+ SERIAL_ECHOLNPGM("?Specified bed temperature not plausible (40-", BED_MAX_TARGET, "C).");
return;
}
g26.bed_temp = bedtemp;
@@ -613,7 +613,7 @@ void GcodeSuite::G26() {
celsius_t noztemp = 0;
// Accept 'I' if temperature presets are defined
- #if PREHEAT_COUNT
+ #if HAS_PREHEAT
if (preset_index) noztemp = ui.material_preset[preset_index - 1].hotend_temp;
#endif
@@ -854,7 +854,7 @@ void GcodeSuite::G26() {
} while (--g26_repeats && location.valid());
LEAVE:
- ui.set_status_P(GET_TEXT(MSG_G26_LEAVING), -1);
+ ui.set_status(GET_TEXT_F(MSG_G26_LEAVING), -1);
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(location, ExtUI::G26_FINISH));
g26.retract_filament(destination);
diff --git a/Marlin/src/gcode/bedlevel/G35.cpp b/Marlin/src/gcode/bedlevel/G35.cpp
index 3d75a7691537d..e45e18b7fbc2b 100644
--- a/Marlin/src/gcode/bedlevel/G35.cpp
+++ b/Marlin/src/gcode/bedlevel/G35.cpp
@@ -92,7 +92,7 @@ void GcodeSuite::G35() {
TERN_(HAS_DUPLICATION_MODE, set_duplication_enabled(false));
// Home only Z axis when X and Y is trusted, otherwise all axes, if needed before this procedure
- if (!all_axes_trusted()) process_subcommands_now_P(PSTR("G28Z"));
+ if (!all_axes_trusted()) process_subcommands_now(F("G28Z"));
bool err_break = false;
@@ -103,22 +103,22 @@ void GcodeSuite::G35() {
// Users of G35 might have a badly misaligned bed, so raise Z by the
// length of the deployed pin (BLTOUCH stroke < 7mm)
do_blocking_move_to_z(SUM_TERN(BLTOUCH_HS_MODE, Z_CLEARANCE_BETWEEN_PROBES, 7));
- const float z_probed_height = probe.probe_at_point(screws_tilt_adjust_pos[i], PROBE_PT_RAISE, 0, true);
+ const float z_probed_height = probe.probe_at_point(tramming_points[i], PROBE_PT_RAISE, 0, true);
if (isnan(z_probed_height)) {
- SERIAL_ECHOPAIR("G35 failed at point ", i + 1, " (");
+ SERIAL_ECHOPGM("G35 failed at point ", i + 1, " (");
SERIAL_ECHOPGM_P((char *)pgm_read_ptr(&tramming_point_name[i]));
SERIAL_CHAR(')');
- SERIAL_ECHOLNPAIR_P(SP_X_STR, screws_tilt_adjust_pos[i].x, SP_Y_STR, screws_tilt_adjust_pos[i].y);
+ SERIAL_ECHOLNPGM_P(SP_X_STR, tramming_points[i].x, SP_Y_STR, tramming_points[i].y);
err_break = true;
break;
}
if (DEBUGGING(LEVELING)) {
- DEBUG_ECHOPAIR("Probing point ", i + 1, " (");
- DEBUG_ECHOPGM_P((char *)pgm_read_ptr(&tramming_point_name[i]));
+ DEBUG_ECHOPGM("Probing point ", i + 1, " (");
+ DEBUG_ECHOF(FPSTR(pgm_read_ptr(&tramming_point_name[i])));
DEBUG_CHAR(')');
- DEBUG_ECHOLNPAIR_P(SP_X_STR, screws_tilt_adjust_pos[i].x, SP_Y_STR, screws_tilt_adjust_pos[i].y, SP_Z_STR, z_probed_height);
+ DEBUG_ECHOLNPGM_P(SP_X_STR, tramming_points[i].x, SP_Y_STR, tramming_points[i].y, SP_Z_STR, z_probed_height);
}
z_measured[i] = z_probed_height;
@@ -138,9 +138,9 @@ void GcodeSuite::G35() {
SERIAL_ECHOPGM("Turn ");
SERIAL_ECHOPGM_P((char *)pgm_read_ptr(&tramming_point_name[i]));
- SERIAL_ECHOPAIR(" ", (screw_thread & 1) == (adjust > 0) ? "CCW" : "CW", " by ", ABS(full_turns), " turns");
- if (minutes) SERIAL_ECHOPAIR(" and ", ABS(minutes), " minutes");
- if (ENABLED(REPORT_TRAMMING_MM)) SERIAL_ECHOPAIR(" (", -diff, "mm)");
+ SERIAL_ECHOPGM(" ", (screw_thread & 1) == (adjust > 0) ? "CCW" : "CW", " by ", ABS(full_turns), " turns");
+ if (minutes) SERIAL_ECHOPGM(" and ", ABS(minutes), " minutes");
+ if (ENABLED(REPORT_TRAMMING_MM)) SERIAL_ECHOPGM(" (", -diff, "mm)");
SERIAL_EOL();
}
}
diff --git a/Marlin/src/gcode/bedlevel/M420.cpp b/Marlin/src/gcode/bedlevel/M420.cpp
index 703e73b5a4ce6..3c23e85a1dfbc 100644
--- a/Marlin/src/gcode/bedlevel/M420.cpp
+++ b/Marlin/src/gcode/bedlevel/M420.cpp
@@ -76,9 +76,9 @@ void GcodeSuite::M420() {
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, Z_VALUES(x, y)));
}
SERIAL_ECHOPGM("Simulated " STRINGIFY(GRID_MAX_POINTS_X) "x" STRINGIFY(GRID_MAX_POINTS_Y) " mesh ");
- SERIAL_ECHOPAIR(" (", x_min);
+ SERIAL_ECHOPGM(" (", x_min);
SERIAL_CHAR(','); SERIAL_ECHO(y_min);
- SERIAL_ECHOPAIR(")-(", x_max);
+ SERIAL_ECHOPGM(")-(", x_max);
SERIAL_CHAR(','); SERIAL_ECHO(y_max);
SERIAL_ECHOLNPGM(")");
}
@@ -108,7 +108,7 @@ void GcodeSuite::M420() {
if (!WITHIN(storage_slot, 0, a - 1)) {
SERIAL_ECHOLNPGM("?Invalid storage slot.");
- SERIAL_ECHOLNPAIR("?Use 0 to ", a - 1);
+ SERIAL_ECHOLNPGM("?Use 0 to ", a - 1);
return;
}
@@ -128,7 +128,7 @@ void GcodeSuite::M420() {
ubl.display_map(parser.byteval('T'));
SERIAL_ECHOPGM("Mesh is ");
if (!ubl.mesh_is_valid()) SERIAL_ECHOPGM("in");
- SERIAL_ECHOLNPAIR("valid\nStorage slot: ", ubl.storage_slot);
+ SERIAL_ECHOLNPGM("valid\nStorage slot: ", ubl.storage_slot);
}
#endif // AUTO_BED_LEVELING_UBL
@@ -195,7 +195,7 @@ void GcodeSuite::M420() {
// V to print the matrix or mesh
if (seenV) {
#if ABL_PLANAR
- planner.bed_level_matrix.debug(PSTR("Bed Level Correction Matrix:"));
+ planner.bed_level_matrix.debug(F("Bed Level Correction Matrix:"));
#else
if (leveling_is_valid()) {
#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
@@ -242,4 +242,18 @@ void GcodeSuite::M420() {
report_current_position();
}
+void GcodeSuite::M420_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(
+ TERN(MESH_BED_LEVELING, "Mesh Bed Leveling", TERN(AUTO_BED_LEVELING_UBL, "Unified Bed Leveling", "Auto Bed Leveling"))
+ ));
+ SERIAL_ECHOF(
+ F(" M420 S"), planner.leveling_active
+ #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
+ , FPSTR(SP_Z_STR), LINEAR_UNIT(planner.z_fade_height)
+ #endif
+ , F(" ; Leveling ")
+ );
+ serialprintln_onoff(planner.leveling_active);
+}
+
#endif // HAS_LEVELING
diff --git a/Marlin/src/gcode/bedlevel/abl/G29.cpp b/Marlin/src/gcode/bedlevel/abl/G29.cpp
index c3c8d3c92bf1b..14da38c8fe2bb 100644
--- a/Marlin/src/gcode/bedlevel/abl/G29.cpp
+++ b/Marlin/src/gcode/bedlevel/abl/G29.cpp
@@ -36,7 +36,7 @@
#include "../../../module/probe.h"
#include "../../queue.h"
-#if ENABLED(PROBE_TEMP_COMPENSATION)
+#if HAS_PTC
#include "../../../feature/probe_temp_comp.h"
#include "../../../module/temperature.h"
#endif
@@ -58,10 +58,10 @@
#if ENABLED(EXTENSIBLE_UI)
#include "../../../lcd/extui/ui_api.h"
-#endif
-
-#if ENABLED(DWIN_CREALITY_LCD)
+#elif ENABLED(DWIN_CREALITY_LCD)
#include "../../../lcd/e3v2/creality/dwin.h"
+#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
+ #include "../../../lcd/e3v2/enhanced/dwin.h"
#endif
#if HAS_MULTI_HOTEND
@@ -244,7 +244,7 @@ G29_TYPE GcodeSuite::G29() {
// Send 'N' to force homing before G29 (internal only)
if (parser.seen_test('N'))
- process_subcommands_now_P(TERN(CAN_SET_LEVELING_AFTER_G28, PSTR("G28L0"), G28_STR));
+ process_subcommands_now(TERN(CAN_SET_LEVELING_AFTER_G28, F("G28L0"), FPSTR(G28_STR)));
// Don't allow auto-leveling without homing first
if (homing_needed_error()) G29_RETURN(false);
@@ -379,7 +379,7 @@ G29_TYPE GcodeSuite::G29() {
if (!probe.good_bounds(abl.probe_position_lf, abl.probe_position_rb)) {
if (DEBUGGING(LEVELING)) {
- DEBUG_ECHOLNPAIR("G29 L", abl.probe_position_lf.x, " R", abl.probe_position_rb.x,
+ DEBUG_ECHOLNPGM("G29 L", abl.probe_position_lf.x, " R", abl.probe_position_rb.x,
" F", abl.probe_position_lf.y, " B", abl.probe_position_rb.y);
}
SERIAL_ECHOLNPGM("? (L,R,F,B) out of bounds.");
@@ -403,10 +403,9 @@ G29_TYPE GcodeSuite::G29() {
#if ENABLED(AUTO_BED_LEVELING_3POINT)
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> 3-point Leveling");
points[0].z = points[1].z = points[2].z = 0; // Probe at 3 arbitrary points
- #endif
-
- #if BOTH(AUTO_BED_LEVELING_BILINEAR, EXTENSIBLE_UI)
- ExtUI::onMeshLevelingStart();
+ #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
+ TERN_(EXTENSIBLE_UI, ExtUI::onMeshLevelingStart());
+ TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_MeshLevelingStart());
#endif
if (!faux) {
@@ -471,7 +470,7 @@ G29_TYPE GcodeSuite::G29() {
if (abl.verbose_level || seenQ) {
SERIAL_ECHOPGM("Manual G29 ");
if (g29_in_progress)
- SERIAL_ECHOLNPAIR("point ", _MIN(abl.abl_probe_index + 1, abl.abl_points), " of ", abl.abl_points);
+ SERIAL_ECHOLNPGM("point ", _MIN(abl.abl_probe_index + 1, abl.abl_points), " of ", abl.abl_points);
else
SERIAL_ECHOLNPGM("idle");
}
@@ -514,7 +513,7 @@ G29_TYPE GcodeSuite::G29() {
z_values[abl.meshCount.x][abl.meshCount.y] = newz;
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(abl.meshCount, newz));
- if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR_P(PSTR("Save X"), abl.meshCount.x, SP_Y_STR, abl.meshCount.y, SP_Z_STR, abl.measured_z + abl.Z_offset);
+ if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM_P(PSTR("Save X"), abl.meshCount.x, SP_Y_STR, abl.meshCount.y, SP_Z_STR, abl.measured_z + abl.Z_offset);
#endif
}
@@ -636,8 +635,8 @@ G29_TYPE GcodeSuite::G29() {
// Avoid probing outside the round or hexagonal area
if (TERN0(IS_KINEMATIC, !probe.can_reach(abl.probePos))) continue;
- if (abl.verbose_level) SERIAL_ECHOLNPAIR("Probing mesh point ", pt_index, "/", abl.abl_points, ".");
- TERN_(HAS_STATUS_MESSAGE, ui.status_printf_P(0, PSTR(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_MESH), int(pt_index), int(abl.abl_points)));
+ if (abl.verbose_level) SERIAL_ECHOLNPGM("Probing mesh point ", pt_index, "/", abl.abl_points, ".");
+ TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), int(pt_index), int(abl.abl_points)));
abl.measured_z = faux ? 0.001f * random(-100, 101) : probe.probe_at_point(abl.probePos, raise_after, abl.verbose_level);
@@ -646,11 +645,9 @@ G29_TYPE GcodeSuite::G29() {
break; // Breaks out of both loops
}
- #if ENABLED(PROBE_TEMP_COMPENSATION)
- temp_comp.compensate_measurement(TSI_BED, thermalManager.degBed(), abl.measured_z);
- temp_comp.compensate_measurement(TSI_PROBE, thermalManager.degProbe(), abl.measured_z);
- TERN_(USE_TEMP_EXT_COMPENSATION, temp_comp.compensate_measurement(TSI_EXT, thermalManager.degHotend(), abl.measured_z));
- #endif
+ TERN_(PTC_BED, ptc.compensate_measurement(TSI_BED, thermalManager.degBed(), abl.measured_z));
+ TERN_(PTC_PROBE, ptc.compensate_measurement(TSI_PROBE, thermalManager.degProbe(), abl.measured_z));
+ TERN_(PTC_HOTEND, ptc.compensate_measurement(TSI_EXT, thermalManager.degHotend(0), abl.measured_z));
#if ENABLED(AUTO_BED_LEVELING_LINEAR)
@@ -681,8 +678,8 @@ G29_TYPE GcodeSuite::G29() {
// Probe at 3 arbitrary points
LOOP_L_N(i, 3) {
- if (abl.verbose_level) SERIAL_ECHOLNPAIR("Probing point ", i + 1, "/3.");
- TERN_(HAS_STATUS_MESSAGE, ui.status_printf_P(0, PSTR(S_FMT " %i/3"), GET_TEXT(MSG_PROBING_MESH), int(i + 1)));
+ if (abl.verbose_level) SERIAL_ECHOLNPGM("Probing point ", i + 1, "/3.");
+ TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), GET_TEXT(MSG_PROBING_POINT), int(i + 1)));
// Retain the last probe position
abl.probePos = xy_pos_t(points[i]);
@@ -784,8 +781,8 @@ G29_TYPE GcodeSuite::G29() {
float min_diff = 999;
- auto print_topo_map = [&](PGM_P const title, const bool get_min) {
- SERIAL_ECHOPGM_P(title);
+ auto print_topo_map = [&](FSTR_P const title, const bool get_min) {
+ SERIAL_ECHOF(title);
for (int8_t yy = abl.grid_points.y - 1; yy >= 0; yy--) {
LOOP_L_N(xx, abl.grid_points.x) {
const int ind = abl.indexIntoAB[xx][yy];
@@ -803,19 +800,19 @@ G29_TYPE GcodeSuite::G29() {
SERIAL_EOL();
};
- print_topo_map(PSTR("\nBed Height Topography:\n"
- " +--- BACK --+\n"
- " | |\n"
- " L | (+) | R\n"
- " E | | I\n"
- " F | (-) N (+) | G\n"
- " T | | H\n"
- " | (-) | T\n"
- " | |\n"
- " O-- FRONT --+\n"
- " (0,0)\n"), true);
+ print_topo_map(F("\nBed Height Topography:\n"
+ " +--- BACK --+\n"
+ " | |\n"
+ " L | (+) | R\n"
+ " E | | I\n"
+ " F | (-) N (+) | G\n"
+ " T | | H\n"
+ " | (-) | T\n"
+ " | |\n"
+ " O-- FRONT --+\n"
+ " (0,0)\n"), true);
if (abl.verbose_level > 3)
- print_topo_map(PSTR("\nCorrected Bed Height vs. Bed Topology:\n"), false);
+ print_topo_map(F("\nCorrected Bed Height vs. Bed Topology:\n"), false);
} // abl.topography_map
@@ -826,7 +823,7 @@ G29_TYPE GcodeSuite::G29() {
// For LINEAR and 3POINT leveling correct the current position
if (abl.verbose_level > 0)
- planner.bed_level_matrix.debug(PSTR("\n\nBed Level Correction Matrix:"));
+ planner.bed_level_matrix.debug(F("\n\nBed Level Correction Matrix:"));
if (!abl.dryrun) {
//
@@ -843,7 +840,7 @@ G29_TYPE GcodeSuite::G29() {
&& NEAR(current_position.y, abl.probePos.y - probe.offset_xy.y)
) {
const float simple_z = current_position.z - abl.measured_z;
- if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Probed Z", simple_z, " Matrix Z", converted.z, " Discrepancy ", simple_z - converted.z);
+ if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Probed Z", simple_z, " Matrix Z", converted.z, " Discrepancy ", simple_z - converted.z);
converted.z = simple_z;
}
@@ -856,14 +853,14 @@ G29_TYPE GcodeSuite::G29() {
#elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
if (!abl.dryrun) {
- if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("G29 uncorrected Z:", current_position.z);
+ if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("G29 uncorrected Z:", current_position.z);
// Unapply the offset because it is going to be immediately applied
// and cause compensation movement in Z
const float fade_scaling_factor = TERN(ENABLE_LEVELING_FADE_HEIGHT, planner.fade_scaling_factor_for_z(current_position.z), 1);
current_position.z -= fade_scaling_factor * bilinear_z_offset(current_position);
- if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR(" corrected Z:", current_position.z);
+ if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM(" corrected Z:", current_position.z);
}
#endif // ABL_PLANAR
@@ -881,14 +878,12 @@ G29_TYPE GcodeSuite::G29() {
TERN_(HAS_BED_PROBE, probe.move_z_after_probing());
#ifdef Z_PROBE_END_SCRIPT
- if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Z Probe End Script: ", Z_PROBE_END_SCRIPT);
+ if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Z Probe End Script: ", Z_PROBE_END_SCRIPT);
planner.synchronize();
- process_subcommands_now_P(PSTR(Z_PROBE_END_SCRIPT));
+ process_subcommands_now(F(Z_PROBE_END_SCRIPT));
#endif
- #if ENABLED(DWIN_CREALITY_LCD)
- DWIN_CompletedLeveling();
- #endif
+ TERN_(HAS_DWIN_E3V2_BASIC, DWIN_CompletedLeveling());
report_current_position();
diff --git a/Marlin/src/gcode/bedlevel/mbl/G29.cpp b/Marlin/src/gcode/bedlevel/mbl/G29.cpp
index 984e008d2782d..eec89f73acffe 100644
--- a/Marlin/src/gcode/bedlevel/mbl/G29.cpp
+++ b/Marlin/src/gcode/bedlevel/mbl/G29.cpp
@@ -40,6 +40,8 @@
#if ENABLED(EXTENSIBLE_UI)
#include "../../../lcd/extui/ui_api.h"
+#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
+ #include "../../../lcd/e3v2/enhanced/dwin.h"
#endif
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
@@ -101,7 +103,7 @@ void GcodeSuite::G29() {
mbl.reset();
mbl_probe_index = 0;
if (!ui.wait_for_move) {
- queue.inject_P(parser.seen_test('N') ? PSTR("G28" TERN(CAN_SET_LEVELING_AFTER_G28, "L0", "") "\nG29S2") : PSTR("G29S2"));
+ queue.inject(parser.seen_test('N') ? F("G28" TERN(CAN_SET_LEVELING_AFTER_G28, "L0", "") "\nG29S2") : F("G29S2"));
TERN_(EXTENSIBLE_UI, ExtUI::onMeshLevelingStart());
return;
}
@@ -150,7 +152,7 @@ void GcodeSuite::G29() {
// After recording the last point, activate home and activate
mbl_probe_index = -1;
SERIAL_ECHOLNPGM("Mesh probing done.");
- TERN_(HAS_STATUS_MESSAGE, ui.set_status(GET_TEXT(MSG_MESH_DONE)));
+ TERN_(HAS_STATUS_MESSAGE, LCD_MESSAGE(MSG_MESH_DONE));
BUZZ(100, 659);
BUZZ(100, 698);
@@ -171,7 +173,7 @@ void GcodeSuite::G29() {
if (parser.seenval('I')) {
ix = parser.value_int();
if (!WITHIN(ix, 0, (GRID_MAX_POINTS_X) - 1)) {
- SERIAL_ECHOLNPAIR("I out of range (0-", (GRID_MAX_POINTS_X) - 1, ")");
+ SERIAL_ECHOLNPGM("I out of range (0-", (GRID_MAX_POINTS_X) - 1, ")");
return;
}
}
@@ -181,7 +183,7 @@ void GcodeSuite::G29() {
if (parser.seenval('J')) {
iy = parser.value_int();
if (!WITHIN(iy, 0, (GRID_MAX_POINTS_Y) - 1)) {
- SERIAL_ECHOLNPAIR("J out of range (0-", (GRID_MAX_POINTS_Y) - 1, ")");
+ SERIAL_ECHOLNPGM("J out of range (0-", (GRID_MAX_POINTS_Y) - 1, ")");
return;
}
}
@@ -191,6 +193,7 @@ void GcodeSuite::G29() {
if (parser.seenval('Z')) {
mbl.z_values[ix][iy] = parser.value_linear_units();
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(ix, iy, mbl.z_values[ix][iy]));
+ TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_MeshUpdate(ix, iy, mbl.z_values[ix][iy]));
}
else
return echo_not_entered('Z');
@@ -210,8 +213,8 @@ void GcodeSuite::G29() {
} // switch(state)
if (state == MeshNext) {
- SERIAL_ECHOLNPAIR("MBL G29 point ", _MIN(mbl_probe_index, GRID_MAX_POINTS), " of ", GRID_MAX_POINTS);
- if (mbl_probe_index > 0) TERN_(HAS_STATUS_MESSAGE, ui.status_printf_P(0, PSTR(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_MESH), _MIN(mbl_probe_index, GRID_MAX_POINTS), int(GRID_MAX_POINTS)));
+ SERIAL_ECHOLNPGM("MBL G29 point ", _MIN(mbl_probe_index, GRID_MAX_POINTS), " of ", GRID_MAX_POINTS);
+ if (mbl_probe_index > 0) TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), _MIN(mbl_probe_index, GRID_MAX_POINTS), int(GRID_MAX_POINTS)));
}
report_current_position();
diff --git a/Marlin/src/gcode/bedlevel/ubl/M421.cpp b/Marlin/src/gcode/bedlevel/ubl/M421.cpp
index f1e1b76126ed9..e6f0ef1f8907c 100644
--- a/Marlin/src/gcode/bedlevel/ubl/M421.cpp
+++ b/Marlin/src/gcode/bedlevel/ubl/M421.cpp
@@ -33,6 +33,8 @@
#if ENABLED(EXTENSIBLE_UI)
#include "../../../lcd/extui/ui_api.h"
+#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
+ #include "../../../lcd/e3v2/enhanced/dwin.h"
#endif
/**
@@ -67,6 +69,7 @@ void GcodeSuite::M421() {
float &zval = ubl.z_values[ij.x][ij.y]; // Altering this Mesh Point
zval = hasN ? NAN : parser.value_linear_units() + (hasQ ? zval : 0); // N=NAN, Z=NEWVAL, or Q=ADDVAL
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(ij.x, ij.y, zval)); // Ping ExtUI in case it's showing the mesh
+ TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_MeshUpdate(ij.x, ij.y, zval));
}
}
diff --git a/Marlin/src/gcode/calibrate/G28.cpp b/Marlin/src/gcode/calibrate/G28.cpp
index 89ad20d906c7b..95f2a9b17614f 100644
--- a/Marlin/src/gcode/calibrate/G28.cpp
+++ b/Marlin/src/gcode/calibrate/G28.cpp
@@ -46,12 +46,13 @@
#endif
#include "../../lcd/marlinui.h"
-#if ENABLED(DWIN_CREALITY_LCD)
- #include "../../lcd/e3v2/creality/dwin.h"
-#endif
#if ENABLED(EXTENSIBLE_UI)
#include "../../lcd/extui/ui_api.h"
+#elif ENABLED(DWIN_CREALITY_LCD)
+ #include "../../lcd/e3v2/creality/dwin.h"
+#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
+ #include "../../lcd/e3v2/enhanced/dwin.h"
#endif
#if HAS_L64XX // set L6470 absolute position registers to counts
@@ -155,7 +156,7 @@
homeaxis(Z_AXIS);
}
else {
- LCD_MESSAGEPGM(MSG_ZPROBE_OUT);
+ LCD_MESSAGE(MSG_ZPROBE_OUT);
SERIAL_ECHO_MSG(STR_ZPROBE_OUT_SER);
}
}
@@ -238,7 +239,7 @@ void GcodeSuite::G28() {
return;
}
- TERN_(DWIN_CREALITY_LCD, DWIN_StartHoming());
+ TERN_(HAS_DWIN_E3V2_BASIC, DWIN_StartHoming());
TERN_(EXTENSIBLE_UI, ExtUI::onHomingStart());
planner.synchronize(); // Wait for planner moves to finish!
@@ -268,33 +269,33 @@ void GcodeSuite::G28() {
#endif
#if HAS_HOMING_CURRENT
- auto debug_current = [](PGM_P const s, const int16_t a, const int16_t b) {
- DEBUG_ECHOPGM_P(s); DEBUG_ECHOLNPAIR(" current: ", a, " -> ", b);
+ auto debug_current = [](FSTR_P const s, const int16_t a, const int16_t b) {
+ DEBUG_ECHOF(s); DEBUG_ECHOLNPGM(" current: ", a, " -> ", b);
};
#if HAS_CURRENT_HOME(X)
const int16_t tmc_save_current_X = stepperX.getMilliamps();
stepperX.rms_current(X_CURRENT_HOME);
- if (DEBUGGING(LEVELING)) debug_current(PSTR("X"), tmc_save_current_X, X_CURRENT_HOME);
+ if (DEBUGGING(LEVELING)) debug_current(F("X"), tmc_save_current_X, X_CURRENT_HOME);
#endif
#if HAS_CURRENT_HOME(X2)
const int16_t tmc_save_current_X2 = stepperX2.getMilliamps();
stepperX2.rms_current(X2_CURRENT_HOME);
- if (DEBUGGING(LEVELING)) debug_current(PSTR("X2"), tmc_save_current_X2, X2_CURRENT_HOME);
+ if (DEBUGGING(LEVELING)) debug_current(F("X2"), tmc_save_current_X2, X2_CURRENT_HOME);
#endif
#if HAS_CURRENT_HOME(Y)
const int16_t tmc_save_current_Y = stepperY.getMilliamps();
stepperY.rms_current(Y_CURRENT_HOME);
- if (DEBUGGING(LEVELING)) debug_current(PSTR("Y"), tmc_save_current_Y, Y_CURRENT_HOME);
+ if (DEBUGGING(LEVELING)) debug_current(F("Y"), tmc_save_current_Y, Y_CURRENT_HOME);
#endif
#if HAS_CURRENT_HOME(Y2)
const int16_t tmc_save_current_Y2 = stepperY2.getMilliamps();
stepperY2.rms_current(Y2_CURRENT_HOME);
- if (DEBUGGING(LEVELING)) debug_current(PSTR("Y2"), tmc_save_current_Y2, Y2_CURRENT_HOME);
+ if (DEBUGGING(LEVELING)) debug_current(F("Y2"), tmc_save_current_Y2, Y2_CURRENT_HOME);
#endif
#if HAS_CURRENT_HOME(Z) && ENABLED(DELTA)
const int16_t tmc_save_current_Z = stepperZ.getMilliamps();
stepperZ.rms_current(Z_CURRENT_HOME);
- if (DEBUGGING(LEVELING)) debug_current(PSTR("Z"), tmc_save_current_Z, Z_CURRENT_HOME);
+ if (DEBUGGING(LEVELING)) debug_current(F("Z"), tmc_save_current_Z, Z_CURRENT_HOME);
#endif
#endif
@@ -370,7 +371,7 @@ void GcodeSuite::G28() {
if (z_homing_height && (LINEAR_AXIS_GANG(doX, || doY, || TERN0(Z_SAFE_HOMING, doZ), || doI, || doJ, || doK))) {
// Raise Z before homing any other axes and z is not already high enough (never lower z)
- if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Raise Z (before homing) by ", z_homing_height);
+ if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Raise Z (before homing) by ", z_homing_height);
do_z_clearance(z_homing_height);
TERN_(BLTOUCH, bltouch.init());
}
@@ -522,7 +523,7 @@ void GcodeSuite::G28() {
ui.refresh();
- TERN_(DWIN_CREALITY_LCD, DWIN_CompletedHoming());
+ TERN_(HAS_DWIN_E3V2_BASIC, DWIN_CompletedHoming());
TERN_(EXTENSIBLE_UI, ExtUI::onHomingComplete());
report_current_position();
diff --git a/Marlin/src/gcode/calibrate/G33.cpp b/Marlin/src/gcode/calibrate/G33.cpp
index a897a101157c6..779ae99d0adf3 100644
--- a/Marlin/src/gcode/calibrate/G33.cpp
+++ b/Marlin/src/gcode/calibrate/G33.cpp
@@ -69,11 +69,13 @@ enum CalEnum : char { // the 7 main calibration points -
float lcd_probe_pt(const xy_pos_t &xy);
+float dcr;
+
void ac_home() {
endstops.enable(true);
- TERN_(SENSORLESS_HOMING, probe.set_homing_current(true));
+ TERN_(HAS_DELTA_SENSORLESS_PROBING, probe.set_homing_current(true));
home_delta();
- TERN_(SENSORLESS_HOMING, probe.set_homing_current(false));
+ TERN_(HAS_DELTA_SENSORLESS_PROBING, probe.set_homing_current(false));
endstops.not_homing();
}
@@ -95,10 +97,9 @@ void ac_cleanup(TERN_(HAS_MULTI_HOTEND, const uint8_t old_tool_index)) {
TERN_(HAS_MULTI_HOTEND, tool_change(old_tool_index, true));
}
-void print_signed_float(PGM_P const prefix, const_float_t f) {
+void print_signed_float(FSTR_P const prefix, const_float_t f) {
SERIAL_ECHOPGM(" ");
- SERIAL_ECHOPGM_P(prefix);
- SERIAL_CHAR(':');
+ SERIAL_ECHOF(prefix, AS_CHAR(':'));
if (f >= 0) SERIAL_CHAR('+');
SERIAL_ECHO_F(f, 2);
}
@@ -107,26 +108,25 @@ void print_signed_float(PGM_P const prefix, const_float_t f) {
* - Print the delta settings
*/
static void print_calibration_settings(const bool end_stops, const bool tower_angles) {
- SERIAL_ECHOPAIR(".Height:", delta_height);
+ SERIAL_ECHOPGM(".Height:", delta_height);
if (end_stops) {
- print_signed_float(PSTR("Ex"), delta_endstop_adj.a);
- print_signed_float(PSTR("Ey"), delta_endstop_adj.b);
- print_signed_float(PSTR("Ez"), delta_endstop_adj.c);
+ print_signed_float(F("Ex"), delta_endstop_adj.a);
+ print_signed_float(F("Ey"), delta_endstop_adj.b);
+ print_signed_float(F("Ez"), delta_endstop_adj.c);
}
if (end_stops && tower_angles) {
- SERIAL_ECHOPAIR(" Radius:", delta_radius);
- SERIAL_EOL();
+ SERIAL_ECHOLNPGM(" Radius:", delta_radius);
SERIAL_CHAR('.');
SERIAL_ECHO_SP(13);
}
if (tower_angles) {
- print_signed_float(PSTR("Tx"), delta_tower_angle_trim.a);
- print_signed_float(PSTR("Ty"), delta_tower_angle_trim.b);
- print_signed_float(PSTR("Tz"), delta_tower_angle_trim.c);
- }
- if ((!end_stops && tower_angles) || (end_stops && !tower_angles)) { // XOR
- SERIAL_ECHOPAIR(" Radius:", delta_radius);
+ print_signed_float(F("Tx"), delta_tower_angle_trim.a);
+ print_signed_float(F("Ty"), delta_tower_angle_trim.b);
+ print_signed_float(F("Tz"), delta_tower_angle_trim.c);
}
+ if (end_stops != tower_angles)
+ SERIAL_ECHOPGM(" Radius:", delta_radius);
+
SERIAL_EOL();
}
@@ -135,11 +135,11 @@ static void print_calibration_settings(const bool end_stops, const bool tower_an
*/
static void print_calibration_results(const float z_pt[NPP + 1], const bool tower_points, const bool opposite_points) {
SERIAL_ECHOPGM(". ");
- print_signed_float(PSTR("c"), z_pt[CEN]);
+ print_signed_float(F("c"), z_pt[CEN]);
if (tower_points) {
- print_signed_float(PSTR(" x"), z_pt[__A]);
- print_signed_float(PSTR(" y"), z_pt[__B]);
- print_signed_float(PSTR(" z"), z_pt[__C]);
+ print_signed_float(F(" x"), z_pt[__A]);
+ print_signed_float(F(" y"), z_pt[__B]);
+ print_signed_float(F(" z"), z_pt[__C]);
}
if (tower_points && opposite_points) {
SERIAL_EOL();
@@ -147,9 +147,9 @@ static void print_calibration_results(const float z_pt[NPP + 1], const bool towe
SERIAL_ECHO_SP(13);
}
if (opposite_points) {
- print_signed_float(PSTR("yz"), z_pt[_BC]);
- print_signed_float(PSTR("zx"), z_pt[_CA]);
- print_signed_float(PSTR("xy"), z_pt[_AB]);
+ print_signed_float(F("yz"), z_pt[_BC]);
+ print_signed_float(F("zx"), z_pt[_CA]);
+ print_signed_float(F("xy"), z_pt[_AB]);
}
SERIAL_EOL();
}
@@ -175,9 +175,9 @@ static float std_dev_points(float z_pt[NPP + 1], const bool _0p_cal, const bool
/**
* - Probe a point
*/
-static float calibration_probe(const xy_pos_t &xy, const bool stow) {
+static float calibration_probe(const xy_pos_t &xy, const bool stow, const bool probe_at_offset) {
#if HAS_BED_PROBE
- return probe.probe_at_point(xy, stow ? PROBE_PT_STOW : PROBE_PT_RAISE, 0, true, false);
+ return probe.probe_at_point(xy, stow ? PROBE_PT_STOW : PROBE_PT_RAISE, 0, true, probe_at_offset);
#else
UNUSED(stow);
return lcd_probe_pt(xy);
@@ -187,7 +187,7 @@ static float calibration_probe(const xy_pos_t &xy, const bool stow) {
/**
* - Probe a grid
*/
-static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_points, const bool towers_set, const bool stow_after_each) {
+static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_points, const bool towers_set, const bool stow_after_each, const bool probe_at_offset) {
const bool _0p_calibration = probe_points == 0,
_1p_calibration = probe_points == 1 || probe_points == -1,
_4p_calibration = probe_points == 2,
@@ -209,11 +209,9 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
if (!_0p_calibration) {
- const float dcr = delta_calibration_radius();
-
if (!_7p_no_intermediates && !_7p_4_intermediates && !_7p_11_intermediates) { // probe the center
const xy_pos_t center{0};
- z_pt[CEN] += calibration_probe(center, stow_after_each);
+ z_pt[CEN] += calibration_probe(center, stow_after_each, probe_at_offset);
if (isnan(z_pt[CEN])) return false;
}
@@ -224,7 +222,7 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
const float a = RADIANS(210 + (360 / NPP) * (rad - 1)),
r = dcr * 0.1;
const xy_pos_t vec = { cos(a), sin(a) };
- z_pt[CEN] += calibration_probe(vec * r, stow_after_each);
+ z_pt[CEN] += calibration_probe(vec * r, stow_after_each, probe_at_offset);
if (isnan(z_pt[CEN])) return false;
}
z_pt[CEN] /= float(_7p_2_intermediates ? 7 : probe_points);
@@ -249,7 +247,7 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
r = dcr * (1 - 0.1 * (zig_zag ? offset - circle : circle)),
interpol = FMOD(rad, 1);
const xy_pos_t vec = { cos(a), sin(a) };
- const float z_temp = calibration_probe(vec * r, stow_after_each);
+ const float z_temp = calibration_probe(vec * r, stow_after_each, probe_at_offset);
if (isnan(z_temp)) return false;
// split probe point to neighbouring calibration points
z_pt[uint8_t(LROUND(rad - interpol + NPP - 1)) % NPP + 1] += z_temp * sq(cos(RADIANS(interpol * 90)));
@@ -276,7 +274,6 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
static void reverse_kinematics_probe_points(float z_pt[NPP + 1], abc_float_t mm_at_pt_axis[NPP + 1]) {
xyz_pos_t pos{0};
- const float dcr = delta_calibration_radius();
LOOP_CAL_ALL(rad) {
const float a = RADIANS(210 + (360 / NPP) * (rad - 1)),
r = (rad == CEN ? 0.0f : dcr);
@@ -287,7 +284,7 @@ static void reverse_kinematics_probe_points(float z_pt[NPP + 1], abc_float_t mm_
}
static void forward_kinematics_probe_points(abc_float_t mm_at_pt_axis[NPP + 1], float z_pt[NPP + 1]) {
- const float r_quot = delta_calibration_radius() / delta_radius;
+ const float r_quot = dcr / delta_radius;
#define ZPP(N,I,A) (((1.0f + r_quot * (N)) / 3.0f) * mm_at_pt_axis[I].A)
#define Z00(I, A) ZPP( 0, I, A)
@@ -328,7 +325,7 @@ static void calc_kinematics_diff_probe_points(float z_pt[NPP + 1], abc_float_t d
}
static float auto_tune_h() {
- const float r_quot = delta_calibration_radius() / delta_radius;
+ const float r_quot = dcr / delta_radius;
return RECIPROCAL(r_quot / (2.0f / 3.0f)); // (2/3)/CR
}
@@ -373,6 +370,8 @@ static float auto_tune_a() {
* P3 Probe all positions: center, towers and opposite towers. Calibrate all.
* P4-P10 Probe all positions at different intermediate locations and average them.
*
+ * Rn.nn override default calibration Radius
+ *
* T Don't calibrate tower angle corrections
*
* Cn.nn Calibration precision; when omitted calibrates to maximum precision
@@ -387,6 +386,8 @@ static float auto_tune_a() {
*
* E Engage the probe for each point
*
+ * O Probe at offset points (this is wrong but it seems to work)
+ *
* With SENSORLESS_PROBING:
* Use these flags to calibrate stall sensitivity: (e.g., `G33 P1 Y Z` to calibrate X only.)
* X Don't activate stallguard on X.
@@ -403,7 +404,27 @@ void GcodeSuite::G33() {
return;
}
- const bool towers_set = !parser.seen_test('T');
+ const bool probe_at_offset = TERN0(HAS_PROBE_XY_OFFSET, parser.boolval('O')),
+ towers_set = !parser.seen_test('T');
+
+ float max_dcr = dcr = DELTA_PRINTABLE_RADIUS;
+ #if HAS_PROBE_XY_OFFSET
+ // For offset probes the calibration radius is set to a safe but non-optimal value
+ dcr -= HYPOT(probe.offset_xy.x, probe.offset_xy.y);
+ if (probe_at_offset) {
+ // With probe positions both probe and nozzle need to be within the printable area
+ max_dcr = dcr;
+ }
+ // else with nozzle positions there is a risk of the probe being outside the bed
+ // but as long the nozzle stays within the printable area there is no risk of
+ // the effector crashing into the towers.
+ #endif
+
+ if (parser.seenval('R')) dcr = parser.value_float();
+ if (!WITHIN(dcr, 0, max_dcr)) {
+ SERIAL_ECHOLNPGM("?calibration (R)adius implausible.");
+ return;
+ }
const float calibration_precision = parser.floatval('C', 0.0f);
if (calibration_precision < 0) {
@@ -425,7 +446,7 @@ void GcodeSuite::G33() {
const bool stow_after_each = parser.seen_test('E');
- #if ENABLED(SENSORLESS_PROBING)
+ #if HAS_DELTA_SENSORLESS_PROBING
probe.test_sensitivity.x = !parser.seen_test('X');
TERN_(HAS_Y_AXIS, probe.test_sensitivity.y = !parser.seen_test('Y'));
TERN_(HAS_Z_AXIS, probe.test_sensitivity.z = !parser.seen_test('Z'));
@@ -453,24 +474,12 @@ void GcodeSuite::G33() {
SERIAL_ECHOLNPGM("G33 Auto Calibrate");
- const float dcr = delta_calibration_radius();
-
- if (!_1p_calibration && !_0p_calibration) { // test if the outer radius is reachable
- LOOP_CAL_RAD(axis) {
- const float a = RADIANS(210 + (360 / NPP) * (axis - 1));
- if (!position_is_reachable(cos(a) * dcr, sin(a) * dcr)) {
- SERIAL_ECHOLNPGM("?Bed calibration radius implausible.");
- return;
- }
- }
- }
-
// Report settings
- PGM_P const checkingac = PSTR("Checking... AC");
- SERIAL_ECHOPGM_P(checkingac);
+ FSTR_P const checkingac = F("Checking... AC");
+ SERIAL_ECHOF(checkingac);
if (verbose_level == 0) SERIAL_ECHOPGM(" (DRY-RUN)");
SERIAL_EOL();
- ui.set_status_P(checkingac);
+ ui.set_status(checkingac);
print_calibration_settings(_endstop_results, _angle_results);
@@ -487,7 +496,7 @@ void GcodeSuite::G33() {
// Probe the points
zero_std_dev_old = zero_std_dev;
- if (!probe_calibration_points(z_at_pt, probe_points, towers_set, stow_after_each)) {
+ if (!probe_calibration_points(z_at_pt, probe_points, towers_set, stow_after_each, probe_at_offset)) {
SERIAL_ECHOLNPGM("Correct delta settings with M665 and M666");
return ac_cleanup(TERN_(HAS_MULTI_HOTEND, old_tool_index));
}
@@ -526,11 +535,11 @@ void GcodeSuite::G33() {
#define Z0(I) ZP(0, I)
// calculate factors
- if (_7p_9_center) calibration_radius_factor = 0.9f;
+ if (_7p_9_center) dcr *= 0.9f;
h_factor = auto_tune_h();
r_factor = auto_tune_r();
a_factor = auto_tune_a();
- calibration_radius_factor = 1.0f;
+ dcr /= 0.9f;
switch (probe_points) {
case 0:
@@ -642,13 +651,13 @@ void GcodeSuite::G33() {
}
}
else { // dry run
- PGM_P const enddryrun = PSTR("End DRY-RUN");
- SERIAL_ECHOPGM_P(enddryrun);
+ FSTR_P const enddryrun = F("End DRY-RUN");
+ SERIAL_ECHOF(enddryrun);
SERIAL_ECHO_SP(35);
SERIAL_ECHOLNPAIR_F("std dev:", zero_std_dev, 3);
char mess[21];
- strcpy_P(mess, enddryrun);
+ strcpy_P(mess, FTOP(enddryrun));
strcpy_P(&mess[11], PSTR(" sd:"));
if (zero_std_dev < 1)
sprintf_P(&mess[15], PSTR("0.%03i"), (int)LROUND(zero_std_dev * 1000.0f));
diff --git a/Marlin/src/gcode/calibrate/G34.cpp b/Marlin/src/gcode/calibrate/G34.cpp
index f335a123114a5..98a0bdef88988 100644
--- a/Marlin/src/gcode/calibrate/G34.cpp
+++ b/Marlin/src/gcode/calibrate/G34.cpp
@@ -47,7 +47,7 @@ void GcodeSuite::G34() {
TemporaryGlobalEndstopsState unlock_z(false);
#ifdef GANTRY_CALIBRATION_COMMANDS_PRE
- gcode.process_subcommands_now_P(PSTR(GANTRY_CALIBRATION_COMMANDS_PRE));
+ process_subcommands_now(F(GANTRY_CALIBRATION_COMMANDS_PRE));
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Sub Commands Processed");
#endif
@@ -148,7 +148,7 @@ void GcodeSuite::G34() {
#ifdef GANTRY_CALIBRATION_COMMANDS_POST
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Running Post Commands");
- gcode.process_subcommands_now_P(PSTR(GANTRY_CALIBRATION_COMMANDS_POST));
+ process_subcommands_now(F(GANTRY_CALIBRATION_COMMANDS_POST));
#endif
SET_SOFT_ENDSTOP_LOOSE(false);
diff --git a/Marlin/src/gcode/calibrate/G34_M422.cpp b/Marlin/src/gcode/calibrate/G34_M422.cpp
index 50f3419c89600..8f4eab2c9715b 100644
--- a/Marlin/src/gcode/calibrate/G34_M422.cpp
+++ b/Marlin/src/gcode/calibrate/G34_M422.cpp
@@ -31,7 +31,7 @@
#include "../../module/stepper.h"
#include "../../module/planner.h"
#include "../../module/probe.h"
-#include "../../lcd/marlinui.h" // for LCD_MESSAGEPGM
+#include "../../lcd/marlinui.h" // for LCD_MESSAGE
#if HAS_LEVELING
#include "../../feature/bedlevel/bedlevel.h"
@@ -201,7 +201,7 @@ void GcodeSuite::G34() {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> probing all positions.");
const int iter = iteration + 1;
- SERIAL_ECHOLNPAIR("\nG34 Iteration: ", iter);
+ SERIAL_ECHOLNPGM("\nG34 Iteration: ", iter);
#if HAS_STATUS_MESSAGE
char str[iter_str_len + 2 + 1];
sprintf_P(str, msg_iteration, iter);
@@ -221,7 +221,7 @@ void GcodeSuite::G34() {
if ((iteration == 0 || i > 0) && z_probe > current_position.z) do_blocking_move_to_z(z_probe);
if (DEBUGGING(LEVELING))
- DEBUG_ECHOLNPAIR_P(PSTR("Probing X"), z_stepper_align.xy[iprobe].x, SP_Y_STR, z_stepper_align.xy[iprobe].y);
+ DEBUG_ECHOLNPGM_P(PSTR("Probing X"), z_stepper_align.xy[iprobe].x, SP_Y_STR, z_stepper_align.xy[iprobe].y);
// Probe a Z height for each stepper.
// Probing sanity check is disabled, as it would trigger even in normal cases because
@@ -229,7 +229,7 @@ void GcodeSuite::G34() {
const float z_probed_height = probe.probe_at_point(z_stepper_align.xy[iprobe], raise_after, 0, true, false);
if (isnan(z_probed_height)) {
SERIAL_ECHOLNPGM("Probing failed");
- LCD_MESSAGEPGM(MSG_LCD_PROBING_FAILED);
+ LCD_MESSAGE(MSG_LCD_PROBING_FAILED);
err_break = true;
break;
}
@@ -238,7 +238,7 @@ void GcodeSuite::G34() {
// the next iteration of probing. This allows adjustments to be made away from the bed.
z_measured[iprobe] = z_probed_height + Z_CLEARANCE_BETWEEN_PROBES;
- if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("> Z", iprobe + 1, " measured position is ", z_measured[iprobe]);
+ if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> Z", iprobe + 1, " measured position is ", z_measured[iprobe]);
// Remember the minimum measurement to calculate the correction later on
z_measured_min = _MIN(z_measured_min, z_measured[iprobe]);
@@ -267,7 +267,7 @@ void GcodeSuite::G34() {
linear_fit_data lfd;
incremental_LSF_reset(&lfd);
LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS) {
- SERIAL_ECHOLNPAIR("PROBEPT_", i, ": ", z_measured[i]);
+ SERIAL_ECHOLNPGM("PROBEPT_", i, ": ", z_measured[i]);
incremental_LSF(&lfd, z_stepper_align.xy[i], z_measured[i]);
}
finish_incremental_LSF(&lfd);
@@ -278,7 +278,7 @@ void GcodeSuite::G34() {
z_measured_min = _MIN(z_measured_min, z_measured[i]);
}
- SERIAL_ECHOLNPAIR(
+ SERIAL_ECHOLNPGM(
LIST_N(DOUBLE(NUM_Z_STEPPER_DRIVERS),
"Calculated Z1=", z_measured[0],
" Z2=", z_measured[1],
@@ -288,7 +288,7 @@ void GcodeSuite::G34() {
);
#endif
- SERIAL_ECHOLNPAIR("\n"
+ SERIAL_ECHOLNPGM("\n"
"Z2-Z1=", ABS(z_measured[1] - z_measured[0])
#if TRIPLE_Z
, " Z3-Z2=", ABS(z_measured[2] - z_measured[1])
@@ -328,7 +328,7 @@ void GcodeSuite::G34() {
auto decreasing_accuracy = [](const_float_t v1, const_float_t v2) {
if (v1 < v2 * 0.7f) {
SERIAL_ECHOLNPGM("Decreasing Accuracy Detected.");
- LCD_MESSAGEPGM(MSG_DECREASING_ACCURACY);
+ LCD_MESSAGE(MSG_DECREASING_ACCURACY);
return true;
}
return false;
@@ -372,8 +372,8 @@ void GcodeSuite::G34() {
// Check for less accuracy compared to last move
if (decreasing_accuracy(last_z_align_move[zstepper], z_align_abs)) {
- if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("> Z", zstepper + 1, " last_z_align_move = ", last_z_align_move[zstepper]);
- if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("> Z", zstepper + 1, " z_align_abs = ", z_align_abs);
+ if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> Z", zstepper + 1, " last_z_align_move = ", last_z_align_move[zstepper]);
+ if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> Z", zstepper + 1, " z_align_abs = ", z_align_abs);
adjustment_reverse = !adjustment_reverse;
}
@@ -385,7 +385,7 @@ void GcodeSuite::G34() {
// Stop early if all measured points achieve accuracy target
if (z_align_abs > z_auto_align_accuracy) success_break = false;
- if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("> Z", zstepper + 1, " corrected by ", z_align_move);
+ if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> Z", zstepper + 1, " corrected by ", z_align_move);
// Lock all steppers except one
stepper.set_all_z_lock(true, zstepper);
@@ -395,7 +395,7 @@ void GcodeSuite::G34() {
// Will match reversed Z steppers on dual steppers. Triple will need more work to map.
if (adjustment_reverse) {
z_align_move = -z_align_move;
- if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("> Z", zstepper + 1, " correction reversed to ", z_align_move);
+ if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> Z", zstepper + 1, " correction reversed to ", z_align_move);
}
#endif
@@ -411,7 +411,7 @@ void GcodeSuite::G34() {
if (success_break) {
SERIAL_ECHOLNPGM("Target accuracy achieved.");
- LCD_MESSAGEPGM(MSG_ACCURACY_ACHIEVED);
+ LCD_MESSAGE(MSG_ACCURACY_ACHIEVED);
break;
}
@@ -421,7 +421,7 @@ void GcodeSuite::G34() {
if (err_break)
SERIAL_ECHOLNPGM("G34 aborted.");
else {
- SERIAL_ECHOLNPAIR("Did ", iteration + (iteration != z_auto_align_iterations), " of ", z_auto_align_iterations);
+ SERIAL_ECHOLNPGM("Did ", iteration + (iteration != z_auto_align_iterations), " of ", z_auto_align_iterations);
SERIAL_ECHOLNPAIR_F("Accuracy: ", z_maxdiff);
}
@@ -433,7 +433,7 @@ void GcodeSuite::G34() {
// After this operation the z position needs correction
set_axis_never_homed(Z_AXIS);
// Home Z after the alignment procedure
- process_subcommands_now_P(PSTR("G28Z"));
+ process_subcommands_now(F("G28Z"));
#else
// Use the probed height from the last iteration to determine the Z height.
// z_measured_min is used, because all steppers are aligned to z_measured_min.
@@ -475,21 +475,13 @@ void GcodeSuite::G34() {
*/
void GcodeSuite::M422() {
+ if (!parser.seen_any()) return M422_report();
+
if (parser.seen('R')) {
z_stepper_align.reset_to_default();
return;
}
- if (!parser.seen_any()) {
- LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS)
- SERIAL_ECHOLNPAIR_P(PSTR("M422 S"), i + 1, SP_X_STR, z_stepper_align.xy[i].x, SP_Y_STR, z_stepper_align.xy[i].y);
- #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
- LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS)
- SERIAL_ECHOLNPAIR_P(PSTR("M422 W"), i + 1, SP_X_STR, z_stepper_align.stepper_xy[i].x, SP_Y_STR, z_stepper_align.stepper_xy[i].y);
- #endif
- return;
- }
-
const bool is_probe_point = parser.seen('S');
if (TERN0(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS, is_probe_point && parser.seen('W'))) {
@@ -545,4 +537,26 @@ void GcodeSuite::M422() {
pos_dest[position_index] = pos;
}
+void GcodeSuite::M422_report(const bool forReplay/*=true*/) {
+ report_heading(forReplay, F(STR_Z_AUTO_ALIGN));
+ LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS) {
+ report_echo_start(forReplay);
+ SERIAL_ECHOLNPGM_P(
+ PSTR(" M422 S"), i + 1,
+ SP_X_STR, z_stepper_align.xy[i].x,
+ SP_Y_STR, z_stepper_align.xy[i].y
+ );
+ }
+ #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
+ LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS) {
+ report_echo_start(forReplay);
+ SERIAL_ECHOLNPGM_P(
+ PSTR(" M422 W"), i + 1,
+ SP_X_STR, z_stepper_align.stepper_xy[i].x,
+ SP_Y_STR, z_stepper_align.stepper_xy[i].y
+ );
+ }
+ #endif
+}
+
#endif // Z_STEPPER_AUTO_ALIGN
diff --git a/Marlin/src/gcode/calibrate/G425.cpp b/Marlin/src/gcode/calibrate/G425.cpp
index c8efea858ca5d..88c906f4937aa 100644
--- a/Marlin/src/gcode/calibrate/G425.cpp
+++ b/Marlin/src/gcode/calibrate/G425.cpp
@@ -354,44 +354,44 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
inline void report_measured_faces(const measurements_t &m) {
SERIAL_ECHOLNPGM("Sides:");
#if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z)
- SERIAL_ECHOLNPAIR(" Top: ", m.obj_side[TOP]);
+ SERIAL_ECHOLNPGM(" Top: ", m.obj_side[TOP]);
#endif
#if ENABLED(CALIBRATION_MEASURE_LEFT)
- SERIAL_ECHOLNPAIR(" Left: ", m.obj_side[LEFT]);
+ SERIAL_ECHOLNPGM(" Left: ", m.obj_side[LEFT]);
#endif
#if ENABLED(CALIBRATION_MEASURE_RIGHT)
- SERIAL_ECHOLNPAIR(" Right: ", m.obj_side[RIGHT]);
+ SERIAL_ECHOLNPGM(" Right: ", m.obj_side[RIGHT]);
#endif
#if HAS_Y_AXIS
#if ENABLED(CALIBRATION_MEASURE_FRONT)
- SERIAL_ECHOLNPAIR(" Front: ", m.obj_side[FRONT]);
+ SERIAL_ECHOLNPGM(" Front: ", m.obj_side[FRONT]);
#endif
#if ENABLED(CALIBRATION_MEASURE_BACK)
- SERIAL_ECHOLNPAIR(" Back: ", m.obj_side[BACK]);
+ SERIAL_ECHOLNPGM(" Back: ", m.obj_side[BACK]);
#endif
#endif
#if LINEAR_AXES >= 4
#if ENABLED(CALIBRATION_MEASURE_IMIN)
- SERIAL_ECHOLNPAIR(" " STR_I_MIN ": ", m.obj_side[IMINIMUM]);
+ SERIAL_ECHOLNPGM(" " STR_I_MIN ": ", m.obj_side[IMINIMUM]);
#endif
#if ENABLED(CALIBRATION_MEASURE_IMAX)
- SERIAL_ECHOLNPAIR(" " STR_I_MAX ": ", m.obj_side[IMAXIMUM]);
+ SERIAL_ECHOLNPGM(" " STR_I_MAX ": ", m.obj_side[IMAXIMUM]);
#endif
#endif
#if LINEAR_AXES >= 5
#if ENABLED(CALIBRATION_MEASURE_JMIN)
- SERIAL_ECHOLNPAIR(" " STR_J_MIN ": ", m.obj_side[JMINIMUM]);
+ SERIAL_ECHOLNPGM(" " STR_J_MIN ": ", m.obj_side[JMINIMUM]);
#endif
#if ENABLED(CALIBRATION_MEASURE_JMAX)
- SERIAL_ECHOLNPAIR(" " STR_J_MAX ": ", m.obj_side[JMAXIMUM]);
+ SERIAL_ECHOLNPGM(" " STR_J_MAX ": ", m.obj_side[JMAXIMUM]);
#endif
#endif
#if LINEAR_AXES >= 6
#if ENABLED(CALIBRATION_MEASURE_KMIN)
- SERIAL_ECHOLNPAIR(" " STR_K_MIN ": ", m.obj_side[KMINIMUM]);
+ SERIAL_ECHOLNPGM(" " STR_K_MIN ": ", m.obj_side[KMINIMUM]);
#endif
#if ENABLED(CALIBRATION_MEASURE_KMAX)
- SERIAL_ECHOLNPAIR(" " STR_K_MAX ": ", m.obj_side[KMAXIMUM]);
+ SERIAL_ECHOLNPGM(" " STR_K_MAX ": ", m.obj_side[KMAXIMUM]);
#endif
#endif
SERIAL_EOL();
@@ -400,20 +400,20 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
inline void report_measured_center(const measurements_t &m) {
SERIAL_ECHOLNPGM("Center:");
#if HAS_X_CENTER
- SERIAL_ECHOLNPAIR_P(SP_X_STR, m.obj_center.x);
+ SERIAL_ECHOLNPGM_P(SP_X_STR, m.obj_center.x);
#endif
#if HAS_Y_CENTER
- SERIAL_ECHOLNPAIR_P(SP_Y_STR, m.obj_center.y);
+ SERIAL_ECHOLNPGM_P(SP_Y_STR, m.obj_center.y);
#endif
- SERIAL_ECHOLNPAIR_P(SP_Z_STR, m.obj_center.z);
+ SERIAL_ECHOLNPGM_P(SP_Z_STR, m.obj_center.z);
#if HAS_I_CENTER
- SERIAL_ECHOLNPAIR_P(SP_I_STR, m.obj_center.i);
+ SERIAL_ECHOLNPGM_P(SP_I_STR, m.obj_center.i);
#endif
#if HAS_J_CENTER
- SERIAL_ECHOLNPAIR_P(SP_J_STR, m.obj_center.j);
+ SERIAL_ECHOLNPGM_P(SP_J_STR, m.obj_center.j);
#endif
#if HAS_K_CENTER
- SERIAL_ECHOLNPAIR_P(SP_K_STR, m.obj_center.k);
+ SERIAL_ECHOLNPGM_P(SP_K_STR, m.obj_center.k);
#endif
SERIAL_EOL();
}
@@ -422,45 +422,45 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
SERIAL_ECHOLNPGM("Backlash:");
#if AXIS_CAN_CALIBRATE(X)
#if ENABLED(CALIBRATION_MEASURE_LEFT)
- SERIAL_ECHOLNPAIR(" Left: ", m.backlash[LEFT]);
+ SERIAL_ECHOLNPGM(" Left: ", m.backlash[LEFT]);
#endif
#if ENABLED(CALIBRATION_MEASURE_RIGHT)
- SERIAL_ECHOLNPAIR(" Right: ", m.backlash[RIGHT]);
+ SERIAL_ECHOLNPGM(" Right: ", m.backlash[RIGHT]);
#endif
#endif
#if HAS_Y_AXIS && AXIS_CAN_CALIBRATE(Y)
#if ENABLED(CALIBRATION_MEASURE_FRONT)
- SERIAL_ECHOLNPAIR(" Front: ", m.backlash[FRONT]);
+ SERIAL_ECHOLNPGM(" Front: ", m.backlash[FRONT]);
#endif
#if ENABLED(CALIBRATION_MEASURE_BACK)
- SERIAL_ECHOLNPAIR(" Back: ", m.backlash[BACK]);
+ SERIAL_ECHOLNPGM(" Back: ", m.backlash[BACK]);
#endif
#endif
#if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z)
- SERIAL_ECHOLNPAIR(" Top: ", m.backlash[TOP]);
+ SERIAL_ECHOLNPGM(" Top: ", m.backlash[TOP]);
#endif
#if LINEAR_AXES >= 4 && AXIS_CAN_CALIBRATE(I)
#if ENABLED(CALIBRATION_MEASURE_IMIN)
- SERIAL_ECHOLNPAIR(" " STR_I_MIN ": ", m.backlash[IMINIMUM]);
+ SERIAL_ECHOLNPGM(" " STR_I_MIN ": ", m.backlash[IMINIMUM]);
#endif
#if ENABLED(CALIBRATION_MEASURE_IMAX)
- SERIAL_ECHOLNPAIR(" " STR_I_MAX ": ", m.backlash[IMAXIMUM]);
+ SERIAL_ECHOLNPGM(" " STR_I_MAX ": ", m.backlash[IMAXIMUM]);
#endif
#endif
#if LINEAR_AXES >= 5 && AXIS_CAN_CALIBRATE(J)
#if ENABLED(CALIBRATION_MEASURE_JMIN)
- SERIAL_ECHOLNPAIR(" " STR_J_MIN ": ", m.backlash[JMINIMUM]);
+ SERIAL_ECHOLNPGM(" " STR_J_MIN ": ", m.backlash[JMINIMUM]);
#endif
#if ENABLED(CALIBRATION_MEASURE_JMAX)
- SERIAL_ECHOLNPAIR(" " STR_J_MAX ": ", m.backlash[JMAXIMUM]);
+ SERIAL_ECHOLNPGM(" " STR_J_MAX ": ", m.backlash[JMAXIMUM]);
#endif
#endif
#if LINEAR_AXES >= 6 && AXIS_CAN_CALIBRATE(K)
#if ENABLED(CALIBRATION_MEASURE_KMIN)
- SERIAL_ECHOLNPAIR(" " STR_K_MIN ": ", m.backlash[KMINIMUM]);
+ SERIAL_ECHOLNPGM(" " STR_K_MIN ": ", m.backlash[KMINIMUM]);
#endif
#if ENABLED(CALIBRATION_MEASURE_KMAX)
- SERIAL_ECHOLNPAIR(" " STR_K_MAX ": ", m.backlash[KMAXIMUM]);
+ SERIAL_ECHOLNPGM(" " STR_K_MAX ": ", m.backlash[KMAXIMUM]);
#endif
#endif
SERIAL_EOL();
@@ -471,22 +471,22 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
SERIAL_ECHO(active_extruder);
SERIAL_ECHOLNPGM(" Positional Error:");
#if HAS_X_CENTER && AXIS_CAN_CALIBRATE(X)
- SERIAL_ECHOLNPAIR_P(SP_X_STR, m.pos_error.x);
+ SERIAL_ECHOLNPGM_P(SP_X_STR, m.pos_error.x);
#endif
#if HAS_Y_CENTER && AXIS_CAN_CALIBRATE(Y)
- SERIAL_ECHOLNPAIR_P(SP_Y_STR, m.pos_error.y);
+ SERIAL_ECHOLNPGM_P(SP_Y_STR, m.pos_error.y);
#endif
#if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z)
- SERIAL_ECHOLNPAIR_P(SP_Z_STR, m.pos_error.z);
+ SERIAL_ECHOLNPGM_P(SP_Z_STR, m.pos_error.z);
#endif
#if HAS_I_CENTER && AXIS_CAN_CALIBRATE(I)
- SERIAL_ECHOLNPAIR_P(SP_I_STR, m.pos_error.i);
+ SERIAL_ECHOLNPGM_P(SP_I_STR, m.pos_error.i);
#endif
#if HAS_J_CENTER && AXIS_CAN_CALIBRATE(J)
- SERIAL_ECHOLNPAIR_P(SP_J_STR, m.pos_error.j);
+ SERIAL_ECHOLNPGM_P(SP_J_STR, m.pos_error.j);
#endif
#if HAS_K_CENTER && AXIS_CAN_CALIBRATE(K)
- SERIAL_ECHOLNPAIR_P(SP_Z_STR, m.pos_error.z);
+ SERIAL_ECHOLNPGM_P(SP_Z_STR, m.pos_error.z);
#endif
SERIAL_EOL();
}
@@ -494,10 +494,10 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
inline void report_measured_nozzle_dimensions(const measurements_t &m) {
SERIAL_ECHOLNPGM("Nozzle Tip Outer Dimensions:");
#if HAS_X_CENTER
- SERIAL_ECHOLNPAIR_P(SP_X_STR, m.nozzle_outer_dimension.x);
+ SERIAL_ECHOLNPGM_P(SP_X_STR, m.nozzle_outer_dimension.x);
#endif
#if HAS_Y_CENTER
- SERIAL_ECHOLNPAIR_P(SP_Y_STR, m.nozzle_outer_dimension.y);
+ SERIAL_ECHOLNPGM_P(SP_Y_STR, m.nozzle_outer_dimension.y);
#endif
SERIAL_EOL();
UNUSED(m);
@@ -509,7 +509,7 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
//
inline void report_hotend_offsets() {
LOOP_S_L_N(e, 1, HOTENDS)
- SERIAL_ECHOLNPAIR_P(PSTR("T"), e, PSTR(" Hotend Offset X"), hotend_offset[e].x, SP_Y_STR, hotend_offset[e].y, SP_Z_STR, hotend_offset[e].z);
+ SERIAL_ECHOLNPGM_P(PSTR("T"), e, PSTR(" Hotend Offset X"), hotend_offset[e].x, SP_Y_STR, hotend_offset[e].y, SP_Z_STR, hotend_offset[e].z);
}
#endif
@@ -709,7 +709,7 @@ inline void calibrate_all() {
void GcodeSuite::G425() {
#ifdef CALIBRATION_SCRIPT_PRE
- GcodeSuite::process_subcommands_now_P(PSTR(CALIBRATION_SCRIPT_PRE));
+ process_subcommands_now(F(CALIBRATION_SCRIPT_PRE));
#endif
if (homing_needed_error()) return;
@@ -745,7 +745,7 @@ void GcodeSuite::G425() {
SET_SOFT_ENDSTOP_LOOSE(false);
#ifdef CALIBRATION_SCRIPT_POST
- GcodeSuite::process_subcommands_now_P(PSTR(CALIBRATION_SCRIPT_POST));
+ process_subcommands_now(F(CALIBRATION_SCRIPT_POST));
#endif
}
diff --git a/Marlin/src/gcode/calibrate/G76_M192_M871.cpp b/Marlin/src/gcode/calibrate/G76_M192_M871.cpp
deleted file mode 100644
index 2d1b9443bf17b..0000000000000
--- a/Marlin/src/gcode/calibrate/G76_M192_M871.cpp
+++ /dev/null
@@ -1,358 +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 .
- *
- */
-
-/**
- * G76_M871.cpp - Temperature calibration/compensation for z-probing
- */
-
-#include "../../inc/MarlinConfig.h"
-
-#if ENABLED(PROBE_TEMP_COMPENSATION)
-
-#include "../gcode.h"
-#include "../../module/motion.h"
-#include "../../module/planner.h"
-#include "../../module/probe.h"
-#include "../../feature/bedlevel/bedlevel.h"
-#include "../../module/temperature.h"
-#include "../../module/probe.h"
-#include "../../feature/probe_temp_comp.h"
-#include "../../lcd/marlinui.h"
-
-/**
- * G76: calibrate probe and/or bed temperature offsets
- * Notes:
- * - When calibrating probe, bed temperature is held constant.
- * Compensation values are deltas to first probe measurement at probe temp. = 30°C.
- * - When calibrating bed, probe temperature is held constant.
- * Compensation values are deltas to first probe measurement at bed temp. = 60°C.
- * - The hotend will not be heated at any time.
- * - On my Průša MK3S clone I put a piece of paper between the probe and the hotend
- * so the hotend fan would not cool my probe constantly. Alternatively you could just
- * make sure the fan is not running while running the calibration process.
- *
- * Probe calibration:
- * - Moves probe to cooldown point.
- * - Heats up bed to 100°C.
- * - Moves probe to probing point (1mm above heatbed).
- * - Waits until probe reaches target temperature (30°C).
- * - Does a z-probing (=base value) and increases target temperature by 5°C.
- * - Waits until probe reaches increased target temperature.
- * - Does a z-probing (delta to base value will be a compensation value) and increases target temperature by 5°C.
- * - Repeats last two steps until max. temperature reached or timeout (i.e. probe does not heat up any further).
- * - Compensation values of higher temperatures will be extrapolated (using linear regression first).
- * While this is not exact by any means it is still better than simply using the last compensation value.
- *
- * Bed calibration:
- * - Moves probe to cooldown point.
- * - Heats up bed to 60°C.
- * - Moves probe to probing point (1mm above heatbed).
- * - Waits until probe reaches target temperature (30°C).
- * - Does a z-probing (=base value) and increases bed temperature by 5°C.
- * - Moves probe to cooldown point.
- * - Waits until probe is below 30°C and bed has reached target temperature.
- * - Moves probe to probing point and waits until it reaches target temperature (30°C).
- * - Does a z-probing (delta to base value will be a compensation value) and increases bed temperature by 5°C.
- * - Repeats last four points until max. bed temperature reached (110°C) or timeout.
- * - Compensation values of higher temperatures will be extrapolated (using linear regression first).
- * While this is not exact by any means it is still better than simply using the last compensation value.
- *
- * G76 [B | P]
- * - no flag - Both calibration procedures will be run.
- * - `B` - Run bed temperature calibration.
- * - `P` - Run probe temperature calibration.
- */
-
-static void say_waiting_for() { SERIAL_ECHOPGM("Waiting for "); }
-static void say_waiting_for_probe_heating() { say_waiting_for(); SERIAL_ECHOLNPGM("probe heating."); }
-static void say_successfully_calibrated() { SERIAL_ECHOPGM("Successfully calibrated"); }
-static void say_failed_to_calibrate() { SERIAL_ECHOPGM("!Failed to calibrate"); }
-
-void GcodeSuite::G76() {
- // Check if heated bed is available and z-homing is done with probe
- #if TEMP_SENSOR_BED == 0 || !(HOMING_Z_WITH_PROBE)
- return;
- #endif
-
- auto report_temps = [](millis_t &ntr, millis_t timeout=0) {
- idle_no_sleep();
- const millis_t ms = millis();
- if (ELAPSED(ms, ntr)) {
- ntr = ms + 1000;
- thermalManager.print_heater_states(active_extruder);
- }
- return (timeout && ELAPSED(ms, timeout));
- };
-
- auto wait_for_temps = [&](const celsius_t tb, const celsius_t tp, millis_t &ntr, const millis_t timeout=0) {
- say_waiting_for(); SERIAL_ECHOLNPGM("bed and probe temperature.");
- while (thermalManager.wholeDegBed() != tb || thermalManager.wholeDegProbe() > tp)
- if (report_temps(ntr, timeout)) return true;
- return false;
- };
-
- auto g76_probe = [](const TempSensorID sid, celsius_t &targ, const xy_pos_t &nozpos) {
- do_z_clearance(5.0); // Raise nozzle before probing
- const float measured_z = probe.probe_at_point(nozpos, PROBE_PT_STOW, 0, false); // verbose=0, probe_relative=false
- if (isnan(measured_z))
- SERIAL_ECHOLNPGM("!Received NAN. Aborting.");
- else {
- SERIAL_ECHOLNPAIR_F("Measured: ", measured_z);
- if (targ == cali_info_init[sid].start_temp)
- temp_comp.prepare_new_calibration(measured_z);
- else
- temp_comp.push_back_new_measurement(sid, measured_z);
- targ += cali_info_init[sid].temp_res;
- }
- return measured_z;
- };
-
- #if ENABLED(BLTOUCH)
- // Make sure any BLTouch error condition is cleared
- bltouch_command(BLTOUCH_RESET, BLTOUCH_RESET_DELAY);
- set_bltouch_deployed(false);
- #endif
-
- bool do_bed_cal = parser.boolval('B'), do_probe_cal = parser.boolval('P');
- if (!do_bed_cal && !do_probe_cal) do_bed_cal = do_probe_cal = true;
-
- // Synchronize with planner
- planner.synchronize();
-
- const xyz_pos_t parkpos = temp_comp.park_point,
- probe_pos_xyz = xyz_pos_t(temp_comp.measure_point) + xyz_pos_t({ 0.0f, 0.0f, PTC_PROBE_HEATING_OFFSET }),
- noz_pos_xyz = probe_pos_xyz - probe.offset_xy; // Nozzle position based on probe position
-
- if (do_bed_cal || do_probe_cal) {
- // Ensure park position is reachable
- bool reachable = position_is_reachable(parkpos) || WITHIN(parkpos.z, Z_MIN_POS - fslop, Z_MAX_POS + fslop);
- if (!reachable)
- SERIAL_ECHOLNPGM("!Park");
- else {
- // Ensure probe position is reachable
- reachable = probe.can_reach(probe_pos_xyz);
- if (!reachable) SERIAL_ECHOLNPGM("!Probe");
- }
-
- if (!reachable) {
- SERIAL_ECHOLNPGM(" position unreachable - aborting.");
- return;
- }
-
- process_subcommands_now_P(G28_STR);
- }
-
- remember_feedrate_scaling_off();
-
- /******************************************
- * Calibrate bed temperature offsets
- ******************************************/
-
- // Report temperatures every second and handle heating timeouts
- millis_t next_temp_report = millis() + 1000;
-
- auto report_targets = [&](const celsius_t tb, const celsius_t tp) {
- SERIAL_ECHOLNPAIR("Target Bed:", tb, " Probe:", tp);
- };
-
- if (do_bed_cal) {
-
- celsius_t target_bed = cali_info_init[TSI_BED].start_temp,
- target_probe = temp_comp.bed_calib_probe_temp;
-
- say_waiting_for(); SERIAL_ECHOLNPGM(" cooling.");
- while (thermalManager.wholeDegBed() > target_bed || thermalManager.wholeDegProbe() > target_probe)
- report_temps(next_temp_report);
-
- // Disable leveling so it won't mess with us
- TERN_(HAS_LEVELING, set_bed_leveling_enabled(false));
-
- for (;;) {
- thermalManager.setTargetBed(target_bed);
-
- report_targets(target_bed, target_probe);
-
- // Park nozzle
- do_blocking_move_to(parkpos);
-
- // Wait for heatbed to reach target temp and probe to cool below target temp
- if (wait_for_temps(target_bed, target_probe, next_temp_report, millis() + MIN_TO_MS(15))) {
- SERIAL_ECHOLNPGM("!Bed heating timeout.");
- break;
- }
-
- // Move the nozzle to the probing point and wait for the probe to reach target temp
- do_blocking_move_to(noz_pos_xyz);
- say_waiting_for_probe_heating();
- SERIAL_EOL();
- while (thermalManager.wholeDegProbe() < target_probe)
- report_temps(next_temp_report);
-
- const float measured_z = g76_probe(TSI_BED, target_bed, noz_pos_xyz);
- if (isnan(measured_z) || target_bed > (BED_MAX_TARGET)) break;
- }
-
- SERIAL_ECHOLNPAIR("Retrieved measurements: ", temp_comp.get_index());
- if (temp_comp.finish_calibration(TSI_BED)) {
- say_successfully_calibrated();
- SERIAL_ECHOLNPGM(" bed.");
- }
- else {
- say_failed_to_calibrate();
- SERIAL_ECHOLNPGM(" bed. Values reset.");
- }
-
- // Cleanup
- thermalManager.setTargetBed(0);
- TERN_(HAS_LEVELING, set_bed_leveling_enabled(true));
- } // do_bed_cal
-
- /********************************************
- * Calibrate probe temperature offsets
- ********************************************/
-
- if (do_probe_cal) {
-
- // Park nozzle
- do_blocking_move_to(parkpos);
-
- // Initialize temperatures
- const celsius_t target_bed = temp_comp.probe_calib_bed_temp;
- thermalManager.setTargetBed(target_bed);
-
- celsius_t target_probe = cali_info_init[TSI_PROBE].start_temp;
-
- report_targets(target_bed, target_probe);
-
- // Wait for heatbed to reach target temp and probe to cool below target temp
- wait_for_temps(target_bed, target_probe, next_temp_report);
-
- // Disable leveling so it won't mess with us
- TERN_(HAS_LEVELING, set_bed_leveling_enabled(false));
-
- bool timeout = false;
- for (;;) {
- // Move probe to probing point and wait for it to reach target temperature
- do_blocking_move_to(noz_pos_xyz);
-
- say_waiting_for_probe_heating();
- SERIAL_ECHOLNPAIR(" Bed:", target_bed, " Probe:", target_probe);
- const millis_t probe_timeout_ms = millis() + SEC_TO_MS(900UL);
- while (thermalManager.degProbe() < target_probe) {
- if (report_temps(next_temp_report, probe_timeout_ms)) {
- SERIAL_ECHOLNPGM("!Probe heating timed out.");
- timeout = true;
- break;
- }
- }
- if (timeout) break;
-
- const float measured_z = g76_probe(TSI_PROBE, target_probe, noz_pos_xyz);
- if (isnan(measured_z) || target_probe > cali_info_init[TSI_PROBE].end_temp) break;
- }
-
- SERIAL_ECHOLNPAIR("Retrieved measurements: ", temp_comp.get_index());
- if (temp_comp.finish_calibration(TSI_PROBE))
- say_successfully_calibrated();
- else
- say_failed_to_calibrate();
- SERIAL_ECHOLNPGM(" probe.");
-
- // Cleanup
- thermalManager.setTargetBed(0);
- TERN_(HAS_LEVELING, set_bed_leveling_enabled(true));
-
- SERIAL_ECHOLNPGM("Final compensation values:");
- temp_comp.print_offsets();
- } // do_probe_cal
-
- restore_feedrate_and_scaling();
-}
-
-/**
- * M871: Report / reset temperature compensation offsets.
- * Note: This does not affect values in EEPROM until M500.
- *
- * M871 [ R | B | P | E ]
- *
- * No Parameters - Print current offset values.
- *
- * Select only one of these flags:
- * R - Reset all offsets to zero (i.e., disable compensation).
- * B - Manually set offset for bed
- * P - Manually set offset for probe
- * E - Manually set offset for extruder
- *
- * With B, P, or E:
- * I[index] - Index in the array
- * V[value] - Adjustment in µm
- */
-void GcodeSuite::M871() {
-
- if (parser.seen('R')) {
- // Reset z-probe offsets to factory defaults
- temp_comp.clear_all_offsets();
- SERIAL_ECHOLNPGM("Offsets reset to default.");
- }
- else if (parser.seen("BPE")) {
- if (!parser.seenval('V')) return;
- const int16_t offset_val = parser.value_int();
- if (!parser.seenval('I')) return;
- const int16_t idx = parser.value_int();
- const TempSensorID mod = (parser.seen('B') ? TSI_BED :
- #if ENABLED(USE_TEMP_EXT_COMPENSATION)
- parser.seen('E') ? TSI_EXT :
- #endif
- TSI_PROBE
- );
- if (idx > 0 && temp_comp.set_offset(mod, idx - 1, offset_val))
- SERIAL_ECHOLNPAIR("Set value: ", offset_val);
- else
- SERIAL_ECHOLNPGM("!Invalid index. Failed to set value (note: value at index 0 is constant).");
-
- }
- else // Print current Z-probe adjustments. Note: Values in EEPROM might differ.
- temp_comp.print_offsets();
-}
-
-/**
- * M192: Wait for probe temperature sensor to reach a target
- *
- * Select only one of these flags:
- * R - Wait for heating or cooling
- * S - Wait only for heating
- */
-void GcodeSuite::M192() {
- if (DEBUGGING(DRYRUN)) return;
-
- const bool no_wait_for_cooling = parser.seenval('S');
- if (!no_wait_for_cooling && ! parser.seenval('R')) {
- SERIAL_ERROR_MSG("No target temperature set.");
- return;
- }
-
- const celsius_t target_temp = parser.value_celsius();
- ui.set_status_P(thermalManager.isProbeBelowTemp(target_temp) ? GET_TEXT(MSG_PROBE_HEATING) : GET_TEXT(MSG_PROBE_COOLING));
- thermalManager.wait_for_probe(target_temp, no_wait_for_cooling);
-}
-
-#endif // PROBE_TEMP_COMPENSATION
diff --git a/Marlin/src/gcode/calibrate/G76_M871.cpp b/Marlin/src/gcode/calibrate/G76_M871.cpp
new file mode 100644
index 0000000000000..21bb2c7590066
--- /dev/null
+++ b/Marlin/src/gcode/calibrate/G76_M871.cpp
@@ -0,0 +1,337 @@
+/**
+ * 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 .
+ *
+ */
+
+/**
+ * G76_M871.cpp - Temperature calibration/compensation for z-probing
+ */
+
+#include "../../inc/MarlinConfig.h"
+
+#if HAS_PTC
+
+#include "../gcode.h"
+#include "../../module/motion.h"
+#include "../../module/planner.h"
+#include "../../module/probe.h"
+#include "../../feature/bedlevel/bedlevel.h"
+#include "../../module/temperature.h"
+#include "../../module/probe.h"
+#include "../../feature/probe_temp_comp.h"
+#include "../../lcd/marlinui.h"
+
+/**
+ * G76: calibrate probe and/or bed temperature offsets
+ * Notes:
+ * - When calibrating probe, bed temperature is held constant.
+ * Compensation values are deltas to first probe measurement at probe temp. = 30°C.
+ * - When calibrating bed, probe temperature is held constant.
+ * Compensation values are deltas to first probe measurement at bed temp. = 60°C.
+ * - The hotend will not be heated at any time.
+ * - On my Průša MK3S clone I put a piece of paper between the probe and the hotend
+ * so the hotend fan would not cool my probe constantly. Alternatively you could just
+ * make sure the fan is not running while running the calibration process.
+ *
+ * Probe calibration:
+ * - Moves probe to cooldown point.
+ * - Heats up bed to 100°C.
+ * - Moves probe to probing point (1mm above heatbed).
+ * - Waits until probe reaches target temperature (30°C).
+ * - Does a z-probing (=base value) and increases target temperature by 5°C.
+ * - Waits until probe reaches increased target temperature.
+ * - Does a z-probing (delta to base value will be a compensation value) and increases target temperature by 5°C.
+ * - Repeats last two steps until max. temperature reached or timeout (i.e. probe does not heat up any further).
+ * - Compensation values of higher temperatures will be extrapolated (using linear regression first).
+ * While this is not exact by any means it is still better than simply using the last compensation value.
+ *
+ * Bed calibration:
+ * - Moves probe to cooldown point.
+ * - Heats up bed to 60°C.
+ * - Moves probe to probing point (1mm above heatbed).
+ * - Waits until probe reaches target temperature (30°C).
+ * - Does a z-probing (=base value) and increases bed temperature by 5°C.
+ * - Moves probe to cooldown point.
+ * - Waits until probe is below 30°C and bed has reached target temperature.
+ * - Moves probe to probing point and waits until it reaches target temperature (30°C).
+ * - Does a z-probing (delta to base value will be a compensation value) and increases bed temperature by 5°C.
+ * - Repeats last four points until max. bed temperature reached (110°C) or timeout.
+ * - Compensation values of higher temperatures will be extrapolated (using linear regression first).
+ * While this is not exact by any means it is still better than simply using the last compensation value.
+ *
+ * G76 [B | P]
+ * - no flag - Both calibration procedures will be run.
+ * - `B` - Run bed temperature calibration.
+ * - `P` - Run probe temperature calibration.
+ */
+
+static void say_waiting_for() { SERIAL_ECHOPGM("Waiting for "); }
+static void say_waiting_for_probe_heating() { say_waiting_for(); SERIAL_ECHOLNPGM("probe heating."); }
+static void say_successfully_calibrated() { SERIAL_ECHOPGM("Successfully calibrated"); }
+static void say_failed_to_calibrate() { SERIAL_ECHOPGM("!Failed to calibrate"); }
+
+#if BOTH(PTC_PROBE, PTC_BED)
+
+ void GcodeSuite::G76() {
+ auto report_temps = [](millis_t &ntr, millis_t timeout=0) {
+ idle_no_sleep();
+ const millis_t ms = millis();
+ if (ELAPSED(ms, ntr)) {
+ ntr = ms + 1000;
+ thermalManager.print_heater_states(active_extruder);
+ }
+ return (timeout && ELAPSED(ms, timeout));
+ };
+
+ auto wait_for_temps = [&](const celsius_t tb, const celsius_t tp, millis_t &ntr, const millis_t timeout=0) {
+ say_waiting_for(); SERIAL_ECHOLNPGM("bed and probe temperature.");
+ while (thermalManager.wholeDegBed() != tb || thermalManager.wholeDegProbe() > tp)
+ if (report_temps(ntr, timeout)) return true;
+ return false;
+ };
+
+ auto g76_probe = [](const TempSensorID sid, celsius_t &targ, const xy_pos_t &nozpos) {
+ do_z_clearance(5.0); // Raise nozzle before probing
+ const float measured_z = probe.probe_at_point(nozpos, PROBE_PT_STOW, 0, false); // verbose=0, probe_relative=false
+ if (isnan(measured_z))
+ SERIAL_ECHOLNPGM("!Received NAN. Aborting.");
+ else {
+ SERIAL_ECHOLNPAIR_F("Measured: ", measured_z);
+ if (targ == ProbeTempComp::cali_info[sid].start_temp)
+ ptc.prepare_new_calibration(measured_z);
+ else
+ ptc.push_back_new_measurement(sid, measured_z);
+ targ += ProbeTempComp::cali_info[sid].temp_resolution;
+ }
+ return measured_z;
+ };
+
+ #if ENABLED(BLTOUCH)
+ // Make sure any BLTouch error condition is cleared
+ bltouch_command(BLTOUCH_RESET, BLTOUCH_RESET_DELAY);
+ set_bltouch_deployed(false);
+ #endif
+
+ bool do_bed_cal = parser.boolval('B'), do_probe_cal = parser.boolval('P');
+ if (!do_bed_cal && !do_probe_cal) do_bed_cal = do_probe_cal = true;
+
+ // Synchronize with planner
+ planner.synchronize();
+
+ #ifndef PTC_PROBE_HEATING_OFFSET
+ #define PTC_PROBE_HEATING_OFFSET 0
+ #endif
+ const xyz_pos_t parkpos = PTC_PARK_POS,
+ probe_pos_xyz = xyz_pos_t(PTC_PROBE_POS) + xyz_pos_t({ 0.0f, 0.0f, PTC_PROBE_HEATING_OFFSET }),
+ noz_pos_xyz = probe_pos_xyz - probe.offset_xy; // Nozzle position based on probe position
+
+ if (do_bed_cal || do_probe_cal) {
+ // Ensure park position is reachable
+ bool reachable = position_is_reachable(parkpos) || WITHIN(parkpos.z, Z_MIN_POS - fslop, Z_MAX_POS + fslop);
+ if (!reachable)
+ SERIAL_ECHOLNPGM("!Park");
+ else {
+ // Ensure probe position is reachable
+ reachable = probe.can_reach(probe_pos_xyz);
+ if (!reachable) SERIAL_ECHOLNPGM("!Probe");
+ }
+
+ if (!reachable) {
+ SERIAL_ECHOLNPGM(" position unreachable - aborting.");
+ return;
+ }
+
+ process_subcommands_now(FPSTR(G28_STR));
+ }
+
+ remember_feedrate_scaling_off();
+
+ /******************************************
+ * Calibrate bed temperature offsets
+ ******************************************/
+
+ // Report temperatures every second and handle heating timeouts
+ millis_t next_temp_report = millis() + 1000;
+
+ auto report_targets = [&](const celsius_t tb, const celsius_t tp) {
+ SERIAL_ECHOLNPGM("Target Bed:", tb, " Probe:", tp);
+ };
+
+ if (do_bed_cal) {
+
+ celsius_t target_bed = PTC_BED_START,
+ target_probe = PTC_PROBE_TEMP;
+
+ say_waiting_for(); SERIAL_ECHOLNPGM(" cooling.");
+ while (thermalManager.wholeDegBed() > target_bed || thermalManager.wholeDegProbe() > target_probe)
+ report_temps(next_temp_report);
+
+ // Disable leveling so it won't mess with us
+ TERN_(HAS_LEVELING, set_bed_leveling_enabled(false));
+
+ for (uint8_t idx = 0; idx <= PTC_BED_COUNT; idx++) {
+ thermalManager.setTargetBed(target_bed);
+
+ report_targets(target_bed, target_probe);
+
+ // Park nozzle
+ do_blocking_move_to(parkpos);
+
+ // Wait for heatbed to reach target temp and probe to cool below target temp
+ if (wait_for_temps(target_bed, target_probe, next_temp_report, millis() + MIN_TO_MS(15))) {
+ SERIAL_ECHOLNPGM("!Bed heating timeout.");
+ break;
+ }
+
+ // Move the nozzle to the probing point and wait for the probe to reach target temp
+ do_blocking_move_to(noz_pos_xyz);
+ say_waiting_for_probe_heating();
+ SERIAL_EOL();
+ while (thermalManager.wholeDegProbe() < target_probe)
+ report_temps(next_temp_report);
+
+ const float measured_z = g76_probe(TSI_BED, target_bed, noz_pos_xyz);
+ if (isnan(measured_z) || target_bed > (BED_MAX_TARGET)) break;
+ }
+
+ SERIAL_ECHOLNPGM("Retrieved measurements: ", ptc.get_index());
+ if (ptc.finish_calibration(TSI_BED)) {
+ say_successfully_calibrated();
+ SERIAL_ECHOLNPGM(" bed.");
+ }
+ else {
+ say_failed_to_calibrate();
+ SERIAL_ECHOLNPGM(" bed. Values reset.");
+ }
+
+ // Cleanup
+ thermalManager.setTargetBed(0);
+ TERN_(HAS_LEVELING, set_bed_leveling_enabled(true));
+ } // do_bed_cal
+
+ /********************************************
+ * Calibrate probe temperature offsets
+ ********************************************/
+
+ if (do_probe_cal) {
+
+ // Park nozzle
+ do_blocking_move_to(parkpos);
+
+ // Initialize temperatures
+ const celsius_t target_bed = BED_MAX_TARGET;
+ thermalManager.setTargetBed(target_bed);
+
+ celsius_t target_probe = PTC_PROBE_START;
+
+ report_targets(target_bed, target_probe);
+
+ // Wait for heatbed to reach target temp and probe to cool below target temp
+ wait_for_temps(target_bed, target_probe, next_temp_report);
+
+ // Disable leveling so it won't mess with us
+ TERN_(HAS_LEVELING, set_bed_leveling_enabled(false));
+
+ bool timeout = false;
+ for (uint8_t idx = 0; idx <= PTC_PROBE_COUNT; idx++) {
+ // Move probe to probing point and wait for it to reach target temperature
+ do_blocking_move_to(noz_pos_xyz);
+
+ say_waiting_for_probe_heating();
+ SERIAL_ECHOLNPGM(" Bed:", target_bed, " Probe:", target_probe);
+ const millis_t probe_timeout_ms = millis() + SEC_TO_MS(900UL);
+ while (thermalManager.degProbe() < target_probe) {
+ if (report_temps(next_temp_report, probe_timeout_ms)) {
+ SERIAL_ECHOLNPGM("!Probe heating timed out.");
+ timeout = true;
+ break;
+ }
+ }
+ if (timeout) break;
+
+ const float measured_z = g76_probe(TSI_PROBE, target_probe, noz_pos_xyz);
+ if (isnan(measured_z)) break;
+ }
+
+ SERIAL_ECHOLNPGM("Retrieved measurements: ", ptc.get_index());
+ if (ptc.finish_calibration(TSI_PROBE))
+ say_successfully_calibrated();
+ else
+ say_failed_to_calibrate();
+ SERIAL_ECHOLNPGM(" probe.");
+
+ // Cleanup
+ thermalManager.setTargetBed(0);
+ TERN_(HAS_LEVELING, set_bed_leveling_enabled(true));
+
+ SERIAL_ECHOLNPGM("Final compensation values:");
+ ptc.print_offsets();
+ } // do_probe_cal
+
+ restore_feedrate_and_scaling();
+ }
+
+#endif // PTC_PROBE && PTC_BED
+
+/**
+ * M871: Report / reset temperature compensation offsets.
+ * Note: This does not affect values in EEPROM until M500.
+ *
+ * M871 [ R | B | P | E ]
+ *
+ * No Parameters - Print current offset values.
+ *
+ * Select only one of these flags:
+ * R - Reset all offsets to zero (i.e., disable compensation).
+ * B - Manually set offset for bed
+ * P - Manually set offset for probe
+ * E - Manually set offset for extruder
+ *
+ * With B, P, or E:
+ * I[index] - Index in the array
+ * V[value] - Adjustment in µm
+ */
+void GcodeSuite::M871() {
+
+ if (parser.seen('R')) {
+ // Reset z-probe offsets to factory defaults
+ ptc.clear_all_offsets();
+ SERIAL_ECHOLNPGM("Offsets reset to default.");
+ }
+ else if (parser.seen("BPE")) {
+ if (!parser.seenval('V')) return;
+ const int16_t offset_val = parser.value_int();
+ if (!parser.seenval('I')) return;
+ const int16_t idx = parser.value_int();
+ const TempSensorID mod = TERN_(PTC_BED, parser.seen_test('B') ? TSI_BED :)
+ TERN_(PTC_HOTEND, parser.seen_test('E') ? TSI_EXT :)
+ TERN_(PTC_PROBE, parser.seen_test('P') ? TSI_PROBE :) TSI_COUNT;
+ if (mod == TSI_COUNT)
+ SERIAL_ECHOLNPGM("!Invalid sensor.");
+ else if (idx > 0 && ptc.set_offset(mod, idx - 1, offset_val))
+ SERIAL_ECHOLNPGM("Set value: ", offset_val);
+ else
+ SERIAL_ECHOLNPGM("!Invalid index. Failed to set value (note: value at index 0 is constant).");
+ }
+ else // Print current Z-probe adjustments. Note: Values in EEPROM might differ.
+ ptc.print_offsets();
+}
+
+#endif // HAS_PTC
diff --git a/Marlin/src/gcode/calibrate/M100.cpp b/Marlin/src/gcode/calibrate/M100.cpp
index ee572e033d755..338392b59746a 100644
--- a/Marlin/src/gcode/calibrate/M100.cpp
+++ b/Marlin/src/gcode/calibrate/M100.cpp
@@ -51,7 +51,7 @@
* Also, there are two support functions that can be called from a developer's C code.
*
* uint16_t check_for_free_memory_corruption(PGM_P const free_memory_start);
- * void M100_dump_routine(PGM_P const title, const char * const start, const uintptr_t size);
+ * void M100_dump_routine(FSTR_P const title, const char * const start, const uintptr_t size);
*
* Initial version by Roxy-3D
*/
@@ -182,8 +182,8 @@ inline int32_t count_test_bytes(const char * const start_free_memory) {
}
}
- void M100_dump_routine(PGM_P const title, const char * const start, const uintptr_t size) {
- SERIAL_ECHOLNPGM_P(title);
+ void M100_dump_routine(FSTR_P const title, const char * const start, const uintptr_t size) {
+ SERIAL_ECHOLNF(title);
//
// Round the start and end locations to produce full lines of output
//
@@ -196,13 +196,13 @@ inline int32_t count_test_bytes(const char * const start_free_memory) {
#endif // M100_FREE_MEMORY_DUMPER
-inline int check_for_free_memory_corruption(PGM_P const title) {
- SERIAL_ECHOPGM_P(title);
+inline int check_for_free_memory_corruption(FSTR_P const title) {
+ SERIAL_ECHOF(title);
char *start_free_memory = free_memory_start, *end_free_memory = free_memory_end;
int n = end_free_memory - start_free_memory;
- SERIAL_ECHOLNPAIR("\nfmc() n=", n,
+ SERIAL_ECHOLNPGM("\nfmc() n=", n,
"\nfree_memory_start=", hex_address(free_memory_start),
" end=", hex_address(end_free_memory));
@@ -217,7 +217,7 @@ inline int check_for_free_memory_corruption(PGM_P const title) {
// idle();
serial_delay(20);
#if ENABLED(M100_FREE_MEMORY_DUMPER)
- M100_dump_routine(PSTR(" Memory corruption detected with end_free_memory 8) {
- //SERIAL_ECHOPAIR("Found ", j);
- //SERIAL_ECHOLNPAIR(" bytes free at ", hex_address(start_free_memory + i));
+ //SERIAL_ECHOPGM("Found ", j);
+ //SERIAL_ECHOLNPGM(" bytes free at ", hex_address(start_free_memory + i));
i += j;
block_cnt++;
- SERIAL_ECHOLNPAIR(" (", block_cnt, ") found=", j);
+ SERIAL_ECHOLNPGM(" (", block_cnt, ") found=", j);
}
}
}
- SERIAL_ECHOPAIR(" block_found=", block_cnt);
+ SERIAL_ECHOPGM(" block_found=", block_cnt);
if (block_cnt != 1)
SERIAL_ECHOLNPGM("\nMemory Corruption detected in free memory area.");
@@ -267,7 +267,7 @@ inline void free_memory_pool_report(char * const start_free_memory, const int32_
if (*addr == TEST_BYTE) {
const int32_t j = count_test_bytes(addr);
if (j > 8) {
- SERIAL_ECHOLNPAIR("Found ", j, " bytes free at ", hex_address(addr));
+ SERIAL_ECHOLNPGM("Found ", j, " bytes free at ", hex_address(addr));
if (j > max_cnt) {
max_cnt = j;
max_addr = addr;
@@ -277,11 +277,11 @@ inline void free_memory_pool_report(char * const start_free_memory, const int32_
}
}
}
- if (block_cnt > 1) SERIAL_ECHOLNPAIR(
+ if (block_cnt > 1) SERIAL_ECHOLNPGM(
"\nMemory Corruption detected in free memory area."
"\nLargest free block is ", max_cnt, " bytes at ", hex_address(max_addr)
);
- SERIAL_ECHOLNPAIR("check_for_free_memory_corruption() = ", check_for_free_memory_corruption(PSTR("M100 F ")));
+ SERIAL_ECHOLNPGM("check_for_free_memory_corruption() = ", check_for_free_memory_corruption(F("M100 F ")));
}
#if ENABLED(M100_FREE_MEMORY_CORRUPTOR)
@@ -299,7 +299,7 @@ inline void free_memory_pool_report(char * const start_free_memory, const int32_
for (uint32_t i = 1; i <= size; i++) {
char * const addr = start_free_memory + i * j;
*addr = i;
- SERIAL_ECHOPAIR("\nCorrupting address: ", hex_address(addr));
+ SERIAL_ECHOPGM("\nCorrupting address: ", hex_address(addr));
}
SERIAL_EOL();
}
@@ -327,8 +327,8 @@ inline void init_free_memory(char *start_free_memory, int32_t size) {
for (int32_t i = 0; i < size; i++) {
if (start_free_memory[i] != TEST_BYTE) {
- SERIAL_ECHOPAIR("? address : ", hex_address(start_free_memory + i));
- SERIAL_ECHOLNPAIR("=", hex_byte(start_free_memory[i]));
+ SERIAL_ECHOPGM("? address : ", hex_address(start_free_memory + i));
+ SERIAL_ECHOLNPGM("=", hex_byte(start_free_memory[i]));
SERIAL_EOL();
}
}
@@ -340,14 +340,14 @@ inline void init_free_memory(char *start_free_memory, int32_t size) {
void GcodeSuite::M100() {
char *sp = top_of_stack();
if (!free_memory_end) free_memory_end = sp - MEMORY_END_CORRECTION;
- SERIAL_ECHOPAIR("\nbss_end : ", hex_address(end_bss));
- if (heaplimit) SERIAL_ECHOPAIR("\n__heaplimit : ", hex_address(heaplimit));
- SERIAL_ECHOPAIR("\nfree_memory_start : ", hex_address(free_memory_start));
- if (stacklimit) SERIAL_ECHOPAIR("\n__stacklimit : ", hex_address(stacklimit));
- SERIAL_ECHOPAIR("\nfree_memory_end : ", hex_address(free_memory_end));
+ SERIAL_ECHOPGM("\nbss_end : ", hex_address(end_bss));
+ if (heaplimit) SERIAL_ECHOPGM("\n__heaplimit : ", hex_address(heaplimit));
+ SERIAL_ECHOPGM("\nfree_memory_start : ", hex_address(free_memory_start));
+ if (stacklimit) SERIAL_ECHOPGM("\n__stacklimit : ", hex_address(stacklimit));
+ SERIAL_ECHOPGM("\nfree_memory_end : ", hex_address(free_memory_end));
if (MEMORY_END_CORRECTION)
- SERIAL_ECHOPAIR("\nMEMORY_END_CORRECTION : ", MEMORY_END_CORRECTION);
- SERIAL_ECHOLNPAIR("\nStack Pointer : ", hex_address(sp));
+ SERIAL_ECHOPGM("\nMEMORY_END_CORRECTION : ", MEMORY_END_CORRECTION);
+ SERIAL_ECHOLNPGM("\nStack Pointer : ", hex_address(sp));
// Always init on the first invocation of M100
static bool m100_not_initialized = true;
diff --git a/Marlin/src/gcode/calibrate/M12.cpp b/Marlin/src/gcode/calibrate/M12.cpp
index da244543754da..191ff22d7dd97 100644
--- a/Marlin/src/gcode/calibrate/M12.cpp
+++ b/Marlin/src/gcode/calibrate/M12.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER)
diff --git a/Marlin/src/gcode/calibrate/M425.cpp b/Marlin/src/gcode/calibrate/M425.cpp
index f30de00a0fdf8..190af0f71bbe0 100644
--- a/Marlin/src/gcode/calibrate/M425.cpp
+++ b/Marlin/src/gcode/calibrate/M425.cpp
@@ -86,7 +86,7 @@ void GcodeSuite::M425() {
SERIAL_ECHOPGM("Backlash Correction ");
if (!backlash.correction) SERIAL_ECHOPGM("in");
SERIAL_ECHOLNPGM("active:");
- SERIAL_ECHOLNPAIR(" Correction Amount/Fade-out: F", backlash.get_correction(), " (F1.0 = full, F0.0 = none)");
+ SERIAL_ECHOLNPGM(" Correction Amount/Fade-out: F", backlash.get_correction(), " (F1.0 = full, F0.0 = none)");
SERIAL_ECHOPGM(" Backlash Distance (mm): ");
LOOP_LINEAR_AXES(a) if (axis_can_calibrate(a)) {
SERIAL_CHAR(' ', AXIS_CHAR(a));
@@ -95,7 +95,7 @@ void GcodeSuite::M425() {
}
#ifdef BACKLASH_SMOOTHING_MM
- SERIAL_ECHOLNPAIR(" Smoothing (mm): S", backlash.smoothing_mm);
+ SERIAL_ECHOLNPGM(" Smoothing (mm): S", backlash.smoothing_mm);
#endif
#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
@@ -113,4 +113,22 @@ void GcodeSuite::M425() {
}
}
+void GcodeSuite::M425_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_BACKLASH_COMPENSATION));
+ SERIAL_ECHOLNPGM_P(
+ PSTR(" M425 F"), backlash.get_correction()
+ #ifdef BACKLASH_SMOOTHING_MM
+ , PSTR(" S"), LINEAR_UNIT(backlash.smoothing_mm)
+ #endif
+ , LIST_N(DOUBLE(LINEAR_AXES),
+ SP_X_STR, LINEAR_UNIT(backlash.distance_mm.x),
+ SP_Y_STR, LINEAR_UNIT(backlash.distance_mm.y),
+ SP_Z_STR, LINEAR_UNIT(backlash.distance_mm.z),
+ SP_I_STR, LINEAR_UNIT(backlash.distance_mm.i),
+ SP_J_STR, LINEAR_UNIT(backlash.distance_mm.j),
+ SP_K_STR, LINEAR_UNIT(backlash.distance_mm.k)
+ )
+ );
+}
+
#endif // BACKLASH_GCODE
diff --git a/Marlin/src/gcode/calibrate/M48.cpp b/Marlin/src/gcode/calibrate/M48.cpp
index 19b11f602a425..913ffe30d478c 100644
--- a/Marlin/src/gcode/calibrate/M48.cpp
+++ b/Marlin/src/gcode/calibrate/M48.cpp
@@ -79,7 +79,7 @@ void GcodeSuite::M48() {
};
if (!probe.can_reach(test_position)) {
- ui.set_status_P(GET_TEXT(MSG_M48_OUT_OF_BOUNDS), 99);
+ ui.set_status(GET_TEXT_F(MSG_M48_OUT_OF_BOUNDS), 99);
SERIAL_ECHOLNPGM("? (X,Y) out of bounds.");
return;
}
@@ -144,7 +144,7 @@ void GcodeSuite::M48() {
LOOP_L_N(n, n_samples) {
#if HAS_STATUS_MESSAGE
// Display M48 progress in the status bar
- ui.status_printf_P(0, PSTR(S_FMT ": %d/%d"), GET_TEXT(MSG_M48_POINT), int(n + 1), int(n_samples));
+ ui.status_printf(0, F(S_FMT ": %d/%d"), GET_TEXT(MSG_M48_POINT), int(n + 1), int(n_samples));
#endif
// When there are "legs" of movement move around the point before probing
@@ -162,7 +162,7 @@ void GcodeSuite::M48() {
#endif
);
if (verbose_level > 3) {
- SERIAL_ECHOPAIR("Start radius:", radius, " angle:", angle, " dir:");
+ SERIAL_ECHOPGM("Start radius:", radius, " angle:", angle, " dir:");
if (dir > 0) SERIAL_CHAR('C');
SERIAL_ECHOLNPGM("CW");
}
@@ -200,7 +200,7 @@ void GcodeSuite::M48() {
while (!probe.can_reach(next_pos)) {
next_pos *= 0.8f;
if (verbose_level > 3)
- SERIAL_ECHOLNPAIR_P(PSTR("Moving inward: X"), next_pos.x, SP_Y_STR, next_pos.y);
+ SERIAL_ECHOLNPGM_P(PSTR("Moving inward: X"), next_pos.x, SP_Y_STR, next_pos.y);
}
#elif HAS_ENDSTOPS
// For a rectangular bed just keep the probe in bounds
@@ -209,7 +209,7 @@ void GcodeSuite::M48() {
#endif
if (verbose_level > 3)
- SERIAL_ECHOLNPAIR_P(PSTR("Going to: X"), next_pos.x, SP_Y_STR, next_pos.y);
+ SERIAL_ECHOLNPGM_P(PSTR("Going to: X"), next_pos.x, SP_Y_STR, next_pos.y);
do_blocking_move_to_xy(next_pos);
} // n_legs loop
@@ -241,7 +241,7 @@ void GcodeSuite::M48() {
if (verbose_level > 1) {
SERIAL_ECHO(n + 1);
- SERIAL_ECHOPAIR(" of ", n_samples);
+ SERIAL_ECHOPGM(" of ", n_samples);
SERIAL_ECHOPAIR_F(": z: ", pz, 3);
SERIAL_CHAR(' ');
dev_report(verbose_level > 2, mean, sigma, min, max);
@@ -260,7 +260,7 @@ void GcodeSuite::M48() {
#if HAS_STATUS_MESSAGE
// Display M48 results in the status bar
char sigma_str[8];
- ui.status_printf_P(0, PSTR(S_FMT ": %s"), GET_TEXT(MSG_M48_DEVIATION), dtostrf(sigma, 2, 6, sigma_str));
+ ui.status_printf(0, F(S_FMT ": %s"), GET_TEXT(MSG_M48_DEVIATION), dtostrf(sigma, 2, 6, sigma_str));
#endif
}
diff --git a/Marlin/src/gcode/calibrate/M665.cpp b/Marlin/src/gcode/calibrate/M665.cpp
index 0d0c4146d931d..aa21471b6027e 100644
--- a/Marlin/src/gcode/calibrate/M665.cpp
+++ b/Marlin/src/gcode/calibrate/M665.cpp
@@ -30,6 +30,7 @@
#if ENABLED(DELTA)
#include "../../module/delta.h"
+
/**
* M665: Set delta configurations
*
@@ -45,6 +46,8 @@
* C = Gamma (Tower 3) diagonal rod trim
*/
void GcodeSuite::M665() {
+ if (!parser.seen_any()) return M665_report();
+
if (parser.seenval('H')) delta_height = parser.value_linear_units();
if (parser.seenval('L')) delta_diagonal_rod = parser.value_linear_units();
if (parser.seenval('R')) delta_radius = parser.value_linear_units();
@@ -58,6 +61,22 @@
recalc_delta_settings();
}
+ void GcodeSuite::M665_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_DELTA_SETTINGS));
+ SERIAL_ECHOLNPGM_P(
+ PSTR(" M665 L"), LINEAR_UNIT(delta_diagonal_rod)
+ , PSTR(" R"), LINEAR_UNIT(delta_radius)
+ , PSTR(" H"), LINEAR_UNIT(delta_height)
+ , PSTR(" S"), segments_per_second
+ , SP_X_STR, LINEAR_UNIT(delta_tower_angle_trim.a)
+ , SP_Y_STR, LINEAR_UNIT(delta_tower_angle_trim.b)
+ , SP_Z_STR, LINEAR_UNIT(delta_tower_angle_trim.c)
+ , PSTR(" A"), LINEAR_UNIT(delta_diagonal_rod_trim.a)
+ , PSTR(" B"), LINEAR_UNIT(delta_diagonal_rod_trim.b)
+ , PSTR(" C"), LINEAR_UNIT(delta_diagonal_rod_trim.c)
+ );
+ }
+
#elif IS_SCARA
#include "../../module/scara.h"
@@ -68,6 +87,9 @@
* Parameters:
*
* S[segments-per-second] - Segments-per-second
+ *
+ * Without NO_WORKSPACE_OFFSETS:
+ *
* P[theta-psi-offset] - Theta-Psi offset, added to the shoulder (A/X) angle
* T[theta-offset] - Theta offset, added to the elbow (B/Y) angle
* Z[z-offset] - Z offset, added to Z
@@ -76,6 +98,8 @@
* B, T, and Y are all aliases for the elbow angle
*/
void GcodeSuite::M665() {
+ if (!parser.seen_any()) return M665_report();
+
if (parser.seenval('S')) segments_per_second = parser.value_float();
#if HAS_SCARA_OFFSET
@@ -107,6 +131,41 @@
#endif // HAS_SCARA_OFFSET
}
+ void GcodeSuite::M665_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_SCARA_SETTINGS " (" STR_S_SEG_PER_SEC TERN_(HAS_SCARA_OFFSET, " " STR_SCARA_P_T_Z) ")"));
+ SERIAL_ECHOLNPGM_P(
+ PSTR(" M665 S"), segments_per_second
+ #if HAS_SCARA_OFFSET
+ , SP_P_STR, scara_home_offset.a
+ , SP_T_STR, scara_home_offset.b
+ , SP_Z_STR, LINEAR_UNIT(scara_home_offset.z)
+ #endif
+ );
+ }
+
+#elif ENABLED(POLARGRAPH)
+
+ #include "../../module/polargraph.h"
+
+ /**
+ * M665: Set POLARGRAPH settings
+ *
+ * Parameters:
+ *
+ * S[segments-per-second] - Segments-per-second
+ */
+ void GcodeSuite::M665() {
+ if (parser.seenval('S'))
+ segments_per_second = parser.value_float();
+ else
+ M665_report();
+ }
+
+ void GcodeSuite::M665_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_POLARGRAPH_SETTINGS " (" STR_S_SEG_PER_SEC ")"));
+ SERIAL_ECHOLNPGM(" M665 S", segments_per_second);
+ }
+
#endif
#endif // IS_KINEMATIC
diff --git a/Marlin/src/gcode/calibrate/M666.cpp b/Marlin/src/gcode/calibrate/M666.cpp
index 872344e4e9231..15f8baf109eb3 100644
--- a/Marlin/src/gcode/calibrate/M666.cpp
+++ b/Marlin/src/gcode/calibrate/M666.cpp
@@ -36,38 +36,6 @@
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
#include "../../core/debug_out.h"
-void M666_report(const bool forReplay=true) {
- if (!forReplay) { SERIAL_ECHOLNPGM("; Endstop adjustment:"); SERIAL_ECHO_START(); }
- #if ENABLED(DELTA)
- SERIAL_ECHOLNPAIR_P(
- PSTR(" M666 X"), LINEAR_UNIT(delta_endstop_adj.a)
- , SP_Y_STR, LINEAR_UNIT(delta_endstop_adj.b)
- , SP_Z_STR, LINEAR_UNIT(delta_endstop_adj.c)
- );
- #else
- SERIAL_ECHOPGM(" M666");
- #if ENABLED(X_DUAL_ENDSTOPS)
- SERIAL_ECHOLNPAIR_P(SP_X_STR, LINEAR_UNIT(endstops.x2_endstop_adj));
- #endif
- #if ENABLED(Y_DUAL_ENDSTOPS)
- SERIAL_ECHOLNPAIR_P(SP_Y_STR, LINEAR_UNIT(endstops.y2_endstop_adj));
- #endif
- #if ENABLED(Z_MULTI_ENDSTOPS)
- #if NUM_Z_STEPPER_DRIVERS >= 3
- SERIAL_ECHOPAIR(" S2 Z", LINEAR_UNIT(endstops.z3_endstop_adj));
- if (!forReplay) SERIAL_ECHO_START();
- SERIAL_ECHOPAIR(" M666 S3 Z", LINEAR_UNIT(endstops.z3_endstop_adj));
- #if NUM_Z_STEPPER_DRIVERS >= 4
- if (!forReplay) SERIAL_ECHO_START();
- SERIAL_ECHOPAIR(" M666 S4 Z", LINEAR_UNIT(endstops.z4_endstop_adj));
- #endif
- #else
- SERIAL_ECHOLNPAIR_P(SP_Z_STR, LINEAR_UNIT(endstops.z2_endstop_adj));
- #endif
- #endif
- #endif
-}
-
#if ENABLED(DELTA)
/**
@@ -84,14 +52,23 @@ void M666_report(const bool forReplay=true) {
is_err = true;
else {
delta_endstop_adj[i] = v;
- if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("delta_endstop_adj[", AS_CHAR(AXIS_CHAR(i)), "] = ", v);
+ if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("delta_endstop_adj[", AS_CHAR(AXIS_CHAR(i)), "] = ", v);
}
}
}
- if (is_err) SERIAL_ECHOLNPAIR("?M666 offsets must be <= 0");
+ if (is_err) SERIAL_ECHOLNPGM("?M666 offsets must be <= 0");
if (!is_set) M666_report();
}
+ void GcodeSuite::M666_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_ENDSTOP_ADJUSTMENT));
+ SERIAL_ECHOLNPGM_P(
+ PSTR(" M666 X"), LINEAR_UNIT(delta_endstop_adj.a)
+ , SP_Y_STR, LINEAR_UNIT(delta_endstop_adj.b)
+ , SP_Z_STR, LINEAR_UNIT(delta_endstop_adj.c)
+ );
+ }
+
#else
/**
@@ -105,6 +82,8 @@ void M666_report(const bool forReplay=true) {
* Set All: M666 Z
*/
void GcodeSuite::M666() {
+ if (!parser.seen_any()) return M666_report();
+
#if ENABLED(X_DUAL_ENDSTOPS)
if (parser.seenval('X')) endstops.x2_endstop_adj = parser.value_linear_units();
#endif
@@ -123,7 +102,30 @@ void M666_report(const bool forReplay=true) {
#endif
}
#endif
- if (!parser.seen("XYZ")) M666_report();
+ }
+
+ void GcodeSuite::M666_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_ENDSTOP_ADJUSTMENT));
+ SERIAL_ECHOPGM(" M666");
+ #if ENABLED(X_DUAL_ENDSTOPS)
+ SERIAL_ECHOLNPGM_P(SP_X_STR, LINEAR_UNIT(endstops.x2_endstop_adj));
+ #endif
+ #if ENABLED(Y_DUAL_ENDSTOPS)
+ SERIAL_ECHOLNPGM_P(SP_Y_STR, LINEAR_UNIT(endstops.y2_endstop_adj));
+ #endif
+ #if ENABLED(Z_MULTI_ENDSTOPS)
+ #if NUM_Z_STEPPER_DRIVERS >= 3
+ SERIAL_ECHOPGM(" S2 Z", LINEAR_UNIT(endstops.z3_endstop_adj));
+ report_echo_start(forReplay);
+ SERIAL_ECHOPGM(" M666 S3 Z", LINEAR_UNIT(endstops.z3_endstop_adj));
+ #if NUM_Z_STEPPER_DRIVERS >= 4
+ report_echo_start(forReplay);
+ SERIAL_ECHOPGM(" M666 S4 Z", LINEAR_UNIT(endstops.z4_endstop_adj));
+ #endif
+ #else
+ SERIAL_ECHOLNPGM_P(SP_Z_STR, LINEAR_UNIT(endstops.z2_endstop_adj));
+ #endif
+ #endif
}
#endif // HAS_EXTRA_ENDSTOPS
diff --git a/Marlin/src/gcode/calibrate/M852.cpp b/Marlin/src/gcode/calibrate/M852.cpp
index 73b18ad4665e9..b24a449652a37 100644
--- a/Marlin/src/gcode/calibrate/M852.cpp
+++ b/Marlin/src/gcode/calibrate/M852.cpp
@@ -36,10 +36,11 @@
* K[yz_factor] - New YZ skew factor
*/
void GcodeSuite::M852() {
- uint8_t ijk = 0, badval = 0, setval = 0;
+ if (!parser.seen("SIJK")) return M852_report();
- if (parser.seen('I') || parser.seen('S')) {
- ++ijk;
+ uint8_t badval = 0, setval = 0;
+
+ if (parser.seenval('I') || parser.seenval('S')) {
const float value = parser.value_linear_units();
if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) {
if (planner.skew_factor.xy != value) {
@@ -53,8 +54,7 @@ void GcodeSuite::M852() {
#if ENABLED(SKEW_CORRECTION_FOR_Z)
- if (parser.seen('J')) {
- ++ijk;
+ if (parser.seenval('J')) {
const float value = parser.value_linear_units();
if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) {
if (planner.skew_factor.xz != value) {
@@ -66,8 +66,7 @@ void GcodeSuite::M852() {
++badval;
}
- if (parser.seen('K')) {
- ++ijk;
+ if (parser.seenval('K')) {
const float value = parser.value_linear_units();
if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) {
if (planner.skew_factor.yz != value) {
@@ -90,17 +89,18 @@ void GcodeSuite::M852() {
sync_plan_position();
report_current_position();
}
+}
- if (!ijk) {
- SERIAL_ECHO_START();
- SERIAL_ECHOPGM("Skew Factor");
- SERIAL_ECHOPAIR_F(" XY: ", planner.skew_factor.xy, 6);
- #if ENABLED(SKEW_CORRECTION_FOR_Z)
- SERIAL_ECHOPAIR_F(" XZ: ", planner.skew_factor.xz, 6);
- SERIAL_ECHOPAIR_F(" YZ: ", planner.skew_factor.yz, 6);
- #endif
- SERIAL_EOL();
- }
+void GcodeSuite::M852_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_SKEW_FACTOR));
+ SERIAL_ECHOPAIR_F(" M851 I", planner.skew_factor.xy, 6);
+ #if ENABLED(SKEW_CORRECTION_FOR_Z)
+ SERIAL_ECHOPAIR_F(" J", planner.skew_factor.xz, 6);
+ SERIAL_ECHOPAIR_F(" K", planner.skew_factor.yz, 6);
+ SERIAL_ECHOLNPGM(" ; XY, XZ, YZ");
+ #else
+ SERIAL_ECHOLNPGM(" ; XY");
+ #endif
}
#endif // SKEW_CORRECTION_GCODE
diff --git a/Marlin/src/gcode/config/M200-M205.cpp b/Marlin/src/gcode/config/M200-M205.cpp
index a2bcb8bb86a86..7b7ce5e10d7f0 100644
--- a/Marlin/src/gcode/config/M200-M205.cpp
+++ b/Marlin/src/gcode/config/M200-M205.cpp
@@ -32,9 +32,14 @@
* T - Optional extruder number. Current extruder if omitted.
* D - Set filament diameter and enable. D0 disables volumetric.
* S - Turn volumetric ON or OFF.
+ *
+ * With VOLUMETRIC_EXTRUDER_LIMIT:
+ *
* L - Volumetric extruder limit (in mm^3/sec). L0 disables the limit.
*/
void GcodeSuite::M200() {
+ if (!parser.seen("DST" TERN_(VOLUMETRIC_EXTRUDER_LIMIT, "L")))
+ return M200_report();
const int8_t target_extruder = get_target_extruder_from_command();
if (target_extruder < 0) return;
@@ -69,6 +74,37 @@
planner.calculate_volumetric_multipliers();
}
+ void GcodeSuite::M200_report(const bool forReplay/*=true*/) {
+ if (!forReplay) {
+ report_heading(forReplay, F(STR_FILAMENT_SETTINGS), false);
+ if (!parser.volumetric_enabled) SERIAL_ECHOPGM(" (Disabled):");
+ SERIAL_EOL();
+ report_echo_start(forReplay);
+ }
+
+ #if EXTRUDERS == 1
+ {
+ SERIAL_ECHOLNPGM(
+ " M200 S", parser.volumetric_enabled, " D", LINEAR_UNIT(planner.filament_size[0])
+ #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
+ , " L", LINEAR_UNIT(planner.volumetric_extruder_limit[0])
+ #endif
+ );
+ }
+ #else
+ SERIAL_ECHOLNPGM(" M200 S", parser.volumetric_enabled);
+ LOOP_L_N(i, EXTRUDERS) {
+ report_echo_start(forReplay);
+ SERIAL_ECHOLNPGM(
+ " M200 T", i, " D", LINEAR_UNIT(planner.filament_size[i])
+ #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
+ , " L", LINEAR_UNIT(planner.volumetric_extruder_limit[i])
+ #endif
+ );
+ }
+ #endif
+ }
+
#endif // !NO_VOLUMETRICS
/**
@@ -77,6 +113,8 @@
* With multiple extruders use T to specify which one.
*/
void GcodeSuite::M201() {
+ if (!parser.seen("T" LOGICAL_AXES_STRING))
+ return M201_report();
const int8_t target_extruder = get_target_extruder_from_command();
if (target_extruder < 0) return;
@@ -94,12 +132,40 @@ void GcodeSuite::M201() {
}
}
+void GcodeSuite::M201_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_MAX_ACCELERATION));
+ SERIAL_ECHOLNPGM_P(
+ LIST_N(DOUBLE(LINEAR_AXES),
+ PSTR(" M201 X"), LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[X_AXIS]),
+ SP_Y_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Y_AXIS]),
+ SP_Z_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Z_AXIS]),
+ SP_I_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[I_AXIS]),
+ SP_J_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[J_AXIS]),
+ SP_K_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[K_AXIS])
+ )
+ #if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
+ , SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_acceleration_mm_per_s2[E_AXIS])
+ #endif
+ );
+ #if ENABLED(DISTINCT_E_FACTORS)
+ LOOP_L_N(i, E_STEPPERS) {
+ report_echo_start(forReplay);
+ SERIAL_ECHOLNPGM_P(
+ PSTR(" M201 T"), i
+ , SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(i)])
+ );
+ }
+ #endif
+}
+
/**
* M203: Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in units/sec
*
* With multiple extruders use T to specify which one.
*/
void GcodeSuite::M203() {
+ if (!parser.seen("T" LOGICAL_AXES_STRING))
+ return M203_report();
const int8_t target_extruder = get_target_extruder_from_command();
if (target_extruder < 0) return;
@@ -111,6 +177,32 @@ void GcodeSuite::M203() {
}
}
+void GcodeSuite::M203_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_MAX_FEEDRATES));
+ SERIAL_ECHOLNPGM_P(
+ LIST_N(DOUBLE(LINEAR_AXES),
+ PSTR(" M203 X"), LINEAR_UNIT(planner.settings.max_feedrate_mm_s[X_AXIS]),
+ SP_Y_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Y_AXIS]),
+ SP_Z_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Z_AXIS]),
+ SP_I_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[I_AXIS]),
+ SP_J_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[J_AXIS]),
+ SP_K_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[K_AXIS])
+ )
+ #if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
+ , SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_feedrate_mm_s[E_AXIS])
+ #endif
+ );
+ #if ENABLED(DISTINCT_E_FACTORS)
+ LOOP_L_N(i, E_STEPPERS) {
+ SERIAL_ECHO_START();
+ SERIAL_ECHOLNPGM_P(
+ PSTR(" M203 T"), i
+ , SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_feedrate_mm_s[E_AXIS_N(i)])
+ );
+ }
+ #endif
+}
+
/**
* M204: Set Accelerations in units/sec^2 (M204 P1200 R3000 T3000)
*
@@ -119,11 +211,8 @@ void GcodeSuite::M203() {
* T = Travel (non printing) moves
*/
void GcodeSuite::M204() {
- if (!parser.seen("PRST")) {
- SERIAL_ECHOPAIR("Acceleration: P", planner.settings.acceleration);
- SERIAL_ECHOPAIR(" R", planner.settings.retract_acceleration);
- SERIAL_ECHOLNPAIR_P(SP_T_STR, planner.settings.travel_acceleration);
- }
+ if (!parser.seen("PRST"))
+ return M204_report();
else {
//planner.synchronize();
// 'S' for legacy compatibility. Should NOT BE USED for new development
@@ -134,6 +223,15 @@ void GcodeSuite::M204() {
}
}
+void GcodeSuite::M204_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_ACCELERATION_P_R_T));
+ SERIAL_ECHOLNPGM_P(
+ PSTR(" M204 P"), LINEAR_UNIT(planner.settings.acceleration)
+ , PSTR(" R"), LINEAR_UNIT(planner.settings.retract_acceleration)
+ , SP_T_STR, LINEAR_UNIT(planner.settings.travel_acceleration)
+ );
+}
+
/**
* M205: Set Advanced Settings
*
@@ -147,7 +245,8 @@ void GcodeSuite::M204() {
* J = Junction Deviation (mm) (If not using CLASSIC_JERK)
*/
void GcodeSuite::M205() {
- if (!parser.seen("BST" TERN_(HAS_JUNCTION_DEVIATION, "J") TERN_(HAS_CLASSIC_JERK, "XYZE"))) return;
+ if (!parser.seen("BST" TERN_(HAS_JUNCTION_DEVIATION, "J") TERN_(HAS_CLASSIC_JERK, "XYZE")))
+ return M205_report();
//planner.synchronize();
if (parser.seenval('B')) planner.settings.min_segment_time_us = parser.value_ulong();
@@ -184,3 +283,34 @@ void GcodeSuite::M205() {
#endif
#endif // HAS_CLASSIC_JERK
}
+
+void GcodeSuite::M205_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(
+ "Advanced (B S T"
+ TERN_(HAS_JUNCTION_DEVIATION, " J")
+ TERN_(HAS_CLASSIC_JERK, " X Y Z")
+ TERN_(HAS_CLASSIC_E_JERK, " E")
+ ")"
+ ));
+ SERIAL_ECHOLNPGM_P(
+ PSTR(" M205 B"), LINEAR_UNIT(planner.settings.min_segment_time_us)
+ , PSTR(" S"), LINEAR_UNIT(planner.settings.min_feedrate_mm_s)
+ , SP_T_STR, LINEAR_UNIT(planner.settings.min_travel_feedrate_mm_s)
+ #if HAS_JUNCTION_DEVIATION
+ , PSTR(" J"), LINEAR_UNIT(planner.junction_deviation_mm)
+ #endif
+ #if HAS_CLASSIC_JERK
+ , LIST_N(DOUBLE(LINEAR_AXES),
+ SP_X_STR, LINEAR_UNIT(planner.max_jerk.x),
+ SP_Y_STR, LINEAR_UNIT(planner.max_jerk.y),
+ SP_Z_STR, LINEAR_UNIT(planner.max_jerk.z),
+ SP_I_STR, LINEAR_UNIT(planner.max_jerk.i),
+ SP_J_STR, LINEAR_UNIT(planner.max_jerk.j),
+ SP_K_STR, LINEAR_UNIT(planner.max_jerk.k)
+ )
+ #if HAS_CLASSIC_E_JERK
+ , SP_E_STR, LINEAR_UNIT(planner.max_jerk.e)
+ #endif
+ #endif
+ );
+}
diff --git a/Marlin/src/gcode/config/M217.cpp b/Marlin/src/gcode/config/M217.cpp
index 2035ae55abeb1..7576272a48b6b 100644
--- a/Marlin/src/gcode/config/M217.cpp
+++ b/Marlin/src/gcode/config/M217.cpp
@@ -33,44 +33,6 @@
#include "../../MarlinCore.h" // for SP_X_STR, etc.
-void M217_report(const bool eeprom=false) {
-
- #if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
- SERIAL_ECHOPGM_P(eeprom ? PSTR(" M217") : PSTR("Toolchange:"));
- SERIAL_ECHOPAIR(" S", LINEAR_UNIT(toolchange_settings.swap_length));
- SERIAL_ECHOPAIR_P(SP_B_STR, LINEAR_UNIT(toolchange_settings.extra_resume),
- SP_E_STR, LINEAR_UNIT(toolchange_settings.extra_prime),
- SP_P_STR, LINEAR_UNIT(toolchange_settings.prime_speed));
- SERIAL_ECHOPAIR(" R", LINEAR_UNIT(toolchange_settings.retract_speed),
- " U", LINEAR_UNIT(toolchange_settings.unretract_speed),
- " F", toolchange_settings.fan_speed,
- " G", toolchange_settings.fan_time);
-
- #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
- SERIAL_ECHOPAIR(" A", migration.automode);
- SERIAL_ECHOPAIR(" L", LINEAR_UNIT(migration.last));
- #endif
-
- #if ENABLED(TOOLCHANGE_PARK)
- SERIAL_ECHOPAIR(" W", LINEAR_UNIT(toolchange_settings.enable_park));
- SERIAL_ECHOPAIR_P(SP_X_STR, LINEAR_UNIT(toolchange_settings.change_point.x));
- SERIAL_ECHOPAIR_P(SP_Y_STR, LINEAR_UNIT(toolchange_settings.change_point.y));
- #endif
-
- #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
- SERIAL_ECHOPAIR(" V", LINEAR_UNIT(enable_first_prime));
- #endif
-
- #else
-
- UNUSED(eeprom);
-
- #endif
-
- SERIAL_ECHOPAIR_P(SP_Z_STR, LINEAR_UNIT(toolchange_settings.z_raise));
- SERIAL_EOL();
-}
-
/**
* M217 - Set SINGLENOZZLE toolchange parameters
*
@@ -168,4 +130,39 @@ void GcodeSuite::M217() {
M217_report();
}
+void GcodeSuite::M217_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_TOOL_CHANGING));
+
+ SERIAL_ECHOPGM(" M217");
+
+ #if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
+ SERIAL_ECHOPGM(" S", LINEAR_UNIT(toolchange_settings.swap_length));
+ SERIAL_ECHOPGM_P(SP_B_STR, LINEAR_UNIT(toolchange_settings.extra_resume),
+ SP_E_STR, LINEAR_UNIT(toolchange_settings.extra_prime),
+ SP_P_STR, LINEAR_UNIT(toolchange_settings.prime_speed));
+ SERIAL_ECHOPGM(" R", LINEAR_UNIT(toolchange_settings.retract_speed),
+ " U", LINEAR_UNIT(toolchange_settings.unretract_speed),
+ " F", toolchange_settings.fan_speed,
+ " G", toolchange_settings.fan_time);
+
+ #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
+ SERIAL_ECHOPGM(" A", migration.automode);
+ SERIAL_ECHOPGM(" L", LINEAR_UNIT(migration.last));
+ #endif
+
+ #if ENABLED(TOOLCHANGE_PARK)
+ SERIAL_ECHOPGM(" W", LINEAR_UNIT(toolchange_settings.enable_park));
+ SERIAL_ECHOPGM_P(SP_X_STR, LINEAR_UNIT(toolchange_settings.change_point.x));
+ SERIAL_ECHOPGM_P(SP_Y_STR, LINEAR_UNIT(toolchange_settings.change_point.y));
+ #endif
+
+ #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
+ SERIAL_ECHOPGM(" V", LINEAR_UNIT(enable_first_prime));
+ #endif
+
+ #endif
+
+ SERIAL_ECHOLNPGM_P(SP_Z_STR, LINEAR_UNIT(toolchange_settings.z_raise));
+}
+
#endif // HAS_MULTI_EXTRUDER
diff --git a/Marlin/src/gcode/config/M218.cpp b/Marlin/src/gcode/config/M218.cpp
index 7701320e9eae0..c39447a28d380 100644
--- a/Marlin/src/gcode/config/M218.cpp
+++ b/Marlin/src/gcode/config/M218.cpp
@@ -41,6 +41,8 @@
*/
void GcodeSuite::M218() {
+ if (!parser.seen_any()) return M218_report();
+
const int8_t target_extruder = get_target_extruder_from_command();
if (target_extruder < 0) return;
@@ -48,24 +50,23 @@ void GcodeSuite::M218() {
if (parser.seenval('Y')) hotend_offset[target_extruder].y = parser.value_linear_units();
if (parser.seenval('Z')) hotend_offset[target_extruder].z = parser.value_linear_units();
- if (!parser.seen("XYZ")) {
- SERIAL_ECHO_START();
- SERIAL_ECHOPGM(STR_HOTEND_OFFSET);
- HOTEND_LOOP() {
- SERIAL_CHAR(' ');
- SERIAL_ECHO(hotend_offset[e].x);
- SERIAL_CHAR(',');
- SERIAL_ECHO(hotend_offset[e].y);
- SERIAL_CHAR(',');
- SERIAL_ECHO_F(hotend_offset[e].z, 3);
- }
- SERIAL_EOL();
- }
-
#if ENABLED(DELTA)
if (target_extruder == active_extruder)
do_blocking_move_to_xy(current_position, planner.settings.max_feedrate_mm_s[X_AXIS]);
#endif
}
+void GcodeSuite::M218_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_HOTEND_OFFSETS));
+ LOOP_S_L_N(e, 1, HOTENDS) {
+ report_echo_start(forReplay);
+ SERIAL_ECHOPGM_P(
+ PSTR(" M218 T"), e,
+ SP_X_STR, LINEAR_UNIT(hotend_offset[e].x),
+ SP_Y_STR, LINEAR_UNIT(hotend_offset[e].y)
+ );
+ SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, LINEAR_UNIT(hotend_offset[e].z), 3);
+ }
+}
+
#endif // HAS_HOTEND_OFFSET
diff --git a/Marlin/src/gcode/config/M220.cpp b/Marlin/src/gcode/config/M220.cpp
index 75339f10b9fc8..c9070df803b89 100644
--- a/Marlin/src/gcode/config/M220.cpp
+++ b/Marlin/src/gcode/config/M220.cpp
@@ -44,7 +44,7 @@ void GcodeSuite::M220() {
if (parser.seenval('S')) feedrate_percentage = parser.value_int();
if (!parser.seen_any()) {
- SERIAL_ECHOPAIR("FR:", feedrate_percentage);
+ SERIAL_ECHOPGM("FR:", feedrate_percentage);
SERIAL_CHAR('%');
SERIAL_EOL();
}
diff --git a/Marlin/src/gcode/config/M221.cpp b/Marlin/src/gcode/config/M221.cpp
index e380bfb1c7d0f..f653aded7c165 100644
--- a/Marlin/src/gcode/config/M221.cpp
+++ b/Marlin/src/gcode/config/M221.cpp
@@ -38,7 +38,7 @@ void GcodeSuite::M221() {
else {
SERIAL_ECHO_START();
SERIAL_CHAR('E', '0' + target_extruder);
- SERIAL_ECHOPAIR(" Flow: ", planner.flow_percentage[target_extruder]);
+ SERIAL_ECHOPGM(" Flow: ", planner.flow_percentage[target_extruder]);
SERIAL_CHAR('%');
SERIAL_EOL();
}
diff --git a/Marlin/src/gcode/config/M281.cpp b/Marlin/src/gcode/config/M281.cpp
index eeb0fcc470e1b..b90de6be30f9f 100644
--- a/Marlin/src/gcode/config/M281.cpp
+++ b/Marlin/src/gcode/config/M281.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#include "../../inc/MarlinConfig.h"
#if ENABLED(EDITABLE_SERVO_ANGLES)
@@ -34,6 +35,7 @@
* U - Stowed Angle
*/
void GcodeSuite::M281() {
+ if (!parser.seen_any()) return M281_report();
if (!parser.seenval('P')) return;
@@ -45,24 +47,32 @@ void GcodeSuite::M281() {
return;
}
#endif
- bool angle_change = false;
- if (parser.seen('L')) {
- servo_angles[servo_index][0] = parser.value_int();
- angle_change = true;
- }
- if (parser.seen('U')) {
- servo_angles[servo_index][1] = parser.value_int();
- angle_change = true;
- }
- if (!angle_change) {
- SERIAL_ECHO_MSG(" Servo ", servo_index,
- " L", servo_angles[servo_index][0],
- " U", servo_angles[servo_index][1]);
- }
+ if (parser.seen('L')) servo_angles[servo_index][0] = parser.value_int();
+ if (parser.seen('U')) servo_angles[servo_index][1] = parser.value_int();
}
else
SERIAL_ERROR_MSG("Servo ", servo_index, " out of range");
+}
+void GcodeSuite::M281_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_SERVO_ANGLES));
+ LOOP_L_N(i, NUM_SERVOS) {
+ switch (i) {
+ default: break;
+ #if ENABLED(SWITCHING_EXTRUDER)
+ case SWITCHING_EXTRUDER_SERVO_NR:
+ #if EXTRUDERS > 3
+ case SWITCHING_EXTRUDER_E23_SERVO_NR:
+ #endif
+ #elif ENABLED(SWITCHING_NOZZLE)
+ case SWITCHING_NOZZLE_SERVO_NR:
+ #elif ENABLED(BLTOUCH) || (HAS_Z_SERVO_PROBE && defined(Z_SERVO_ANGLES))
+ case Z_PROBE_SERVO_NR:
+ #endif
+ report_echo_start(forReplay);
+ SERIAL_ECHOLNPGM(" M281 P", i, " L", servo_angles[i][0], " U", servo_angles[i][1]);
+ }
+ }
}
#endif // EDITABLE_SERVO_ANGLES
diff --git a/Marlin/src/gcode/config/M301.cpp b/Marlin/src/gcode/config/M301.cpp
index 7b3f57608bad0..fc9f1883d6161 100644
--- a/Marlin/src/gcode/config/M301.cpp
+++ b/Marlin/src/gcode/config/M301.cpp
@@ -46,46 +46,64 @@
* F[float] Kf term
*/
void GcodeSuite::M301() {
-
// multi-extruder PID patch: M301 updates or prints a single extruder's PID values
// default behavior (omitting E parameter) is to update for extruder 0 only
- const uint8_t e = parser.byteval('E'); // extruder being updated
+ int8_t e = E_TERN0(parser.byteval('E', -1)); // extruder being updated
+
+ if (!parser.seen("PID" TERN_(PID_EXTRUSION_SCALING, "CL") TERN_(PID_FAN_SCALING, "F")))
+ return M301_report(true E_OPTARG(e));
+
+ if (e == -1) e = 0;
if (e < HOTENDS) { // catch bad input value
- if (parser.seen('P')) PID_PARAM(Kp, e) = parser.value_float();
- if (parser.seen('I')) PID_PARAM(Ki, e) = scalePID_i(parser.value_float());
- if (parser.seen('D')) PID_PARAM(Kd, e) = scalePID_d(parser.value_float());
+
+ if (parser.seenval('P')) PID_PARAM(Kp, e) = parser.value_float();
+ if (parser.seenval('I')) PID_PARAM(Ki, e) = scalePID_i(parser.value_float());
+ if (parser.seenval('D')) PID_PARAM(Kd, e) = scalePID_d(parser.value_float());
+
#if ENABLED(PID_EXTRUSION_SCALING)
- if (parser.seen('C')) PID_PARAM(Kc, e) = parser.value_float();
+ if (parser.seenval('C')) PID_PARAM(Kc, e) = parser.value_float();
if (parser.seenval('L')) thermalManager.lpq_len = parser.value_int();
NOMORE(thermalManager.lpq_len, LPQ_MAX_LEN);
NOLESS(thermalManager.lpq_len, 0);
#endif
#if ENABLED(PID_FAN_SCALING)
- if (parser.seen('F')) PID_PARAM(Kf, e) = parser.value_float();
+ if (parser.seenval('F')) PID_PARAM(Kf, e) = parser.value_float();
#endif
thermalManager.updatePID();
-
- SERIAL_ECHO_START();
- #if ENABLED(PID_PARAMS_PER_HOTEND)
- SERIAL_ECHOPAIR(" e:", e); // specify extruder in serial output
- #endif
- SERIAL_ECHOPAIR(" p:", PID_PARAM(Kp, e),
- " i:", unscalePID_i(PID_PARAM(Ki, e)),
- " d:", unscalePID_d(PID_PARAM(Kd, e)));
- #if ENABLED(PID_EXTRUSION_SCALING)
- SERIAL_ECHOPAIR(" c:", PID_PARAM(Kc, e));
- #endif
- #if ENABLED(PID_FAN_SCALING)
- SERIAL_ECHOPAIR(" f:", PID_PARAM(Kf, e));
- #endif
-
- SERIAL_EOL();
}
else
SERIAL_ERROR_MSG(STR_INVALID_EXTRUDER);
}
+void GcodeSuite::M301_report(const bool forReplay/*=true*/ E_OPTARG(const int8_t eindex/*=-1*/)) {
+ report_heading(forReplay, F(STR_HOTEND_PID));
+ IF_DISABLED(HAS_MULTI_EXTRUDER, constexpr int8_t eindex = -1);
+ HOTEND_LOOP() {
+ if (e == eindex || eindex == -1) {
+ report_echo_start(forReplay);
+ SERIAL_ECHOPGM_P(
+ #if ENABLED(PID_PARAMS_PER_HOTEND)
+ PSTR(" M301 E"), e, SP_P_STR
+ #else
+ PSTR(" M301 P")
+ #endif
+ , PID_PARAM(Kp, e)
+ , PSTR(" I"), unscalePID_i(PID_PARAM(Ki, e))
+ , PSTR(" D"), unscalePID_d(PID_PARAM(Kd, e))
+ );
+ #if ENABLED(PID_EXTRUSION_SCALING)
+ SERIAL_ECHOPGM_P(SP_C_STR, PID_PARAM(Kc, e));
+ if (e == 0) SERIAL_ECHOPGM(" L", thermalManager.lpq_len);
+ #endif
+ #if ENABLED(PID_FAN_SCALING)
+ SERIAL_ECHOPGM(" F", PID_PARAM(Kf, e));
+ #endif
+ SERIAL_EOL();
+ }
+ }
+}
+
#endif // PIDTEMP
diff --git a/Marlin/src/gcode/config/M302.cpp b/Marlin/src/gcode/config/M302.cpp
index e3ce5a10ef0e3..e271dcd469eee 100644
--- a/Marlin/src/gcode/config/M302.cpp
+++ b/Marlin/src/gcode/config/M302.cpp
@@ -55,8 +55,8 @@ void GcodeSuite::M302() {
// Report current state
SERIAL_ECHO_START();
SERIAL_ECHOPGM("Cold extrudes are ");
- SERIAL_ECHOPGM_P(thermalManager.allow_cold_extrude ? PSTR("en") : PSTR("dis"));
- SERIAL_ECHOLNPAIR("abled (min temp ", thermalManager.extrude_min_temp, "C)");
+ SERIAL_ECHOF(thermalManager.allow_cold_extrude ? F("en") : F("dis"));
+ SERIAL_ECHOLNPGM("abled (min temp ", thermalManager.extrude_min_temp, "C)");
}
}
diff --git a/Marlin/src/gcode/config/M304.cpp b/Marlin/src/gcode/config/M304.cpp
index b1af5a5ae21f4..97dc4be25e1c8 100644
--- a/Marlin/src/gcode/config/M304.cpp
+++ b/Marlin/src/gcode/config/M304.cpp
@@ -35,15 +35,19 @@
* D - Set the D value
*/
void GcodeSuite::M304() {
-
+ if (!parser.seen("PID")) return M304_report();
if (parser.seen('P')) thermalManager.temp_bed.pid.Kp = parser.value_float();
if (parser.seen('I')) thermalManager.temp_bed.pid.Ki = scalePID_i(parser.value_float());
if (parser.seen('D')) thermalManager.temp_bed.pid.Kd = scalePID_d(parser.value_float());
+}
- SERIAL_ECHO_MSG(" p:", thermalManager.temp_bed.pid.Kp,
- " i:", unscalePID_i(thermalManager.temp_bed.pid.Ki),
- " d:", unscalePID_d(thermalManager.temp_bed.pid.Kd));
-
+void GcodeSuite::M304_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_BED_PID));
+ SERIAL_ECHOLNPGM(
+ " M304 P", thermalManager.temp_bed.pid.Kp
+ , " I", unscalePID_i(thermalManager.temp_bed.pid.Ki)
+ , " D", unscalePID_d(thermalManager.temp_bed.pid.Kd)
+ );
}
#endif // PIDTEMPBED
diff --git a/Marlin/src/gcode/config/M305.cpp b/Marlin/src/gcode/config/M305.cpp
index 10ef55c173417..6957eef050dd7 100644
--- a/Marlin/src/gcode/config/M305.cpp
+++ b/Marlin/src/gcode/config/M305.cpp
@@ -70,10 +70,10 @@ void GcodeSuite::M305() {
} // If not setting then report parameters
else if (t_index < 0) { // ...all user thermistors
LOOP_L_N(i, USER_THERMISTORS)
- thermalManager.log_user_thermistor(i);
+ thermalManager.M305_report(i);
}
else // ...one user thermistor
- thermalManager.log_user_thermistor(t_index);
+ thermalManager.M305_report(t_index);
}
#endif // HAS_USER_THERMISTORS
diff --git a/Marlin/src/gcode/config/M309.cpp b/Marlin/src/gcode/config/M309.cpp
index 2247481b25798..577023292e2d4 100644
--- a/Marlin/src/gcode/config/M309.cpp
+++ b/Marlin/src/gcode/config/M309.cpp
@@ -35,14 +35,19 @@
* D - Set the D value
*/
void GcodeSuite::M309() {
+ if (!parser.seen("PID")) return M309_report();
if (parser.seen('P')) thermalManager.temp_chamber.pid.Kp = parser.value_float();
if (parser.seen('I')) thermalManager.temp_chamber.pid.Ki = scalePID_i(parser.value_float());
if (parser.seen('D')) thermalManager.temp_chamber.pid.Kd = scalePID_d(parser.value_float());
+}
- SERIAL_ECHO_START();
- SERIAL_ECHOLNPAIR(" p:", thermalManager.temp_chamber.pid.Kp,
- " i:", unscalePID_i(thermalManager.temp_chamber.pid.Ki),
- " d:", unscalePID_d(thermalManager.temp_chamber.pid.Kd));
+void GcodeSuite::M309_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_CHAMBER_PID));
+ SERIAL_ECHOLNPGM(
+ " M309 P", thermalManager.temp_chamber.pid.Kp
+ , " I", unscalePID_i(thermalManager.temp_chamber.pid.Ki)
+ , " D", unscalePID_d(thermalManager.temp_chamber.pid.Kd)
+ );
}
#endif // PIDTEMPCHAMBER
diff --git a/Marlin/src/gcode/config/M43.cpp b/Marlin/src/gcode/config/M43.cpp
index 84757e7403706..097aa142f03f2 100644
--- a/Marlin/src/gcode/config/M43.cpp
+++ b/Marlin/src/gcode/config/M43.cpp
@@ -65,12 +65,12 @@ inline void toggle_pins() {
pin_t pin = GET_PIN_MAP_PIN_M43(i);
if (!VALID_PIN(pin)) continue;
if (M43_NEVER_TOUCH(i) || (!ignore_protection && pin_is_protected(pin))) {
- report_pin_state_extended(pin, ignore_protection, true, PSTR("Untouched "));
+ report_pin_state_extended(pin, ignore_protection, true, F("Untouched "));
SERIAL_EOL();
}
else {
watchdog_refresh();
- report_pin_state_extended(pin, ignore_protection, true, PSTR("Pulsing "));
+ report_pin_state_extended(pin, ignore_protection, true, F("Pulsing "));
#ifdef __STM32F1__
const auto prior_mode = _GET_MODE(i);
#else
@@ -112,7 +112,7 @@ inline void toggle_pins() {
}
SERIAL_EOL();
}
- SERIAL_ECHOLNPGM("Done.");
+ SERIAL_ECHOLNPGM(STR_DONE);
} // toggle_pins
@@ -130,7 +130,7 @@ inline void servo_probe_test() {
const uint8_t probe_index = parser.byteval('P', Z_PROBE_SERVO_NR);
- SERIAL_ECHOLNPAIR("Servo probe test\n"
+ SERIAL_ECHOLNPGM("Servo probe test\n"
". using index: ", probe_index,
", deploy angle: ", servo_angles[probe_index][0],
", stow angle: ", servo_angles[probe_index][1]
@@ -143,7 +143,7 @@ inline void servo_probe_test() {
#define PROBE_TEST_PIN Z_MIN_PIN
constexpr bool probe_inverting = Z_MIN_ENDSTOP_INVERTING;
- SERIAL_ECHOLNPAIR(". Probe Z_MIN_PIN: ", PROBE_TEST_PIN);
+ SERIAL_ECHOLNPGM(". Probe Z_MIN_PIN: ", PROBE_TEST_PIN);
SERIAL_ECHOPGM(". Z_MIN_ENDSTOP_INVERTING: ");
#else
@@ -151,7 +151,7 @@ inline void servo_probe_test() {
#define PROBE_TEST_PIN Z_MIN_PROBE_PIN
constexpr bool probe_inverting = Z_MIN_PROBE_ENDSTOP_INVERTING;
- SERIAL_ECHOLNPAIR(". Probe Z_MIN_PROBE_PIN: ", PROBE_TEST_PIN);
+ SERIAL_ECHOLNPGM(". Probe Z_MIN_PROBE_PIN: ", PROBE_TEST_PIN);
SERIAL_ECHOPGM( ". Z_MIN_PROBE_ENDSTOP_INVERTING: ");
#endif
@@ -211,11 +211,11 @@ inline void servo_probe_test() {
if (deploy_state != stow_state) {
SERIAL_ECHOLNPGM("= Mechanical Switch detected");
if (deploy_state) {
- SERIAL_ECHOLNPAIR(" DEPLOYED state: HIGH (logic 1)",
+ SERIAL_ECHOLNPGM(" DEPLOYED state: HIGH (logic 1)",
" STOWED (triggered) state: LOW (logic 0)");
}
else {
- SERIAL_ECHOLNPAIR(" DEPLOYED state: LOW (logic 0)",
+ SERIAL_ECHOLNPGM(" DEPLOYED state: LOW (logic 0)",
" STOWED (triggered) state: HIGH (logic 1)");
}
#if ENABLED(BLTOUCH)
@@ -244,7 +244,7 @@ inline void servo_probe_test() {
if (probe_counter == 15)
SERIAL_ECHOLNPGM(": 30ms or more");
else
- SERIAL_ECHOLNPAIR(" (+/- 4ms): ", probe_counter * 2);
+ SERIAL_ECHOLNPGM(" (+/- 4ms): ", probe_counter * 2);
if (probe_counter >= 4) {
if (probe_counter == 15) {
@@ -303,7 +303,7 @@ void GcodeSuite::M43() {
if (parser.seen('E')) {
endstops.monitor_flag = parser.value_bool();
SERIAL_ECHOPGM("endstop monitor ");
- SERIAL_ECHOPGM_P(endstops.monitor_flag ? PSTR("en") : PSTR("dis"));
+ SERIAL_ECHOF(endstops.monitor_flag ? F("en") : F("dis"));
SERIAL_ECHOLNPGM("abled");
return;
}
@@ -344,8 +344,8 @@ void GcodeSuite::M43() {
#if HAS_RESUME_CONTINUE
KEEPALIVE_STATE(PAUSED_FOR_USER);
wait_for_user = true;
- TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, PSTR("M43 Wait Called"), CONTINUE_STR));
- TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("M43 Wait Called")));
+ TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, F("M43 Wait Called"), FPSTR(CONTINUE_STR)));
+ TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(F("M43 Wait Called")));
#endif
for (;;) {
diff --git a/Marlin/src/gcode/config/M575.cpp b/Marlin/src/gcode/config/M575.cpp
index 7739510cf3cff..2c12428d982af 100644
--- a/Marlin/src/gcode/config/M575.cpp
+++ b/Marlin/src/gcode/config/M575.cpp
@@ -53,13 +53,13 @@ void GcodeSuite::M575() {
case 115200: case 250000: case 500000: case 1000000: {
const int8_t port = parser.intval('P', -99);
const bool set1 = (port == -99 || port == 0);
- if (set1) SERIAL_ECHO_MSG(" Serial ", AS_CHAR('0'), " baud rate set to ", baud);
+ if (set1) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(0), " baud rate set to ", baud);
#if HAS_MULTI_SERIAL
const bool set2 = (port == -99 || port == 1);
- if (set2) SERIAL_ECHO_MSG(" Serial ", AS_CHAR('1'), " baud rate set to ", baud);
+ if (set2) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(1), " baud rate set to ", baud);
#ifdef SERIAL_PORT_3
const bool set3 = (port == -99 || port == 2);
- if (set3) SERIAL_ECHO_MSG(" Serial ", AS_CHAR('2'), " baud rate set to ", baud);
+ if (set3) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(2), " baud rate set to ", baud);
#endif
#endif
diff --git a/Marlin/src/gcode/config/M92.cpp b/Marlin/src/gcode/config/M92.cpp
index 544c66a0768a1..54fe698f97b29 100644
--- a/Marlin/src/gcode/config/M92.cpp
+++ b/Marlin/src/gcode/config/M92.cpp
@@ -23,33 +23,6 @@
#include "../gcode.h"
#include "../../module/planner.h"
-void report_M92(const bool echo=true, const int8_t e=-1) {
- if (echo) SERIAL_ECHO_START(); else SERIAL_CHAR(' ');
- SERIAL_ECHOPAIR_P(LIST_N(DOUBLE(LINEAR_AXES),
- PSTR(" M92 X"), LINEAR_UNIT(planner.settings.axis_steps_per_mm[X_AXIS]),
- SP_Y_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Y_AXIS]),
- SP_Z_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Z_AXIS]),
- SP_I_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[I_AXIS]),
- SP_J_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[J_AXIS]),
- SP_K_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[K_AXIS]))
- );
- #if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
- SERIAL_ECHOPAIR_P(SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS]));
- #endif
- SERIAL_EOL();
-
- #if ENABLED(DISTINCT_E_FACTORS)
- LOOP_L_N(i, E_STEPPERS) {
- if (e >= 0 && i != e) continue;
- if (echo) SERIAL_ECHO_START(); else SERIAL_CHAR(' ');
- SERIAL_ECHOLNPAIR_P(PSTR(" M92 T"), i,
- SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS_N(i)]));
- }
- #endif
-
- UNUSED(e);
-}
-
/**
* M92: Set axis steps-per-unit for one or more axes, X, Y, Z, and E.
* (Follows the same syntax as G92)
@@ -58,10 +31,11 @@ void report_M92(const bool echo=true, const int8_t e=-1) {
*
* If no argument is given print the current values.
*
- * With MAGIC_NUMBERS_GCODE:
- * Use 'H' and/or 'L' to get ideal layer-height information.
- * 'H' specifies micro-steps to use. We guess if it's not supplied.
- * 'L' specifies a desired layer height. Nearest good heights are shown.
+ * With MAGIC_NUMBERS_GCODE:
+ *
+ * Use 'H' and/or 'L' to get ideal layer-height information.
+ * H - Specify micro-steps to use. Best guess if not supplied.
+ * L - Desired layer height in current units. Nearest good heights are shown.
*/
void GcodeSuite::M92() {
@@ -69,10 +43,8 @@ void GcodeSuite::M92() {
if (target_extruder < 0) return;
// No arguments? Show M92 report.
- if (!parser.seen(
- LOGICAL_AXIS_GANG("E", "X", "Y", "Z", AXIS4_STR, AXIS5_STR, AXIS6_STR)
- TERN_(MAGIC_NUMBERS_GCODE, "HL")
- )) return report_M92(true, target_extruder);
+ if (!parser.seen(LOGICAL_AXES_STRING TERN_(MAGIC_NUMBERS_GCODE, "HL")))
+ return M92_report(true, target_extruder);
LOOP_LOGICAL_AXES(i) {
if (parser.seenval(axis_codes[i])) {
@@ -100,16 +72,16 @@ void GcodeSuite::M92() {
#ifndef Z_MICROSTEPS
#define Z_MICROSTEPS 16
#endif
- const float wanted = parser.floatval('L');
+ const float wanted = parser.linearval('L');
if (parser.seen('H') || wanted) {
const uint16_t argH = parser.ushortval('H'),
micro_steps = argH ?: Z_MICROSTEPS;
- const float z_full_step_mm = micro_steps * planner.steps_to_mm[Z_AXIS];
+ const float z_full_step_mm = micro_steps * planner.mm_per_step[Z_AXIS];
SERIAL_ECHO_START();
- SERIAL_ECHOPAIR("{ micro_steps:", micro_steps, ", z_full_step_mm:", z_full_step_mm);
+ SERIAL_ECHOPGM("{ micro_steps:", micro_steps, ", z_full_step_mm:", z_full_step_mm);
if (wanted) {
const float best = uint16_t(wanted / z_full_step_mm) * z_full_step_mm;
- SERIAL_ECHOPAIR(", best:[", best);
+ SERIAL_ECHOPGM(", best:[", best);
if (best != wanted) { SERIAL_CHAR(','); SERIAL_DECIMAL(best + z_full_step_mm); }
SERIAL_CHAR(']');
}
@@ -117,3 +89,32 @@ void GcodeSuite::M92() {
}
#endif
}
+
+void GcodeSuite::M92_report(const bool forReplay/*=true*/, const int8_t e/*=-1*/) {
+ report_heading_etc(forReplay, F(STR_STEPS_PER_UNIT));
+ SERIAL_ECHOPGM_P(LIST_N(DOUBLE(LINEAR_AXES),
+ PSTR(" M92 X"), LINEAR_UNIT(planner.settings.axis_steps_per_mm[X_AXIS]),
+ SP_Y_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Y_AXIS]),
+ SP_Z_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Z_AXIS]),
+ SP_I_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[I_AXIS]),
+ SP_J_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[J_AXIS]),
+ SP_K_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[K_AXIS]))
+ );
+ #if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
+ SERIAL_ECHOPGM_P(SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS]));
+ #endif
+ SERIAL_EOL();
+
+ #if ENABLED(DISTINCT_E_FACTORS)
+ LOOP_L_N(i, E_STEPPERS) {
+ if (e >= 0 && i != e) continue;
+ report_echo_start(forReplay);
+ SERIAL_ECHOLNPGM_P(
+ PSTR(" M92 T"), i,
+ SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS_N(i)])
+ );
+ }
+ #else
+ UNUSED(e);
+ #endif
+}
diff --git a/Marlin/src/gcode/control/M108_M112_M410.cpp b/Marlin/src/gcode/control/M108_M112_M410.cpp
index 309c806c8fc5b..39f9c04e1915b 100644
--- a/Marlin/src/gcode/control/M108_M112_M410.cpp
+++ b/Marlin/src/gcode/control/M108_M112_M410.cpp
@@ -40,7 +40,7 @@ void GcodeSuite::M108() {
* M112: Full Shutdown
*/
void GcodeSuite::M112() {
- kill(M112_KILL_STR, nullptr, true);
+ kill(FPSTR(M112_KILL_STR), nullptr, true);
}
/**
diff --git a/Marlin/src/gcode/control/M111.cpp b/Marlin/src/gcode/control/M111.cpp
index e762e3387fcac..08c39b762ea41 100644
--- a/Marlin/src/gcode/control/M111.cpp
+++ b/Marlin/src/gcode/control/M111.cpp
@@ -26,7 +26,7 @@
* M111: Set the debug level
*/
void GcodeSuite::M111() {
- if (parser.seen('S')) marlin_debug_flags = parser.byteval('S');
+ if (parser.seenval('S')) marlin_debug_flags = parser.value_byte();
static PGMSTR(str_debug_1, STR_DEBUG_ECHO);
static PGMSTR(str_debug_2, STR_DEBUG_INFO);
@@ -57,19 +57,19 @@ void GcodeSuite::M111() {
SERIAL_ECHOPGM(STR_DEBUG_OFF);
#if !defined(__AVR__) || !defined(USBCON)
#if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS)
- SERIAL_ECHOPAIR("\nBuffer Overruns: ", MYSERIAL1.buffer_overruns());
+ SERIAL_ECHOPGM("\nBuffer Overruns: ", MYSERIAL1.buffer_overruns());
#endif
#if ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS)
- SERIAL_ECHOPAIR("\nFraming Errors: ", MYSERIAL1.framing_errors());
+ SERIAL_ECHOPGM("\nFraming Errors: ", MYSERIAL1.framing_errors());
#endif
#if ENABLED(SERIAL_STATS_DROPPED_RX)
- SERIAL_ECHOPAIR("\nDropped bytes: ", MYSERIAL1.dropped());
+ SERIAL_ECHOPGM("\nDropped bytes: ", MYSERIAL1.dropped());
#endif
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
- SERIAL_ECHOPAIR("\nMax RX Queue Size: ", MYSERIAL1.rxMaxEnqueued());
+ SERIAL_ECHOPGM("\nMax RX Queue Size: ", MYSERIAL1.rxMaxEnqueued());
#endif
#endif // !__AVR__ || !USBCON
}
diff --git a/Marlin/src/gcode/control/M17_M18_M84.cpp b/Marlin/src/gcode/control/M17_M18_M84.cpp
index 4ebb81cf7ea74..4683786f1fd02 100644
--- a/Marlin/src/gcode/control/M17_M18_M84.cpp
+++ b/Marlin/src/gcode/control/M17_M18_M84.cpp
@@ -29,29 +29,186 @@
#include "../../feature/bedlevel/bedlevel.h"
#endif
+#define DEBUG_OUT ENABLED(MARLIN_DEV_MODE)
+#include "../../core/debug_out.h"
+#include "../../libs/hex_print.h"
+
+inline axis_flags_t selected_axis_bits() {
+ axis_flags_t selected{0};
+ #if HAS_EXTRUDERS
+ if (parser.seen('E')) {
+ if (E_TERN0(parser.has_value())) {
+ const uint8_t e = parser.value_int();
+ if (e < EXTRUDERS)
+ selected.bits = _BV(INDEX_OF_AXIS(E_AXIS, e));
+ }
+ else
+ selected.bits = selected.e_bits();
+ }
+ #endif
+ selected.bits |= LINEAR_AXIS_GANG(
+ (parser.seen_test('X') << X_AXIS),
+ | (parser.seen_test('Y') << Y_AXIS),
+ | (parser.seen_test('Z') << Z_AXIS),
+ | (parser.seen_test(AXIS4_NAME) << I_AXIS),
+ | (parser.seen_test(AXIS5_NAME) << J_AXIS),
+ | (parser.seen_test(AXIS6_NAME) << K_AXIS)
+ );
+ return selected;
+}
+
+// Enable specified axes and warn about other affected axes
+void do_enable(const axis_flags_t to_enable) {
+ const ena_mask_t was_enabled = stepper.axis_enabled.bits,
+ shall_enable = to_enable.bits & ~was_enabled;
+
+ DEBUG_ECHOLNPGM("Now Enabled: ", hex_word(stepper.axis_enabled.bits), " Enabling: ", hex_word(to_enable.bits), " | ", shall_enable);
+
+ if (!shall_enable) return; // All specified axes already enabled?
+
+ ena_mask_t also_enabled = 0; // Track steppers enabled due to overlap
+
+ // Enable all flagged axes
+ LOOP_LINEAR_AXES(a) {
+ if (TEST(shall_enable, a)) {
+ stepper.enable_axis(AxisEnum(a)); // Mark and enable the requested axis
+ DEBUG_ECHOLNPGM("Enabled ", axis_codes[a], " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... Enabled: ", hex_word(stepper.axis_enabled.bits));
+ also_enabled |= enable_overlap[a];
+ }
+ }
+ #if HAS_EXTRUDERS
+ LOOP_L_N(e, EXTRUDERS) {
+ const uint8_t a = INDEX_OF_AXIS(E_AXIS, e);
+ if (TEST(shall_enable, a)) {
+ stepper.ENABLE_EXTRUDER(e);
+ DEBUG_ECHOLNPGM("Enabled E", AS_DIGIT(e), " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... ", hex_word(stepper.axis_enabled.bits));
+ also_enabled |= enable_overlap[a];
+ }
+ }
+ #endif
+
+ if ((also_enabled &= ~(shall_enable | was_enabled))) {
+ SERIAL_CHAR('(');
+ LOOP_LINEAR_AXES(a) if (TEST(also_enabled, a)) SERIAL_CHAR(axis_codes[a], ' ');
+ #if HAS_EXTRUDERS
+ #define _EN_ALSO(N) if (TEST(also_enabled, INDEX_OF_AXIS(E_AXIS, N))) SERIAL_CHAR('E', '0' + N, ' ');
+ REPEAT(EXTRUDERS, _EN_ALSO)
+ #endif
+ SERIAL_ECHOLNPGM("also enabled)");
+ }
+
+ DEBUG_ECHOLNPGM("Enabled Now: ", hex_word(stepper.axis_enabled.bits));
+}
+
/**
- * M17: Enable stepper motors
+ * M17: Enable stepper motor power for one or more axes.
+ * Print warnings for axes that share an ENABLE_PIN.
+ *
+ * Examples:
+ *
+ * M17 XZ ; Enable X and Z axes
+ * M17 E ; Enable all E steppers
+ * M17 E1 ; Enable just the E1 stepper
*/
void GcodeSuite::M17() {
- if (parser.seen(LOGICAL_AXIS_GANG("E", "X", "Y", "Z", AXIS4_STR, AXIS5_STR, AXIS6_STR))) {
- LOGICAL_AXIS_CODE(
- if (TERN0(HAS_E_STEPPER_ENABLE, parser.seen_test('E'))) enable_e_steppers(),
- if (parser.seen_test('X')) ENABLE_AXIS_X(),
- if (parser.seen_test('Y')) ENABLE_AXIS_Y(),
- if (parser.seen_test('Z')) ENABLE_AXIS_Z(),
- if (parser.seen_test(AXIS4_NAME)) ENABLE_AXIS_I(),
- if (parser.seen_test(AXIS5_NAME)) ENABLE_AXIS_J(),
- if (parser.seen_test(AXIS6_NAME)) ENABLE_AXIS_K()
- );
+ if (parser.seen_axis()) {
+ if (any_enable_overlap())
+ do_enable(selected_axis_bits());
+ else {
+ #if HAS_EXTRUDERS
+ if (parser.seen('E')) {
+ if (parser.has_value()) {
+ const uint8_t e = parser.value_int();
+ if (e < EXTRUDERS) stepper.ENABLE_EXTRUDER(e);
+ }
+ else
+ stepper.enable_e_steppers();
+ }
+ #endif
+ LINEAR_AXIS_CODE(
+ if (parser.seen_test('X')) stepper.enable_axis(X_AXIS),
+ if (parser.seen_test('Y')) stepper.enable_axis(Y_AXIS),
+ if (parser.seen_test('Z')) stepper.enable_axis(Z_AXIS),
+ if (parser.seen_test(AXIS4_NAME)) stepper.enable_axis(I_AXIS),
+ if (parser.seen_test(AXIS5_NAME)) stepper.enable_axis(J_AXIS),
+ if (parser.seen_test(AXIS6_NAME)) stepper.enable_axis(K_AXIS)
+ );
+ }
}
else {
- LCD_MESSAGEPGM(MSG_NO_MOVE);
- enable_all_steppers();
+ LCD_MESSAGE(MSG_NO_MOVE);
+ stepper.enable_all_steppers();
}
}
+void try_to_disable(const axis_flags_t to_disable) {
+ ena_mask_t still_enabled = to_disable.bits & stepper.axis_enabled.bits;
+
+ DEBUG_ECHOLNPGM("Enabled: ", hex_word(stepper.axis_enabled.bits), " To Disable: ", hex_word(to_disable.bits), " | ", hex_word(still_enabled));
+
+ if (!still_enabled) return;
+
+ // Attempt to disable all flagged axes
+ LOOP_LINEAR_AXES(a)
+ if (TEST(to_disable.bits, a)) {
+ DEBUG_ECHOPGM("Try to disable ", axis_codes[a], " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... ");
+ 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
+ }
+ else
+ DEBUG_ECHOPGM("OVERLAP");
+ DEBUG_ECHOLNPGM(" ... still_enabled=", hex_word(still_enabled));
+ }
+ #if HAS_EXTRUDERS
+ LOOP_L_N(e, EXTRUDERS) {
+ const uint8_t a = INDEX_OF_AXIS(E_AXIS, e);
+ if (TEST(to_disable.bits, a)) {
+ DEBUG_ECHOPGM("Try to disable E", AS_DIGIT(e), " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... ");
+ if (stepper.DISABLE_EXTRUDER(e)) {
+ DEBUG_ECHOPGM("OK");
+ still_enabled &= ~(_BV(a) | enable_overlap[a]);
+ }
+ else
+ DEBUG_ECHOPGM("OVERLAP");
+ DEBUG_ECHOLNPGM(" ... still_enabled=", hex_word(still_enabled));
+ }
+ }
+ #endif
+
+ auto overlap_warning = [](const ena_mask_t axis_bits) {
+ SERIAL_ECHOPGM(" not disabled. Shared with");
+ LOOP_LINEAR_AXES(a) if (TEST(axis_bits, a)) SERIAL_CHAR(' ', axis_codes[a]);
+ #if HAS_EXTRUDERS
+ #define _EN_STILLON(N) if (TEST(axis_bits, INDEX_OF_AXIS(E_AXIS, N))) SERIAL_CHAR(' ', 'E', '0' + N);
+ REPEAT(EXTRUDERS, _EN_STILLON)
+ #endif
+ SERIAL_ECHOLNPGM(".");
+ };
+
+ // If any of the requested axes are still enabled, give a warning
+ LOOP_LINEAR_AXES(a) {
+ if (TEST(still_enabled, a)) {
+ SERIAL_CHAR(axis_codes[a]);
+ overlap_warning(stepper.axis_enabled.bits & enable_overlap[a]);
+ }
+ }
+ #if HAS_EXTRUDERS
+ LOOP_L_N(e, EXTRUDERS) {
+ const uint8_t a = INDEX_OF_AXIS(E_AXIS, e);
+ if (TEST(still_enabled, a)) {
+ SERIAL_CHAR('E', '0' + e);
+ overlap_warning(stepper.axis_enabled.bits & enable_overlap[a]);
+ }
+ }
+ #endif
+
+ DEBUG_ECHOLNPGM("Enabled Now: ", hex_word(stepper.axis_enabled.bits));
+}
+
/**
- * M18, M84: Disable stepper motors
+ * M18, M84: Disable stepper motor power for one or more axes.
+ * Print warnings for axes that share an ENABLE_PIN.
*/
void GcodeSuite::M18_M84() {
if (parser.seenval('S')) {
@@ -59,17 +216,28 @@ void GcodeSuite::M18_M84() {
stepper_inactive_time = parser.value_millis_from_seconds();
}
else {
- if (parser.seen(LOGICAL_AXIS_GANG("E", "X", "Y", "Z", AXIS4_STR, AXIS5_STR, AXIS6_STR))) {
+ if (parser.seen_axis()) {
planner.synchronize();
- LOGICAL_AXIS_CODE(
- if (TERN0(HAS_E_STEPPER_ENABLE, parser.seen_test('E'))) disable_e_steppers(),
- if (parser.seen_test('X')) DISABLE_AXIS_X(),
- if (parser.seen_test('Y')) DISABLE_AXIS_Y(),
- if (parser.seen_test('Z')) DISABLE_AXIS_Z(),
- if (parser.seen_test(AXIS4_NAME)) DISABLE_AXIS_I(),
- if (parser.seen_test(AXIS5_NAME)) DISABLE_AXIS_J(),
- if (parser.seen_test(AXIS6_NAME)) DISABLE_AXIS_K()
- );
+ if (any_enable_overlap())
+ try_to_disable(selected_axis_bits());
+ else {
+ #if HAS_EXTRUDERS
+ if (parser.seen('E')) {
+ if (E_TERN0(parser.has_value()))
+ stepper.DISABLE_EXTRUDER(parser.value_int());
+ else
+ stepper.disable_e_steppers();
+ }
+ #endif
+ LINEAR_AXIS_CODE(
+ if (parser.seen_test('X')) stepper.disable_axis(X_AXIS),
+ if (parser.seen_test('Y')) stepper.disable_axis(Y_AXIS),
+ if (parser.seen_test('Z')) stepper.disable_axis(Z_AXIS),
+ if (parser.seen_test(AXIS4_NAME)) stepper.disable_axis(I_AXIS),
+ if (parser.seen_test(AXIS5_NAME)) stepper.disable_axis(J_AXIS),
+ if (parser.seen_test(AXIS6_NAME)) stepper.disable_axis(K_AXIS)
+ );
+ }
}
else
planner.finish_and_disable();
diff --git a/Marlin/src/gcode/control/M211.cpp b/Marlin/src/gcode/control/M211.cpp
index 2ba777ba650ef..95ae052a7bd4b 100644
--- a/Marlin/src/gcode/control/M211.cpp
+++ b/Marlin/src/gcode/control/M211.cpp
@@ -33,14 +33,22 @@
* Usage: M211 S1 to enable, M211 S0 to disable, M211 alone for report
*/
void GcodeSuite::M211() {
+ if (parser.seen('S'))
+ soft_endstop._enabled = parser.value_bool();
+ else
+ M211_report();
+}
+
+void GcodeSuite::M211_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_SOFT_ENDSTOPS));
+ SERIAL_ECHOPGM(" M211 S", AS_DIGIT(soft_endstop._enabled), " ; ");
+ serialprintln_onoff(soft_endstop._enabled);
+
+ report_echo_start(forReplay);
const xyz_pos_t l_soft_min = soft_endstop.min.asLogical(),
l_soft_max = soft_endstop.max.asLogical();
- SERIAL_ECHO_START();
- SERIAL_ECHOPGM(STR_SOFT_ENDSTOPS);
- if (parser.seen('S')) soft_endstop._enabled = parser.value_bool();
- serialprint_onoff(soft_endstop._enabled);
- print_pos(l_soft_min, PSTR(STR_SOFT_MIN), PSTR(" "));
- print_pos(l_soft_max, PSTR(STR_SOFT_MAX));
+ print_pos(l_soft_min, F(STR_SOFT_MIN), F(" "));
+ print_pos(l_soft_max, F(STR_SOFT_MAX));
}
-#endif
+#endif // HAS_SOFTWARE_ENDSTOPS
diff --git a/Marlin/src/gcode/control/M280.cpp b/Marlin/src/gcode/control/M280.cpp
index 187c9a9b1998a..2a8e73eafbf27 100644
--- a/Marlin/src/gcode/control/M280.cpp
+++ b/Marlin/src/gcode/control/M280.cpp
@@ -26,22 +26,44 @@
#include "../gcode.h"
#include "../../module/servo.h"
+#include "../../module/planner.h"
/**
- * M280: Get or set servo position. P [S]
+ * M280: Get or set servo position.
+ * P - Servo index
+ * S - Angle to set, omit to read current angle, or use -1 to detach
+ *
+ * With POLARGRAPH:
+ * T - Duration of servo move
*/
void GcodeSuite::M280() {
- if (!parser.seen('P')) return;
+ if (!parser.seenval('P')) return;
+
+ TERN_(POLARGRAPH, planner.synchronize());
const int servo_index = parser.value_int();
if (WITHIN(servo_index, 0, NUM_SERVOS - 1)) {
- if (parser.seen('S')) {
- const int a = parser.value_int();
- if (a == -1)
- servo[servo_index].detach();
+ if (parser.seenval('S')) {
+ const int anew = parser.value_int();
+ if (anew >= 0) {
+ #if ENABLED(POLARGRAPH)
+ if (parser.seen('T')) { // (ms) Total duration of servo move
+ const int16_t t = constrain(parser.value_int(), 0, 10000);
+ const int aold = servo[servo_index].read();
+ millis_t now = millis();
+ const millis_t start = now, end = start + t;
+ while (PENDING(now, end)) {
+ safe_delay(50);
+ now = _MIN(millis(), end);
+ MOVE_SERVO(servo_index, LROUND(aold + (anew - aold) * (float(now - start) / t)));
+ }
+ }
+ #endif // POLARGRAPH
+ MOVE_SERVO(servo_index, anew);
+ }
else
- MOVE_SERVO(servo_index, a);
+ DETACH_SERVO(servo_index);
}
else
SERIAL_ECHO_MSG(" Servo ", servo_index, ": ", servo[servo_index].read());
diff --git a/Marlin/src/gcode/control/M282.cpp b/Marlin/src/gcode/control/M282.cpp
new file mode 100644
index 0000000000000..e6f5ce7dccc3a
--- /dev/null
+++ b/Marlin/src/gcode/control/M282.cpp
@@ -0,0 +1,45 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include "../../inc/MarlinConfig.h"
+
+#if ENABLED(SERVO_DETACH_GCODE)
+
+#include "../gcode.h"
+#include "../../module/servo.h"
+
+/**
+ * M282: Detach Servo. P
+ */
+void GcodeSuite::M282() {
+
+ if (!parser.seenval('P')) return;
+
+ const int servo_index = parser.value_int();
+ if (WITHIN(servo_index, 0, NUM_SERVOS - 1))
+ DETACH_SERVO(servo_index);
+ else
+ SERIAL_ECHO_MSG("Servo ", servo_index, " out of range");
+
+}
+
+#endif // SERVO_DETACH_GCODE
diff --git a/Marlin/src/gcode/control/M3-M5.cpp b/Marlin/src/gcode/control/M3-M5.cpp
index 711bb7e5e4a78..ecae8b06c69fe 100644
--- a/Marlin/src/gcode/control/M3-M5.cpp
+++ b/Marlin/src/gcode/control/M3-M5.cpp
@@ -72,7 +72,7 @@ void GcodeSuite::M3_M4(const bool is_M4) {
#if ENABLED(SPINDLE_SERVO)
cutter.unitPower = spwr;
#else
- cutter.unitPower = TERN(SPINDLE_LASER_PWM,
+ cutter.unitPower = TERN(SPINDLE_LASER_USE_PWM,
cutter.power_to_range(cutter_power_t(round(spwr))),
spwr > 0 ? 255 : 0);
#endif
@@ -86,7 +86,7 @@ void GcodeSuite::M3_M4(const bool is_M4) {
if (parser.seen('I') == DISABLED(LASER_POWER_INLINE_INVERT)) {
// Laser power in inline mode
cutter.inline_direction(is_M4); // Should always be unused
- #if ENABLED(SPINDLE_LASER_PWM)
+ #if ENABLED(SPINDLE_LASER_USE_PWM)
if (parser.seen('O')) {
cutter.unitPower = cutter.power_to_range(parser.value_byte(), 0);
cutter.inline_ocr_power(cutter.unitPower); // The OCR is a value from 0 to 255 (uint8_t)
@@ -105,10 +105,10 @@ void GcodeSuite::M3_M4(const bool is_M4) {
planner.synchronize(); // Wait for previous movement commands (G0/G0/G2/G3) to complete before changing power
cutter.set_reverse(is_M4);
- #if ENABLED(SPINDLE_LASER_PWM)
+ #if ENABLED(SPINDLE_LASER_USE_PWM)
if (parser.seenval('O')) {
cutter.unitPower = cutter.power_to_range(parser.value_byte(), 0);
- cutter.set_ocr_power(cutter.unitPower); // The OCR is a value from 0 to 255 (uint8_t)
+ cutter.ocr_set_power(cutter.unitPower); // The OCR is a value from 0 to 255 (uint8_t)
}
else
cutter.set_power(cutter.upower_to_ocr(get_s_power()));
diff --git a/Marlin/src/gcode/control/M42.cpp b/Marlin/src/gcode/control/M42.cpp
index 908260ed25dda..77c0ccc49b0f8 100644
--- a/Marlin/src/gcode/control/M42.cpp
+++ b/Marlin/src/gcode/control/M42.cpp
@@ -126,10 +126,10 @@ void GcodeSuite::M42() {
extDigitalWrite(pin, pin_status);
#ifdef ARDUINO_ARCH_STM32
- // A simple I/O will be set to 0 by analogWrite()
- if (pin_status <= 1) return;
+ // A simple I/O will be set to 0 by set_pwm_duty()
+ if (pin_status <= 1 && !PWM_PIN(pin)) return;
#endif
- analogWrite(pin, pin_status);
+ set_pwm_duty(pin, pin_status);
}
#endif // DIRECT_PIN_CONTROL
diff --git a/Marlin/src/gcode/control/M605.cpp b/Marlin/src/gcode/control/M605.cpp
index 23d43dd0a60bf..788659e7e27a9 100644
--- a/Marlin/src/gcode/control/M605.cpp
+++ b/Marlin/src/gcode/control/M605.cpp
@@ -110,7 +110,7 @@
set_duplication_enabled(false);
#ifdef EVENT_GCODE_IDEX_AFTER_MODECHANGE
- gcode.process_subcommands_now_P(PSTR(EVENT_GCODE_IDEX_AFTER_MODECHANGE));
+ process_subcommands_now(F(EVENT_GCODE_IDEX_AFTER_MODECHANGE));
#endif
}
else if (!parser.seen('W')) // if no S or W parameter, the DXC mode gets reset to the user's default
@@ -127,26 +127,26 @@
case DXC_DUPLICATION_MODE: DEBUG_ECHOPGM("DUPLICATION"); break;
case DXC_MIRRORED_MODE: DEBUG_ECHOPGM("MIRRORED"); break;
}
- DEBUG_ECHOPAIR("\nActive Ext: ", active_extruder);
+ DEBUG_ECHOPGM("\nActive Ext: ", active_extruder);
if (!active_extruder_parked) DEBUG_ECHOPGM(" NOT ");
DEBUG_ECHOPGM(" parked.");
- DEBUG_ECHOPAIR("\nactive_extruder_x_pos: ", current_position.x);
- DEBUG_ECHOPAIR("\ninactive_extruder_x: ", inactive_extruder_x);
- DEBUG_ECHOPAIR("\nextruder_duplication_enabled: ", extruder_duplication_enabled);
- DEBUG_ECHOPAIR("\nduplicate_extruder_x_offset: ", duplicate_extruder_x_offset);
- DEBUG_ECHOPAIR("\nduplicate_extruder_temp_offset: ", duplicate_extruder_temp_offset);
- DEBUG_ECHOPAIR("\ndelayed_move_time: ", delayed_move_time);
- DEBUG_ECHOPAIR("\nX1 Home X: ", x_home_pos(0), "\nX1_MIN_POS=", X1_MIN_POS, "\nX1_MAX_POS=", X1_MAX_POS);
- DEBUG_ECHOPAIR("\nX2 Home X: ", x_home_pos(1), "\nX2_MIN_POS=", X2_MIN_POS, "\nX2_MAX_POS=", X2_MAX_POS);
- DEBUG_ECHOPAIR("\nX2_HOME_DIR=", X2_HOME_DIR, "\nX2_HOME_POS=", X2_HOME_POS);
- DEBUG_ECHOPAIR("\nDEFAULT_DUAL_X_CARRIAGE_MODE=", STRINGIFY(DEFAULT_DUAL_X_CARRIAGE_MODE));
- DEBUG_ECHOPAIR("\toolchange_settings.z_raise=", toolchange_settings.z_raise);
- DEBUG_ECHOPAIR("\nDEFAULT_DUPLICATION_X_OFFSET=", DEFAULT_DUPLICATION_X_OFFSET);
+ DEBUG_ECHOPGM("\nactive_extruder_x_pos: ", current_position.x);
+ DEBUG_ECHOPGM("\ninactive_extruder_x: ", inactive_extruder_x);
+ DEBUG_ECHOPGM("\nextruder_duplication_enabled: ", extruder_duplication_enabled);
+ DEBUG_ECHOPGM("\nduplicate_extruder_x_offset: ", duplicate_extruder_x_offset);
+ DEBUG_ECHOPGM("\nduplicate_extruder_temp_offset: ", duplicate_extruder_temp_offset);
+ DEBUG_ECHOPGM("\ndelayed_move_time: ", delayed_move_time);
+ DEBUG_ECHOPGM("\nX1 Home X: ", x_home_pos(0), "\nX1_MIN_POS=", X1_MIN_POS, "\nX1_MAX_POS=", X1_MAX_POS);
+ DEBUG_ECHOPGM("\nX2 Home X: ", x_home_pos(1), "\nX2_MIN_POS=", X2_MIN_POS, "\nX2_MAX_POS=", X2_MAX_POS);
+ DEBUG_ECHOPGM("\nX2_HOME_DIR=", X2_HOME_DIR, "\nX2_HOME_POS=", X2_HOME_POS);
+ DEBUG_ECHOPGM("\nDEFAULT_DUAL_X_CARRIAGE_MODE=", STRINGIFY(DEFAULT_DUAL_X_CARRIAGE_MODE));
+ DEBUG_ECHOPGM("\toolchange_settings.z_raise=", toolchange_settings.z_raise);
+ DEBUG_ECHOPGM("\nDEFAULT_DUPLICATION_X_OFFSET=", DEFAULT_DUPLICATION_X_OFFSET);
DEBUG_EOL();
HOTEND_LOOP() {
- DEBUG_ECHOPAIR_P(SP_T_STR, e);
- LOOP_LINEAR_AXES(a) DEBUG_ECHOPAIR(" hotend_offset[", e, "].", AS_CHAR(AXIS_CHAR(a) | 0x20), "=", hotend_offset[e][a]);
+ DEBUG_ECHOPGM_P(SP_T_STR, e);
+ LOOP_LINEAR_AXES(a) DEBUG_ECHOPGM(" hotend_offset[", e, "].", AS_CHAR(AXIS_CHAR(a) | 0x20), "=", hotend_offset[e][a]);
DEBUG_EOL();
}
DEBUG_EOL();
diff --git a/Marlin/src/gcode/control/M80_M81.cpp b/Marlin/src/gcode/control/M80_M81.cpp
index 149613ee15c86..b8be9daa40152 100644
--- a/Marlin/src/gcode/control/M80_M81.cpp
+++ b/Marlin/src/gcode/control/M80_M81.cpp
@@ -25,7 +25,7 @@
#include "../../module/temperature.h"
#include "../../module/planner.h" // for planner.finish_and_disable
#include "../../module/printcounter.h" // for print_job_timer.stop
-#include "../../lcd/marlinui.h" // for LCD_MESSAGEPGM_P
+#include "../../lcd/marlinui.h" // for LCD_MESSAGE_F
#include "../../inc/MarlinConfig.h"
@@ -48,7 +48,7 @@
// S: Report the current power supply state and exit
if (parser.seen('S')) {
- SERIAL_ECHOPGM_P(powerManager.psu_on ? PSTR("PS:1\n") : PSTR("PS:0\n"));
+ SERIAL_ECHOF(powerManager.psu_on ? F("PS:1\n") : F("PS:0\n"));
return;
}
@@ -74,13 +74,12 @@
* This code should ALWAYS be available for FULL SHUTDOWN!
*/
void GcodeSuite::M81() {
- thermalManager.disable_all_heaters();
planner.finish_and_disable();
+ thermalManager.cooldown();
print_job_timer.stop();
#if HAS_FAN
- thermalManager.zero_fan_speeds();
#if ENABLED(PROBING_FANS_OFF)
thermalManager.fans_paused = false;
ZERO(thermalManager.saved_fan_speed);
@@ -95,5 +94,5 @@ void GcodeSuite::M81() {
powerManager.power_off_soon();
#endif
- LCD_MESSAGEPGM_P(PSTR(MACHINE_NAME " " STR_OFF "."));
+ LCD_MESSAGE_F(MACHINE_NAME " " STR_OFF ".");
}
diff --git a/Marlin/src/gcode/control/M993_M994.cpp b/Marlin/src/gcode/control/M993_M994.cpp
index ff9ff85bf5bd5..252792e5224eb 100644
--- a/Marlin/src/gcode/control/M993_M994.cpp
+++ b/Marlin/src/gcode/control/M993_M994.cpp
@@ -37,7 +37,7 @@ void GcodeSuite::M993() {
char fname[] = "spiflash.bin";
card.openFileWrite(fname);
if (!card.isFileOpen()) {
- SERIAL_ECHOLNPAIR("Failed to open ", fname, " to write.");
+ SERIAL_ECHOLNPGM("Failed to open ", fname, " to write.");
return;
}
@@ -65,7 +65,7 @@ void GcodeSuite::M994() {
char fname[] = "spiflash.bin";
card.openFileRead(fname);
if (!card.isFileOpen()) {
- SERIAL_ECHOLNPAIR("Failed to open ", fname, " to read.");
+ SERIAL_ECHOLNPGM("Failed to open ", fname, " to read.");
return;
}
diff --git a/Marlin/src/gcode/control/M997.cpp b/Marlin/src/gcode/control/M997.cpp
index cdff96f1acd81..73d795bcefc80 100644
--- a/Marlin/src/gcode/control/M997.cpp
+++ b/Marlin/src/gcode/control/M997.cpp
@@ -24,11 +24,17 @@
#if ENABLED(PLATFORM_M997_SUPPORT)
+#if ENABLED(DWIN_CREALITY_LCD_ENHANCED)
+ #include "../../lcd/e3v2/enhanced/dwin.h"
+#endif
+
/**
* M997: Perform in-application firmware update
*/
void GcodeSuite::M997() {
+ TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_RebootScreen());
+
flashFirmware(parser.intval('S'));
}
diff --git a/Marlin/src/gcode/control/T.cpp b/Marlin/src/gcode/control/T.cpp
index 6a084d83ad27d..5e8f6b5436d43 100644
--- a/Marlin/src/gcode/control/T.cpp
+++ b/Marlin/src/gcode/control/T.cpp
@@ -49,7 +49,7 @@
void GcodeSuite::T(const int8_t tool_index) {
DEBUG_SECTION(log_T, "T", DEBUGGING(LEVELING));
- if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("...(", tool_index, ")");
+ if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("...(", tool_index, ")");
// Count this command as movement / activity
reset_stepper_timeout();
diff --git a/Marlin/src/gcode/eeprom/M500-M504.cpp b/Marlin/src/gcode/eeprom/M500-M504.cpp
index cd7833c701bf5..a06e98ad1ea79 100644
--- a/Marlin/src/gcode/eeprom/M500-M504.cpp
+++ b/Marlin/src/gcode/eeprom/M500-M504.cpp
@@ -75,14 +75,14 @@ void GcodeSuite::M502() {
if (dowrite) {
val = parser.byteval('V');
persistentStore.write_data(addr, &val);
- SERIAL_ECHOLNPAIR("Wrote address ", addr, " with ", val);
+ SERIAL_ECHOLNPGM("Wrote address ", addr, " with ", val);
}
else {
if (parser.seenval('T')) {
const int endaddr = parser.value_ushort();
while (addr <= endaddr) {
persistentStore.read_data(addr, &val);
- SERIAL_ECHOLNPAIR("0x", hex_word(addr), ":", hex_byte(val));
+ SERIAL_ECHOLNPGM("0x", hex_word(addr), ":", hex_byte(val));
addr++;
safe_delay(10);
}
@@ -90,7 +90,7 @@ void GcodeSuite::M502() {
}
else {
persistentStore.read_data(addr, &val);
- SERIAL_ECHOLNPAIR("Read address ", addr, " and got ", val);
+ SERIAL_ECHOLNPGM("Read address ", addr, " and got ", val);
}
}
return;
diff --git a/Marlin/src/gcode/feature/L6470/M122.cpp b/Marlin/src/gcode/feature/L6470/M122.cpp
index cfac427642786..4a5629b049209 100644
--- a/Marlin/src/gcode/feature/L6470/M122.cpp
+++ b/Marlin/src/gcode/feature/L6470/M122.cpp
@@ -47,10 +47,10 @@ inline void L6470_say_status(const L64XX_axis_t axis) {
}
#endif
SERIAL_ECHOPGM("\n...OUTPUT: ");
- SERIAL_ECHOPGM_P(sh.STATUS_AXIS & STATUS_HIZ ? PSTR("OFF") : PSTR("ON "));
+ SERIAL_ECHOF(sh.STATUS_AXIS & STATUS_HIZ ? F("OFF") : F("ON "));
SERIAL_ECHOPGM(" BUSY: "); echo_yes_no((sh.STATUS_AXIS & STATUS_BUSY) == 0);
SERIAL_ECHOPGM(" DIR: ");
- SERIAL_ECHOPGM_P((((sh.STATUS_AXIS & STATUS_DIR) >> 4) ^ L64xxManager.index_to_dir[axis]) ? PSTR("FORWARD") : PSTR("REVERSE"));
+ SERIAL_ECHOF((((sh.STATUS_AXIS & STATUS_DIR) >> 4) ^ L64xxManager.index_to_dir[axis]) ? F("FORWARD") : F("REVERSE"));
if (sh.STATUS_AXIS_LAYOUT == L6480_STATUS_LAYOUT) {
SERIAL_ECHOPGM(" Last Command: ");
if (sh.STATUS_AXIS & sh.STATUS_AXIS_WRONG_CMD) SERIAL_ECHOPGM("VALID");
@@ -67,8 +67,8 @@ inline void L6470_say_status(const L64XX_axis_t axis) {
SERIAL_ECHOPGM(" Last Command: ");
if (!(sh.STATUS_AXIS & sh.STATUS_AXIS_WRONG_CMD)) SERIAL_ECHOPGM("IN");
SERIAL_ECHOPGM("VALID ");
- SERIAL_ECHOPGM_P(sh.STATUS_AXIS & sh.STATUS_AXIS_NOTPERF_CMD ? PSTR("COMPLETED ") : PSTR("Not PERFORMED"));
- SERIAL_ECHOPAIR("\n...THERMAL: ", !(sh.STATUS_AXIS & sh.STATUS_AXIS_TH_SD) ? "SHUTDOWN " : !(sh.STATUS_AXIS & sh.STATUS_AXIS_TH_WRN) ? "WARNING " : "OK ");
+ SERIAL_ECHOF(sh.STATUS_AXIS & sh.STATUS_AXIS_NOTPERF_CMD ? F("COMPLETED ") : F("Not PERFORMED"));
+ SERIAL_ECHOPGM("\n...THERMAL: ", !(sh.STATUS_AXIS & sh.STATUS_AXIS_TH_SD) ? "SHUTDOWN " : !(sh.STATUS_AXIS & sh.STATUS_AXIS_TH_WRN) ? "WARNING " : "OK ");
}
SERIAL_ECHOPGM(" OVERCURRENT:"); echo_yes_no((sh.STATUS_AXIS & sh.STATUS_AXIS_OCD) == 0);
if (sh.STATUS_AXIS_LAYOUT != L6474_STATUS_LAYOUT) {
diff --git a/Marlin/src/gcode/feature/L6470/M906.cpp b/Marlin/src/gcode/feature/L6470/M906.cpp
index b1beed068a7b1..d058ce5501ae5 100644
--- a/Marlin/src/gcode/feature/L6470/M906.cpp
+++ b/Marlin/src/gcode/feature/L6470/M906.cpp
@@ -63,7 +63,7 @@ void L64XX_report_current(L64XX &motor, const L64XX_axis_t axis) {
#if ENABLED(L6470_CHITCHAT)
char tmp[10];
sprintf_P(tmp, PSTR("%4x "), status);
- DEBUG_ECHOPAIR(" status: ", tmp);
+ DEBUG_ECHOPGM(" status: ", tmp);
print_bin(status);
#else
UNUSED(status);
@@ -104,13 +104,13 @@ void L64XX_report_current(L64XX &motor, const L64XX_axis_t axis) {
}
SERIAL_EOL();
- SERIAL_ECHOPAIR("...MicroSteps: ", MicroSteps,
+ SERIAL_ECHOPGM("...MicroSteps: ", MicroSteps,
" ADC_OUT: ", L6470_ADC_out);
SERIAL_ECHOPGM(" Vs_compensation: ");
- SERIAL_ECHOPGM_P((motor.GetParam(sh.L6470_AXIS_CONFIG) & CONFIG_EN_VSCOMP) ? PSTR("ENABLED ") : PSTR("DISABLED"));
- SERIAL_ECHOLNPAIR(" Compensation coefficient: ~", comp_coef * 0.01f);
+ SERIAL_ECHOF((motor.GetParam(sh.L6470_AXIS_CONFIG) & CONFIG_EN_VSCOMP) ? F("ENABLED ") : F("DISABLED"));
+ SERIAL_ECHOLNPGM(" Compensation coefficient: ~", comp_coef * 0.01f);
- SERIAL_ECHOPAIR("...KVAL_HOLD: ", motor.GetParam(L6470_KVAL_HOLD),
+ SERIAL_ECHOPGM("...KVAL_HOLD: ", motor.GetParam(L6470_KVAL_HOLD),
" KVAL_RUN : ", motor.GetParam(L6470_KVAL_RUN),
" KVAL_ACC: ", motor.GetParam(L6470_KVAL_ACC),
" KVAL_DEC: ", motor.GetParam(L6470_KVAL_DEC),
@@ -168,7 +168,7 @@ void L64XX_report_current(L64XX &motor, const L64XX_axis_t axis) {
SERIAL_ECHOLNPGM(" mA) Motor Status: NA");
const uint16_t MicroSteps = _BV(motor.GetParam(L6470_STEP_MODE) & 0x07); //NOMORE(MicroSteps, 16);
- SERIAL_ECHOPAIR("...MicroSteps: ", MicroSteps,
+ SERIAL_ECHOPGM("...MicroSteps: ", MicroSteps,
" ADC_OUT: ", L6470_ADC_out);
SERIAL_ECHOLNPGM(" Vs_compensation: NA\n");
@@ -185,7 +185,7 @@ void L64XX_report_current(L64XX &motor, const L64XX_axis_t axis) {
case 1: DEBUG_ECHOLNPGM("75V/uS") ; break;
case 2: DEBUG_ECHOLNPGM("110V/uS") ; break;
case 3: DEBUG_ECHOLNPGM("260V/uS") ; break;
- default: DEBUG_ECHOLNPAIR("slew rate: ", (motor.GetParam(sh.L6470_AXIS_CONFIG) & CONFIG_POW_SR) >> CONFIG_POW_SR_BIT); break;
+ default: DEBUG_ECHOLNPGM("slew rate: ", (motor.GetParam(sh.L6470_AXIS_CONFIG) & CONFIG_POW_SR) >> CONFIG_POW_SR_BIT); break;
}
#endif
SERIAL_EOL();
@@ -280,7 +280,7 @@ void GcodeSuite::M906() {
#if E_STEPPERS
case E_AXIS: {
- const int8_t target_e_stepper = get_target_e_stepper_from_command();
+ const int8_t target_e_stepper = get_target_e_stepper_from_command(0);
if (target_e_stepper < 0) return;
switch (target_e_stepper) {
#if AXIS_IS_L64XX(E0)
diff --git a/Marlin/src/gcode/feature/L6470/M916-918.cpp b/Marlin/src/gcode/feature/L6470/M916-918.cpp
index 3dd21ef985273..8d614603eda09 100644
--- a/Marlin/src/gcode/feature/L6470/M916-918.cpp
+++ b/Marlin/src/gcode/feature/L6470/M916-918.cpp
@@ -96,7 +96,7 @@ void GcodeSuite::M916() {
if (L64xxManager.get_user_input(driver_count, axis_index, axis_mon, position_max, position_min, final_feedrate, kval_hold, over_current_flag, OCD_TH_val, STALL_TH_val, over_current_threshold))
return; // quit if invalid user input
- DEBUG_ECHOLNPAIR("feedrate = ", final_feedrate);
+ DEBUG_ECHOLNPGM("feedrate = ", final_feedrate);
planner.synchronize(); // wait for all current movement commands to complete
@@ -127,9 +127,9 @@ void GcodeSuite::M916() {
do {
if (sh.STATUS_AXIS_LAYOUT == L6474_STATUS_LAYOUT)
- DEBUG_ECHOLNPAIR("TVAL current (mA) = ", (M91x_counter + 1) * sh.AXIS_STALL_CURRENT_CONSTANT_INV); // report TVAL current for this run
+ DEBUG_ECHOLNPGM("TVAL current (mA) = ", (M91x_counter + 1) * sh.AXIS_STALL_CURRENT_CONSTANT_INV); // report TVAL current for this run
else
- DEBUG_ECHOLNPAIR("kval_hold = ", M91x_counter); // report KVAL_HOLD for this run
+ DEBUG_ECHOLNPGM("kval_hold = ", M91x_counter); // report KVAL_HOLD for this run
for (j = 0; j < driver_count; j++)
L64xxManager.set_param(axis_index[j], L6470_KVAL_HOLD, M91x_counter); //set KVAL_HOLD or TVAL (same register address)
@@ -138,10 +138,10 @@ void GcodeSuite::M916() {
do {
// turn the motor(s) both directions
sprintf_P(gcode_string, PSTR("G0 %s%03d F%03d"), temp_axis_string, uint16_t(position_min), uint16_t(final_feedrate));
- gcode.process_subcommands_now_P(gcode_string);
+ process_subcommands_now(gcode_string);
sprintf_P(gcode_string, PSTR("G0 %s%03d F%03d"), temp_axis_string, uint16_t(position_max), uint16_t(final_feedrate));
- gcode.process_subcommands_now_P(gcode_string);
+ process_subcommands_now(gcode_string);
// get the status after the motors have stopped
planner.synchronize();
@@ -236,7 +236,7 @@ void GcodeSuite::M917() {
if (L64xxManager.get_user_input(driver_count, axis_index, axis_mon, position_max, position_min, final_feedrate, kval_hold, over_current_flag, OCD_TH_val, STALL_TH_val, over_current_threshold))
return; // quit if invalid user input
- DEBUG_ECHOLNPAIR("feedrate = ", final_feedrate);
+ DEBUG_ECHOLNPGM("feedrate = ", final_feedrate);
planner.synchronize(); // wait for all current movement commands to complete
@@ -252,24 +252,24 @@ void GcodeSuite::M917() {
// 2 - OCD finalized - decreasing STALL - exit when STALL warning happens
// 3 - OCD finalized - increasing STALL - exit when STALL warning stop
// 4 - all testing completed
- DEBUG_ECHOPAIR(".\n.\n.\nover_current threshold : ", (OCD_TH_val + 1) * 375); // first status display
- DEBUG_ECHOPAIR(" (OCD_TH: : ", OCD_TH_val);
+ DEBUG_ECHOPGM(".\n.\n.\nover_current threshold : ", (OCD_TH_val + 1) * 375); // first status display
+ DEBUG_ECHOPGM(" (OCD_TH: : ", OCD_TH_val);
if (sh.STATUS_AXIS_LAYOUT != L6474_STATUS_LAYOUT) {
- DEBUG_ECHOPAIR(") Stall threshold: ", (STALL_TH_val + 1) * 31.25);
- DEBUG_ECHOPAIR(" (STALL_TH: ", STALL_TH_val);
+ DEBUG_ECHOPGM(") Stall threshold: ", (STALL_TH_val + 1) * 31.25);
+ DEBUG_ECHOPGM(" (STALL_TH: ", STALL_TH_val);
}
DEBUG_ECHOLNPGM(")");
do {
- if (sh.STATUS_AXIS_LAYOUT != L6474_STATUS_LAYOUT) DEBUG_ECHOPAIR("STALL threshold : ", (STALL_TH_val + 1) * 31.25);
- DEBUG_ECHOLNPAIR(" OCD threshold : ", (OCD_TH_val + 1) * 375);
+ if (sh.STATUS_AXIS_LAYOUT != L6474_STATUS_LAYOUT) DEBUG_ECHOPGM("STALL threshold : ", (STALL_TH_val + 1) * 31.25);
+ DEBUG_ECHOLNPGM(" OCD threshold : ", (OCD_TH_val + 1) * 375);
sprintf_P(gcode_string, PSTR("G0 %s%03d F%03d"), temp_axis_string, uint16_t(position_min), uint16_t(final_feedrate));
- gcode.process_subcommands_now_P(gcode_string);
+ process_subcommands_now(gcode_string);
sprintf_P(gcode_string, PSTR("G0 %s%03d F%03d"), temp_axis_string, uint16_t(position_max), uint16_t(final_feedrate));
- gcode.process_subcommands_now_P(gcode_string);
+ process_subcommands_now(gcode_string);
planner.synchronize();
@@ -303,12 +303,12 @@ void GcodeSuite::M917() {
if (!(k % 4)) {
kval_hold *= 0.95;
DEBUG_EOL();
- DEBUG_ECHOLNPAIR("Lowering KVAL_HOLD by about 5% to ", kval_hold);
+ DEBUG_ECHOLNPGM("Lowering KVAL_HOLD by about 5% to ", kval_hold);
for (j = 0; j < driver_count; j++)
L64xxManager.set_param(axis_index[j], L6470_KVAL_HOLD, kval_hold);
}
DEBUG_ECHOLNPGM(".");
- gcode.reset_stepper_timeout(); // keep steppers powered
+ reset_stepper_timeout(); // keep steppers powered
watchdog_refresh();
safe_delay(5000);
status_composite_temp = 0;
@@ -590,8 +590,8 @@ void GcodeSuite::M918() {
}
m_steps = L64xxManager.get_param(axis_index[0], L6470_STEP_MODE) & 0x07; // get microsteps
- DEBUG_ECHOLNPAIR("Microsteps = ", _BV(m_steps));
- DEBUG_ECHOLNPAIR("target (maximum) feedrate = ", final_feedrate);
+ DEBUG_ECHOLNPGM("Microsteps = ", _BV(m_steps));
+ DEBUG_ECHOLNPGM("target (maximum) feedrate = ", final_feedrate);
const float feedrate_inc = final_feedrate / 10, // Start at 1/10 of max & go up by 1/10 per step
fr_limit = final_feedrate * 0.99f; // Rounding-safe comparison value
@@ -612,13 +612,13 @@ void GcodeSuite::M918() {
do {
current_feedrate += feedrate_inc;
- DEBUG_ECHOLNPAIR("...feedrate = ", current_feedrate);
+ DEBUG_ECHOLNPGM("...feedrate = ", current_feedrate);
sprintf_P(gcode_string, PSTR("G0 %s%03d F%03d"), temp_axis_string, uint16_t(position_min), uint16_t(current_feedrate));
- gcode.process_subcommands_now_P(gcode_string);
+ process_subcommands_now(gcode_string);
sprintf_P(gcode_string, PSTR("G0 %s%03d F%03d"), temp_axis_string, uint16_t(position_max), uint16_t(current_feedrate));
- gcode.process_subcommands_now_P(gcode_string);
+ process_subcommands_now(gcode_string);
planner.synchronize();
diff --git a/Marlin/src/gcode/feature/advance/M900.cpp b/Marlin/src/gcode/feature/advance/M900.cpp
index 1d76ebf7d531b..054ea3617f9b3 100644
--- a/Marlin/src/gcode/feature/advance/M900.cpp
+++ b/Marlin/src/gcode/feature/advance/M900.cpp
@@ -115,11 +115,11 @@ void GcodeSuite::M900() {
#if ENABLED(EXTRA_LIN_ADVANCE_K)
#if EXTRUDERS < 2
- SERIAL_ECHOLNPAIR("Advance S", new_slot, " K", kref, "(S", !new_slot, " K", lref, ")");
+ SERIAL_ECHOLNPGM("Advance S", new_slot, " K", kref, "(S", !new_slot, " K", lref, ")");
#else
LOOP_L_N(i, EXTRUDERS) {
const bool slot = TEST(lin_adv_slot, i);
- SERIAL_ECHOLNPAIR("Advance T", i, " S", slot, " K", planner.extruder_advance_K[i],
+ SERIAL_ECHOLNPGM("Advance T", i, " S", slot, " K", planner.extruder_advance_K[i],
"(S", !slot, " K", other_extruder_advance_K[i], ")");
SERIAL_EOL();
}
@@ -129,7 +129,7 @@ void GcodeSuite::M900() {
SERIAL_ECHO_START();
#if EXTRUDERS < 2
- SERIAL_ECHOLNPAIR("Advance K=", planner.extruder_advance_K[0]);
+ SERIAL_ECHOLNPGM("Advance K=", planner.extruder_advance_K[0]);
#else
SERIAL_ECHOPGM("Advance K");
LOOP_L_N(i, EXTRUDERS) {
@@ -144,4 +144,17 @@ void GcodeSuite::M900() {
}
+void GcodeSuite::M900_report(const bool forReplay/*=true*/) {
+ report_heading(forReplay, F(STR_LINEAR_ADVANCE));
+ #if EXTRUDERS < 2
+ report_echo_start(forReplay);
+ SERIAL_ECHOLNPGM(" M900 K", planner.extruder_advance_K[0]);
+ #else
+ LOOP_L_N(i, EXTRUDERS) {
+ report_echo_start(forReplay);
+ SERIAL_ECHOLNPGM(" M900 T", i, " K", planner.extruder_advance_K[i]);
+ }
+ #endif
+}
+
#endif // LIN_ADVANCE
diff --git a/Marlin/src/gcode/feature/clean/G12.cpp b/Marlin/src/gcode/feature/clean/G12.cpp
index b19932eb983dc..a0b87b1abc9e7 100644
--- a/Marlin/src/gcode/feature/clean/G12.cpp
+++ b/Marlin/src/gcode/feature/clean/G12.cpp
@@ -50,7 +50,7 @@ void GcodeSuite::G12() {
#ifdef WIPE_SEQUENCE_COMMANDS
if (!parser.seen_any()) {
- gcode.process_subcommands_now_P(PSTR(WIPE_SEQUENCE_COMMANDS));
+ process_subcommands_now(F(WIPE_SEQUENCE_COMMANDS));
return;
}
#endif
diff --git a/Marlin/src/gcode/feature/controllerfan/M710.cpp b/Marlin/src/gcode/feature/controllerfan/M710.cpp
index aa382a3ea9eb6..b98d88845dece 100644
--- a/Marlin/src/gcode/feature/controllerfan/M710.cpp
+++ b/Marlin/src/gcode/feature/controllerfan/M710.cpp
@@ -27,18 +27,6 @@
#include "../../gcode.h"
#include "../../../feature/controllerfan.h"
-void M710_report(const bool forReplay=true) {
- if (!forReplay) { SERIAL_ECHOLNPGM("; Controller Fan"); SERIAL_ECHO_START(); }
- SERIAL_ECHOLNPAIR(" M710"
- " S", int(controllerFan.settings.active_speed),
- " I", int(controllerFan.settings.idle_speed),
- " A", int(controllerFan.settings.auto_mode),
- " D", controllerFan.settings.duration,
- " ; (", (int(controllerFan.settings.active_speed) * 100) / 255, "%"
- " ", (int(controllerFan.settings.idle_speed) * 100) / 255, "%)"
- );
-}
-
/**
* M710: Set controller fan settings
*
@@ -78,4 +66,16 @@ void GcodeSuite::M710() {
M710_report();
}
+void GcodeSuite::M710_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_CONTROLLER_FAN));
+ SERIAL_ECHOLNPGM(" M710"
+ " S", int(controllerFan.settings.active_speed),
+ " I", int(controllerFan.settings.idle_speed),
+ " A", int(controllerFan.settings.auto_mode),
+ " D", controllerFan.settings.duration,
+ " ; (", (int(controllerFan.settings.active_speed) * 100) / 255, "%"
+ " ", (int(controllerFan.settings.idle_speed) * 100) / 255, "%)"
+ );
+}
+
#endif // CONTROLLER_FAN_EDITABLE
diff --git a/Marlin/src/gcode/feature/digipot/M907-M910.cpp b/Marlin/src/gcode/feature/digipot/M907-M910.cpp
index bd741f8a64b48..757cffd473830 100644
--- a/Marlin/src/gcode/feature/digipot/M907-M910.cpp
+++ b/Marlin/src/gcode/feature/digipot/M907-M910.cpp
@@ -22,7 +22,7 @@
#include "../../../inc/MarlinConfig.h"
-#if ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_PWM, HAS_MOTOR_CURRENT_I2C, HAS_MOTOR_CURRENT_DAC)
+#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM || HAS_MOTOR_CURRENT_I2C || HAS_MOTOR_CURRENT_DAC
#include "../../gcode.h"
@@ -44,12 +44,27 @@
void GcodeSuite::M907() {
#if HAS_MOTOR_CURRENT_SPI
+ if (!parser.seen("BS" LOGICAL_AXES_STRING))
+ return M907_report();
+
LOOP_LOGICAL_AXES(i) if (parser.seenval(axis_codes[i])) stepper.set_digipot_current(i, parser.value_int());
if (parser.seenval('B')) stepper.set_digipot_current(4, parser.value_int());
if (parser.seenval('S')) LOOP_LE_N(i, 4) stepper.set_digipot_current(i, parser.value_int());
#elif HAS_MOTOR_CURRENT_PWM
+ if (!parser.seen(
+ #if ANY_PIN(MOTOR_CURRENT_PWM_X, MOTOR_CURRENT_PWM_Y, MOTOR_CURRENT_PWM_XY)
+ "XY"
+ #endif
+ #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
+ "Z"
+ #endif
+ #if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
+ "E"
+ #endif
+ )) return M907_report();
+
#if ANY_PIN(MOTOR_CURRENT_PWM_X, MOTOR_CURRENT_PWM_Y, MOTOR_CURRENT_PWM_XY)
if (parser.seenval('X') || parser.seenval('Y')) stepper.set_digipot_current(0, parser.value_int());
#endif
@@ -82,7 +97,30 @@ void GcodeSuite::M907() {
#endif
}
-#if EITHER(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_DAC)
+#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
+
+ void GcodeSuite::M907_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_STEPPER_MOTOR_CURRENTS));
+ #if HAS_MOTOR_CURRENT_PWM
+ SERIAL_ECHOLNPGM_P( // PWM-based has 3 values:
+ PSTR(" M907 X"), stepper.motor_current_setting[0] // X and Y
+ , SP_Z_STR, stepper.motor_current_setting[1] // Z
+ , SP_E_STR, stepper.motor_current_setting[2] // E
+ );
+ #elif HAS_MOTOR_CURRENT_SPI
+ SERIAL_ECHOPGM(" M907"); // SPI-based has 5 values:
+ LOOP_LOGICAL_AXES(q) { // X Y Z (I J K) E (map to X Y Z (I J K) E0 by default)
+ SERIAL_CHAR(' ', axis_codes[q]);
+ SERIAL_ECHO(stepper.motor_current_setting[q]);
+ }
+ SERIAL_CHAR(' ', 'B'); // B (maps to E1 by default)
+ SERIAL_ECHOLN(stepper.motor_current_setting[4]);
+ #endif
+ }
+
+#endif // HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
+
+#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_DAC
/**
* M908: Control digital trimpot directly (M908 P S)
diff --git a/Marlin/src/gcode/feature/filwidth/M404-M407.cpp b/Marlin/src/gcode/feature/filwidth/M404-M407.cpp
index a70f7a61fec7e..ff174ecf1358c 100644
--- a/Marlin/src/gcode/feature/filwidth/M404-M407.cpp
+++ b/Marlin/src/gcode/feature/filwidth/M404-M407.cpp
@@ -38,7 +38,7 @@ void GcodeSuite::M404() {
planner.volumetric_area_nominal = CIRCLE_AREA(filwidth.nominal_mm * 0.5);
}
else
- SERIAL_ECHOLNPAIR("Filament dia (nominal mm):", filwidth.nominal_mm);
+ SERIAL_ECHOLNPGM("Filament dia (nominal mm):", filwidth.nominal_mm);
}
/**
@@ -65,7 +65,7 @@ void GcodeSuite::M406() {
* M407: Get measured filament diameter on serial output
*/
void GcodeSuite::M407() {
- SERIAL_ECHOLNPAIR("Filament dia (measured mm):", filwidth.measured_mm);
+ SERIAL_ECHOLNPGM("Filament dia (measured mm):", filwidth.measured_mm);
}
#endif // FILAMENT_WIDTH_SENSOR
diff --git a/Marlin/src/gcode/feature/fwretract/G10_G11.cpp b/Marlin/src/gcode/feature/fwretract/G10_G11.cpp
index 35330fe0ac129..1889f83d62118 100644
--- a/Marlin/src/gcode/feature/fwretract/G10_G11.cpp
+++ b/Marlin/src/gcode/feature/fwretract/G10_G11.cpp
@@ -32,7 +32,7 @@
* G10 - Retract filament according to settings of M207
* TODO: Handle 'G10 P' for tool settings and 'G10 L' for workspace settings
*/
-void GcodeSuite::G10() { fwretract.retract(true OPTARG(HAS_MULTI_EXTRUDER, parser.boolval('S'))); }
+void GcodeSuite::G10() { fwretract.retract(true E_OPTARG(parser.boolval('S'))); }
/**
* G11 - Recover filament according to settings of M208
diff --git a/Marlin/src/gcode/feature/fwretract/M207-M209.cpp b/Marlin/src/gcode/feature/fwretract/M207-M209.cpp
index 5793d73f948c0..173c2894dcd6a 100644
--- a/Marlin/src/gcode/feature/fwretract/M207-M209.cpp
+++ b/Marlin/src/gcode/feature/fwretract/M207-M209.cpp
@@ -29,14 +29,34 @@
/**
* M207: Set firmware retraction values
+ *
+ * S[+units] retract_length
+ * W[+units] swap_retract_length (multi-extruder)
+ * F[units/min] retract_feedrate_mm_s
+ * Z[units] retract_zraise
*/
void GcodeSuite::M207() { fwretract.M207(); }
+void GcodeSuite::M207_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_RETRACT_S_F_Z));
+ fwretract.M207_report();
+}
+
/**
* M208: Set firmware un-retraction values
+ *
+ * S[+units] retract_recover_extra (in addition to M207 S*)
+ * W[+units] swap_retract_recover_extra (multi-extruder)
+ * F[units/min] retract_recover_feedrate_mm_s
+ * R[units/min] swap_retract_recover_feedrate_mm_s
*/
void GcodeSuite::M208() { fwretract.M208(); }
+void GcodeSuite::M208_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_RECOVER_S_F));
+ fwretract.M208_report();
+}
+
#if ENABLED(FWRETRACT_AUTORETRACT)
/**
@@ -47,6 +67,11 @@ void GcodeSuite::M208() { fwretract.M208(); }
*/
void GcodeSuite::M209() { fwretract.M209(); }
+ void GcodeSuite::M209_report(const bool forReplay/*=true*/) {
+ report_heading_etc(forReplay, F(STR_AUTO_RETRACT_S));
+ fwretract.M209_report();
+ }
+
#endif
#endif // FWRETRACT
diff --git a/Marlin/src/gcode/feature/i2c/M260_M261.cpp b/Marlin/src/gcode/feature/i2c/M260_M261.cpp
index 438d1527f5f78..e978fb5048fbf 100644
--- a/Marlin/src/gcode/feature/i2c/M260_M261.cpp
+++ b/Marlin/src/gcode/feature/i2c/M260_M261.cpp
@@ -60,15 +60,16 @@ void GcodeSuite::M260() {
/**
* M261: Request X bytes from I2C slave device
*
- * Usage: M261 A B
+ * Usage: M261 A B S