Compare commits

..

3 Commits

Author SHA1 Message Date
Scott Lahteine
4518dbc5d3 🔨 Specify versions in INI 2023-12-08 21:54:24 -06:00
Scott Lahteine
23775c0f2d 🔖 Marlin 2.0.8.3 2023-07-20 13:47:19 -05:00
Scott Lahteine
a5051f73bd 🔨 PlatformIO 6 compatibility 2023-07-20 13:47:19 -05:00
562 changed files with 7151 additions and 12186 deletions

View File

@@ -56,31 +56,29 @@ jobs:
# STM32F1 (Maple) Environments # STM32F1 (Maple) Environments
#- STM32F103RC_btt_maple - STM32F103RC_btt
- STM32F103RC_btt_USB_maple - STM32F103RC_btt_USB
- STM32F103RE_btt
- STM32F103RE_btt_USB
- STM32F103RC_fysetc - STM32F103RC_fysetc
- STM32F103RC_meeb - STM32F103RC_meeb
- jgaurora_a5s_a1 - jgaurora_a5s_a1
- STM32F103VE_longer - STM32F103VE_longer
#- mks_robin_maple - mks_robin
- mks_robin_lite - mks_robin_lite
- mks_robin_pro - mks_robin_pro
#- mks_robin_nano35_maple - STM32F103RET6_creality
#- STM32F103RET6_creality_maple - mks_robin_nano35
# STM32 (ST) Environments # STM32 (ST) Environments
- STM32F103RC_btt - STM32F103RC_btt_stm32
#- STM32F103RC_btt_USB
- STM32F103RE_btt
- STM32F103RE_btt_USB
- STM32F103RET6_creality
- STM32F407VE_black - STM32F407VE_black
- STM32F401VE_STEVAL - STM32F401VE_STEVAL
- BIGTREE_BTT002 - BIGTREE_BTT002
- BIGTREE_SKR_PRO - BIGTREE_SKR_PRO
- BIGTREE_GTR_V1_0 - BIGTREE_GTR_V1_0
- mks_robin - mks_robin_stm32
- ARMED - ARMED
- FYSETC_S6 - FYSETC_S6
- STM32F070CB_malyan - STM32F070CB_malyan
@@ -90,7 +88,7 @@ jobs:
- rumba32 - rumba32
- LERDGEX - LERDGEX
- LERDGEK - LERDGEK
- mks_robin_nano35 - mks_robin_nano35_stm32
- NUCLEO_F767ZI - NUCLEO_F767ZI
- REMRAM_V1 - REMRAM_V1
- BTT_SKR_SE_BX - BTT_SKR_SE_BX
@@ -109,25 +107,8 @@ jobs:
steps: steps:
- name: Check out the PR
uses: actions/checkout@v2
- name: Cache pip
uses: actions/cache@v2
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Cache PlatformIO
uses: actions/cache@v2
with:
path: ~/.platformio
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
- name: Select Python 3.7 - name: Select Python 3.7
uses: actions/setup-python@v2 uses: actions/setup-python@v1
with: with:
python-version: '3.7' # Version range or exact version of a Python version to use, using semvers version range syntax. python-version: '3.7' # Version range or exact version of a Python version to use, using semvers version range syntax.
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
@@ -137,6 +118,9 @@ jobs:
pip install -U https://github.com/platformio/platformio-core/archive/develop.zip pip install -U https://github.com/platformio/platformio-core/archive/develop.zip
platformio update platformio update
- name: Check out the PR
uses: actions/checkout@v2
- name: Run ${{ matrix.test-platform }} Tests - name: Run ${{ matrix.test-platform }} Tests
run: | run: |
make tests-single-ci TEST_TARGET=${{ matrix.test-platform }} make tests-single-ci TEST_TARGET=${{ matrix.test-platform }}

View File

@@ -35,7 +35,7 @@
* *
* Advanced settings can be found in Configuration_adv.h * Advanced settings can be found in Configuration_adv.h
*/ */
#define CONFIGURATION_H_VERSION 02000901 #define CONFIGURATION_H_VERSION 02000801
//=========================================================================== //===========================================================================
//============================= Getting Started ============================= //============================= Getting Started =============================
@@ -149,45 +149,6 @@
// Choose your own or use a service like https://www.uuidgenerator.net/version4 // Choose your own or use a service like https://www.uuidgenerator.net/version4
//#define MACHINE_UUID "00000000-0000-0000-0000-000000000000" //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
/**
* Define the number of coordinated linear axes.
* See https://github.com/DerAndere1/Marlin/wiki
* Each linear axis gets its own stepper control and endstop:
*
* Steppers: *_STEP_PIN, *_ENABLE_PIN, *_DIR_PIN, *_ENABLE_ON
* Endstops: *_STOP_PIN, USE_*MIN_PLUG, USE_*MAX_PLUG
* Axes: *_MIN_POS, *_MAX_POS, INVERT_*_DIR
* Planner: DEFAULT_AXIS_STEPS_PER_UNIT, DEFAULT_MAX_FEEDRATE
* DEFAULT_MAX_ACCELERATION, AXIS_RELATIVE_MODES,
* MICROSTEP_MODES, MANUAL_FEEDRATE
*
* :[3, 4, 5, 6]
*/
//#define LINEAR_AXES 3
/**
* Axis codes for additional axes:
* This defines the axis code that is used in G-code commands to
* reference a specific axis.
* 'A' for rotational axis parallel to X
* 'B' for rotational axis parallel to Y
* 'C' for rotational axis parallel to Z
* 'U' for secondary linear axis parallel to X
* 'V' for secondary linear axis parallel to Y
* 'W' for secondary linear axis parallel to Z
* Regardless of the settings, firmware-internal axis IDs are
* I (AXIS4), J (AXIS5), K (AXIS6).
*/
#if LINEAR_AXES >= 4
#define AXIS4_NAME 'A' // :['A', 'B', 'C', 'U', 'V', 'W']
#endif
#if LINEAR_AXES >= 5
#define AXIS5_NAME 'B' // :['A', 'B', 'C', 'U', 'V', 'W']
#endif
#if LINEAR_AXES >= 6
#define AXIS6_NAME 'C' // :['A', 'B', 'C', 'U', 'V', 'W']
#endif
// @section extruder // @section extruder
// This defines the number of extruders // This defines the number of extruders
@@ -472,7 +433,6 @@
#define TEMP_SENSOR_PROBE 0 #define TEMP_SENSOR_PROBE 0
#define TEMP_SENSOR_CHAMBER 0 #define TEMP_SENSOR_CHAMBER 0
#define TEMP_SENSOR_COOLER 0 #define TEMP_SENSOR_COOLER 0
#define TEMP_SENSOR_REDUNDANT 0
// Dummy thermistor constant temperature readings, for use with 998 and 999 // Dummy thermistor constant temperature readings, for use with 998 and 999
#define DUMMY_THERMISTOR_998_VALUE 25 #define DUMMY_THERMISTOR_998_VALUE 25
@@ -484,6 +444,11 @@
//#define MAX31865_SENSOR_OHMS_1 100 //#define MAX31865_SENSOR_OHMS_1 100
//#define MAX31865_CALIBRATION_OHMS_1 430 //#define MAX31865_CALIBRATION_OHMS_1 430
// Use temp sensor 1 as a redundant sensor with sensor 0. If the readings
// from the two sensors differ too much the print will be aborted.
//#define TEMP_SENSOR_1_AS_REDUNDANT
#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10
#define TEMP_RESIDENCY_TIME 10 // (seconds) Time to wait for hotend to "settle" in M109 #define TEMP_RESIDENCY_TIME 10 // (seconds) Time to wait for hotend to "settle" in M109
#define TEMP_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer #define TEMP_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
#define TEMP_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target #define TEMP_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
@@ -496,28 +461,6 @@
#define TEMP_CHAMBER_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer #define TEMP_CHAMBER_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
#define TEMP_CHAMBER_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target #define TEMP_CHAMBER_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
/**
* Redundant Temperature Sensor (TEMP_SENSOR_REDUNDANT)
*
* Use a temp sensor as a redundant sensor for another reading. Select an unused temperature sensor, and another
* sensor you'd like it to be redundant for. If the two thermistors differ by TEMP_SENSOR_REDUNDANT_MAX_DIFF (°C),
* the print will be aborted. Whichever sensor is selected will have its normal functions disabled; i.e. selecting
* the Bed sensor (-1) will disable bed heating/monitoring.
*
* Use the following to select temp sensors:
* -5 : Cooler
* -4 : Probe
* -3 : not used
* -2 : Chamber
* -1 : Bed
* 0-7 : E0 through E7
*/
#if TEMP_SENSOR_REDUNDANT
#define TEMP_SENSOR_REDUNDANT_SOURCE 1 // The sensor that will provide the redundant reading.
#define TEMP_SENSOR_REDUNDANT_TARGET 0 // The sensor that we are providing a redundant reading for.
#define TEMP_SENSOR_REDUNDANT_MAX_DIFF 10 // (°C) Temperature difference that will trigger a print abort.
#endif
// Below this temperature the heater will be switched off // Below this temperature the heater will be switched off
// because it probably indicates a broken thermistor wire. // because it probably indicates a broken thermistor wire.
#define HEATER_0_MINTEMP 5 #define HEATER_0_MINTEMP 5
@@ -748,15 +691,9 @@
#define USE_XMIN_PLUG #define USE_XMIN_PLUG
#define USE_YMIN_PLUG #define USE_YMIN_PLUG
#define USE_ZMIN_PLUG #define USE_ZMIN_PLUG
//#define USE_IMIN_PLUG
//#define USE_JMIN_PLUG
//#define USE_KMIN_PLUG
//#define USE_XMAX_PLUG //#define USE_XMAX_PLUG
//#define USE_YMAX_PLUG //#define USE_YMAX_PLUG
//#define USE_ZMAX_PLUG //#define USE_ZMAX_PLUG
//#define USE_IMAX_PLUG
//#define USE_JMAX_PLUG
//#define USE_KMAX_PLUG
// Enable pullup for all endstops to prevent a floating state // Enable pullup for all endstops to prevent a floating state
#define ENDSTOPPULLUPS #define ENDSTOPPULLUPS
@@ -765,15 +702,9 @@
//#define ENDSTOPPULLUP_XMAX //#define ENDSTOPPULLUP_XMAX
//#define ENDSTOPPULLUP_YMAX //#define ENDSTOPPULLUP_YMAX
//#define ENDSTOPPULLUP_ZMAX //#define ENDSTOPPULLUP_ZMAX
//#define ENDSTOPPULLUP_IMAX
//#define ENDSTOPPULLUP_JMAX
//#define ENDSTOPPULLUP_KMAX
//#define ENDSTOPPULLUP_XMIN //#define ENDSTOPPULLUP_XMIN
//#define ENDSTOPPULLUP_YMIN //#define ENDSTOPPULLUP_YMIN
//#define ENDSTOPPULLUP_ZMIN //#define ENDSTOPPULLUP_ZMIN
//#define ENDSTOPPULLUP_IMIN
//#define ENDSTOPPULLUP_JMIN
//#define ENDSTOPPULLUP_KMIN
//#define ENDSTOPPULLUP_ZMIN_PROBE //#define ENDSTOPPULLUP_ZMIN_PROBE
#endif #endif
@@ -784,15 +715,9 @@
//#define ENDSTOPPULLDOWN_XMAX //#define ENDSTOPPULLDOWN_XMAX
//#define ENDSTOPPULLDOWN_YMAX //#define ENDSTOPPULLDOWN_YMAX
//#define ENDSTOPPULLDOWN_ZMAX //#define ENDSTOPPULLDOWN_ZMAX
//#define ENDSTOPPULLDOWN_IMAX
//#define ENDSTOPPULLDOWN_JMAX
//#define ENDSTOPPULLDOWN_KMAX
//#define ENDSTOPPULLDOWN_XMIN //#define ENDSTOPPULLDOWN_XMIN
//#define ENDSTOPPULLDOWN_YMIN //#define ENDSTOPPULLDOWN_YMIN
//#define ENDSTOPPULLDOWN_ZMIN //#define ENDSTOPPULLDOWN_ZMIN
//#define ENDSTOPPULLDOWN_IMIN
//#define ENDSTOPPULLDOWN_JMIN
//#define ENDSTOPPULLDOWN_KMIN
//#define ENDSTOPPULLDOWN_ZMIN_PROBE //#define ENDSTOPPULLDOWN_ZMIN_PROBE
#endif #endif
@@ -800,15 +725,9 @@
#define X_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop. #define X_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Y_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop. #define Y_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Z_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop. #define Z_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define I_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define J_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define K_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define X_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop. #define X_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Y_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop. #define Y_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Z_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop. #define Z_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define I_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define J_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define K_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Z_MIN_PROBE_ENDSTOP_INVERTING false // Set to true to invert the logic of the probe. #define Z_MIN_PROBE_ENDSTOP_INVERTING false // Set to true to invert the logic of the probe.
/** /**
@@ -837,9 +756,6 @@
//#define Z2_DRIVER_TYPE A4988 //#define Z2_DRIVER_TYPE A4988
//#define Z3_DRIVER_TYPE A4988 //#define Z3_DRIVER_TYPE A4988
//#define Z4_DRIVER_TYPE A4988 //#define Z4_DRIVER_TYPE A4988
//#define I_DRIVER_TYPE A4988
//#define J_DRIVER_TYPE A4988
//#define K_DRIVER_TYPE A4988
#define E0_DRIVER_TYPE A4988 #define E0_DRIVER_TYPE A4988
//#define E1_DRIVER_TYPE A4988 //#define E1_DRIVER_TYPE A4988
//#define E2_DRIVER_TYPE A4988 //#define E2_DRIVER_TYPE A4988
@@ -893,14 +809,14 @@
/** /**
* Default Axis Steps Per Unit (steps/mm) * Default Axis Steps Per Unit (steps/mm)
* Override with M92 * Override with M92
* X, Y, Z [, I [, J [, K]]], E0 [, E1[, E2...]] * X, Y, Z, E0 [, E1[, E2...]]
*/ */
#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 400, 500 } #define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 400, 500 }
/** /**
* Default Max Feed Rate (mm/s) * Default Max Feed Rate (mm/s)
* Override with M203 * Override with M203
* X, Y, Z [, I [, J [, K]]], E0 [, E1[, E2...]] * X, Y, Z, E0 [, E1[, E2...]]
*/ */
#define DEFAULT_MAX_FEEDRATE { 300, 300, 5, 25 } #define DEFAULT_MAX_FEEDRATE { 300, 300, 5, 25 }
@@ -913,7 +829,7 @@
* Default Max Acceleration (change/s) change = mm/s * Default Max Acceleration (change/s) change = mm/s
* (Maximum start speed for accelerated moves) * (Maximum start speed for accelerated moves)
* Override with M201 * Override with M201
* X, Y, Z [, I [, J [, K]]], E0 [, E1[, E2...]] * X, Y, Z, E0 [, E1[, E2...]]
*/ */
#define DEFAULT_MAX_ACCELERATION { 3000, 3000, 100, 10000 } #define DEFAULT_MAX_ACCELERATION { 3000, 3000, 100, 10000 }
@@ -947,9 +863,6 @@
#define DEFAULT_XJERK 10.0 #define DEFAULT_XJERK 10.0
#define DEFAULT_YJERK 10.0 #define DEFAULT_YJERK 10.0
#define DEFAULT_ZJERK 0.3 #define DEFAULT_ZJERK 0.3
//#define DEFAULT_IJERK 0.3
//#define DEFAULT_JJERK 0.3
//#define DEFAULT_KJERK 0.3
//#define TRAVEL_EXTRA_XYJERK 0.0 // Additional jerk allowance for all travel moves //#define TRAVEL_EXTRA_XYJERK 0.0 // Additional jerk allowance for all travel moves
@@ -1248,8 +1161,7 @@
//#define WAIT_FOR_HOTEND // Wait for hotend to heat back up between probes (to improve accuracy & prevent cold extrude) //#define WAIT_FOR_HOTEND // Wait for hotend to heat back up between probes (to improve accuracy & prevent cold extrude)
#endif #endif
//#define PROBING_FANS_OFF // Turn fans off when probing //#define PROBING_FANS_OFF // Turn fans off when probing
//#define PROBING_ESTEPPERS_OFF // Turn all extruder steppers off when probing //#define PROBING_STEPPERS_OFF // Turn steppers off (unless needed to hold position) when probing
//#define PROBING_STEPPERS_OFF // Turn all steppers off (unless needed to hold position) when probing (including extruders)
//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors //#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors
// Require minimum nozzle and/or bed temperature for probing // Require minimum nozzle and/or bed temperature for probing
@@ -1265,18 +1177,12 @@
#define Y_ENABLE_ON 0 #define Y_ENABLE_ON 0
#define Z_ENABLE_ON 0 #define Z_ENABLE_ON 0
#define E_ENABLE_ON 0 // For all extruders #define E_ENABLE_ON 0 // For all extruders
//#define I_ENABLE_ON 0
//#define J_ENABLE_ON 0
//#define K_ENABLE_ON 0
// Disable axis steppers immediately when they're not being stepped. // Disable axis steppers immediately when they're not being stepped.
// WARNING: When motors turn off there is a chance of losing position accuracy! // WARNING: When motors turn off there is a chance of losing position accuracy!
#define DISABLE_X false #define DISABLE_X false
#define DISABLE_Y false #define DISABLE_Y false
#define DISABLE_Z false #define DISABLE_Z false
//#define DISABLE_I false
//#define DISABLE_J false
//#define DISABLE_K false
// Turn off the display blinking that warns about possible accuracy reduction // Turn off the display blinking that warns about possible accuracy reduction
//#define DISABLE_REDUCED_ACCURACY_WARNING //#define DISABLE_REDUCED_ACCURACY_WARNING
@@ -1292,9 +1198,6 @@
#define INVERT_X_DIR false #define INVERT_X_DIR false
#define INVERT_Y_DIR true #define INVERT_Y_DIR true
#define INVERT_Z_DIR false #define INVERT_Z_DIR false
//#define INVERT_I_DIR false
//#define INVERT_J_DIR false
//#define INVERT_K_DIR false
// @section extruder // @section extruder
@@ -1330,9 +1233,6 @@
#define X_HOME_DIR -1 #define X_HOME_DIR -1
#define Y_HOME_DIR -1 #define Y_HOME_DIR -1
#define Z_HOME_DIR -1 #define Z_HOME_DIR -1
//#define I_HOME_DIR -1
//#define J_HOME_DIR -1
//#define K_HOME_DIR -1
// @section machine // @section machine
@@ -1347,12 +1247,6 @@
#define X_MAX_POS X_BED_SIZE #define X_MAX_POS X_BED_SIZE
#define Y_MAX_POS Y_BED_SIZE #define Y_MAX_POS Y_BED_SIZE
#define Z_MAX_POS 200 #define Z_MAX_POS 200
//#define I_MIN_POS 0
//#define I_MAX_POS 50
//#define J_MIN_POS 0
//#define J_MAX_POS 50
//#define K_MIN_POS 0
//#define K_MAX_POS 50
/** /**
* Software Endstops * Software Endstops
@@ -1369,9 +1263,6 @@
#define MIN_SOFTWARE_ENDSTOP_X #define MIN_SOFTWARE_ENDSTOP_X
#define MIN_SOFTWARE_ENDSTOP_Y #define MIN_SOFTWARE_ENDSTOP_Y
#define MIN_SOFTWARE_ENDSTOP_Z #define MIN_SOFTWARE_ENDSTOP_Z
#define MIN_SOFTWARE_ENDSTOP_I
#define MIN_SOFTWARE_ENDSTOP_J
#define MIN_SOFTWARE_ENDSTOP_K
#endif #endif
// Max software endstops constrain movement within maximum coordinate bounds // Max software endstops constrain movement within maximum coordinate bounds
@@ -1380,9 +1271,6 @@
#define MAX_SOFTWARE_ENDSTOP_X #define MAX_SOFTWARE_ENDSTOP_X
#define MAX_SOFTWARE_ENDSTOP_Y #define MAX_SOFTWARE_ENDSTOP_Y
#define MAX_SOFTWARE_ENDSTOP_Z #define MAX_SOFTWARE_ENDSTOP_Z
#define MAX_SOFTWARE_ENDSTOP_I
#define MAX_SOFTWARE_ENDSTOP_J
#define MAX_SOFTWARE_ENDSTOP_K
#endif #endif
#if EITHER(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS) #if EITHER(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS)
@@ -1694,9 +1582,6 @@
//#define MANUAL_X_HOME_POS 0 //#define MANUAL_X_HOME_POS 0
//#define MANUAL_Y_HOME_POS 0 //#define MANUAL_Y_HOME_POS 0
//#define MANUAL_Z_HOME_POS 0 //#define MANUAL_Z_HOME_POS 0
//#define MANUAL_I_HOME_POS 0
//#define MANUAL_J_HOME_POS 0
//#define MANUAL_K_HOME_POS 0
// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. // Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area.
// //
@@ -1939,20 +1824,11 @@
/** /**
* Print Job Timer * Print Job Timer
* *
* Automatically start and stop the print job timer on M104/M109/M140/M190/M141/M191. * Automatically start and stop the print job timer on M104/M109/M190.
* The print job timer will only be stopped if the bed/chamber target temp is
* below BED_MINTEMP/CHAMBER_MINTEMP.
* *
* M104 (hotend, no wait) - high temp = none, low temp = stop timer * M104 (hotend, no wait) - high temp = none, low temp = stop timer
* M109 (hotend, wait) - high temp = start timer, low temp = stop timer * M109 (hotend, wait) - high temp = start timer, low temp = stop timer
* M140 (bed, no wait) - high temp = none, low temp = stop timer * M190 (bed, wait) - high temp = start timer, low temp = none
* M190 (bed, wait) - high temp = start timer, low temp = none
* M141 (chamber, no wait) - high temp = none, low temp = stop timer
* M191 (chamber, wait) - high temp = start timer, low temp = none
*
* For M104/M109, high temp is anything over EXTRUDE_MINTEMP / 2.
* For M140/M190, high temp is anything over BED_MINTEMP.
* For M141/M191, high temp is anything over CHAMBER_MINTEMP.
* *
* The timer can also be controlled with the following commands: * The timer can also be controlled with the following commands:
* *

View File

@@ -30,7 +30,7 @@
* *
* Basic settings can be found in Configuration.h * Basic settings can be found in Configuration.h
*/ */
#define CONFIGURATION_ADV_H_VERSION 02000901 #define CONFIGURATION_ADV_H_VERSION 02000801
//=========================================================================== //===========================================================================
//============================= Thermal Settings ============================ //============================= Thermal Settings ============================
@@ -125,12 +125,6 @@
#define PROBE_BETA 3950 // Beta value #define PROBE_BETA 3950 // Beta value
#endif #endif
#if TEMP_SENSOR_REDUNDANT == 1000
#define REDUNDANT_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor
#define REDUNDANT_RESISTANCE_25C_OHMS 100000 // Resistance at 25C
#define REDUNDANT_BETA 3950 // Beta value
#endif
// //
// Hephestos 2 24V heated bed upgrade kit. // Hephestos 2 24V heated bed upgrade kit.
// https://store.bq.com/en/heated-bed-kit-hephestos2 // https://store.bq.com/en/heated-bed-kit-hephestos2
@@ -202,7 +196,7 @@
#define COOLER_MAXTEMP 26 // (°C) #define COOLER_MAXTEMP 26 // (°C)
#define COOLER_DEFAULT_TEMP 16 // (°C) #define COOLER_DEFAULT_TEMP 16 // (°C)
#define TEMP_COOLER_HYSTERESIS 1 // (°C) Temperature proximity considered "close enough" to the target #define TEMP_COOLER_HYSTERESIS 1 // (°C) Temperature proximity considered "close enough" to the target
#define COOLER_PIN 8 // Laser cooler on/off pin used to control power to the cooling element (e.g., TEC, External chiller via relay) #define COOLER_PIN 8 // Laser cooler on/off pin used to control power to the cooling element e.g. TEC, External chiller via relay
#define COOLER_INVERTING false #define COOLER_INVERTING false
#define TEMP_COOLER_PIN 15 // Laser/Cooler temperature sensor pin. ADC is required. #define TEMP_COOLER_PIN 15 // Laser/Cooler temperature sensor pin. ADC is required.
#define COOLER_FAN // Enable a fan on the cooler, Fan# 0,1,2,3 etc. #define COOLER_FAN // Enable a fan on the cooler, Fan# 0,1,2,3 etc.
@@ -532,11 +526,6 @@
//#define USE_OCR2A_AS_TOP //#define USE_OCR2A_AS_TOP
#endif #endif
/**
* Use one of the PWM fans as a redundant part-cooling fan
*/
//#define REDUNDANT_PART_COOLING_FAN 2 // Index of the fan to sync with FAN 0.
// @section extruder // @section extruder
/** /**
@@ -682,12 +671,6 @@
#endif #endif
#endif #endif
// Drive the E axis with two synchronized steppers
//#define E_DUAL_STEPPER_DRIVERS
#if ENABLED(E_DUAL_STEPPER_DRIVERS)
//#define INVERT_E1_VS_E0_DIR // Enable if the E motors need opposite DIR states
#endif
/** /**
* Dual X Carriage * Dual X Carriage
* *
@@ -751,7 +734,7 @@
* the position of the toolhead relative to the workspace. * the position of the toolhead relative to the workspace.
*/ */
//#define SENSORLESS_BACKOFF_MM { 2, 2, 0 } // (mm) Backoff from endstops before sensorless homing //#define SENSORLESS_BACKOFF_MM { 2, 2 } // (mm) Backoff from endstops before sensorless homing
#define HOMING_BUMP_MM { 5, 5, 2 } // (mm) Backoff from endstops after first bump #define HOMING_BUMP_MM { 5, 5, 2 } // (mm) Backoff from endstops after first bump
#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) #define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate)
@@ -935,9 +918,6 @@
#define INVERT_X_STEP_PIN false #define INVERT_X_STEP_PIN false
#define INVERT_Y_STEP_PIN false #define INVERT_Y_STEP_PIN false
#define INVERT_Z_STEP_PIN false #define INVERT_Z_STEP_PIN false
#define INVERT_I_STEP_PIN false
#define INVERT_J_STEP_PIN false
#define INVERT_K_STEP_PIN false
#define INVERT_E_STEP_PIN false #define INVERT_E_STEP_PIN false
/** /**
@@ -949,9 +929,6 @@
#define DISABLE_INACTIVE_X true #define DISABLE_INACTIVE_X true
#define DISABLE_INACTIVE_Y true #define DISABLE_INACTIVE_Y true
#define DISABLE_INACTIVE_Z true // Set 'false' if the nozzle could fall onto your printed part! #define DISABLE_INACTIVE_Z true // Set 'false' if the nozzle could fall onto your printed part!
#define DISABLE_INACTIVE_I true
#define DISABLE_INACTIVE_J true
#define DISABLE_INACTIVE_K true
#define DISABLE_INACTIVE_E true #define DISABLE_INACTIVE_E true
// Default Minimum Feedrates for printing and travel moves // Default Minimum Feedrates for printing and travel moves
@@ -992,7 +969,7 @@
#if ENABLED(BACKLASH_COMPENSATION) #if ENABLED(BACKLASH_COMPENSATION)
// Define values for backlash distance and correction. // Define values for backlash distance and correction.
// If BACKLASH_GCODE is enabled these values are the defaults. // If BACKLASH_GCODE is enabled these values are the defaults.
#define BACKLASH_DISTANCE_MM { 0, 0, 0 } // (mm) One value for each linear axis #define BACKLASH_DISTANCE_MM { 0, 0, 0 } // (mm)
#define BACKLASH_CORRECTION 0.0 // 0.0 = no correction; 1.0 = full correction #define BACKLASH_CORRECTION 0.0 // 0.0 = no correction; 1.0 = full correction
// Add steps for motor direction changes on CORE kinematics // Add steps for motor direction changes on CORE kinematics
@@ -1063,13 +1040,6 @@
#define CALIBRATION_MEASURE_LEFT #define CALIBRATION_MEASURE_LEFT
#define CALIBRATION_MEASURE_BACK #define CALIBRATION_MEASURE_BACK
//#define CALIBRATION_MEASURE_IMIN
//#define CALIBRATION_MEASURE_IMAX
//#define CALIBRATION_MEASURE_JMIN
//#define CALIBRATION_MEASURE_JMAX
//#define CALIBRATION_MEASURE_KMIN
//#define CALIBRATION_MEASURE_KMAX
// Probing at the exact top center only works if the center is flat. If // Probing at the exact top center only works if the center is flat. If
// probing on a screwhead or hollow washer, probe near the edges. // probing on a screwhead or hollow washer, probe near the edges.
//#define CALIBRATION_MEASURE_AT_TOP_EDGES //#define CALIBRATION_MEASURE_AT_TOP_EDGES
@@ -1594,7 +1564,7 @@
*/ */
//#define STATUS_COMBINE_HEATERS // Use combined heater images instead of separate ones //#define STATUS_COMBINE_HEATERS // Use combined heater images instead of separate ones
//#define STATUS_HOTEND_NUMBERLESS // Use plain hotend icons instead of numbered ones (with 2+ hotends) //#define STATUS_HOTEND_NUMBERLESS // Use plain hotend icons instead of numbered ones (with 2+ hotends)
#define STATUS_HOTEND_INVERTED // Show solid nozzle bitmaps when heating (Requires STATUS_HOTEND_ANIM for numbered hotends) #define STATUS_HOTEND_INVERTED // Show solid nozzle bitmaps when heating (Requires STATUS_HOTEND_ANIM)
#define STATUS_HOTEND_ANIM // Use a second bitmap to indicate hotend heating #define STATUS_HOTEND_ANIM // Use a second bitmap to indicate hotend heating
#define STATUS_BED_ANIM // Use a second bitmap to indicate bed heating #define STATUS_BED_ANIM // Use a second bitmap to indicate bed heating
#define STATUS_CHAMBER_ANIM // Use a second bitmap to indicate chamber heating #define STATUS_CHAMBER_ANIM // Use a second bitmap to indicate chamber heating
@@ -1972,30 +1942,30 @@
//#define USE_TEMP_EXT_COMPENSATION //#define USE_TEMP_EXT_COMPENSATION
// Probe temperature calibration generates a table of values starting at PTC_SAMPLE_START // 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. // (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_START 30.0f
//#define PTC_SAMPLE_RES 5 // (°C) //#define PTC_SAMPLE_RES 5.0f
//#define PTC_SAMPLE_COUNT 10 //#define PTC_SAMPLE_COUNT 10U
// Bed temperature calibration builds a similar table. // Bed temperature calibration builds a similar table.
//#define BTC_SAMPLE_START 60 // (°C) //#define BTC_SAMPLE_START 60.0f
//#define BTC_SAMPLE_RES 5 // (°C) //#define BTC_SAMPLE_RES 5.0f
//#define BTC_SAMPLE_COUNT 10 //#define BTC_SAMPLE_COUNT 10U
// The temperature the probe should be at while taking measurements during bed temperature // The temperature the probe should be at while taking measurements during bed temperature
// calibration. // calibration.
//#define BTC_PROBE_TEMP 30 // (°C) //#define BTC_PROBE_TEMP 30.0f
// Height above Z=0.0 to raise the nozzle. Lowering this can help the probe to heat faster. // Height above Z=0.0f 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. // Note: the Z=0.0f offset is determined by the probe offset which can be set using M851.
//#define PTC_PROBE_HEATING_OFFSET 0.5 //#define PTC_PROBE_HEATING_OFFSET 0.5f
// Height to raise the Z-probe between heating and taking the next measurement. Some probes // 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 // 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. // increasing the height the probe is raised to.
//#define PTC_PROBE_RAISE 15 //#define PTC_PROBE_RAISE 15U
// If the probe is outside of the defined range, use linear extrapolation using the closest // 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] // point and the PTC_LINEAR_EXTRAPOLATION'th next point. E.g. if set to 4 it will use data[0]
@@ -2110,7 +2080,7 @@
// @section motion // @section motion
// The number of linear moves that can be in the planner at once. // The number of linear moves that can be in the planner at once.
// The value of BLOCK_BUFFER_SIZE must be a power of 2 (e.g., 8, 16, 32) // The value of BLOCK_BUFFER_SIZE must be a power of 2 (e.g. 8, 16, 32)
#if BOTH(SDSUPPORT, DIRECT_STEPPING) #if BOTH(SDSUPPORT, DIRECT_STEPPING)
#define BLOCK_BUFFER_SIZE 8 #define BLOCK_BUFFER_SIZE 8
#elif ENABLED(SDSUPPORT) #elif ENABLED(SDSUPPORT)
@@ -2266,13 +2236,6 @@
//#define EVENT_GCODE_AFTER_TOOLCHANGE "G12X" // Extra G-code to run after tool-change //#define EVENT_GCODE_AFTER_TOOLCHANGE "G12X" // Extra G-code to run after tool-change
#endif #endif
/**
* Extra G-code to run while executing tool-change commands. Can be used to use an additional
* stepper motor (I axis, see option LINEAR_AXES in Configuration.h) to drive the tool-changer.
*/
//#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
/** /**
* Tool Sensors detect when tools have been picked up or dropped. * Tool Sensors detect when tools have been picked up or dropped.
* Requires the pins TOOL_SENSOR1_PIN, TOOL_SENSOR2_PIN, etc. * Requires the pins TOOL_SENSOR1_PIN, TOOL_SENSOR2_PIN, etc.
@@ -2398,7 +2361,7 @@
* TMC26X Stepper Driver options * TMC26X Stepper Driver options
* *
* The TMC26XStepper library is required for this stepper driver. * The TMC26XStepper library is required for this stepper driver.
* https://github.com/trinamic/TMC26XStepper * https://github.com/MarlinFirmware/TMC26XStepper
*/ */
#if HAS_DRIVER(TMC26X) #if HAS_DRIVER(TMC26X)
@@ -2450,24 +2413,6 @@
#define Z4_MICROSTEPS Z_MICROSTEPS #define Z4_MICROSTEPS Z_MICROSTEPS
#endif #endif
#if AXIS_DRIVER_TYPE_I(TMC26X)
#define I_MAX_CURRENT 1000
#define I_SENSE_RESISTOR 91
#define I_MICROSTEPS 16
#endif
#if AXIS_DRIVER_TYPE_J(TMC26X)
#define J_MAX_CURRENT 1000
#define J_SENSE_RESISTOR 91
#define J_MICROSTEPS 16
#endif
#if AXIS_DRIVER_TYPE_K(TMC26X)
#define K_MAX_CURRENT 1000
#define K_SENSE_RESISTOR 91
#define K_MICROSTEPS 16
#endif
#if AXIS_DRIVER_TYPE_E0(TMC26X) #if AXIS_DRIVER_TYPE_E0(TMC26X)
#define E0_MAX_CURRENT 1000 #define E0_MAX_CURRENT 1000
#define E0_SENSE_RESISTOR 91 #define E0_SENSE_RESISTOR 91
@@ -2618,33 +2563,6 @@
//#define Z4_INTERPOLATE true //#define Z4_INTERPOLATE true
#endif #endif
#if AXIS_IS_TMC(I)
#define I_CURRENT 800
#define I_CURRENT_HOME I_CURRENT
#define I_MICROSTEPS 16
#define I_RSENSE 0.11
#define I_CHAIN_POS -1
//#define I_INTERPOLATE true
#endif
#if AXIS_IS_TMC(J)
#define J_CURRENT 800
#define J_CURRENT_HOME J_CURRENT
#define J_MICROSTEPS 16
#define J_RSENSE 0.11
#define J_CHAIN_POS -1
//#define J_INTERPOLATE true
#endif
#if AXIS_IS_TMC(K)
#define K_CURRENT 800
#define K_CURRENT_HOME K_CURRENT
#define K_MICROSTEPS 16
#define K_RSENSE 0.11
#define K_CHAIN_POS -1
//#define K_INTERPOLATE true
#endif
#if AXIS_IS_TMC(E0) #if AXIS_IS_TMC(E0)
#define E0_CURRENT 800 #define E0_CURRENT 800
#define E0_MICROSTEPS 16 #define E0_MICROSTEPS 16
@@ -2720,10 +2638,6 @@
//#define Y2_CS_PIN -1 //#define Y2_CS_PIN -1
//#define Z2_CS_PIN -1 //#define Z2_CS_PIN -1
//#define Z3_CS_PIN -1 //#define Z3_CS_PIN -1
//#define Z4_CS_PIN -1
//#define I_CS_PIN -1
//#define J_CS_PIN -1
//#define K_CS_PIN -1
//#define E0_CS_PIN -1 //#define E0_CS_PIN -1
//#define E1_CS_PIN -1 //#define E1_CS_PIN -1
//#define E2_CS_PIN -1 //#define E2_CS_PIN -1
@@ -2763,9 +2677,6 @@
//#define Z2_SLAVE_ADDRESS 0 //#define Z2_SLAVE_ADDRESS 0
//#define Z3_SLAVE_ADDRESS 0 //#define Z3_SLAVE_ADDRESS 0
//#define Z4_SLAVE_ADDRESS 0 //#define Z4_SLAVE_ADDRESS 0
//#define I_SLAVE_ADDRESS 0
//#define J_SLAVE_ADDRESS 0
//#define K_SLAVE_ADDRESS 0
//#define E0_SLAVE_ADDRESS 0 //#define E0_SLAVE_ADDRESS 0
//#define E1_SLAVE_ADDRESS 0 //#define E1_SLAVE_ADDRESS 0
//#define E2_SLAVE_ADDRESS 0 //#define E2_SLAVE_ADDRESS 0
@@ -2790,9 +2701,6 @@
*/ */
#define STEALTHCHOP_XY #define STEALTHCHOP_XY
#define STEALTHCHOP_Z #define STEALTHCHOP_Z
#define STEALTHCHOP_I
#define STEALTHCHOP_J
#define STEALTHCHOP_K
#define STEALTHCHOP_E #define STEALTHCHOP_E
/** /**
@@ -2864,9 +2772,6 @@
#define Z2_HYBRID_THRESHOLD 3 #define Z2_HYBRID_THRESHOLD 3
#define Z3_HYBRID_THRESHOLD 3 #define Z3_HYBRID_THRESHOLD 3
#define Z4_HYBRID_THRESHOLD 3 #define Z4_HYBRID_THRESHOLD 3
#define I_HYBRID_THRESHOLD 3
#define J_HYBRID_THRESHOLD 3
#define K_HYBRID_THRESHOLD 3
#define E0_HYBRID_THRESHOLD 30 #define E0_HYBRID_THRESHOLD 30
#define E1_HYBRID_THRESHOLD 30 #define E1_HYBRID_THRESHOLD 30
#define E2_HYBRID_THRESHOLD 30 #define E2_HYBRID_THRESHOLD 30
@@ -2892,7 +2797,7 @@
* *
* It is recommended to set HOMING_BUMP_MM to { 0, 0, 0 }. * It is recommended to set HOMING_BUMP_MM to { 0, 0, 0 }.
* *
* SPI_ENDSTOPS *** Beta feature! *** TMC2130/TMC5160 Only *** * SPI_ENDSTOPS *** Beta feature! *** TMC2130 Only ***
* Poll the driver through SPI to determine load when homing. * Poll the driver through SPI to determine load when homing.
* Removes the need for a wire from DIAG1 to an endstop pin. * Removes the need for a wire from DIAG1 to an endstop pin.
* *
@@ -2913,9 +2818,6 @@
//#define Z2_STALL_SENSITIVITY Z_STALL_SENSITIVITY //#define Z2_STALL_SENSITIVITY Z_STALL_SENSITIVITY
//#define Z3_STALL_SENSITIVITY Z_STALL_SENSITIVITY //#define Z3_STALL_SENSITIVITY Z_STALL_SENSITIVITY
//#define Z4_STALL_SENSITIVITY Z_STALL_SENSITIVITY //#define Z4_STALL_SENSITIVITY Z_STALL_SENSITIVITY
//#define I_STALL_SENSITIVITY 8
//#define J_STALL_SENSITIVITY 8
//#define K_STALL_SENSITIVITY 8
//#define SPI_ENDSTOPS // TMC2130 only //#define SPI_ENDSTOPS // TMC2130 only
//#define IMPROVE_HOMING_RELIABILITY //#define IMPROVE_HOMING_RELIABILITY
#endif #endif
@@ -3056,33 +2958,6 @@
#define Z4_SLEW_RATE 1 #define Z4_SLEW_RATE 1
#endif #endif
#if AXIS_DRIVER_TYPE_I(L6470)
#define I_MICROSTEPS 128
#define I_OVERCURRENT 2000
#define I_STALLCURRENT 1500
#define I_MAX_VOLTAGE 127
#define I_CHAIN_POS -1
#define I_SLEW_RATE 1
#endif
#if AXIS_DRIVER_TYPE_J(L6470)
#define J_MICROSTEPS 128
#define J_OVERCURRENT 2000
#define J_STALLCURRENT 1500
#define J_MAX_VOLTAGE 127
#define J_CHAIN_POS -1
#define J_SLEW_RATE 1
#endif
#if AXIS_DRIVER_TYPE_K(L6470)
#define K_MICROSTEPS 128
#define K_OVERCURRENT 2000
#define K_STALLCURRENT 1500
#define K_MAX_VOLTAGE 127
#define K_CHAIN_POS -1
#define K_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(E0) #if AXIS_IS_L64XX(E0)
#define E0_MICROSTEPS 128 #define E0_MICROSTEPS 128
#define E0_OVERCURRENT 2000 #define E0_OVERCURRENT 2000
@@ -3432,18 +3307,8 @@
#define SPINDLE_LASER_POWERDOWN_DELAY 50 // (ms) Delay to allow the spindle to stop #define SPINDLE_LASER_POWERDOWN_DELAY 50 // (ms) Delay to allow the spindle to stop
#endif #endif
//
// Laser I2C Ammeter (High precision INA226 low/high side module)
//
//#define I2C_AMMETER
#if ENABLED(I2C_AMMETER)
#define I2C_AMMETER_IMAX 0.1 // (Amps) Calibration value for the expected current range
#define I2C_AMMETER_SHUNT_RESISTOR 0.1 // (Ohms) Calibration shunt resistor value
#endif
#endif #endif
#endif // SPINDLE_FEATURE || LASER_FEATURE #endif
/** /**
* Synchronous Laser Control with M106/M107 * Synchronous Laser Control with M106/M107

View File

@@ -28,7 +28,7 @@
/** /**
* Marlin release version identifier * Marlin release version identifier
*/ */
//#define SHORT_BUILD_VERSION "2.0.9.1" //#define SHORT_BUILD_VERSION "2.0.8.4"
/** /**
* Verbose version identifier which should contain a reference to the location * Verbose version identifier which should contain a reference to the location
@@ -41,7 +41,7 @@
* here we define this default string as the date where the latest release * here we define this default string as the date where the latest release
* version was tagged. * version was tagged.
*/ */
//#define STRING_DISTRIBUTION_DATE "2021-06-27" //#define STRING_DISTRIBUTION_DATE "2023-12-08"
/** /**
* Defines a generic printer name to be output to the LCD after booting Marlin. * Defines a generic printer name to be output to the LCD after booting Marlin.

View File

@@ -186,7 +186,7 @@ inline void HAL_adc_init() {
#define GET_PIN_MAP_INDEX(pin) pin #define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval) #define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
#define HAL_SENSITIVE_PINS 0, 1, #define HAL_SENSITIVE_PINS 0, 1
#ifdef __AVR_AT90USB1286__ #ifdef __AVR_AT90USB1286__
#define JTAG_DISABLE() do{ MCUCR = 0x80; MCUCR = 0x80; }while(0) #define JTAG_DISABLE() do{ MCUCR = 0x80; MCUCR = 0x80; }while(0)

View File

@@ -168,51 +168,6 @@ void setup_endstop_interrupts() {
pciSetup(Z_MIN_PIN); pciSetup(Z_MIN_PIN);
#endif #endif
#endif #endif
#if HAS_I_MAX
#if (digitalPinToInterrupt(I_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(I_MAX_PIN);
#else
static_assert(digitalPinHasPCICR(I_MAX_PIN), "I_MAX_PIN is not interrupt-capable");
pciSetup(I_MAX_PIN);
#endif
#elif HAS_I_MIN
#if (digitalPinToInterrupt(I_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(I_MIN_PIN);
#else
static_assert(digitalPinHasPCICR(I_MIN_PIN), "I_MIN_PIN is not interrupt-capable");
pciSetup(I_MIN_PIN);
#endif
#endif
#if HAS_J_MAX
#if (digitalPinToInterrupt(J_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(J_MAX_PIN);
#else
static_assert(digitalPinHasPCICR(J_MAX_PIN), "J_MAX_PIN is not interrupt-capable");
pciSetup(J_MAX_PIN);
#endif
#elif HAS_J_MIN
#if (digitalPinToInterrupt(J_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(J_MIN_PIN);
#else
static_assert(digitalPinHasPCICR(J_MIN_PIN), "J_MIN_PIN is not interrupt-capable");
pciSetup(J_MIN_PIN);
#endif
#endif
#if HAS_K_MAX
#if (digitalPinToInterrupt(K_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(K_MAX_PIN);
#else
static_assert(digitalPinHasPCICR(K_MAX_PIN), "K_MAX_PIN is not interrupt-capable");
pciSetup(K_MAX_PIN);
#endif
#elif HAS_K_MIN
#if (digitalPinToInterrupt(K_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(K_MIN_PIN);
#else
static_assert(digitalPinHasPCICR(K_MIN_PIN), "K_MIN_PIN is not interrupt-capable");
pciSetup(K_MIN_PIN);
#endif
#endif
#if HAS_X2_MAX #if HAS_X2_MAX
#if (digitalPinToInterrupt(X2_MAX_PIN) != NOT_AN_INTERRUPT) #if (digitalPinToInterrupt(X2_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X2_MAX_PIN); _ATTACH(X2_MAX_PIN);
@@ -301,5 +256,6 @@ void setup_endstop_interrupts() {
pciSetup(Z_MIN_PROBE_PIN); pciSetup(Z_MIN_PROBE_PIN);
#endif #endif
#endif #endif
// If we arrive here without raising an assertion, each pin has either an EXT-interrupt or a PCI. // If we arrive here without raising an assertion, each pin has either an EXT-interrupt or a PCI.
} }

View File

@@ -64,10 +64,4 @@ void setup_endstop_interrupts() {
TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN));
TERN_(HAS_I_MAX, _ATTACH(I_MAX_PIN));
TERN_(HAS_I_MIN, _ATTACH(I_MIN_PIN));
TERN_(HAS_J_MAX, _ATTACH(J_MAX_PIN));
TERN_(HAS_J_MIN, _ATTACH(J_MIN_PIN));
TERN_(HAS_K_MAX, _ATTACH(K_MAX_PIN));
TERN_(HAS_K_MIN, _ATTACH(K_MIN_PIN));
} }

View File

@@ -59,10 +59,4 @@ void setup_endstop_interrupts() {
TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN));
TERN_(HAS_I_MAX, _ATTACH(I_MAX_PIN));
TERN_(HAS_I_MIN, _ATTACH(I_MIN_PIN));
TERN_(HAS_J_MAX, _ATTACH(J_MAX_PIN));
TERN_(HAS_J_MIN, _ATTACH(J_MIN_PIN));
TERN_(HAS_K_MAX, _ATTACH(K_MAX_PIN));
TERN_(HAS_K_MIN, _ATTACH(K_MIN_PIN));
} }

View File

@@ -25,6 +25,43 @@
#include "../../../gcode/parser.h" #include "../../../gcode/parser.h"
uint8_t analog_offset = NUM_DIGITAL_PINS - NUM_ANALOG_INPUTS;
// Get the digital pin for an analog index
pin_t analogInputToDigitalPin(const int8_t p) {
return (WITHIN(p, 0, NUM_ANALOG_INPUTS) ? analog_offset + p : P_NC);
}
// Return the index of a pin number
int16_t GET_PIN_MAP_INDEX(const pin_t pin) {
return pin;
}
// Test whether the pin is valid
bool VALID_PIN(const pin_t p) {
return WITHIN(p, 0, NUM_DIGITAL_PINS);
}
// Get the analog index for a digital pin
int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t p) {
return (WITHIN(p, analog_offset, NUM_DIGITAL_PINS) ? p - analog_offset : P_NC);
}
// Test whether the pin is PWM
bool PWM_PIN(const pin_t p) {
return false;
}
// Test whether the pin is interruptable
bool INTERRUPT_PIN(const pin_t p) {
return false;
}
// Get the pin number at the given index
pin_t GET_PIN_MAP_PIN(const int16_t ind) {
return ind;
}
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) { int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) {
return parser.intval(code, dval); return parser.intval(code, dval);
} }

View File

@@ -34,32 +34,26 @@ constexpr uint8_t NUM_ANALOG_INPUTS = 16;
#define HAL_SENSITIVE_PINS #define HAL_SENSITIVE_PINS
constexpr uint8_t analog_offset = NUM_DIGITAL_PINS - NUM_ANALOG_INPUTS;
// Get the digital pin for an analog index // Get the digital pin for an analog index
constexpr pin_t analogInputToDigitalPin(const int8_t p) { pin_t analogInputToDigitalPin(const int8_t p);
return (WITHIN(p, 0, NUM_ANALOG_INPUTS) ? analog_offset + p : P_NC);
}
// Get the analog index for a digital pin
constexpr int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t p) {
return (WITHIN(p, analog_offset, NUM_DIGITAL_PINS) ? p - analog_offset : P_NC);
}
// Return the index of a pin number // Return the index of a pin number
constexpr int16_t GET_PIN_MAP_INDEX(const pin_t pin) { return pin; } int16_t GET_PIN_MAP_INDEX(const pin_t pin);
// Test whether the pin is valid // Test whether the pin is valid
constexpr bool VALID_PIN(const pin_t p) { return WITHIN(p, 0, NUM_DIGITAL_PINS); } bool VALID_PIN(const pin_t p);
// Get the analog index for a digital pin
int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t p);
// Test whether the pin is PWM // Test whether the pin is PWM
constexpr bool PWM_PIN(const pin_t p) { return false; } bool PWM_PIN(const pin_t p);
// Test whether the pin is interruptable // Test whether the pin is interruptable
constexpr bool INTERRUPT_PIN(const pin_t p) { return false; } bool INTERRUPT_PIN(const pin_t p);
// Get the pin number at the given index // Get the pin number at the given index
constexpr pin_t GET_PIN_MAP_PIN(const int16_t ind) { return ind; } pin_t GET_PIN_MAP_PIN(const int16_t ind);
// Parse a G-code word into a pin index // Parse a G-code word into a pin index
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval); int16_t PARSED_PIN_INDEX(const char code, const int16_t dval);

View File

@@ -198,7 +198,7 @@ constexpr pin_t GET_PIN_MAP_PIN(const int16_t index) {
// Parse a G-code word into a pin index // Parse a G-code word into a pin index
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval); int16_t PARSED_PIN_INDEX(const char code, const int16_t dval);
// P0.6 thru P0.9 are for the onboard SD card // P0.6 thru P0.9 are for the onboard SD card
#define HAL_SENSITIVE_PINS P0_06, P0_07, P0_08, P0_09, #define HAL_SENSITIVE_PINS P0_06, P0_07, P0_08, P0_09
#define HAL_IDLETASK 1 #define HAL_IDLETASK 1
void HAL_idletask(); void HAL_idletask();

View File

@@ -66,7 +66,11 @@
#include <SoftwareSPI.h> #include <SoftwareSPI.h>
static uint8_t SPI_speed = SPI_FULL_SPEED; #ifndef HAL_SPI_SPEED
#define HAL_SPI_SPEED SPI_FULL_SPEED
#endif
static uint8_t SPI_speed = HAL_SPI_SPEED;
static uint8_t spiTransfer(uint8_t b) { static uint8_t spiTransfer(uint8_t b) {
return swSpiTransfer(b, SPI_speed, SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN); return swSpiTransfer(b, SPI_speed, SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN);
@@ -102,13 +106,15 @@
#else #else
#ifdef SD_SPI_SPEED #ifndef HAL_SPI_SPEED
#define INIT_SPI_SPEED SD_SPI_SPEED #ifdef SD_SPI_SPEED
#else #define HAL_SPI_SPEED SD_SPI_SPEED
#define INIT_SPI_SPEED SPI_FULL_SPEED #else
#define HAL_SPI_SPEED SPI_FULL_SPEED
#endif
#endif #endif
void spiBegin() { spiInit(INIT_SPI_SPEED); } // Set up SCK, MOSI & MISO pins for SSP0 void spiBegin() { spiInit(HAL_SPI_SPEED); } // Set up SCK, MOSI & MISO pins for SSP0
void spiInit(uint8_t spiRate) { void spiInit(uint8_t spiRate) {
#if SD_MISO_PIN == BOARD_SPI1_MISO_PIN #if SD_MISO_PIN == BOARD_SPI1_MISO_PIN

View File

@@ -122,37 +122,4 @@ void setup_endstop_interrupts() {
#endif #endif
_ATTACH(Z_MIN_PROBE_PIN); _ATTACH(Z_MIN_PROBE_PIN);
#endif #endif
#if HAS_I_MAX
#if !LPC1768_PIN_INTERRUPT_M(I_MAX_PIN)
#error "I_MAX_PIN is not INTERRUPT-capable."
#endif
_ATTACH(I_MAX_PIN);
#elif HAS_I_MIN
#if !LPC1768_PIN_INTERRUPT_M(I_MIN_PIN)
#error "I_MIN_PIN is not INTERRUPT-capable."
#endif
_ATTACH(I_MIN_PIN);
#endif
#if HAS_J_MAX
#if !LPC1768_PIN_INTERRUPT_M(J_MAX_PIN)
#error "J_MAX_PIN is not INTERRUPT-capable."
#endif
_ATTACH(J_MAX_PIN);
#elif HAS_J_MIN
#if !LPC1768_PIN_INTERRUPT_M(J_MIN_PIN)
#error "J_MIN_PIN is not INTERRUPT-capable."
#endif
_ATTACH(J_MIN_PIN);
#endif
#if HAS_K_MAX
#if !LPC1768_PIN_INTERRUPT_M(K_MAX_PIN)
#error "K_MAX_PIN is not INTERRUPT-capable."
#endif
_ATTACH(K_MAX_PIN);
#elif HAS_K_MIN
#if !LPC1768_PIN_INTERRUPT_M(K_MIN_PIN)
#error "K_MIN_PIN is not INTERRUPT-capable."
#endif
_ATTACH(K_MIN_PIN);
#endif
} }

View File

@@ -54,7 +54,7 @@ enum XPTCoordinate : uint8_t {
XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE, XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE,
}; };
#ifndef XPT2046_Z1_THRESHOLD #if !defined(XPT2046_Z1_THRESHOLD)
#define XPT2046_Z1_THRESHOLD 10 #define XPT2046_Z1_THRESHOLD 10
#endif #endif

View File

@@ -47,38 +47,80 @@
#include "../../module/endstops.h" #include "../../module/endstops.h"
#define MATCH_EILINE(P1,P2) (P1 != P2 && PIN_TO_EILINE(P1) == PIN_TO_EILINE(P2)) #define MATCH_EILINE(P1,P2) (P1 != P2 && PIN_TO_EILINE(P1) == PIN_TO_EILINE(P2))
#define MATCH_X_MAX_EILINE(P) TERN0(HAS_X_MAX, DEFER4(MATCH_EILINE)(P, X_MAX_PIN)) #if HAS_X_MAX
#define MATCH_X_MIN_EILINE(P) TERN0(HAS_X_MIN, DEFER4(MATCH_EILINE)(P, X_MIN_PIN)) #define MATCH_X_MAX_EILINE(P) MATCH_EILINE(P, X_MAX_PIN)
#define MATCH_Y_MAX_EILINE(P) TERN0(HAS_Y_MAX, DEFER4(MATCH_EILINE)(P, Y_MAX_PIN)) #else
#define MATCH_Y_MIN_EILINE(P) TERN0(HAS_Y_MIN, DEFER4(MATCH_EILINE)(P, Y_MIN_PIN)) #define MATCH_X_MAX_EILINE(P) false
#define MATCH_Z_MAX_EILINE(P) TERN0(HAS_Z_MAX, DEFER4(MATCH_EILINE)(P, Z_MAX_PIN)) #endif
#define MATCH_Z_MIN_EILINE(P) TERN0(HAS_Z_MIN, DEFER4(MATCH_EILINE)(P, Z_MIN_PIN)) #if HAS_X_MIN
#define MATCH_I_MAX_EILINE(P) TERN0(HAS_I_MAX, DEFER4(MATCH_EILINE)(P, I_MAX_PIN)) #define MATCH_X_MIN_EILINE(P) MATCH_EILINE(P, X_MIN_PIN)
#define MATCH_I_MIN_EILINE(P) TERN0(HAS_I_MIN, DEFER4(MATCH_EILINE)(P, I_MIN_PIN)) #else
#define MATCH_J_MAX_EILINE(P) TERN0(HAS_J_MAX, DEFER4(MATCH_EILINE)(P, J_MAX_PIN)) #define MATCH_X_MIN_EILINE(P) false
#define MATCH_J_MIN_EILINE(P) TERN0(HAS_J_MIN, DEFER4(MATCH_EILINE)(P, J_MIN_PIN)) #endif
#define MATCH_K_MAX_EILINE(P) TERN0(HAS_K_MAX, DEFER4(MATCH_EILINE)(P, K_MAX_PIN)) #if HAS_Y_MAX
#define MATCH_K_MIN_EILINE(P) TERN0(HAS_K_MIN, DEFER4(MATCH_EILINE)(P, K_MIN_PIN)) #define MATCH_Y_MAX_EILINE(P) MATCH_EILINE(P, Y_MAX_PIN)
#define MATCH_Z2_MAX_EILINE(P) TERN0(HAS_Z2_MAX, DEFER4(MATCH_EILINE)(P, Z2_MAX_PIN)) #else
#define MATCH_Z2_MIN_EILINE(P) TERN0(HAS_Z2_MIN, DEFER4(MATCH_EILINE)(P, Z2_MIN_PIN)) #define MATCH_Y_MAX_EILINE(P) false
#define MATCH_Z3_MAX_EILINE(P) TERN0(HAS_Z3_MAX, DEFER4(MATCH_EILINE)(P, Z3_MAX_PIN)) #endif
#define MATCH_Z3_MIN_EILINE(P) TERN0(HAS_Z3_MIN, DEFER4(MATCH_EILINE)(P, Z3_MIN_PIN)) #if HAS_Y_MIN
#define MATCH_Z4_MAX_EILINE(P) TERN0(HAS_Z4_MAX, DEFER4(MATCH_EILINE)(P, Z4_MAX_PIN)) #define MATCH_Y_MIN_EILINE(P) MATCH_EILINE(P, Y_MIN_PIN)
#define MATCH_Z4_MIN_EILINE(P) TERN0(HAS_Z4_MIN, DEFER4(MATCH_EILINE)(P, Z4_MIN_PIN)) #else
#define MATCH_Z_MIN_PROBE_EILINE(P) TERN0(HAS_Z_MIN_PROBE_PIN, DEFER4(MATCH_EILINE)(P, Z_MIN_PROBE_PIN)) #define MATCH_Y_MIN_EILINE(P) false
#endif
#define AVAILABLE_EILINE(P) ( PIN_TO_EILINE(P) != -1 \ #if HAS_Z_MAX
&& !MATCH_X_MAX_EILINE(P) && !MATCH_X_MIN_EILINE(P) \ #define MATCH_Z_MAX_EILINE(P) MATCH_EILINE(P, Z_MAX_PIN)
&& !MATCH_Y_MAX_EILINE(P) && !MATCH_Y_MIN_EILINE(P) \ #else
&& !MATCH_Z_MAX_EILINE(P) && !MATCH_Z_MIN_EILINE(P) \ #define MATCH_Z_MAX_EILINE(P) false
&& !MATCH_I_MAX_EILINE(P) && !MATCH_I_MIN_EILINE(P) \ #endif
&& !MATCH_J_MAX_EILINE(P) && !MATCH_J_MIN_EILINE(P) \ #if HAS_Z_MIN
&& !MATCH_K_MAX_EILINE(P) && !MATCH_K_MIN_EILINE(P) \ #define MATCH_Z_MIN_EILINE(P) MATCH_EILINE(P, Z_MIN_PIN)
&& !MATCH_Z2_MAX_EILINE(P) && !MATCH_Z2_MIN_EILINE(P) \ #else
&& !MATCH_Z3_MAX_EILINE(P) && !MATCH_Z3_MIN_EILINE(P) \ #define MATCH_Z_MIN_EILINE(P) false
&& !MATCH_Z4_MAX_EILINE(P) && !MATCH_Z4_MIN_EILINE(P) \ #endif
&& !MATCH_Z_MIN_PROBE_EILINE(P) ) #if HAS_Z2_MAX
#define MATCH_Z2_MAX_EILINE(P) MATCH_EILINE(P, Z2_MAX_PIN)
#else
#define MATCH_Z2_MAX_EILINE(P) false
#endif
#if HAS_Z2_MIN
#define MATCH_Z2_MIN_EILINE(P) MATCH_EILINE(P, Z2_MIN_PIN)
#else
#define MATCH_Z2_MIN_EILINE(P) false
#endif
#if HAS_Z3_MAX
#define MATCH_Z3_MAX_EILINE(P) MATCH_EILINE(P, Z3_MAX_PIN)
#else
#define MATCH_Z3_MAX_EILINE(P) false
#endif
#if HAS_Z3_MIN
#define MATCH_Z3_MIN_EILINE(P) MATCH_EILINE(P, Z3_MIN_PIN)
#else
#define MATCH_Z3_MIN_EILINE(P) false
#endif
#if HAS_Z4_MAX
#define MATCH_Z4_MAX_EILINE(P) MATCH_EILINE(P, Z4_MAX_PIN)
#else
#define MATCH_Z4_MAX_EILINE(P) false
#endif
#if HAS_Z4_MIN
#define MATCH_Z4_MIN_EILINE(P) MATCH_EILINE(P, Z4_MIN_PIN)
#else
#define MATCH_Z4_MIN_EILINE(P) false
#endif
#if HAS_Z_MIN_PROBE_PIN
#define MATCH_Z_MIN_PROBE_EILINE(P) MATCH_EILINE(P, Z_MIN_PROBE_PIN)
#else
#define MATCH_Z_MIN_PROBE_EILINE(P) false
#endif
#define AVAILABLE_EILINE(P) (PIN_TO_EILINE(P) != -1 \
&& !MATCH_X_MAX_EILINE(P) && !MATCH_X_MIN_EILINE(P) \
&& !MATCH_Y_MAX_EILINE(P) && !MATCH_Y_MIN_EILINE(P) \
&& !MATCH_Z_MAX_EILINE(P) && !MATCH_Z_MIN_EILINE(P) \
&& !MATCH_Z2_MAX_EILINE(P) && !MATCH_Z2_MIN_EILINE(P) \
&& !MATCH_Z3_MAX_EILINE(P) && !MATCH_Z3_MIN_EILINE(P) \
&& !MATCH_Z4_MAX_EILINE(P) && !MATCH_Z4_MIN_EILINE(P) \
&& !MATCH_Z_MIN_PROBE_EILINE(P))
// One ISR for all EXT-Interrupts // One ISR for all EXT-Interrupts
void endstop_ISR() { endstops.update(); } void endstop_ISR() { endstops.update(); }
@@ -162,37 +204,5 @@ void setup_endstop_interrupts() {
#error "Z_MIN_PROBE_PIN has no EXTINT line available." #error "Z_MIN_PROBE_PIN has no EXTINT line available."
#endif #endif
_ATTACH(Z_MIN_PROBE_PIN); _ATTACH(Z_MIN_PROBE_PIN);
#elif 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
#if !AVAILABLE_EILINE(I_MIN_PIN)
#error "I_MIN_PIN has no EXTINT line available."
#endif
attachInterrupt(I_MIN_PIN, endstop_ISR, CHANGE);
#endif
#if HAS_J_MAX
#if !AVAILABLE_EILINE(J_MAX_PIN)
#error "J_MAX_PIN has no EXTINT line available."
#endif
attachInterrupt(J_MAX_PIN, endstop_ISR, CHANGE);
#elif HAS_J_MIN
#if !AVAILABLE_EILINE(J_MIN_PIN)
#error "J_MIN_PIN has no EXTINT line available."
#endif
attachInterrupt(J_MIN_PIN, endstop_ISR, CHANGE);
#endif
#if HAS_K_MAX
#if !AVAILABLE_EILINE(K_MAX_PIN)
#error "K_MAX_PIN has no EXTINT line available."
#endif
attachInterrupt(K_MAX_PIN, endstop_ISR, CHANGE);
#elif HAS_K_MIN
#if !AVAILABLE_EILINE(K_MIN_PIN)
#error "K_MIN_PIN has no EXTINT line available."
#endif
attachInterrupt(K_MIN_PIN, endstop_ISR, CHANGE);
#endif #endif
} }

View File

@@ -195,7 +195,6 @@ uint16_t HAL_adc_get_result();
#ifdef STM32F1xx #ifdef STM32F1xx
#define JTAG_DISABLE() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_JTAGDISABLE) #define JTAG_DISABLE() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_JTAGDISABLE)
#define JTAGSWD_DISABLE() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_DISABLE) #define JTAGSWD_DISABLE() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_DISABLE)
#define JTAGSWD_RESET() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_RESET); // Reset: FULL SWD+JTAG
#endif #endif
#define PLATFORM_M997_SUPPORT #define PLATFORM_M997_SUPPORT

View File

@@ -163,9 +163,11 @@ static SPISettings spiConfig;
} }
spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0); spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0);
SPI.setMISO(SD_MISO_PIN); #if ENABLED(CUSTOM_SPI_PINS)
SPI.setMOSI(SD_MOSI_PIN); SPI.setMISO(SD_MISO_PIN);
SPI.setSCLK(SD_SCK_PIN); SPI.setMOSI(SD_MOSI_PIN);
SPI.setSCLK(SD_SCK_PIN);
#endif
SPI.begin(); SPI.begin();
} }

View File

@@ -1,82 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifdef STM32F1
/**
* PersistentStore for Arduino-style EEPROM interface
* with simple implementations supplied by Marlin.
*/
#include "../../inc/MarlinConfig.h"
#if ENABLED(IIC_BL24CXX_EEPROM)
#include "../shared/eeprom_if.h"
#include "../shared/eeprom_api.h"
//
// PersistentStore
//
#ifndef MARLIN_EEPROM_SIZE
#error "MARLIN_EEPROM_SIZE is required for IIC_BL24CXX_EEPROM."
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
bool PersistentStore::access_start() { eeprom_init(); return true; }
bool PersistentStore::access_finish() { return true; }
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
uint16_t written = 0;
while (size--) {
uint8_t v = *value;
uint8_t * const p = (uint8_t * const)pos;
if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
eeprom_write_byte(p, v);
if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes
if (eeprom_read_byte(p) != v) {
SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE);
return true;
}
}
crc16(crc, &v, 1);
pos++;
value++;
}
return false;
}
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t * const p = (uint8_t * const)pos;
uint8_t c = eeprom_read_byte(p);
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;
value++;
} while (--size);
return false;
}
#endif // IIC_BL24CXX_EEPROM
#endif // STM32F1

View File

@@ -28,10 +28,6 @@
#include "../shared/eeprom_api.h" #include "../shared/eeprom_api.h"
// Better: "utility/stm32_eeprom.h", but only after updating stm32duino to 2.0.0
// Use EEPROM.h for compatibility, for now.
#include <EEPROM.h>
/** /**
* The STM32 HAL supports chips that deal with "pages" and some with "sectors" and some that * The STM32 HAL supports chips that deal with "pages" and some with "sectors" and some that
* even have multiple "banks" of flash. * even have multiple "banks" of flash.

View File

@@ -1,54 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/**
* Platform-independent Arduino functions for I2C EEPROM.
* Enable USE_SHARED_EEPROM if not supplied by the framework.
*/
#ifdef STM32F1
#include "../../inc/MarlinConfig.h"
#if ENABLED(IIC_BL24CXX_EEPROM)
#include "../../libs/BL24CXX.h"
#include "../shared/eeprom_if.h"
void eeprom_init() { BL24CXX::init(); }
// ------------------------
// Public functions
// ------------------------
void eeprom_write_byte(uint8_t *pos, uint8_t value) {
const unsigned eeprom_address = (unsigned)pos;
return BL24CXX::writeOneByte(eeprom_address, value);
}
uint8_t eeprom_read_byte(uint8_t *pos) {
const unsigned eeprom_address = (unsigned)pos;
return BL24CXX::readOneByte(eeprom_address);
}
#endif // IIC_BL24CXX_EEPROM
#endif // STM32F1

View File

@@ -46,10 +46,4 @@ void setup_endstop_interrupts() {
TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN));
TERN_(HAS_I_MAX, _ATTACH(I_MAX_PIN));
TERN_(HAS_I_MIN, _ATTACH(I_MIN_PIN));
TERN_(HAS_J_MAX, _ATTACH(J_MAX_PIN));
TERN_(HAS_J_MIN, _ATTACH(J_MIN_PIN));
TERN_(HAS_K_MAX, _ATTACH(K_MAX_PIN));
TERN_(HAS_K_MIN, _ATTACH(K_MIN_PIN));
} }

View File

@@ -21,7 +21,7 @@
*/ */
#pragma once #pragma once
#if BOTH(SDSUPPORT, USBD_USE_CDC_MSC) && DISABLED(NO_SD_HOST_DRIVE) #if defined(USBD_USE_CDC_MSC) && DISABLED(NO_SD_HOST_DRIVE)
#define HAS_SD_HOST_DRIVE 1 #define HAS_SD_HOST_DRIVE 1
#endif #endif
@@ -30,6 +30,3 @@
#undef F_CPU #undef F_CPU
#define F_CPU BOARD_F_CPU #define F_CPU BOARD_F_CPU
#endif #endif
// The Sensitive Pins array is not optimizable
#define RUNTIME_ONLY_ANALOG_TO_DIGITAL

View File

@@ -33,9 +33,9 @@ public:
DiskIODriver* diskIODriver() { DiskIODriver* diskIODriver() {
#if ENABLED(MULTI_VOLUME) #if ENABLED(MULTI_VOLUME)
#if SHARED_VOLUME_IS(SD_ONBOARD) #if SHARED_VOLUME_IS(SD_ONBOARD)
return &card.media_driver_sdcard; return &card.media_sd_spi;
#elif SHARED_VOLUME_IS(USB_FLASH_DRIVE) #elif SHARED_VOLUME_IS(USB_FLASH_DRIVE)
return &card.media_driver_usbFlash; return &card.media_usbFlashDrive;
#endif #endif
#else #else
return card.diskIODriver(); return card.diskIODriver();

View File

@@ -125,20 +125,12 @@ void TFT_SPI::DataTransferBegin(uint16_t DataSize) {
WRITE(TFT_CS_PIN, LOW); WRITE(TFT_CS_PIN, LOW);
} }
#ifdef TFT_DEFAULT_DRIVER
#include "../../../lcd/tft_io/tft_ids.h"
#endif
uint32_t TFT_SPI::GetID() { uint32_t TFT_SPI::GetID() {
uint32_t id; uint32_t id;
id = ReadID(LCD_READ_ID); id = ReadID(LCD_READ_ID);
if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF) {
if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF)
id = ReadID(LCD_READ_ID4); id = ReadID(LCD_READ_ID4);
#ifdef TFT_DEFAULT_DRIVER
if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF)
id = TFT_DEFAULT_DRIVER;
#endif
}
return id; return id;
} }

View File

@@ -56,7 +56,7 @@ enum XPTCoordinate : uint8_t {
XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE, XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE,
}; };
#ifndef XPT2046_Z1_THRESHOLD #if !defined(XPT2046_Z1_THRESHOLD)
#define XPT2046_Z1_THRESHOLD 10 #define XPT2046_Z1_THRESHOLD 10
#endif #endif

View File

@@ -167,15 +167,6 @@ constexpr bool IsSerialClassAllowed(const HardwareSerial&) { return false; }
#if AXIS_HAS_HW_SERIAL(Z4) #if AXIS_HAS_HW_SERIAL(Z4)
CHECK_AXIS_SERIAL(Z4); CHECK_AXIS_SERIAL(Z4);
#endif #endif
#if AXIS_HAS_HW_SERIAL(I)
CHECK_AXIS_SERIAL(I);
#endif
#if AXIS_HAS_HW_SERIAL(J)
CHECK_AXIS_SERIAL(J);
#endif
#if AXIS_HAS_HW_SERIAL(K)
CHECK_AXIS_SERIAL(K);
#endif
#if AXIS_HAS_HW_SERIAL(E0) #if AXIS_HAS_HW_SERIAL(E0)
CHECK_AXIS_SERIAL(E0); CHECK_AXIS_SERIAL(E0);
#endif #endif

View File

@@ -11,7 +11,6 @@ if __name__ == "__main__":
"-fsigned-char", "-fsigned-char",
"-fno-move-loop-invariants", "-fno-move-loop-invariants",
"-fno-strict-aliasing", "-fno-strict-aliasing",
"-fsingle-precision-constant",
"--specs=nano.specs", "--specs=nano.specs",
"--specs=nosys.specs", "--specs=nosys.specs",

View File

@@ -71,10 +71,4 @@ void setup_endstop_interrupts() {
TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN));
TERN_(HAS_I_MAX, _ATTACH(I_MAX_PIN));
TERN_(HAS_I_MIN, _ATTACH(I_MIN_PIN));
TERN_(HAS_J_MAX, _ATTACH(J_MAX_PIN));
TERN_(HAS_J_MIN, _ATTACH(J_MIN_PIN));
TERN_(HAS_K_MAX, _ATTACH(K_MAX_PIN));
TERN_(HAS_K_MIN, _ATTACH(K_MIN_PIN));
} }

View File

@@ -38,8 +38,8 @@
#define SPI_CLOCK_MAX SPI_BAUD_PCLK_DIV_2 #define SPI_CLOCK_MAX SPI_BAUD_PCLK_DIV_2
#endif #endif
#define CS_LOW() WRITE(ONBOARD_SD_CS_PIN, LOW) // Set OnboardSPI cs low #define CS_LOW() WRITE(ONBOARD_SD_CS_PIN, LOW) /* Set OnboardSPI cs low */
#define CS_HIGH() WRITE(ONBOARD_SD_CS_PIN, HIGH) // Set OnboardSPI cs high #define CS_HIGH() WRITE(ONBOARD_SD_CS_PIN, HIGH) /* Set OnboardSPI cs high */
#define FCLK_FAST() ONBOARD_SD_SPI.setClockDivider(SPI_CLOCK_MAX) #define FCLK_FAST() ONBOARD_SD_SPI.setClockDivider(SPI_CLOCK_MAX)
#define FCLK_SLOW() ONBOARD_SD_SPI.setClockDivider(SPI_BAUD_PCLK_DIV_256) #define FCLK_SLOW() ONBOARD_SD_SPI.setClockDivider(SPI_BAUD_PCLK_DIV_256)
@@ -49,32 +49,32 @@
---------------------------------------------------------------------------*/ ---------------------------------------------------------------------------*/
/* MMC/SD command */ /* MMC/SD command */
#define CMD0 (0) // GO_IDLE_STATE #define CMD0 (0) /* GO_IDLE_STATE */
#define CMD1 (1) // SEND_OP_COND (MMC) #define CMD1 (1) /* SEND_OP_COND (MMC) */
#define ACMD41 (0x80+41) // SEND_OP_COND (SDC) #define ACMD41 (0x80+41) /* SEND_OP_COND (SDC) */
#define CMD8 (8) // SEND_IF_COND #define CMD8 (8) /* SEND_IF_COND */
#define CMD9 (9) // SEND_CSD #define CMD9 (9) /* SEND_CSD */
#define CMD10 (10) // SEND_CID #define CMD10 (10) /* SEND_CID */
#define CMD12 (12) // STOP_TRANSMISSION #define CMD12 (12) /* STOP_TRANSMISSION */
#define ACMD13 (0x80+13) // SD_STATUS (SDC) #define ACMD13 (0x80+13) /* SD_STATUS (SDC) */
#define CMD16 (16) // SET_BLOCKLEN #define CMD16 (16) /* SET_BLOCKLEN */
#define CMD17 (17) // READ_SINGLE_BLOCK #define CMD17 (17) /* READ_SINGLE_BLOCK */
#define CMD18 (18) // READ_MULTIPLE_BLOCK #define CMD18 (18) /* READ_MULTIPLE_BLOCK */
#define CMD23 (23) // SET_BLOCK_COUNT (MMC) #define CMD23 (23) /* SET_BLOCK_COUNT (MMC) */
#define ACMD23 (0x80+23) // SET_WR_BLK_ERASE_COUNT (SDC) #define ACMD23 (0x80+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
#define CMD24 (24) // WRITE_BLOCK #define CMD24 (24) /* WRITE_BLOCK */
#define CMD25 (25) // WRITE_MULTIPLE_BLOCK #define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */
#define CMD32 (32) // ERASE_ER_BLK_START #define CMD32 (32) /* ERASE_ER_BLK_START */
#define CMD33 (33) // ERASE_ER_BLK_END #define CMD33 (33) /* ERASE_ER_BLK_END */
#define CMD38 (38) // ERASE #define CMD38 (38) /* ERASE */
#define CMD48 (48) // READ_EXTR_SINGLE #define CMD48 (48) /* READ_EXTR_SINGLE */
#define CMD49 (49) // WRITE_EXTR_SINGLE #define CMD49 (49) /* WRITE_EXTR_SINGLE */
#define CMD55 (55) // APP_CMD #define CMD55 (55) /* APP_CMD */
#define CMD58 (58) // READ_OCR #define CMD58 (58) /* READ_OCR */
static volatile DSTATUS Stat = STA_NOINIT; // Physical drive status static volatile DSTATUS Stat = STA_NOINIT; /* Physical drive status */
static volatile UINT timeout; static volatile UINT timeout;
static BYTE CardType; // Card type flags static BYTE CardType; /* Card type flags */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* Send/Receive data to the MMC (Platform dependent) */ /* Send/Receive data to the MMC (Platform dependent) */
@@ -82,7 +82,7 @@ static BYTE CardType; // Card type flags
/* Exchange a byte */ /* Exchange a byte */
static BYTE xchg_spi ( static BYTE xchg_spi (
BYTE dat // Data to send BYTE dat /* Data to send */
) { ) {
BYTE returnByte = ONBOARD_SD_SPI.transfer(dat); BYTE returnByte = ONBOARD_SD_SPI.transfer(dat);
return returnByte; return returnByte;
@@ -90,18 +90,18 @@ static BYTE xchg_spi (
/* Receive multiple byte */ /* Receive multiple byte */
static void rcvr_spi_multi ( static void rcvr_spi_multi (
BYTE *buff, // Pointer to data buffer BYTE *buff, /* Pointer to data buffer */
UINT btr // Number of bytes to receive (16, 64 or 512) UINT btr /* Number of bytes to receive (16, 64 or 512) */
) { ) {
ONBOARD_SD_SPI.dmaTransfer(0, const_cast<uint8_t*>(buff), btr); ONBOARD_SD_SPI.dmaTransfer(0, const_cast<uint8_t*>(buff), btr);
} }
#if _DISKIO_WRITE #if _DISKIO_WRITE
// Send multiple bytes /* Send multiple bytes */
static void xmit_spi_multi ( static void xmit_spi_multi (
const BYTE *buff, // Pointer to the data const BYTE *buff, /* Pointer to the data */
UINT btx // Number of bytes to send (multiple of 16) UINT btx /* Number of bytes to send (multiple of 16) */
) { ) {
ONBOARD_SD_SPI.dmaSend(const_cast<uint8_t*>(buff), btx); ONBOARD_SD_SPI.dmaSend(const_cast<uint8_t*>(buff), btx);
} }
@@ -112,15 +112,16 @@ static void rcvr_spi_multi (
/* Wait for card ready */ /* Wait for card ready */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static int wait_ready ( // 1:Ready, 0:Timeout static int wait_ready ( /* 1:Ready, 0:Timeout */
UINT wt // Timeout [ms] UINT wt /* Timeout [ms] */
) { ) {
BYTE d; BYTE d;
timeout = millis() + wt; timeout = millis() + wt;
do { do {
d = xchg_spi(0xFF); d = xchg_spi(0xFF);
// This loop takes a while. Insert rot_rdq() here for multitask environment. /* This loop takes a while. Insert rot_rdq() here for multitask environment. */
} while (d != 0xFF && (timeout > millis())); // Wait for card goes ready or timeout } while (d != 0xFF && (timeout > millis())); /* Wait for card goes ready or timeout */
return (d == 0xFF) ? 1 : 0; return (d == 0xFF) ? 1 : 0;
} }
@@ -130,21 +131,21 @@ static int wait_ready ( // 1:Ready, 0:Timeout
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static void deselect() { static void deselect() {
CS_HIGH(); // CS = H CS_HIGH(); /* CS = H */
xchg_spi(0xFF); // Dummy clock (force DO hi-z for multiple slave SPI) xchg_spi(0xFF); /* Dummy clock (force DO hi-z for multiple slave SPI) */
} }
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* Select card and wait for ready */ /* Select card and wait for ready */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static int select() { // 1:OK, 0:Timeout static int select() { /* 1:OK, 0:Timeout */
CS_LOW(); // CS = L CS_LOW(); /* CS = L */
xchg_spi(0xFF); // Dummy clock (force DO enabled) xchg_spi(0xFF); /* Dummy clock (force DO enabled) */
if (wait_ready(500)) return 1; // Leading busy check: Wait for card ready if (wait_ready(500)) return 1; /* Leading busy check: Wait for card ready */
deselect(); // Timeout deselect(); /* Timeout */
return 0; return 0;
} }
@@ -152,18 +153,16 @@ static int select() { // 1:OK, 0:Timeout
/* Control SPI module (Platform dependent) */ /* Control SPI module (Platform dependent) */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
// Enable SSP module and attach it to I/O pads static void power_on() { /* Enable SSP module and attach it to I/O pads */
static void sd_power_on() {
ONBOARD_SD_SPI.setModule(ONBOARD_SPI_DEVICE); ONBOARD_SD_SPI.setModule(ONBOARD_SPI_DEVICE);
ONBOARD_SD_SPI.begin(); ONBOARD_SD_SPI.begin();
ONBOARD_SD_SPI.setBitOrder(MSBFIRST); ONBOARD_SD_SPI.setBitOrder(MSBFIRST);
ONBOARD_SD_SPI.setDataMode(SPI_MODE0); ONBOARD_SD_SPI.setDataMode(SPI_MODE0);
OUT_WRITE(ONBOARD_SD_CS_PIN, HIGH); // Set CS# high OUT_WRITE(ONBOARD_SD_CS_PIN, HIGH); /* Set CS# high */
} }
// Disable SPI function static void power_off() { /* Disable SPI function */
static void sd_power_off() { select(); /* Wait for card ready */
select(); // Wait for card ready
deselect(); deselect();
} }
@@ -171,23 +170,23 @@ static void sd_power_off() {
/* Receive a data packet from the MMC */ /* Receive a data packet from the MMC */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static int rcvr_datablock ( // 1:OK, 0:Error static int rcvr_datablock ( /* 1:OK, 0:Error */
BYTE *buff, // Data buffer BYTE *buff, /* Data buffer */
UINT btr // Data block length (byte) UINT btr /* Data block length (byte) */
) { ) {
BYTE token; BYTE token;
timeout = millis() + 200; timeout = millis() + 200;
do { // Wait for DataStart token in timeout of 200ms do { /* Wait for DataStart token in timeout of 200ms */
token = xchg_spi(0xFF); token = xchg_spi(0xFF);
// This loop will take a while. Insert rot_rdq() here for multitask environment. /* This loop will take a while. Insert rot_rdq() here for multitask environment. */
} while ((token == 0xFF) && (timeout > millis())); } while ((token == 0xFF) && (timeout > millis()));
if (token != 0xFE) return 0; // Function fails if invalid DataStart token or timeout if (token != 0xFE) return 0; /* Function fails if invalid DataStart token or timeout */
rcvr_spi_multi(buff, btr); // Store trailing data to the buffer rcvr_spi_multi(buff, btr); /* Store trailing data to the buffer */
xchg_spi(0xFF); xchg_spi(0xFF); // Discard CRC xchg_spi(0xFF); xchg_spi(0xFF); /* Discard CRC */
return 1; // Function succeeded return 1; /* Function succeeded */
} }
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@@ -196,25 +195,25 @@ static int rcvr_datablock ( // 1:OK, 0:Error
#if _DISKIO_WRITE #if _DISKIO_WRITE
static int xmit_datablock( // 1:OK, 0:Failed static int xmit_datablock ( /* 1:OK, 0:Failed */
const BYTE *buff, // Pointer to 512 byte data to be sent const BYTE *buff, /* Ponter to 512 byte data to be sent */
BYTE token // Token BYTE token /* Token */
) { ) {
BYTE resp; BYTE resp;
if (!wait_ready(500)) return 0; // Leading busy check: Wait for card ready to accept data block if (!wait_ready(500)) return 0; /* Leading busy check: Wait for card ready to accept data block */
xchg_spi(token); // Send token xchg_spi(token); /* Send token */
if (token == 0xFD) return 1; // Do not send data if token is StopTran if (token == 0xFD) return 1; /* Do not send data if token is StopTran */
xmit_spi_multi(buff, 512); // Data xmit_spi_multi(buff, 512); /* Data */
xchg_spi(0xFF); xchg_spi(0xFF); // Dummy CRC xchg_spi(0xFF); xchg_spi(0xFF); /* Dummy CRC */
resp = xchg_spi(0xFF); // Receive data resp resp = xchg_spi(0xFF); /* Receive data resp */
return (resp & 0x1F) == 0x05 ? 1 : 0; // Data was accepted or not return (resp & 0x1F) == 0x05 ? 1 : 0; /* Data was accepted or not */
// Busy check is done at next transmission /* Busy check is done at next transmission */
} }
#endif // _DISKIO_WRITE #endif // _DISKIO_WRITE
@@ -223,43 +222,43 @@ static int rcvr_datablock ( // 1:OK, 0:Error
/* Send a command packet to the MMC */ /* Send a command packet to the MMC */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static BYTE send_cmd( // Return value: R1 resp (bit7==1:Failed to send) static BYTE send_cmd ( /* Return value: R1 resp (bit7==1:Failed to send) */
BYTE cmd, // Command index BYTE cmd, /* Command index */
DWORD arg // Argument DWORD arg /* Argument */
) { ) {
BYTE n, res; BYTE n, res;
if (cmd & 0x80) { // Send a CMD55 prior to ACMD<n> if (cmd & 0x80) { /* Send a CMD55 prior to ACMD<n> */
cmd &= 0x7F; cmd &= 0x7F;
res = send_cmd(CMD55, 0); res = send_cmd(CMD55, 0);
if (res > 1) return res; if (res > 1) return res;
} }
// Select the card and wait for ready except to stop multiple block read /* Select the card and wait for ready except to stop multiple block read */
if (cmd != CMD12) { if (cmd != CMD12) {
deselect(); deselect();
if (!select()) return 0xFF; if (!select()) return 0xFF;
} }
// Send command packet /* Send command packet */
xchg_spi(0x40 | cmd); // Start + command index xchg_spi(0x40 | cmd); /* Start + command index */
xchg_spi((BYTE)(arg >> 24)); // Argument[31..24] xchg_spi((BYTE)(arg >> 24)); /* Argument[31..24] */
xchg_spi((BYTE)(arg >> 16)); // Argument[23..16] xchg_spi((BYTE)(arg >> 16)); /* Argument[23..16] */
xchg_spi((BYTE)(arg >> 8)); // Argument[15..8] xchg_spi((BYTE)(arg >> 8)); /* Argument[15..8] */
xchg_spi((BYTE)arg); // Argument[7..0] xchg_spi((BYTE)arg); /* Argument[7..0] */
n = 0x01; // Dummy CRC + Stop n = 0x01; /* Dummy CRC + Stop */
if (cmd == CMD0) n = 0x95; // Valid CRC for CMD0(0) if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */
if (cmd == CMD8) n = 0x87; // Valid CRC for CMD8(0x1AA) if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */
xchg_spi(n); xchg_spi(n);
// Receive command response /* Receive command resp */
if (cmd == CMD12) xchg_spi(0xFF); // Discard the following byte when CMD12 if (cmd == CMD12) xchg_spi(0xFF); /* Diacard following one byte when CMD12 */
n = 10; // Wait for response (10 bytes max) n = 10; /* Wait for response (10 bytes max) */
do do
res = xchg_spi(0xFF); res = xchg_spi(0xFF);
while ((res & 0x80) && --n); while ((res & 0x80) && --n);
return res; // Return received response return res; /* Return received response */
} }
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
@@ -271,52 +270,49 @@ static BYTE send_cmd( // Return value: R1 resp (bit7==1:Failed to send)
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
DSTATUS disk_initialize ( DSTATUS disk_initialize (
BYTE drv // Physical drive number (0) BYTE drv /* Physical drive number (0) */
) { ) {
BYTE n, cmd, ty, ocr[4]; BYTE n, cmd, ty, ocr[4];
if (drv) return STA_NOINIT; // Supports only drive 0 if (drv) return STA_NOINIT; /* Supports only drive 0 */
sd_power_on(); // Initialize SPI power_on(); /* Initialize SPI */
if (Stat & STA_NODISK) return Stat; // Is a card existing in the soket? if (Stat & STA_NODISK) return Stat; /* Is a card existing in the soket? */
FCLK_SLOW(); FCLK_SLOW();
for (n = 10; n; n--) xchg_spi(0xFF); // Send 80 dummy clocks for (n = 10; n; n--) xchg_spi(0xFF); /* Send 80 dummy clocks */
ty = 0; ty = 0;
if (send_cmd(CMD0, 0) == 1) { // Put the card SPI state if (send_cmd(CMD0, 0) == 1) { /* Put the card SPI state */
timeout = millis() + 1000; // Initialization timeout = 1 sec timeout = millis() + 1000; /* Initialization timeout = 1 sec */
if (send_cmd(CMD8, 0x1AA) == 1) { // Is the catd SDv2? if (send_cmd(CMD8, 0x1AA) == 1) { /* Is the catd SDv2? */
for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF); // Get 32 bit return value of R7 resp for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF); /* Get 32 bit return value of R7 resp */
if (ocr[2] == 0x01 && ocr[3] == 0xAA) { // Does the card support 2.7-3.6V? if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* Does the card support 2.7-3.6V? */
while ((timeout > millis()) && send_cmd(ACMD41, 1UL << 30)); // Wait for end of initialization with ACMD41(HCS) while ((timeout > millis()) && send_cmd(ACMD41, 1UL << 30)) ; /* Wait for end of initialization with ACMD41(HCS) */
if ((timeout > millis()) && send_cmd(CMD58, 0) == 0) { // Check CCS bit in the OCR if ((timeout > millis()) && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */
for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF); for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF);
ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; // Check if the card is SDv2 ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* Check if the card is SDv2 */
} }
} }
} } else { /* Not an SDv2 card */
else { // Not an SDv2 card if (send_cmd(ACMD41, 0) <= 1) { /* SDv1 or MMCv3? */
if (send_cmd(ACMD41, 0) <= 1) { // SDv1 or MMCv3? ty = CT_SD1; cmd = ACMD41; /* SDv1 (ACMD41(0)) */
ty = CT_SD1; cmd = ACMD41; // SDv1 (ACMD41(0)) } else {
ty = CT_MMC; cmd = CMD1; /* MMCv3 (CMD1(0)) */
} }
else { while ((timeout > millis()) && send_cmd(cmd, 0)) ; /* Wait for the card leaves idle state */
ty = CT_MMC; cmd = CMD1; // MMCv3 (CMD1(0)) if (!(timeout > millis()) || send_cmd(CMD16, 512) != 0) /* Set block length: 512 */
}
while ((timeout > millis()) && send_cmd(cmd, 0)); // Wait for the card leaves idle state
if (!(timeout > millis()) || send_cmd(CMD16, 512) != 0) // Set block length: 512
ty = 0; ty = 0;
} }
} }
CardType = ty; // Card type CardType = ty; /* Card type */
deselect(); deselect();
if (ty) { // OK if (ty) { /* OK */
FCLK_FAST(); // Set fast clock FCLK_FAST(); /* Set fast clock */
Stat &= ~STA_NOINIT; // Clear STA_NOINIT flag Stat &= ~STA_NOINIT; /* Clear STA_NOINIT flag */
} } else { /* Failed */
else { // Failed power_off();
sd_power_off();
Stat = STA_NOINIT; Stat = STA_NOINIT;
} }
@@ -328,10 +324,10 @@ DSTATUS disk_initialize (
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
DSTATUS disk_status ( DSTATUS disk_status (
BYTE drv // Physical drive number (0) BYTE drv /* Physical drive number (0) */
) { ) {
if (drv) return STA_NOINIT; // Supports only drive 0 if (drv) return STA_NOINIT; /* Supports only drive 0 */
return Stat; // Return disk status return Stat; /* Return disk status */
} }
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@@ -339,28 +335,28 @@ DSTATUS disk_status (
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
DRESULT disk_read ( DRESULT disk_read (
BYTE drv, // Physical drive number (0) BYTE drv, /* Physical drive number (0) */
BYTE *buff, // Pointer to the data buffer to store read data BYTE *buff, /* Pointer to the data buffer to store read data */
DWORD sector, // Start sector number (LBA) DWORD sector, /* Start sector number (LBA) */
UINT count // Number of sectors to read (1..128) UINT count /* Number of sectors to read (1..128) */
) { ) {
BYTE cmd; BYTE cmd;
if (drv || !count) return RES_PARERR; // Check parameter if (drv || !count) return RES_PARERR; /* Check parameter */
if (Stat & STA_NOINIT) return RES_NOTRDY; // Check if drive is ready if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check if drive is ready */
if (!(CardType & CT_BLOCK)) sector *= 512; // LBA ot BA conversion (byte addressing cards) if (!(CardType & CT_BLOCK)) sector *= 512; /* LBA ot BA conversion (byte addressing cards) */
FCLK_FAST(); FCLK_FAST();
cmd = count > 1 ? CMD18 : CMD17; // READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK cmd = count > 1 ? CMD18 : CMD17; /* READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK */
if (send_cmd(cmd, sector) == 0) { if (send_cmd(cmd, sector) == 0) {
do { do {
if (!rcvr_datablock(buff, 512)) break; if (!rcvr_datablock(buff, 512)) break;
buff += 512; buff += 512;
} while (--count); } while (--count);
if (cmd == CMD18) send_cmd(CMD12, 0); // STOP_TRANSMISSION if (cmd == CMD18) send_cmd(CMD12, 0); /* STOP_TRANSMISSION */
} }
deselect(); deselect();
return count ? RES_ERROR : RES_OK; // Return result return count ? RES_ERROR : RES_OK; /* Return result */
} }
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@@ -370,36 +366,36 @@ DRESULT disk_read (
#if _DISKIO_WRITE #if _DISKIO_WRITE
DRESULT disk_write( DRESULT disk_write(
BYTE drv, // Physical drive number (0) BYTE drv, /* Physical drive number (0) */
const BYTE *buff, // Pointer to the data to write const BYTE *buff, /* Ponter to the data to write */
DWORD sector, // Start sector number (LBA) DWORD sector, /* Start sector number (LBA) */
UINT count // Number of sectors to write (1..128) UINT count /* Number of sectors to write (1..128) */
) { ) {
if (drv || !count) return RES_PARERR; // Check parameter if (drv || !count) return RES_PARERR; /* Check parameter */
if (Stat & STA_NOINIT) return RES_NOTRDY; // Check drive status if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check drive status */
if (Stat & STA_PROTECT) return RES_WRPRT; // Check write protect if (Stat & STA_PROTECT) return RES_WRPRT; /* Check write protect */
FCLK_FAST(); FCLK_FAST();
if (!(CardType & CT_BLOCK)) sector *= 512; // LBA ==> BA conversion (byte addressing cards) if (!(CardType & CT_BLOCK)) sector *= 512; /* LBA ==> BA conversion (byte addressing cards) */
if (count == 1) { // Single sector write if (count == 1) { /* Single sector write */
if ((send_cmd(CMD24, sector) == 0) // WRITE_BLOCK if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */
&& xmit_datablock(buff, 0xFE)) { && xmit_datablock(buff, 0xFE)) {
count = 0; count = 0;
} }
} }
else { // Multiple sector write else { /* Multiple sector write */
if (CardType & CT_SDC) send_cmd(ACMD23, count); // Predefine number of sectors if (CardType & CT_SDC) send_cmd(ACMD23, count); /* Predefine number of sectors */
if (send_cmd(CMD25, sector) == 0) { // WRITE_MULTIPLE_BLOCK if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */
do { do {
if (!xmit_datablock(buff, 0xFC)) break; if (!xmit_datablock(buff, 0xFC)) break;
buff += 512; buff += 512;
} while (--count); } while (--count);
if (!xmit_datablock(0, 0xFD)) count = 1; // STOP_TRAN token if (!xmit_datablock(0, 0xFD)) count = 1; /* STOP_TRAN token */
} }
} }
deselect(); deselect();
return count ? RES_ERROR : RES_OK; // Return result return count ? RES_ERROR : RES_OK; /* Return result */
} }
#endif // _DISKIO_WRITE #endif // _DISKIO_WRITE
@@ -411,9 +407,9 @@ DRESULT disk_read (
#if _DISKIO_IOCTL #if _DISKIO_IOCTL
DRESULT disk_ioctl ( DRESULT disk_ioctl (
BYTE drv, // Physical drive number (0) BYTE drv, /* Physical drive number (0) */
BYTE cmd, // Control command code BYTE cmd, /* Control command code */
void *buff // Pointer to the conrtol data void *buff /* Pointer to the conrtol data */
) { ) {
DRESULT res; DRESULT res;
BYTE n, csd[16], *ptr = (BYTE *)buff; BYTE n, csd[16], *ptr = (BYTE *)buff;
@@ -424,23 +420,22 @@ DRESULT disk_read (
UINT dc; UINT dc;
#endif #endif
if (drv) return RES_PARERR; // Check parameter if (drv) return RES_PARERR; /* Check parameter */
if (Stat & STA_NOINIT) return RES_NOTRDY; // Check if drive is ready if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check if drive is ready */
res = RES_ERROR; res = RES_ERROR;
FCLK_FAST(); FCLK_FAST();
switch (cmd) { switch (cmd) {
case CTRL_SYNC: // Wait for end of internal write process of the drive case CTRL_SYNC: /* Wait for end of internal write process of the drive */
if (select()) res = RES_OK; if (select()) res = RES_OK;
break; break;
case GET_SECTOR_COUNT: // Get drive capacity in unit of sector (DWORD) case GET_SECTOR_COUNT: /* Get drive capacity in unit of sector (DWORD) */
if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
if ((csd[0] >> 6) == 1) { // SDC ver 2.00 if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */
csize = csd[9] + ((WORD)csd[8] << 8) + ((DWORD)(csd[7] & 63) << 16) + 1; csize = csd[9] + ((WORD)csd[8] << 8) + ((DWORD)(csd[7] & 63) << 16) + 1;
*(DWORD*)buff = csize << 10; *(DWORD*)buff = csize << 10;
} } else { /* SDC ver 1.XX or MMC ver 3 */
else { // SDC ver 1.XX or MMC ver 3
n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2; n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1; csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
*(DWORD*)buff = csize << (n - 9); *(DWORD*)buff = csize << (n - 9);
@@ -449,23 +444,21 @@ DRESULT disk_read (
} }
break; break;
case GET_BLOCK_SIZE: // Get erase block size in unit of sector (DWORD) case GET_BLOCK_SIZE: /* Get erase block size in unit of sector (DWORD) */
if (CardType & CT_SD2) { // SDC ver 2.00 if (CardType & CT_SD2) { /* SDC ver 2.00 */
if (send_cmd(ACMD13, 0) == 0) { // Read SD status if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */
xchg_spi(0xFF); xchg_spi(0xFF);
if (rcvr_datablock(csd, 16)) { // Read partial block if (rcvr_datablock(csd, 16)) { /* Read partial block */
for (n = 64 - 16; n; n--) xchg_spi(0xFF); // Purge trailing data for (n = 64 - 16; n; n--) xchg_spi(0xFF); /* Purge trailing data */
*(DWORD*)buff = 16UL << (csd[10] >> 4); *(DWORD*)buff = 16UL << (csd[10] >> 4);
res = RES_OK; res = RES_OK;
} }
} }
} } else { /* SDC ver 1.XX or MMC */
else { // SDC ver 1.XX or MMC if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { /* Read CSD */
if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { // Read CSD if (CardType & CT_SD1) { /* SDC ver 1.XX */
if (CardType & CT_SD1) { // SDC ver 1.XX
*(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1); *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
} } else { /* MMC */
else { // MMC
*(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1); *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
} }
res = RES_OK; res = RES_OK;
@@ -473,47 +466,47 @@ DRESULT disk_read (
} }
break; break;
case CTRL_TRIM: // Erase a block of sectors (used when _USE_TRIM in ffconf.h is 1) case CTRL_TRIM: /* Erase a block of sectors (used when _USE_TRIM in ffconf.h is 1) */
if (!(CardType & CT_SDC)) break; // Check if the card is SDC if (!(CardType & CT_SDC)) break; /* Check if the card is SDC */
if (disk_ioctl(drv, MMC_GET_CSD, csd)) break; // Get CSD if (disk_ioctl(drv, MMC_GET_CSD, csd)) break; /* Get CSD */
if (!(csd[0] >> 6) && !(csd[10] & 0x40)) break; // Check if sector erase can be applied to the card if (!(csd[0] >> 6) && !(csd[10] & 0x40)) break; /* Check if sector erase can be applied to the card */
dp = (DWORD *)buff; st = dp[0]; ed = dp[1]; // Load sector block dp = (DWORD *)buff; st = dp[0]; ed = dp[1]; /* Load sector block */
if (!(CardType & CT_BLOCK)) { if (!(CardType & CT_BLOCK)) {
st *= 512; ed *= 512; st *= 512; ed *= 512;
} }
if (send_cmd(CMD32, st) == 0 && send_cmd(CMD33, ed) == 0 && send_cmd(CMD38, 0) == 0 && wait_ready(30000)) { // Erase sector block if (send_cmd(CMD32, st) == 0 && send_cmd(CMD33, ed) == 0 && send_cmd(CMD38, 0) == 0 && wait_ready(30000)) { /* Erase sector block */
res = RES_OK; // FatFs does not check result of this command res = RES_OK; /* FatFs does not check result of this command */
} }
break; break;
// The following commands are never used by FatFs module /* Following commands are never used by FatFs module */
case MMC_GET_TYPE: // Get MMC/SDC type (BYTE) case MMC_GET_TYPE: /* Get MMC/SDC type (BYTE) */
*ptr = CardType; *ptr = CardType;
res = RES_OK; res = RES_OK;
break; break;
case MMC_GET_CSD: // Read CSD (16 bytes) case MMC_GET_CSD: /* Read CSD (16 bytes) */
if (send_cmd(CMD9, 0) == 0 && rcvr_datablock(ptr, 16)) { if (send_cmd(CMD9, 0) == 0 && rcvr_datablock(ptr, 16)) { /* READ_CSD */
res = RES_OK; res = RES_OK;
} }
break; break;
case MMC_GET_CID: // Read CID (16 bytes) case MMC_GET_CID: /* Read CID (16 bytes) */
if (send_cmd(CMD10, 0) == 0 && rcvr_datablock(ptr, 16)) { if (send_cmd(CMD10, 0) == 0 && rcvr_datablock(ptr, 16)) { /* READ_CID */
res = RES_OK; res = RES_OK;
} }
break; break;
case MMC_GET_OCR: // Read OCR (4 bytes) case MMC_GET_OCR: /* Read OCR (4 bytes) */
if (send_cmd(CMD58, 0) == 0) { if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */
for (n = 4; n; n--) *ptr++ = xchg_spi(0xFF); for (n = 4; n; n--) *ptr++ = xchg_spi(0xFF);
res = RES_OK; res = RES_OK;
} }
break; break;
case MMC_GET_SDSTAT: // Read SD status (64 bytes) case MMC_GET_SDSTAT: /* Read SD status (64 bytes) */
if (send_cmd(ACMD13, 0) == 0) { if (send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */
xchg_spi(0xFF); xchg_spi(0xFF);
if (rcvr_datablock(ptr, 64)) res = RES_OK; if (rcvr_datablock(ptr, 64)) res = RES_OK;
} }

View File

@@ -90,20 +90,12 @@ void TFT_SPI::DataTransferBegin(uint16_t DataSize) {
TFT_CS_L; TFT_CS_L;
} }
#ifdef TFT_DEFAULT_DRIVER
#include "../../../lcd/tft_io/tft_ids.h"
#endif
uint32_t TFT_SPI::GetID() { uint32_t TFT_SPI::GetID() {
uint32_t id; uint32_t id;
id = ReadID(LCD_READ_ID); id = ReadID(LCD_READ_ID);
if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF) {
if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF)
id = ReadID(LCD_READ_ID4); id = ReadID(LCD_READ_ID4);
#ifdef TFT_DEFAULT_DRIVER
if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF)
id = TFT_DEFAULT_DRIVER;
#endif
}
return id; return id;
} }

View File

@@ -54,7 +54,7 @@ enum XPTCoordinate : uint8_t {
XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE, XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE,
}; };
#ifndef XPT2046_Z1_THRESHOLD #if !defined(XPT2046_Z1_THRESHOLD)
#define XPT2046_Z1_THRESHOLD 10 #define XPT2046_Z1_THRESHOLD 10
#endif #endif

View File

@@ -64,10 +64,4 @@ void setup_endstop_interrupts() {
TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN));
TERN_(HAS_I_MAX, _ATTACH(I_MAX_PIN));
TERN_(HAS_I_MIN, _ATTACH(I_MIN_PIN));
TERN_(HAS_J_MAX, _ATTACH(J_MAX_PIN));
TERN_(HAS_J_MIN, _ATTACH(J_MIN_PIN));
TERN_(HAS_K_MAX, _ATTACH(K_MAX_PIN));
TERN_(HAS_K_MIN, _ATTACH(K_MIN_PIN));
} }

View File

@@ -63,10 +63,4 @@ void setup_endstop_interrupts() {
TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN));
TERN_(HAS_I_MAX, _ATTACH(I_MAX_PIN));
TERN_(HAS_I_MIN, _ATTACH(I_MIN_PIN));
TERN_(HAS_J_MAX, _ATTACH(J_MAX_PIN));
TERN_(HAS_J_MIN, _ATTACH(J_MIN_PIN));
TERN_(HAS_K_MAX, _ATTACH(K_MAX_PIN));
TERN_(HAS_K_MIN, _ATTACH(K_MIN_PIN));
} }

View File

@@ -63,10 +63,4 @@ void setup_endstop_interrupts() {
TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN));
TERN_(HAS_I_MAX, _ATTACH(I_MAX_PIN));
TERN_(HAS_I_MIN, _ATTACH(I_MIN_PIN));
TERN_(HAS_J_MAX, _ATTACH(J_MAX_PIN));
TERN_(HAS_J_MIN, _ATTACH(J_MIN_PIN));
TERN_(HAS_K_MAX, _ATTACH(K_MAX_PIN));
TERN_(HAS_K_MIN, _ATTACH(K_MIN_PIN));
} }

View File

@@ -61,24 +61,11 @@ static constexpr uint8_t eeprom_device_address = I2C_ADDRESS(EEPROM_DEVICE_ADDRE
// Public functions // Public functions
// ------------------------ // ------------------------
#define SMALL_EEPROM (MARLIN_EEPROM_SIZE <= 2048)
// Combine Address high bits into the device address on <=16Kbit (2K) and >512Kbit (64K) EEPROMs.
// Note: MARLIN_EEPROM_SIZE is specified in bytes, whereas EEPROM model numbers refer to bits.
// e.g., The "16" in BL24C16 indicates a 16Kbit (2KB) size.
static uint8_t _eeprom_calc_device_address(uint8_t * const pos) {
const unsigned eeprom_address = (unsigned)pos;
return (SMALL_EEPROM || MARLIN_EEPROM_SIZE > 65536)
? uint8_t(eeprom_device_address | ((eeprom_address >> (SMALL_EEPROM ? 8 : 16)) & 0x07))
: eeprom_device_address;
}
static void _eeprom_begin(uint8_t * const pos) { static void _eeprom_begin(uint8_t * const pos) {
const unsigned eeprom_address = (unsigned)pos; const unsigned eeprom_address = (unsigned)pos;
Wire.beginTransmission(_eeprom_calc_device_address(pos)); Wire.beginTransmission(eeprom_device_address);
if (!SMALL_EEPROM) Wire.write(int(eeprom_address >> 8)); // Address High
Wire.write(uint8_t((eeprom_address >> 8) & 0xFF)); // Address High, if needed Wire.write(int(eeprom_address & 0xFF)); // Address Low
Wire.write(uint8_t(eeprom_address & 0xFF)); // Address Low
} }
void eeprom_write_byte(uint8_t *pos, uint8_t value) { void eeprom_write_byte(uint8_t *pos, uint8_t value) {
@@ -94,7 +81,7 @@ void eeprom_write_byte(uint8_t *pos, uint8_t value) {
uint8_t eeprom_read_byte(uint8_t *pos) { uint8_t eeprom_read_byte(uint8_t *pos) {
_eeprom_begin(pos); _eeprom_begin(pos);
Wire.endTransmission(); Wire.endTransmission();
Wire.requestFrom(_eeprom_calc_device_address(pos), (byte)1); Wire.requestFrom(eeprom_device_address, (byte)1);
return Wire.available() ? Wire.read() : 0xFF; return Wire.available() ? Wire.read() : 0xFF;
} }

View File

@@ -282,22 +282,12 @@ bool wait_for_heatup = true;
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnarrowing" #pragma GCC diagnostic ignored "-Wnarrowing"
#ifndef RUNTIME_ONLY_ANALOG_TO_DIGITAL
template <pin_t ...D>
constexpr pin_t OnlyPins<_SP_END, D...>::table[sizeof...(D)];
#endif
bool pin_is_protected(const pin_t pin) { bool pin_is_protected(const pin_t pin) {
#ifdef RUNTIME_ONLY_ANALOG_TO_DIGITAL static const pin_t sensitive_pins[] PROGMEM = SENSITIVE_PINS;
static const pin_t sensitive_pins[] PROGMEM = { SENSITIVE_PINS }; LOOP_L_N(i, COUNT(sensitive_pins)) {
const size_t pincount = COUNT(sensitive_pins); pin_t sensitive_pin;
#else memcpy_P(&sensitive_pin, &sensitive_pins[i], sizeof(pin_t));
static constexpr size_t pincount = OnlyPins<SENSITIVE_PINS>::size; if (pin == sensitive_pin) return true;
static const pin_t (&sensitive_pins)[pincount] PROGMEM = OnlyPins<SENSITIVE_PINS>::table;
#endif
LOOP_L_N(i, pincount) {
const pin_t * const pptr = &sensitive_pins[i];
if (pin == (sizeof(pin_t) == 2 ? (pin_t)pgm_read_word(pptr) : (pin_t)pgm_read_byte(pptr))) return true;
} }
return false; return false;
} }
@@ -314,9 +304,6 @@ void enable_all_steppers() {
ENABLE_AXIS_X(); ENABLE_AXIS_X();
ENABLE_AXIS_Y(); ENABLE_AXIS_Y();
ENABLE_AXIS_Z(); 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(); enable_e_steppers();
TERN_(EXTENSIBLE_UI, ExtUI::onSteppersEnabled()); TERN_(EXTENSIBLE_UI, ExtUI::onSteppersEnabled());
@@ -330,7 +317,7 @@ void disable_e_steppers() {
void disable_e_stepper(const uint8_t e) { void disable_e_stepper(const uint8_t e) {
#define _CASE_DIS_E(N) case N: DISABLE_AXIS_E##N(); break; #define _CASE_DIS_E(N) case N: DISABLE_AXIS_E##N(); break;
switch (e) { switch (e) {
REPEAT(E_STEPPERS, _CASE_DIS_E) REPEAT(EXTRUDERS, _CASE_DIS_E)
} }
} }
@@ -338,9 +325,6 @@ void disable_all_steppers() {
DISABLE_AXIS_X(); DISABLE_AXIS_X();
DISABLE_AXIS_Y(); DISABLE_AXIS_Y();
DISABLE_AXIS_Z(); DISABLE_AXIS_Z();
DISABLE_AXIS_I();
DISABLE_AXIS_J();
DISABLE_AXIS_K();
disable_e_steppers(); disable_e_steppers();
TERN_(EXTENSIBLE_UI, ExtUI::onSteppersDisabled()); TERN_(EXTENSIBLE_UI, ExtUI::onSteppersDisabled());
@@ -424,18 +408,19 @@ void startOrResumeJob() {
* - Check if an idle but hot extruder needs filament extruded (EXTRUDER_RUNOUT_PREVENT) * - Check if an idle but hot extruder needs filament extruded (EXTRUDER_RUNOUT_PREVENT)
* - Pulse FET_SAFETY_PIN if it exists * - Pulse FET_SAFETY_PIN if it exists
*/ */
inline void manage_inactivity(const bool no_stepper_sleep=false) { inline void manage_inactivity(const bool ignore_stepper_queue=false) {
queue.get_available_commands(); queue.get_available_commands();
const millis_t ms = millis(); const millis_t ms = millis();
// Prevent steppers timing-out // Prevent steppers timing-out in the middle of M600
const bool do_reset_timeout = no_stepper_sleep // unless PAUSE_PARK_NO_STEPPER_TIMEOUT is disabled
const bool parked_or_ignoring = ignore_stepper_queue
|| TERN0(PAUSE_PARK_NO_STEPPER_TIMEOUT, did_pause_print); || TERN0(PAUSE_PARK_NO_STEPPER_TIMEOUT, did_pause_print);
// Reset both the M18/M84 activity timeout and the M85 max 'kill' timeout // Reset both the M18/M84 activity timeout and the M85 max 'kill' timeout
if (do_reset_timeout) gcode.reset_stepper_timeout(ms); if (parked_or_ignoring) gcode.reset_stepper_timeout(ms);
if (gcode.stepper_max_timed_out(ms)) { if (gcode.stepper_max_timed_out(ms)) {
SERIAL_ERROR_MSG(STR_KILL_INACTIVE_TIME, parser.command_ptr); SERIAL_ERROR_MSG(STR_KILL_INACTIVE_TIME, parser.command_ptr);
@@ -451,7 +436,7 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
// activity timeout and the M85 max 'kill' timeout // activity timeout and the M85 max 'kill' timeout
if (planner.has_blocks_queued()) if (planner.has_blocks_queued())
gcode.reset_stepper_timeout(ms); gcode.reset_stepper_timeout(ms);
else if (!do_reset_timeout && gcode.stepper_inactive_timeout()) { else if (!parked_or_ignoring && gcode.stepper_inactive_timeout()) {
if (!already_shutdown_steppers) { if (!already_shutdown_steppers) {
already_shutdown_steppers = true; // L6470 SPI will consume 99% of free time without this already_shutdown_steppers = true; // L6470 SPI will consume 99% of free time without this
@@ -459,9 +444,6 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
if (ENABLED(DISABLE_INACTIVE_X)) DISABLE_AXIS_X(); if (ENABLED(DISABLE_INACTIVE_X)) DISABLE_AXIS_X();
if (ENABLED(DISABLE_INACTIVE_Y)) DISABLE_AXIS_Y(); if (ENABLED(DISABLE_INACTIVE_Y)) DISABLE_AXIS_Y();
if (ENABLED(DISABLE_INACTIVE_Z)) DISABLE_AXIS_Z(); 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(); if (ENABLED(DISABLE_INACTIVE_E)) disable_e_steppers();
TERN_(AUTO_BED_LEVELING_UBL, ubl.steppers_were_disabled()); TERN_(AUTO_BED_LEVELING_UBL, ubl.steppers_were_disabled());
@@ -734,14 +716,14 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
* - Update the Průša MMU2 * - Update the Průša MMU2
* - Handle Joystick jogging * - Handle Joystick jogging
*/ */
void idle(bool no_stepper_sleep/*=false*/) { void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) {
#if ENABLED(MARLIN_DEV_MODE) #if ENABLED(MARLIN_DEV_MODE)
static uint16_t idle_depth = 0; static uint16_t idle_depth = 0;
if (++idle_depth > 5) SERIAL_ECHOLNPAIR("idle() call depth: ", idle_depth); if (++idle_depth > 5) SERIAL_ECHOLNPAIR("idle() call depth: ", idle_depth);
#endif #endif
// Core Marlin activities // Core Marlin activities
manage_inactivity(no_stepper_sleep); manage_inactivity(TERN_(ADVANCED_PAUSE_FEATURE, no_stepper_sleep));
// Manage Heaters (and Watchdog) // Manage Heaters (and Watchdog)
thermalManager.manage_heater(); thermalManager.manage_heater();
@@ -953,15 +935,6 @@ inline void tmc_standby_setup() {
#if PIN_EXISTS(Z4_STDBY) #if PIN_EXISTS(Z4_STDBY)
SET_INPUT_PULLDOWN(Z4_STDBY_PIN); SET_INPUT_PULLDOWN(Z4_STDBY_PIN);
#endif #endif
#if PIN_EXISTS(I_STDBY)
SET_INPUT_PULLDOWN(I_STDBY_PIN);
#endif
#if PIN_EXISTS(J_STDBY)
SET_INPUT_PULLDOWN(J_STDBY_PIN);
#endif
#if PIN_EXISTS(K_STDBY)
SET_INPUT_PULLDOWN(K_STDBY_PIN);
#endif
#if PIN_EXISTS(E0_STDBY) #if PIN_EXISTS(E0_STDBY)
SET_INPUT_PULLDOWN(E0_STDBY_PIN); SET_INPUT_PULLDOWN(E0_STDBY_PIN);
#endif #endif
@@ -1128,7 +1101,6 @@ void setup() {
#endif #endif
#if HAS_FREEZE_PIN #if HAS_FREEZE_PIN
SETUP_LOG("FREEZE_PIN");
SET_INPUT_PULLUP(FREEZE_PIN); SET_INPUT_PULLUP(FREEZE_PIN);
#endif #endif
@@ -1137,19 +1109,11 @@ void setup() {
OUT_WRITE(SUICIDE_PIN, !SUICIDE_PIN_INVERTING); OUT_WRITE(SUICIDE_PIN, !SUICIDE_PIN_INVERTING);
#endif #endif
#ifdef JTAGSWD_RESET
SETUP_LOG("JTAGSWD_RESET");
JTAGSWD_RESET();
#endif
#if EITHER(DISABLE_DEBUG, DISABLE_JTAG) #if EITHER(DISABLE_DEBUG, DISABLE_JTAG)
delay(10);
// Disable any hardware debug to free up pins for IO // Disable any hardware debug to free up pins for IO
#if ENABLED(DISABLE_DEBUG) && defined(JTAGSWD_DISABLE) #if ENABLED(DISABLE_DEBUG) && defined(JTAGSWD_DISABLE)
SETUP_LOG("JTAGSWD_DISABLE");
JTAGSWD_DISABLE(); JTAGSWD_DISABLE();
#elif defined(JTAG_DISABLE) #elif defined(JTAG_DISABLE)
SETUP_LOG("JTAG_DISABLE");
JTAG_DISABLE(); JTAG_DISABLE();
#else #else
#error "DISABLE_(DEBUG|JTAG) is not supported for the selected MCU/Board." #error "DISABLE_(DEBUG|JTAG) is not supported for the selected MCU/Board."
@@ -1168,10 +1132,10 @@ void setup() {
SETUP_RUN(HAL_init()); SETUP_RUN(HAL_init());
// Init and disable SPI thermocouples; this is still needed // Init and disable SPI thermocouples; this is still needed
#if TEMP_SENSOR_0_IS_MAX_TC || (TEMP_SENSOR_REDUNDANT_IS_MAX_TC && TEMP_SENSOR_REDUNDANT_SOURCE == 0) #if TEMP_SENSOR_0_IS_MAX_TC
OUT_WRITE(MAX6675_SS_PIN, HIGH); // Disable OUT_WRITE(MAX6675_SS_PIN, HIGH); // Disable
#endif #endif
#if TEMP_SENSOR_1_IS_MAX_TC || (TEMP_SENSOR_REDUNDANT_IS_MAX_TC && TEMP_SENSOR_REDUNDANT_SOURCE == 1) #if TEMP_SENSOR_1_IS_MAX_TC
OUT_WRITE(MAX6675_SS2_PIN, HIGH); // Disable OUT_WRITE(MAX6675_SS2_PIN, HIGH); // Disable
#endif #endif
@@ -1459,7 +1423,10 @@ void setup() {
#endif #endif
#if HAS_PRUSA_MMU1 #if HAS_PRUSA_MMU1
SETUP_RUN(mmu_init()); SETUP_LOG("Prusa MMU1");
SET_OUTPUT(E_MUX0_PIN);
SET_OUTPUT(E_MUX1_PIN);
SET_OUTPUT(E_MUX2_PIN);
#endif #endif
#if HAS_FANMUX #if HAS_FANMUX

View File

@@ -34,8 +34,8 @@
void stop(); void stop();
// Pass true to keep steppers from timing out // Pass true to keep steppers from timing out
void idle(bool no_stepper_sleep=false); void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep=false));
inline void idle_no_sleep() { idle(true); } inline void idle_no_sleep() { idle(TERN_(ADVANCED_PAUSE_FEATURE, true)); }
#if ENABLED(G38_PROBE_TARGET) #if ENABLED(G38_PROBE_TARGET)
extern uint8_t G38_move; // Flag to tell the ISR that G38 is in progress, and the type extern uint8_t G38_move; // Flag to tell the ISR that G38 is in progress, and the type

View File

@@ -321,7 +321,7 @@
#define BOARD_BTT_SKR_MINI_V1_1 4023 // BigTreeTech SKR Mini v1.1 (STM32F103RC) #define BOARD_BTT_SKR_MINI_V1_1 4023 // BigTreeTech SKR Mini v1.1 (STM32F103RC)
#define BOARD_BTT_SKR_MINI_E3_V1_0 4024 // BigTreeTech SKR Mini E3 (STM32F103RC) #define BOARD_BTT_SKR_MINI_E3_V1_0 4024 // BigTreeTech SKR Mini E3 (STM32F103RC)
#define BOARD_BTT_SKR_MINI_E3_V1_2 4025 // BigTreeTech SKR Mini E3 V1.2 (STM32F103RC) #define BOARD_BTT_SKR_MINI_E3_V1_2 4025 // BigTreeTech SKR Mini E3 V1.2 (STM32F103RC)
#define BOARD_BTT_SKR_MINI_E3_V2_0 4026 // BigTreeTech SKR Mini E3 V2.0 (STM32F103RC / STM32F103RE) #define BOARD_BTT_SKR_MINI_E3_V2_0 4026 // BigTreeTech SKR Mini E3 V2.0 (STM32F103RC)
#define BOARD_BTT_SKR_MINI_MZ_V1_0 4027 // BigTreeTech SKR Mini MZ V1.0 (STM32F103RC) #define BOARD_BTT_SKR_MINI_MZ_V1_0 4027 // BigTreeTech SKR Mini MZ V1.0 (STM32F103RC)
#define BOARD_BTT_SKR_E3_DIP 4028 // BigTreeTech SKR E3 DIP V1.0 (STM32F103RC / STM32F103RE) #define BOARD_BTT_SKR_E3_DIP 4028 // BigTreeTech SKR E3 DIP V1.0 (STM32F103RC / STM32F103RE)
#define BOARD_BTT_SKR_CR6 4029 // BigTreeTech SKR CR6 v1.0 (STM32F103RE) #define BOARD_BTT_SKR_CR6 4029 // BigTreeTech SKR CR6 v1.0 (STM32F103RE)
@@ -372,21 +372,20 @@
#define BOARD_BTT_SKR_V2_0_REV_B 4212 // BigTreeTech SKR v2.0 Rev B (STM32F407VGT6) #define BOARD_BTT_SKR_V2_0_REV_B 4212 // BigTreeTech SKR v2.0 Rev B (STM32F407VGT6)
#define BOARD_BTT_GTR_V1_0 4213 // BigTreeTech GTR v1.0 (STM32F407IGT) #define BOARD_BTT_GTR_V1_0 4213 // BigTreeTech GTR v1.0 (STM32F407IGT)
#define BOARD_BTT_OCTOPUS_V1_0 4214 // BigTreeTech Octopus v1.0 (STM32F446ZET6) #define BOARD_BTT_OCTOPUS_V1_0 4214 // BigTreeTech Octopus v1.0 (STM32F446ZET6)
#define BOARD_BTT_OCTOPUS_V1_1 4215 // BigTreeTech Octopus v1.1 (STM32F446ZET6) #define BOARD_LERDGE_K 4215 // Lerdge K (STM32F407ZG)
#define BOARD_LERDGE_K 4216 // Lerdge K (STM32F407ZG) #define BOARD_LERDGE_S 4216 // Lerdge S (STM32F407VE)
#define BOARD_LERDGE_S 4217 // Lerdge S (STM32F407VE) #define BOARD_LERDGE_X 4217 // Lerdge X (STM32F407VE)
#define BOARD_LERDGE_X 4218 // Lerdge X (STM32F407VE) #define BOARD_VAKE403D 4218 // VAkE 403D (STM32F446VET6)
#define BOARD_VAKE403D 4219 // VAkE 403D (STM32F446VET6) #define BOARD_FYSETC_S6 4219 // FYSETC S6 (STM32F446VET6)
#define BOARD_FYSETC_S6 4220 // FYSETC S6 (STM32F446VET6) #define BOARD_FYSETC_S6_V2_0 4220 // FYSETC S6 v2.0 (STM32F446VET6)
#define BOARD_FYSETC_S6_V2_0 4221 // FYSETC S6 v2.0 (STM32F446VET6) #define BOARD_FYSETC_SPIDER 4221 // FYSETC Spider (STM32F446VET6)
#define BOARD_FYSETC_SPIDER 4222 // FYSETC Spider (STM32F446VET6) #define BOARD_FLYF407ZG 4222 // FLYF407ZG (STM32F407ZG)
#define BOARD_FLYF407ZG 4223 // FLYF407ZG (STM32F407ZG) #define BOARD_MKS_ROBIN2 4223 // MKS_ROBIN2 (STM32F407ZE)
#define BOARD_MKS_ROBIN2 4224 // MKS_ROBIN2 (STM32F407ZE) #define BOARD_MKS_ROBIN_PRO_V2 4224 // MKS Robin Pro V2 (STM32F407VE)
#define BOARD_MKS_ROBIN_PRO_V2 4225 // MKS Robin Pro V2 (STM32F407VE) #define BOARD_MKS_ROBIN_NANO_V3 4225 // MKS Robin Nano V3 (STM32F407VG)
#define BOARD_MKS_ROBIN_NANO_V3 4226 // MKS Robin Nano V3 (STM32F407VG) #define BOARD_ANET_ET4 4226 // ANET ET4 V1.x (STM32F407VGT6)
#define BOARD_ANET_ET4 4227 // ANET ET4 V1.x (STM32F407VGT6) #define BOARD_ANET_ET4P 4227 // ANET ET4P V1.x (STM32F407VGT6)
#define BOARD_ANET_ET4P 4228 // ANET ET4P V1.x (STM32F407VGT6) #define BOARD_FYSETC_CHEETAH_V20 4228 // FYSETC Cheetah V2.0
#define BOARD_FYSETC_CHEETAH_V20 4229 // FYSETC Cheetah V2.0
// //

View File

@@ -60,9 +60,6 @@
#define AXIS_DRIVER_TYPE_X(T) _AXIS_DRIVER_TYPE(X,T) #define AXIS_DRIVER_TYPE_X(T) _AXIS_DRIVER_TYPE(X,T)
#define AXIS_DRIVER_TYPE_Y(T) _AXIS_DRIVER_TYPE(Y,T) #define AXIS_DRIVER_TYPE_Y(T) _AXIS_DRIVER_TYPE(Y,T)
#define AXIS_DRIVER_TYPE_Z(T) _AXIS_DRIVER_TYPE(Z,T) #define AXIS_DRIVER_TYPE_Z(T) _AXIS_DRIVER_TYPE(Z,T)
#define AXIS_DRIVER_TYPE_I(T) _AXIS_DRIVER_TYPE(I,T)
#define AXIS_DRIVER_TYPE_J(T) _AXIS_DRIVER_TYPE(J,T)
#define AXIS_DRIVER_TYPE_K(T) _AXIS_DRIVER_TYPE(K,T)
#define AXIS_DRIVER_TYPE_X2(T) (EITHER(X_DUAL_STEPPER_DRIVERS, DUAL_X_CARRIAGE) && _AXIS_DRIVER_TYPE(X2,T)) #define AXIS_DRIVER_TYPE_X2(T) (EITHER(X_DUAL_STEPPER_DRIVERS, DUAL_X_CARRIAGE) && _AXIS_DRIVER_TYPE(X2,T))
#define AXIS_DRIVER_TYPE_Y2(T) (ENABLED(Y_DUAL_STEPPER_DRIVERS) && _AXIS_DRIVER_TYPE(Y2,T)) #define AXIS_DRIVER_TYPE_Y2(T) (ENABLED(Y_DUAL_STEPPER_DRIVERS) && _AXIS_DRIVER_TYPE(Y2,T))
@@ -86,7 +83,6 @@
#define HAS_E_DRIVER(T) (0 RREPEAT2(E_STEPPERS, _OR_ADTE, T)) #define HAS_E_DRIVER(T) (0 RREPEAT2(E_STEPPERS, _OR_ADTE, T))
#define HAS_DRIVER(T) ( AXIS_DRIVER_TYPE_X(T) || AXIS_DRIVER_TYPE_Y(T) || AXIS_DRIVER_TYPE_Z(T) \ #define HAS_DRIVER(T) ( AXIS_DRIVER_TYPE_X(T) || AXIS_DRIVER_TYPE_Y(T) || AXIS_DRIVER_TYPE_Z(T) \
|| AXIS_DRIVER_TYPE_I(T) || AXIS_DRIVER_TYPE_J(T) || AXIS_DRIVER_TYPE_K(T) \
|| AXIS_DRIVER_TYPE_X2(T) || AXIS_DRIVER_TYPE_Y2(T) || AXIS_DRIVER_TYPE_Z2(T) \ || AXIS_DRIVER_TYPE_X2(T) || AXIS_DRIVER_TYPE_Y2(T) || AXIS_DRIVER_TYPE_Z2(T) \
|| AXIS_DRIVER_TYPE_Z3(T) || AXIS_DRIVER_TYPE_Z4(T) || HAS_E_DRIVER(T) ) || AXIS_DRIVER_TYPE_Z3(T) || AXIS_DRIVER_TYPE_Z4(T) || HAS_E_DRIVER(T) )
@@ -157,11 +153,9 @@
#define _OR_EAH(N,T) || AXIS_HAS_##T(E##N) #define _OR_EAH(N,T) || AXIS_HAS_##T(E##N)
#define E_AXIS_HAS(T) (0 _OR_EAH(0,T) _OR_EAH(1,T) _OR_EAH(2,T) _OR_EAH(3,T) _OR_EAH(4,T) _OR_EAH(5,T) _OR_EAH(6,T) _OR_EAH(7,T)) #define E_AXIS_HAS(T) (0 _OR_EAH(0,T) _OR_EAH(1,T) _OR_EAH(2,T) _OR_EAH(3,T) _OR_EAH(4,T) _OR_EAH(5,T) _OR_EAH(6,T) _OR_EAH(7,T))
#define ANY_AXIS_HAS(T) ( AXIS_HAS_##T(X) || AXIS_HAS_##T(X2) \ #define ANY_AXIS_HAS(T) ( AXIS_HAS_##T(X) || AXIS_HAS_##T(Y) || AXIS_HAS_##T(Z) \
|| AXIS_HAS_##T(Y) || AXIS_HAS_##T(Y2) \ || AXIS_HAS_##T(X2) || AXIS_HAS_##T(Y2) || AXIS_HAS_##T(Z2) \
|| AXIS_HAS_##T(Z) || AXIS_HAS_##T(Z2) || AXIS_HAS_##T(Z3) || AXIS_HAS_##T(Z4) \ || AXIS_HAS_##T(Z3) || AXIS_HAS_##T(Z4) || E_AXIS_HAS(T) )
|| AXIS_HAS_##T(I) || AXIS_HAS_##T(J) || AXIS_HAS_##T(K) \
|| E_AXIS_HAS(T) )
#if ANY_AXIS_HAS(STEALTHCHOP) #if ANY_AXIS_HAS(STEALTHCHOP)
#define HAS_STEALTHCHOP 1 #define HAS_STEALTHCHOP 1

View File

@@ -266,25 +266,18 @@
#define STR_X_MAX "x_max" #define STR_X_MAX "x_max"
#define STR_X2_MIN "x2_min" #define STR_X2_MIN "x2_min"
#define STR_X2_MAX "x2_max" #define STR_X2_MAX "x2_max"
#define STR_Y_MIN "y_min"
#if HAS_Y_AXIS #define STR_Y_MAX "y_max"
#define STR_Y_MIN "y_min" #define STR_Y2_MIN "y2_min"
#define STR_Y_MAX "y_max" #define STR_Y2_MAX "y2_max"
#define STR_Y2_MIN "y2_min" #define STR_Z_MIN "z_min"
#define STR_Y2_MAX "y2_max" #define STR_Z_MAX "z_max"
#endif #define STR_Z2_MIN "z2_min"
#define STR_Z2_MAX "z2_max"
#if HAS_Z_AXIS #define STR_Z3_MIN "z3_min"
#define STR_Z_MIN "z_min" #define STR_Z3_MAX "z3_max"
#define STR_Z_MAX "z_max" #define STR_Z4_MIN "z4_min"
#define STR_Z2_MIN "z2_min" #define STR_Z4_MAX "z4_max"
#define STR_Z2_MAX "z2_max"
#define STR_Z3_MIN "z3_min"
#define STR_Z3_MAX "z3_max"
#define STR_Z4_MIN "z4_min"
#define STR_Z4_MAX "z4_max"
#endif
#define STR_Z_PROBE "z_probe" #define STR_Z_PROBE "z_probe"
#define STR_PROBE_EN "probe_en" #define STR_PROBE_EN "probe_en"
#define STR_FILAMENT_RUNOUT_SENSOR "filament" #define STR_FILAMENT_RUNOUT_SENSOR "filament"
@@ -293,9 +286,6 @@
#define STR_X "X" #define STR_X "X"
#define STR_Y "Y" #define STR_Y "Y"
#define STR_Z "Z" #define STR_Z "Z"
#define STR_I AXIS4_STR
#define STR_J AXIS5_STR
#define STR_K AXIS6_STR
#define STR_E "E" #define STR_E "E"
#if IS_KINEMATIC #if IS_KINEMATIC
#define STR_A "A" #define STR_A "A"
@@ -315,114 +305,8 @@
#define LCD_STR_A STR_A #define LCD_STR_A STR_A
#define LCD_STR_B STR_B #define LCD_STR_B STR_B
#define LCD_STR_C STR_C #define LCD_STR_C STR_C
#define LCD_STR_I STR_I
#define LCD_STR_J STR_J
#define LCD_STR_K STR_K
#define LCD_STR_E STR_E #define LCD_STR_E STR_E
// Extra Axis and Endstop Names
#if LINEAR_AXES >= 4
#if AXIS4_NAME == 'A'
#define AXIS4_STR "A"
#define STR_I_MIN "a_min"
#define STR_I_MAX "a_max"
#elif AXIS4_NAME == 'B'
#define AXIS4_STR "B"
#define STR_I_MIN "b_min"
#define STR_I_MAX "b_max"
#elif AXIS4_NAME == 'C'
#define AXIS4_STR "C"
#define STR_I_MIN "c_min"
#define STR_I_MAX "c_max"
#elif AXIS4_NAME == 'U'
#define AXIS4_STR "U"
#define STR_I_MIN "u_min"
#define STR_I_MAX "u_max"
#elif AXIS4_NAME == 'V'
#define AXIS4_STR "V"
#define STR_I_MIN "v_min"
#define STR_I_MAX "v_max"
#elif AXIS4_NAME == 'W'
#define AXIS4_STR "W"
#define STR_I_MIN "w_min"
#define STR_I_MAX "w_max"
#else
#define AXIS4_STR "A"
#define STR_I_MIN "a_min"
#define STR_I_MAX "a_max"
#endif
#else
#define AXIS4_STR ""
#endif
#if LINEAR_AXES >= 5
#if AXIS5_NAME == 'A'
#define AXIS5_STR "A"
#define STR_J_MIN "a_min"
#define STR_J_MAX "a_max"
#elif AXIS5_NAME == 'B'
#define AXIS5_STR "B"
#define STR_J_MIN "b_min"
#define STR_J_MAX "b_max"
#elif AXIS5_NAME == 'C'
#define AXIS5_STR "C"
#define STR_J_MIN "c_min"
#define STR_J_MAX "c_max"
#elif AXIS5_NAME == 'U'
#define AXIS5_STR "U"
#define STR_J_MIN "u_min"
#define STR_J_MAX "u_max"
#elif AXIS5_NAME == 'V'
#define AXIS5_STR "V"
#define STR_J_MIN "v_min"
#define STR_J_MAX "v_max"
#elif AXIS5_NAME == 'W'
#define AXIS5_STR "W"
#define STR_J_MIN "w_min"
#define STR_J_MAX "w_max"
#else
#define AXIS5_STR "B"
#define STR_J_MIN "b_min"
#define STR_J_MAX "b_max"
#endif
#else
#define AXIS5_STR ""
#endif
#if LINEAR_AXES >= 6
#if AXIS6_NAME == 'A'
#define AXIS6_STR "A"
#define STR_K_MIN "a_min"
#define STR_K_MAX "a_max"
#elif AXIS6_NAME == 'B'
#define AXIS6_STR "B"
#define STR_K_MIN "b_min"
#define STR_K_MAX "b_max"
#elif AXIS6_NAME == 'C'
#define AXIS6_STR "C"
#define STR_K_MIN "c_min"
#define STR_K_MAX "c_max"
#elif AXIS6_NAME == 'U'
#define AXIS6_STR "U"
#define STR_K_MIN "u_min"
#define STR_K_MAX "u_max"
#elif AXIS6_NAME == 'V'
#define AXIS6_STR "V"
#define STR_K_MIN "v_min"
#define STR_K_MAX "v_max"
#elif AXIS6_NAME == 'W'
#define AXIS6_STR "W"
#define STR_K_MIN "w_min"
#define STR_K_MAX "w_max"
#else
#define AXIS6_STR "C"
#define STR_K_MIN "c_min"
#define STR_K_MAX "c_max"
#endif
#else
#define AXIS6_STR ""
#endif
#if EITHER(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL) #if EITHER(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL)
// Custom characters defined in the first 8 characters of the LCD // Custom characters defined in the first 8 characters of the LCD

View File

@@ -36,21 +36,12 @@
#define _XMIN_ 100 #define _XMIN_ 100
#define _YMIN_ 200 #define _YMIN_ 200
#define _ZMIN_ 300 #define _ZMIN_ 300
#define _IMIN_ 500
#define _JMIN_ 600
#define _KMIN_ 700
#define _XMAX_ 101 #define _XMAX_ 101
#define _YMAX_ 201 #define _YMAX_ 201
#define _ZMAX_ 301 #define _ZMAX_ 301
#define _IMAX_ 501
#define _JMAX_ 601
#define _KMAX_ 701
#define _XDIAG_ 102 #define _XDIAG_ 102
#define _YDIAG_ 202 #define _YDIAG_ 202
#define _ZDIAG_ 302 #define _ZDIAG_ 302
#define _IDIAG_ 502
#define _JDIAG_ 602
#define _KDIAG_ 702
#define _E0DIAG_ 400 #define _E0DIAG_ 400
#define _E1DIAG_ 401 #define _E1DIAG_ 401
#define _E2DIAG_ 402 #define _E2DIAG_ 402

View File

@@ -36,10 +36,6 @@ PGMSTR(X_LBL, "X:"); PGMSTR(Y_LBL, "Y:"); PGMSTR(Z_LBL, "Z:"); PGMST
PGMSTR(SP_A_STR, " A"); PGMSTR(SP_B_STR, " B"); PGMSTR(SP_C_STR, " C"); PGMSTR(SP_A_STR, " A"); PGMSTR(SP_B_STR, " B"); PGMSTR(SP_C_STR, " C");
PGMSTR(SP_X_STR, " X"); PGMSTR(SP_Y_STR, " Y"); PGMSTR(SP_Z_STR, " Z"); PGMSTR(SP_E_STR, " E"); PGMSTR(SP_X_STR, " X"); PGMSTR(SP_Y_STR, " Y"); PGMSTR(SP_Z_STR, " Z"); PGMSTR(SP_E_STR, " E");
PGMSTR(SP_X_LBL, " X:"); PGMSTR(SP_Y_LBL, " Y:"); PGMSTR(SP_Z_LBL, " Z:"); PGMSTR(SP_E_LBL, " E:"); PGMSTR(SP_X_LBL, " X:"); PGMSTR(SP_Y_LBL, " Y:"); PGMSTR(SP_Z_LBL, " Z:"); PGMSTR(SP_E_LBL, " E:");
PGMSTR(I_STR, AXIS4_STR); PGMSTR(J_STR, AXIS5_STR); PGMSTR(K_STR, AXIS6_STR);
PGMSTR(I_LBL, AXIS4_STR ":"); PGMSTR(J_LBL, AXIS5_STR ":"); PGMSTR(K_LBL, AXIS6_STR ":");
PGMSTR(SP_I_STR, " " AXIS4_STR); PGMSTR(SP_J_STR, " " AXIS5_STR); PGMSTR(SP_K_STR, " " AXIS6_STR);
PGMSTR(SP_I_LBL, " " AXIS4_STR ":"); PGMSTR(SP_J_LBL, " " AXIS5_STR ":"); PGMSTR(SP_K_LBL, " " AXIS6_STR ":");
// Hook Meatpack if it's enabled on the first leaf // Hook Meatpack if it's enabled on the first leaf
#if ENABLED(MEATPACK_ON_SERIAL_PORT_1) #if ENABLED(MEATPACK_ON_SERIAL_PORT_1)
@@ -105,10 +101,8 @@ 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*/) { void print_pos(const_float_t x, const_float_t y, const_float_t z, PGM_P const prefix/*=nullptr*/, PGM_P const suffix/*=nullptr*/) {
if (prefix) serialprintPGM(prefix); if (prefix) serialprintPGM(prefix);
SERIAL_ECHOPAIR_P( SERIAL_ECHOPAIR_P(SP_X_STR, x, SP_Y_STR, y, SP_Z_STR, z);
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) serialprintPGM(suffix); else SERIAL_EOL();
} }

View File

@@ -29,16 +29,12 @@
#endif #endif
// Commonly-used strings in serial output // Commonly-used strings in serial output
extern const char NUL_STR[], extern const char NUL_STR[], SP_P_STR[], SP_T_STR[],
SP_X_STR[], SP_Y_STR[], SP_Z_STR[],
SP_A_STR[], SP_B_STR[], SP_C_STR[], SP_E_STR[],
SP_X_LBL[], SP_Y_LBL[], SP_Z_LBL[], SP_E_LBL[],
SP_I_STR[], SP_J_STR[], SP_K_STR[],
SP_I_LBL[], SP_J_LBL[], SP_K_LBL[],
SP_P_STR[], SP_T_STR[],
X_STR[], Y_STR[], Z_STR[], E_STR[], X_STR[], Y_STR[], Z_STR[], E_STR[],
X_LBL[], Y_LBL[], Z_LBL[], E_LBL[], X_LBL[], Y_LBL[], Z_LBL[], E_LBL[],
I_LBL[], J_LBL[], K_LBL[]; SP_A_STR[], SP_B_STR[], SP_C_STR[],
SP_X_STR[], SP_Y_STR[], SP_Z_STR[], SP_E_STR[],
SP_X_LBL[], SP_Y_LBL[], SP_Z_LBL[], SP_E_LBL[];
// //
// Debugging flags for use by M111 // Debugging flags for use by M111
@@ -314,10 +310,10 @@ void serialprint_truefalse(const bool tf);
void serial_spaces(uint8_t count); void serial_spaces(uint8_t count);
void print_bin(const uint16_t val); 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(const_float_t x, const_float_t y, const_float_t z, PGM_P const prefix=nullptr, PGM_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, PGM_P const prefix=nullptr, PGM_P const suffix=nullptr) {
print_pos(LINEAR_AXIS_ELEM(xyz), prefix, suffix); print_pos(xyz.x, xyz.y, xyz.z, prefix, suffix);
} }
#define SERIAL_POS(SUFFIX,VAR) do { print_pos(VAR, PSTR(" " STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n")); }while(0) #define SERIAL_POS(SUFFIX,VAR) do { print_pos(VAR, PSTR(" " STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n")); }while(0)

View File

@@ -39,32 +39,6 @@ struct IF { typedef R type; };
template <class L, class R> template <class L, class R>
struct IF<true, L, R> { typedef L type; }; struct IF<true, L, R> { typedef L type; };
#define LINEAR_AXIS_GANG(V...) GANG_N(LINEAR_AXES, V)
#define LINEAR_AXIS_CODE(V...) CODE_N(LINEAR_AXES, V)
#define LINEAR_AXIS_LIST(V...) LIST_N(LINEAR_AXES, V)
#define LINEAR_AXIS_ARRAY(V...) { LINEAR_AXIS_LIST(V) }
#define LINEAR_AXIS_ARGS(T...) LINEAR_AXIS_LIST(T x, T y, T z, T i, T j, T k)
#define LINEAR_AXIS_ELEM(O) LINEAR_AXIS_LIST(O.x, O.y, O.z, O.i, O.j, O.k)
#define LINEAR_AXIS_DEFS(T,V) LINEAR_AXIS_LIST(T x=V, T y=V, T z=V, T i=V, T j=V, T k=V)
#define LOGICAL_AXIS_GANG(E,V...) LINEAR_AXIS_GANG(V) GANG_ITEM_E(E)
#define LOGICAL_AXIS_CODE(E,V...) LINEAR_AXIS_CODE(V) CODE_ITEM_E(E)
#define LOGICAL_AXIS_LIST(E,V...) LINEAR_AXIS_LIST(V) LIST_ITEM_E(E)
#define LOGICAL_AXIS_ARRAY(E,V...) { LOGICAL_AXIS_LIST(E,V) }
#define LOGICAL_AXIS_ARGS(T...) LOGICAL_AXIS_LIST(T e, T x, T y, T z, T i, T j, T k)
#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)
#if HAS_EXTRUDERS
#define LIST_ITEM_E(N) , N
#define CODE_ITEM_E(N) ; N
#define GANG_ITEM_E(N) N
#else
#define LIST_ITEM_E(N)
#define CODE_ITEM_E(N)
#define GANG_ITEM_E(N)
#endif
// //
// Enumerated axis indices // Enumerated axis indices
// //
@@ -73,43 +47,16 @@ struct IF<true, L, R> { typedef L type; };
// - X_HEAD, Y_HEAD, and Z_HEAD should be used for Steppers on Core kinematics // - X_HEAD, Y_HEAD, and Z_HEAD should be used for Steppers on Core kinematics
// //
enum AxisEnum : uint8_t { enum AxisEnum : uint8_t {
X_AXIS = 0, A_AXIS = X_AXIS,
// Linear axes may be controlled directly or indirectly Y_AXIS = 1, B_AXIS = Y_AXIS,
LINEAR_AXIS_LIST(X_AXIS, Y_AXIS, Z_AXIS, I_AXIS, J_AXIS, K_AXIS) Z_AXIS = 2, C_AXIS = Z_AXIS,
E_AXIS,
// Extruder axes may be considered distinctly X_HEAD, Y_HEAD, Z_HEAD,
#define _EN_ITEM(N) , E##N##_AXIS E0_AXIS = E_AXIS,
REPEAT(EXTRUDERS, _EN_ITEM) E1_AXIS, E2_AXIS, E3_AXIS, E4_AXIS, E5_AXIS, E6_AXIS, E7_AXIS,
#undef _EN_ITEM ALL_AXES_ENUM = 0xFE, NO_AXIS_ENUM = 0xFF
// Core also keeps toolhead directions
#if EITHER(IS_CORE, MARKFORGED_XY)
, X_HEAD, Y_HEAD, Z_HEAD
#endif
// Distinct axes, including all E and Core
, NUM_AXIS_ENUMS
// Most of the time we refer only to the single E_AXIS
#if HAS_EXTRUDERS
, E_AXIS = E0_AXIS
#endif
// A, B, and C are for DELTA, SCARA, etc.
, A_AXIS = X_AXIS
#if LINEAR_AXES >= 2
, B_AXIS = Y_AXIS
#endif
#if LINEAR_AXES >= 3
, C_AXIS = Z_AXIS
#endif
// To refer to all or none
, ALL_AXES_ENUM = 0xFE, NO_AXIS_ENUM = 0xFF
}; };
typedef IF<(NUM_AXIS_ENUMS > 8), uint16_t, uint8_t>::type axis_bits_t;
// //
// Loop over axes // Loop over axes
// //
@@ -238,7 +185,7 @@ void toNative(xyz_pos_t &raw);
void toNative(xyze_pos_t &raw); void toNative(xyze_pos_t &raw);
// //
// Paired XY coordinates, counters, flags, etc. // XY coordinates, counters, etc.
// //
template<typename T> template<typename T>
struct XYval { struct XYval {
@@ -247,34 +194,18 @@ struct XYval {
struct { T a, b; }; struct { T a, b; };
T pos[2]; T pos[2];
}; };
// Set all to 0
FI void reset() { x = y = 0; }
// Setters taking struct types and arrays
FI void set(const T px) { x = px; } FI void set(const T px) { x = px; }
#if HAS_Y_AXIS FI void set(const T px, const T py) { x = px; y = py; }
FI void set(const T px, const T py) { x = px; y = py; } FI void set(const T (&arr)[XY]) { x = arr[0]; y = arr[1]; }
FI void set(const T (&arr)[XY]) { x = arr[0]; y = arr[1]; } FI void set(const T (&arr)[XYZ]) { x = arr[0]; y = arr[1]; }
FI void set(const T (&arr)[XYZE]) { x = arr[0]; y = arr[1]; }
#if DISTINCT_AXES > LOGICAL_AXES
FI void set(const T (&arr)[DISTINCT_AXES]) { x = arr[0]; y = arr[1]; }
#endif #endif
#if LINEAR_AXES > XY FI void reset() { x = y = 0; }
FI void set(const T (&arr)[LINEAR_AXES]) { x = arr[0]; y = arr[1]; }
#endif
#if LOGICAL_AXES > LINEAR_AXES
FI void set(const T (&arr)[LOGICAL_AXES]) { x = arr[0]; y = arr[1]; }
#if DISTINCT_AXES > LOGICAL_AXES
FI void set(const T (&arr)[DISTINCT_AXES]) { x = arr[0]; y = arr[1]; }
#endif
#endif
// Length reduced to one dimension
FI T magnitude() const { return (T)sqrtf(x*x + y*y); } FI T magnitude() const { return (T)sqrtf(x*x + y*y); }
// Pointer to the data as a simple array
FI operator T* () { return pos; } FI operator T* () { return pos; }
// If any element is true then it's true
FI operator bool() { return x || y; } FI operator bool() { return x || y; }
// Explicit copy and copies with conversion
FI XYval<T> copy() const { return *this; } FI XYval<T> copy() const { return *this; }
FI XYval<T> ABS() const { return { T(_ABS(x)), T(_ABS(y)) }; } FI XYval<T> ABS() const { return { T(_ABS(x)), T(_ABS(y)) }; }
FI XYval<int16_t> asInt() { return { int16_t(x), int16_t(y) }; } FI XYval<int16_t> asInt() { return { int16_t(x), int16_t(y) }; }
@@ -286,27 +217,17 @@ struct XYval {
FI XYval<float> asFloat() { return { static_cast<float>(x), static_cast<float>(y) }; } FI XYval<float> asFloat() { return { static_cast<float>(x), static_cast<float>(y) }; }
FI XYval<float> asFloat() const { return { static_cast<float>(x), static_cast<float>(y) }; } FI XYval<float> asFloat() const { return { static_cast<float>(x), static_cast<float>(y) }; }
FI XYval<float> reciprocal() const { return { _RECIP(x), _RECIP(y) }; } FI XYval<float> reciprocal() const { return { _RECIP(x), _RECIP(y) }; }
// Marlin workspace shifting is done with G92 and M206
FI XYval<float> asLogical() const { XYval<float> o = asFloat(); toLogical(o); return o; } FI XYval<float> asLogical() const { XYval<float> o = asFloat(); toLogical(o); return o; }
FI XYval<float> asNative() const { XYval<float> o = asFloat(); toNative(o); return o; } FI XYval<float> asNative() const { XYval<float> o = asFloat(); toNative(o); return o; }
// Cast to a type with more fields by making a new object
FI operator XYZval<T>() { return { x, y }; } FI operator XYZval<T>() { return { x, y }; }
FI operator XYZval<T>() const { return { x, y }; } FI operator XYZval<T>() const { return { x, y }; }
FI operator XYZEval<T>() { return { x, y }; } FI operator XYZEval<T>() { return { x, y }; }
FI operator XYZEval<T>() const { return { x, y }; } FI operator XYZEval<T>() const { return { x, y }; }
FI T& operator[](const int i) { return pos[i]; }
// Accessor via an AxisEnum (or any integer) [index] FI const T& operator[](const int i) const { return pos[i]; }
FI T& operator[](const int n) { return pos[n]; }
FI const T& operator[](const int n) const { return pos[n]; }
// Assignment operator overrides do the expected thing
FI XYval<T>& operator= (const T v) { set(v, v ); return *this; } FI XYval<T>& operator= (const T v) { set(v, v ); return *this; }
FI XYval<T>& operator= (const XYZval<T> &rs) { set(rs.x, rs.y); return *this; } FI XYval<T>& operator= (const XYZval<T> &rs) { set(rs.x, rs.y); return *this; }
FI XYval<T>& operator= (const XYZEval<T> &rs) { set(rs.x, rs.y); return *this; } FI XYval<T>& operator= (const XYZEval<T> &rs) { set(rs.x, rs.y); return *this; }
// Override other operators to get intuitive behaviors
FI XYval<T> operator+ (const XYval<T> &rs) const { XYval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; } FI XYval<T> operator+ (const XYval<T> &rs) const { XYval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
FI XYval<T> operator+ (const XYval<T> &rs) { XYval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; } FI XYval<T> operator+ (const XYval<T> &rs) { XYval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
FI XYval<T> operator- (const XYval<T> &rs) const { XYval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; } FI XYval<T> operator- (const XYval<T> &rs) const { XYval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; }
@@ -343,10 +264,6 @@ struct XYval {
FI XYval<T> operator>>(const int &v) { XYval<T> ls = *this; _RS(ls.x); _RS(ls.y); return ls; } FI XYval<T> operator>>(const int &v) { XYval<T> ls = *this; _RS(ls.x); _RS(ls.y); return ls; }
FI XYval<T> operator<<(const int &v) const { XYval<T> ls = *this; _LS(ls.x); _LS(ls.y); return ls; } FI XYval<T> operator<<(const int &v) const { XYval<T> ls = *this; _LS(ls.x); _LS(ls.y); return ls; }
FI XYval<T> operator<<(const int &v) { XYval<T> ls = *this; _LS(ls.x); _LS(ls.y); return ls; } FI XYval<T> operator<<(const int &v) { XYval<T> ls = *this; _LS(ls.x); _LS(ls.y); return ls; }
FI const XYval<T> operator-() const { XYval<T> o = *this; o.x = -x; o.y = -y; return o; }
FI XYval<T> operator-() { XYval<T> o = *this; o.x = -x; o.y = -y; return o; }
// Modifier operators
FI XYval<T>& operator+=(const XYval<T> &rs) { x += rs.x; y += rs.y; return *this; } FI XYval<T>& operator+=(const XYval<T> &rs) { x += rs.x; y += rs.y; return *this; }
FI XYval<T>& operator-=(const XYval<T> &rs) { x -= rs.x; y -= rs.y; return *this; } FI XYval<T>& operator-=(const XYval<T> &rs) { x -= rs.x; y -= rs.y; return *this; }
FI XYval<T>& operator*=(const XYval<T> &rs) { x *= rs.x; y *= rs.y; return *this; } FI XYval<T>& operator*=(const XYval<T> &rs) { x *= rs.x; y *= rs.y; return *this; }
@@ -360,8 +277,6 @@ struct XYval {
FI XYval<T>& operator*=(const int &v) { x *= v; y *= v; return *this; } FI XYval<T>& operator*=(const int &v) { x *= v; y *= v; return *this; }
FI XYval<T>& operator>>=(const int &v) { _RS(x); _RS(y); return *this; } FI XYval<T>& operator>>=(const int &v) { _RS(x); _RS(y); return *this; }
FI XYval<T>& operator<<=(const int &v) { _LS(x); _LS(y); return *this; } FI XYval<T>& operator<<=(const int &v) { _LS(x); _LS(y); return *this; }
// Exact comparisons. For floats a "NEAR" operation may be better.
FI bool operator==(const XYval<T> &rs) { return x == rs.x && y == rs.y; } FI bool operator==(const XYval<T> &rs) { return x == rs.x && y == rs.y; }
FI bool operator==(const XYZval<T> &rs) { return x == rs.x && y == rs.y; } FI bool operator==(const XYZval<T> &rs) { return x == rs.x && y == rs.y; }
FI bool operator==(const XYZEval<T> &rs) { return x == rs.x && y == rs.y; } FI bool operator==(const XYZEval<T> &rs) { return x == rs.x && y == rs.y; }
@@ -374,291 +289,224 @@ struct XYval {
FI bool operator!=(const XYval<T> &rs) const { return !operator==(rs); } FI bool operator!=(const XYval<T> &rs) const { return !operator==(rs); }
FI bool operator!=(const XYZval<T> &rs) const { return !operator==(rs); } FI bool operator!=(const XYZval<T> &rs) const { return !operator==(rs); }
FI bool operator!=(const XYZEval<T> &rs) const { return !operator==(rs); } FI bool operator!=(const XYZEval<T> &rs) const { return !operator==(rs); }
FI XYval<T> operator-() { XYval<T> o = *this; o.x = -x; o.y = -y; return o; }
FI const XYval<T> operator-() const { XYval<T> o = *this; o.x = -x; o.y = -y; return o; }
}; };
// //
// Linear Axes coordinates, counters, flags, etc. // XYZ coordinates, counters, etc.
// //
template<typename T> template<typename T>
struct XYZval { struct XYZval {
union { union {
struct { T LINEAR_AXIS_ARGS(); }; struct { T x, y, z; };
struct { T LINEAR_AXIS_LIST(a, b, c, u, v, w); }; struct { T a, b, c; };
T pos[LINEAR_AXES]; T pos[3];
}; };
// Set all to 0
FI void reset() { LINEAR_AXIS_GANG(x =, y =, z =, i =, j =, k =) 0; }
// Setters taking struct types and arrays
FI void set(const T px) { x = px; } FI void set(const T px) { x = px; }
FI void set(const T px, const T py) { x = px; y = py; } FI void set(const T px, const T py) { x = px; y = py; }
FI void set(const XYval<T> pxy) { x = pxy.x; y = pxy.y; } FI void set(const T px, const T py, const T pz) { x = px; y = py; z = pz; }
FI void set(const XYval<T> pxy, const T pz) { LINEAR_AXIS_CODE(x = pxy.x, y = pxy.y, z = pz, NOOP, NOOP, NOOP); } FI void set(const XYval<T> pxy, const T pz) { x = pxy.x; y = pxy.y; z = pz; }
FI void set(const T (&arr)[XY]) { x = arr[0]; y = arr[1]; } FI void set(const T (&arr)[XY]) { x = arr[0]; y = arr[1]; }
#if HAS_Z_AXIS FI void set(const T (&arr)[XYZ]) { x = arr[0]; y = arr[1]; z = arr[2]; }
FI void set(const T (&arr)[LINEAR_AXES]) { LINEAR_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5]); } FI void set(const T (&arr)[XYZE]) { x = arr[0]; y = arr[1]; z = arr[2]; }
FI void set(LINEAR_AXIS_ARGS(const T)) { LINEAR_AXIS_CODE(a = x, b = y, c = z, u = i, v = j, w = k ); } #if DISTINCT_AXES > XYZE
FI void set(const T (&arr)[DISTINCT_AXES]) { x = arr[0]; y = arr[1]; z = arr[2]; }
#endif #endif
#if LOGICAL_AXES > LINEAR_AXES FI void reset() { x = y = z = 0; }
FI void set(const T (&arr)[LOGICAL_AXES]) { LINEAR_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5]); } FI T magnitude() const { return (T)sqrtf(x*x + y*y + z*z); }
FI void set(LOGICAL_AXIS_ARGS(const T)) { LINEAR_AXIS_CODE(a = x, b = y, c = z, u = i, v = j, w = k ); }
#if DISTINCT_AXES > LOGICAL_AXES
FI void set(const T (&arr)[DISTINCT_AXES]) { LINEAR_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5]); }
#endif
#endif
#if LINEAR_AXES >= 4
FI void set(const T px, const T py, const T pz) { x = px; y = py; z = pz; }
#endif
#if LINEAR_AXES >= 5
FI void set(const T px, const T py, const T pz, const T pi) { x = px; y = py; z = pz; i = pi; }
#endif
#if LINEAR_AXES >= 6
FI void set(const T px, const T py, const T pz, const T pi, const T pj) { x = px; y = py; z = pz; i = pi; j = pj; }
#endif
// Length reduced to one dimension
FI T magnitude() const { return (T)sqrtf(LINEAR_AXIS_GANG(x*x, + y*y, + z*z, + i*i, + j*j, + k*k)); }
// Pointer to the data as a simple array
FI operator T* () { return pos; } FI operator T* () { return pos; }
// If any element is true then it's true FI operator bool() { return z || x || y; }
FI operator bool() { return LINEAR_AXIS_GANG(x, || y, || z, || i, || j, || k); }
// Explicit copy and copies with conversion
FI XYZval<T> copy() const { XYZval<T> o = *this; return o; } FI XYZval<T> copy() const { XYZval<T> o = *this; return o; }
FI XYZval<T> ABS() const { return LINEAR_AXIS_ARRAY(T(_ABS(x)), T(_ABS(y)), T(_ABS(z)), T(_ABS(i)), T(_ABS(j)), T(_ABS(k))); } FI XYZval<T> ABS() const { return { T(_ABS(x)), T(_ABS(y)), T(_ABS(z)) }; }
FI XYZval<int16_t> asInt() { return LINEAR_AXIS_ARRAY(int16_t(x), int16_t(y), int16_t(z), int16_t(i), int16_t(j), int16_t(k)); } FI XYZval<int16_t> asInt() { return { int16_t(x), int16_t(y), int16_t(z) }; }
FI XYZval<int16_t> asInt() const { return LINEAR_AXIS_ARRAY(int16_t(x), int16_t(y), int16_t(z), int16_t(i), int16_t(j), int16_t(k)); } FI XYZval<int16_t> asInt() const { return { int16_t(x), int16_t(y), int16_t(z) }; }
FI XYZval<int32_t> asLong() { return LINEAR_AXIS_ARRAY(int32_t(x), int32_t(y), int32_t(z), int32_t(i), int32_t(j), int32_t(k)); } FI XYZval<int32_t> asLong() { return { int32_t(x), int32_t(y), int32_t(z) }; }
FI XYZval<int32_t> asLong() const { return LINEAR_AXIS_ARRAY(int32_t(x), int32_t(y), int32_t(z), int32_t(i), int32_t(j), int32_t(k)); } FI XYZval<int32_t> asLong() const { return { int32_t(x), int32_t(y), int32_t(z) }; }
FI XYZval<int32_t> ROUNDL() { return LINEAR_AXIS_ARRAY(int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)), int32_t(LROUND(i)), int32_t(LROUND(j)), int32_t(LROUND(k))); } FI XYZval<int32_t> ROUNDL() { return { int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)) }; }
FI XYZval<int32_t> ROUNDL() const { return LINEAR_AXIS_ARRAY(int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)), int32_t(LROUND(i)), int32_t(LROUND(j)), int32_t(LROUND(k))); } FI XYZval<int32_t> ROUNDL() const { return { int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)) }; }
FI XYZval<float> asFloat() { return LINEAR_AXIS_ARRAY(static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(i), static_cast<float>(j), static_cast<float>(k)); } FI XYZval<float> asFloat() { return { static_cast<float>(x), static_cast<float>(y), static_cast<float>(z) }; }
FI XYZval<float> asFloat() const { return LINEAR_AXIS_ARRAY(static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(i), static_cast<float>(j), static_cast<float>(k)); } FI XYZval<float> asFloat() const { return { static_cast<float>(x), static_cast<float>(y), static_cast<float>(z) }; }
FI XYZval<float> reciprocal() const { return LINEAR_AXIS_ARRAY(_RECIP(x), _RECIP(y), _RECIP(z), _RECIP(i), _RECIP(j), _RECIP(k)); } FI XYZval<float> reciprocal() const { return { _RECIP(x), _RECIP(y), _RECIP(z) }; }
// Marlin workspace shifting is done with G92 and M206
FI XYZval<float> asLogical() const { XYZval<float> o = asFloat(); toLogical(o); return o; } FI XYZval<float> asLogical() const { XYZval<float> o = asFloat(); toLogical(o); return o; }
FI XYZval<float> asNative() const { XYZval<float> o = asFloat(); toNative(o); return o; } FI XYZval<float> asNative() const { XYZval<float> o = asFloat(); toNative(o); return o; }
// In-place cast to types having fewer fields
FI operator XYval<T>&() { return *(XYval<T>*)this; } FI operator XYval<T>&() { return *(XYval<T>*)this; }
FI operator const XYval<T>&() const { return *(const XYval<T>*)this; } FI operator const XYval<T>&() const { return *(const XYval<T>*)this; }
FI operator XYZEval<T>() const { return { x, y, z }; }
// Cast to a type with more fields by making a new object FI T& operator[](const int i) { return pos[i]; }
FI operator XYZEval<T>() const { return LINEAR_AXIS_ARRAY(x, y, z, i, j, k); } FI const T& operator[](const int i) const { return pos[i]; }
FI XYZval<T>& operator= (const T v) { set(v, v, v ); return *this; }
// Accessor via an AxisEnum (or any integer) [index]
FI T& operator[](const int n) { return pos[n]; }
FI const T& operator[](const int n) const { return pos[n]; }
// Assignment operator overrides do the expected thing
FI XYZval<T>& operator= (const T v) { set(ARRAY_N_1(LINEAR_AXES, v)); return *this; }
FI XYZval<T>& operator= (const XYval<T> &rs) { set(rs.x, rs.y ); return *this; } FI XYZval<T>& operator= (const XYval<T> &rs) { set(rs.x, rs.y ); return *this; }
FI XYZval<T>& operator= (const XYZEval<T> &rs) { set(LINEAR_AXIS_ELEM(rs)); return *this; } FI XYZval<T>& operator= (const XYZEval<T> &rs) { set(rs.x, rs.y, rs.z); return *this; }
FI XYZval<T> operator+ (const XYval<T> &rs) const { XYZval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
// Override other operators to get intuitive behaviors FI XYZval<T> operator+ (const XYval<T> &rs) { XYZval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
FI XYZval<T> operator+ (const XYval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, NOOP , NOOP , NOOP , NOOP ); return ls; } FI XYZval<T> operator- (const XYval<T> &rs) const { XYZval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; }
FI XYZval<T> operator+ (const XYval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, NOOP , NOOP , NOOP , NOOP ); return ls; } FI XYZval<T> operator- (const XYval<T> &rs) { XYZval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; }
FI XYZval<T> operator- (const XYval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, NOOP , NOOP , NOOP , NOOP ); return ls; } FI XYZval<T> operator* (const XYval<T> &rs) const { XYZval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; }
FI XYZval<T> operator- (const XYval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, NOOP , NOOP , NOOP , NOOP ); return ls; } FI XYZval<T> operator* (const XYval<T> &rs) { XYZval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; }
FI XYZval<T> operator* (const XYval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, NOOP , NOOP , NOOP , NOOP ); return ls; } FI XYZval<T> operator/ (const XYval<T> &rs) const { XYZval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
FI XYZval<T> operator* (const XYval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, NOOP , NOOP , NOOP , NOOP ); return ls; } FI XYZval<T> operator/ (const XYval<T> &rs) { XYZval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
FI XYZval<T> operator/ (const XYval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, NOOP , NOOP , NOOP , NOOP ); return ls; } FI XYZval<T> operator+ (const XYZval<T> &rs) const { XYZval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; ls.z += rs.z; return ls; }
FI XYZval<T> operator/ (const XYval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, NOOP , NOOP , NOOP , NOOP ); return ls; } FI XYZval<T> operator+ (const XYZval<T> &rs) { XYZval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; ls.z += rs.z; return ls; }
FI XYZval<T> operator+ (const XYZval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, ls.z += rs.z, ls.i += rs.i, ls.j += rs.j, ls.k += rs.k); return ls; } FI XYZval<T> operator- (const XYZval<T> &rs) const { XYZval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; ls.z -= rs.z; return ls; }
FI XYZval<T> operator+ (const XYZval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, ls.z += rs.z, ls.i += rs.i, ls.j += rs.j, ls.k += rs.k); return ls; } FI XYZval<T> operator- (const XYZval<T> &rs) { XYZval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; ls.z -= rs.z; return ls; }
FI XYZval<T> operator- (const XYZval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z, ls.i -= rs.i, ls.j -= rs.j, ls.k -= rs.k); return ls; } FI XYZval<T> operator* (const XYZval<T> &rs) const { XYZval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; ls.z *= rs.z; return ls; }
FI XYZval<T> operator- (const XYZval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z, ls.i -= rs.i, ls.j -= rs.j, ls.k -= rs.k); return ls; } FI XYZval<T> operator* (const XYZval<T> &rs) { XYZval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; ls.z *= rs.z; return ls; }
FI XYZval<T> operator* (const XYZval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k); return ls; } FI XYZval<T> operator/ (const XYZval<T> &rs) const { XYZval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; ls.z /= rs.z; return ls; }
FI XYZval<T> operator* (const XYZval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k); return ls; } FI XYZval<T> operator/ (const XYZval<T> &rs) { XYZval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; ls.z /= rs.z; return ls; }
FI XYZval<T> operator/ (const XYZval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k); return ls; } FI XYZval<T> operator+ (const XYZEval<T> &rs) const { XYZval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; ls.z += rs.z; return ls; }
FI XYZval<T> operator/ (const XYZval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k); return ls; } FI XYZval<T> operator+ (const XYZEval<T> &rs) { XYZval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; ls.z += rs.z; return ls; }
FI XYZval<T> operator+ (const XYZEval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, ls.z += rs.z, ls.i += rs.i, ls.j += rs.j, ls.k += rs.k); return ls; } FI XYZval<T> operator- (const XYZEval<T> &rs) const { XYZval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; ls.z -= rs.z; return ls; }
FI XYZval<T> operator+ (const XYZEval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, ls.z += rs.z, ls.i += rs.i, ls.j += rs.j, ls.k += rs.k); return ls; } FI XYZval<T> operator- (const XYZEval<T> &rs) { XYZval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; ls.z -= rs.z; return ls; }
FI XYZval<T> operator- (const XYZEval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z, ls.i -= rs.i, ls.j -= rs.j, ls.k -= rs.k); return ls; } FI XYZval<T> operator* (const XYZEval<T> &rs) const { XYZval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; ls.z *= rs.z; return ls; }
FI XYZval<T> operator- (const XYZEval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z, ls.i -= rs.i, ls.j -= rs.j, ls.k -= rs.k); return ls; } FI XYZval<T> operator* (const XYZEval<T> &rs) { XYZval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; ls.z *= rs.z; return ls; }
FI XYZval<T> operator* (const XYZEval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k); return ls; } FI XYZval<T> operator/ (const XYZEval<T> &rs) const { XYZval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; ls.z /= rs.z; return ls; }
FI XYZval<T> operator* (const XYZEval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k); return ls; } FI XYZval<T> operator/ (const XYZEval<T> &rs) { XYZval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; ls.z /= rs.z; return ls; }
FI XYZval<T> operator/ (const XYZEval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k); return ls; } FI XYZval<T> operator* (const float &v) const { XYZval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; return ls; }
FI XYZval<T> operator/ (const XYZEval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k); return ls; } FI XYZval<T> operator* (const float &v) { XYZval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; return ls; }
FI XYZval<T> operator* (const float &v) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v ); return ls; } FI XYZval<T> operator* (const int &v) const { XYZval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; return ls; }
FI XYZval<T> operator* (const float &v) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v ); return ls; } FI XYZval<T> operator* (const int &v) { XYZval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; return ls; }
FI XYZval<T> operator* (const int &v) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v ); return ls; } FI XYZval<T> operator/ (const float &v) const { XYZval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; return ls; }
FI XYZval<T> operator* (const int &v) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v ); return ls; } FI XYZval<T> operator/ (const float &v) { XYZval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; return ls; }
FI XYZval<T> operator/ (const float &v) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v ); return ls; } FI XYZval<T> operator/ (const int &v) const { XYZval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; return ls; }
FI XYZval<T> operator/ (const float &v) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v ); return ls; } FI XYZval<T> operator/ (const int &v) { XYZval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; return ls; }
FI XYZval<T> operator/ (const int &v) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v ); return ls; } FI XYZval<T> operator>>(const int &v) const { XYZval<T> ls = *this; _RS(ls.x); _RS(ls.y); _RS(ls.z); return ls; }
FI XYZval<T> operator/ (const int &v) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v ); return ls; } FI XYZval<T> operator>>(const int &v) { XYZval<T> ls = *this; _RS(ls.x); _RS(ls.y); _RS(ls.z); return ls; }
FI XYZval<T> operator>>(const int &v) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(_RS(ls.x), _RS(ls.y), _RS(ls.z), _RS(ls.i), _RS(ls.j), _RS(ls.k) ); return ls; } FI XYZval<T> operator<<(const int &v) const { XYZval<T> ls = *this; _LS(ls.x); _LS(ls.y); _LS(ls.z); return ls; }
FI XYZval<T> operator>>(const int &v) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(_RS(ls.x), _RS(ls.y), _RS(ls.z), _RS(ls.i), _RS(ls.j), _RS(ls.k) ); return ls; } FI XYZval<T> operator<<(const int &v) { XYZval<T> ls = *this; _LS(ls.x); _LS(ls.y); _LS(ls.z); return ls; }
FI XYZval<T> operator<<(const int &v) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(_LS(ls.x), _LS(ls.y), _LS(ls.z), _LS(ls.i), _LS(ls.j), _LS(ls.k) ); return ls; } FI XYZval<T>& operator+=(const XYval<T> &rs) { x += rs.x; y += rs.y; return *this; }
FI XYZval<T> operator<<(const int &v) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(_LS(ls.x), _LS(ls.y), _LS(ls.z), _LS(ls.i), _LS(ls.j), _LS(ls.k) ); return ls; } FI XYZval<T>& operator-=(const XYval<T> &rs) { x -= rs.x; y -= rs.y; return *this; }
FI const XYZval<T> operator-() const { XYZval<T> o = *this; LINEAR_AXIS_CODE(o.x = -x, o.y = -y, o.z = -z, o.i = -i, o.j = -j, o.k = -k); return o; } FI XYZval<T>& operator*=(const XYval<T> &rs) { x *= rs.x; y *= rs.y; return *this; }
FI XYZval<T> operator-() { XYZval<T> o = *this; LINEAR_AXIS_CODE(o.x = -x, o.y = -y, o.z = -z, o.i = -i, o.j = -j, o.k = -k); return o; } FI XYZval<T>& operator/=(const XYval<T> &rs) { x /= rs.x; y /= rs.y; return *this; }
FI XYZval<T>& operator+=(const XYZval<T> &rs) { x += rs.x; y += rs.y; z += rs.z; return *this; }
// Modifier operators FI XYZval<T>& operator-=(const XYZval<T> &rs) { x -= rs.x; y -= rs.y; z -= rs.z; return *this; }
FI XYZval<T>& operator+=(const XYval<T> &rs) { LINEAR_AXIS_CODE(x += rs.x, y += rs.y, NOOP, NOOP, NOOP, NOOP ); return *this; } FI XYZval<T>& operator*=(const XYZval<T> &rs) { x *= rs.x; y *= rs.y; z *= rs.z; return *this; }
FI XYZval<T>& operator-=(const XYval<T> &rs) { LINEAR_AXIS_CODE(x -= rs.x, y -= rs.y, NOOP, NOOP, NOOP, NOOP ); return *this; } FI XYZval<T>& operator/=(const XYZval<T> &rs) { x /= rs.x; y /= rs.y; z /= rs.z; return *this; }
FI XYZval<T>& operator*=(const XYval<T> &rs) { LINEAR_AXIS_CODE(x *= rs.x, y *= rs.y, NOOP, NOOP, NOOP, NOOP ); return *this; } FI XYZval<T>& operator+=(const XYZEval<T> &rs) { x += rs.x; y += rs.y; z += rs.z; return *this; }
FI XYZval<T>& operator/=(const XYval<T> &rs) { LINEAR_AXIS_CODE(x /= rs.x, y /= rs.y, NOOP, NOOP, NOOP, NOOP ); return *this; } FI XYZval<T>& operator-=(const XYZEval<T> &rs) { x -= rs.x; y -= rs.y; z -= rs.z; return *this; }
FI XYZval<T>& operator+=(const XYZval<T> &rs) { LINEAR_AXIS_CODE(x += rs.x, y += rs.y, z += rs.z, i += rs.i, j += rs.j, k += rs.k); return *this; } FI XYZval<T>& operator*=(const XYZEval<T> &rs) { x *= rs.x; y *= rs.y; z *= rs.z; return *this; }
FI XYZval<T>& operator-=(const XYZval<T> &rs) { LINEAR_AXIS_CODE(x -= rs.x, y -= rs.y, z -= rs.z, i -= rs.i, j -= rs.j, k -= rs.k); return *this; } FI XYZval<T>& operator/=(const XYZEval<T> &rs) { x /= rs.x; y /= rs.y; z /= rs.z; return *this; }
FI XYZval<T>& operator*=(const XYZval<T> &rs) { LINEAR_AXIS_CODE(x *= rs.x, y *= rs.y, z *= rs.z, i *= rs.i, j *= rs.j, k *= rs.k); return *this; } FI XYZval<T>& operator*=(const float &v) { x *= v; y *= v; z *= v; return *this; }
FI XYZval<T>& operator/=(const XYZval<T> &rs) { LINEAR_AXIS_CODE(x /= rs.x, y /= rs.y, z /= rs.z, i /= rs.i, j /= rs.j, k /= rs.k); return *this; } FI XYZval<T>& operator*=(const int &v) { x *= v; y *= v; z *= v; return *this; }
FI XYZval<T>& operator+=(const XYZEval<T> &rs) { LINEAR_AXIS_CODE(x += rs.x, y += rs.y, z += rs.z, i += rs.i, j += rs.j, k += rs.k); return *this; } FI XYZval<T>& operator>>=(const int &v) { _RS(x); _RS(y); _RS(z); return *this; }
FI XYZval<T>& operator-=(const XYZEval<T> &rs) { LINEAR_AXIS_CODE(x -= rs.x, y -= rs.y, z -= rs.z, i -= rs.i, j -= rs.j, k -= rs.k); return *this; } FI XYZval<T>& operator<<=(const int &v) { _LS(x); _LS(y); _LS(z); return *this; }
FI XYZval<T>& operator*=(const XYZEval<T> &rs) { LINEAR_AXIS_CODE(x *= rs.x, y *= rs.y, z *= rs.z, i *= rs.i, j *= rs.j, k *= rs.k); return *this; } FI bool operator==(const XYZEval<T> &rs) { return x == rs.x && y == rs.y && z == rs.z; }
FI XYZval<T>& operator/=(const XYZEval<T> &rs) { LINEAR_AXIS_CODE(x /= rs.x, y /= rs.y, z /= rs.z, i /= rs.i, j /= rs.j, k /= rs.k); return *this; }
FI XYZval<T>& operator*=(const float &v) { LINEAR_AXIS_CODE(x *= v, y *= v, z *= v, i *= v, j *= v, k *= v); return *this; }
FI XYZval<T>& operator*=(const int &v) { LINEAR_AXIS_CODE(x *= v, y *= v, z *= v, i *= v, j *= v, k *= v); return *this; }
FI XYZval<T>& operator>>=(const int &v) { LINEAR_AXIS_CODE(_RS(x), _RS(y), _RS(z), _RS(i), _RS(j), _RS(k)); return *this; }
FI XYZval<T>& operator<<=(const int &v) { LINEAR_AXIS_CODE(_LS(x), _LS(y), _LS(z), _LS(i), _LS(j), _LS(k)); return *this; }
// Exact comparisons. For floats a "NEAR" operation may be better.
FI bool operator==(const XYZEval<T> &rs) { return true LINEAR_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k); }
FI bool operator==(const XYZEval<T> &rs) const { return true LINEAR_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k); }
FI bool operator!=(const XYZEval<T> &rs) { return !operator==(rs); } FI bool operator!=(const XYZEval<T> &rs) { return !operator==(rs); }
FI bool operator==(const XYZEval<T> &rs) const { return x == rs.x && y == rs.y && z == rs.z; }
FI bool operator!=(const XYZEval<T> &rs) const { return !operator==(rs); } FI bool operator!=(const XYZEval<T> &rs) const { return !operator==(rs); }
FI XYZval<T> operator-() { XYZval<T> o = *this; o.x = -x; o.y = -y; o.z = -z; return o; }
FI const XYZval<T> operator-() const { XYZval<T> o = *this; o.x = -x; o.y = -y; o.z = -z; return o; }
}; };
// //
// Logical Axes coordinates, counters, etc. // XYZE coordinates, counters, etc.
// //
template<typename T> template<typename T>
struct XYZEval { struct XYZEval {
union { union {
struct { T LOGICAL_AXIS_ARGS(); }; struct{ T x, y, z, e; };
struct { T LOGICAL_AXIS_LIST(_e, a, b, c, u, v, w); }; struct{ T a, b, c; };
T pos[LOGICAL_AXES]; T pos[4];
}; };
// Reset all to 0 FI void reset() { x = y = z = e = 0; }
FI void reset() { LOGICAL_AXIS_GANG(e =, x =, y =, z =, i =, j =, k =) 0; } FI T magnitude() const { return (T)sqrtf(x*x + y*y + z*z + e*e); }
FI operator T* () { return pos; }
// Setters taking struct types and arrays FI operator bool() { return e || z || x || y; }
FI void set(const T px) { x = px; } FI void set(const T px) { x = px; }
FI void set(const T px, const T py) { x = px; y = py; } FI void set(const T px, const T py) { x = px; y = py; }
FI void set(const XYval<T> pxy) { x = pxy.x; y = pxy.y; } FI void set(const T px, const T py, const T pz) { x = px; y = py; z = pz; }
FI void set(const XYZval<T> pxyz) { set(LINEAR_AXIS_ELEM(pxyz)); } FI void set(const T px, const T py, const T pz, const T pe) { x = px; y = py; z = pz; e = pe; }
#if HAS_Z_AXIS FI void set(const XYval<T> pxy) { x = pxy.x; y = pxy.y; }
FI void set(LINEAR_AXIS_ARGS(const T)) { LINEAR_AXIS_CODE(a = x, b = y, c = z, u = i, v = j, w = k); } FI void set(const XYval<T> pxy, const T pz) { x = pxy.x; y = pxy.y; z = pz; }
FI void set(const XYZval<T> pxyz) { x = pxyz.x; y = pxyz.y; z = pxyz.z; }
FI void set(const XYval<T> pxy, const T pz, const T pe) { x = pxy.x; y = pxy.y; z = pz; e = pe; }
FI void set(const XYval<T> pxy, const XYval<T> pze) { x = pxy.x; y = pxy.y; z = pze.z; e = pze.e; }
FI void set(const XYZval<T> pxyz, const T pe) { x = pxyz.x; y = pxyz.y; z = pxyz.z; e = pe; }
FI void set(const T (&arr)[XY]) { x = arr[0]; y = arr[1]; }
FI void set(const T (&arr)[XYZ]) { x = arr[0]; y = arr[1]; z = arr[2]; }
FI void set(const T (&arr)[XYZE]) { x = arr[0]; y = arr[1]; z = arr[2]; e = arr[3]; }
#if DISTINCT_AXES > XYZE
FI void set(const T (&arr)[DISTINCT_AXES]) { x = arr[0]; y = arr[1]; z = arr[2]; e = arr[3]; }
#endif #endif
#if LOGICAL_AXES > LINEAR_AXES FI XYZEval<T> copy() const { return *this; }
FI void set(const XYval<T> pxy, const T pe) { set(pxy); e = pe; } FI XYZEval<T> ABS() const { return { T(_ABS(x)), T(_ABS(y)), T(_ABS(z)), T(_ABS(e)) }; }
FI void set(const XYZval<T> pxyz, const T pe) { set(pxyz); e = pe; } FI XYZEval<int16_t> asInt() { return { int16_t(x), int16_t(y), int16_t(z), int16_t(e) }; }
FI void set(LOGICAL_AXIS_ARGS(const T)) { LOGICAL_AXIS_CODE(_e = e, a = x, b = y, c = z, u = i, v = j, w = k); } FI XYZEval<int16_t> asInt() const { return { int16_t(x), int16_t(y), int16_t(z), int16_t(e) }; }
#endif FI XYZEval<int32_t> asLong() { return { int32_t(x), int32_t(y), int32_t(z), int32_t(e) }; }
#if LINEAR_AXES >= 4 FI XYZEval<int32_t> asLong() const { return { int32_t(x), int32_t(y), int32_t(z), int32_t(e) }; }
FI void set(const T px, const T py, const T pz) { x = px; y = py; z = pz; } FI XYZEval<int32_t> ROUNDL() { return { int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)), int32_t(LROUND(e)) }; }
#endif FI XYZEval<int32_t> ROUNDL() const { return { int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)), int32_t(LROUND(e)) }; }
#if LINEAR_AXES >= 5 FI XYZEval<float> asFloat() { return { static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(e) }; }
FI void set(const T px, const T py, const T pz, const T pi) { x = px; y = py; z = pz; i = pi; } FI XYZEval<float> asFloat() const { return { static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(e) }; }
#endif FI XYZEval<float> reciprocal() const { return { _RECIP(x), _RECIP(y), _RECIP(z), _RECIP(e) }; }
#if LINEAR_AXES >= 6 FI XYZEval<float> asLogical() const { XYZEval<float> o = asFloat(); toLogical(o); return o; }
FI void set(const T px, const T py, const T pz, const T pi, const T pj) { x = px; y = py; z = pz; i = pi; j = pj; } FI XYZEval<float> asNative() const { XYZEval<float> o = asFloat(); toNative(o); return o; }
#endif FI operator XYval<T>&() { return *(XYval<T>*)this; }
FI operator const XYval<T>&() const { return *(const XYval<T>*)this; }
// Length reduced to one dimension FI operator XYZval<T>&() { return *(XYZval<T>*)this; }
FI T magnitude() const { return (T)sqrtf(LOGICAL_AXIS_GANG(+ e*e, + x*x, + y*y, + z*z, + i*i, + j*j, + k*k)); } FI operator const XYZval<T>&() const { return *(const XYZval<T>*)this; }
// Pointer to the data as a simple array FI T& operator[](const int i) { return pos[i]; }
FI operator T* () { return pos; } FI const T& operator[](const int i) const { return pos[i]; }
// If any element is true then it's true FI XYZEval<T>& operator= (const T v) { set(v, v, v, v); return *this; }
FI operator bool() { return 0 LOGICAL_AXIS_GANG(|| e, || x, || y, || z, || i, || j, || k); } FI XYZEval<T>& operator= (const XYval<T> &rs) { set(rs.x, rs.y); return *this; }
FI XYZEval<T>& operator= (const XYZval<T> &rs) { set(rs.x, rs.y, rs.z); return *this; }
// Explicit copy and copies with conversion FI XYZEval<T> operator+ (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
FI XYZEval<T> copy() const { XYZEval<T> o = *this; return o; } FI XYZEval<T> operator+ (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
FI XYZEval<T> ABS() const { return LOGICAL_AXIS_ARRAY(T(_ABS(e)), T(_ABS(x)), T(_ABS(y)), T(_ABS(z)), T(_ABS(i)), T(_ABS(j)), T(_ABS(k))); } FI XYZEval<T> operator- (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; }
FI XYZEval<int16_t> asInt() { return LOGICAL_AXIS_ARRAY(int16_t(e), int16_t(x), int16_t(y), int16_t(z), int16_t(i), int16_t(j), int16_t(k)); } FI XYZEval<T> operator- (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; }
FI XYZEval<int16_t> asInt() const { return LOGICAL_AXIS_ARRAY(int16_t(e), int16_t(x), int16_t(y), int16_t(z), int16_t(i), int16_t(j), int16_t(k)); } FI XYZEval<T> operator* (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; }
FI XYZEval<int32_t> asLong() { return LOGICAL_AXIS_ARRAY(int32_t(e), int32_t(x), int32_t(y), int32_t(z), int32_t(i), int32_t(j), int32_t(k)); } FI XYZEval<T> operator* (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; }
FI XYZEval<int32_t> asLong() const { return LOGICAL_AXIS_ARRAY(int32_t(e), int32_t(x), int32_t(y), int32_t(z), int32_t(i), int32_t(j), int32_t(k)); } FI XYZEval<T> operator/ (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
FI XYZEval<int32_t> ROUNDL() { return LOGICAL_AXIS_ARRAY(int32_t(LROUND(e)), int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)), int32_t(LROUND(i)), int32_t(LROUND(j)), int32_t(LROUND(k))); } FI XYZEval<T> operator/ (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
FI XYZEval<int32_t> ROUNDL() const { return LOGICAL_AXIS_ARRAY(int32_t(LROUND(e)), int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)), int32_t(LROUND(i)), int32_t(LROUND(j)), int32_t(LROUND(k))); } FI XYZEval<T> operator+ (const XYZval<T> &rs) const { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; ls.z += rs.z; return ls; }
FI XYZEval<float> asFloat() { return LOGICAL_AXIS_ARRAY(static_cast<float>(e), static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(i), static_cast<float>(j), static_cast<float>(k)); } FI XYZEval<T> operator+ (const XYZval<T> &rs) { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; ls.z += rs.z; return ls; }
FI XYZEval<float> asFloat() const { return LOGICAL_AXIS_ARRAY(static_cast<float>(e), static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(i), static_cast<float>(j), static_cast<float>(k)); } FI XYZEval<T> operator- (const XYZval<T> &rs) const { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; ls.z -= rs.z; return ls; }
FI XYZEval<float> reciprocal() const { return LOGICAL_AXIS_ARRAY(_RECIP(e), _RECIP(x), _RECIP(y), _RECIP(z), _RECIP(i), _RECIP(j), _RECIP(k)); } FI XYZEval<T> operator- (const XYZval<T> &rs) { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; ls.z -= rs.z; return ls; }
FI XYZEval<T> operator* (const XYZval<T> &rs) const { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; ls.z *= rs.z; return ls; }
// Marlin workspace shifting is done with G92 and M206 FI XYZEval<T> operator* (const XYZval<T> &rs) { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; ls.z *= rs.z; return ls; }
FI XYZEval<float> asLogical() const { XYZEval<float> o = asFloat(); toLogical(o); return o; } FI XYZEval<T> operator/ (const XYZval<T> &rs) const { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; ls.z /= rs.z; return ls; }
FI XYZEval<float> asNative() const { XYZEval<float> o = asFloat(); toNative(o); return o; } FI XYZEval<T> operator/ (const XYZval<T> &rs) { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; ls.z /= rs.z; return ls; }
FI XYZEval<T> operator+ (const XYZEval<T> &rs) const { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; ls.z += rs.z; ls.e += rs.e; return ls; }
// In-place cast to types having fewer fields FI XYZEval<T> operator+ (const XYZEval<T> &rs) { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; ls.z += rs.z; ls.e += rs.e; return ls; }
FI operator XYval<T>&() { return *(XYval<T>*)this; } FI XYZEval<T> operator- (const XYZEval<T> &rs) const { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; ls.z -= rs.z; ls.e -= rs.e; return ls; }
FI operator const XYval<T>&() const { return *(const XYval<T>*)this; } FI XYZEval<T> operator- (const XYZEval<T> &rs) { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; ls.z -= rs.z; ls.e -= rs.e; return ls; }
FI operator XYZval<T>&() { return *(XYZval<T>*)this; } FI XYZEval<T> operator* (const XYZEval<T> &rs) const { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; ls.z *= rs.z; ls.e *= rs.e; return ls; }
FI operator const XYZval<T>&() const { return *(const XYZval<T>*)this; } FI XYZEval<T> operator* (const XYZEval<T> &rs) { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; ls.z *= rs.z; ls.e *= rs.e; return ls; }
FI XYZEval<T> operator/ (const XYZEval<T> &rs) const { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; ls.z /= rs.z; ls.e /= rs.e; return ls; }
// Accessor via an AxisEnum (or any integer) [index] FI XYZEval<T> operator/ (const XYZEval<T> &rs) { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; ls.z /= rs.z; ls.e /= rs.e; return ls; }
FI T& operator[](const int n) { return pos[n]; } FI XYZEval<T> operator* (const float &v) const { XYZEval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; ls.e *= v; return ls; }
FI const T& operator[](const int n) const { return pos[n]; } FI XYZEval<T> operator* (const float &v) { XYZEval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; ls.e *= v; return ls; }
FI XYZEval<T> operator* (const int &v) const { XYZEval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; ls.e *= v; return ls; }
// Assignment operator overrides do the expected thing FI XYZEval<T> operator* (const int &v) { XYZEval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; ls.e *= v; return ls; }
FI XYZEval<T>& operator= (const T v) { set(LIST_N_1(LINEAR_AXES, v)); return *this; } FI XYZEval<T> operator/ (const float &v) const { XYZEval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; ls.e /= v; return ls; }
FI XYZEval<T>& operator= (const XYval<T> &rs) { set(rs.x, rs.y); return *this; } FI XYZEval<T> operator/ (const float &v) { XYZEval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; ls.e /= v; return ls; }
FI XYZEval<T>& operator= (const XYZval<T> &rs) { set(LINEAR_AXIS_ELEM(rs)); return *this; } FI XYZEval<T> operator/ (const int &v) const { XYZEval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; ls.e /= v; return ls; }
FI XYZEval<T> operator/ (const int &v) { XYZEval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; ls.e /= v; return ls; }
// Override other operators to get intuitive behaviors FI XYZEval<T> operator>>(const int &v) const { XYZEval<T> ls = *this; _RS(ls.x); _RS(ls.y); _RS(ls.z); _RS(ls.e); return ls; }
FI XYZEval<T> operator+ (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; } FI XYZEval<T> operator>>(const int &v) { XYZEval<T> ls = *this; _RS(ls.x); _RS(ls.y); _RS(ls.z); _RS(ls.e); return ls; }
FI XYZEval<T> operator+ (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; } FI XYZEval<T> operator<<(const int &v) const { XYZEval<T> ls = *this; _LS(ls.x); _LS(ls.y); _LS(ls.z); _LS(ls.e); return ls; }
FI XYZEval<T> operator- (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; } FI XYZEval<T> operator<<(const int &v) { XYZEval<T> ls = *this; _LS(ls.x); _LS(ls.y); _LS(ls.z); _LS(ls.e); return ls; }
FI XYZEval<T> operator- (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; } FI XYZEval<T>& operator+=(const XYval<T> &rs) { x += rs.x; y += rs.y; return *this; }
FI XYZEval<T> operator* (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; } FI XYZEval<T>& operator-=(const XYval<T> &rs) { x -= rs.x; y -= rs.y; return *this; }
FI XYZEval<T> operator* (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; } FI XYZEval<T>& operator*=(const XYval<T> &rs) { x *= rs.x; y *= rs.y; return *this; }
FI XYZEval<T> operator/ (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; } FI XYZEval<T>& operator/=(const XYval<T> &rs) { x /= rs.x; y /= rs.y; return *this; }
FI XYZEval<T> operator/ (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; } FI XYZEval<T>& operator+=(const XYZval<T> &rs) { x += rs.x; y += rs.y; z += rs.z; return *this; }
FI XYZEval<T> operator+ (const XYZval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, ls.z += rs.z, ls.i += rs.i, ls.j += rs.j, ls.k += rs.k); return ls; } FI XYZEval<T>& operator-=(const XYZval<T> &rs) { x -= rs.x; y -= rs.y; z -= rs.z; return *this; }
FI XYZEval<T> operator+ (const XYZval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, ls.z += rs.z, ls.i += rs.i, ls.j += rs.j, ls.k += rs.k); return ls; } FI XYZEval<T>& operator*=(const XYZval<T> &rs) { x *= rs.x; y *= rs.y; z *= rs.z; return *this; }
FI XYZEval<T> operator- (const XYZval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z, ls.i -= rs.i, ls.j -= rs.j, ls.k -= rs.k); return ls; } FI XYZEval<T>& operator/=(const XYZval<T> &rs) { x /= rs.x; y /= rs.y; z /= rs.z; return *this; }
FI XYZEval<T> operator- (const XYZval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z, ls.i -= rs.i, ls.j -= rs.j, ls.k -= rs.k); return ls; } FI XYZEval<T>& operator+=(const XYZEval<T> &rs) { x += rs.x; y += rs.y; z += rs.z; e += rs.e; return *this; }
FI XYZEval<T> operator* (const XYZval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k); return ls; } FI XYZEval<T>& operator-=(const XYZEval<T> &rs) { x -= rs.x; y -= rs.y; z -= rs.z; e -= rs.e; return *this; }
FI XYZEval<T> operator* (const XYZval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k); return ls; } FI XYZEval<T>& operator*=(const XYZEval<T> &rs) { x *= rs.x; y *= rs.y; z *= rs.z; e *= rs.e; return *this; }
FI XYZEval<T> operator/ (const XYZval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k); return ls; } FI XYZEval<T>& operator/=(const XYZEval<T> &rs) { x /= rs.x; y /= rs.y; z /= rs.z; e /= rs.e; return *this; }
FI XYZEval<T> operator/ (const XYZval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k); return ls; } FI XYZEval<T>& operator*=(const T &v) { x *= v; y *= v; z *= v; e *= v; return *this; }
FI XYZEval<T> operator+ (const XYZEval<T> &rs) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e += rs.e, ls.x += rs.x, ls.y += rs.y, ls.z += rs.z, ls.i += rs.i, ls.j += rs.j, ls.k += rs.k); return ls; } FI XYZEval<T>& operator>>=(const int &v) { _RS(x); _RS(y); _RS(z); _RS(e); return *this; }
FI XYZEval<T> operator+ (const XYZEval<T> &rs) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e += rs.e, ls.x += rs.x, ls.y += rs.y, ls.z += rs.z, ls.i += rs.i, ls.j += rs.j, ls.k += rs.k); return ls; } FI XYZEval<T>& operator<<=(const int &v) { _LS(x); _LS(y); _LS(z); _LS(e); return *this; }
FI XYZEval<T> operator- (const XYZEval<T> &rs) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e -= rs.e, ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z, ls.i -= rs.i, ls.j -= rs.j, ls.k -= rs.k); return ls; } FI bool operator==(const XYZval<T> &rs) { return x == rs.x && y == rs.y && z == rs.z; }
FI XYZEval<T> operator- (const XYZEval<T> &rs) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e -= rs.e, ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z, ls.i -= rs.i, ls.j -= rs.j, ls.k -= rs.k); return ls; } FI bool operator!=(const XYZval<T> &rs) { return !operator==(rs); }
FI XYZEval<T> operator* (const XYZEval<T> &rs) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= rs.e, ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k); return ls; } FI bool operator==(const XYZval<T> &rs) const { return x == rs.x && y == rs.y && z == rs.z; }
FI XYZEval<T> operator* (const XYZEval<T> &rs) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= rs.e, ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k); return ls; } FI bool operator!=(const XYZval<T> &rs) const { return !operator==(rs); }
FI XYZEval<T> operator/ (const XYZEval<T> &rs) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= rs.e, ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k); return ls; } FI XYZEval<T> operator-() { return { -x, -y, -z, -e }; }
FI XYZEval<T> operator/ (const XYZEval<T> &rs) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= rs.e, ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k); return ls; } FI const XYZEval<T> operator-() const { return { -x, -y, -z, -e }; }
FI XYZEval<T> operator* (const float &v) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= v, ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v ); return ls; }
FI XYZEval<T> operator* (const float &v) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= v, ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v ); return ls; }
FI XYZEval<T> operator* (const int &v) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= v, ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v ); return ls; }
FI XYZEval<T> operator* (const int &v) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= v, ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v ); return ls; }
FI XYZEval<T> operator/ (const float &v) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= v, ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v ); return ls; }
FI XYZEval<T> operator/ (const float &v) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= v, ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v ); return ls; }
FI XYZEval<T> operator/ (const int &v) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= v, ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v ); return ls; }
FI XYZEval<T> operator/ (const int &v) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= v, ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v ); return ls; }
FI XYZEval<T> operator>>(const int &v) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(_RS(ls.e), _RS(ls.x), _RS(ls.y), _RS(ls.z), _RS(ls.i), _RS(ls.j), _RS(ls.k) ); return ls; }
FI XYZEval<T> operator>>(const int &v) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(_RS(ls.e), _RS(ls.x), _RS(ls.y), _RS(ls.z), _RS(ls.i), _RS(ls.j), _RS(ls.k) ); return ls; }
FI XYZEval<T> operator<<(const int &v) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(_LS(ls.e), _LS(ls.x), _LS(ls.y), _LS(ls.z), _LS(ls.i), _LS(ls.j), _LS(ls.k) ); return ls; }
FI XYZEval<T> operator<<(const int &v) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(_LS(ls.e), _LS(ls.x), _LS(ls.y), _LS(ls.z), _LS(ls.i), _LS(ls.j), _LS(ls.k) ); return ls; }
FI const XYZEval<T> operator-() const { return LOGICAL_AXIS_ARRAY(-e, -x, -y, -z, -i, -j, -k); }
FI XYZEval<T> operator-() { return LOGICAL_AXIS_ARRAY(-e, -x, -y, -z, -i, -j, -k); }
// Modifier operators
FI XYZEval<T>& operator+=(const XYval<T> &rs) { x += rs.x; y += rs.y; return *this; }
FI XYZEval<T>& operator-=(const XYval<T> &rs) { x -= rs.x; y -= rs.y; return *this; }
FI XYZEval<T>& operator*=(const XYval<T> &rs) { x *= rs.x; y *= rs.y; return *this; }
FI XYZEval<T>& operator/=(const XYval<T> &rs) { x /= rs.x; y /= rs.y; return *this; }
FI XYZEval<T>& operator+=(const XYZval<T> &rs) { LINEAR_AXIS_CODE(x += rs.x, y += rs.y, z += rs.z, i += rs.i, j += rs.j, k += rs.k); return *this; }
FI XYZEval<T>& operator-=(const XYZval<T> &rs) { LINEAR_AXIS_CODE(x -= rs.x, y -= rs.y, z -= rs.z, i -= rs.i, j -= rs.j, k -= rs.k); return *this; }
FI XYZEval<T>& operator*=(const XYZval<T> &rs) { LINEAR_AXIS_CODE(x *= rs.x, y *= rs.y, z *= rs.z, i *= rs.i, j *= rs.j, k *= rs.k); return *this; }
FI XYZEval<T>& operator/=(const XYZval<T> &rs) { LINEAR_AXIS_CODE(x /= rs.x, y /= rs.y, z /= rs.z, i /= rs.i, j /= rs.j, k /= rs.k); return *this; }
FI XYZEval<T>& operator+=(const XYZEval<T> &rs) { LOGICAL_AXIS_CODE(e += rs.e, x += rs.x, y += rs.y, z += rs.z, i += rs.i, j += rs.j, k += rs.k); return *this; }
FI XYZEval<T>& operator-=(const XYZEval<T> &rs) { LOGICAL_AXIS_CODE(e -= rs.e, x -= rs.x, y -= rs.y, z -= rs.z, i -= rs.i, j -= rs.j, k -= rs.k); return *this; }
FI XYZEval<T>& operator*=(const XYZEval<T> &rs) { LOGICAL_AXIS_CODE(e *= rs.e, x *= rs.x, y *= rs.y, z *= rs.z, i *= rs.i, j *= rs.j, k *= rs.k); return *this; }
FI XYZEval<T>& operator/=(const XYZEval<T> &rs) { LOGICAL_AXIS_CODE(e /= rs.e, x /= rs.x, y /= rs.y, z /= rs.z, i /= rs.i, j /= rs.j, k /= rs.k); return *this; }
FI XYZEval<T>& operator*=(const T &v) { LOGICAL_AXIS_CODE(e *= v, x *= v, y *= v, z *= v, i *= v, j *= v, k *= v); return *this; }
FI XYZEval<T>& operator>>=(const int &v) { LOGICAL_AXIS_CODE(_RS(e), _RS(x), _RS(y), _RS(z), _RS(i), _RS(j), _RS(k)); return *this; }
FI XYZEval<T>& operator<<=(const int &v) { LOGICAL_AXIS_CODE(_LS(e), _LS(x), _LS(y), _LS(z), _LS(i), _LS(j), _LS(k)); return *this; }
// Exact comparisons. For floats a "NEAR" operation may be better.
FI bool operator==(const XYZval<T> &rs) { return true LINEAR_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k); }
FI bool operator==(const XYZval<T> &rs) const { return true LINEAR_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k); }
FI bool operator!=(const XYZval<T> &rs) { return !operator==(rs); }
FI bool operator!=(const XYZval<T> &rs) const { return !operator==(rs); }
}; };
#undef _RECIP #undef _RECIP
@@ -666,3 +514,6 @@ struct XYZEval {
#undef _LS #undef _LS
#undef _RS #undef _RS
#undef FI #undef FI
const xyze_char_t axis_codes { 'X', 'Y', 'Z', 'E' };
#define AXIS_CHAR(A) ((char)('X' + A))

View File

@@ -122,7 +122,7 @@ void safe_delay(millis_t ms) {
SERIAL_ECHOLNPAIR("Z Fade: ", planner.z_fade_height); SERIAL_ECHOLNPAIR("Z Fade: ", planner.z_fade_height);
#endif #endif
#if ABL_PLANAR #if ABL_PLANAR
SERIAL_ECHOPGM("ABL Adjustment"); SERIAL_ECHOPGM("ABL Adjustment X");
LOOP_LINEAR_AXES(a) { LOOP_LINEAR_AXES(a) {
const float v = planner.get_axis_position_mm(AxisEnum(a)) - current_position[a]; const float v = planner.get_axis_position_mm(AxisEnum(a)) - current_position[a];
SERIAL_CHAR(' ', AXIS_CHAR(a)); SERIAL_CHAR(' ', AXIS_CHAR(a));

View File

@@ -76,11 +76,3 @@ public:
// Converts from an uint8_t in the range of 0-255 to an uint8_t // Converts from an uint8_t in the range of 0-255 to an uint8_t
// in the range 0-100 while avoiding rounding artifacts // in the range 0-100 while avoiding rounding artifacts
constexpr uint8_t ui8_to_percent(const uint8_t i) { return (int(i) * 100 + 127) / 255; } constexpr uint8_t ui8_to_percent(const uint8_t i) { return (int(i) * 100 + 127) / 255; }
const xyze_char_t axis_codes LOGICAL_AXIS_ARRAY('E', 'X', 'Y', 'Z', AXIS4_NAME, AXIS5_NAME, AXIS6_NAME);
#if LINEAR_AXES <= XYZ
#define AXIS_CHAR(A) ((char)('X' + A))
#else
#define AXIS_CHAR(A) axis_codes[A]
#endif

View File

@@ -1,54 +0,0 @@
/**
* 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 <https://www.gnu.org/licenses/>.
*
*/
#include "../inc/MarlinConfig.h"
#if ENABLED(I2C_AMMETER)
#include "ammeter.h"
#ifndef I2C_AMMETER_IMAX
#define I2C_AMMETER_IMAX 0.500 // Calibration range 500 Milliamps
#endif
INA226 ina;
Ammeter ammeter;
float Ammeter::scale;
float Ammeter::current;
void Ammeter::init() {
ina.begin();
ina.configure(INA226_AVERAGES_16, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);
ina.calibrate(I2C_AMMETER_SHUNT_RESISTOR, I2C_AMMETER_IMAX);
}
float Ammeter::read() {
scale = 1;
current = ina.readShuntCurrent();
if (current <= 0.0001f) current = 0; // Clean up least-significant-bit amplification errors
if (current < 0.1f) scale = 1000;
return current * scale;
}
#endif // I2C_AMMETER

View File

@@ -1,39 +0,0 @@
/**
* 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 <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "../inc/MarlinConfigPre.h"
#include <Wire.h>
#include <INA226.h>
class Ammeter {
private:
static float scale;
public:
static float current;
static void init();
static float read();
};
extern Ammeter ammeter;

View File

@@ -24,7 +24,7 @@
#include "../../inc/MarlinConfigPre.h" #include "../../inc/MarlinConfigPre.h"
#if EITHER(RESTORE_LEVELING_AFTER_G28, ENABLE_LEVELING_AFTER_G28) #if EITHER(RESTORE_LEVELING_AFTER_G28, ENABLE_LEVELING_AFTER_G28)
#define CAN_SET_LEVELING_AFTER_G28 1 #define G28_L0_ENSURES_LEVELING_OFF 1
#endif #endif
#if ENABLED(PROBE_MANUALLY) #if ENABLED(PROBE_MANUALLY)

View File

@@ -164,7 +164,7 @@ static void serial_echo_column_labels(const uint8_t sp) {
* 2: TODO: Display on Graphical LCD * 2: TODO: Display on Graphical LCD
* 4: Compact Human-Readable * 4: Compact Human-Readable
*/ */
void unified_bed_leveling::display_map(const uint8_t map_type) { void unified_bed_leveling::display_map(const int map_type) {
const bool was = gcode.set_autoreport_paused(true); const bool was = gcode.set_autoreport_paused(true);
constexpr uint8_t eachsp = 1 + 6 + 1, // [-3.567] constexpr uint8_t eachsp = 1 + 6 + 1, // [-3.567]
@@ -263,7 +263,7 @@ bool unified_bed_leveling::sanity_check() {
void GcodeSuite::M1004() { void GcodeSuite::M1004() {
#define ALIGN_GCODE TERN(Z_STEPPER_AUTO_ALIGN, "G34", "") #define ALIGN_GCODE TERN(Z_STEPPER_AUTO_ALIGN, "G34", "")
#define PROBE_GCODE TERN(HAS_BED_PROBE, "G29P1\nG29P3", "G29P4R") #define PROBE_GCODE TERN(HAS_BED_PROBE, "G29P1\nG29P3", "G29P4R255")
#if HAS_HOTEND #if HAS_HOTEND
if (parser.seenval('H')) { // Handle H# parameter to set Hotend temp if (parser.seenval('H')) { // Handle H# parameter to set Hotend temp

View File

@@ -47,10 +47,10 @@ struct mesh_index_pair;
typedef struct { typedef struct {
bool C_seen; bool C_seen;
int8_t KLS_storage_slot; int8_t V_verbosity,
uint8_t R_repetition,
V_verbosity,
P_phase, P_phase,
R_repetition,
KLS_storage_slot,
T_map_type; T_map_type;
float B_shim_thickness, float B_shim_thickness,
C_constant; C_constant;
@@ -98,7 +98,7 @@ public:
static void report_state(); static void report_state();
static void save_ubl_active_state_and_disable(); static void save_ubl_active_state_and_disable();
static void restore_ubl_active_state_and_leave(); static void restore_ubl_active_state_and_leave();
static void display_map(const uint8_t) _O0; static void display_map(const int) _O0;
static mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType, const xy_pos_t&, const bool=false, MeshFlags *done_flags=nullptr) _O0; static mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType, const xy_pos_t&, const bool=false, MeshFlags *done_flags=nullptr) _O0;
static mesh_index_pair find_furthest_invalid_mesh_point() _O0; static mesh_index_pair find_furthest_invalid_mesh_point() _O0;
static void reset(); static void reset();

View File

@@ -305,7 +305,7 @@ void unified_bed_leveling::G29() {
bool probe_deployed = false; bool probe_deployed = false;
if (G29_parse_parameters()) return; // Abort on parameter error if (G29_parse_parameters()) return; // Abort on parameter error
const uint8_t p_val = parser.byteval('P'); const int8_t p_val = parser.intval('P', -1);
const bool may_move = p_val == 1 || p_val == 2 || p_val == 4 || parser.seen_test('J'); const bool may_move = p_val == 1 || p_val == 2 || p_val == 4 || parser.seen_test('J');
#if ENABLED(HAS_MULTI_HOTEND) #if ENABLED(HAS_MULTI_HOTEND)
const uint8_t old_tool_index = active_extruder; const uint8_t old_tool_index = active_extruder;
@@ -321,7 +321,7 @@ void unified_bed_leveling::G29() {
// Invalidate one or more nearby mesh points, possibly all. // Invalidate one or more nearby mesh points, possibly all.
if (parser.seen('I')) { if (parser.seen('I')) {
uint8_t count = parser.has_value() ? parser.value_byte() : 1; int16_t count = parser.has_value() ? parser.value_int() : 1;
bool invalidate_all = count >= GRID_MAX_POINTS; bool invalidate_all = count >= GRID_MAX_POINTS;
if (!invalidate_all) { if (!invalidate_all) {
while (count--) { while (count--) {
@@ -345,7 +345,7 @@ void unified_bed_leveling::G29() {
} }
if (parser.seen('Q')) { if (parser.seen('Q')) {
const int16_t test_pattern = parser.has_value() ? parser.value_int() : -99; const int test_pattern = parser.has_value() ? parser.value_int() : -99;
if (!WITHIN(test_pattern, -1, 2)) { if (!WITHIN(test_pattern, -1, 2)) {
SERIAL_ECHOLNPGM("Invalid test_pattern value. (-1 to 2)\n"); SERIAL_ECHOLNPGM("Invalid test_pattern value. (-1 to 2)\n");
return; return;
@@ -592,7 +592,7 @@ void unified_bed_leveling::G29() {
// //
if (parser.seen('L')) { // Load Current Mesh Data if (parser.seen('L')) { // Load Current Mesh Data
param.KLS_storage_slot = parser.has_value() ? (int8_t)parser.value_int() : storage_slot; param.KLS_storage_slot = parser.has_value() ? parser.value_int() : storage_slot;
int16_t a = settings.calc_num_meshes(); int16_t a = settings.calc_num_meshes();
@@ -617,10 +617,10 @@ void unified_bed_leveling::G29() {
// //
if (parser.seen('S')) { // Store (or Save) Current Mesh Data if (parser.seen('S')) { // Store (or Save) Current Mesh Data
param.KLS_storage_slot = parser.has_value() ? (int8_t)parser.value_int() : storage_slot; param.KLS_storage_slot = parser.has_value() ? parser.value_int() : storage_slot;
if (param.KLS_storage_slot == -1) // Special case: 'Export' the mesh to the if (param.KLS_storage_slot == -1) // Special case, the user wants to 'Export' the mesh to the
return report_current_mesh(); // host so it can be saved in a file. return report_current_mesh(); // host program to be saved on the user's computer
int16_t a = settings.calc_num_meshes(); int16_t a = settings.calc_num_meshes();
@@ -673,7 +673,7 @@ void unified_bed_leveling::G29() {
*/ */
void unified_bed_leveling::adjust_mesh_to_mean(const bool cflag, const_float_t offset) { void unified_bed_leveling::adjust_mesh_to_mean(const bool cflag, const_float_t offset) {
float sum = 0; float sum = 0;
uint8_t n = 0; int n = 0;
GRID_LOOP(x, y) GRID_LOOP(x, y)
if (!isnan(z_values[x][y])) { if (!isnan(z_values[x][y])) {
sum += z_values[x][y]; sum += z_values[x][y];
@@ -734,7 +734,7 @@ void unified_bed_leveling::shift_mesh_height() {
do { do {
if (do_ubl_mesh_map) display_map(param.T_map_type); if (do_ubl_mesh_map) display_map(param.T_map_type);
const uint8_t point_num = (GRID_MAX_POINTS - count) + 1; const int point_num = (GRID_MAX_POINTS) - count + 1;
SERIAL_ECHOLNPAIR("Probing mesh point ", point_num, "/", GRID_MAX_POINTS, "."); 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))); 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)));
@@ -1025,7 +1025,7 @@ void set_message_with_feedback(PGM_P const msg_P) {
SET_SOFT_ENDSTOP_LOOSE(true); SET_SOFT_ENDSTOP_LOOSE(true);
do { do {
idle_no_sleep(); idle();
new_z = ui.ubl_mesh_value(); new_z = ui.ubl_mesh_value();
TERN_(UBL_MESH_EDIT_MOVES_Z, do_blocking_move_to_z(h_offset + new_z)); // Move the nozzle as the point is edited TERN_(UBL_MESH_EDIT_MOVES_Z, do_blocking_move_to_z(h_offset + new_z)); // Move the nozzle as the point is edited
SERIAL_FLUSH(); // Prevent host M105 buffer overrun. SERIAL_FLUSH(); // Prevent host M105 buffer overrun.
@@ -1083,7 +1083,7 @@ bool unified_bed_leveling::G29_parse_parameters() {
param.R_repetition = 0; param.R_repetition = 0;
if (parser.seen('R')) { if (parser.seen('R')) {
param.R_repetition = parser.has_value() ? parser.value_byte() : GRID_MAX_POINTS; param.R_repetition = parser.has_value() ? parser.value_int() : GRID_MAX_POINTS;
NOMORE(param.R_repetition, GRID_MAX_POINTS); NOMORE(param.R_repetition, GRID_MAX_POINTS);
if (param.R_repetition < 1) { if (param.R_repetition < 1) {
SERIAL_ECHOLNPGM("?(R)epetition count invalid (1+).\n"); SERIAL_ECHOLNPGM("?(R)epetition count invalid (1+).\n");
@@ -1091,14 +1091,14 @@ bool unified_bed_leveling::G29_parse_parameters() {
} }
} }
param.V_verbosity = parser.byteval('V'); param.V_verbosity = parser.intval('V');
if (!WITHIN(param.V_verbosity, 0, 4)) { if (!WITHIN(param.V_verbosity, 0, 4)) {
SERIAL_ECHOLNPGM("?(V)erbose level implausible (0-4).\n"); SERIAL_ECHOLNPGM("?(V)erbose level implausible (0-4).\n");
err_flag = true; err_flag = true;
} }
if (parser.seen('P')) { if (parser.seen('P')) {
const uint8_t pv = parser.value_byte(); const int pv = parser.value_int();
#if !HAS_BED_PROBE #if !HAS_BED_PROBE
if (pv == 1) { if (pv == 1) {
SERIAL_ECHOLNPGM("G29 P1 requires a probe.\n"); SERIAL_ECHOLNPGM("G29 P1 requires a probe.\n");
@@ -1181,7 +1181,7 @@ bool unified_bed_leveling::G29_parse_parameters() {
} }
#endif #endif
param.T_map_type = parser.byteval('T'); param.T_map_type = parser.intval('T');
if (!WITHIN(param.T_map_type, 0, 2)) { if (!WITHIN(param.T_map_type, 0, 2)) {
SERIAL_ECHOLNPGM("Invalid map type.\n"); SERIAL_ECHOLNPGM("Invalid map type.\n");
return UBL_ERR; return UBL_ERR;
@@ -1833,7 +1833,7 @@ void unified_bed_leveling::smart_fill_mesh() {
return; return;
} }
param.KLS_storage_slot = (int8_t)parser.value_int(); param.KLS_storage_slot = parser.value_int();
float tmp_z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; float tmp_z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
settings.load_mesh(param.KLS_storage_slot, &tmp_z_values); settings.load_mesh(param.KLS_storage_slot, &tmp_z_values);

View File

@@ -113,22 +113,20 @@
const xy_float_t ad = sign * dist; const xy_float_t ad = sign * dist;
const bool use_x_dist = ad.x > ad.y; const bool use_x_dist = ad.x > ad.y;
float on_axis_distance = use_x_dist ? dist.x : dist.y; float on_axis_distance = use_x_dist ? dist.x : dist.y,
e_position = end.e - start.e,
z_position = end.z - start.z;
const float z_normalized_dist = (end.z - start.z) / on_axis_distance; // Allow divide by zero const float e_normalized_dist = e_position / on_axis_distance, // Allow divide by zero
#if HAS_EXTRUDERS z_normalized_dist = z_position / on_axis_distance;
const float e_normalized_dist = (end.e - start.e) / on_axis_distance;
const bool inf_normalized_flag = isinf(e_normalized_dist);
#endif
xy_int8_t icell = istart; xy_int8_t icell = istart;
const float ratio = dist.y / dist.x, // Allow divide by zero const float ratio = dist.y / dist.x, // Allow divide by zero
c = start.y - ratio * start.x; c = start.y - ratio * start.x;
const bool inf_ratio_flag = isinf(ratio); const bool inf_normalized_flag = isinf(e_normalized_dist),
inf_ratio_flag = isinf(ratio);
xyze_pos_t dest; // Stores XYZE for segmented moves
/** /**
* Handle vertical lines that stay within one column. * Handle vertical lines that stay within one column.
@@ -145,36 +143,34 @@
* For others the next X is the same so this can continue. * For others the next X is the same so this can continue.
* Calculate X at the next Y mesh line. * Calculate X at the next Y mesh line.
*/ */
dest.x = inf_ratio_flag ? start.x : (next_mesh_line_y - c) / ratio; const float rx = inf_ratio_flag ? start.x : (next_mesh_line_y - c) / ratio;
float z0 = z_correction_for_x_on_horizontal_mesh_line(dest.x, icell.x, icell.y) float z0 = z_correction_for_x_on_horizontal_mesh_line(rx, icell.x, icell.y)
* planner.fade_scaling_factor_for_z(end.z); * planner.fade_scaling_factor_for_z(end.z);
// Undefined parts of the Mesh in z_values[][] are NAN. // Undefined parts of the Mesh in z_values[][] are NAN.
// Replace NAN corrections with 0.0 to prevent NAN propagation. // Replace NAN corrections with 0.0 to prevent NAN propagation.
if (isnan(z0)) z0 = 0.0; if (isnan(z0)) z0 = 0.0;
dest.y = mesh_index_to_ypos(icell.y); const float ry = mesh_index_to_ypos(icell.y);
/** /**
* Without this check, it's possible to generate a zero length move, as in the case where * Without this check, it's possible to generate a zero length move, as in the case where
* the line is heading down, starting exactly on a mesh line boundary. Since this is rare * the line is heading down, starting exactly on a mesh line boundary. Since this is rare
* it might be fine to remove this check and let planner.buffer_segment() filter it out. * it might be fine to remove this check and let planner.buffer_segment() filter it out.
*/ */
if (dest.y != start.y) { if (ry != start.y) {
if (!inf_normalized_flag) { // fall-through faster than branch if (!inf_normalized_flag) { // fall-through faster than branch
on_axis_distance = use_x_dist ? dest.x - start.x : dest.y - start.y; on_axis_distance = use_x_dist ? rx - start.x : ry - start.y;
TERN_(HAS_EXTRUDERS, dest.e = start.e + on_axis_distance * e_normalized_dist); e_position = start.e + on_axis_distance * e_normalized_dist;
dest.z = start.z + on_axis_distance * z_normalized_dist; z_position = start.z + on_axis_distance * z_normalized_dist;
} }
else { else {
TERN_(HAS_EXTRUDERS, dest.e = end.e); e_position = end.e;
dest.z = end.z; z_position = end.z;
} }
dest.z += z0; planner.buffer_segment(rx, ry, z_position + z0, e_position, scaled_fr_mm_s, extruder);
planner.buffer_segment(dest, scaled_fr_mm_s, extruder);
} //else printf("FIRST MOVE PRUNED "); } //else printf("FIRST MOVE PRUNED ");
} }
@@ -192,13 +188,12 @@
*/ */
if (iadd.y == 0) { // Horizontal line? if (iadd.y == 0) { // Horizontal line?
icell.x += ineg.x; // Heading left? Just go to the left edge of the cell for the first move. icell.x += ineg.x; // Heading left? Just go to the left edge of the cell for the first move.
while (icell.x != iend.x + ineg.x) { while (icell.x != iend.x + ineg.x) {
icell.x += iadd.x; icell.x += iadd.x;
dest.x = mesh_index_to_xpos(icell.x); const float rx = mesh_index_to_xpos(icell.x);
dest.y = ratio * dest.x + c; // Calculate Y at the next X mesh line const float ry = ratio * rx + c; // Calculate Y at the next X mesh line
float z0 = z_correction_for_y_on_vertical_mesh_line(dest.y, icell.x, icell.y) float z0 = z_correction_for_y_on_vertical_mesh_line(ry, icell.x, icell.y)
* planner.fade_scaling_factor_for_z(end.z); * planner.fade_scaling_factor_for_z(end.z);
// Undefined parts of the Mesh in z_values[][] are NAN. // Undefined parts of the Mesh in z_values[][] are NAN.
@@ -210,20 +205,19 @@
* the line is heading left, starting exactly on a mesh line boundary. Since this is rare * the line is heading left, starting exactly on a mesh line boundary. Since this is rare
* it might be fine to remove this check and let planner.buffer_segment() filter it out. * it might be fine to remove this check and let planner.buffer_segment() filter it out.
*/ */
if (dest.x != start.x) { if (rx != start.x) {
if (!inf_normalized_flag) { if (!inf_normalized_flag) {
on_axis_distance = use_x_dist ? dest.x - start.x : dest.y - start.y; on_axis_distance = use_x_dist ? rx - start.x : ry - start.y;
TERN_(HAS_EXTRUDERS, dest.e = start.e + on_axis_distance * e_normalized_dist); // Based on X or Y because the move is horizontal e_position = start.e + on_axis_distance * e_normalized_dist; // is based on X or Y because this is a horizontal move
dest.z = start.z + on_axis_distance * z_normalized_dist; z_position = start.z + on_axis_distance * z_normalized_dist;
} }
else { else {
TERN_(HAS_EXTRUDERS, dest.e = end.e); e_position = end.e;
dest.z = end.z; z_position = end.z;
} }
dest.z += z0; if (!planner.buffer_segment(rx, ry, z_position + z0, e_position, scaled_fr_mm_s, extruder))
if (!planner.buffer_segment(dest, scaled_fr_mm_s, extruder)) break; break;
} //else printf("FIRST MOVE PRUNED "); } //else printf("FIRST MOVE PRUNED ");
} }
@@ -245,65 +239,57 @@
while (cnt) { while (cnt) {
const float next_mesh_line_x = mesh_index_to_xpos(icell.x + iadd.x), const float next_mesh_line_x = mesh_index_to_xpos(icell.x + iadd.x),
next_mesh_line_y = mesh_index_to_ypos(icell.y + iadd.y); next_mesh_line_y = mesh_index_to_ypos(icell.y + iadd.y),
ry = ratio * next_mesh_line_x + c, // Calculate Y at the next X mesh line
rx = (next_mesh_line_y - c) / ratio; // Calculate X at the next Y mesh line
// (No need to worry about ratio == 0.
// In that case, it was already detected
// as a vertical line move above.)
dest.y = ratio * next_mesh_line_x + c; // Calculate Y at the next X mesh line if (neg.x == (rx > next_mesh_line_x)) { // Check if we hit the Y line first
dest.x = (next_mesh_line_y - c) / ratio; // Calculate X at the next Y mesh line
// (No need to worry about ratio == 0.
// In that case, it was already detected
// as a vertical line move above.)
if (neg.x == (dest.x > next_mesh_line_x)) { // Check if we hit the Y line first
// Yes! Crossing a Y Mesh Line next // Yes! Crossing a Y Mesh Line next
float z0 = z_correction_for_x_on_horizontal_mesh_line(dest.x, icell.x - ineg.x, icell.y + iadd.y) float z0 = z_correction_for_x_on_horizontal_mesh_line(rx, icell.x - ineg.x, icell.y + iadd.y)
* planner.fade_scaling_factor_for_z(end.z); * planner.fade_scaling_factor_for_z(end.z);
// Undefined parts of the Mesh in z_values[][] are NAN. // Undefined parts of the Mesh in z_values[][] are NAN.
// Replace NAN corrections with 0.0 to prevent NAN propagation. // Replace NAN corrections with 0.0 to prevent NAN propagation.
if (isnan(z0)) z0 = 0.0; if (isnan(z0)) z0 = 0.0;
dest.y = next_mesh_line_y;
if (!inf_normalized_flag) { if (!inf_normalized_flag) {
on_axis_distance = use_x_dist ? dest.x - start.x : dest.y - start.y; on_axis_distance = use_x_dist ? rx - start.x : next_mesh_line_y - start.y;
TERN_(HAS_EXTRUDERS, dest.e = start.e + on_axis_distance * e_normalized_dist); e_position = start.e + on_axis_distance * e_normalized_dist;
dest.z = start.z + on_axis_distance * z_normalized_dist; z_position = start.z + on_axis_distance * z_normalized_dist;
} }
else { else {
TERN_(HAS_EXTRUDERS, dest.e = end.e); e_position = end.e;
dest.z = end.z; z_position = end.z;
} }
if (!planner.buffer_segment(rx, next_mesh_line_y, z_position + z0, e_position, scaled_fr_mm_s, extruder))
dest.z += z0; break;
if (!planner.buffer_segment(dest, scaled_fr_mm_s, extruder)) break;
icell.y += iadd.y; icell.y += iadd.y;
cnt.y--; cnt.y--;
} }
else { else {
// Yes! Crossing a X Mesh Line next // Yes! Crossing a X Mesh Line next
float z0 = z_correction_for_y_on_vertical_mesh_line(dest.y, icell.x + iadd.x, icell.y - ineg.y) float z0 = z_correction_for_y_on_vertical_mesh_line(ry, icell.x + iadd.x, icell.y - ineg.y)
* planner.fade_scaling_factor_for_z(end.z); * planner.fade_scaling_factor_for_z(end.z);
// Undefined parts of the Mesh in z_values[][] are NAN. // Undefined parts of the Mesh in z_values[][] are NAN.
// Replace NAN corrections with 0.0 to prevent NAN propagation. // Replace NAN corrections with 0.0 to prevent NAN propagation.
if (isnan(z0)) z0 = 0.0; if (isnan(z0)) z0 = 0.0;
dest.x = next_mesh_line_x;
if (!inf_normalized_flag) { if (!inf_normalized_flag) {
on_axis_distance = use_x_dist ? dest.x - start.x : dest.y - start.y; on_axis_distance = use_x_dist ? next_mesh_line_x - start.x : ry - start.y;
TERN_(HAS_EXTRUDERS, dest.e = start.e + on_axis_distance * e_normalized_dist); e_position = start.e + on_axis_distance * e_normalized_dist;
dest.z = start.z + on_axis_distance * z_normalized_dist; z_position = start.z + on_axis_distance * z_normalized_dist;
} }
else { else {
TERN_(HAS_EXTRUDERS, dest.e = end.e); e_position = end.e;
dest.z = end.z; z_position = end.z;
} }
dest.z += z0; if (!planner.buffer_segment(next_mesh_line_x, ry, z_position + z0, e_position, scaled_fr_mm_s, extruder))
if (!planner.buffer_segment(dest, scaled_fr_mm_s, extruder)) break; break;
icell.x += iadd.x; icell.x += iadd.x;
cnt.x--; cnt.x--;
} }
@@ -452,9 +438,11 @@
#endif #endif
; ;
const float oldz = raw.z; raw.z += z_cxcy; planner.buffer_line(raw.x, raw.y, raw.z + z_cxcy, raw.e, scaled_fr_mm_s, active_extruder, segment_xyz_mm
planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, segment_xyz_mm OPTARG(SCARA_FEEDRATE_SCALING, inv_duration) ); #if ENABLED(SCARA_FEEDRATE_SCALING)
raw.z = oldz; , inv_duration
#endif
);
if (segments == 0) // done with last segment if (segments == 0) // done with last segment
return false; // didn't set current from destination return false; // didn't set current from destination

View File

@@ -24,11 +24,9 @@
#include "../inc/MarlinConfig.h" #include "../inc/MarlinConfig.h"
#define BINARY_STREAM_COMPRESSION #define BINARY_STREAM_COMPRESSION
#if ENABLED(BINARY_STREAM_COMPRESSION) #if ENABLED(BINARY_STREAM_COMPRESSION)
#include "../libs/heatshrink/heatshrink_decoder.h" #include "../libs/heatshrink/heatshrink_decoder.h"
// STM32 (and others?) require a word-aligned buffer for SD card transfers via DMA
static __attribute__((aligned(sizeof(size_t)))) uint8_t decode_buffer[512] = {};
static heatshrink_decoder hsd;
#endif #endif
inline bool bs_serial_data_available(const serial_index_t index) { inline bool bs_serial_data_available(const serial_index_t index) {
@@ -39,6 +37,16 @@ inline int bs_read_serial(const serial_index_t index) {
return SERIAL_IMPL.read(index); return SERIAL_IMPL.read(index);
} }
#if ENABLED(BINARY_STREAM_COMPRESSION)
static heatshrink_decoder hsd;
#if BOTH(ARDUINO_ARCH_STM32F1, SDIO_SUPPORT)
// STM32 requires a word-aligned buffer for SD card transfers via DMA
static __attribute__((aligned(sizeof(size_t)))) uint8_t decode_buffer[512] = {};
#else
static uint8_t decode_buffer[512] = {};
#endif
#endif
class SDFileTransferProtocol { class SDFileTransferProtocol {
private: private:
struct Packet { struct Packet {

View File

@@ -85,16 +85,10 @@ void StepperDAC::print_values() {
if (!dac_present) return; if (!dac_present) return;
SERIAL_ECHO_MSG("Stepper current values in % (Amps):"); SERIAL_ECHO_MSG("Stepper current values in % (Amps):");
SERIAL_ECHO_START(); SERIAL_ECHO_START();
SERIAL_ECHOPAIR_P(SP_X_LBL, dac_perc(X_AXIS), PSTR(" ("), dac_amps(X_AXIS), PSTR(")")); SERIAL_ECHOPAIR_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_ECHOPAIR_P(SP_Y_LBL, dac_perc(Y_AXIS), PSTR(" ("), dac_amps(Y_AXIS), PSTR(")")); SERIAL_ECHOPAIR_P( SP_Z_LBL, dac_perc(Z_AXIS), PSTR(" ("), dac_amps(Z_AXIS), PSTR(")"));
#endif SERIAL_ECHOLNPAIR_P(SP_E_LBL, dac_perc(E_AXIS), PSTR(" ("), dac_amps(E_AXIS), PSTR(")"));
#if HAS_Z_AXIS
SERIAL_ECHOPAIR_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(")"));
#endif
} }
void StepperDAC::commit_eeprom() { void StepperDAC::commit_eeprom() {

View File

@@ -327,7 +327,7 @@ int32_t I2CPositionEncoder::get_raw_count() {
} }
bool I2CPositionEncoder::test_axis() { bool I2CPositionEncoder::test_axis() {
// Only works on XYZ Cartesian machines for the time being //only works on XYZ cartesian machines for the time being
if (!(encoderAxis == X_AXIS || encoderAxis == Y_AXIS || encoderAxis == Z_AXIS)) return false; if (!(encoderAxis == X_AXIS || encoderAxis == Y_AXIS || encoderAxis == Z_AXIS)) return false;
const float startPosition = soft_endstop.min[encoderAxis] + 10, const float startPosition = soft_endstop.min[encoderAxis] + 10,
@@ -345,12 +345,9 @@ bool I2CPositionEncoder::test_axis() {
endCoord[encoderAxis] = endPosition; endCoord[encoderAxis] = endPosition;
planner.synchronize(); planner.synchronize();
startCoord.e = planner.get_axis_position_mm(E_AXIS);
#if HAS_EXTRUDERS planner.buffer_line(startCoord, fr_mm_s, 0);
startCoord.e = planner.get_axis_position_mm(E_AXIS); planner.synchronize();
planner.buffer_line(startCoord, fr_mm_s, 0);
planner.synchronize();
#endif
// if the module isn't currently trusted, wait until it is (or until it should be if things are working) // if the module isn't currently trusted, wait until it is (or until it should be if things are working)
if (!trusted) { if (!trusted) {
@@ -360,7 +357,7 @@ bool I2CPositionEncoder::test_axis() {
} }
if (trusted) { // if trusted, commence test if (trusted) { // if trusted, commence test
TERN_(HAS_EXTRUDERS, endCoord.e = planner.get_axis_position_mm(E_AXIS)); endCoord.e = planner.get_axis_position_mm(E_AXIS);
planner.buffer_line(endCoord, fr_mm_s, 0); planner.buffer_line(endCoord, fr_mm_s, 0);
planner.synchronize(); planner.synchronize();
} }
@@ -405,7 +402,7 @@ void I2CPositionEncoder::calibrate_steps_mm(const uint8_t iter) {
planner.synchronize(); planner.synchronize();
LOOP_L_N(i, iter) { LOOP_L_N(i, iter) {
TERN_(HAS_EXTRUDERS, startCoord.e = planner.get_axis_position_mm(E_AXIS)); startCoord.e = planner.get_axis_position_mm(E_AXIS);
planner.buffer_line(startCoord, fr_mm_s, 0); planner.buffer_line(startCoord, fr_mm_s, 0);
planner.synchronize(); planner.synchronize();
@@ -414,7 +411,7 @@ void I2CPositionEncoder::calibrate_steps_mm(const uint8_t iter) {
//do_blocking_move_to(endCoord); //do_blocking_move_to(endCoord);
TERN_(HAS_EXTRUDERS, endCoord.e = planner.get_axis_position_mm(E_AXIS)); endCoord.e = planner.get_axis_position_mm(E_AXIS);
planner.buffer_line(endCoord, fr_mm_s, 0); planner.buffer_line(endCoord, fr_mm_s, 0);
planner.synchronize(); planner.synchronize();
@@ -500,7 +497,9 @@ void I2CPositionEncodersMgr::init() {
encoders[i].set_active(encoders[i].passes_test(true)); encoders[i].set_active(encoders[i].passes_test(true));
TERN_(HAS_EXTRUDERS, if (I2CPE_ENC_1_AXIS == E_AXIS) encoders[i].set_homed()); #if I2CPE_ENC_1_AXIS == E_AXIS
encoders[i].set_homed();
#endif
#endif #endif
#if I2CPE_ENCODER_CNT > 1 #if I2CPE_ENCODER_CNT > 1
@@ -529,7 +528,9 @@ void I2CPositionEncodersMgr::init() {
encoders[i].set_active(encoders[i].passes_test(true)); encoders[i].set_active(encoders[i].passes_test(true));
TERN_(HAS_EXTRUDERS, if (I2CPE_ENC_2_AXIS == E_AXIS) encoders[i].set_homed()); #if I2CPE_ENC_2_AXIS == E_AXIS
encoders[i].set_homed();
#endif
#endif #endif
#if I2CPE_ENCODER_CNT > 2 #if I2CPE_ENCODER_CNT > 2
@@ -556,9 +557,11 @@ void I2CPositionEncodersMgr::init() {
encoders[i].set_ec_threshold(I2CPE_ENC_3_EC_THRESH); encoders[i].set_ec_threshold(I2CPE_ENC_3_EC_THRESH);
#endif #endif
encoders[i].set_active(encoders[i].passes_test(true)); encoders[i].set_active(encoders[i].passes_test(true));
TERN_(HAS_EXTRUDERS, if (I2CPE_ENC_3_AXIS == E_AXIS) encoders[i].set_homed()); #if I2CPE_ENC_3_AXIS == E_AXIS
encoders[i].set_homed();
#endif
#endif #endif
#if I2CPE_ENCODER_CNT > 3 #if I2CPE_ENCODER_CNT > 3
@@ -587,7 +590,9 @@ void I2CPositionEncodersMgr::init() {
encoders[i].set_active(encoders[i].passes_test(true)); encoders[i].set_active(encoders[i].passes_test(true));
TERN_(HAS_EXTRUDERS, if (I2CPE_ENC_4_AXIS == E_AXIS) encoders[i].set_homed()); #if I2CPE_ENC_4_AXIS == E_AXIS
encoders[i].set_homed();
#endif
#endif #endif
#if I2CPE_ENCODER_CNT > 4 #if I2CPE_ENCODER_CNT > 4
@@ -616,7 +621,9 @@ void I2CPositionEncodersMgr::init() {
encoders[i].set_active(encoders[i].passes_test(true)); encoders[i].set_active(encoders[i].passes_test(true));
TERN_(HAS_EXTRUDERS, if (I2CPE_ENC_5_AXIS == E_AXIS) encoders[i].set_homed()); #if I2CPE_ENC_5_AXIS == E_AXIS
encoders[i].set_homed();
#endif
#endif #endif
#if I2CPE_ENCODER_CNT > 5 #if I2CPE_ENCODER_CNT > 5
@@ -645,7 +652,9 @@ void I2CPositionEncodersMgr::init() {
encoders[i].set_active(encoders[i].passes_test(true)); encoders[i].set_active(encoders[i].passes_test(true));
TERN_(HAS_EXTRUDERS, if (I2CPE_ENC_6_AXIS == E_AXIS) encoders[i].set_homed()); #if I2CPE_ENC_6_AXIS == E_AXIS
encoders[i].set_homed();
#endif
#endif #endif
} }

View File

@@ -114,6 +114,7 @@ public:
#if CONJOINED_NEOPIXEL #if CONJOINED_NEOPIXEL
adaneo2.show(); adaneo2.show();
#else #else
IF_DISABLED(NEOPIXEL2_SEPARATE, adaneo1.setPin(NEOPIXEL2_PIN));
adaneo1.show(); adaneo1.show();
adaneo1.setPin(NEOPIXEL_PIN); adaneo1.setPin(NEOPIXEL_PIN);
#endif #endif

View File

@@ -24,14 +24,7 @@
#if HAS_PRUSA_MMU1 #if HAS_PRUSA_MMU1
#include "../MarlinCore.h" #include "../module/stepper.h"
#include "../module/planner.h"
void mmu_init() {
SET_OUTPUT(E_MUX0_PIN);
SET_OUTPUT(E_MUX1_PIN);
SET_OUTPUT(E_MUX2_PIN);
}
void select_multiplexed_stepper(const uint8_t e) { void select_multiplexed_stepper(const uint8_t e) {
planner.synchronize(); planner.synchronize();

View File

@@ -21,5 +21,4 @@
*/ */
#pragma once #pragma once
void mmu_init();
void select_multiplexed_stepper(const uint8_t e); void select_multiplexed_stepper(const uint8_t e);

View File

@@ -81,10 +81,7 @@ bool Power::is_power_needed() {
#endif #endif
) return true; ) return true;
#if HAS_HOTEND HOTEND_LOOP() if (thermalManager.degTargetHotend(e) > 0 || thermalManager.temp_hotend[e].soft_pwm_amount > 0) return true;
HOTEND_LOOP() if (thermalManager.degTargetHotend(e) > 0 || thermalManager.temp_hotend[e].soft_pwm_amount > 0) return true;
#endif
if (TERN0(HAS_HEATED_BED, thermalManager.degTargetBed() > 0 || thermalManager.temp_bed.soft_pwm_amount > 0)) return true; if (TERN0(HAS_HEATED_BED, thermalManager.degTargetBed() > 0 || thermalManager.temp_bed.soft_pwm_amount > 0)) return true;
#if HAS_HOTEND && AUTO_POWER_E_TEMP #if HAS_HOTEND && AUTO_POWER_E_TEMP
@@ -108,12 +105,12 @@ bool Power::is_power_needed() {
void Power::check() { void Power::check() {
static millis_t nextPowerCheck = 0; static millis_t nextPowerCheck = 0;
millis_t now = millis(); millis_t ms = millis();
if (ELAPSED(now, nextPowerCheck)) { if (ELAPSED(ms, nextPowerCheck)) {
nextPowerCheck = now + 2500UL; nextPowerCheck = ms + 2500UL;
if (is_power_needed()) if (is_power_needed())
power_on(); power_on();
else if (!lastPowerOn || (POWER_TIMEOUT > 0 && ELAPSED(now, lastPowerOn + SEC_TO_MS(POWER_TIMEOUT)))) else if (!lastPowerOn || (POWER_TIMEOUT > 0 && ELAPSED(ms, lastPowerOn + SEC_TO_MS(POWER_TIMEOUT))))
power_off(); power_off();
} }
} }

View File

@@ -88,7 +88,7 @@ typedef struct {
uint8_t fan_speed[FAN_COUNT]; uint8_t fan_speed[FAN_COUNT];
#endif #endif
#if HAS_LEVELING #if ENABLED(HAS_LEVELING)
float fade; float fade;
#endif #endif
@@ -120,7 +120,7 @@ typedef struct {
bool raised:1; // Raised before saved bool raised:1; // Raised before saved
bool dryrun:1; // M111 S8 bool dryrun:1; // M111 S8
bool allow_cold_extrusion:1; // M302 P1 bool allow_cold_extrusion:1; // M302 P1
#if HAS_LEVELING #if ENABLED(HAS_LEVELING)
bool leveling:1; // M420 S bool leveling:1; // M420 S
#endif #endif
#if DISABLED(NO_VOLUMETRICS) #if DISABLED(NO_VOLUMETRICS)

View File

@@ -47,7 +47,7 @@ typedef struct {
// Probe temperature calibration constants // Probe temperature calibration constants
#ifndef PTC_SAMPLE_COUNT #ifndef PTC_SAMPLE_COUNT
#define PTC_SAMPLE_COUNT 10 #define PTC_SAMPLE_COUNT 10U
#endif #endif
#ifndef PTC_SAMPLE_RES #ifndef PTC_SAMPLE_RES
#define PTC_SAMPLE_RES 5 #define PTC_SAMPLE_RES 5
@@ -55,22 +55,22 @@ typedef struct {
#ifndef PTC_SAMPLE_START #ifndef PTC_SAMPLE_START
#define PTC_SAMPLE_START 30 #define PTC_SAMPLE_START 30
#endif #endif
#define PTC_SAMPLE_END (PTC_SAMPLE_START + (PTC_SAMPLE_COUNT) * PTC_SAMPLE_RES) #define PTC_SAMPLE_END ((PTC_SAMPLE_START) + (PTC_SAMPLE_COUNT) * (PTC_SAMPLE_RES))
// Bed temperature calibration constants // Bed temperature calibration constants
#ifndef BTC_PROBE_TEMP #ifndef BTC_PROBE_TEMP
#define BTC_PROBE_TEMP 30 #define BTC_PROBE_TEMP 30
#endif #endif
#ifndef BTC_SAMPLE_COUNT #ifndef BTC_SAMPLE_COUNT
#define BTC_SAMPLE_COUNT 10 #define BTC_SAMPLE_COUNT 10U
#endif #endif
#ifndef BTC_SAMPLE_RES #ifndef BTC_SAMPLE_STEP
#define BTC_SAMPLE_RES 5 #define BTC_SAMPLE_RES 5
#endif #endif
#ifndef BTC_SAMPLE_START #ifndef BTC_SAMPLE_START
#define BTC_SAMPLE_START 60 #define BTC_SAMPLE_START 60
#endif #endif
#define BTC_SAMPLE_END (BTC_SAMPLE_START + (BTC_SAMPLE_COUNT) * BTC_SAMPLE_RES) #define BTC_SAMPLE_END ((BTC_SAMPLE_START) + (BTC_SAMPLE_COUNT) * (BTC_SAMPLE_RES))
#ifndef PTC_PROBE_HEATING_OFFSET #ifndef PTC_PROBE_HEATING_OFFSET
#define PTC_PROBE_HEATING_OFFSET 0.5f #define PTC_PROBE_HEATING_OFFSET 0.5f

View File

@@ -34,10 +34,6 @@
#include "../module/servo.h" #include "../module/servo.h"
#endif #endif
#if ENABLED(I2C_AMMETER)
#include "../feature/ammeter.h"
#endif
SpindleLaser cutter; SpindleLaser cutter;
uint8_t SpindleLaser::power; uint8_t SpindleLaser::power;
#if ENABLED(LASER_FEATURE) #if ENABLED(LASER_FEATURE)
@@ -78,9 +74,6 @@ void SpindleLaser::init() {
#if ENABLED(AIR_ASSIST) #if ENABLED(AIR_ASSIST)
OUT_WRITE(AIR_ASSIST_PIN, !AIR_ASSIST_ACTIVE); // Init Air Assist OFF OUT_WRITE(AIR_ASSIST_PIN, !AIR_ASSIST_ACTIVE); // Init Air Assist OFF
#endif #endif
#if ENABLED(I2C_AMMETER)
ammeter.init(); // Init I2C Ammeter
#endif
} }
#if ENABLED(SPINDLE_LASER_PWM) #if ENABLED(SPINDLE_LASER_PWM)

View File

@@ -417,21 +417,6 @@
} }
#endif #endif
#if AXIS_IS_TMC(I)
if (monitor_tmc_driver(stepperI, need_update_error_counters, need_debug_reporting))
step_current_down(stepperI);
#endif
#if AXIS_IS_TMC(J)
if (monitor_tmc_driver(stepperJ, need_update_error_counters, need_debug_reporting))
step_current_down(stepperJ);
#endif
#if AXIS_IS_TMC(K)
if (monitor_tmc_driver(stepperK, need_update_error_counters, need_debug_reporting))
step_current_down(stepperK);
#endif
#if AXIS_IS_TMC(E0) #if AXIS_IS_TMC(E0)
(void)monitor_tmc_driver(stepperE0, need_update_error_counters, need_debug_reporting); (void)monitor_tmc_driver(stepperE0, need_update_error_counters, need_debug_reporting);
#endif #endif
@@ -772,148 +757,128 @@
} }
} }
static void tmc_debug_loop(const TMC_debug_enum n, LOGICAL_AXIS_ARGS(const bool)) { static void tmc_debug_loop(const TMC_debug_enum i, const bool print_x, const bool print_y, const bool print_z, const bool print_e) {
if (x) { if (print_x) {
#if AXIS_IS_TMC(X) #if AXIS_IS_TMC(X)
tmc_status(stepperX, n); tmc_status(stepperX, i);
#endif #endif
#if AXIS_IS_TMC(X2) #if AXIS_IS_TMC(X2)
tmc_status(stepperX2, n); tmc_status(stepperX2, i);
#endif #endif
} }
if (TERN0(HAS_Y_AXIS, y)) { if (print_y) {
#if AXIS_IS_TMC(Y) #if AXIS_IS_TMC(Y)
tmc_status(stepperY, n); tmc_status(stepperY, i);
#endif #endif
#if AXIS_IS_TMC(Y2) #if AXIS_IS_TMC(Y2)
tmc_status(stepperY2, n); tmc_status(stepperY2, i);
#endif #endif
} }
if (TERN0(HAS_Z_AXIS, z)) { if (print_z) {
#if AXIS_IS_TMC(Z) #if AXIS_IS_TMC(Z)
tmc_status(stepperZ, n); tmc_status(stepperZ, i);
#endif #endif
#if AXIS_IS_TMC(Z2) #if AXIS_IS_TMC(Z2)
tmc_status(stepperZ2, n); tmc_status(stepperZ2, i);
#endif #endif
#if AXIS_IS_TMC(Z3) #if AXIS_IS_TMC(Z3)
tmc_status(stepperZ3, n); tmc_status(stepperZ3, i);
#endif #endif
#if AXIS_IS_TMC(Z4) #if AXIS_IS_TMC(Z4)
tmc_status(stepperZ4, n); tmc_status(stepperZ4, i);
#endif #endif
} }
#if AXIS_IS_TMC(I) if (print_e) {
if (i) tmc_status(stepperI, n);
#endif
#if AXIS_IS_TMC(J)
if (j) tmc_status(stepperJ, n);
#endif
#if AXIS_IS_TMC(K)
if (k) tmc_status(stepperK, n);
#endif
if (TERN0(HAS_EXTRUDERS, e)) {
#if AXIS_IS_TMC(E0) #if AXIS_IS_TMC(E0)
tmc_status(stepperE0, n); tmc_status(stepperE0, i);
#endif #endif
#if AXIS_IS_TMC(E1) #if AXIS_IS_TMC(E1)
tmc_status(stepperE1, n); tmc_status(stepperE1, i);
#endif #endif
#if AXIS_IS_TMC(E2) #if AXIS_IS_TMC(E2)
tmc_status(stepperE2, n); tmc_status(stepperE2, i);
#endif #endif
#if AXIS_IS_TMC(E3) #if AXIS_IS_TMC(E3)
tmc_status(stepperE3, n); tmc_status(stepperE3, i);
#endif #endif
#if AXIS_IS_TMC(E4) #if AXIS_IS_TMC(E4)
tmc_status(stepperE4, n); tmc_status(stepperE4, i);
#endif #endif
#if AXIS_IS_TMC(E5) #if AXIS_IS_TMC(E5)
tmc_status(stepperE5, n); tmc_status(stepperE5, i);
#endif #endif
#if AXIS_IS_TMC(E6) #if AXIS_IS_TMC(E6)
tmc_status(stepperE6, n); tmc_status(stepperE6, i);
#endif #endif
#if AXIS_IS_TMC(E7) #if AXIS_IS_TMC(E7)
tmc_status(stepperE7, n); tmc_status(stepperE7, i);
#endif #endif
} }
SERIAL_EOL(); SERIAL_EOL();
} }
static void drv_status_loop(const TMC_drv_status_enum n, LOGICAL_AXIS_ARGS(const bool)) { static void drv_status_loop(const TMC_drv_status_enum i, const bool print_x, const bool print_y, const bool print_z, const bool print_e) {
if (x) { if (print_x) {
#if AXIS_IS_TMC(X) #if AXIS_IS_TMC(X)
tmc_parse_drv_status(stepperX, n); tmc_parse_drv_status(stepperX, i);
#endif #endif
#if AXIS_IS_TMC(X2) #if AXIS_IS_TMC(X2)
tmc_parse_drv_status(stepperX2, n); tmc_parse_drv_status(stepperX2, i);
#endif #endif
} }
if (TERN0(HAS_Y_AXIS, y)) { if (print_y) {
#if AXIS_IS_TMC(Y) #if AXIS_IS_TMC(Y)
tmc_parse_drv_status(stepperY, n); tmc_parse_drv_status(stepperY, i);
#endif #endif
#if AXIS_IS_TMC(Y2) #if AXIS_IS_TMC(Y2)
tmc_parse_drv_status(stepperY2, n); tmc_parse_drv_status(stepperY2, i);
#endif #endif
} }
if (TERN0(HAS_Z_AXIS, z)) { if (print_z) {
#if AXIS_IS_TMC(Z) #if AXIS_IS_TMC(Z)
tmc_parse_drv_status(stepperZ, n); tmc_parse_drv_status(stepperZ, i);
#endif #endif
#if AXIS_IS_TMC(Z2) #if AXIS_IS_TMC(Z2)
tmc_parse_drv_status(stepperZ2, n); tmc_parse_drv_status(stepperZ2, i);
#endif #endif
#if AXIS_IS_TMC(Z3) #if AXIS_IS_TMC(Z3)
tmc_parse_drv_status(stepperZ3, n); tmc_parse_drv_status(stepperZ3, i);
#endif #endif
#if AXIS_IS_TMC(Z4) #if AXIS_IS_TMC(Z4)
tmc_parse_drv_status(stepperZ4, n); tmc_parse_drv_status(stepperZ4, i);
#endif #endif
} }
#if AXIS_IS_TMC(I) if (print_e) {
if (i) tmc_parse_drv_status(stepperI, n);
#endif
#if AXIS_IS_TMC(J)
if (j) tmc_parse_drv_status(stepperJ, n);
#endif
#if AXIS_IS_TMC(K)
if (k) tmc_parse_drv_status(stepperK, n);
#endif
if (TERN0(HAS_EXTRUDERS, e)) {
#if AXIS_IS_TMC(E0) #if AXIS_IS_TMC(E0)
tmc_parse_drv_status(stepperE0, n); tmc_parse_drv_status(stepperE0, i);
#endif #endif
#if AXIS_IS_TMC(E1) #if AXIS_IS_TMC(E1)
tmc_parse_drv_status(stepperE1, n); tmc_parse_drv_status(stepperE1, i);
#endif #endif
#if AXIS_IS_TMC(E2) #if AXIS_IS_TMC(E2)
tmc_parse_drv_status(stepperE2, n); tmc_parse_drv_status(stepperE2, i);
#endif #endif
#if AXIS_IS_TMC(E3) #if AXIS_IS_TMC(E3)
tmc_parse_drv_status(stepperE3, n); tmc_parse_drv_status(stepperE3, i);
#endif #endif
#if AXIS_IS_TMC(E4) #if AXIS_IS_TMC(E4)
tmc_parse_drv_status(stepperE4, n); tmc_parse_drv_status(stepperE4, i);
#endif #endif
#if AXIS_IS_TMC(E5) #if AXIS_IS_TMC(E5)
tmc_parse_drv_status(stepperE5, n); tmc_parse_drv_status(stepperE5, i);
#endif #endif
#if AXIS_IS_TMC(E6) #if AXIS_IS_TMC(E6)
tmc_parse_drv_status(stepperE6, n); tmc_parse_drv_status(stepperE6, i);
#endif #endif
#if AXIS_IS_TMC(E7) #if AXIS_IS_TMC(E7)
tmc_parse_drv_status(stepperE7, n); tmc_parse_drv_status(stepperE7, i);
#endif #endif
} }
@@ -924,10 +889,9 @@
* M122 report functions * M122 report functions
*/ */
void tmc_report_all(LOGICAL_AXIS_ARGS(const bool)) { void tmc_report_all(const bool print_x/*=true*/, const bool print_y/*=true*/, const bool print_z/*=true*/, const bool print_e/*=true*/) {
#define TMC_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_debug_loop(ITEM, LOGICAL_AXIS_ARGS()); }while(0) #define TMC_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_debug_loop(ITEM, print_x, print_y, print_z, print_e); }while(0)
#define DRV_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); drv_status_loop(ITEM, LOGICAL_AXIS_ARGS()); }while(0) #define DRV_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); drv_status_loop(ITEM, print_x, print_y, print_z, print_e); }while(0)
TMC_REPORT("\t", TMC_CODES); TMC_REPORT("\t", TMC_CODES);
#if HAS_DRIVER(TMC2209) #if HAS_DRIVER(TMC2209)
TMC_REPORT("Address\t", TMC_UART_ADDR); TMC_REPORT("Address\t", TMC_UART_ADDR);
@@ -1051,82 +1015,72 @@
} }
#endif #endif
static void tmc_get_registers(TMC_get_registers_enum n, LOGICAL_AXIS_ARGS(const bool)) { static void tmc_get_registers(TMC_get_registers_enum i, const bool print_x, const bool print_y, const bool print_z, const bool print_e) {
if (x) { if (print_x) {
#if AXIS_IS_TMC(X) #if AXIS_IS_TMC(X)
tmc_get_registers(stepperX, n); tmc_get_registers(stepperX, i);
#endif #endif
#if AXIS_IS_TMC(X2) #if AXIS_IS_TMC(X2)
tmc_get_registers(stepperX2, n); tmc_get_registers(stepperX2, i);
#endif #endif
} }
if (TERN0(HAS_Y_AXIS, y)) { if (print_y) {
#if AXIS_IS_TMC(Y) #if AXIS_IS_TMC(Y)
tmc_get_registers(stepperY, n); tmc_get_registers(stepperY, i);
#endif #endif
#if AXIS_IS_TMC(Y2) #if AXIS_IS_TMC(Y2)
tmc_get_registers(stepperY2, n); tmc_get_registers(stepperY2, i);
#endif #endif
} }
if (TERN0(HAS_Z_AXIS, z)) { if (print_z) {
#if AXIS_IS_TMC(Z) #if AXIS_IS_TMC(Z)
tmc_get_registers(stepperZ, n); tmc_get_registers(stepperZ, i);
#endif #endif
#if AXIS_IS_TMC(Z2) #if AXIS_IS_TMC(Z2)
tmc_get_registers(stepperZ2, n); tmc_get_registers(stepperZ2, i);
#endif #endif
#if AXIS_IS_TMC(Z3) #if AXIS_IS_TMC(Z3)
tmc_get_registers(stepperZ3, n); tmc_get_registers(stepperZ3, i);
#endif #endif
#if AXIS_IS_TMC(Z4) #if AXIS_IS_TMC(Z4)
tmc_get_registers(stepperZ4, n); tmc_get_registers(stepperZ4, i);
#endif #endif
} }
#if AXIS_IS_TMC(I) if (print_e) {
if (i) tmc_get_registers(stepperI, n);
#endif
#if AXIS_IS_TMC(J)
if (j) tmc_get_registers(stepperJ, n);
#endif
#if AXIS_IS_TMC(K)
if (k) tmc_get_registers(stepperK, n);
#endif
if (TERN0(HAS_EXTRUDERS, e)) {
#if AXIS_IS_TMC(E0) #if AXIS_IS_TMC(E0)
tmc_get_registers(stepperE0, n); tmc_get_registers(stepperE0, i);
#endif #endif
#if AXIS_IS_TMC(E1) #if AXIS_IS_TMC(E1)
tmc_get_registers(stepperE1, n); tmc_get_registers(stepperE1, i);
#endif #endif
#if AXIS_IS_TMC(E2) #if AXIS_IS_TMC(E2)
tmc_get_registers(stepperE2, n); tmc_get_registers(stepperE2, i);
#endif #endif
#if AXIS_IS_TMC(E3) #if AXIS_IS_TMC(E3)
tmc_get_registers(stepperE3, n); tmc_get_registers(stepperE3, i);
#endif #endif
#if AXIS_IS_TMC(E4) #if AXIS_IS_TMC(E4)
tmc_get_registers(stepperE4, n); tmc_get_registers(stepperE4, i);
#endif #endif
#if AXIS_IS_TMC(E5) #if AXIS_IS_TMC(E5)
tmc_get_registers(stepperE5, n); tmc_get_registers(stepperE5, i);
#endif #endif
#if AXIS_IS_TMC(E6) #if AXIS_IS_TMC(E6)
tmc_get_registers(stepperE6, n); tmc_get_registers(stepperE6, i);
#endif #endif
#if AXIS_IS_TMC(E7) #if AXIS_IS_TMC(E7)
tmc_get_registers(stepperE7, n); tmc_get_registers(stepperE7, i);
#endif #endif
} }
SERIAL_EOL(); SERIAL_EOL();
} }
void tmc_get_registers(LOGICAL_AXIS_ARGS(bool)) { void tmc_get_registers(bool print_x, bool print_y, bool print_z, bool print_e) {
#define _TMC_GET_REG(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_get_registers(ITEM, LOGICAL_AXIS_ARGS()); }while(0) #define _TMC_GET_REG(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_get_registers(ITEM, print_x, print_y, print_z, print_e); }while(0)
#define TMC_GET_REG(NAME, TABS) _TMC_GET_REG(STRINGIFY(NAME) TABS, TMC_GET_##NAME) #define TMC_GET_REG(NAME, TABS) _TMC_GET_REG(STRINGIFY(NAME) TABS, TMC_GET_##NAME)
_TMC_GET_REG("\t", TMC_AXIS_CODES); _TMC_GET_REG("\t", TMC_AXIS_CODES);
TMC_GET_REG(GCONF, "\t\t"); TMC_GET_REG(GCONF, "\t\t");
@@ -1211,15 +1165,6 @@
#if AXIS_HAS_SPI(Z4) #if AXIS_HAS_SPI(Z4)
SET_CS_PIN(Z4); SET_CS_PIN(Z4);
#endif #endif
#if AXIS_HAS_SPI(I)
SET_CS_PIN(I);
#endif
#if AXIS_HAS_SPI(J)
SET_CS_PIN(J);
#endif
#if AXIS_HAS_SPI(K)
SET_CS_PIN(K);
#endif
#if AXIS_HAS_SPI(E0) #if AXIS_HAS_SPI(E0)
SET_CS_PIN(E0); SET_CS_PIN(E0);
#endif #endif
@@ -1269,10 +1214,10 @@ static bool test_connection(TMC &st) {
return test_result; return test_result;
} }
void test_tmc_connection(LOGICAL_AXIS_ARGS(const bool)) { void test_tmc_connection(const bool test_x/*=true*/, const bool test_y/*=true*/, const bool test_z/*=true*/, const bool test_e/*=true*/) {
uint8_t axis_connection = 0; uint8_t axis_connection = 0;
if (x) { if (test_x) {
#if AXIS_IS_TMC(X) #if AXIS_IS_TMC(X)
axis_connection += test_connection(stepperX); axis_connection += test_connection(stepperX);
#endif #endif
@@ -1281,7 +1226,7 @@ void test_tmc_connection(LOGICAL_AXIS_ARGS(const bool)) {
#endif #endif
} }
if (TERN0(HAS_Y_AXIS, y)) { if (test_y) {
#if AXIS_IS_TMC(Y) #if AXIS_IS_TMC(Y)
axis_connection += test_connection(stepperY); axis_connection += test_connection(stepperY);
#endif #endif
@@ -1290,7 +1235,7 @@ void test_tmc_connection(LOGICAL_AXIS_ARGS(const bool)) {
#endif #endif
} }
if (TERN0(HAS_Z_AXIS, z)) { if (test_z) {
#if AXIS_IS_TMC(Z) #if AXIS_IS_TMC(Z)
axis_connection += test_connection(stepperZ); axis_connection += test_connection(stepperZ);
#endif #endif
@@ -1305,17 +1250,7 @@ void test_tmc_connection(LOGICAL_AXIS_ARGS(const bool)) {
#endif #endif
} }
#if AXIS_IS_TMC(I) if (test_e) {
if (i) axis_connection += test_connection(stepperI);
#endif
#if AXIS_IS_TMC(J)
if (j) axis_connection += test_connection(stepperJ);
#endif
#if AXIS_IS_TMC(K)
if (k) axis_connection += test_connection(stepperK);
#endif
if (TERN0(HAS_EXTRUDERS, e)) {
#if AXIS_IS_TMC(E0) #if AXIS_IS_TMC(E0)
axis_connection += test_connection(stepperE0); axis_connection += test_connection(stepperE0);
#endif #endif

View File

@@ -335,14 +335,14 @@ void tmc_print_current(TMC &st) {
#endif #endif
void monitor_tmc_drivers(); void monitor_tmc_drivers();
void test_tmc_connection(LOGICAL_AXIS_DECL(const bool, true)); void test_tmc_connection(const bool test_x=true, const bool test_y=true, const bool test_z=true, const bool test_e=true);
#if ENABLED(TMC_DEBUG) #if ENABLED(TMC_DEBUG)
#if ENABLED(MONITOR_DRIVER_STATUS) #if ENABLED(MONITOR_DRIVER_STATUS)
void tmc_set_report_interval(const uint16_t update_interval); void tmc_set_report_interval(const uint16_t update_interval);
#endif #endif
void tmc_report_all(LOGICAL_AXIS_DECL(const bool, true)); void tmc_report_all(const bool print_x=true, const bool print_y=true, const bool print_z=true, const bool print_e=true);
void tmc_get_registers(LOGICAL_AXIS_ARGS(const bool)); void tmc_get_registers(const bool print_x, const bool print_y, const bool print_z, const bool print_e);
#endif #endif
/** /**
@@ -355,16 +355,16 @@ void test_tmc_connection(LOGICAL_AXIS_DECL(const bool, true));
#if USE_SENSORLESS #if USE_SENSORLESS
// Track enabled status of stealthChop and only re-enable where applicable // Track enabled status of stealthChop and only re-enable where applicable
struct sensorless_t { bool LINEAR_AXIS_ARGS(), x2, y2, z2, z3, z4; }; struct sensorless_t { bool x, y, z, x2, y2, z2, z3, z4; };
#if ENABLED(IMPROVE_HOMING_RELIABILITY) #if ENABLED(IMPROVE_HOMING_RELIABILITY)
extern millis_t sg_guard_period; extern millis_t sg_guard_period;
constexpr uint16_t default_sg_guard_duration = 400; constexpr uint16_t default_sg_guard_duration = 400;
struct motion_state_t { struct slow_homing_t {
xy_ulong_t acceleration; xy_ulong_t acceleration;
#if ENABLED(HAS_CLASSIC_JERK) #if ENABLED(HAS_CLASSIC_JERK)
xy_float_t jerk_state; xy_float_t jerk_xy;
#endif #endif
}; };
#endif #endif

View File

@@ -291,7 +291,7 @@ typedef struct {
if (p2.x < 0 || p2.x >= (GRID_MAX_POINTS_X)) return; if (p2.x < 0 || p2.x >= (GRID_MAX_POINTS_X)) return;
if (p2.y < 0 || p2.y >= (GRID_MAX_POINTS_Y)) return; if (p2.y < 0 || p2.y >= (GRID_MAX_POINTS_Y)) return;
if (circle_flags.marked(p1.x, p1.y) && circle_flags.marked(p2.x, p2.y)) { if(circle_flags.marked(p1.x, p1.y) && circle_flags.marked(p2.x, p2.y)) {
xyz_pos_t s, e; xyz_pos_t s, e;
s.x = _GET_MESH_X(p1.x) + (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)) * dx; s.x = _GET_MESH_X(p1.x) + (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)) * dx;
e.x = _GET_MESH_X(p2.x) - (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)) * dx; e.x = _GET_MESH_X(p2.x) - (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)) * dx;

View File

@@ -91,8 +91,8 @@ void GcodeSuite::G35() {
// Disable duplication mode on homing // Disable duplication mode on homing
TERN_(HAS_DUPLICATION_MODE, set_duplication_enabled(false)); 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 // Home all before this procedure
if (!all_axes_trusted()) process_subcommands_now_P(PSTR("G28Z")); home_all_axes();
bool err_break = false; bool err_break = false;

View File

@@ -246,7 +246,7 @@ G29_TYPE GcodeSuite::G29() {
// Send 'N' to force homing before G29 (internal only) // Send 'N' to force homing before G29 (internal only)
if (parser.seen_test('N')) if (parser.seen_test('N'))
process_subcommands_now_P(TERN(CAN_SET_LEVELING_AFTER_G28, PSTR("G28L0"), G28_STR)); process_subcommands_now_P(TERN(G28_L0_ENSURES_LEVELING_OFF, PSTR("G28L0"), G28_STR));
// Don't allow auto-leveling without homing first // Don't allow auto-leveling without homing first
if (homing_needed_error()) G29_RETURN(false); if (homing_needed_error()) G29_RETURN(false);
@@ -689,7 +689,7 @@ G29_TYPE GcodeSuite::G29() {
TERN_(HAS_STATUS_MESSAGE, ui.status_printf_P(0, PSTR(S_FMT " %i/3"), GET_TEXT(MSG_PROBING_MESH), int(i + 1))); TERN_(HAS_STATUS_MESSAGE, ui.status_printf_P(0, PSTR(S_FMT " %i/3"), GET_TEXT(MSG_PROBING_MESH), int(i + 1)));
// Retain the last probe position // Retain the last probe position
abl.probePos = xy_pos_t(points[i]); abl.probePos = points[i];
abl.measured_z = faux ? 0.001 * random(-100, 101) : probe.probe_at_point(abl.probePos, raise_after, abl.verbose_level); abl.measured_z = faux ? 0.001 * random(-100, 101) : probe.probe_at_point(abl.probePos, raise_after, abl.verbose_level);
if (isnan(abl.measured_z)) { if (isnan(abl.measured_z)) {
set_bed_leveling_enabled(abl.reenable); set_bed_leveling_enabled(abl.reenable);
@@ -795,7 +795,7 @@ G29_TYPE GcodeSuite::G29() {
const int ind = abl.indexIntoAB[xx][yy]; const int ind = abl.indexIntoAB[xx][yy];
xyz_float_t tmp = { abl.eqnAMatrix[ind + 0 * abl.abl_points], xyz_float_t tmp = { abl.eqnAMatrix[ind + 0 * abl.abl_points],
abl.eqnAMatrix[ind + 1 * abl.abl_points], 0 }; abl.eqnAMatrix[ind + 1 * abl.abl_points], 0 };
planner.bed_level_matrix.apply_rotation_xyz(tmp.x, tmp.y, tmp.z); planner.bed_level_matrix.apply_rotation_xyz(tmp);
if (get_min) NOMORE(min_diff, abl.eqnBVector[ind] - tmp.z); if (get_min) NOMORE(min_diff, abl.eqnBVector[ind] - tmp.z);
const float subval = get_min ? abl.mean : tmp.z + min_diff, const float subval = get_min ? abl.mean : tmp.z + min_diff,
diff = abl.eqnBVector[ind] - subval; diff = abl.eqnBVector[ind] - subval;

View File

@@ -70,7 +70,7 @@ void GcodeSuite::G29() {
return; return;
} }
int8_t ix, iy = 0; int8_t ix, iy;
switch (state) { switch (state) {
case MeshReport: case MeshReport:
@@ -87,8 +87,7 @@ void GcodeSuite::G29() {
mbl.reset(); mbl.reset();
mbl_probe_index = 0; mbl_probe_index = 0;
if (!ui.wait_for_move) { 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_P(parser.seen_test('N') ? PSTR("G28" TERN(G28_L0_ENSURES_LEVELING_OFF, "L0", "") "\nG29S2") : PSTR("G29S2"));
TERN_(EXTENSIBLE_UI, ExtUI::onMeshLevelingStart());
return; return;
} }
state = MeshNext; state = MeshNext;
@@ -110,7 +109,6 @@ void GcodeSuite::G29() {
else { else {
// Save Z for the previous mesh position // Save Z for the previous mesh position
mbl.set_zigzag_z(mbl_probe_index - 1, current_position.z); mbl.set_zigzag_z(mbl_probe_index - 1, current_position.z);
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(ix, iy, current_position.z));
SET_SOFT_ENDSTOP_LOOSE(false); SET_SOFT_ENDSTOP_LOOSE(false);
} }
// If there's another point to sample, move there with optional lift. // If there's another point to sample, move there with optional lift.

View File

@@ -164,24 +164,24 @@
#if ENABLED(IMPROVE_HOMING_RELIABILITY) #if ENABLED(IMPROVE_HOMING_RELIABILITY)
motion_state_t begin_slow_homing() { slow_homing_t begin_slow_homing() {
motion_state_t motion_state{0}; slow_homing_t slow_homing{0};
motion_state.acceleration.set(planner.settings.max_acceleration_mm_per_s2[X_AXIS], slow_homing.acceleration.set(planner.settings.max_acceleration_mm_per_s2[X_AXIS],
planner.settings.max_acceleration_mm_per_s2[Y_AXIS]); planner.settings.max_acceleration_mm_per_s2[Y_AXIS]);
planner.settings.max_acceleration_mm_per_s2[X_AXIS] = 100; planner.settings.max_acceleration_mm_per_s2[X_AXIS] = 100;
planner.settings.max_acceleration_mm_per_s2[Y_AXIS] = 100; planner.settings.max_acceleration_mm_per_s2[Y_AXIS] = 100;
#if HAS_CLASSIC_JERK #if HAS_CLASSIC_JERK
motion_state.jerk_state = planner.max_jerk; slow_homing.jerk_xy = planner.max_jerk;
planner.max_jerk.set(0, 0); planner.max_jerk.set(0, 0);
#endif #endif
planner.reset_acceleration_rates(); planner.reset_acceleration_rates();
return motion_state; return slow_homing;
} }
void end_slow_homing(const motion_state_t &motion_state) { void end_slow_homing(const slow_homing_t &slow_homing) {
planner.settings.max_acceleration_mm_per_s2[X_AXIS] = motion_state.acceleration.x; planner.settings.max_acceleration_mm_per_s2[X_AXIS] = slow_homing.acceleration.x;
planner.settings.max_acceleration_mm_per_s2[Y_AXIS] = motion_state.acceleration.y; planner.settings.max_acceleration_mm_per_s2[Y_AXIS] = slow_homing.acceleration.y;
TERN_(HAS_CLASSIC_JERK, planner.max_jerk = motion_state.jerk_state); TERN_(HAS_CLASSIC_JERK, planner.max_jerk = slow_homing.jerk_xy);
planner.reset_acceleration_rates(); planner.reset_acceleration_rates();
} }
@@ -195,9 +195,9 @@
* None Home to all axes with no parameters. * None Home to all axes with no parameters.
* With QUICK_HOME enabled XY will home together, then Z. * With QUICK_HOME enabled XY will home together, then Z.
* *
* L<bool> Force leveling state ON (if possible) or OFF after homing (Requires RESTORE_LEVELING_AFTER_G28 or ENABLE_LEVELING_AFTER_G28) * O Home only if position is unknown
* O Home only if the position is not known and trusted *
* R<linear> Raise by n mm/inches before homing * Rn Raise by n mm/inches before homing
* *
* Cartesian/SCARA parameters * Cartesian/SCARA parameters
* *
@@ -229,7 +229,7 @@ void GcodeSuite::G28() {
#endif #endif
// Home (O)nly if position is unknown // Home (O)nly if position is unknown
if (!axes_should_home() && parser.seen_test('O')) { if (!axes_should_home() && parser.boolval('O')) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> homing not needed, skip"); if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> homing not needed, skip");
return; return;
} }
@@ -242,16 +242,12 @@ void GcodeSuite::G28() {
SET_SOFT_ENDSTOP_LOOSE(false); // Reset a leftover 'loose' motion state SET_SOFT_ENDSTOP_LOOSE(false); // Reset a leftover 'loose' motion state
// Disable the leveling matrix before homing // Disable the leveling matrix before homing
#if CAN_SET_LEVELING_AFTER_G28 #if HAS_LEVELING
const bool leveling_restore_state = parser.boolval('L', TERN1(RESTORE_LEVELING_AFTER_G28, planner.leveling_active)); const bool leveling_restore_state = parser.boolval('L', TERN(RESTORE_LEVELING_AFTER_G28, planner.leveling_active, ENABLED(ENABLE_LEVELING_AFTER_G28)));
IF_ENABLED(PROBE_MANUALLY, g29_in_progress = false); // Cancel the active G29 session
set_bed_leveling_enabled(false);
#endif #endif
// Cancel any prior G29 session
TERN_(PROBE_MANUALLY, g29_in_progress = false);
// Disable leveling before homing
TERN_(HAS_LEVELING, set_bed_leveling_enabled(false));
// Reset to the XY plane // Reset to the XY plane
TERN_(CNC_WORKSPACE_PLANES, workspace_plane = PLANE_XY); TERN_(CNC_WORKSPACE_PLANES, workspace_plane = PLANE_XY);
@@ -289,9 +285,7 @@ void GcodeSuite::G28() {
#endif #endif
#endif #endif
#if ENABLED(IMPROVE_HOMING_RELIABILITY) TERN_(IMPROVE_HOMING_RELIABILITY, slow_homing_t slow_homing = begin_slow_homing());
motion_state_t saved_motion_state = begin_slow_homing();
#endif
// Always home with tool 0 active // Always home with tool 0 active
#if HAS_MULTI_HOTEND #if HAS_MULTI_HOTEND
@@ -317,7 +311,7 @@ void GcodeSuite::G28() {
home_delta(); home_delta();
TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(saved_motion_state)); TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(slow_homing));
#elif ENABLED(AXEL_TPARA) #elif ENABLED(AXEL_TPARA)
@@ -327,47 +321,33 @@ void GcodeSuite::G28() {
#else #else
#define _UNSAFE(A) (homeZ && TERN0(Z_SAFE_HOMING, axes_should_home(_BV(A##_AXIS)))) const bool homeZ = parser.seen_test('Z'),
needX = homeZ && TERN0(Z_SAFE_HOMING, axes_should_home(_BV(X_AXIS))),
needY = homeZ && TERN0(Z_SAFE_HOMING, axes_should_home(_BV(Y_AXIS))),
homeX = needX || parser.seen_test('X'), homeY = needY || parser.seen_test('Y'),
home_all = homeX == homeY && homeX == homeZ, // All or None
doX = home_all || homeX, doY = home_all || homeY, doZ = home_all || homeZ;
const bool homeZ = TERN0(HAS_Z_AXIS, parser.seen_test('Z')), #if ENABLED(HOME_Z_FIRST)
LINEAR_AXIS_LIST( // Other axes should be homed before Z safe-homing
needX = _UNSAFE(X), needY = _UNSAFE(Y), needZ = false, // UNUSED if (doZ) homeaxis(Z_AXIS);
needI = _UNSAFE(I), needJ = _UNSAFE(J), needK = _UNSAFE(K)
),
LINEAR_AXIS_LIST( // Home each axis if needed or flagged
homeX = needX || parser.seen_test('X'),
homeY = needY || parser.seen_test('Y'),
homeZZ = homeZ,
homeI = needI || parser.seen_test(AXIS4_NAME), homeJ = needJ || parser.seen_test(AXIS5_NAME), homeK = needK || parser.seen_test(AXIS6_NAME),
),
home_all = LINEAR_AXIS_GANG( // Home-all if all or none are flagged
homeX == homeX, && homeY == homeX, && homeZ == homeX,
&& homeI == homeX, && homeJ == homeX, && homeK == homeX
),
LINEAR_AXIS_LIST(
doX = home_all || homeX, doY = home_all || homeY, doZ = home_all || homeZ,
doI = home_all || homeI, doJ = home_all || homeJ, doK = home_all || homeK
);
#if HAS_Z_AXIS
UNUSED(needZ); UNUSED(homeZZ);
#else
constexpr bool doZ = false;
#endif #endif
TERN_(HOME_Z_FIRST, if (doZ) homeaxis(Z_AXIS));
const float z_homing_height = parser.seenval('R') ? parser.value_linear_units() : Z_HOMING_HEIGHT; const float z_homing_height = parser.seenval('R') ? parser.value_linear_units() : Z_HOMING_HEIGHT;
if (z_homing_height && (LINEAR_AXIS_GANG(doX, || doY, || TERN0(Z_SAFE_HOMING, doZ), || doI, || doJ, || doK))) { if (z_homing_height && (doX || doY || TERN0(Z_SAFE_HOMING, doZ))) {
// Raise Z before homing any other axes and z is not already high enough (never lower z) // 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_ECHOLNPAIR("Raise Z (before homing) by ", z_homing_height);
do_z_clearance(z_homing_height); do_z_clearance(z_homing_height);
TERN_(BLTOUCH, bltouch.init()); TERN_(BLTOUCH, bltouch.init());
} }
// Diagonal move first if both are homing #if ENABLED(QUICK_HOME)
TERN_(QUICK_HOME, if (doX && doY) quick_home_xy());
if (doX && doY) quick_home_xy();
#endif
// Home Y (before X) // Home Y (before X)
if (ENABLED(HOME_Y_BEFORE_X) && (doY || TERN0(CODEPENDENT_XY_HOMING, doX))) if (ENABLED(HOME_Y_BEFORE_X) && (doY || TERN0(CODEPENDENT_XY_HOMING, doX)))
@@ -403,10 +383,10 @@ void GcodeSuite::G28() {
if (DISABLED(HOME_Y_BEFORE_X) && doY) if (DISABLED(HOME_Y_BEFORE_X) && doY)
homeaxis(Y_AXIS); homeaxis(Y_AXIS);
TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(saved_motion_state)); TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(slow_homing));
// Home Z last if homing towards the bed // Home Z last if homing towards the bed
#if HAS_Z_AXIS && DISABLED(HOME_Z_FIRST) #if DISABLED(HOME_Z_FIRST)
if (doZ) { if (doZ) {
#if EITHER(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN) #if EITHER(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
stepper.set_all_z_lock(false); stepper.set_all_z_lock(false);
@@ -418,16 +398,6 @@ void GcodeSuite::G28() {
} }
#endif #endif
#if LINEAR_AXES >= 4
if (doI) homeaxis(I_AXIS);
#endif
#if LINEAR_AXES >= 5
if (doJ) homeaxis(J_AXIS);
#endif
#if LINEAR_AXES >= 6
if (doK) homeaxis(K_AXIS);
#endif
sync_plan_position(); sync_plan_position();
#endif #endif
@@ -442,7 +412,7 @@ void GcodeSuite::G28() {
if (idex_is_duplicating()) { if (idex_is_duplicating()) {
TERN_(IMPROVE_HOMING_RELIABILITY, saved_motion_state = begin_slow_homing()); TERN_(IMPROVE_HOMING_RELIABILITY, slow_homing = begin_slow_homing());
// Always home the 2nd (right) extruder first // Always home the 2nd (right) extruder first
active_extruder = 1; active_extruder = 1;
@@ -461,7 +431,7 @@ void GcodeSuite::G28() {
dual_x_carriage_mode = IDEX_saved_mode; dual_x_carriage_mode = IDEX_saved_mode;
set_duplication_enabled(IDEX_saved_duplication_state); set_duplication_enabled(IDEX_saved_duplication_state);
TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(saved_motion_state)); TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(slow_homing));
} }
#endif // DUAL_X_CARRIAGE #endif // DUAL_X_CARRIAGE
@@ -471,10 +441,12 @@ void GcodeSuite::G28() {
// Clear endstop state for polled stallGuard endstops // Clear endstop state for polled stallGuard endstops
TERN_(SPI_ENDSTOPS, endstops.clear_endstop_state()); TERN_(SPI_ENDSTOPS, endstops.clear_endstop_state());
// Move to a height where we can use the full xy-area #if BOTH(DELTA, DELTA_HOME_TO_SAFE_ZONE)
TERN_(DELTA_HOME_TO_SAFE_ZONE, do_blocking_move_to_z(delta_clip_start_height)); // move to a height where we can use the full xy-area
do_blocking_move_to_z(delta_clip_start_height);
#endif
TERN_(CAN_SET_LEVELING_AFTER_G28, if (leveling_restore_state) set_bed_leveling_enabled()); TERN_(HAS_LEVELING, set_bed_leveling_enabled(leveling_restore_state));
restore_feedrate_and_scaling(); restore_feedrate_and_scaling();
@@ -497,16 +469,7 @@ void GcodeSuite::G28() {
#if HAS_CURRENT_HOME(Y2) #if HAS_CURRENT_HOME(Y2)
stepperY2.rms_current(tmc_save_current_Y2); stepperY2.rms_current(tmc_save_current_Y2);
#endif #endif
#if HAS_CURRENT_HOME(I) #endif
stepperI.rms_current(tmc_save_current_I);
#endif
#if HAS_CURRENT_HOME(J)
stepperJ.rms_current(tmc_save_current_J);
#endif
#if HAS_CURRENT_HOME(K)
stepperK.rms_current(tmc_save_current_K);
#endif
#endif // HAS_HOMING_CURRENT
ui.refresh(); ui.refresh();
@@ -524,13 +487,11 @@ void GcodeSuite::G28() {
// Set L6470 absolute position registers to counts // Set L6470 absolute position registers to counts
// constexpr *might* move this to PROGMEM. // constexpr *might* move this to PROGMEM.
// If not, this will need a PROGMEM directive and an accessor. // If not, this will need a PROGMEM directive and an accessor.
#define _EN_ITEM(N) , E_AXIS
static constexpr AxisEnum L64XX_axis_xref[MAX_L64XX] = { static constexpr AxisEnum L64XX_axis_xref[MAX_L64XX] = {
LINEAR_AXIS_LIST(X_AXIS, Y_AXIS, Z_AXIS, I_AXIS, J_AXIS, K_AXIS), X_AXIS, Y_AXIS, Z_AXIS,
X_AXIS, Y_AXIS, Z_AXIS, Z_AXIS, Z_AXIS X_AXIS, Y_AXIS, Z_AXIS, Z_AXIS,
REPEAT(E_STEPPERS, _EN_ITEM) E_AXIS, E_AXIS, E_AXIS, E_AXIS, E_AXIS, E_AXIS
}; };
#undef _EN_ITEM
for (uint8_t j = 1; j <= L64XX::chain[0]; j++) { for (uint8_t j = 1; j <= L64XX::chain[0]; j++) {
const uint8_t cv = L64XX::chain[j]; const uint8_t cv = L64XX::chain[j];
L64xxManager.set_param((L64XX_axis_t)cv, L6470_ABS_POS, stepper.position(L64XX_axis_xref[cv])); L64xxManager.set_param((L64XX_axis_t)cv, L6470_ABS_POS, stepper.position(L64XX_axis_xref[cv]));

View File

@@ -39,7 +39,7 @@
void GcodeSuite::G34() { void GcodeSuite::G34() {
// Home before the alignment procedure // Home before the alignment procedure
home_if_needed(); if (!all_axes_trusted()) home_all_axes();
TERN_(HAS_LEVELING, TEMPORARY_BED_LEVELING_STATE(false)); TERN_(HAS_LEVELING, TEMPORARY_BED_LEVELING_STATE(false));

View File

@@ -48,13 +48,6 @@
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) #define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
#include "../../core/debug_out.h" #include "../../core/debug_out.h"
#if NUM_Z_STEPPER_DRIVERS >= 3
#define TRIPLE_Z 1
#if NUM_Z_STEPPER_DRIVERS >= 4
#define QUAD_Z 1
#endif
#endif
/** /**
* G34: Z-Stepper automatic alignment * G34: Z-Stepper automatic alignment
* *
@@ -89,9 +82,9 @@ void GcodeSuite::G34() {
switch (parser.intval('Z')) { switch (parser.intval('Z')) {
case 1: stepper.set_z1_lock(state); break; case 1: stepper.set_z1_lock(state); break;
case 2: stepper.set_z2_lock(state); break; case 2: stepper.set_z2_lock(state); break;
#if TRIPLE_Z #if NUM_Z_STEPPER_DRIVERS >= 3
case 3: stepper.set_z3_lock(state); break; case 3: stepper.set_z3_lock(state); break;
#if QUAD_Z #if NUM_Z_STEPPER_DRIVERS >= 4
case 4: stepper.set_z4_lock(state); break; case 4: stepper.set_z4_lock(state); break;
#endif #endif
#endif #endif
@@ -106,6 +99,13 @@ void GcodeSuite::G34() {
#if ENABLED(Z_STEPPER_AUTO_ALIGN) #if ENABLED(Z_STEPPER_AUTO_ALIGN)
do { // break out on error do { // break out on error
#if NUM_Z_STEPPER_DRIVERS == 4
SERIAL_ECHOLNPGM("Alignment for 4 steppers is Experimental!");
#elif NUM_Z_STEPPER_DRIVERS > 4
SERIAL_ECHOLNPGM("Alignment not supported for over 4 steppers");
break;
#endif
const int8_t z_auto_align_iterations = parser.intval('I', Z_STEPPER_ALIGN_ITERATIONS); const int8_t z_auto_align_iterations = parser.intval('I', Z_STEPPER_ALIGN_ITERATIONS);
if (!WITHIN(z_auto_align_iterations, 1, 30)) { if (!WITHIN(z_auto_align_iterations, 1, 30)) {
SERIAL_ECHOLNPGM("?(I)teration out of bounds (1-30)."); SERIAL_ECHOLNPGM("?(I)teration out of bounds (1-30).");
@@ -157,17 +157,19 @@ void GcodeSuite::G34() {
const xy_pos_t diff = z_stepper_align.xy[i] - z_stepper_align.xy[j]; const xy_pos_t diff = z_stepper_align.xy[i] - z_stepper_align.xy[j];
return HYPOT2(diff.x, diff.y); return HYPOT2(diff.x, diff.y);
}; };
float z_probe = Z_BASIC_CLEARANCE + (G34_MAX_GRADE) * 0.01f * SQRT(_MAX(0, magnitude2(0, 1) float z_probe = Z_BASIC_CLEARANCE + (G34_MAX_GRADE) * 0.01f * SQRT(
#if TRIPLE_Z #if NUM_Z_STEPPER_DRIVERS == 3
, magnitude2(2, 1), magnitude2(2, 0) _MAX(magnitude2(0, 1), magnitude2(1, 2), magnitude2(2, 0))
#if QUAD_Z #elif NUM_Z_STEPPER_DRIVERS == 4
, magnitude2(3, 2), magnitude2(3, 1), magnitude2(3, 0) _MAX(magnitude2(0, 1), magnitude2(1, 2), magnitude2(2, 3),
#endif magnitude2(3, 0), magnitude2(0, 2), magnitude2(1, 3))
#else
magnitude2(0, 1)
#endif #endif
)); );
// Home before the alignment procedure // Home before the alignment procedure
home_if_needed(); if (!all_axes_trusted()) home_all_axes();
// Move the Z coordinate realm towards the positive - dirty trick // Move the Z coordinate realm towards the positive - dirty trick
current_position.z += z_probe * 0.5f; current_position.z += z_probe * 0.5f;
@@ -176,7 +178,7 @@ void GcodeSuite::G34() {
// This hack is un-done at the end of G34 - either by re-homing, or by using the probed heights of the last iteration. // This hack is un-done at the end of G34 - either by re-homing, or by using the probed heights of the last iteration.
#if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) #if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
float last_z_align_move[NUM_Z_STEPPER_DRIVERS] = ARRAY_N_1(NUM_Z_STEPPER_DRIVERS, 10000.0f); float last_z_align_move[NUM_Z_STEPPER_DRIVERS] = ARRAY_N(NUM_Z_STEPPER_DRIVERS, 10000.0f, 10000.0f, 10000.0f, 10000.0f);
#else #else
float last_z_align_level_indicator = 10000.0f; float last_z_align_level_indicator = 10000.0f;
#endif #endif
@@ -278,52 +280,39 @@ void GcodeSuite::G34() {
z_measured_min = _MIN(z_measured_min, z_measured[i]); z_measured_min = _MIN(z_measured_min, z_measured[i]);
} }
SERIAL_ECHOLNPAIR( SERIAL_ECHOLNPAIR("CALCULATED STEPPER POSITIONS: Z1=", z_measured[0], " Z2=", z_measured[1], " Z3=", z_measured[2]);
LIST_N(DOUBLE(NUM_Z_STEPPER_DRIVERS),
"Calculated Z1=", z_measured[0],
" Z2=", z_measured[1],
" Z3=", z_measured[2],
" Z4=", z_measured[3]
)
);
#endif #endif
SERIAL_ECHOLNPAIR("\n" SERIAL_ECHOLNPAIR("\n"
"Z2-Z1=", ABS(z_measured[1] - z_measured[0]) "DIFFERENCE Z1-Z2=", ABS(z_measured[0] - z_measured[1])
#if TRIPLE_Z #if NUM_Z_STEPPER_DRIVERS == 3
, " Z3-Z2=", ABS(z_measured[2] - z_measured[1]) , " Z2-Z3=", ABS(z_measured[1] - z_measured[2])
, " Z3-Z1=", ABS(z_measured[2] - z_measured[0]) , " Z3-Z1=", ABS(z_measured[2] - z_measured[0])
#if QUAD_Z
, " Z4-Z3=", ABS(z_measured[3] - z_measured[2])
, " Z4-Z2=", ABS(z_measured[3] - z_measured[1])
, " Z4-Z1=", ABS(z_measured[3] - z_measured[0])
#endif
#endif #endif
); );
#if HAS_STATUS_MESSAGE #if HAS_STATUS_MESSAGE
char fstr1[10]; char fstr1[10];
char msg[6 + (6 + 5) * NUM_Z_STEPPER_DRIVERS + 1] #if NUM_Z_STEPPER_DRIVERS == 2
#if TRIPLE_Z char msg[6 + (6 + 5) * 1 + 1];
, fstr2[10], fstr3[10] #else
#if QUAD_Z char msg[6 + (6 + 5) * 3 + 1], fstr2[10], fstr3[10];
, fstr4[10], fstr5[10], fstr6[10] #endif
#endif
#endif
;
sprintf_P(msg, sprintf_P(msg,
PSTR("1:2=%s" TERN_(TRIPLE_Z, " 3-2=%s 3-1=%s") TERN_(QUAD_Z, " 4-3=%s 4-2=%s 4-1=%s")), PSTR("Diffs Z1-Z2=%s"
dtostrf(ABS(z_measured[1] - z_measured[0]), 1, 3, fstr1) #if NUM_Z_STEPPER_DRIVERS == 3
OPTARG(TRIPLE_Z, dtostrf(ABS(z_measured[2] - z_measured[1]), 1, 3, fstr2)) " Z2-Z3=%s"
OPTARG(TRIPLE_Z, dtostrf(ABS(z_measured[2] - z_measured[0]), 1, 3, fstr3)) " Z3-Z1=%s"
OPTARG(QUAD_Z, dtostrf(ABS(z_measured[3] - z_measured[2]), 1, 3, fstr4)) #endif
OPTARG(QUAD_Z, dtostrf(ABS(z_measured[3] - z_measured[1]), 1, 3, fstr5)) ), dtostrf(ABS(z_measured[0] - z_measured[1]), 1, 3, fstr1)
OPTARG(QUAD_Z, dtostrf(ABS(z_measured[3] - z_measured[0]), 1, 3, fstr6)) #if NUM_Z_STEPPER_DRIVERS == 3
, dtostrf(ABS(z_measured[1] - z_measured[2]), 1, 3, fstr2)
, dtostrf(ABS(z_measured[2] - z_measured[0]), 1, 3, fstr3)
#endif
); );
ui.set_status(msg); ui.set_status(msg);
#endif #endif
auto decreasing_accuracy = [](const_float_t v1, const_float_t v2) { auto decreasing_accuracy = [](const_float_t v1, const_float_t v2){
if (v1 < v2 * 0.7f) { if (v1 < v2 * 0.7f) {
SERIAL_ECHOLNPGM("Decreasing Accuracy Detected."); SERIAL_ECHOLNPGM("Decreasing Accuracy Detected.");
LCD_MESSAGEPGM(MSG_DECREASING_ACCURACY); LCD_MESSAGEPGM(MSG_DECREASING_ACCURACY);
@@ -448,7 +437,7 @@ void GcodeSuite::G34() {
#endif #endif
}while(0); }while(0);
#endif // Z_STEPPER_AUTO_ALIGN #endif
} }
#endif // Z_MULTI_ENDSTOPS || Z_STEPPER_AUTO_ALIGN #endif // Z_MULTI_ENDSTOPS || Z_STEPPER_AUTO_ALIGN

View File

@@ -73,23 +73,11 @@
#if BOTH(CALIBRATION_MEASURE_LEFT, CALIBRATION_MEASURE_RIGHT) #if BOTH(CALIBRATION_MEASURE_LEFT, CALIBRATION_MEASURE_RIGHT)
#define HAS_X_CENTER 1 #define HAS_X_CENTER 1
#endif #endif
#if HAS_Y_AXIS && BOTH(CALIBRATION_MEASURE_FRONT, CALIBRATION_MEASURE_BACK) #if BOTH(CALIBRATION_MEASURE_FRONT, CALIBRATION_MEASURE_BACK)
#define HAS_Y_CENTER 1 #define HAS_Y_CENTER 1
#endif #endif
#if LINEAR_AXES >= 4 && BOTH(CALIBRATION_MEASURE_IMIN, CALIBRATION_MEASURE_IMAX)
#define HAS_I_CENTER 1
#endif
#if LINEAR_AXES >= 5 && BOTH(CALIBRATION_MEASURE_JMIN, CALIBRATION_MEASURE_JMAX)
#define HAS_J_CENTER 1
#endif
#if LINEAR_AXES >= 6 && BOTH(CALIBRATION_MEASURE_KMIN, CALIBRATION_MEASURE_KMAX)
#define HAS_K_CENTER 1
#endif
enum side_t : uint8_t { enum side_t : uint8_t { TOP, RIGHT, FRONT, LEFT, BACK, NUM_SIDES };
TOP, RIGHT, FRONT, LEFT, BACK, NUM_SIDES,
LIST_N(DOUBLE(SUB3(LINEAR_AXES)), IMINIMUM, IMAXIMUM, JMINIMUM, JMAXIMUM, KMINIMUM, KMAXIMUM)
};
static constexpr xyz_pos_t true_center CALIBRATION_OBJECT_CENTER; static constexpr xyz_pos_t true_center CALIBRATION_OBJECT_CENTER;
static constexpr xyz_float_t dimensions CALIBRATION_OBJECT_DIMENSIONS; static constexpr xyz_float_t dimensions CALIBRATION_OBJECT_DIMENSIONS;
@@ -117,7 +105,7 @@ struct measurements_t {
#endif #endif
inline void calibration_move() { inline void calibration_move() {
do_blocking_move_to((xyz_pos_t)current_position, MMM_TO_MMS(CALIBRATION_FEEDRATE_TRAVEL)); do_blocking_move_to(current_position, MMM_TO_MMS(CALIBRATION_FEEDRATE_TRAVEL));
} }
/** /**
@@ -186,7 +174,7 @@ float measuring_movement(const AxisEnum axis, const int dir, const bool stop_sta
destination = current_position; destination = current_position;
for (float travel = 0; travel < limit; travel += step) { for (float travel = 0; travel < limit; travel += step) {
destination[axis] += dir * step; destination[axis] += dir * step;
do_blocking_move_to((xyz_pos_t)destination, mms); do_blocking_move_to(destination, mms);
planner.synchronize(); planner.synchronize();
if (read_calibration_pin() == stop_state) break; if (read_calibration_pin() == stop_state) break;
} }
@@ -221,7 +209,7 @@ inline float measure(const AxisEnum axis, const int dir, const bool stop_state,
// Move back to the starting position // Move back to the starting position
destination = current_position; destination = current_position;
destination[axis] = start_pos; destination[axis] = start_pos;
do_blocking_move_to((xyz_pos_t)destination, MMM_TO_MMS(CALIBRATION_FEEDRATE_TRAVEL)); do_blocking_move_to(destination, MMM_TO_MMS(CALIBRATION_FEEDRATE_TRAVEL));
return measured_pos; return measured_pos;
} }
@@ -242,15 +230,7 @@ inline void probe_side(measurements_t &m, const float uncertainty, const side_t
park_above_object(m, uncertainty); park_above_object(m, uncertainty);
switch (side) { switch (side) {
#if AXIS_CAN_CALIBRATE(X) #if AXIS_CAN_CALIBRATE(Z)
case RIGHT: dir = -1;
case LEFT: axis = X_AXIS; break;
#endif
#if LINEAR_AXES >= 2 && AXIS_CAN_CALIBRATE(Y)
case BACK: dir = -1;
case FRONT: axis = Y_AXIS; break;
#endif
#if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z)
case TOP: { case TOP: {
const float measurement = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty); const float measurement = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty);
m.obj_center.z = measurement - dimensions.z / 2; m.obj_center.z = measurement - dimensions.z / 2;
@@ -258,17 +238,13 @@ inline void probe_side(measurements_t &m, const float uncertainty, const side_t
return; return;
} }
#endif #endif
#if LINEAR_AXES >= 4 && AXIS_CAN_CALIBRATE(I) #if AXIS_CAN_CALIBRATE(X)
case IMINIMUM: dir = -1; case RIGHT: dir = -1;
case IMAXIMUM: axis = I_AXIS; break; case LEFT: axis = X_AXIS; break;
#endif #endif
#if LINEAR_AXES >= 5 && AXIS_CAN_CALIBRATE(J) #if AXIS_CAN_CALIBRATE(Y)
case JMINIMUM: dir = -1; case BACK: dir = -1;
case JMAXIMUM: axis = J_AXIS; break; case FRONT: axis = Y_AXIS; break;
#endif
#if LINEAR_AXES >= 6 && AXIS_CAN_CALIBRATE(K)
case KMINIMUM: dir = -1;
case KMAXIMUM: axis = K_AXIS; break;
#endif #endif
default: return; default: return;
} }
@@ -313,23 +289,14 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
probe_side(m, uncertainty, TOP); probe_side(m, uncertainty, TOP);
#endif #endif
TERN_(CALIBRATION_MEASURE_RIGHT, probe_side(m, uncertainty, RIGHT, probe_top_at_edge)); TERN_(CALIBRATION_MEASURE_RIGHT, probe_side(m, uncertainty, RIGHT, probe_top_at_edge));
TERN_(CALIBRATION_MEASURE_FRONT, probe_side(m, uncertainty, FRONT, probe_top_at_edge)); TERN_(CALIBRATION_MEASURE_FRONT, probe_side(m, uncertainty, FRONT, probe_top_at_edge));
TERN_(CALIBRATION_MEASURE_LEFT, probe_side(m, uncertainty, LEFT, probe_top_at_edge)); TERN_(CALIBRATION_MEASURE_LEFT, probe_side(m, uncertainty, LEFT, probe_top_at_edge));
TERN_(CALIBRATION_MEASURE_BACK, probe_side(m, uncertainty, BACK, probe_top_at_edge)); TERN_(CALIBRATION_MEASURE_BACK, probe_side(m, uncertainty, BACK, probe_top_at_edge));
TERN_(CALIBRATION_MEASURE_IMIN, probe_side(m, uncertainty, IMINIMUM, probe_top_at_edge));
TERN_(CALIBRATION_MEASURE_IMAX, probe_side(m, uncertainty, IMAXIMUM, probe_top_at_edge));
TERN_(CALIBRATION_MEASURE_JMIN, probe_side(m, uncertainty, JMINIMUM, probe_top_at_edge));
TERN_(CALIBRATION_MEASURE_JMAX, probe_side(m, uncertainty, JMAXIMUM, probe_top_at_edge));
TERN_(CALIBRATION_MEASURE_KMIN, probe_side(m, uncertainty, KMINIMUM, probe_top_at_edge));
TERN_(CALIBRATION_MEASURE_KMAX, probe_side(m, uncertainty, KMAXIMUM, probe_top_at_edge));
// Compute the measured center of the calibration object. // Compute the measured center of the calibration object.
TERN_(HAS_X_CENTER, m.obj_center.x = (m.obj_side[LEFT] + m.obj_side[RIGHT]) / 2); TERN_(HAS_X_CENTER, m.obj_center.x = (m.obj_side[LEFT] + m.obj_side[RIGHT]) / 2);
TERN_(HAS_Y_CENTER, m.obj_center.y = (m.obj_side[FRONT] + m.obj_side[BACK]) / 2); TERN_(HAS_Y_CENTER, m.obj_center.y = (m.obj_side[FRONT] + m.obj_side[BACK]) / 2);
TERN_(HAS_I_CENTER, m.obj_center.i = (m.obj_side[IMINIMUM] + m.obj_side[IMAXIMUM]) / 2);
TERN_(HAS_J_CENTER, m.obj_center.j = (m.obj_side[JMINIMUM] + m.obj_side[JMAXIMUM]) / 2);
TERN_(HAS_K_CENTER, m.obj_center.k = (m.obj_side[KMINIMUM] + m.obj_side[KMAXIMUM]) / 2);
// Compute the outside diameter of the nozzle at the height // Compute the outside diameter of the nozzle at the height
// at which it makes contact with the calibration object // at which it makes contact with the calibration object
@@ -340,20 +307,15 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
// The difference between the known and the measured location // The difference between the known and the measured location
// of the calibration object is the positional error // of the calibration object is the positional error
LINEAR_AXIS_CODE( m.pos_error.x = TERN0(HAS_X_CENTER, true_center.x - m.obj_center.x);
m.pos_error.x = TERN0(HAS_X_CENTER, true_center.x - m.obj_center.x), m.pos_error.y = TERN0(HAS_Y_CENTER, true_center.y - m.obj_center.y);
m.pos_error.y = TERN0(HAS_Y_CENTER, true_center.y - m.obj_center.y), m.pos_error.z = true_center.z - m.obj_center.z;
m.pos_error.z = true_center.z - m.obj_center.z,
m.pos_error.i = TERN0(HAS_I_CENTER, true_center.i - m.obj_center.i),
m.pos_error.j = TERN0(HAS_J_CENTER, true_center.j - m.obj_center.j),
m.pos_error.k = TERN0(HAS_K_CENTER, true_center.k - m.obj_center.k)
);
} }
#if ENABLED(CALIBRATION_REPORTING) #if ENABLED(CALIBRATION_REPORTING)
inline void report_measured_faces(const measurements_t &m) { inline void report_measured_faces(const measurements_t &m) {
SERIAL_ECHOLNPGM("Sides:"); SERIAL_ECHOLNPGM("Sides:");
#if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z) #if AXIS_CAN_CALIBRATE(Z)
SERIAL_ECHOLNPAIR(" Top: ", m.obj_side[TOP]); SERIAL_ECHOLNPAIR(" Top: ", m.obj_side[TOP]);
#endif #endif
#if ENABLED(CALIBRATION_MEASURE_LEFT) #if ENABLED(CALIBRATION_MEASURE_LEFT)
@@ -362,37 +324,11 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
#if ENABLED(CALIBRATION_MEASURE_RIGHT) #if ENABLED(CALIBRATION_MEASURE_RIGHT)
SERIAL_ECHOLNPAIR(" Right: ", m.obj_side[RIGHT]); SERIAL_ECHOLNPAIR(" Right: ", m.obj_side[RIGHT]);
#endif #endif
#if HAS_Y_AXIS #if ENABLED(CALIBRATION_MEASURE_FRONT)
#if ENABLED(CALIBRATION_MEASURE_FRONT) SERIAL_ECHOLNPAIR(" Front: ", m.obj_side[FRONT]);
SERIAL_ECHOLNPAIR(" Front: ", m.obj_side[FRONT]);
#endif
#if ENABLED(CALIBRATION_MEASURE_BACK)
SERIAL_ECHOLNPAIR(" Back: ", m.obj_side[BACK]);
#endif
#endif #endif
#if LINEAR_AXES >= 4 #if ENABLED(CALIBRATION_MEASURE_BACK)
#if ENABLED(CALIBRATION_MEASURE_IMIN) SERIAL_ECHOLNPAIR(" Back: ", m.obj_side[BACK]);
SERIAL_ECHOLNPAIR(" " STR_I_MIN ": ", m.obj_side[IMINIMUM]);
#endif
#if ENABLED(CALIBRATION_MEASURE_IMAX)
SERIAL_ECHOLNPAIR(" " 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]);
#endif
#if ENABLED(CALIBRATION_MEASURE_JMAX)
SERIAL_ECHOLNPAIR(" " 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]);
#endif
#if ENABLED(CALIBRATION_MEASURE_KMAX)
SERIAL_ECHOLNPAIR(" " STR_K_MAX ": ", m.obj_side[KMAXIMUM]);
#endif
#endif #endif
SERIAL_EOL(); SERIAL_EOL();
} }
@@ -406,15 +342,6 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
SERIAL_ECHOLNPAIR_P(SP_Y_STR, m.obj_center.y); SERIAL_ECHOLNPAIR_P(SP_Y_STR, m.obj_center.y);
#endif #endif
SERIAL_ECHOLNPAIR_P(SP_Z_STR, m.obj_center.z); SERIAL_ECHOLNPAIR_P(SP_Z_STR, m.obj_center.z);
#if HAS_I_CENTER
SERIAL_ECHOLNPAIR_P(SP_I_STR, m.obj_center.i);
#endif
#if HAS_J_CENTER
SERIAL_ECHOLNPAIR_P(SP_J_STR, m.obj_center.j);
#endif
#if HAS_K_CENTER
SERIAL_ECHOLNPAIR_P(SP_K_STR, m.obj_center.k);
#endif
SERIAL_EOL(); SERIAL_EOL();
} }
@@ -428,7 +355,7 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
SERIAL_ECHOLNPAIR(" Right: ", m.backlash[RIGHT]); SERIAL_ECHOLNPAIR(" Right: ", m.backlash[RIGHT]);
#endif #endif
#endif #endif
#if HAS_Y_AXIS && AXIS_CAN_CALIBRATE(Y) #if AXIS_CAN_CALIBRATE(Y)
#if ENABLED(CALIBRATION_MEASURE_FRONT) #if ENABLED(CALIBRATION_MEASURE_FRONT)
SERIAL_ECHOLNPAIR(" Front: ", m.backlash[FRONT]); SERIAL_ECHOLNPAIR(" Front: ", m.backlash[FRONT]);
#endif #endif
@@ -436,33 +363,9 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
SERIAL_ECHOLNPAIR(" Back: ", m.backlash[BACK]); SERIAL_ECHOLNPAIR(" Back: ", m.backlash[BACK]);
#endif #endif
#endif #endif
#if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z) #if AXIS_CAN_CALIBRATE(Z)
SERIAL_ECHOLNPAIR(" Top: ", m.backlash[TOP]); SERIAL_ECHOLNPAIR(" Top: ", m.backlash[TOP]);
#endif #endif
#if LINEAR_AXES >= 4 && AXIS_CAN_CALIBRATE(I)
#if ENABLED(CALIBRATION_MEASURE_IMIN)
SERIAL_ECHOLNPAIR(" " STR_I_MIN ": ", m.backlash[IMINIMUM]);
#endif
#if ENABLED(CALIBRATION_MEASURE_IMAX)
SERIAL_ECHOLNPAIR(" " 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]);
#endif
#if ENABLED(CALIBRATION_MEASURE_JMAX)
SERIAL_ECHOLNPAIR(" " 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]);
#endif
#if ENABLED(CALIBRATION_MEASURE_KMAX)
SERIAL_ECHOLNPAIR(" " STR_K_MAX ": ", m.backlash[KMAXIMUM]);
#endif
#endif
SERIAL_EOL(); SERIAL_EOL();
} }
@@ -470,37 +373,29 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
SERIAL_CHAR('T'); SERIAL_CHAR('T');
SERIAL_ECHO(active_extruder); SERIAL_ECHO(active_extruder);
SERIAL_ECHOLNPGM(" Positional Error:"); SERIAL_ECHOLNPGM(" Positional Error:");
#if HAS_X_CENTER && AXIS_CAN_CALIBRATE(X) #if HAS_X_CENTER
SERIAL_ECHOLNPAIR_P(SP_X_STR, m.pos_error.x); SERIAL_ECHOLNPAIR_P(SP_X_STR, m.pos_error.x);
#endif #endif
#if HAS_Y_CENTER && AXIS_CAN_CALIBRATE(Y) #if HAS_Y_CENTER
SERIAL_ECHOLNPAIR_P(SP_Y_STR, m.pos_error.y); SERIAL_ECHOLNPAIR_P(SP_Y_STR, m.pos_error.y);
#endif #endif
#if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z) if (AXIS_CAN_CALIBRATE(Z)) SERIAL_ECHOLNPAIR_P(SP_Z_STR, m.pos_error.z);
SERIAL_ECHOLNPAIR_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);
#endif
#if HAS_J_CENTER && AXIS_CAN_CALIBRATE(J)
SERIAL_ECHOLNPAIR_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);
#endif
SERIAL_EOL(); SERIAL_EOL();
} }
inline void report_measured_nozzle_dimensions(const measurements_t &m) { inline void report_measured_nozzle_dimensions(const measurements_t &m) {
SERIAL_ECHOLNPGM("Nozzle Tip Outer Dimensions:"); SERIAL_ECHOLNPGM("Nozzle Tip Outer Dimensions:");
#if HAS_X_CENTER #if HAS_X_CENTER || HAS_Y_CENTER
SERIAL_ECHOLNPAIR_P(SP_X_STR, m.nozzle_outer_dimension.x); #if HAS_X_CENTER
#endif SERIAL_ECHOLNPAIR_P(SP_X_STR, m.nozzle_outer_dimension.x);
#if HAS_Y_CENTER #endif
SERIAL_ECHOLNPAIR_P(SP_Y_STR, m.nozzle_outer_dimension.y); #if HAS_Y_CENTER
SERIAL_ECHOLNPAIR_P(SP_Y_STR, m.nozzle_outer_dimension.y);
#endif
#else
UNUSED(m);
#endif #endif
SERIAL_EOL(); SERIAL_EOL();
UNUSED(m);
} }
#if HAS_HOTEND_OFFSET #if HAS_HOTEND_OFFSET
@@ -549,33 +444,8 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) {
backlash.distance_mm.y = m.backlash[BACK]; backlash.distance_mm.y = m.backlash[BACK];
#endif #endif
TERN_(HAS_Z_AXIS, if (AXIS_CAN_CALIBRATE(Z)) backlash.distance_mm.z = m.backlash[TOP]); if (AXIS_CAN_CALIBRATE(Z)) backlash.distance_mm.z = m.backlash[TOP];
#endif
#if HAS_I_CENTER
backlash.distance_mm.i = (m.backlash[IMINIMUM] + m.backlash[IMAXIMUM]) / 2;
#elif ENABLED(CALIBRATION_MEASURE_IMIN)
backlash.distance_mm.i = m.backlash[IMINIMUM];
#elif ENABLED(CALIBRATION_MEASURE_IMAX)
backlash.distance_mm.i = m.backlash[IMAXIMUM];
#endif
#if HAS_J_CENTER
backlash.distance_mm.j = (m.backlash[JMINIMUM] + m.backlash[JMAXIMUM]) / 2;
#elif ENABLED(CALIBRATION_MEASURE_JMIN)
backlash.distance_mm.j = m.backlash[JMINIMUM];
#elif ENABLED(CALIBRATION_MEASURE_JMAX)
backlash.distance_mm.j = m.backlash[JMAXIMUM];
#endif
#if HAS_K_CENTER
backlash.distance_mm.k = (m.backlash[KMINIMUM] + m.backlash[KMAXIMUM]) / 2;
#elif ENABLED(CALIBRATION_MEASURE_KMIN)
backlash.distance_mm.k = m.backlash[KMINIMUM];
#elif ENABLED(CALIBRATION_MEASURE_KMAX)
backlash.distance_mm.k = m.backlash[KMAXIMUM];
#endif
#endif // BACKLASH_GCODE
} }
#if ENABLED(BACKLASH_GCODE) #if ENABLED(BACKLASH_GCODE)
@@ -585,10 +455,7 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) {
// New scope for TEMPORARY_BACKLASH_CORRECTION // New scope for TEMPORARY_BACKLASH_CORRECTION
TEMPORARY_BACKLASH_CORRECTION(all_on); TEMPORARY_BACKLASH_CORRECTION(all_on);
TEMPORARY_BACKLASH_SMOOTHING(0.0f); TEMPORARY_BACKLASH_SMOOTHING(0.0f);
const xyz_float_t move = LINEAR_AXIS_ARRAY( const xyz_float_t move = { AXIS_CAN_CALIBRATE(X) * 3, AXIS_CAN_CALIBRATE(Y) * 3, AXIS_CAN_CALIBRATE(Z) * 3 };
AXIS_CAN_CALIBRATE(X) * 3, AXIS_CAN_CALIBRATE(Y) * 3, AXIS_CAN_CALIBRATE(Z) * 3,
AXIS_CAN_CALIBRATE(I) * 3, AXIS_CAN_CALIBRATE(J) * 3, AXIS_CAN_CALIBRATE(K) * 3
);
current_position += move; calibration_move(); current_position += move; calibration_move();
current_position -= move; calibration_move(); current_position -= move; calibration_move();
} }
@@ -616,7 +483,11 @@ inline void calibrate_toolhead(measurements_t &m, const float uncertainty, const
TEMPORARY_BACKLASH_CORRECTION(all_on); TEMPORARY_BACKLASH_CORRECTION(all_on);
TEMPORARY_BACKLASH_SMOOTHING(0.0f); TEMPORARY_BACKLASH_SMOOTHING(0.0f);
TERN(HAS_MULTI_HOTEND, set_nozzle(m, extruder), UNUSED(extruder)); #if HAS_MULTI_HOTEND
set_nozzle(m, extruder);
#else
UNUSED(extruder);
#endif
probe_sides(m, uncertainty); probe_sides(m, uncertainty);
@@ -635,10 +506,6 @@ inline void calibrate_toolhead(measurements_t &m, const float uncertainty, const
if (ENABLED(HAS_Y_CENTER) && AXIS_CAN_CALIBRATE(Y)) update_measurements(m, Y_AXIS); if (ENABLED(HAS_Y_CENTER) && AXIS_CAN_CALIBRATE(Y)) update_measurements(m, Y_AXIS);
if (AXIS_CAN_CALIBRATE(Z)) update_measurements(m, Z_AXIS); if (AXIS_CAN_CALIBRATE(Z)) update_measurements(m, Z_AXIS);
TERN_(HAS_I_CENTER, update_measurements(m, I_AXIS));
TERN_(HAS_J_CENTER, update_measurements(m, J_AXIS));
TERN_(HAS_K_CENTER, update_measurements(m, K_AXIS));
sync_plan_position(); sync_plan_position();
} }

View File

@@ -48,15 +48,10 @@ void GcodeSuite::M425() {
auto axis_can_calibrate = [](const uint8_t a) { auto axis_can_calibrate = [](const uint8_t a) {
switch (a) { switch (a) {
default: return false; default:
LINEAR_AXIS_CODE( case X_AXIS: return AXIS_CAN_CALIBRATE(X);
case X_AXIS: return AXIS_CAN_CALIBRATE(X), case Y_AXIS: return AXIS_CAN_CALIBRATE(Y);
case Y_AXIS: return AXIS_CAN_CALIBRATE(Y), case Z_AXIS: return AXIS_CAN_CALIBRATE(Z);
case Z_AXIS: return AXIS_CAN_CALIBRATE(Z),
case I_AXIS: return AXIS_CAN_CALIBRATE(I),
case J_AXIS: return AXIS_CAN_CALIBRATE(J),
case K_AXIS: return AXIS_CAN_CALIBRATE(K),
);
} }
}; };

View File

@@ -71,27 +71,29 @@
#endif #endif
#if ENABLED(Z_MULTI_ENDSTOPS) #if ENABLED(Z_MULTI_ENDSTOPS)
if (parser.seenval('Z')) { if (parser.seenval('Z')) {
const float z_adj = parser.value_linear_units(); #if NUM_Z_STEPPER_DRIVERS >= 3
#if NUM_Z_STEPPER_DRIVERS == 2 const float z_adj = parser.value_linear_units();
endstops.z2_endstop_adj = z_adj;
#else
const int ind = parser.intval('S'); const int ind = parser.intval('S');
#define _SET_ZADJ(N) if (!ind || ind == N) endstops.z##N##_endstop_adj = z_adj; if (!ind || ind == 2) endstops.z2_endstop_adj = z_adj;
REPEAT_S(2, INCREMENT(NUM_Z_STEPPER_DRIVERS), _SET_ZADJ) if (!ind || ind == 3) endstops.z3_endstop_adj = z_adj;
#if NUM_Z_STEPPER_DRIVERS >= 4
if (!ind || ind == 4) endstops.z4_endstop_adj = z_adj;
#endif
#else
endstops.z2_endstop_adj = parser.value_linear_units();
#endif #endif
} }
#endif #endif
if (!parser.seen("XYZ")) { if (!parser.seen("XYZ")) {
auto echo_adj = [](PGM_P const label, const_float_t value) { SERIAL_ECHOPAIR_P(label, value); };
SERIAL_ECHOPGM("Dual Endstop Adjustment (mm): "); SERIAL_ECHOPGM("Dual Endstop Adjustment (mm): ");
#if ENABLED(X_DUAL_ENDSTOPS) #if ENABLED(X_DUAL_ENDSTOPS)
echo_adj(PSTR(" X2:"), endstops.x2_endstop_adj); SERIAL_ECHOPAIR(" X2:", endstops.x2_endstop_adj);
#endif #endif
#if ENABLED(Y_DUAL_ENDSTOPS) #if ENABLED(Y_DUAL_ENDSTOPS)
echo_adj(PSTR(" Y2:"), endstops.y2_endstop_adj); SERIAL_ECHOPAIR(" Y2:", endstops.y2_endstop_adj);
#endif #endif
#if ENABLED(Z_MULTI_ENDSTOPS) #if ENABLED(Z_MULTI_ENDSTOPS)
#define _ECHO_ZADJ(N) echo_adj(PSTR(" Z" STRINGIFY(N) ":"), endstops.z##N##_endstop_adj); #define _ECHO_ZADJ(N) SERIAL_ECHOPAIR(" Z" STRINGIFY(N) ":", endstops.z##N##_endstop_adj);
REPEAT_S(2, INCREMENT(NUM_Z_STEPPER_DRIVERS), _ECHO_ZADJ) REPEAT_S(2, INCREMENT(NUM_Z_STEPPER_DRIVERS), _ECHO_ZADJ)
#endif #endif
SERIAL_EOL(); SERIAL_EOL();

View File

@@ -88,7 +88,7 @@ void GcodeSuite::M201() {
LOOP_LOGICAL_AXES(i) { LOOP_LOGICAL_AXES(i) {
if (parser.seenval(axis_codes[i])) { if (parser.seenval(axis_codes[i])) {
const uint8_t a = TERN(HAS_EXTRUDERS, (i == E_AXIS ? uint8_t(E_AXIS_N(target_extruder)) : i), i); const uint8_t a = (i == E_AXIS ? uint8_t(E_AXIS_N(target_extruder)) : i);
planner.set_max_acceleration(a, parser.value_axis_units((AxisEnum)a)); planner.set_max_acceleration(a, parser.value_axis_units((AxisEnum)a));
} }
} }
@@ -106,7 +106,7 @@ void GcodeSuite::M203() {
LOOP_LOGICAL_AXES(i) LOOP_LOGICAL_AXES(i)
if (parser.seenval(axis_codes[i])) { if (parser.seenval(axis_codes[i])) {
const uint8_t a = TERN(HAS_EXTRUDERS, (i == E_AXIS ? uint8_t(E_AXIS_N(target_extruder)) : i), i); const uint8_t a = (i == E_AXIS ? uint8_t(E_AXIS_N(target_extruder)) : i);
planner.set_max_feedrate(a, parser.value_axis_units((AxisEnum)a)); planner.set_max_feedrate(a, parser.value_axis_units((AxisEnum)a));
} }
} }
@@ -154,9 +154,6 @@ void GcodeSuite::M205() {
if (parser.seenval('S')) planner.settings.min_feedrate_mm_s = parser.value_linear_units(); if (parser.seenval('S')) planner.settings.min_feedrate_mm_s = parser.value_linear_units();
if (parser.seenval('T')) planner.settings.min_travel_feedrate_mm_s = parser.value_linear_units(); if (parser.seenval('T')) planner.settings.min_travel_feedrate_mm_s = parser.value_linear_units();
#if HAS_JUNCTION_DEVIATION #if HAS_JUNCTION_DEVIATION
#if HAS_CLASSIC_JERK && (AXIS4_NAME == 'J' || AXIS5_NAME == 'J' || AXIS6_NAME == 'J')
#error "Can't set_max_jerk for 'J' axis because 'J' is used for Junction Deviation."
#endif
if (parser.seenval('J')) { if (parser.seenval('J')) {
const float junc_dev = parser.value_linear_units(); const float junc_dev = parser.value_linear_units();
if (WITHIN(junc_dev, 0.01f, 0.3f)) { if (WITHIN(junc_dev, 0.01f, 0.3f)) {
@@ -168,19 +165,17 @@ void GcodeSuite::M205() {
} }
#endif #endif
#if HAS_CLASSIC_JERK #if HAS_CLASSIC_JERK
bool seenZ = false; if (parser.seenval('X')) planner.set_max_jerk(X_AXIS, parser.value_linear_units());
LOGICAL_AXIS_CODE( if (parser.seenval('Y')) planner.set_max_jerk(Y_AXIS, parser.value_linear_units());
if (parser.seenval('E')) planner.set_max_jerk(E_AXIS, parser.value_linear_units()), if (parser.seenval('Z')) {
if (parser.seenval('X')) planner.set_max_jerk(X_AXIS, parser.value_linear_units()), planner.set_max_jerk(Z_AXIS, parser.value_linear_units());
if (parser.seenval('Y')) planner.set_max_jerk(Y_AXIS, parser.value_linear_units()), #if HAS_MESH && DISABLED(LIMITED_JERK_EDITING)
if ((seenZ = parser.seenval('Z'))) planner.set_max_jerk(Z_AXIS, parser.value_linear_units()), if (planner.max_jerk.z <= 0.1f)
if (parser.seenval(AXIS4_NAME)) planner.set_max_jerk(I_AXIS, parser.value_linear_units()), SERIAL_ECHOLNPGM("WARNING! Low Z Jerk may lead to unwanted pauses.");
if (parser.seenval(AXIS5_NAME)) planner.set_max_jerk(J_AXIS, parser.value_linear_units()), #endif
if (parser.seenval(AXIS6_NAME)) planner.set_max_jerk(K_AXIS, parser.value_linear_units()) }
); #if HAS_CLASSIC_E_JERK
#if HAS_MESH && DISABLED(LIMITED_JERK_EDITING) if (parser.seenval('E')) planner.set_max_jerk(E_AXIS, parser.value_linear_units());
if (seenZ && planner.max_jerk.z <= 0.1f)
SERIAL_ECHOLNPGM("WARNING! Low Z Jerk may lead to unwanted pauses.");
#endif #endif
#endif // HAS_CLASSIC_JERK #endif
} }

View File

@@ -25,15 +25,10 @@
void report_M92(const bool echo=true, const int8_t e=-1) { void report_M92(const bool echo=true, const int8_t e=-1) {
if (echo) SERIAL_ECHO_START(); else SERIAL_CHAR(' '); if (echo) SERIAL_ECHO_START(); else SERIAL_CHAR(' ');
SERIAL_ECHOPAIR_P(LIST_N(DOUBLE(LINEAR_AXES), SERIAL_ECHOPAIR_P(PSTR(" M92 X"), LINEAR_UNIT(planner.settings.axis_steps_per_mm[X_AXIS]),
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_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_Z_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Z_AXIS]), #if DISABLED(DISTINCT_E_FACTORS)
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])); SERIAL_ECHOPAIR_P(SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS]));
#endif #endif
SERIAL_EOL(); SERIAL_EOL();
@@ -69,28 +64,25 @@ void GcodeSuite::M92() {
if (target_extruder < 0) return; if (target_extruder < 0) return;
// No arguments? Show M92 report. // No arguments? Show M92 report.
if (!parser.seen( if (!parser.seen("XYZE" TERN_(MAGIC_NUMBERS_GCODE, "HL")))
LOGICAL_AXIS_GANG("E", "X", "Y", "Z", AXIS4_STR, AXIS5_STR, AXIS6_STR) return report_M92(true, target_extruder);
TERN_(MAGIC_NUMBERS_GCODE, "HL")
)) return report_M92(true, target_extruder);
LOOP_LOGICAL_AXES(i) { LOOP_LOGICAL_AXES(i) {
if (parser.seenval(axis_codes[i])) { if (parser.seenval(axis_codes[i])) {
if (TERN1(HAS_EXTRUDERS, i != E_AXIS)) if (i == E_AXIS) {
planner.settings.axis_steps_per_mm[i] = parser.value_per_axis_units((AxisEnum)i); const float value = parser.value_per_axis_units((AxisEnum)(E_AXIS_N(target_extruder)));
if (value < 20) {
float factor = planner.settings.axis_steps_per_mm[E_AXIS_N(target_extruder)] / value; // increase e constants if M92 E14 is given for netfab.
#if HAS_CLASSIC_JERK && HAS_CLASSIC_E_JERK
planner.max_jerk.e *= factor;
#endif
planner.settings.max_feedrate_mm_s[E_AXIS_N(target_extruder)] *= factor;
planner.max_acceleration_steps_per_s2[E_AXIS_N(target_extruder)] *= factor;
}
planner.settings.axis_steps_per_mm[E_AXIS_N(target_extruder)] = value;
}
else { else {
#if HAS_EXTRUDERS planner.settings.axis_steps_per_mm[i] = parser.value_per_axis_units((AxisEnum)i);
const float value = parser.value_per_axis_units((AxisEnum)(E_AXIS_N(target_extruder)));
if (value < 20) {
float factor = planner.settings.axis_steps_per_mm[E_AXIS_N(target_extruder)] / value; // increase e constants if M92 E14 is given for netfab.
#if HAS_CLASSIC_JERK && HAS_CLASSIC_E_JERK
planner.max_jerk.e *= factor;
#endif
planner.settings.max_feedrate_mm_s[E_AXIS_N(target_extruder)] *= factor;
planner.max_acceleration_steps_per_s2[E_AXIS_N(target_extruder)] *= factor;
}
planner.settings.axis_steps_per_mm[E_AXIS_N(target_extruder)] = value;
#endif
} }
} }
} }

View File

@@ -33,16 +33,11 @@
* M17: Enable stepper motors * M17: Enable stepper motors
*/ */
void GcodeSuite::M17() { void GcodeSuite::M17() {
if (parser.seen(LOGICAL_AXIS_GANG("E", "X", "Y", "Z", AXIS4_STR, AXIS5_STR, AXIS6_STR))) { if (parser.seen("XYZE")) {
LOGICAL_AXIS_CODE( if (parser.seen_test('X')) ENABLE_AXIS_X();
if (TERN0(HAS_E_STEPPER_ENABLE, parser.seen_test('E'))) enable_e_steppers(), if (parser.seen_test('Y')) ENABLE_AXIS_Y();
if (parser.seen_test('X')) ENABLE_AXIS_X(), if (parser.seen_test('Z')) ENABLE_AXIS_Z();
if (parser.seen_test('Y')) ENABLE_AXIS_Y(), if (TERN0(HAS_E_STEPPER_ENABLE, parser.seen_test('E'))) enable_e_steppers();
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()
);
} }
else { else {
LCD_MESSAGEPGM(MSG_NO_MOVE); LCD_MESSAGEPGM(MSG_NO_MOVE);
@@ -59,17 +54,12 @@ void GcodeSuite::M18_M84() {
stepper_inactive_time = parser.value_millis_from_seconds(); stepper_inactive_time = parser.value_millis_from_seconds();
} }
else { else {
if (parser.seen(LOGICAL_AXIS_GANG("E", "X", "Y", "Z", AXIS4_STR, AXIS5_STR, AXIS6_STR))) { if (parser.seen("XYZE")) {
planner.synchronize(); planner.synchronize();
LOGICAL_AXIS_CODE( if (parser.seen_test('X')) DISABLE_AXIS_X();
if (TERN0(HAS_E_STEPPER_ENABLE, parser.seen_test('E'))) disable_e_steppers(), if (parser.seen_test('Y')) DISABLE_AXIS_Y();
if (parser.seen_test('X')) DISABLE_AXIS_X(), if (parser.seen_test('Z')) DISABLE_AXIS_Z();
if (parser.seen_test('Y')) DISABLE_AXIS_Y(), if (TERN0(HAS_E_STEPPER_ENABLE, parser.seen_test('E'))) disable_e_steppers();
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()
);
} }
else else
planner.finish_and_disable(); planner.finish_and_disable();

View File

@@ -70,12 +70,26 @@
dual_x_carriage_mode = (DualXMode)parser.value_byte(); dual_x_carriage_mode = (DualXMode)parser.value_byte();
idex_set_mirrored_mode(false); idex_set_mirrored_mode(false);
switch (dual_x_carriage_mode) { if (dual_x_carriage_mode == DXC_MIRRORED_MODE) {
if (previous_mode != DXC_DUPLICATION_MODE) {
SERIAL_ECHOLNPGM("Printer must be in DXC_DUPLICATION_MODE prior to ");
SERIAL_ECHOLNPGM("specifying DXC_MIRRORED_MODE.");
dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
return;
}
idex_set_mirrored_mode(true);
float x_jog = current_position.x - .1;
for (uint8_t i = 2; --i;) {
planner.buffer_line(x_jog, current_position.y, current_position.z, current_position.e, feedrate_mm_s, 0);
x_jog += .1;
}
return;
}
switch (dual_x_carriage_mode) {
case DXC_FULL_CONTROL_MODE: case DXC_FULL_CONTROL_MODE:
case DXC_AUTO_PARK_MODE: case DXC_AUTO_PARK_MODE:
break; break;
case DXC_DUPLICATION_MODE: case DXC_DUPLICATION_MODE:
// Set the X offset, but no less than the safety gap // Set the X offset, but no less than the safety gap
if (parser.seen('X')) duplicate_extruder_x_offset = _MAX(parser.value_linear_units(), (X2_MIN_POS) - (X1_MIN_POS)); if (parser.seen('X')) duplicate_extruder_x_offset = _MAX(parser.value_linear_units(), (X2_MIN_POS) - (X1_MIN_POS));
@@ -83,29 +97,10 @@
// Always switch back to tool 0 // Always switch back to tool 0
if (active_extruder != 0) tool_change(0); if (active_extruder != 0) tool_change(0);
break; break;
case DXC_MIRRORED_MODE: {
if (previous_mode != DXC_DUPLICATION_MODE) {
SERIAL_ECHOLNPGM("Printer must be in DXC_DUPLICATION_MODE prior to ");
SERIAL_ECHOLNPGM("specifying DXC_MIRRORED_MODE.");
dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
return;
}
idex_set_mirrored_mode(true);
// Do a small 'jog' motion in the X axis
xyze_pos_t dest = current_position; dest.x -= 0.1f;
for (uint8_t i = 2; --i;) {
planner.buffer_line(dest, feedrate_mm_s, 0);
dest.x += 0.1f;
}
} return;
default: default:
dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE; dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
break; break;
} }
idex_set_parked(false); idex_set_parked(false);
set_duplication_enabled(false); set_duplication_enabled(false);

View File

@@ -20,9 +20,9 @@
* *
*/ */
#include "../../inc/MarlinConfigPre.h" #include "../../inc/MarlinConfig.h"
#if ANY(COOLANT_MIST, COOLANT_FLOOD, AIR_ASSIST) #if ENABLED(COOLANT_CONTROL)
#include "../gcode.h" #include "../gcode.h"
#include "../../module/planner.h" #include "../../module/planner.h"
@@ -37,41 +37,51 @@
} }
#endif #endif
#if EITHER(COOLANT_FLOOD, AIR_ASSIST) #if ENABLED(COOLANT_FLOOD)
#if ENABLED(AIR_ASSIST)
#include "../../feature/spindle_laser.h"
#endif
/** /**
* M8: Flood Coolant / Air Assist ON * M8: Flood Coolant On
*/ */
void GcodeSuite::M8() { void GcodeSuite::M8() {
planner.synchronize(); // Wait for move to arrive planner.synchronize(); // Wait for move to arrive
#if ENABLED(COOLANT_FLOOD) WRITE(COOLANT_FLOOD_PIN, !(COOLANT_FLOOD_INVERT)); // Turn on Flood coolant
WRITE(COOLANT_FLOOD_PIN, !(COOLANT_FLOOD_INVERT)); // Turn on Flood coolant
#endif
#if ENABLED(AIR_ASSIST)
cutter.air_assist_enable(); // Turn on Air Assist
#endif
} }
#endif #endif
/** /**
* M9: Coolant / Air Assist OFF * M9: Coolant OFF
*/ */
void GcodeSuite::M9() { void GcodeSuite::M9() {
planner.synchronize(); // Wait for move to arrive planner.synchronize(); // Wait for move to arrive
#if ENABLED(COOLANT_MIST) #if ENABLED(COOLANT_MIST)
WRITE(COOLANT_MIST_PIN, COOLANT_MIST_INVERT); // Turn off Mist coolant WRITE(COOLANT_MIST_PIN, COOLANT_MIST_INVERT); // Turn off Mist coolant
#endif #endif
#if ENABLED(COOLANT_FLOOD) #if ENABLED(COOLANT_FLOOD)
WRITE(COOLANT_FLOOD_PIN, COOLANT_FLOOD_INVERT); // Turn off Flood coolant WRITE(COOLANT_FLOOD_PIN, COOLANT_FLOOD_INVERT); // Turn off Flood coolant
#endif
#if ENABLED(AIR_ASSIST)
cutter.air_assist_disable(); // Turn off Air Assist
#endif #endif
} }
#endif // COOLANT_MIST | COOLANT_FLOOD | AIR_ASSIST #endif // COOLANT_CONTROL
#if ENABLED(AIR_ASSIST)
#include "../gcode.h"
#include "../../module/planner.h"
#include "../../feature/spindle_laser.h"
/**
* M8: Air Assist On
*/
void GcodeSuite::M8() {
planner.synchronize();
cutter.air_assist_enable(); // Turn on Air Assist pin
}
/**
* M9: Air Assist Off
*/
void GcodeSuite::M9() {
planner.synchronize();
cutter.air_assist_disable(); // Turn off Air Assist pin
}
#endif // AIR_ASSIST

View File

@@ -32,6 +32,31 @@
#define DEBUG_OUT ENABLED(L6470_CHITCHAT) #define DEBUG_OUT ENABLED(L6470_CHITCHAT)
#include "../../../core/debug_out.h" #include "../../../core/debug_out.h"
/**
* M906: report or set KVAL_HOLD which sets the maximum effective voltage provided by the
* PWMs to the steppers
*
* On L6474 this sets the TVAL register (same address).
*
* I - select which driver(s) to change on multi-driver axis
* 0 - (default) all drivers on the axis or E0
* 1 - monitor only X, Y, Z or E1
* 2 - monitor only X2, Y2, Z2 or E2
* 3 - monitor only Z3 or E3
* 4 - monitor only Z4 or E4
* 5 - monitor only E5
* Xxxx, Yxxx, Zxxx, Exxx - axis to change (optional)
* L6474 - current in mA (4A max)
* All others - 0-255
*/
/**
* Sets KVAL_HOLD wich affects the current being driven through the stepper.
*
* L6470 is used in the STEP-CLOCK mode. KVAL_HOLD is the only KVAL_xxx
* that affects the effective voltage seen by the stepper.
*/
/** /**
* MACRO to fetch information on the items associated with current limiting * MACRO to fetch information on the items associated with current limiting
* and maximum voltage output. * and maximum voltage output.
@@ -195,28 +220,6 @@ void L64XX_report_current(L64XX &motor, const L64XX_axis_t axis) {
} }
} }
/**
* M906: report or set KVAL_HOLD which sets the maximum effective voltage provided by the
* PWMs to the steppers
*
* On L6474 this sets the TVAL register (same address).
*
* I - select which driver(s) to change on multi-driver axis
* 0 - (default) all drivers on the axis or E0
* 1 - monitor only X, Y, Z or E1
* 2 - monitor only X2, Y2, Z2 or E2
* 3 - monitor only Z3 or E3
* 4 - monitor only Z4 or E4
* 5 - monitor only E5
* Xxxx, Yxxx, Zxxx, Exxx - axis to change (optional)
* L6474 - current in mA (4A max)
* All others - 0-255
*
* Sets KVAL_HOLD wich affects the current being driven through the stepper.
*
* L6470 is used in the STEP-CLOCK mode. KVAL_HOLD is the only KVAL_xxx
* that affects the effective voltage seen by the stepper.
*/
void GcodeSuite::M906() { void GcodeSuite::M906() {
L64xxManager.pause_monitor(true); // Keep monitor_driver() from stealing status L64xxManager.pause_monitor(true); // Keep monitor_driver() from stealing status
@@ -249,67 +252,58 @@ void GcodeSuite::M906() {
if (index == 1) L6470_SET_KVAL_HOLD(X2); if (index == 1) L6470_SET_KVAL_HOLD(X2);
#endif #endif
break; break;
case Y_AXIS:
#if HAS_Y_AXIS #if AXIS_IS_L64XX(Y)
case Y_AXIS: if (index == 0) L6470_SET_KVAL_HOLD(Y);
#if AXIS_IS_L64XX(Y) #endif
if (index == 0) L6470_SET_KVAL_HOLD(Y); #if AXIS_IS_L64XX(Y2)
if (index == 1) L6470_SET_KVAL_HOLD(Y2);
#endif
break;
case Z_AXIS:
#if AXIS_IS_L64XX(Z)
if (index == 0) L6470_SET_KVAL_HOLD(Z);
#endif
#if AXIS_IS_L64XX(Z2)
if (index == 1) L6470_SET_KVAL_HOLD(Z2);
#endif
#if AXIS_IS_L64XX(Z3)
if (index == 2) L6470_SET_KVAL_HOLD(Z3);
#endif
#if AXIS_DRIVER_TYPE_Z4(L6470)
if (index == 3) L6470_SET_KVAL_HOLD(Z4);
#endif
break;
case E_AXIS: {
const int8_t target_extruder = get_target_extruder_from_command();
if (target_extruder < 0) return;
switch (target_extruder) {
#if AXIS_IS_L64XX(E0)
case 0: L6470_SET_KVAL_HOLD(E0); break;
#endif #endif
#if AXIS_IS_L64XX(Y2) #if AXIS_IS_L64XX(E1)
if (index == 1) L6470_SET_KVAL_HOLD(Y2); case 1: L6470_SET_KVAL_HOLD(E1); break;
#endif #endif
break; #if AXIS_IS_L64XX(E2)
#endif case 2: L6470_SET_KVAL_HOLD(E2); break;
#if HAS_Z_AXIS
case Z_AXIS:
#if AXIS_IS_L64XX(Z)
if (index == 0) L6470_SET_KVAL_HOLD(Z);
#endif #endif
#if AXIS_IS_L64XX(Z2) #if AXIS_IS_L64XX(E3)
if (index == 1) L6470_SET_KVAL_HOLD(Z2); case 3: L6470_SET_KVAL_HOLD(E3); break;
#endif #endif
#if AXIS_IS_L64XX(Z3) #if AXIS_IS_L64XX(E4)
if (index == 2) L6470_SET_KVAL_HOLD(Z3); case 4: L6470_SET_KVAL_HOLD(E4); break;
#endif #endif
#if AXIS_DRIVER_TYPE_Z4(L6470) #if AXIS_IS_L64XX(E5)
if (index == 3) L6470_SET_KVAL_HOLD(Z4); case 5: L6470_SET_KVAL_HOLD(E5); break;
#endif #endif
break; #if AXIS_IS_L64XX(E6)
#endif case 6: L6470_SET_KVAL_HOLD(E6); break;
#endif
#if E_STEPPERS #if AXIS_IS_L64XX(E7)
case E_AXIS: { case 7: L6470_SET_KVAL_HOLD(E7); break;
const int8_t target_e_stepper = get_target_e_stepper_from_command(); #endif
if (target_e_stepper < 0) return; }
switch (target_e_stepper) { } break;
#if AXIS_IS_L64XX(E0)
case 0: L6470_SET_KVAL_HOLD(E0); break;
#endif
#if AXIS_IS_L64XX(E1)
case 1: L6470_SET_KVAL_HOLD(E1); break;
#endif
#if AXIS_IS_L64XX(E2)
case 2: L6470_SET_KVAL_HOLD(E2); break;
#endif
#if AXIS_IS_L64XX(E3)
case 3: L6470_SET_KVAL_HOLD(E3); break;
#endif
#if AXIS_IS_L64XX(E4)
case 4: L6470_SET_KVAL_HOLD(E4); break;
#endif
#if AXIS_IS_L64XX(E5)
case 5: L6470_SET_KVAL_HOLD(E5); break;
#endif
#if AXIS_IS_L64XX(E6)
case 6: L6470_SET_KVAL_HOLD(E6); break;
#endif
#if AXIS_IS_L64XX(E7)
case 7: L6470_SET_KVAL_HOLD(E7); break;
#endif
}
} break;
#endif
} }
} }

View File

@@ -42,7 +42,6 @@
* P0 S<strokes> : Stroke cleaning with S strokes * P0 S<strokes> : Stroke cleaning with S strokes
* P1 Sn T<objects> : Zigzag cleaning with S repeats and T zigzags * P1 Sn T<objects> : Zigzag cleaning with S repeats and T zigzags
* P2 Sn R<radius> : Circle cleaning with S repeats and R radius * P2 Sn R<radius> : Circle cleaning with S repeats and R radius
* X, Y, Z : Specify axes to move during cleaning. Default: ALL.
*/ */
void GcodeSuite::G12() { void GcodeSuite::G12() {
// Don't allow nozzle cleaning without homing first // Don't allow nozzle cleaning without homing first

View File

@@ -67,10 +67,8 @@ void GcodeSuite::M907() {
LOOP_LOGICAL_AXES(i) if (parser.seenval(axis_codes[i])) digipot_i2c.set_current(i, parser.value_float()); LOOP_LOGICAL_AXES(i) if (parser.seenval(axis_codes[i])) digipot_i2c.set_current(i, parser.value_float());
// Additional extruders use B,C,D for channels 4,5,6. // Additional extruders use B,C,D for channels 4,5,6.
// TODO: Change these parameters because 'E' is used. B<index>? // TODO: Change these parameters because 'E' is used. B<index>?
#if HAS_EXTRUDERS for (uint8_t i = E_AXIS + 1; i < DIGIPOT_I2C_NUM_CHANNELS; i++)
for (uint8_t i = E_AXIS + 1; i < DIGIPOT_I2C_NUM_CHANNELS; i++) if (parser.seenval('B' + i - (E_AXIS + 1))) digipot_i2c.set_current(i, parser.value_float());
if (parser.seenval('B' + i - (E_AXIS + 1))) digipot_i2c.set_current(i, parser.value_float());
#endif
#endif #endif
#if ENABLED(HAS_MOTOR_CURRENT_DAC) #if ENABLED(HAS_MOTOR_CURRENT_DAC)

View File

@@ -52,16 +52,14 @@
* M150 I1 R ; Set NEOPIXEL index 1 to red * M150 I1 R ; Set NEOPIXEL index 1 to red
* M150 S1 I1 R ; Set SEPARATE index 1 to red * M150 S1 I1 R ; Set SEPARATE index 1 to red
*/ */
void GcodeSuite::M150() { void GcodeSuite::M150() {
#if ENABLED(NEOPIXEL_LED) #if ENABLED(NEOPIXEL_LED)
const int8_t index = parser.intval('I', -1); const uint8_t index = parser.intval('I', -1);
#if ENABLED(NEOPIXEL2_SEPARATE) #if ENABLED(NEOPIXEL2_SEPARATE)
int8_t brightness, unit = parser.intval('S', -1); const uint8_t unit = parser.intval('S'),
switch (unit) { brightness = unit ? neo2.brightness() : neo.brightness();
case -1: neo2.neoindex = index; // fall-thru *(unit ? &neo2.neoindex : &neo.neoindex) = index;
case 0: neo.neoindex = index; brightness = neo.brightness(); break;
case 1: neo2.neoindex = index; brightness = neo2.brightness(); break;
}
#else #else
const uint8_t brightness = neo.brightness(); const uint8_t brightness = neo.brightness();
neo.neoindex = index; neo.neoindex = index;
@@ -77,15 +75,10 @@ void GcodeSuite::M150() {
); );
#if ENABLED(NEOPIXEL2_SEPARATE) #if ENABLED(NEOPIXEL2_SEPARATE)
switch (unit) { if (unit == 1) { leds2.set_color(color); return; }
case 0: leds.set_color(color); return;
case 1: leds2.set_color(color); return;
}
#endif #endif
// If 'S' is not specified use both
leds.set_color(color); leds.set_color(color);
TERN_(NEOPIXEL2_SEPARATE, leds2.set_color(color));
} }
#endif // HAS_COLOR_LEDS #endif // HAS_COLOR_LEDS

View File

@@ -47,13 +47,12 @@ void GcodeSuite::G60() {
SBI(saved_slots[slot >> 3], slot & 0x07); SBI(saved_slots[slot >> 3], slot & 0x07);
#if ENABLED(SAVED_POSITIONS_DEBUG) #if ENABLED(SAVED_POSITIONS_DEBUG)
DEBUG_ECHOPAIR(STR_SAVED_POS " S", slot);
const xyze_pos_t &pos = stored_position[slot]; const xyze_pos_t &pos = stored_position[slot];
DEBUG_ECHOLNPAIR_F_P( DEBUG_ECHOPAIR(STR_SAVED_POS " S", slot);
LIST_N(DOUBLE(LOGICAL_AXES), SP_E_STR, pos.e, DEBUG_ECHOPAIR_F(" : X", pos.x);
PSTR(" : X"), pos.x, SP_Y_STR, pos.y, SP_Z_STR, pos.z, DEBUG_ECHOPAIR_F_P(SP_Y_STR, pos.y);
SP_I_STR, pos.i, SP_J_STR, pos.j, SP_K_STR, pos.k) DEBUG_ECHOPAIR_F_P(SP_Z_STR, pos.z);
); DEBUG_ECHOLNPAIR_F_P(SP_E_STR, pos.e);
#endif #endif
} }

View File

@@ -37,7 +37,8 @@
* *
* F<rate> - Feedrate (optional) for the move back. * F<rate> - Feedrate (optional) for the move back.
* S<slot> - Slot # (0-based) to restore from (default 0). * S<slot> - Slot # (0-based) to restore from (default 0).
* X Y Z E - Axes to restore. At least one is required. * X Y Z - Axes to restore. At least one is required.
* E - Restore extruder position
* *
* If XYZE are not given, default restore uses the smart blocking move. * If XYZE are not given, default restore uses the smart blocking move.
*/ */
@@ -45,7 +46,7 @@ void GcodeSuite::G61(void) {
const uint8_t slot = parser.byteval('S'); const uint8_t slot = parser.byteval('S');
#define SYNC_E(POINT) TERN_(HAS_EXTRUDERS, planner.set_e_position_mm((destination.e = current_position.e = (POINT)))) #define SYNC_E(POINT) planner.set_e_position_mm((destination.e = current_position.e = (POINT)))
#if SAVED_POSITIONS < 256 #if SAVED_POSITIONS < 256
if (slot >= SAVED_POSITIONS) { if (slot >= SAVED_POSITIONS) {
@@ -68,7 +69,7 @@ void GcodeSuite::G61(void) {
SYNC_E(stored_position[slot].e); SYNC_E(stored_position[slot].e);
} }
else { else {
if (parser.seen(LINEAR_AXIS_GANG("X", "Y", "Z", AXIS4_STR, AXIS5_STR, AXIS6_STR))) { if (parser.seen("XYZ")) {
DEBUG_ECHOPAIR(STR_RESTORING_POS " S", slot); DEBUG_ECHOPAIR(STR_RESTORING_POS " S", slot);
LOOP_LINEAR_AXES(i) { LOOP_LINEAR_AXES(i) {
destination[i] = parser.seen(AXIS_CHAR(i)) destination[i] = parser.seen(AXIS_CHAR(i))
@@ -81,12 +82,10 @@ void GcodeSuite::G61(void) {
// Move to the saved position // Move to the saved position
prepare_line_to_destination(); prepare_line_to_destination();
} }
#if HAS_EXTRUDERS if (parser.seen_test('E')) {
if (parser.seen_test('E')) { DEBUG_ECHOLNPAIR(STR_RESTORING_POS " S", slot, " E", current_position.e, "=>", stored_position[slot].e);
DEBUG_ECHOLNPAIR(STR_RESTORING_POS " S", slot, " E", current_position.e, "=>", stored_position[slot].e); SYNC_E(stored_position[slot].e);
SYNC_E(stored_position[slot].e); }
}
#endif
} }
feedrate_mm_s = saved_feedrate; feedrate_mm_s = saved_feedrate;

View File

@@ -56,7 +56,7 @@
*/ */
void GcodeSuite::M125() { void GcodeSuite::M125() {
// Initial retract before move to filament change position // Initial retract before move to filament change position
const float retract = TERN0(HAS_EXTRUDERS, -ABS(parser.axisunitsval('L', E_AXIS, PAUSE_PARK_RETRACT_LENGTH))); const float retract = -ABS(parser.axisunitsval('L', E_AXIS, PAUSE_PARK_RETRACT_LENGTH));
xyz_pos_t park_point = NOZZLE_PARK_POINT; xyz_pos_t park_point = NOZZLE_PARK_POINT;

View File

@@ -99,7 +99,7 @@ void GcodeSuite::M600() {
#if ENABLED(HOME_BEFORE_FILAMENT_CHANGE) #if ENABLED(HOME_BEFORE_FILAMENT_CHANGE)
// If needed, home before parking for filament change // If needed, home before parking for filament change
home_if_needed(true); if (!all_axes_trusted()) home_all_axes(true);
#endif #endif
#if HAS_MULTI_EXTRUDER #if HAS_MULTI_EXTRUDER

View File

@@ -54,15 +54,10 @@ void GcodeSuite::M412() {
else { else {
SERIAL_ECHO_START(); SERIAL_ECHO_START();
SERIAL_ECHOPGM("Filament runout "); SERIAL_ECHOPGM("Filament runout ");
serialprint_onoff(runout.enabled); serialprintln_onoff(runout.enabled);
#if HAS_FILAMENT_RUNOUT_DISTANCE #if HAS_FILAMENT_RUNOUT_DISTANCE
SERIAL_ECHOPAIR(" ; Distance ", runout.runout_distance(), "mm"); SERIAL_ECHOLNPAIR("Filament runout distance (mm): ", runout.runout_distance());
#endif #endif
#if ENABLED(HOST_ACTION_COMMANDS)
SERIAL_ECHOPGM(" ; Host handling ");
serialprint_onoff(runout.host_handling);
#endif
SERIAL_EOL();
} }
} }

View File

@@ -35,7 +35,7 @@ void GcodeSuite::M122() {
xyze_bool_t print_axis = ARRAY_N_1(LOGICAL_AXES, false); xyze_bool_t print_axis = ARRAY_N_1(LOGICAL_AXES, false);
bool print_all = true; bool print_all = true;
LOOP_LOGICAL_AXES(i) if (parser.seen_test(axis_codes[i])) { print_axis[i] = true; print_all = false; } LOOP_LOGICAL_AXES(i) if (parser.seen(axis_codes[i])) { print_axis[i] = true; print_all = false; }
if (print_all) LOOP_LOGICAL_AXES(i) print_axis[i] = true; if (print_all) LOOP_LOGICAL_AXES(i) print_axis[i] = true;
@@ -50,12 +50,12 @@ void GcodeSuite::M122() {
#endif #endif
if (parser.seen_test('V')) if (parser.seen_test('V'))
tmc_get_registers(LOGICAL_AXIS_ELEM(print_axis)); tmc_get_registers(print_axis.x, print_axis.y, print_axis.z, print_axis.e);
else else
tmc_report_all(LOGICAL_AXIS_ELEM(print_axis)); tmc_report_all(print_axis.x, print_axis.y, print_axis.z, print_axis.e);
#endif #endif
test_tmc_connection(LOGICAL_AXIS_ELEM(print_axis)); test_tmc_connection(print_axis.x, print_axis.y, print_axis.z, print_axis.e);
} }
#endif // HAS_TRINAMIC_CONFIG #endif // HAS_TRINAMIC_CONFIG

View File

@@ -40,88 +40,132 @@ void tmc_set_stealthChop(TMC &st, const bool enable) {
st.refresh_stepping_mode(); st.refresh_stepping_mode();
} }
static void set_stealth_status(const bool enable, const int8_t target_e_stepper) { static void set_stealth_status(const bool enable, const int8_t target_extruder) {
#define TMC_SET_STEALTH(Q) tmc_set_stealthChop(stepper##Q, enable) #define TMC_SET_STEALTH(Q) tmc_set_stealthChop(stepper##Q, enable)
#if X_HAS_STEALTHCHOP || Y_HAS_STEALTHCHOP || Z_HAS_STEALTHCHOP \ #if AXIS_HAS_STEALTHCHOP(X) || AXIS_HAS_STEALTHCHOP(X2) \
|| I_HAS_STEALTHCHOP || J_HAS_STEALTHCHOP || K_HAS_STEALTHCHOP \ || AXIS_HAS_STEALTHCHOP(Y) || AXIS_HAS_STEALTHCHOP(Y2) \
|| X2_HAS_STEALTHCHOP || Y2_HAS_STEALTHCHOP || Z2_HAS_STEALTHCHOP || Z3_HAS_STEALTHCHOP || Z4_HAS_STEALTHCHOP || AXIS_HAS_STEALTHCHOP(Z) || AXIS_HAS_STEALTHCHOP(Z2) \
|| AXIS_HAS_STEALTHCHOP(Z3) || AXIS_HAS_STEALTHCHOP(Z4)
const uint8_t index = parser.byteval('I'); const uint8_t index = parser.byteval('I');
#endif #endif
LOOP_LOGICAL_AXES(i) if (parser.seen(axis_codes[i])) { LOOP_LOGICAL_AXES(i) if (parser.seen(axis_codes[i])) {
switch (i) { switch (i) {
case X_AXIS: case X_AXIS:
TERN_(X_HAS_STEALTHCHOP, if (index == 0) TMC_SET_STEALTH(X)); #if AXIS_HAS_STEALTHCHOP(X)
TERN_(X2_HAS_STEALTHCHOP, if (index == 1) TMC_SET_STEALTH(X2)); if (index == 0) TMC_SET_STEALTH(X);
#endif
#if AXIS_HAS_STEALTHCHOP(X2)
if (index == 1) TMC_SET_STEALTH(X2);
#endif
break; break;
case Y_AXIS:
#if HAS_Y_AXIS #if AXIS_HAS_STEALTHCHOP(Y)
case Y_AXIS: if (index == 0) TMC_SET_STEALTH(Y);
TERN_(Y_HAS_STEALTHCHOP, if (index == 0) TMC_SET_STEALTH(Y)); #endif
TERN_(Y2_HAS_STEALTHCHOP, if (index == 1) TMC_SET_STEALTH(Y2)); #if AXIS_HAS_STEALTHCHOP(Y2)
break; if (index == 1) TMC_SET_STEALTH(Y2);
#endif #endif
break;
#if HAS_Z_AXIS case Z_AXIS:
case Z_AXIS: #if AXIS_HAS_STEALTHCHOP(Z)
TERN_(Z_HAS_STEALTHCHOP, if (index == 0) TMC_SET_STEALTH(Z)); if (index == 0) TMC_SET_STEALTH(Z);
TERN_(Z2_HAS_STEALTHCHOP, if (index == 1) TMC_SET_STEALTH(Z2)); #endif
TERN_(Z3_HAS_STEALTHCHOP, if (index == 2) TMC_SET_STEALTH(Z3)); #if AXIS_HAS_STEALTHCHOP(Z2)
TERN_(Z4_HAS_STEALTHCHOP, if (index == 3) TMC_SET_STEALTH(Z4)); if (index == 1) TMC_SET_STEALTH(Z2);
break; #endif
#endif #if AXIS_HAS_STEALTHCHOP(Z3)
if (index == 2) TMC_SET_STEALTH(Z3);
#if I_HAS_STEALTHCHOP #endif
case I_AXIS: TMC_SET_STEALTH(I); break; #if AXIS_HAS_STEALTHCHOP(Z4)
#endif if (index == 3) TMC_SET_STEALTH(Z4);
#if J_HAS_STEALTHCHOP #endif
case J_AXIS: TMC_SET_STEALTH(J); break; break;
#endif case E_AXIS: {
#if K_HAS_STEALTHCHOP if (target_extruder < 0) return;
case K_AXIS: TMC_SET_STEALTH(K); break; switch (target_extruder) {
#endif #if AXIS_HAS_STEALTHCHOP(E0)
case 0: TMC_SET_STEALTH(E0); break;
#if E_STEPPERS #endif
case E_AXIS: { #if AXIS_HAS_STEALTHCHOP(E1)
if (target_e_stepper < 0) return; case 1: TMC_SET_STEALTH(E1); break;
switch (target_e_stepper) { #endif
TERN_(E0_HAS_STEALTHCHOP, case 0: TMC_SET_STEALTH(E0); break;) #if AXIS_HAS_STEALTHCHOP(E2)
TERN_(E1_HAS_STEALTHCHOP, case 1: TMC_SET_STEALTH(E1); break;) case 2: TMC_SET_STEALTH(E2); break;
TERN_(E2_HAS_STEALTHCHOP, case 2: TMC_SET_STEALTH(E2); break;) #endif
TERN_(E3_HAS_STEALTHCHOP, case 3: TMC_SET_STEALTH(E3); break;) #if AXIS_HAS_STEALTHCHOP(E3)
TERN_(E4_HAS_STEALTHCHOP, case 4: TMC_SET_STEALTH(E4); break;) case 3: TMC_SET_STEALTH(E3); break;
TERN_(E5_HAS_STEALTHCHOP, case 5: TMC_SET_STEALTH(E5); break;) #endif
TERN_(E6_HAS_STEALTHCHOP, case 6: TMC_SET_STEALTH(E6); break;) #if AXIS_HAS_STEALTHCHOP(E4)
TERN_(E7_HAS_STEALTHCHOP, case 7: TMC_SET_STEALTH(E7); break;) case 4: TMC_SET_STEALTH(E4); break;
} #endif
} break; #if AXIS_HAS_STEALTHCHOP(E5)
#endif case 5: TMC_SET_STEALTH(E5); break;
#endif
#if AXIS_HAS_STEALTHCHOP(E6)
case 6: TMC_SET_STEALTH(E6); break;
#endif
#if AXIS_HAS_STEALTHCHOP(E7)
case 7: TMC_SET_STEALTH(E7); break;
#endif
}
} break;
} }
} }
} }
static void say_stealth_status() { static void say_stealth_status() {
#define TMC_SAY_STEALTH_STATUS(Q) tmc_say_stealth_status(stepper##Q) #define TMC_SAY_STEALTH_STATUS(Q) tmc_say_stealth_status(stepper##Q)
OPTCODE( X_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(X))
OPTCODE(X2_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(X2)) #if AXIS_HAS_STEALTHCHOP(X)
OPTCODE( Y_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(Y)) TMC_SAY_STEALTH_STATUS(X);
OPTCODE(Y2_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(Y2)) #endif
OPTCODE( Z_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(Z)) #if AXIS_HAS_STEALTHCHOP(X2)
OPTCODE(Z2_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(Z2)) TMC_SAY_STEALTH_STATUS(X2);
OPTCODE(Z3_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(Z3)) #endif
OPTCODE(Z4_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(Z4)) #if AXIS_HAS_STEALTHCHOP(Y)
OPTCODE( I_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(I)) TMC_SAY_STEALTH_STATUS(Y);
OPTCODE( J_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(J)) #endif
OPTCODE( K_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(K)) #if AXIS_HAS_STEALTHCHOP(Y2)
OPTCODE(E0_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(E0)) TMC_SAY_STEALTH_STATUS(Y2);
OPTCODE(E1_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(E1)) #endif
OPTCODE(E2_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(E2)) #if AXIS_HAS_STEALTHCHOP(Z)
OPTCODE(E3_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(E3)) TMC_SAY_STEALTH_STATUS(Z);
OPTCODE(E4_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(E4)) #endif
OPTCODE(E5_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(E5)) #if AXIS_HAS_STEALTHCHOP(Z2)
OPTCODE(E6_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(E6)) TMC_SAY_STEALTH_STATUS(Z2);
OPTCODE(E7_HAS_STEALTHCHOP, TMC_SAY_STEALTH_STATUS(E7)) #endif
#if AXIS_HAS_STEALTHCHOP(Z3)
TMC_SAY_STEALTH_STATUS(Z3);
#endif
#if AXIS_HAS_STEALTHCHOP(Z4)
TMC_SAY_STEALTH_STATUS(Z4);
#endif
#if AXIS_HAS_STEALTHCHOP(E0)
TMC_SAY_STEALTH_STATUS(E0);
#endif
#if AXIS_HAS_STEALTHCHOP(E1)
TMC_SAY_STEALTH_STATUS(E1);
#endif
#if AXIS_HAS_STEALTHCHOP(E2)
TMC_SAY_STEALTH_STATUS(E2);
#endif
#if AXIS_HAS_STEALTHCHOP(E3)
TMC_SAY_STEALTH_STATUS(E3);
#endif
#if AXIS_HAS_STEALTHCHOP(E4)
TMC_SAY_STEALTH_STATUS(E4);
#endif
#if AXIS_HAS_STEALTHCHOP(E5)
TMC_SAY_STEALTH_STATUS(E5);
#endif
#if AXIS_HAS_STEALTHCHOP(E6)
TMC_SAY_STEALTH_STATUS(E6);
#endif
#if AXIS_HAS_STEALTHCHOP(E7)
TMC_SAY_STEALTH_STATUS(E7);
#endif
} }
/** /**
@@ -133,7 +177,7 @@ static void say_stealth_status() {
*/ */
void GcodeSuite::M569() { void GcodeSuite::M569() {
if (parser.seen('S')) if (parser.seen('S'))
set_stealth_status(parser.value_bool(), get_target_e_stepper_from_command()); set_stealth_status(parser.value_bool(), get_target_extruder_from_command());
else else
say_stealth_status(); say_stealth_status();
} }

View File

@@ -48,7 +48,7 @@ void GcodeSuite::M906() {
bool report = true; bool report = true;
#if AXIS_IS_TMC(X) || AXIS_IS_TMC(X2) || AXIS_IS_TMC(Y) || AXIS_IS_TMC(Y2) || AXIS_IS_TMC(Z) || AXIS_IS_TMC(Z2) || AXIS_IS_TMC(Z3) || AXIS_IS_TMC(Z4) || AXIS_IS_TMC(I) || AXIS_IS_TMC(J) || AXIS_IS_TMC(K) #if AXIS_IS_TMC(X) || AXIS_IS_TMC(X2) || AXIS_IS_TMC(Y) || AXIS_IS_TMC(Y2) || AXIS_IS_TMC(Z) || AXIS_IS_TMC(Z2) || AXIS_IS_TMC(Z3) || AXIS_IS_TMC(Z4)
const uint8_t index = parser.byteval('I'); const uint8_t index = parser.byteval('I');
#endif #endif
@@ -63,77 +63,58 @@ void GcodeSuite::M906() {
if (index == 1) TMC_SET_CURRENT(X2); if (index == 1) TMC_SET_CURRENT(X2);
#endif #endif
break; break;
case Y_AXIS:
#if HAS_Y_AXIS #if AXIS_IS_TMC(Y)
case Y_AXIS: if (index == 0) TMC_SET_CURRENT(Y);
#if AXIS_IS_TMC(Y) #endif
if (index == 0) TMC_SET_CURRENT(Y); #if AXIS_IS_TMC(Y2)
if (index == 1) TMC_SET_CURRENT(Y2);
#endif
break;
case Z_AXIS:
#if AXIS_IS_TMC(Z)
if (index == 0) TMC_SET_CURRENT(Z);
#endif
#if AXIS_IS_TMC(Z2)
if (index == 1) TMC_SET_CURRENT(Z2);
#endif
#if AXIS_IS_TMC(Z3)
if (index == 2) TMC_SET_CURRENT(Z3);
#endif
#if AXIS_IS_TMC(Z4)
if (index == 3) TMC_SET_CURRENT(Z4);
#endif
break;
case E_AXIS: {
const int8_t target_extruder = get_target_extruder_from_command();
if (target_extruder < 0) return;
switch (target_extruder) {
#if AXIS_IS_TMC(E0)
case 0: TMC_SET_CURRENT(E0); break;
#endif #endif
#if AXIS_IS_TMC(Y2) #if AXIS_IS_TMC(E1)
if (index == 1) TMC_SET_CURRENT(Y2); case 1: TMC_SET_CURRENT(E1); break;
#endif #endif
break; #if AXIS_IS_TMC(E2)
#endif case 2: TMC_SET_CURRENT(E2); break;
#if HAS_Z_AXIS
case Z_AXIS:
#if AXIS_IS_TMC(Z)
if (index == 0) TMC_SET_CURRENT(Z);
#endif #endif
#if AXIS_IS_TMC(Z2) #if AXIS_IS_TMC(E3)
if (index == 1) TMC_SET_CURRENT(Z2); case 3: TMC_SET_CURRENT(E3); break;
#endif #endif
#if AXIS_IS_TMC(Z3) #if AXIS_IS_TMC(E4)
if (index == 2) TMC_SET_CURRENT(Z3); case 4: TMC_SET_CURRENT(E4); break;
#endif #endif
#if AXIS_IS_TMC(Z4) #if AXIS_IS_TMC(E5)
if (index == 3) TMC_SET_CURRENT(Z4); case 5: TMC_SET_CURRENT(E5); break;
#endif #endif
break; #if AXIS_IS_TMC(E6)
#endif case 6: TMC_SET_CURRENT(E6); break;
#endif
#if AXIS_IS_TMC(I) #if AXIS_IS_TMC(E7)
case I_AXIS: TMC_SET_CURRENT(I); break; case 7: TMC_SET_CURRENT(E7); break;
#endif #endif
#if AXIS_IS_TMC(J) }
case J_AXIS: TMC_SET_CURRENT(J); break; } break;
#endif
#if AXIS_IS_TMC(K)
case K_AXIS: TMC_SET_CURRENT(K); break;
#endif
#if E_STEPPERS
case E_AXIS: {
const int8_t target_e_stepper = get_target_e_stepper_from_command();
if (target_e_stepper < 0) return;
switch (target_e_stepper) {
#if AXIS_IS_TMC(E0)
case 0: TMC_SET_CURRENT(E0); break;
#endif
#if AXIS_IS_TMC(E1)
case 1: TMC_SET_CURRENT(E1); break;
#endif
#if AXIS_IS_TMC(E2)
case 2: TMC_SET_CURRENT(E2); break;
#endif
#if AXIS_IS_TMC(E3)
case 3: TMC_SET_CURRENT(E3); break;
#endif
#if AXIS_IS_TMC(E4)
case 4: TMC_SET_CURRENT(E4); break;
#endif
#if AXIS_IS_TMC(E5)
case 5: TMC_SET_CURRENT(E5); break;
#endif
#if AXIS_IS_TMC(E6)
case 6: TMC_SET_CURRENT(E6); break;
#endif
#if AXIS_IS_TMC(E7)
case 7: TMC_SET_CURRENT(E7); break;
#endif
}
} break;
#endif
} }
} }
@@ -162,15 +143,6 @@ void GcodeSuite::M906() {
#if AXIS_IS_TMC(Z4) #if AXIS_IS_TMC(Z4)
TMC_SAY_CURRENT(Z4); TMC_SAY_CURRENT(Z4);
#endif #endif
#if AXIS_IS_TMC(I)
TMC_SAY_CURRENT(I);
#endif
#if AXIS_IS_TMC(J)
TMC_SAY_CURRENT(J);
#endif
#if AXIS_IS_TMC(K)
TMC_SAY_CURRENT(K);
#endif
#if AXIS_IS_TMC(E0) #if AXIS_IS_TMC(E0)
TMC_SAY_CURRENT(E0); TMC_SAY_CURRENT(E0);
#endif #endif

View File

@@ -38,27 +38,18 @@
#if M91x_USE(X) || M91x_USE(X2) #if M91x_USE(X) || M91x_USE(X2)
#define M91x_SOME_X 1 #define M91x_SOME_X 1
#endif #endif
#if LINEAR_AXES >= 2 && (M91x_USE(Y) || M91x_USE(Y2)) #if M91x_USE(Y) || M91x_USE(Y2)
#define M91x_SOME_Y 1 #define M91x_SOME_Y 1
#endif #endif
#if HAS_Z_AXIS && (M91x_USE(Z) || M91x_USE(Z2) || M91x_USE(Z3) || M91x_USE(Z4)) #if M91x_USE(Z) || M91x_USE(Z2) || M91x_USE(Z3) || M91x_USE(Z4)
#define M91x_SOME_Z 1 #define M91x_SOME_Z 1
#endif #endif
#if LINEAR_AXES >= 4 && M91x_USE(I)
#define M91x_USE_I 1
#endif
#if LINEAR_AXES >= 5 && M91x_USE(J)
#define M91x_USE_J 1
#endif
#if LINEAR_AXES >= 6 && M91x_USE(K)
#define M91x_USE_K 1
#endif
#if M91x_USE_E(0) || M91x_USE_E(1) || M91x_USE_E(2) || M91x_USE_E(3) || M91x_USE_E(4) || M91x_USE_E(5) || M91x_USE_E(6) || M91x_USE_E(7) #if M91x_USE_E(0) || M91x_USE_E(1) || M91x_USE_E(2) || M91x_USE_E(3) || M91x_USE_E(4) || M91x_USE_E(5) || M91x_USE_E(6) || M91x_USE_E(7)
#define M91x_SOME_E 1 #define M91x_SOME_E 1
#endif #endif
#if !M91x_SOME_X && !M91x_SOME_Y && !M91x_SOME_Z && !M91x_USE_I && !M91x_USE_J && !M91x_USE_K && !M91x_SOME_E #if !M91x_SOME_X && !M91x_SOME_Y && !M91x_SOME_Z && !M91x_SOME_E
#error "MONITOR_DRIVER_STATUS requires at least one TMC2130, 2160, 2208, 2209, 2660, 5130, or 5160." #error "MONITOR_DRIVER_STATUS requires at least one TMC2130, 2160, 2208, 2209, 2660, 5130, or 5160."
#endif #endif
@@ -91,9 +82,6 @@
#if M91x_USE(Z4) #if M91x_USE(Z4)
tmc_report_otpw(stepperZ4); tmc_report_otpw(stepperZ4);
#endif #endif
TERN_(M91x_USE_I, tmc_report_otpw(stepperI));
TERN_(M91x_USE_J, tmc_report_otpw(stepperJ));
TERN_(M91x_USE_K, tmc_report_otpw(stepperK));
#if M91x_USE_E(0) #if M91x_USE_E(0)
tmc_report_otpw(stepperE0); tmc_report_otpw(stepperE0);
#endif #endif
@@ -136,12 +124,9 @@
const bool hasX = TERN0(M91x_SOME_X, parser.seen(axis_codes.x)), const bool hasX = TERN0(M91x_SOME_X, parser.seen(axis_codes.x)),
hasY = TERN0(M91x_SOME_Y, parser.seen(axis_codes.y)), hasY = TERN0(M91x_SOME_Y, parser.seen(axis_codes.y)),
hasZ = TERN0(M91x_SOME_Z, parser.seen(axis_codes.z)), hasZ = TERN0(M91x_SOME_Z, parser.seen(axis_codes.z)),
hasI = TERN0(M91x_USE_I, parser.seen(axis_codes.i)),
hasJ = TERN0(M91x_USE_J, parser.seen(axis_codes.j)),
hasK = TERN0(M91x_USE_K, parser.seen(axis_codes.k)),
hasE = TERN0(M91x_SOME_E, parser.seen(axis_codes.e)); hasE = TERN0(M91x_SOME_E, parser.seen(axis_codes.e));
const bool hasNone = !hasE && !hasX && !hasY && !hasZ && !hasI && !hasJ && !hasK; const bool hasNone = !hasE && !hasX && !hasY && !hasZ;
#if M91x_SOME_X #if M91x_SOME_X
const int8_t xval = int8_t(parser.byteval(axis_codes.x, 0xFF)); const int8_t xval = int8_t(parser.byteval(axis_codes.x, 0xFF));
@@ -179,19 +164,6 @@
#endif #endif
#endif #endif
#if M91x_USE_I
const int8_t ival = int8_t(parser.byteval(axis_codes.i, 0xFF));
if (hasNone || ival == 1 || (hasI && ival < 0)) tmc_clear_otpw(stepperI);
#endif
#if M91x_USE_J
const int8_t jval = int8_t(parser.byteval(axis_codes.j, 0xFF));
if (hasNone || jval == 1 || (hasJ && jval < 0)) tmc_clear_otpw(stepperJ);
#endif
#if M91x_USE_K
const int8_t kval = int8_t(parser.byteval(axis_codes.k, 0xFF));
if (hasNone || kval == 1 || (hasK && kval < 0)) tmc_clear_otpw(stepperK);
#endif
#if M91x_SOME_E #if M91x_SOME_E
const int8_t eval = int8_t(parser.byteval(axis_codes.e, 0xFF)); const int8_t eval = int8_t(parser.byteval(axis_codes.e, 0xFF));
#if M91x_USE_E(0) #if M91x_USE_E(0)
@@ -234,78 +206,126 @@
#define TMC_SET_PWMTHRS_E(E) stepperE##E.set_pwm_thrs(value) #define TMC_SET_PWMTHRS_E(E) stepperE##E.set_pwm_thrs(value)
bool report = true; bool report = true;
#if AXIS_IS_TMC(X) || AXIS_IS_TMC(X2) || AXIS_IS_TMC(Y) || AXIS_IS_TMC(Y2) || AXIS_IS_TMC(Z) || AXIS_IS_TMC(Z2) || AXIS_IS_TMC(Z3) || AXIS_IS_TMC(Z4) || AXIS_IS_TMC(I) || AXIS_IS_TMC(J) || AXIS_IS_TMC(K) #if AXIS_IS_TMC(X) || AXIS_IS_TMC(X2) || AXIS_IS_TMC(Y) || AXIS_IS_TMC(Y2) || AXIS_IS_TMC(Z) || AXIS_IS_TMC(Z2) || AXIS_IS_TMC(Z3) || AXIS_IS_TMC(Z4)
const uint8_t index = parser.byteval('I'); const uint8_t index = parser.byteval('I');
#endif #endif
LOOP_LOGICAL_AXES(i) if (int32_t value = parser.longval(axis_codes[i])) { LOOP_LOGICAL_AXES(i) if (int32_t value = parser.longval(axis_codes[i])) {
report = false; report = false;
switch (i) { switch (i) {
case X_AXIS: case X_AXIS:
TERN_(X_HAS_STEALTHCHOP, if (index < 2) TMC_SET_PWMTHRS(X,X)); #if AXIS_HAS_STEALTHCHOP(X)
TERN_(X2_HAS_STEALTHCHOP, if (!(index & 1)) TMC_SET_PWMTHRS(X,X2)); if (index < 2) TMC_SET_PWMTHRS(X,X);
#endif
#if AXIS_HAS_STEALTHCHOP(X2)
if (!(index & 1)) TMC_SET_PWMTHRS(X,X2);
#endif
break; break;
case Y_AXIS: case Y_AXIS:
TERN_(Y_HAS_STEALTHCHOP, if (index < 2) TMC_SET_PWMTHRS(Y,Y)); #if AXIS_HAS_STEALTHCHOP(Y)
TERN_(Y2_HAS_STEALTHCHOP, if (!(index & 1)) TMC_SET_PWMTHRS(Y,Y2)); if (index < 2) TMC_SET_PWMTHRS(Y,Y);
#endif
#if AXIS_HAS_STEALTHCHOP(Y2)
if (!(index & 1)) TMC_SET_PWMTHRS(Y,Y2);
#endif
break; break;
#if I_HAS_STEALTHCHOP
case I_AXIS: TMC_SET_PWMTHRS(I,I); break;
#endif
#if J_HAS_STEALTHCHOP
case J_AXIS: TMC_SET_PWMTHRS(J,J); break;
#endif
#if K_HAS_STEALTHCHOP
case K_AXIS: TMC_SET_PWMTHRS(K,K); break;
#endif
case Z_AXIS: case Z_AXIS:
TERN_(Z_HAS_STEALTCHOP, if (index < 2) TMC_SET_PWMTHRS(Z,Z)); #if AXIS_HAS_STEALTHCHOP(Z)
TERN_(Z2_HAS_STEALTCHOP, if (index == 0 || index == 2) TMC_SET_PWMTHRS(Z,Z2)); if (index < 2) TMC_SET_PWMTHRS(Z,Z);
TERN_(Z3_HAS_STEALTCHOP, if (index == 0 || index == 3) TMC_SET_PWMTHRS(Z,Z3)); #endif
TERN_(Z4_HAS_STEALTCHOP, if (index == 0 || index == 4) TMC_SET_PWMTHRS(Z,Z4)); #if AXIS_HAS_STEALTHCHOP(Z2)
if (index == 0 || index == 2) TMC_SET_PWMTHRS(Z,Z2);
#endif
#if AXIS_HAS_STEALTHCHOP(Z3)
if (index == 0 || index == 3) TMC_SET_PWMTHRS(Z,Z3);
#endif
#if AXIS_HAS_STEALTHCHOP(Z4)
if (index == 0 || index == 4) TMC_SET_PWMTHRS(Z,Z4);
#endif
break; break;
#if E_STEPPERS case E_AXIS: {
case E_AXIS: { #if E_STEPPERS
const int8_t target_e_stepper = get_target_e_stepper_from_command(); const int8_t target_extruder = get_target_extruder_from_command();
if (target_e_stepper < 0) return; if (target_extruder < 0) return;
switch (target_e_stepper) { switch (target_extruder) {
TERN_(E0_HAS_STEALTHCHOP, case 0: TMC_SET_PWMTHRS_E(0); break;) #if AXIS_HAS_STEALTHCHOP(E0)
TERN_(E1_HAS_STEALTHCHOP, case 1: TMC_SET_PWMTHRS_E(1); break;) case 0: TMC_SET_PWMTHRS_E(0); break;
TERN_(E2_HAS_STEALTHCHOP, case 2: TMC_SET_PWMTHRS_E(2); break;) #endif
TERN_(E3_HAS_STEALTHCHOP, case 3: TMC_SET_PWMTHRS_E(3); break;) #if E_STEPPERS > 1 && AXIS_HAS_STEALTHCHOP(E1)
TERN_(E4_HAS_STEALTHCHOP, case 4: TMC_SET_PWMTHRS_E(4); break;) case 1: TMC_SET_PWMTHRS_E(1); break;
TERN_(E5_HAS_STEALTHCHOP, case 5: TMC_SET_PWMTHRS_E(5); break;) #endif
TERN_(E6_HAS_STEALTHCHOP, case 6: TMC_SET_PWMTHRS_E(6); break;) #if E_STEPPERS > 2 && AXIS_HAS_STEALTHCHOP(E2)
TERN_(E7_HAS_STEALTHCHOP, case 7: TMC_SET_PWMTHRS_E(7); break;) case 2: TMC_SET_PWMTHRS_E(2); break;
#endif
#if E_STEPPERS > 3 && AXIS_HAS_STEALTHCHOP(E3)
case 3: TMC_SET_PWMTHRS_E(3); break;
#endif
#if E_STEPPERS > 4 && AXIS_HAS_STEALTHCHOP(E4)
case 4: TMC_SET_PWMTHRS_E(4); break;
#endif
#if E_STEPPERS > 5 && AXIS_HAS_STEALTHCHOP(E5)
case 5: TMC_SET_PWMTHRS_E(5); break;
#endif
#if E_STEPPERS > 6 && AXIS_HAS_STEALTHCHOP(E6)
case 6: TMC_SET_PWMTHRS_E(6); break;
#endif
#if E_STEPPERS > 7 && AXIS_HAS_STEALTHCHOP(E7)
case 7: TMC_SET_PWMTHRS_E(7); break;
#endif
} }
} break; #endif // E_STEPPERS
#endif // E_STEPPERS } break;
} }
} }
if (report) { if (report) {
TERN_( X_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS(X,X)); #if AXIS_HAS_STEALTHCHOP(X)
TERN_(X2_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS(X,X2)); TMC_SAY_PWMTHRS(X,X);
TERN_( Y_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS(Y,Y)); #endif
TERN_(Y2_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS(Y,Y2)); #if AXIS_HAS_STEALTHCHOP(X2)
TERN_( Z_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS(Z,Z)); TMC_SAY_PWMTHRS(X,X2);
TERN_(Z2_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS(Z,Z2)); #endif
TERN_(Z3_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS(Z,Z3)); #if AXIS_HAS_STEALTHCHOP(Y)
TERN_(Z4_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS(Z,Z4)); TMC_SAY_PWMTHRS(Y,Y);
#endif
TERN_( I_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS(I,I)); #if AXIS_HAS_STEALTHCHOP(Y2)
TERN_( J_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS(J,J)); TMC_SAY_PWMTHRS(Y,Y2);
TERN_( K_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS(K,K)); #endif
#if AXIS_HAS_STEALTHCHOP(Z)
TERN_(E0_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS_E(0)); TMC_SAY_PWMTHRS(Z,Z);
TERN_(E1_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS_E(1)); #endif
TERN_(E2_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS_E(2)); #if AXIS_HAS_STEALTHCHOP(Z2)
TERN_(E3_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS_E(3)); TMC_SAY_PWMTHRS(Z,Z2);
TERN_(E4_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS_E(4)); #endif
TERN_(E5_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS_E(5)); #if AXIS_HAS_STEALTHCHOP(Z3)
TERN_(E6_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS_E(6)); TMC_SAY_PWMTHRS(Z,Z3);
TERN_(E7_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS_E(7)); #endif
#if AXIS_HAS_STEALTHCHOP(Z4)
TMC_SAY_PWMTHRS(Z,Z4);
#endif
#if E_STEPPERS && AXIS_HAS_STEALTHCHOP(E0)
TMC_SAY_PWMTHRS_E(0);
#endif
#if E_STEPPERS > 1 && AXIS_HAS_STEALTHCHOP(E1)
TMC_SAY_PWMTHRS_E(1);
#endif
#if E_STEPPERS > 2 && AXIS_HAS_STEALTHCHOP(E2)
TMC_SAY_PWMTHRS_E(2);
#endif
#if E_STEPPERS > 3 && AXIS_HAS_STEALTHCHOP(E3)
TMC_SAY_PWMTHRS_E(3);
#endif
#if E_STEPPERS > 4 && AXIS_HAS_STEALTHCHOP(E4)
TMC_SAY_PWMTHRS_E(4);
#endif
#if E_STEPPERS > 5 && AXIS_HAS_STEALTHCHOP(E5)
TMC_SAY_PWMTHRS_E(5);
#endif
#if E_STEPPERS > 6 && AXIS_HAS_STEALTHCHOP(E6)
TMC_SAY_PWMTHRS_E(6);
#endif
#if E_STEPPERS > 7 && AXIS_HAS_STEALTHCHOP(E7)
TMC_SAY_PWMTHRS_E(7);
#endif
} }
} }
#endif // HYBRID_THRESHOLD #endif // HYBRID_THRESHOLD
@@ -358,15 +378,6 @@
#endif #endif
break; break;
#endif #endif
#if I_SENSORLESS && AXIS_HAS_STALLGUARD(I)
case I_AXIS: stepperI.homing_threshold(value); break;
#endif
#if J_SENSORLESS && AXIS_HAS_STALLGUARD(J)
case J_AXIS: stepperJ.homing_threshold(value); break;
#endif
#if K_SENSORLESS && AXIS_HAS_STALLGUARD(K)
case K_AXIS: stepperK.homing_threshold(value); break;
#endif
} }
} }
@@ -401,15 +412,6 @@
tmc_print_sgt(stepperZ4); tmc_print_sgt(stepperZ4);
#endif #endif
#endif #endif
#if I_SENSORLESS && AXIS_HAS_STALLGUARD(I)
tmc_print_sgt(stepperI);
#endif
#if J_SENSORLESS && AXIS_HAS_STALLGUARD(J)
tmc_print_sgt(stepperJ);
#endif
#if K_SENSORLESS && AXIS_HAS_STALLGUARD(K)
tmc_print_sgt(stepperK);
#endif
} }
} }
#endif // USE_SENSORLESS #endif // USE_SENSORLESS

View File

@@ -74,14 +74,11 @@ millis_t GcodeSuite::previous_move_ms = 0,
// Relative motion mode for each logical axis // Relative motion mode for each logical axis
static constexpr xyze_bool_t ar_init = AXIS_RELATIVE_MODES; static constexpr xyze_bool_t ar_init = AXIS_RELATIVE_MODES;
uint8_t GcodeSuite::axis_relative = 0 LOGICAL_AXIS_GANG( uint8_t GcodeSuite::axis_relative = (
| (ar_init.e << REL_E), (ar_init.x ? _BV(REL_X) : 0)
| (ar_init.x << REL_X), | (ar_init.y ? _BV(REL_Y) : 0)
| (ar_init.y << REL_Y), | (ar_init.z ? _BV(REL_Z) : 0)
| (ar_init.z << REL_Z), | (ar_init.e ? _BV(REL_E) : 0)
| (ar_init.i << REL_I),
| (ar_init.j << REL_J),
| (ar_init.k << REL_K)
); );
#if EITHER(HAS_AUTO_REPORTING, HOST_KEEPALIVE_FEATURE) #if EITHER(HAS_AUTO_REPORTING, HOST_KEEPALIVE_FEATURE)
@@ -164,15 +161,13 @@ void GcodeSuite::get_destination_from_command() {
destination[i] = current_position[i]; destination[i] = current_position[i];
} }
#if HAS_EXTRUDERS // Get new E position, whether absolute or relative
// Get new E position, whether absolute or relative if ( (seen.e = parser.seenval('E')) ) {
if ( (seen.e = parser.seenval('E')) ) { const float v = parser.value_axis_units(E_AXIS);
const float v = parser.value_axis_units(E_AXIS); destination.e = axis_is_relative(E_AXIS) ? current_position.e + v : v;
destination.e = axis_is_relative(E_AXIS) ? current_position.e + v : v; }
} else
else destination.e = current_position.e;
destination.e = current_position.e;
#endif
#if ENABLED(POWER_LOSS_RECOVERY) && !PIN_EXISTS(POWER_LOSS) #if ENABLED(POWER_LOSS_RECOVERY) && !PIN_EXISTS(POWER_LOSS)
// Only update power loss recovery on moves with E // Only update power loss recovery on moves with E
@@ -441,23 +436,20 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 3: M3_M4(false); break; // M3: Turn ON Laser | Spindle (clockwise), set Power | Speed case 3: M3_M4(false); break; // M3: Turn ON Laser | Spindle (clockwise), set Power | Speed
case 4: M3_M4(true ); break; // M4: Turn ON Laser | Spindle (counter-clockwise), set Power | Speed case 4: M3_M4(true ); break; // M4: Turn ON Laser | Spindle (counter-clockwise), set Power | Speed
case 5: M5(); break; // M5: Turn OFF Laser | Spindle case 5: M5(); break; // M5: Turn OFF Laser | Spindle
#if ENABLED(AIR_EVACUATION)
case 10: M10(); break; // M10: Vacuum or Blower motor ON
case 11: M11(); break; // M11: Vacuum or Blower motor OFF
#endif
#endif #endif
#if ENABLED(COOLANT_MIST) #if ENABLED(COOLANT_CONTROL)
case 7: M7(); break; // M7: Coolant Mist ON #if ENABLED(COOLANT_MIST)
#endif case 7: M7(); break; // M7: Mist coolant ON
#endif
#if EITHER(AIR_ASSIST, COOLANT_FLOOD) #if ENABLED(COOLANT_FLOOD)
case 8: M8(); break; // M8: Air Assist / Coolant Flood ON case 8: M8(); break; // M8: Flood coolant ON
#endif #endif
case 9: M9(); break; // M9: Coolant OFF
#if EITHER(AIR_ASSIST, COOLANT_CONTROL)
case 9: M9(); break; // M9: Air Assist / Coolant OFF
#endif
#if ENABLED(AIR_EVACUATION)
case 10: M10(); break; // M10: Vacuum or Blower motor ON
case 11: M11(); break; // M11: Vacuum or Blower motor OFF
#endif #endif
#if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER) #if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER)

View File

@@ -314,12 +314,7 @@
#define HAS_FAST_MOVES 1 #define HAS_FAST_MOVES 1
#endif #endif
enum AxisRelative : uint8_t { enum AxisRelative : uint8_t { REL_X, REL_Y, REL_Z, REL_E, E_MODE_ABS, E_MODE_REL };
LOGICAL_AXIS_LIST(REL_E, REL_X, REL_Y, REL_Z, REL_I, REL_J, REL_K)
#if HAS_EXTRUDERS
, E_MODE_ABS, E_MODE_REL
#endif
};
extern const char G28_STR[]; extern const char G28_STR[];
@@ -329,31 +324,23 @@ public:
static uint8_t axis_relative; static uint8_t axis_relative;
static inline bool axis_is_relative(const AxisEnum a) { static inline bool axis_is_relative(const AxisEnum a) {
#if HAS_EXTRUDERS if (a == E_AXIS) {
if (a == E_AXIS) { if (TEST(axis_relative, E_MODE_REL)) return true;
if (TEST(axis_relative, E_MODE_REL)) return true; if (TEST(axis_relative, E_MODE_ABS)) return false;
if (TEST(axis_relative, E_MODE_ABS)) return false; }
}
#endif
return TEST(axis_relative, a); return TEST(axis_relative, a);
} }
static inline void set_relative_mode(const bool rel) { static inline void set_relative_mode(const bool rel) {
axis_relative = rel ? (0 LOGICAL_AXIS_GANG( axis_relative = rel ? _BV(REL_X) | _BV(REL_Y) | _BV(REL_Z) | _BV(REL_E) : 0;
| _BV(REL_E), }
| _BV(REL_X), | _BV(REL_Y), | _BV(REL_Z), static inline void set_e_relative() {
| _BV(REL_I), | _BV(REL_J), | _BV(REL_K) CBI(axis_relative, E_MODE_ABS);
)) : 0; SBI(axis_relative, E_MODE_REL);
}
static inline void set_e_absolute() {
CBI(axis_relative, E_MODE_REL);
SBI(axis_relative, E_MODE_ABS);
} }
#if HAS_EXTRUDERS
static inline void set_e_relative() {
CBI(axis_relative, E_MODE_ABS);
SBI(axis_relative, E_MODE_REL);
}
static inline void set_e_absolute() {
CBI(axis_relative, E_MODE_REL);
SBI(axis_relative, E_MODE_ABS);
}
#endif
#if ENABLED(CNC_WORKSPACE_PLANES) #if ENABLED(CNC_WORKSPACE_PLANES)
/** /**
@@ -392,7 +379,7 @@ public:
static void process_subcommands_now(char * gcode); static void process_subcommands_now(char * gcode);
static inline void home_all_axes(const bool keep_leveling=false) { static inline void home_all_axes(const bool keep_leveling=false) {
process_subcommands_now_P(keep_leveling ? G28_STR : TERN(CAN_SET_LEVELING_AFTER_G28, PSTR("G28L0"), G28_STR)); process_subcommands_now_P(keep_leveling ? G28_STR : TERN(G28_L0_ENSURES_LEVELING_OFF, PSTR("G28L0"), G28_STR));
} }
#if EITHER(HAS_AUTO_REPORTING, HOST_KEEPALIVE_FEATURE) #if EITHER(HAS_AUTO_REPORTING, HOST_KEEPALIVE_FEATURE)
@@ -564,25 +551,22 @@ private:
#if HAS_CUTTER #if HAS_CUTTER
static void M3_M4(const bool is_M4); static void M3_M4(const bool is_M4);
static void M5(); static void M5();
#if ENABLED(AIR_EVACUATION)
static void M10();
static void M11();
#endif
#endif #endif
#if ENABLED(COOLANT_MIST) #if ENABLED(COOLANT_CONTROL)
static void M7(); #if ENABLED(COOLANT_MIST)
#endif static void M7();
#endif
#if EITHER(AIR_ASSIST, COOLANT_FLOOD) #if ENABLED(COOLANT_FLOOD)
static void M8(); static void M8();
#endif #endif
#if EITHER(AIR_ASSIST, COOLANT_CONTROL)
static void M9(); static void M9();
#endif #endif
#if ENABLED(AIR_EVACUATION)
static void M10();
static void M11();
#endif
#if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER) #if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER)
static void M12(); static void M12();
#endif #endif

View File

@@ -48,10 +48,7 @@
*/ */
void GcodeSuite::G92() { void GcodeSuite::G92() {
#if HAS_EXTRUDERS bool sync_E = false, sync_XYZE = false;
bool sync_E = false;
#endif
bool sync_XYZE = false;
#if USE_GCODE_SUBCODES #if USE_GCODE_SUBCODES
const uint8_t subcode_G92 = parser.subcode; const uint8_t subcode_G92 = parser.subcode;
@@ -75,11 +72,7 @@ void GcodeSuite::G92() {
case 9: // G92.9 - Set Current Position directly (like Marlin 1.0) case 9: // G92.9 - Set Current Position directly (like Marlin 1.0)
LOOP_LOGICAL_AXES(i) { LOOP_LOGICAL_AXES(i) {
if (parser.seenval(axis_codes[i])) { if (parser.seenval(axis_codes[i])) {
if (TERN1(HAS_EXTRUDERS, i != E_AXIS)) if (i == E_AXIS) sync_E = true; else sync_XYZE = true;
sync_XYZE = true;
else {
TERN_(HAS_EXTRUDERS, sync_E = true);
}
current_position[i] = parser.value_axis_units((AxisEnum)i); current_position[i] = parser.value_axis_units((AxisEnum)i);
} }
} }
@@ -90,26 +83,20 @@ void GcodeSuite::G92() {
LOOP_LOGICAL_AXES(i) { LOOP_LOGICAL_AXES(i) {
if (parser.seenval(axis_codes[i])) { if (parser.seenval(axis_codes[i])) {
const float l = parser.value_axis_units((AxisEnum)i), // Given axis coordinate value, converted to millimeters const float l = parser.value_axis_units((AxisEnum)i), // Given axis coordinate value, converted to millimeters
v = TERN0(HAS_EXTRUDERS, i == E_AXIS) ? l : LOGICAL_TO_NATIVE(l, i), // Axis position in NATIVE space (applying the existing offset) v = i == E_AXIS ? l : LOGICAL_TO_NATIVE(l, i), // Axis position in NATIVE space (applying the existing offset)
d = v - current_position[i]; // How much is the current axis position altered by? d = v - current_position[i]; // How much is the current axis position altered by?
if (!NEAR_ZERO(d)) { if (!NEAR_ZERO(d)) {
#if HAS_POSITION_SHIFT && !IS_SCARA // When using workspaces... #if HAS_POSITION_SHIFT && !IS_SCARA // When using workspaces...
if (TERN1(HAS_EXTRUDERS, i != E_AXIS)) { if (i == E_AXIS) {
position_shift[i] += d; // ...most axes offset the workspace... sync_E = true;
current_position.e = v; // ...E is still set directly
}
else {
position_shift[i] += d; // ...but other axes offset the workspace.
update_workspace_offset((AxisEnum)i); update_workspace_offset((AxisEnum)i);
} }
else {
#if HAS_EXTRUDERS
sync_E = true;
current_position.e = v; // ...but E is set directly
#endif
}
#else // Without workspaces... #else // Without workspaces...
if (TERN1(HAS_EXTRUDERS, i != E_AXIS)) if (i == E_AXIS) sync_E = true; else sync_XYZE = true;
sync_XYZE = true;
else {
TERN_(HAS_EXTRUDERS, sync_E = true);
}
current_position[i] = v; // ...set Current Position directly (like Marlin 1.0) current_position[i] = v; // ...set Current Position directly (like Marlin 1.0)
#endif #endif
} }
@@ -124,10 +111,8 @@ void GcodeSuite::G92() {
coordinate_system[active_coordinate_system] = position_shift; coordinate_system[active_coordinate_system] = position_shift;
#endif #endif
if (sync_XYZE) sync_plan_position(); if (sync_XYZE) sync_plan_position();
#if HAS_EXTRUDERS else if (sync_E) sync_plan_position_e();
else if (sync_E) sync_plan_position_e();
#endif
IF_DISABLED(DIRECT_STEPPING, report_current_position()); IF_DISABLED(DIRECT_STEPPING, report_current_position());
} }

View File

@@ -31,16 +31,7 @@
#include "../../MarlinCore.h" #include "../../MarlinCore.h"
void M206_report() { void M206_report() {
SERIAL_ECHOLNPAIR_P( SERIAL_ECHOLNPAIR_P(PSTR("M206 X"), home_offset.x, SP_Y_STR, home_offset.y, SP_Z_STR, home_offset.z);
LIST_N(DOUBLE(LINEAR_AXES),
PSTR("M206 X"), home_offset.x,
SP_Y_STR, home_offset.y,
SP_Z_STR, home_offset.z,
SP_I_STR, home_offset.i,
SP_J_STR, home_offset.j,
SP_K_STR, home_offset.k,
)
);
} }
/** /**
@@ -60,7 +51,7 @@ void GcodeSuite::M206() {
if (parser.seen('P')) set_home_offset(B_AXIS, parser.value_float()); // Psi if (parser.seen('P')) set_home_offset(B_AXIS, parser.value_float()); // Psi
#endif #endif
if (!parser.seen(LINEAR_AXIS_GANG("X", "Y", "Z", "I", "J", "K"))) if (!parser.seen("XYZ"))
M206_report(); M206_report();
else else
report_current_position(); report_current_position();

View File

@@ -125,15 +125,6 @@
#if AXIS_IS_L64XX(Z4) #if AXIS_IS_L64XX(Z4)
REPORT_ABSOLUTE_POS(Z4); REPORT_ABSOLUTE_POS(Z4);
#endif #endif
#if AXIS_IS_L64XX(I)
REPORT_ABSOLUTE_POS(I);
#endif
#if AXIS_IS_L64XX(J)
REPORT_ABSOLUTE_POS(J);
#endif
#if AXIS_IS_L64XX(K)
REPORT_ABSOLUTE_POS(K);
#endif
#if AXIS_IS_L64XX(E0) #if AXIS_IS_L64XX(E0)
REPORT_ABSOLUTE_POS(E0); REPORT_ABSOLUTE_POS(E0);
#endif #endif
@@ -179,13 +170,7 @@
SERIAL_ECHOPGM("FromStp:"); SERIAL_ECHOPGM("FromStp:");
get_cartesian_from_steppers(); // writes 'cartes' (with forward kinematics) get_cartesian_from_steppers(); // writes 'cartes' (with forward kinematics)
xyze_pos_t from_steppers = LOGICAL_AXIS_ARRAY( xyze_pos_t from_steppers = { cartes.x, cartes.y, cartes.z, planner.get_axis_position_mm(E_AXIS) };
planner.get_axis_position_mm(E_AXIS),
cartes.x, cartes.y, cartes.z,
planner.get_axis_position_mm(I_AXIS),
planner.get_axis_position_mm(J_AXIS),
planner.get_axis_position_mm(K_AXIS)
);
report_all_axis_pos(from_steppers); report_all_axis_pos(from_steppers);
const xyze_float_t diff = from_steppers - leveled; const xyze_float_t diff = from_steppers - leveled;
@@ -216,12 +201,10 @@ void GcodeSuite::M114() {
report_current_position_detail(); report_current_position_detail();
return; return;
} }
#if HAS_EXTRUDERS if (parser.seen_test('E')) {
if (parser.seen_test('E')) { SERIAL_ECHOLNPAIR("Count E:", stepper.position(E_AXIS));
SERIAL_ECHOLNPAIR("Count E:", stepper.position(E_AXIS)); return;
return; }
}
#endif
#endif #endif
#if ENABLED(M114_REALTIME) #if ENABLED(M114_REALTIME)

View File

@@ -49,14 +49,9 @@ void GcodeSuite::G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move/*=false*/)) {
if (IsRunning() if (IsRunning()
#if ENABLED(NO_MOTION_BEFORE_HOMING) #if ENABLED(NO_MOTION_BEFORE_HOMING)
&& !homing_needed_error( && !homing_needed_error(
LINEAR_AXIS_GANG( (parser.seen_test('X') ? _BV(X_AXIS) : 0)
(parser.seen_test('X') ? _BV(X_AXIS) : 0), | (parser.seen_test('Y') ? _BV(Y_AXIS) : 0)
| (parser.seen_test('Y') ? _BV(Y_AXIS) : 0), | (parser.seen_test('Z') ? _BV(Z_AXIS) : 0) )
| (parser.seen_test('Z') ? _BV(Z_AXIS) : 0),
| (parser.seen_test(AXIS4_NAME) ? _BV(I_AXIS) : 0),
| (parser.seen_test(AXIS5_NAME) ? _BV(J_AXIS) : 0),
| (parser.seen_test(AXIS6_NAME) ? _BV(K_AXIS) : 0))
)
#endif #endif
) { ) {
TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_RUNNING)); TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_RUNNING));
@@ -88,9 +83,7 @@ void GcodeSuite::G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move/*=false*/)) {
if (MIN_AUTORETRACT <= MAX_AUTORETRACT) { if (MIN_AUTORETRACT <= MAX_AUTORETRACT) {
// When M209 Autoretract is enabled, convert E-only moves to firmware retract/recover moves // When M209 Autoretract is enabled, convert E-only moves to firmware retract/recover moves
if (fwretract.autoretract_enabled && parser.seen_test('E') if (fwretract.autoretract_enabled && parser.seen('E') && !parser.seen("XYZ")) {
&& !parser.seen(LINEAR_AXIS_GANG("X", "Y", "Z", AXIS4_STR, AXIS5_STR, AXIS6_STR))
) {
const float echange = destination.e - current_position.e; const float echange = destination.e - current_position.e;
// Is this a retract or recover move? // Is this a retract or recover move?
if (WITHIN(ABS(echange), MIN_AUTORETRACT, MAX_AUTORETRACT) && fwretract.retracted[active_extruder] == (echange > 0.0)) { if (WITHIN(ABS(echange), MIN_AUTORETRACT, MAX_AUTORETRACT) && fwretract.retracted[active_extruder] == (echange > 0.0)) {

View File

@@ -63,7 +63,7 @@ void plan_arc(
case GcodeSuite::PLANE_ZX: p_axis = Z_AXIS; q_axis = X_AXIS; l_axis = Y_AXIS; break; case GcodeSuite::PLANE_ZX: p_axis = Z_AXIS; q_axis = X_AXIS; l_axis = Y_AXIS; break;
} }
#else #else
constexpr AxisEnum p_axis = X_AXIS, q_axis = Y_AXIS OPTARG(HAS_Z_AXIS, l_axis = Z_AXIS); constexpr AxisEnum p_axis = X_AXIS, q_axis = Y_AXIS, l_axis = Z_AXIS;
#endif #endif
// Radius vector from center to current location // Radius vector from center to current location
@@ -73,8 +73,8 @@ void plan_arc(
center_P = current_position[p_axis] - rvec.a, center_P = current_position[p_axis] - rvec.a,
center_Q = current_position[q_axis] - rvec.b, center_Q = current_position[q_axis] - rvec.b,
rt_X = cart[p_axis] - center_P, rt_X = cart[p_axis] - center_P,
rt_Y = cart[q_axis] - center_Q rt_Y = cart[q_axis] - center_Q,
OPTARG(HAS_Z_AXIS, start_L = current_position[l_axis]); start_L = current_position[l_axis];
#ifdef MIN_ARC_SEGMENTS #ifdef MIN_ARC_SEGMENTS
uint16_t min_segments = MIN_ARC_SEGMENTS; uint16_t min_segments = MIN_ARC_SEGMENTS;
@@ -109,37 +109,27 @@ void plan_arc(
#endif #endif
} }
#if HAS_Z_AXIS float linear_travel = cart[l_axis] - start_L,
float linear_travel = cart[l_axis] - start_L; extruder_travel = cart.e - current_position.e;
#endif
#if HAS_EXTRUDERS
float extruder_travel = cart.e - current_position.e;
#endif
// If circling around... // If circling around...
if (ENABLED(ARC_P_CIRCLES) && circles) { if (ENABLED(ARC_P_CIRCLES) && circles) {
const float total_angular = angular_travel + circles * RADIANS(360), // Total rotation with all circles and remainder const float total_angular = angular_travel + circles * RADIANS(360), // Total rotation with all circles and remainder
part_per_circle = RADIANS(360) / total_angular; // Each circle's part of the total part_per_circle = RADIANS(360) / total_angular, // Each circle's part of the total
l_per_circle = linear_travel * part_per_circle, // L movement per circle
#if HAS_Z_AXIS e_per_circle = extruder_travel * part_per_circle; // E movement per circle
const float l_per_circle = linear_travel * part_per_circle; // L movement per circle
#endif
#if HAS_EXTRUDERS
const float e_per_circle = extruder_travel * part_per_circle; // E movement per circle
#endif
xyze_pos_t temp_position = current_position; // for plan_arc to compare to current_position xyze_pos_t temp_position = current_position; // for plan_arc to compare to current_position
for (uint16_t n = circles; n--;) { for (uint16_t n = circles; n--;) {
TERN_(HAS_EXTRUDERS, temp_position.e += e_per_circle); // Destination E axis temp_position.e += e_per_circle; // Destination E axis
TERN_(HAS_Z_AXIS, temp_position[l_axis] += l_per_circle); // Destination L axis temp_position[l_axis] += l_per_circle; // Destination L axis
plan_arc(temp_position, offset, clockwise, 0); // Plan a single whole circle plan_arc(temp_position, offset, clockwise, 0); // Plan a single whole circle
} }
TERN_(HAS_Z_AXIS, linear_travel = cart[l_axis] - current_position[l_axis]); linear_travel = cart[l_axis] - current_position[l_axis];
TERN_(HAS_EXTRUDERS, extruder_travel = cart.e - current_position.e); extruder_travel = cart.e - current_position.e;
} }
const float flat_mm = radius * angular_travel, const float flat_mm = radius * angular_travel,
mm_of_travel = TERN_(HAS_Z_AXIS, linear_travel ? HYPOT(flat_mm, linear_travel) :) ABS(flat_mm); mm_of_travel = linear_travel ? HYPOT(flat_mm, linear_travel) : ABS(flat_mm);
if (mm_of_travel < 0.001f) return; if (mm_of_travel < 0.001f) return;
const feedRate_t scaled_fr_mm_s = MMS_SCALED(feedrate_mm_s); const feedRate_t scaled_fr_mm_s = MMS_SCALED(feedrate_mm_s);
@@ -188,22 +178,17 @@ void plan_arc(
// Vector rotation matrix values // Vector rotation matrix values
xyze_pos_t raw; xyze_pos_t raw;
const float theta_per_segment = angular_travel / segments, const float theta_per_segment = angular_travel / segments,
linear_per_segment = linear_travel / segments,
extruder_per_segment = extruder_travel / segments,
sq_theta_per_segment = sq(theta_per_segment), sq_theta_per_segment = sq(theta_per_segment),
sin_T = theta_per_segment - sq_theta_per_segment * theta_per_segment / 6, sin_T = theta_per_segment - sq_theta_per_segment * theta_per_segment / 6,
cos_T = 1 - 0.5f * sq_theta_per_segment; // Small angle approximation cos_T = 1 - 0.5f * sq_theta_per_segment; // Small angle approximation
#if HAS_Z_AXIS && DISABLED(AUTO_BED_LEVELING_UBL)
const float linear_per_segment = linear_travel / segments;
#endif
#if HAS_EXTRUDERS
const float extruder_per_segment = extruder_travel / segments;
#endif
// Initialize the linear axis // Initialize the linear axis
TERN_(HAS_Z_AXIS, raw[l_axis] = current_position[l_axis]); raw[l_axis] = current_position[l_axis];
// Initialize the extruder axis // Initialize the extruder axis
TERN_(HAS_EXTRUDERS, raw.e = current_position.e); raw.e = current_position.e;
#if ENABLED(SCARA_FEEDRATE_SCALING) #if ENABLED(SCARA_FEEDRATE_SCALING)
const float inv_duration = scaled_fr_mm_s / seg_length; const float inv_duration = scaled_fr_mm_s / seg_length;
@@ -249,11 +234,13 @@ void plan_arc(
// Update raw location // Update raw location
raw[p_axis] = center_P + rvec.a; raw[p_axis] = center_P + rvec.a;
raw[q_axis] = center_Q + rvec.b; raw[q_axis] = center_Q + rvec.b;
#if HAS_Z_AXIS #if ENABLED(AUTO_BED_LEVELING_UBL)
raw[l_axis] = TERN(AUTO_BED_LEVELING_UBL, start_L, raw[l_axis] + linear_per_segment); raw[l_axis] = start_L;
UNUSED(linear_per_segment);
#else
raw[l_axis] += linear_per_segment;
#endif #endif
raw.e += extruder_per_segment;
TERN_(HAS_EXTRUDERS, raw.e += extruder_per_segment);
apply_motion_limits(raw); apply_motion_limits(raw);
@@ -268,7 +255,7 @@ void plan_arc(
// Ensure last segment arrives at target location. // Ensure last segment arrives at target location.
raw = cart; raw = cart;
TERN_(AUTO_BED_LEVELING_UBL, TERN_(HAS_Z_AXIS, raw[l_axis] = start_L)); TERN_(AUTO_BED_LEVELING_UBL, raw[l_axis] = start_L);
apply_motion_limits(raw); apply_motion_limits(raw);
@@ -280,7 +267,7 @@ void plan_arc(
OPTARG(SCARA_FEEDRATE_SCALING, inv_duration) OPTARG(SCARA_FEEDRATE_SCALING, inv_duration)
); );
TERN_(AUTO_BED_LEVELING_UBL, TERN_(HAS_Z_AXIS, raw[l_axis] = start_L)); TERN_(AUTO_BED_LEVELING_UBL, raw[l_axis] = start_L);
current_position = raw; current_position = raw;
} // plan_arc } // plan_arc

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