Bump
This commit is contained in:
@@ -51,8 +51,8 @@ jobs:
|
||||
export PATH=`pwd`/buildroot/bin/:${PATH}
|
||||
|
||||
# Generate custom version include
|
||||
generate_version ./Marlin/src/inc
|
||||
cat ./Marlin/src/inc/_Version.h
|
||||
generate_version ./Marlin/
|
||||
cat ./Marlin/Version.h
|
||||
#
|
||||
# Back up pins_RAMPS.h
|
||||
#
|
||||
@@ -240,10 +240,10 @@ jobs:
|
||||
build_marlin_pio ./ ${TEST_PLATFORM}
|
||||
restore_configs
|
||||
echo testing STM32F1 targets...
|
||||
export TEST_PLATFORM="-e STM32F103R"
|
||||
export TEST_PLATFORM="-e STM32F103RE"
|
||||
restore_configs
|
||||
echo use_example_configs STM32/STM32F103R
|
||||
use_example_configs STM32/STM32F103R
|
||||
echo use_example_configs STM32/STM32F103RE
|
||||
use_example_configs STM32/STM32F103RE
|
||||
build_marlin_pio ./ ${TEST_PLATFORM}
|
||||
restore_configs
|
||||
echo use_example_configs STM32/stm32f103ret6
|
||||
|
||||
+14
-11
@@ -13,10 +13,8 @@ env:
|
||||
- TEST_PLATFORM="DUE"
|
||||
- TEST_PLATFORM="esp32"
|
||||
- TEST_PLATFORM="linux_native"
|
||||
- TEST_PLATFORM="LPC1768"
|
||||
- TEST_PLATFORM="LPC1769"
|
||||
- TEST_PLATFORM="megaatmega2560"
|
||||
- TEST_PLATFORM="STM32F103R"
|
||||
- TEST_PLATFORM="STM32F103RE"
|
||||
- TEST_PLATFORM="teensy31"
|
||||
- TEST_PLATFORM="teensy35"
|
||||
|
||||
@@ -31,22 +29,27 @@ env:
|
||||
- TEST_PLATFORM="ARMED"
|
||||
- TEST_PLATFORM="BIGTREE_BTT002"
|
||||
- TEST_PLATFORM="BIGTREE_SKR_PRO"
|
||||
- TEST_PLATFORM="STM32F103R_bigtree"
|
||||
- TEST_PLATFORM="STM32F103RC_bigtree"
|
||||
- TEST_PLATFORM="jgaurora_a5s_a1"
|
||||
- TEST_PLATFORM="STM32F103V_longer"
|
||||
- TEST_PLATFORM="STM32F103VE_longer"
|
||||
- TEST_PLATFORM="STM32F407VE_black"
|
||||
- TEST_PLATFORM="mks_robin"
|
||||
|
||||
# Put lengthy tests last
|
||||
- TEST_PLATFORM="LPC1768"
|
||||
- TEST_PLATFORM="LPC1769"
|
||||
|
||||
# Non-working environment tests
|
||||
#- TEST_PLATFORM="at90usb1286_cdc"
|
||||
#- TEST_PLATFORM="at90usb1286_dfu"
|
||||
#- TEST_PLATFORM="malyanm200"
|
||||
#- TEST_PLATFORM="mks_robin"
|
||||
#- TEST_PLATFORM="STM32F103CB_malyan"
|
||||
#- TEST_PLATFORM="mks_robin_lite"
|
||||
#- TEST_PLATFORM="mks_robin_mini"
|
||||
#- TEST_PLATFORM="mks_robin_nano"
|
||||
#- TEST_PLATFORM="SAMD51_grandcentral_m4"
|
||||
#- TEST_PLATFORM="STM32F103R_bigtree"
|
||||
#- TEST_PLATFORM="STM32F103R_fysetc"
|
||||
#- TEST_PLATFORM="STM32F103RC_bigtree"
|
||||
#- TEST_PLATFORM="STM32F103RC_bigtree_USB"
|
||||
#- TEST_PLATFORM="STM32F103RC_fysetc"
|
||||
#- TEST_PLATFORM="STM32F4"
|
||||
#- TEST_PLATFORM="STM32F7"
|
||||
|
||||
@@ -72,8 +75,8 @@ before_script:
|
||||
- cd ${TRAVIS_BUILD_DIR}
|
||||
#
|
||||
# Generate custom version include
|
||||
- generate_version ${TRAVIS_BUILD_DIR}/Marlin/src/inc
|
||||
- cat ${TRAVIS_BUILD_DIR}/Marlin/src/inc/_Version.h
|
||||
- generate_version ${TRAVIS_BUILD_DIR}/Marlin/
|
||||
- cat ${TRAVIS_BUILD_DIR}/Marlin/Version.h
|
||||
#
|
||||
script:
|
||||
- run_tests ${TRAVIS_BUILD_DIR} ${TEST_PLATFORM}
|
||||
|
||||
+39
-26
@@ -1,6 +1,6 @@
|
||||
//#define PetsfangMicroswiss
|
||||
//#define BondtechBMG
|
||||
//#define CR10SPro_GearedExtruder
|
||||
#define CR10SPro_GearedExtruder
|
||||
//#define E3DV6
|
||||
|
||||
//#define FilamentSensorStd
|
||||
@@ -95,6 +95,7 @@
|
||||
|
||||
// Author info of this build printed to the host during boot and M115
|
||||
#define STRING_CONFIG_H_AUTHOR "Tinymachines3D" // Who made the changes.
|
||||
#define CUSTOM_VERSION_FILE Version.h // Path from the root directory (no quotes)
|
||||
|
||||
/**
|
||||
* *** VENDORS PLEASE READ ***
|
||||
@@ -412,6 +413,7 @@
|
||||
* 67 : 450C thermistor from SliceEngineering
|
||||
* 70 : the 100K thermistor found in the bq Hephestos 2
|
||||
* 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor
|
||||
* 99 : 100k thermistor with a 10K pull-up resistor (found on some Wanhao i3 machines)
|
||||
*
|
||||
* 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k.
|
||||
* (but gives greater accuracy and more stable PID)
|
||||
@@ -429,8 +431,6 @@
|
||||
* Use these for Testing or Development purposes. NEVER for production machine.
|
||||
* 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below.
|
||||
* 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below.
|
||||
*
|
||||
* :{ '0':"Not used", '1':"100k / 4.7k - EPCOS", '331':"(3.3V thermistor 1)", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '501':"100K Zonestar (Tronxy X3A)", '512':"100k RPW-Ultra hotend thermistor", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '18':"ATC Semitec 204GT-2 (4.7k pullup) Dagoma.Fr - MKS_Base_DKU001327" '20':"Pt100 (Ultimainboard V2.x)", '201':"Pt100 (Overlord)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '61':"100k Formbot / Vivedino 3950 350C thermistor 4.7k pullup", '66':"Dyze Design 4.7M High Temperature thermistor", '67':"Slice Engineering 450C High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-4':"Thermocouple + AD8495", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595", '998':"Dummy 1", '999':"Dummy 2", '1000':"Custom thermistor params" }
|
||||
*/
|
||||
#if ENABLED(E3DV6)
|
||||
#define TEMP_SENSOR_0 5
|
||||
@@ -558,7 +558,7 @@
|
||||
#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
|
||||
|
||||
#if ENABLED(PIDTEMPBED)
|
||||
|
||||
//#define MIN_BED_POWER 0
|
||||
//#define PID_BED_DEBUG // Sends debug data to the serial port.
|
||||
|
||||
//120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
|
||||
@@ -817,7 +817,12 @@
|
||||
* Override with M203
|
||||
* X, Y, Z, E0 [, E1[, E2[, E3[, E4[, E5]]]]]
|
||||
*/
|
||||
#define DEFAULT_MAX_FEEDRATE { 500, 500, 5, 25 }
|
||||
#define DEFAULT_MAX_FEEDRATE { 500, 500, 5, 70 }
|
||||
|
||||
#define LIMITED_MAX_FR_EDITING // Limit edit via M203 or LCD to DEFAULT_MAX_FEEDRATE * 2
|
||||
#if ENABLED(LIMITED_MAX_FR_EDITING)
|
||||
#define MAX_FEEDRATE_EDIT_VALUES { 1000, 1000, 10, 150 } // ...or, set your own edit limits
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Default Max Acceleration (change/s) change = mm/s
|
||||
@@ -827,6 +832,11 @@
|
||||
*/
|
||||
#define DEFAULT_MAX_ACCELERATION { 4000, 2000, 100, 2000 }
|
||||
|
||||
#define LIMITED_MAX_ACCEL_EDITING // Limit edit via M201 or LCD to DEFAULT_MAX_ACCELERATION * 2
|
||||
#if ENABLED(LIMITED_MAX_ACCEL_EDITING)
|
||||
#define MAX_ACCEL_EDIT_VALUES { 7000, 4000, 200, 5000 } // ...or, set your own edit limits
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Default Acceleration (change/s) change = mm/s
|
||||
* Override with M204
|
||||
@@ -840,35 +850,38 @@
|
||||
#define DEFAULT_TRAVEL_ACCELERATION 2000 // X, Y, Z acceleration for travel (non printing) moves
|
||||
|
||||
/**
|
||||
* Junction Deviation
|
||||
*
|
||||
* Use Junction Deviation instead of traditional Jerk Limiting
|
||||
*
|
||||
* See:
|
||||
* https://reprap.org/forum/read.php?1,739819
|
||||
* http://blog.kyneticcnc.com/2018/10/computing-junction-deviation-for-marlin.html
|
||||
*/
|
||||
#define JUNCTION_DEVIATION
|
||||
#if ENABLED(JUNCTION_DEVIATION)
|
||||
#define JUNCTION_DEVIATION_MM 0.06 // (mm) Distance from real junction edge
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Default Jerk (mm/s)
|
||||
* Default Jerk limits (mm/s)
|
||||
* Override with M205 X Y Z E
|
||||
*
|
||||
* "Jerk" specifies the minimum speed change that requires acceleration.
|
||||
* When changing speed and direction, if the difference is less than the
|
||||
* value set here, it may happen instantaneously.
|
||||
*/
|
||||
#if DISABLED(JUNCTION_DEVIATION)
|
||||
//#define CLASSIC_JERK
|
||||
#if ENABLED(CLASSIC_JERK)
|
||||
#define DEFAULT_XJERK 10.0
|
||||
#define DEFAULT_YJERK 10.0
|
||||
#define DEFAULT_ZJERK 0.3
|
||||
|
||||
//#define LIMITED_JERK_EDITING // Limit edit via M205 or LCD to DEFAULT_aJERK * 2
|
||||
#if ENABLED(LIMITED_JERK_EDITING)
|
||||
#define MAX_JERK_EDIT_VALUES { 20, 20, 0.6, 10 } // ...or, set your own edit limits
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define DEFAULT_EJERK 5.0 // May be used by Linear Advance
|
||||
|
||||
/**
|
||||
* Junction Deviation Factor
|
||||
*
|
||||
* See:
|
||||
* https://reprap.org/forum/read.php?1,739819
|
||||
* http://blog.kyneticcnc.com/2018/10/computing-junction-deviation-for-marlin.html
|
||||
*/
|
||||
#if DISABLED(CLASSIC_JERK)
|
||||
#define JUNCTION_DEVIATION_MM 0.06 // (mm) Distance from real junction edge
|
||||
#endif
|
||||
|
||||
/**
|
||||
* S-Curve Acceleration
|
||||
*
|
||||
@@ -1691,10 +1704,10 @@
|
||||
*
|
||||
* Select the language to display on the LCD. These languages are available:
|
||||
*
|
||||
* en, an, bg, ca, cz, da, de, el, el-gr, es, eu, fi, fr, gl, hr, it, jp-kana,
|
||||
* ko_KR, nl, pl, pt, pt-br, ru, sk, tr, uk, vi, zh_CN, zh_TW, test
|
||||
* en, an, bg, ca, cz, da, de, el, el_gr, es, eu, fi, fr, gl, hr, it, jp_kana,
|
||||
* ko_KR, nl, pl, pt, pt_br, ru, sk, tr, uk, vi, zh_CN, zh_TW, test
|
||||
*
|
||||
* :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cz':'Czech', 'da':'Danish', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'jp-kana':'Japanese', 'ko_KR':'Korean (South Korea)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'ru':'Russian', 'sk':'Slovak', 'tr':'Turkish', 'uk':'Ukrainian', 'vi':'Vietnamese', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Traditional)', 'test':'TEST' }
|
||||
* :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cz':'Czech', 'da':'Danish', 'de':'German', 'el':'Greek', 'el_gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'jp_kana':'Japanese', 'ko_KR':'Korean (South Korea)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt_br':'Portuguese (Brazilian)', 'ru':'Russian', 'sk':'Slovak', 'tr':'Turkish', 'uk':'Ukrainian', 'vi':'Vietnamese', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Traditional)', 'test':'TEST' }
|
||||
*/
|
||||
#define LCD_LANGUAGE en
|
||||
|
||||
@@ -1744,8 +1757,8 @@
|
||||
* Enable one of the following items for a slower SPI transfer speed.
|
||||
* This may be required to resolve "volume init" errors.
|
||||
*/
|
||||
#define SPI_SPEED SPI_HALF_SPEED
|
||||
//#define SPI_SPEED SPI_QUARTER_SPEED
|
||||
//#define SPI_SPEED SPI_HALF_SPEED
|
||||
#define SPI_SPEED SPI_QUARTER_SPEED
|
||||
//#define SPI_SPEED SPI_EIGHTH_SPEED
|
||||
|
||||
/**
|
||||
|
||||
+50
-34
@@ -379,6 +379,7 @@
|
||||
#define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW
|
||||
#define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on
|
||||
#define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin)
|
||||
//#define CASE_LIGHT_MAX_PWM 128 // Limit pwm
|
||||
//#define CASE_LIGHT_MENU // Add Case Light options to the LCD menu
|
||||
//#define CASE_LIGHT_NO_BRIGHTNESS // Disable brightness control. Enable for non-PWM lighting.
|
||||
//#define CASE_LIGHT_USE_NEOPIXEL // Use Neopixel LED as case light, requires NEOPIXEL_LED.
|
||||
@@ -607,12 +608,26 @@
|
||||
#if ENABLED(Z_STEPPER_AUTO_ALIGN)
|
||||
// Define probe X and Y positions for Z1, Z2 [, Z3]
|
||||
#if ENABLED(SX2)
|
||||
#define Z_STEPPER_ALIGN_X { 50, 225 }
|
||||
#define Z_STEPPER_ALIGN_Y { 100, 100 }
|
||||
#define Z_STEPPER_ALIGN_XY { { 50, 100 }, { 225, 100 } }
|
||||
#else
|
||||
#define Z_STEPPER_ALIGN_X { 50, 350 }
|
||||
#define Z_STEPPER_ALIGN_Y { 200, 200 }
|
||||
#define Z_STEPPER_ALIGN_XY { { 50, 200 }, { 350, 200 } }
|
||||
#endif
|
||||
|
||||
// Provide Z stepper positions for more rapid convergence in bed alignment.
|
||||
// Currently requires triple stepper drivers.
|
||||
//#define Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS
|
||||
#if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
|
||||
// Define Stepper XY positions for Z1, Z2, Z3 corresponding to
|
||||
// the Z screw positions in the bed carriage.
|
||||
// Define one position per Z stepper in stepper driver order.
|
||||
#define Z_STEPPER_ALIGN_STEPPER_XY { { 210.7, 102.5 }, { 152.6, 220.0 }, { 94.5, 102.5 } }
|
||||
#else
|
||||
// Amplification factor. Used to scale the correction step up or down.
|
||||
// In case the stepper (spindle) position is further out than the test point.
|
||||
// Use a value > 1. NOTE: This may cause instability
|
||||
#define Z_STEPPER_ALIGN_AMP 1.0
|
||||
#endif
|
||||
|
||||
// Set number of iterations to align
|
||||
#define Z_STEPPER_ALIGN_ITERATIONS 6
|
||||
// Enable to restore leveling setup after operation
|
||||
@@ -621,10 +636,6 @@
|
||||
// On a 300mm bed a 5% grade would give a misalignment of ~1.5cm
|
||||
#define G34_MAX_GRADE 15 // (%) Maximum incline G34 will handle
|
||||
|
||||
// Use the amplification factor to de-/increase correction step.
|
||||
// In case the stepper (spindle) position is further out than the test point
|
||||
// Use a value > 1. NOTE: This may cause instability
|
||||
#define Z_STEPPER_ALIGN_AMP 1.0
|
||||
// Stop criterion. If the accuracy is better than this stop iterating early
|
||||
#define Z_STEPPER_ALIGN_ACC 0.02
|
||||
#endif
|
||||
@@ -899,6 +910,11 @@
|
||||
// Add an 'M73' G-code to set the current percentage
|
||||
//#define LCD_SET_PROGRESS_MANUALLY
|
||||
|
||||
#if HAS_PRINT_PROGRESS
|
||||
//#define PRINT_PROGRESS_SHOW_DECIMALS // Show progress with decimal digits (Graphical LCD only)
|
||||
//#define SHOW_REMAINING_TIME // Display estimated time to completion (Graphical LCD only)
|
||||
#endif
|
||||
|
||||
#if HAS_CHARACTER_LCD && HAS_PRINT_PROGRESS
|
||||
//#define LCD_PROGRESS_BAR // Show a progress bar on HD44780 LCDs for SD printing
|
||||
#if ENABLED(LCD_PROGRESS_BAR)
|
||||
@@ -1816,91 +1832,91 @@
|
||||
#define X_CURRENT 800 // (mA) RMS current. Multiply by 1.414 for peak current.
|
||||
#define X_MICROSTEPS 16 // 0..256
|
||||
#define X_RSENSE 0.11
|
||||
#define X_CHAIN_POS 0 // 0 - Not chained, 1 - MCU MOSI connected, 2 - next in chain, ...
|
||||
#define X_CHAIN_POS -1 // <=0 : Not chained. 1 : MCU MOSI connected. 2 : Next in chain, ...
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(X2)
|
||||
#define X2_CURRENT 800
|
||||
#define X2_MICROSTEPS 16
|
||||
#define X2_RSENSE 0.11
|
||||
#define X2_CHAIN_POS 0
|
||||
#define X2_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(Y)
|
||||
#define Y_CURRENT 800
|
||||
#define Y_MICROSTEPS 16
|
||||
#define Y_RSENSE 0.11
|
||||
#define Y_CHAIN_POS 0
|
||||
#define Y_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(Y2)
|
||||
#define Y2_CURRENT 800
|
||||
#define Y2_MICROSTEPS 16
|
||||
#define Y2_RSENSE 0.11
|
||||
#define Y2_CHAIN_POS 0
|
||||
#define Y2_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(Z)
|
||||
#define Z_CURRENT 800
|
||||
#define Z_MICROSTEPS 16
|
||||
#define Z_RSENSE 0.11
|
||||
#define Z_CHAIN_POS 0
|
||||
#define Z_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(Z2)
|
||||
#define Z2_CURRENT 800
|
||||
#define Z2_MICROSTEPS 16
|
||||
#define Z2_RSENSE 0.11
|
||||
#define Z2_CHAIN_POS 0
|
||||
#define Z2_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(Z3)
|
||||
#define Z3_CURRENT 800
|
||||
#define Z3_MICROSTEPS 16
|
||||
#define Z3_RSENSE 0.11
|
||||
#define Z3_CHAIN_POS 0
|
||||
#define Z3_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(E0)
|
||||
#define E0_CURRENT 800
|
||||
#define E0_MICROSTEPS 16
|
||||
#define E0_RSENSE 0.11
|
||||
#define E0_CHAIN_POS 0
|
||||
#define E0_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(E1)
|
||||
#define E1_CURRENT 800
|
||||
#define E1_MICROSTEPS 16
|
||||
#define E1_RSENSE 0.11
|
||||
#define E1_CHAIN_POS 0
|
||||
#define E1_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(E2)
|
||||
#define E2_CURRENT 800
|
||||
#define E2_MICROSTEPS 16
|
||||
#define E2_RSENSE 0.11
|
||||
#define E2_CHAIN_POS 0
|
||||
#define E2_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(E3)
|
||||
#define E3_CURRENT 800
|
||||
#define E3_MICROSTEPS 16
|
||||
#define E3_RSENSE 0.11
|
||||
#define E3_CHAIN_POS 0
|
||||
#define E3_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(E4)
|
||||
#define E4_CURRENT 800
|
||||
#define E4_MICROSTEPS 16
|
||||
#define E4_RSENSE 0.11
|
||||
#define E4_CHAIN_POS 0
|
||||
#define E4_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(E5)
|
||||
#define E5_CURRENT 800
|
||||
#define E5_MICROSTEPS 16
|
||||
#define E5_RSENSE 0.11
|
||||
#define E5_CHAIN_POS 0
|
||||
#define E5_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -2126,7 +2142,7 @@
|
||||
#define X_OVERCURRENT 2000 // (mA) Current where the driver detects an over current (VALID: 375 x (1 - 16) - 6A max - rounds down)
|
||||
#define X_STALLCURRENT 1500 // (mA) Current where the driver detects a stall (VALID: 31.25 * (1-128) - 4A max - rounds down)
|
||||
#define X_MAX_VOLTAGE 127 // 0-255, Maximum effective voltage seen by stepper
|
||||
#define X_CHAIN_POS 0 // Position in SPI chain, 0=Not in chain, 1=Nearest MOSI
|
||||
#define X_CHAIN_POS -1 // Position in SPI chain. (<=0 : Not in chain. 1 : Nearest MOSI)
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_X2(L6470)
|
||||
@@ -2134,7 +2150,7 @@
|
||||
#define X2_OVERCURRENT 2000
|
||||
#define X2_STALLCURRENT 1500
|
||||
#define X2_MAX_VOLTAGE 127
|
||||
#define X2_CHAIN_POS 0
|
||||
#define X2_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_Y(L6470)
|
||||
@@ -2142,7 +2158,7 @@
|
||||
#define Y_OVERCURRENT 2000
|
||||
#define Y_STALLCURRENT 1500
|
||||
#define Y_MAX_VOLTAGE 127
|
||||
#define Y_CHAIN_POS 0
|
||||
#define Y_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_Y2(L6470)
|
||||
@@ -2150,7 +2166,7 @@
|
||||
#define Y2_OVERCURRENT 2000
|
||||
#define Y2_STALLCURRENT 1500
|
||||
#define Y2_MAX_VOLTAGE 127
|
||||
#define Y2_CHAIN_POS 0
|
||||
#define Y2_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_Z(L6470)
|
||||
@@ -2158,7 +2174,7 @@
|
||||
#define Z_OVERCURRENT 2000
|
||||
#define Z_STALLCURRENT 1500
|
||||
#define Z_MAX_VOLTAGE 127
|
||||
#define Z_CHAIN_POS 0
|
||||
#define Z_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_Z2(L6470)
|
||||
@@ -2166,7 +2182,7 @@
|
||||
#define Z2_OVERCURRENT 2000
|
||||
#define Z2_STALLCURRENT 1500
|
||||
#define Z2_MAX_VOLTAGE 127
|
||||
#define Z2_CHAIN_POS 0
|
||||
#define Z2_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_Z3(L6470)
|
||||
@@ -2174,7 +2190,7 @@
|
||||
#define Z3_OVERCURRENT 2000
|
||||
#define Z3_STALLCURRENT 1500
|
||||
#define Z3_MAX_VOLTAGE 127
|
||||
#define Z3_CHAIN_POS 0
|
||||
#define Z3_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_E0(L6470)
|
||||
@@ -2182,7 +2198,7 @@
|
||||
#define E0_OVERCURRENT 2000
|
||||
#define E0_STALLCURRENT 1500
|
||||
#define E0_MAX_VOLTAGE 127
|
||||
#define E0_CHAIN_POS 0
|
||||
#define E0_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_E1(L6470)
|
||||
@@ -2190,7 +2206,7 @@
|
||||
#define E1_OVERCURRENT 2000
|
||||
#define E1_STALLCURRENT 1500
|
||||
#define E1_MAX_VOLTAGE 127
|
||||
#define E1_CHAIN_POS 0
|
||||
#define E1_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_E2(L6470)
|
||||
@@ -2198,7 +2214,7 @@
|
||||
#define E2_OVERCURRENT 2000
|
||||
#define E2_STALLCURRENT 1500
|
||||
#define E2_MAX_VOLTAGE 127
|
||||
#define E2_CHAIN_POS 0
|
||||
#define E2_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_E3(L6470)
|
||||
@@ -2206,7 +2222,7 @@
|
||||
#define E3_OVERCURRENT 2000
|
||||
#define E3_STALLCURRENT 1500
|
||||
#define E3_MAX_VOLTAGE 127
|
||||
#define E3_CHAIN_POS 0
|
||||
#define E3_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_E4(L6470)
|
||||
@@ -2214,7 +2230,7 @@
|
||||
#define E4_OVERCURRENT 2000
|
||||
#define E4_STALLCURRENT 1500
|
||||
#define E4_MAX_VOLTAGE 127
|
||||
#define E4_CHAIN_POS 0
|
||||
#define E4_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_E5(L6470)
|
||||
@@ -2222,7 +2238,7 @@
|
||||
#define E5_OVERCURRENT 2000
|
||||
#define E5_STALLCURRENT 1500
|
||||
#define E5_MAX_VOLTAGE 127
|
||||
#define E5_CHAIN_POS 0
|
||||
#define E5_CHAIN_POS -1
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2019 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
////////////////////////////
|
||||
// VENDOR VERSION EXAMPLE //
|
||||
////////////////////////////
|
||||
|
||||
/**
|
||||
* Marlin release version identifier
|
||||
*/
|
||||
#define SHORT_BUILD_VERSION "2.0.x_SX4H"
|
||||
|
||||
/**
|
||||
* Verbose version identifier which should contain a reference to the location
|
||||
* from where the binary was downloaded or the source code was compiled.
|
||||
*/
|
||||
#define DETAILED_BUILD_VERSION SHORT_BUILD_VERSION " TM3D"
|
||||
|
||||
/**
|
||||
* The STRING_DISTRIBUTION_DATE represents when the binary file was built,
|
||||
* here we define this default string as the date where the latest release
|
||||
* version was tagged.
|
||||
*/
|
||||
#define STRING_DISTRIBUTION_DATE "2019-10-19"
|
||||
|
||||
/**
|
||||
* Defines a generic printer name to be output to the LCD after booting Marlin.
|
||||
*/
|
||||
#define MACHINE_NAME "TM3D SX4"
|
||||
|
||||
/**
|
||||
* The SOURCE_CODE_URL is the location where users will find the Marlin Source
|
||||
* Code which is installed on the device. In most cases —unless the manufacturer
|
||||
* has a distinct Github fork— the Source Code URL should just be the main
|
||||
* Marlin repository.
|
||||
*/
|
||||
#define SOURCE_CODE_URL "https://github.com/InsanityAutomation/Marlin/tree/TM_SX4_2.0"
|
||||
|
||||
/**
|
||||
* Default generic printer UUID.
|
||||
*/
|
||||
//#define DEFAULT_MACHINE_UUID "cede2a2f-41a2-4748-9b12-c55c62f367ff"
|
||||
|
||||
/**
|
||||
* The WEBSITE_URL is the location where users can get more information such as
|
||||
* documentation about a specific Marlin release.
|
||||
*/
|
||||
#define WEBSITE_URL "tinymachines3d.com"
|
||||
|
||||
/**
|
||||
* Set the vendor info the serial USB interface, if changable
|
||||
* Currently only supported by DUE platform
|
||||
*/
|
||||
//#define USB_DEVICE_VENDOR_ID 0x0000
|
||||
//#define USB_DEVICE_PRODUCT_ID 0x0000
|
||||
//#define USB_DEVICE_MANUFACTURE_NAME WEBSITE_URL
|
||||
@@ -24,3 +24,9 @@
|
||||
#include "platforms.h"
|
||||
|
||||
#include HAL_PATH(.,HAL.h)
|
||||
|
||||
inline void watchdog_refresh() {
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
HAL_watchdog_refresh();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -146,8 +146,7 @@ extern "C" {
|
||||
#define DISABLE_TEMPERATURE_INTERRUPT() CBI(TIMSK0, OCIE0B)
|
||||
#define TEMPERATURE_ISR_ENABLED() TEST(TIMSK0, OCIE0B)
|
||||
|
||||
FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
|
||||
UNUSED(frequency);
|
||||
FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) {
|
||||
switch (timer_num) {
|
||||
case STEP_TIMER_NUM:
|
||||
// waveform generation = 0100 = CTC
|
||||
|
||||
@@ -184,15 +184,10 @@ void spiBegin() {
|
||||
// nop to tune soft SPI timing
|
||||
#define nop asm volatile ("\tnop\n")
|
||||
|
||||
// Set SPI rate
|
||||
void spiInit(uint8_t spiRate) {
|
||||
UNUSED(spiRate); // nothing to do
|
||||
}
|
||||
void spiInit(uint8_t) { /* do nothing */ }
|
||||
|
||||
// Begin SPI transaction, set clock, bit order, data mode
|
||||
void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
|
||||
UNUSED(spiBeginTransaction); // nothing to do
|
||||
}
|
||||
void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { /* do nothing */ }
|
||||
|
||||
// Soft SPI receive byte
|
||||
uint8_t spiRec() {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include "../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if ENABLED(FAST_PWM_FAN)
|
||||
#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_PWM
|
||||
|
||||
#include "HAL.h"
|
||||
|
||||
@@ -278,5 +278,5 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255
|
||||
}
|
||||
}
|
||||
|
||||
#endif // FAST_PWM_FAN
|
||||
#endif // FAST_PWM_FAN || SPINDLE_LASER_PWM
|
||||
#endif // __AVR__
|
||||
|
||||
@@ -227,18 +227,9 @@ static void print_is_also_tied() { SERIAL_ECHOPGM(" is also tied to this pin");
|
||||
void com_print(uint8_t N, uint8_t Z) {
|
||||
const uint8_t *TCCRA = (uint8_t*)TCCR_A(N);
|
||||
SERIAL_ECHOPGM(" COM");
|
||||
SERIAL_CHAR(N + '0');
|
||||
switch (Z) {
|
||||
case 'A':
|
||||
SERIAL_ECHOPAIR("A: ", ((*TCCRA & (_BV(7) | _BV(6))) >> 6));
|
||||
break;
|
||||
case 'B':
|
||||
SERIAL_ECHOPAIR("B: ", ((*TCCRA & (_BV(5) | _BV(4))) >> 4));
|
||||
break;
|
||||
case 'C':
|
||||
SERIAL_ECHOPAIR("C: ", ((*TCCRA & (_BV(3) | _BV(2))) >> 2));
|
||||
break;
|
||||
}
|
||||
SERIAL_CHAR('0' + N);
|
||||
SERIAL_CHAR('A' + Z);
|
||||
SERIAL_ECHOPAIR(": ", int((*TCCRA >> (6 - Z * 2)) & 0x03));
|
||||
}
|
||||
|
||||
void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N - WGM bit layout
|
||||
|
||||
@@ -28,4 +28,4 @@ void watchdog_init();
|
||||
|
||||
// Reset watchdog. MUST be called at least every 4 seconds after the
|
||||
// first watchdog_init or AVR will go into emergency procedures.
|
||||
inline void watchdog_reset() { wdt_reset(); }
|
||||
inline void HAL_watchdog_refresh() { wdt_reset(); }
|
||||
|
||||
@@ -87,7 +87,7 @@ extern "C" {
|
||||
// Return free memory between end of heap (or end bss) and whatever is current
|
||||
int freeMemory() {
|
||||
int free_memory, heap_end = (int)_sbrk(0);
|
||||
return (int)&free_memory - (heap_end ? heap_end : (int)&_ebss);
|
||||
return (int)&free_memory - (heap_end ?: (int)&_ebss);
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
|
||||
@@ -38,22 +38,39 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Serial ports
|
||||
#if !WITHIN(SERIAL_PORT, -1, 3)
|
||||
#error "SERIAL_PORT must be from -1 to 3"
|
||||
// Define MYSERIAL0/1 before MarlinSerial includes!
|
||||
#if SERIAL_PORT == -1
|
||||
#define MYSERIAL0 Serial1
|
||||
#elif SERIAL_PORT == 0
|
||||
#define MYSERIAL0 Serial
|
||||
#elif SERIAL_PORT == 1
|
||||
#define MYSERIAL0 Serial1
|
||||
#elif SERIAL_PORT == 2
|
||||
#define MYSERIAL0 Serial2
|
||||
#elif SERIAL_PORT == 3
|
||||
#define MYSERIAL0 Serial3
|
||||
#else
|
||||
#error "The required SERIAL_PORT must be from -1 to 3. Please update your configuration."
|
||||
#endif
|
||||
|
||||
// MYSERIAL0 required before MarlinSerial includes!
|
||||
#define MYSERIAL0 customizedSerial1
|
||||
|
||||
#ifdef SERIAL_PORT_2
|
||||
#if !WITHIN(SERIAL_PORT_2, -1, 3)
|
||||
#error "SERIAL_PORT_2 must be from -1 to 3"
|
||||
#elif SERIAL_PORT_2 == SERIAL_PORT
|
||||
#error "SERIAL_PORT_2 must be different than SERIAL_PORT"
|
||||
#if SERIAL_PORT_2 == SERIAL_PORT
|
||||
#error "SERIAL_PORT_2 must be different from SERIAL_PORT. Please update your configuration."
|
||||
#endif
|
||||
#if SERIAL_PORT_2 == -1
|
||||
#define MYSERIAL1 Serial1
|
||||
#elif SERIAL_PORT_2 == 0
|
||||
#define MYSERIAL1 Serial
|
||||
#elif SERIAL_PORT_2 == 1
|
||||
#define MYSERIAL1 Serial1
|
||||
#elif SERIAL_PORT_2 == 2
|
||||
#define MYSERIAL1 Serial2
|
||||
#elif SERIAL_PORT_2 == 3
|
||||
#define MYSERIAL1 Serial3
|
||||
#else
|
||||
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
|
||||
#endif
|
||||
#define NUM_SERIAL 2
|
||||
#define MYSERIAL1 customizedSerial2
|
||||
#else
|
||||
#define NUM_SERIAL 1
|
||||
#endif
|
||||
|
||||
@@ -151,13 +151,12 @@
|
||||
(((uint32_t)(addr) & 0xF0000000) + 0x02000000 + ((uint32_t)(addr)&0xFFFFF)*32 + (bit)*4)
|
||||
|
||||
// run at ~8 .. ~10Mhz - Rx version (Tx line not altered)
|
||||
static uint8_t spiTransferRx0(uint8_t bout) { // using Mode 0
|
||||
static uint8_t spiTransferRx0(uint8_t) { // using Mode 0
|
||||
uint32_t bin = 0;
|
||||
uint32_t work = 0;
|
||||
uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(MISO_PIN))+0x3C, PIN_SHIFT(MISO_PIN)); /* PDSR of port in bitband area */
|
||||
uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30; /* SODR of port */
|
||||
uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
|
||||
UNUSED(bout);
|
||||
|
||||
/* The software SPI routine */
|
||||
__asm__ __volatile__(
|
||||
|
||||
@@ -55,12 +55,9 @@ static int pending_char = -1;
|
||||
#endif
|
||||
|
||||
// Public Methods
|
||||
void MarlinSerialUSB::begin(const long baud_setting) {
|
||||
UNUSED(baud_setting);
|
||||
}
|
||||
void MarlinSerialUSB::begin(const long) {}
|
||||
|
||||
void MarlinSerialUSB::end() {
|
||||
}
|
||||
void MarlinSerialUSB::end() {}
|
||||
|
||||
int MarlinSerialUSB::peek() {
|
||||
if (pending_char >= 0)
|
||||
|
||||
@@ -50,7 +50,7 @@ const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
|
||||
{ TC0, 0, TC0_IRQn, 3}, // 0 - [servo timer5]
|
||||
{ TC0, 1, TC1_IRQn, 0}, // 1
|
||||
{ TC0, 2, TC2_IRQn, 2}, // 2 - stepper
|
||||
{ TC1, 0, TC3_IRQn, 0}, // 3
|
||||
{ TC1, 0, TC3_IRQn, 0}, // 3 - stepper for BOARD_ARCHIM1
|
||||
{ TC1, 1, TC4_IRQn, 15}, // 4 - temperature
|
||||
{ TC1, 2, TC5_IRQn, 3}, // 5 - [servo timer3]
|
||||
{ TC2, 0, TC6_IRQn, 14}, // 6 - tone
|
||||
|
||||
@@ -39,7 +39,9 @@ typedef uint32_t hal_timer_t;
|
||||
|
||||
#define HAL_TIMER_RATE ((F_CPU) / 2) // frequency of timers peripherals
|
||||
|
||||
#ifndef STEP_TIMER_NUM
|
||||
#define STEP_TIMER_NUM 2 // index of timer to use for stepper
|
||||
#endif
|
||||
#define TEMP_TIMER_NUM 4 // index of timer to use for temperature
|
||||
#define PULSE_TIMER_NUM STEP_TIMER_NUM
|
||||
#define TONE_TIMER_NUM 6 // index of timer to use for beeper tones
|
||||
@@ -61,7 +63,9 @@ typedef uint32_t hal_timer_t;
|
||||
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
|
||||
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
|
||||
|
||||
#define HAL_STEP_TIMER_ISR() void TC2_Handler()
|
||||
#ifndef HAL_STEP_TIMER_ISR
|
||||
#define HAL_STEP_TIMER_ISR() void TC2_Handler()
|
||||
#endif
|
||||
#define HAL_TEMP_TIMER_ISR() void TC4_Handler()
|
||||
#define HAL_TONE_TIMER_ISR() void TC6_Handler()
|
||||
|
||||
|
||||
@@ -48,9 +48,7 @@
|
||||
#define _CONF_USB_H_
|
||||
|
||||
#undef UNUSED /* To avoid a macro clash as macros.h already defines it */
|
||||
#include "../../../core/macros.h" /* For ENABLED()/DISABLED() */
|
||||
#include "../../../core/boards.h" /* For MB() */
|
||||
#include "../../../../Configuration.h" /* For CUSTOM_MACHINE_NAME definition - We just need the name, no C++ allowed! */
|
||||
#include "../../../inc/MarlinConfigPre.h"
|
||||
#include "compiler.h"
|
||||
|
||||
/**
|
||||
@@ -59,8 +57,6 @@
|
||||
*/
|
||||
|
||||
//! Device definition (mandatory)
|
||||
#define USB_DEVICE_VENDOR_ID 0x03EB /* ATMEL VID */
|
||||
#define USB_DEVICE_PRODUCT_ID 0x2424 /* MSC / CDC */
|
||||
#define USB_DEVICE_MAJOR_VERSION 1
|
||||
#define USB_DEVICE_MINOR_VERSION 0
|
||||
#define USB_DEVICE_POWER 100 // Consumption on Vbus line (mA)
|
||||
@@ -70,15 +66,6 @@
|
||||
// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_SELF_POWERED)
|
||||
// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED)
|
||||
|
||||
//! USB Device string definitions (Optional)
|
||||
#define USB_DEVICE_MANUFACTURE_NAME "marlinfw.org"
|
||||
#ifdef CUSTOM_MACHINE_NAME
|
||||
#define USB_DEVICE_PRODUCT_NAME CUSTOM_MACHINE_NAME
|
||||
#else
|
||||
#define USB_DEVICE_PRODUCT_NAME "3D Printer"
|
||||
#endif
|
||||
#define USB_DEVICE_SERIAL_NAME "123985739853"
|
||||
|
||||
/**
|
||||
* Device speeds support
|
||||
* Low speed not supported by CDC and MSC
|
||||
|
||||
@@ -33,19 +33,12 @@ Ctrl_status sd_mmc_spi_read_capacity(uint32_t *nb_sector) {
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
|
||||
bool sd_mmc_spi_unload(bool unload) {
|
||||
UNUSED(unload);
|
||||
return true;
|
||||
}
|
||||
bool sd_mmc_spi_unload(bool) { return true; }
|
||||
|
||||
bool sd_mmc_spi_wr_protect() {
|
||||
return false;
|
||||
}
|
||||
bool sd_mmc_spi_wr_protect() { return false; }
|
||||
|
||||
bool sd_mmc_spi_removal() {
|
||||
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted())
|
||||
return true;
|
||||
return false;
|
||||
return (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted());
|
||||
}
|
||||
|
||||
#if ACCESS_USB == true
|
||||
|
||||
@@ -30,4 +30,4 @@ void watchdog_init();
|
||||
|
||||
// Reset watchdog. MUST be called at least every 4 seconds after the
|
||||
// first watchdog_init or AVR will go into emergency procedures.
|
||||
inline void watchdog_reset() { watchdogReset(); }
|
||||
inline void HAL_watchdog_refresh() { watchdogReset(); }
|
||||
|
||||
@@ -187,19 +187,21 @@ void HAL_adc_start_conversion(uint8_t adc_pin) {
|
||||
const adc1_channel_t chan = get_channel(adc_pin);
|
||||
uint32_t mv;
|
||||
esp_adc_cal_get_voltage((adc_channel_t)chan, &characteristics[attenuations[chan]], &mv);
|
||||
HAL_adc_result = mv * 1023.0 / 3300.0;
|
||||
|
||||
// Change the attenuation level based on the new reading
|
||||
adc_atten_t atten;
|
||||
if (mv < thresholds[ADC_ATTEN_DB_0] - 100)
|
||||
adc1_set_attenuation(chan, ADC_ATTEN_DB_0);
|
||||
atten = ADC_ATTEN_DB_0;
|
||||
else if (mv > thresholds[ADC_ATTEN_DB_0] - 50 && mv < thresholds[ADC_ATTEN_DB_2_5] - 100)
|
||||
adc1_set_attenuation(chan, ADC_ATTEN_DB_2_5);
|
||||
atten = ADC_ATTEN_DB_2_5;
|
||||
else if (mv > thresholds[ADC_ATTEN_DB_2_5] - 50 && mv < thresholds[ADC_ATTEN_DB_6] - 100)
|
||||
adc1_set_attenuation(chan, ADC_ATTEN_DB_6);
|
||||
atten = ADC_ATTEN_DB_6;
|
||||
else if (mv > thresholds[ADC_ATTEN_DB_6] - 50)
|
||||
adc1_set_attenuation(chan, ADC_ATTEN_DB_11);
|
||||
atten = ADC_ATTEN_DB_11;
|
||||
else return;
|
||||
|
||||
HAL_adc_result = mv * 1023.0 / 3300.0;
|
||||
adc1_set_attenuation(chan, atten);
|
||||
}
|
||||
|
||||
void analogWrite(pin_t pin, int value) {
|
||||
|
||||
@@ -25,4 +25,4 @@
|
||||
void watchdog_init();
|
||||
|
||||
// Reset watchdog.
|
||||
inline void watchdog_reset() { }
|
||||
inline void HAL_watchdog_refresh() {}
|
||||
|
||||
@@ -78,7 +78,7 @@ extern HalSerial usb_serial;
|
||||
#define ENABLE_ISRS()
|
||||
#define DISABLE_ISRS()
|
||||
|
||||
inline void HAL_init() { }
|
||||
inline void HAL_init() {}
|
||||
|
||||
// Utility functions
|
||||
#pragma GCC diagnostic push
|
||||
@@ -97,6 +97,10 @@ void HAL_adc_enable_channel(int pin);
|
||||
void HAL_adc_start_conversion(const uint8_t adc_pin);
|
||||
uint16_t HAL_adc_get_result();
|
||||
|
||||
// Reset source
|
||||
inline void HAL_clear_reset_source(void) {}
|
||||
inline uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; }
|
||||
|
||||
/* ---------------- Delay in cycles */
|
||||
FORCE_INLINE static void DELAY_CYCLES(uint64_t x) {
|
||||
Clock::delayCycles(x);
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
// Interrupts
|
||||
void cli() { } // Disable
|
||||
void sei() { } // Enable
|
||||
void sei() { } // Enable
|
||||
|
||||
// Time functions
|
||||
void _delay_ms(const int delay_ms) {
|
||||
|
||||
@@ -83,9 +83,9 @@ public:
|
||||
|
||||
HalSerial() { host_connected = true; }
|
||||
|
||||
void begin(int32_t baud) { }
|
||||
void begin(int32_t) {}
|
||||
|
||||
void end() { }
|
||||
void end() {}
|
||||
|
||||
int peek() {
|
||||
uint8_t value;
|
||||
|
||||
@@ -29,18 +29,8 @@
|
||||
#include "watchdog.h"
|
||||
|
||||
void watchdog_init() {}
|
||||
void HAL_watchdog_refresh() {}
|
||||
|
||||
void HAL_clear_reset_source() {}
|
||||
|
||||
uint8_t HAL_get_reset_source() {
|
||||
return RST_POWER_ON;
|
||||
}
|
||||
|
||||
void watchdog_reset() {}
|
||||
|
||||
#else
|
||||
void HAL_clear_reset_source() {}
|
||||
uint8_t HAL_get_reset_source() { return RST_POWER_ON; }
|
||||
#endif // USE_WATCHDOG
|
||||
#endif
|
||||
|
||||
#endif // __PLAT_LINUX__
|
||||
|
||||
@@ -24,6 +24,4 @@
|
||||
#define WDT_TIMEOUT 4000000 // 4 second timeout
|
||||
|
||||
void watchdog_init();
|
||||
void watchdog_reset();
|
||||
void HAL_clear_reset_source();
|
||||
uint8_t HAL_get_reset_source();
|
||||
void HAL_watchdog_refresh();
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
#include "../shared/Delay.h"
|
||||
#include "../../../gcode/parser.h"
|
||||
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
#include "watchdog.h"
|
||||
#endif
|
||||
|
||||
// U8glib required functions
|
||||
extern "C" void u8g_xMicroDelay(uint16_t val) {
|
||||
DELAY_US(val);
|
||||
@@ -65,4 +69,17 @@ void flashFirmware(int16_t value) {
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
void HAL_clear_reset_source(void) {
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
watchdog_clear_timeout_flag();
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t HAL_get_reset_source(void) {
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
if (watchdog_timed_out()) return RST_WATCHDOG;
|
||||
#endif
|
||||
return RST_POWER_ON;
|
||||
}
|
||||
|
||||
#endif // TARGET_LPC1768
|
||||
|
||||
@@ -164,3 +164,7 @@ void set_pwm_frequency(const pin_t pin, int f_desired);
|
||||
* Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
|
||||
*/
|
||||
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
|
||||
|
||||
// Reset source
|
||||
void HAL_clear_reset_source(void);
|
||||
uint8_t HAL_get_reset_source(void);
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
void end() { }
|
||||
void end() {}
|
||||
|
||||
#if ENABLED(EMERGENCY_PARSER)
|
||||
bool recv_callback(const char c) override {
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include "../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if ENABLED(FAST_PWM_FAN)
|
||||
#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_PWM
|
||||
|
||||
#include <pwm.h>
|
||||
|
||||
@@ -36,5 +36,5 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255
|
||||
pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size);
|
||||
}
|
||||
|
||||
#endif // FAST_PWM_FAN
|
||||
#endif // FAST_PWM_FAN || SPINDLE_LASER_PWM
|
||||
#endif // TARGET_LPC1768
|
||||
|
||||
@@ -155,7 +155,7 @@ void HAL_idletask() {
|
||||
// a PC via USB.
|
||||
// Other HALs use IS_SD_PRINTING() and IS_SD_FILE_OPEN() to check for access but
|
||||
// this will not reliably detect delete operations. To be safe we will lock
|
||||
// the disk if Marlin has it mounted. Unfortuately there is currently no way
|
||||
// the disk if Marlin has it mounted. Unfortunately there is currently no way
|
||||
// to unmount the disk from the LCD menu.
|
||||
// if (IS_SD_PRINTING() || IS_SD_FILE_OPEN())
|
||||
if (card.isMounted())
|
||||
|
||||
@@ -31,7 +31,7 @@ try:
|
||||
#
|
||||
import subprocess
|
||||
# typical result (string): 'Drives: C:\ D:\ E:\ F:\ G:\ H:\ I:\ J:\ K:\ L:\ M:\ Y:\ Z:\'
|
||||
driveStr = subprocess.check_output("fsutil fsinfo drives")
|
||||
driveStr = subprocess.check_output("fsutil fsinfo drives").decode('utf8')
|
||||
# typical result (string): 'C:\ D:\ E:\ F:\ G:\ H:\ I:\ J:\ K:\ L:\ M:\ Y:\ Z:\'
|
||||
driveStr = driveStr.strip().lstrip('Drives: ')
|
||||
# typical result (array of stings): ['C:\\', 'D:\\', 'E:\\', 'F:\\',
|
||||
@@ -44,7 +44,7 @@ try:
|
||||
for drive in drives:
|
||||
final_drive_name = drive.strip().rstrip('\\') # typical result (string): 'C:'
|
||||
try:
|
||||
volume_info = subprocess.check_output('cmd /C dir ' + final_drive_name, stderr=subprocess.STDOUT)
|
||||
volume_info = subprocess.check_output('cmd /C dir ' + final_drive_name, stderr=subprocess.STDOUT).decode('utf8')
|
||||
except Exception as e:
|
||||
continue
|
||||
else:
|
||||
|
||||
@@ -56,28 +56,16 @@ void watchdog_init() {
|
||||
WDT_Start(WDT_TIMEOUT);
|
||||
}
|
||||
|
||||
void HAL_clear_reset_source() {
|
||||
WDT_ClrTimeOutFlag();
|
||||
}
|
||||
|
||||
uint8_t HAL_get_reset_source() {
|
||||
if (TEST(WDT_ReadTimeOutFlag(), 0)) return RST_WATCHDOG;
|
||||
return RST_POWER_ON;
|
||||
}
|
||||
|
||||
void watchdog_reset() {
|
||||
void HAL_watchdog_refresh() {
|
||||
WDT_Feed();
|
||||
#if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED)
|
||||
TOGGLE(LED_PIN); // heartbeat indicator
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void watchdog_init() {}
|
||||
void watchdog_reset() {}
|
||||
void HAL_clear_reset_source() {}
|
||||
uint8_t HAL_get_reset_source() { return RST_POWER_ON; }
|
||||
// Timeout state
|
||||
bool watchdog_timed_out() { return TEST(WDT_ReadTimeOutFlag(), 0); }
|
||||
void watchdog_clear_timeout_flag() { WDT_ClrTimeOutFlag(); }
|
||||
|
||||
#endif // USE_WATCHDOG
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#define WDT_TIMEOUT 4000000 // 4 second timeout
|
||||
|
||||
void watchdog_init();
|
||||
void watchdog_reset();
|
||||
void HAL_clear_reset_source();
|
||||
uint8_t HAL_get_reset_source();
|
||||
void HAL_watchdog_refresh();
|
||||
|
||||
bool watchdog_timed_out();
|
||||
void watchdog_clear_timeout_flag();
|
||||
|
||||
@@ -414,7 +414,7 @@ extern "C" {
|
||||
// Return free memory between end of heap (or end bss) and whatever is current
|
||||
int freeMemory() {
|
||||
int free_memory, heap_end = (int)_sbrk(0);
|
||||
return (int)&free_memory - (heap_end ? heap_end : (int)&__bss_end__);
|
||||
return (int)&free_memory - (heap_end ?: (int)&__bss_end__);
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
WDT->INTENCLR.reg = WDT_INTENCLR_EW; // Disable early warning interrupt
|
||||
WDT->CONFIG.reg = WDT_CONFIG_PER_CYC4096; // Set at least 4s period for chip reset
|
||||
|
||||
watchdog_reset();
|
||||
HAL_watchdog_refresh();
|
||||
|
||||
WDT->CTRLA.reg = WDT_CTRLA_ENABLE; // Start watchdog now in normal mode
|
||||
SYNC(WDT->SYNCBUSY.bit.ENABLE);
|
||||
|
||||
@@ -25,7 +25,7 @@ void watchdog_init();
|
||||
|
||||
// Reset watchdog. MUST be called at least every 4 seconds after the
|
||||
// first watchdog_init or SAMD will go into emergency procedures.
|
||||
inline void watchdog_reset() {
|
||||
inline void HAL_watchdog_refresh() {
|
||||
SYNC(WDT->SYNCBUSY.bit.CLEAR); // Test first if previous is 'ongoing' to save time waiting for command execution
|
||||
WDT->CLEAR.reg = WDT_CLEAR_CLEAR_KEY;
|
||||
}
|
||||
|
||||
@@ -104,17 +104,11 @@ extern "C" {
|
||||
// ADC
|
||||
// ------------------------
|
||||
|
||||
void HAL_adc_start_conversion(const uint8_t adc_pin) {
|
||||
HAL_adc_result = analogRead(adc_pin);
|
||||
}
|
||||
// TODO: Make sure this doesn't cause any delay
|
||||
void HAL_adc_start_conversion(const uint8_t adc_pin) { HAL_adc_result = analogRead(adc_pin); }
|
||||
|
||||
uint16_t HAL_adc_get_result() {
|
||||
return HAL_adc_result;
|
||||
}
|
||||
uint16_t HAL_adc_get_result() { return HAL_adc_result; }
|
||||
|
||||
void flashFirmware(int16_t value) {
|
||||
UNUSED(value);
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
void flashFirmware(int16_t) { NVIC_SystemReset(); }
|
||||
|
||||
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
void watchdog_init() { IWatchdog.begin(4000000); } // 4 sec timeout
|
||||
|
||||
void watchdog_reset() {
|
||||
void HAL_watchdog_refresh() {
|
||||
IWatchdog.reload();
|
||||
#if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED)
|
||||
TOGGLE(LED_PIN); // heartbeat indicator
|
||||
|
||||
@@ -22,4 +22,4 @@
|
||||
#pragma once
|
||||
|
||||
void watchdog_init();
|
||||
void watchdog_reset();
|
||||
void HAL_watchdog_refresh();
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
|
||||
#ifdef __STM32F1__
|
||||
|
||||
#include "HAL.h"
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include "HAL.h"
|
||||
|
||||
#include <STM32ADC.h>
|
||||
|
||||
@@ -233,7 +233,7 @@ void HAL_idletask() {
|
||||
// a PC via USB.
|
||||
// Other HALs use IS_SD_PRINTING() and IS_SD_FILE_OPEN() to check for access but
|
||||
// this will not reliably detect delete operations. To be safe we will lock
|
||||
// the disk if Marlin has it mounted. Unfortuately there is currently no way
|
||||
// the disk if Marlin has it mounted. Unfortunately there is currently no way
|
||||
// to unmount the disk from the LCD menu.
|
||||
// if (IS_SD_PRINTING() || IS_SD_FILE_OPEN())
|
||||
/* copy from lpc1768 framework, should be fixed later for process SHARED_SD_CARD*/
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
|
||||
#ifdef __STM32F1__
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include "HAL.h"
|
||||
|
||||
#include "timers.h"
|
||||
|
||||
// ------------------------
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <libmaple/timer.h>
|
||||
#include "../../core/boards.h"
|
||||
|
||||
// ------------------------
|
||||
// Defines
|
||||
@@ -54,7 +55,13 @@ typedef uint16_t hal_timer_t;
|
||||
#define TEMP_TIMER_NUM 2 // index of timer to use for temperature
|
||||
//#define TEMP_TIMER_NUM 4 // 2->4, Timer 2 for Stepper Current PWM
|
||||
#define PULSE_TIMER_NUM STEP_TIMER_NUM
|
||||
#define SERVO0_TIMER_NUM 1 // SERVO0 or BLTOUCH
|
||||
|
||||
#if MB(BIGTREE_SKR_MINI_E3, BIGTREE_SKR_E3_DIP, BTT_SKR_MINI_E3_V1_2, MKS_ROBIN_LITE)
|
||||
// SKR Mini E3 boards use PA8 as FAN_PIN, so TIMER 1 is used for Fan PWM.
|
||||
#define SERVO0_TIMER_NUM 8
|
||||
#else
|
||||
#define SERVO0_TIMER_NUM 1 // SERVO0 or BLTOUCH
|
||||
#endif
|
||||
|
||||
#define STEP_TIMER_IRQ_PRIO 1
|
||||
#define TEMP_TIMER_IRQ_PRIO 2
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include <libmaple/iwdg.h>
|
||||
#include "watchdog.h"
|
||||
|
||||
void watchdog_reset() {
|
||||
void HAL_watchdog_refresh() {
|
||||
#if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED)
|
||||
TOGGLE(LED_PIN); // heartbeat indicator
|
||||
#endif
|
||||
|
||||
@@ -41,4 +41,4 @@ void watchdog_init();
|
||||
|
||||
// Reset watchdog. MUST be called at least every 4 seconds after the
|
||||
// first watchdog_init or STM32F1 will reset.
|
||||
void watchdog_reset();
|
||||
void HAL_watchdog_refresh();
|
||||
|
||||
@@ -150,7 +150,7 @@ extern uint16_t HAL_adc_result;
|
||||
// Memory related
|
||||
#define __bss_end __bss_end__
|
||||
|
||||
inline void HAL_init() { }
|
||||
inline void HAL_init() {}
|
||||
|
||||
// Clear reset reason
|
||||
void HAL_clear_reset_source();
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
void watchdog_reset() {
|
||||
void HAL_watchdog_refresh() {
|
||||
/* Refresh IWDG: reload counter */
|
||||
if (HAL_IWDG_Refresh(&hiwdg) != HAL_OK) {
|
||||
/* Refresh Error */
|
||||
|
||||
@@ -24,4 +24,4 @@
|
||||
extern IWDG_HandleTypeDef hiwdg;
|
||||
|
||||
void watchdog_init();
|
||||
void watchdog_reset();
|
||||
void HAL_watchdog_refresh();
|
||||
|
||||
@@ -87,7 +87,7 @@ typedef int8_t pin_t;
|
||||
#undef pgm_read_word
|
||||
#define pgm_read_word(addr) (*((uint16_t*)(addr)))
|
||||
|
||||
inline void HAL_init() { }
|
||||
inline void HAL_init() {}
|
||||
|
||||
// Clear the reset reason
|
||||
void HAL_clear_reset_source();
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
void watchdog_init();
|
||||
|
||||
inline void watchdog_reset() {
|
||||
inline void HAL_watchdog_refresh() {
|
||||
// Watchdog refresh sequence
|
||||
WDOG_REFRESH = 0xA602;
|
||||
WDOG_REFRESH = 0xB480;
|
||||
|
||||
@@ -93,7 +93,7 @@ typedef int8_t pin_t;
|
||||
#undef pgm_read_word
|
||||
#define pgm_read_word(addr) (*((uint16_t*)(addr)))
|
||||
|
||||
inline void HAL_init() { }
|
||||
inline void HAL_init() {}
|
||||
|
||||
// Clear reset reason
|
||||
void HAL_clear_reset_source();
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
void watchdog_init();
|
||||
|
||||
inline void watchdog_reset() {
|
||||
inline void HAL_watchdog_refresh() {
|
||||
// Watchdog refresh sequence
|
||||
WDOG_REFRESH = 0xA602;
|
||||
WDOG_REFRESH = 0xB480;
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
FORCE_INLINE static void DELAY_CYCLES(const uint32_t x) {
|
||||
const uint32_t endCycles = getCycleCount() + x;
|
||||
while (PENDING(getCycleCount(), endCycles)) { }
|
||||
while (PENDING(getCycleCount(), endCycles)) {}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
+34
-115
@@ -173,10 +173,6 @@
|
||||
#include "feature/prusa_MMU2/mmu2.h"
|
||||
#endif
|
||||
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
#include "lcd/extensible_ui/ui_api.h"
|
||||
#endif
|
||||
|
||||
#if HAS_DRIVER(L6470)
|
||||
#include "libs/L6470/L6470_Marlin.h"
|
||||
#endif
|
||||
@@ -279,6 +275,10 @@ void quickstop_stepper() {
|
||||
sync_plan_position();
|
||||
}
|
||||
|
||||
void enable_e_steppers() {
|
||||
enable_E0(); enable_E1(); enable_E2(); enable_E3(); enable_E4(); enable_E5();
|
||||
}
|
||||
|
||||
void enable_all_steppers() {
|
||||
#if ENABLED(AUTO_POWER_CONTROL)
|
||||
powerManager.power_on();
|
||||
@@ -286,30 +286,11 @@ void enable_all_steppers() {
|
||||
enable_X();
|
||||
enable_Y();
|
||||
enable_Z();
|
||||
enable_E0();
|
||||
enable_E1();
|
||||
enable_E2();
|
||||
enable_E3();
|
||||
enable_E4();
|
||||
enable_E5();
|
||||
}
|
||||
|
||||
void enable_e_steppers() {
|
||||
enable_E0();
|
||||
enable_E1();
|
||||
enable_E2();
|
||||
enable_E3();
|
||||
enable_E4();
|
||||
enable_E5();
|
||||
enable_e_steppers();
|
||||
}
|
||||
|
||||
void disable_e_steppers() {
|
||||
disable_E0();
|
||||
disable_E1();
|
||||
disable_E2();
|
||||
disable_E3();
|
||||
disable_E4();
|
||||
disable_E5();
|
||||
disable_E0(); disable_E1(); disable_E2(); disable_E3(); disable_E4(); disable_E5();
|
||||
}
|
||||
|
||||
void disable_e_stepper(const uint8_t e) {
|
||||
@@ -330,71 +311,6 @@ void disable_all_steppers() {
|
||||
disable_e_steppers();
|
||||
}
|
||||
|
||||
#if HAS_FILAMENT_SENSOR
|
||||
|
||||
void event_filament_runout() {
|
||||
|
||||
#if ENABLED(ADVANCED_PAUSE_FEATURE)
|
||||
if (did_pause_print) return; // Action already in progress. Purge triggered repeated runout.
|
||||
#endif
|
||||
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::onFilamentRunout(ExtUI::getActiveTool());
|
||||
#endif
|
||||
|
||||
#if EITHER(HOST_PROMPT_SUPPORT, HOST_ACTION_COMMANDS)
|
||||
const char tool = '0'
|
||||
#if NUM_RUNOUT_SENSORS > 1
|
||||
+ active_extruder
|
||||
#endif
|
||||
;
|
||||
#endif
|
||||
|
||||
//action:out_of_filament
|
||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||
host_prompt_reason = PROMPT_FILAMENT_RUNOUT;
|
||||
host_action_prompt_end();
|
||||
host_action_prompt_begin(PSTR("FilamentRunout T"), false);
|
||||
SERIAL_CHAR(tool);
|
||||
SERIAL_EOL();
|
||||
host_action_prompt_show();
|
||||
#endif
|
||||
|
||||
const bool run_runout_script = !runout.host_handling;
|
||||
|
||||
#if ENABLED(HOST_ACTION_COMMANDS)
|
||||
if (run_runout_script
|
||||
&& ( strstr(FILAMENT_RUNOUT_SCRIPT, "M600")
|
||||
|| strstr(FILAMENT_RUNOUT_SCRIPT, "M125")
|
||||
#if ENABLED(ADVANCED_PAUSE_FEATURE)
|
||||
|| strstr(FILAMENT_RUNOUT_SCRIPT, "M25")
|
||||
#endif
|
||||
)
|
||||
) {
|
||||
host_action_paused(false);
|
||||
}
|
||||
else {
|
||||
// Legacy Repetier command for use until newer version supports standard dialog
|
||||
// To be removed later when pause command also triggers dialog
|
||||
#ifdef ACTION_ON_FILAMENT_RUNOUT
|
||||
host_action(PSTR(ACTION_ON_FILAMENT_RUNOUT " T"), false);
|
||||
SERIAL_CHAR(tool);
|
||||
SERIAL_EOL();
|
||||
#endif
|
||||
|
||||
host_action_pause(false);
|
||||
}
|
||||
SERIAL_ECHOPGM(" " ACTION_REASON_ON_FILAMENT_RUNOUT " ");
|
||||
SERIAL_CHAR(tool);
|
||||
SERIAL_EOL();
|
||||
#endif // HOST_ACTION_COMMANDS
|
||||
|
||||
if (run_runout_script)
|
||||
queue.inject_P(PSTR(FILAMENT_RUNOUT_SCRIPT));
|
||||
}
|
||||
|
||||
#endif // HAS_FILAMENT_SENSOR
|
||||
|
||||
#if ENABLED(G29_RETRY_AND_RECOVER)
|
||||
|
||||
void event_probe_failure() {
|
||||
@@ -408,7 +324,7 @@ void disable_all_steppers() {
|
||||
#ifdef ACTION_ON_CANCEL
|
||||
host_action_cancel();
|
||||
#endif
|
||||
kill(PSTR(MSG_ERR_PROBING_FAILED));
|
||||
kill(GET_TEXT(MSG_LCD_PROBING_FAILED));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -426,6 +342,20 @@ void disable_all_steppers() {
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Printing is active when the print job timer is running
|
||||
*/
|
||||
bool printingIsActive() {
|
||||
return print_job_timer.isRunning() || IS_SD_PRINTING();
|
||||
}
|
||||
|
||||
/**
|
||||
* Printing is paused according to SD or host indicators
|
||||
*/
|
||||
bool printingIsPaused() {
|
||||
return print_job_timer.isPaused() || IS_SD_PAUSED();
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage several activities:
|
||||
* - Check for Filament Runout
|
||||
@@ -582,10 +512,10 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) {
|
||||
}
|
||||
#endif // !SWITCHING_EXTRUDER
|
||||
|
||||
const float olde = current_position[E_AXIS];
|
||||
current_position[E_AXIS] += EXTRUDER_RUNOUT_EXTRUDE;
|
||||
planner.buffer_line(current_position, MMM_TO_MMS(EXTRUDER_RUNOUT_SPEED), active_extruder);
|
||||
current_position[E_AXIS] = olde;
|
||||
const float olde = current_position.e;
|
||||
current_position.e += EXTRUDER_RUNOUT_EXTRUDE;
|
||||
line_to_current_position(MMM_TO_MMS(EXTRUDER_RUNOUT_SPEED));
|
||||
current_position.e = olde;
|
||||
planner.set_e_position_mm(olde);
|
||||
planner.synchronize();
|
||||
|
||||
@@ -629,7 +559,7 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) {
|
||||
if (delayed_move_time && ELAPSED(ms, delayed_move_time + 1000UL) && IsRunning()) {
|
||||
// travel moves have been received so enact them
|
||||
delayed_move_time = 0xFFFFFFFFUL; // force moves to be done
|
||||
set_destination_from_current();
|
||||
destination = current_position;
|
||||
prepare_move_to_destination();
|
||||
}
|
||||
#endif
|
||||
@@ -756,15 +686,16 @@ void idle(
|
||||
* Kill all activity and lock the machine.
|
||||
* After this the machine will need to be reset.
|
||||
*/
|
||||
void kill(PGM_P const lcd_msg/*=nullptr*/, const bool steppers_off/*=false*/) {
|
||||
void kill(PGM_P const lcd_error/*=nullptr*/, PGM_P const lcd_component/*=nullptr*/, const bool steppers_off/*=false*/) {
|
||||
thermalManager.disable_all_heaters();
|
||||
|
||||
SERIAL_ERROR_MSG(MSG_ERR_KILLED);
|
||||
|
||||
#if HAS_DISPLAY
|
||||
ui.kill_screen(lcd_msg ? lcd_msg : PSTR(MSG_KILLED));
|
||||
ui.kill_screen(lcd_error ?: GET_TEXT(MSG_KILLED), lcd_component);
|
||||
#else
|
||||
UNUSED(lcd_msg);
|
||||
UNUSED(lcd_error);
|
||||
UNUSED(lcd_component);
|
||||
#endif
|
||||
|
||||
#ifdef ACTION_ON_KILL
|
||||
@@ -801,29 +732,17 @@ void minkill(const bool steppers_off/*=false*/) {
|
||||
#if HAS_KILL
|
||||
|
||||
// Wait for kill to be released
|
||||
while (!READ(KILL_PIN)) {
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
watchdog_reset();
|
||||
#endif
|
||||
}
|
||||
while (!READ(KILL_PIN)) watchdog_refresh();
|
||||
|
||||
// Wait for kill to be pressed
|
||||
while (READ(KILL_PIN)) {
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
watchdog_reset();
|
||||
#endif
|
||||
}
|
||||
while (READ(KILL_PIN)) watchdog_refresh();
|
||||
|
||||
void (*resetFunc)() = 0; // Declare resetFunc() at address 0
|
||||
resetFunc(); // Jump to address 0
|
||||
|
||||
#else // !HAS_KILL
|
||||
|
||||
for (;;) {
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
watchdog_reset();
|
||||
#endif
|
||||
} // Wait for reset
|
||||
for (;;) watchdog_refresh(); // Wait for reset
|
||||
|
||||
#endif // !HAS_KILL
|
||||
}
|
||||
@@ -1002,7 +921,7 @@ void setup() {
|
||||
|
||||
#if HAS_M206_COMMAND
|
||||
// Initialize current position based on home_offset
|
||||
LOOP_XYZ(a) current_position[a] += home_offset[a];
|
||||
current_position += home_offset;
|
||||
#endif
|
||||
|
||||
// Vital to init stepper/planner equivalent for current_position
|
||||
|
||||
+4
-5
@@ -322,7 +322,7 @@ void disable_e_stepper(const uint8_t e);
|
||||
void disable_e_steppers();
|
||||
void disable_all_steppers();
|
||||
|
||||
void kill(PGM_P const lcd_msg=nullptr, const bool steppers_off=false);
|
||||
void kill(PGM_P const lcd_error=nullptr, PGM_P const lcd_component=nullptr, const bool steppers_off=false);
|
||||
void minkill(const bool steppers_off=false);
|
||||
|
||||
void quickstop_stepper();
|
||||
@@ -331,6 +331,9 @@ extern bool Running;
|
||||
inline bool IsRunning() { return Running; }
|
||||
inline bool IsStopped() { return !Running; }
|
||||
|
||||
bool printingIsActive();
|
||||
bool printingIsPaused();
|
||||
|
||||
extern bool wait_for_heatup;
|
||||
|
||||
#if HAS_RESUME_CONTINUE
|
||||
@@ -368,10 +371,6 @@ void protected_pin_err();
|
||||
inline void suicide() { OUT_WRITE(SUICIDE_PIN, LOW); }
|
||||
#endif
|
||||
|
||||
#if HAS_FILAMENT_SENSOR
|
||||
void event_filament_runout();
|
||||
#endif
|
||||
|
||||
#if ENABLED(G29_RETRY_AND_RECOVER)
|
||||
void event_probe_recover();
|
||||
void event_probe_failure();
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
#define BOARD_UNKNOWN -1
|
||||
|
||||
//
|
||||
@@ -255,9 +257,9 @@
|
||||
// STM32 ARM Cortex-M3
|
||||
//
|
||||
|
||||
#define BOARD_STM32F103R 4000 // STM32F103R Libmaple-based STM32F1 controller
|
||||
#define BOARD_STM32F103RE 4000 // STM32F103RE Libmaple-based STM32F1 controller
|
||||
#define BOARD_MALYAN_M200 4001 // STM32C8T6 Libmaple-based STM32F1 controller
|
||||
#define BOARD_STM3R_MINI 4002 // STM32F103R Libmaple-based STM32F1 controller
|
||||
#define BOARD_STM3R_MINI 4002 // STM32F103RE Libmaple-based STM32F1 controller
|
||||
#define BOARD_GTM32_PRO_VB 4003 // STM32F103VET6 controller
|
||||
#define BOARD_MORPHEUS 4004 // STM32F103C8 / STM32F103CB Libmaple-based STM32F1 controller
|
||||
#define BOARD_CHITU3D 4005 // Chitu3D (STM32F103RET6)
|
||||
@@ -268,11 +270,12 @@
|
||||
#define BOARD_BIGTREE_SKR_MINI_V1_1 4010 // BigTreeTech SKR Mini v1.1 (STM32F103RC)
|
||||
#define BOARD_BIGTREE_SKR_MINI_E3 4011 // BigTreeTech SKR Mini E3 (STM32F103RC)
|
||||
#define BOARD_BIGTREE_SKR_E3_DIP 4012 // BigTreeTech SKR E3 DIP V1.0 (STM32F103RC)
|
||||
#define BOARD_JGAURORA_A5S_A1 4013 // JGAurora A5S A1 (STM32F103ZET6)
|
||||
#define BOARD_FYSETC_AIO_II 4014 // FYSETC AIO_II
|
||||
#define BOARD_FYSETC_CHEETAH 4015 // FYSETC Cheetah
|
||||
#define BOARD_FYSETC_CHEETAH_V12 4016 // FYSETC Cheetah V1.2
|
||||
#define BOARD_LONGER3D_LK 4017 // Alfawise U20/U20+/U30 (Longer3D LK1/2) / STM32F103VET6
|
||||
#define BOARD_BTT_SKR_MINI_E3_V1_2 4013 // BigTreeTech SKR Mini E3 V1.2 (STM32F103RC)
|
||||
#define BOARD_JGAURORA_A5S_A1 4014 // JGAurora A5S A1 (STM32F103ZET6)
|
||||
#define BOARD_FYSETC_AIO_II 4015 // FYSETC AIO_II
|
||||
#define BOARD_FYSETC_CHEETAH 4016 // FYSETC Cheetah
|
||||
#define BOARD_FYSETC_CHEETAH_V12 4017 // FYSETC Cheetah V1.2
|
||||
#define BOARD_LONGER3D_LK 4018 // Alfawise U20/U20+/U30 (Longer3D LK1/2) / STM32F103VET6
|
||||
|
||||
//
|
||||
// ARM Cortex-M4F
|
||||
@@ -307,7 +310,7 @@
|
||||
//
|
||||
// Espressif ESP32 WiFi
|
||||
//
|
||||
#define BOARD_ESP32 6000
|
||||
#define BOARD_ESPRESSIF_ESP32 6000
|
||||
|
||||
//
|
||||
// Simulations
|
||||
@@ -315,4 +318,7 @@
|
||||
|
||||
#define BOARD_LINUX_RAMPS 9999
|
||||
|
||||
#define MB(board) (defined(BOARD_##board) && MOTHERBOARD==BOARD_##board)
|
||||
#define _MB_1(B) (defined(BOARD_##B) && MOTHERBOARD==BOARD_##B)
|
||||
#define MB(V...) DO(MB,||,V)
|
||||
|
||||
#define IS_MELZI MB(MELZI, MELZI_CREALITY, MELZI_MAKR3D, MELZI_MALYAN, MELZI_TRONXY)
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2019 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Axis indices as enumerated constants
|
||||
*
|
||||
* - X_AXIS, Y_AXIS, and Z_AXIS should be used for axes in Cartesian space
|
||||
* - A_AXIS, B_AXIS, and C_AXIS should be used for Steppers, corresponding to XYZ on Cartesians
|
||||
* - X_HEAD, Y_HEAD, and Z_HEAD should be used for Steppers on Core kinematics
|
||||
*/
|
||||
enum AxisEnum : unsigned char {
|
||||
X_AXIS = 0,
|
||||
A_AXIS = 0,
|
||||
Y_AXIS = 1,
|
||||
B_AXIS = 1,
|
||||
Z_AXIS = 2,
|
||||
C_AXIS = 2,
|
||||
E_AXIS = 3,
|
||||
X_HEAD = 4,
|
||||
Y_HEAD = 5,
|
||||
Z_HEAD = 6,
|
||||
E0_AXIS = 3,
|
||||
E1_AXIS = 4,
|
||||
E2_AXIS = 5,
|
||||
E3_AXIS = 6,
|
||||
E4_AXIS = 7,
|
||||
E5_AXIS = 8,
|
||||
ALL_AXES = 0xFE,
|
||||
NO_AXIS = 0xFF
|
||||
};
|
||||
|
||||
#define LOOP_S_LE_N(VAR, S, N) for (uint8_t VAR=(S); VAR<=(N); VAR++)
|
||||
#define LOOP_S_L_N(VAR, S, N) for (uint8_t VAR=(S); VAR<(N); VAR++)
|
||||
#define LOOP_LE_N(VAR, N) LOOP_S_LE_N(VAR, 0, N)
|
||||
#define LOOP_L_N(VAR, N) LOOP_S_L_N(VAR, 0, N)
|
||||
|
||||
#define LOOP_NA(VAR) LOOP_L_N(VAR, NUM_AXIS)
|
||||
#define LOOP_XYZ(VAR) LOOP_S_LE_N(VAR, X_AXIS, Z_AXIS)
|
||||
#define LOOP_XYZE(VAR) LOOP_S_LE_N(VAR, X_AXIS, E_AXIS)
|
||||
#define LOOP_XYZE_N(VAR) LOOP_S_L_N(VAR, X_AXIS, XYZE_N)
|
||||
#define LOOP_ABC(VAR) LOOP_S_LE_N(VAR, A_AXIS, C_AXIS)
|
||||
#define LOOP_ABCE(VAR) LOOP_S_LE_N(VAR, A_AXIS, E_AXIS)
|
||||
#define LOOP_ABCE_N(VAR) LOOP_S_L_N(VAR, A_AXIS, XYZE_N)
|
||||
+66
-63
@@ -49,7 +49,7 @@
|
||||
// da Danish
|
||||
// de German
|
||||
// el Greek
|
||||
// el-gr Greek (Greece)
|
||||
// el_gr Greek (Greece)
|
||||
// en English
|
||||
// es Spanish
|
||||
// eu Basque-Euskera
|
||||
@@ -58,12 +58,12 @@
|
||||
// gl Galician
|
||||
// hr Croatian
|
||||
// it Italian
|
||||
// jp-kana Japanese
|
||||
// jp_kana Japanese
|
||||
// ko_KR Korean (South Korea)
|
||||
// nl Dutch
|
||||
// pl Polish
|
||||
// pt Portuguese
|
||||
// pt-br Portuguese (Brazilian)
|
||||
// pt_br Portuguese (Brazilian)
|
||||
// ru Russian
|
||||
// sk Slovak
|
||||
// tr Turkish
|
||||
@@ -97,7 +97,20 @@
|
||||
// #define STRING_SPLASH_LINE3 WEBSITE_URL
|
||||
//#endif
|
||||
|
||||
#if HAS_GRAPHICAL_LCD
|
||||
#if HAS_CHARACTER_LCD
|
||||
|
||||
// Custom characters defined in the first 8 characters of the LCD
|
||||
#define LCD_STR_BEDTEMP "\x00" // Print only as a char. This will have 'unexpected' results when used in a string!
|
||||
#define LCD_STR_DEGREE "\x01"
|
||||
#define LCD_STR_THERMOMETER "\x02" // Still used with string concatenation
|
||||
#define LCD_STR_UPLEVEL "\x03"
|
||||
#define LCD_STR_REFRESH "\x04"
|
||||
#define LCD_STR_FOLDER "\x05"
|
||||
#define LCD_STR_FEEDRATE "\x06"
|
||||
#define LCD_STR_CLOCK "\x07"
|
||||
#define LCD_STR_ARROW_RIGHT ">" /* from the default character set */
|
||||
|
||||
#else
|
||||
//
|
||||
// Custom characters from Marlin_symbols.fon which was merged into ISO10646-0-3.bdf
|
||||
// \x00 intentionally skipped to avoid problems in strings
|
||||
@@ -120,19 +133,6 @@
|
||||
#define LCD_STR_FILAM_DIA "\xF8"
|
||||
#define LCD_STR_FILAM_MUL "\xA4"
|
||||
|
||||
#elif HAS_CHARACTER_LCD
|
||||
|
||||
// Custom characters defined in the first 8 characters of the LCD
|
||||
#define LCD_STR_BEDTEMP "\x00" // Print only as a char. This will have 'unexpected' results when used in a string!
|
||||
#define LCD_STR_DEGREE "\x01"
|
||||
#define LCD_STR_THERMOMETER "\x02" // Still used with string concatenation
|
||||
#define LCD_STR_UPLEVEL "\x03"
|
||||
#define LCD_STR_REFRESH "\x04"
|
||||
#define LCD_STR_FOLDER "\x05"
|
||||
#define LCD_STR_FEEDRATE "\x06"
|
||||
#define LCD_STR_CLOCK "\x07"
|
||||
#define LCD_STR_ARROW_RIGHT ">" /* from the default character set */
|
||||
|
||||
#endif
|
||||
|
||||
// Common LCD messages
|
||||
@@ -168,7 +168,6 @@
|
||||
#define MSG_INVALID_E_STEPPER "Invalid E stepper"
|
||||
#define MSG_E_STEPPER_NOT_SPECIFIED "E stepper not specified"
|
||||
#define MSG_INVALID_SOLENOID "Invalid solenoid"
|
||||
#define MSG_ERR_NO_THERMISTORS "No thermistors - no temperature"
|
||||
#define MSG_M115_REPORT "FIRMWARE_NAME:Marlin " DETAILED_BUILD_VERSION " SOURCE_CODE_URL:" SOURCE_CODE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID
|
||||
#define MSG_COUNT_X " Count X:"
|
||||
#define MSG_COUNT_A " Count A:"
|
||||
@@ -243,10 +242,9 @@
|
||||
#define MSG_ERR_COLD_EXTRUDE_STOP " cold extrusion prevented"
|
||||
#define MSG_ERR_LONG_EXTRUDE_STOP " too long extrusion prevented"
|
||||
#define MSG_ERR_HOTEND_TOO_COLD "Hotend too cold"
|
||||
#define MSG_ERR_Z_HOMING_SER "Home XY first"
|
||||
#define MSG_ERR_EEPROM_WRITE "Error writing to EEPROM!"
|
||||
|
||||
#define MSG_FILAMENT_CHANGE_HEAT "Press button (or M108) to heat nozzle"
|
||||
#define MSG_FILAMENT_CHANGE_INSERT "Insert filament and press button (or M108)"
|
||||
#define MSG_FILAMENT_CHANGE_WAIT "Press button (or M108) to resume"
|
||||
#define MSG_FILAMENT_CHANGE_HEAT_LCD "Press button to heat nozzle"
|
||||
#define MSG_FILAMENT_CHANGE_INSERT_LCD "Insert filament and press button"
|
||||
#define MSG_FILAMENT_CHANGE_WAIT_LCD "Press button to resume"
|
||||
@@ -254,8 +252,6 @@
|
||||
#define MSG_FILAMENT_CHANGE_INSERT_M108 "Insert filament and send M108"
|
||||
#define MSG_FILAMENT_CHANGE_WAIT_M108 "Send M108 to resume"
|
||||
|
||||
#define MSG_ERR_EEPROM_WRITE "Error writing to EEPROM!"
|
||||
|
||||
#define MSG_STOP_BLTOUCH "STOP called because of BLTouch error - restart with M999"
|
||||
#define MSG_STOP_UNHOMED "STOP called because of unhomed error - restart with M999"
|
||||
#define MSG_KILL_INACTIVE_TIME "KILL caused by too much inactive time - current command: "
|
||||
@@ -298,6 +294,8 @@
|
||||
#define MSG_T_THERMAL_RUNAWAY "Thermal Runaway"
|
||||
#define MSG_T_MAXTEMP "MAXTEMP triggered"
|
||||
#define MSG_T_MINTEMP "MINTEMP triggered"
|
||||
#define MSG_ERR_PROBING_FAILED "Probing Failed"
|
||||
#define MSG_ZPROBE_OUT_SER "Z Probe Past Bed"
|
||||
|
||||
// Debug
|
||||
#define MSG_DEBUG_PREFIX "DEBUG:"
|
||||
@@ -313,11 +311,9 @@
|
||||
|
||||
#define LANGUAGE_DATA_INCL_(M) STRINGIFY_(fontdata/langdata_##M.h)
|
||||
#define LANGUAGE_DATA_INCL(M) LANGUAGE_DATA_INCL_(M)
|
||||
#define INCLUDE_LANGUAGE_DATA LANGUAGE_DATA_INCL(LCD_LANGUAGE)
|
||||
|
||||
#define LANGUAGE_INCL_(M) STRINGIFY_(../lcd/language/language_##M.h)
|
||||
#define LANGUAGE_INCL(M) LANGUAGE_INCL_(M)
|
||||
#define INCLUDE_LANGUAGE LANGUAGE_INCL(LCD_LANGUAGE)
|
||||
|
||||
// Never translate these strings
|
||||
#define MSG_X "X"
|
||||
@@ -337,38 +333,52 @@
|
||||
#define MSG_Y2 "Y2"
|
||||
#define MSG_Z2 "Z2"
|
||||
#define MSG_Z3 "Z3"
|
||||
#define MSG_H1 "1"
|
||||
#define MSG_H2 "2"
|
||||
#define MSG_H3 "3"
|
||||
#define MSG_H4 "4"
|
||||
#define MSG_H5 "5"
|
||||
#define MSG_H6 "6"
|
||||
#define MSG_LCD_N0 " 1"
|
||||
#define MSG_LCD_N1 " 2"
|
||||
#define MSG_LCD_N2 " 3"
|
||||
#define MSG_LCD_N3 " 4"
|
||||
#define MSG_LCD_N4 " 5"
|
||||
#define MSG_LCD_N5 " 6"
|
||||
#define MSG_E1 "E1"
|
||||
#define MSG_E2 "E2"
|
||||
#define MSG_E3 "E3"
|
||||
#define MSG_E4 "E4"
|
||||
#define MSG_E5 "E5"
|
||||
#define MSG_E6 "E6"
|
||||
#define MSG_MOVE_E1 "1"
|
||||
#define MSG_MOVE_E2 "2"
|
||||
#define MSG_MOVE_E3 "3"
|
||||
#define MSG_MOVE_E4 "4"
|
||||
#define MSG_MOVE_E5 "5"
|
||||
#define MSG_MOVE_E6 "6"
|
||||
#define MSG_DIAM_E1 " 1"
|
||||
#define MSG_DIAM_E2 " 2"
|
||||
#define MSG_DIAM_E3 " 3"
|
||||
#define MSG_DIAM_E4 " 4"
|
||||
#define MSG_DIAM_E5 " 5"
|
||||
#define MSG_DIAM_E6 " 6"
|
||||
|
||||
#include INCLUDE_LANGUAGE
|
||||
#define LCD_STR_A MSG_A
|
||||
#define LCD_STR_B MSG_B
|
||||
#define LCD_STR_C MSG_C
|
||||
#define LCD_STR_E MSG_E
|
||||
|
||||
/**
|
||||
* Tool indexes for LCD display only
|
||||
*
|
||||
* By convention the LCD shows "E1" for the first extruder.
|
||||
* However, internal to Marlin E0/T0 is the first tool, and
|
||||
* most board silkscreens say "E0." Zero-based labels will
|
||||
* make these indexes consistent but this defies expectation.
|
||||
*
|
||||
*/
|
||||
#if ENABLED(NUMBER_TOOLS_FROM_0)
|
||||
#define LCD_STR_N0 "0"
|
||||
#define LCD_STR_N1 "1"
|
||||
#define LCD_STR_N2 "2"
|
||||
#define LCD_STR_N3 "3"
|
||||
#define LCD_STR_N4 "4"
|
||||
#define LCD_STR_N5 "5"
|
||||
#else
|
||||
#define LCD_STR_N0 "1"
|
||||
#define LCD_STR_N1 "2"
|
||||
#define LCD_STR_N2 "3"
|
||||
#define LCD_STR_N3 "4"
|
||||
#define LCD_STR_N4 "5"
|
||||
#define LCD_STR_N5 "6"
|
||||
#endif
|
||||
|
||||
#define LCD_STR_E0 "E" LCD_STR_N0
|
||||
#define LCD_STR_E1 "E" LCD_STR_N1
|
||||
#define LCD_STR_E2 "E" LCD_STR_N2
|
||||
#define LCD_STR_E3 "E" LCD_STR_N3
|
||||
#define LCD_STR_E4 "E" LCD_STR_N4
|
||||
#define LCD_STR_E5 "E" LCD_STR_N5
|
||||
|
||||
#include "multi_language.h" // Allow multiple languages
|
||||
|
||||
#include "../lcd/language/language_en.h"
|
||||
#include LANGUAGE_INCL(LCD_LANGUAGE)
|
||||
#include LANGUAGE_INCL(LCD_LANGUAGE_2)
|
||||
#include LANGUAGE_INCL(LCD_LANGUAGE_3)
|
||||
#include LANGUAGE_INCL(LCD_LANGUAGE_4)
|
||||
#include LANGUAGE_INCL(LCD_LANGUAGE_5)
|
||||
|
||||
#if NONE(DISPLAY_CHARSET_ISO10646_1, \
|
||||
DISPLAY_CHARSET_ISO10646_5, \
|
||||
@@ -381,10 +391,3 @@
|
||||
DISPLAY_CHARSET_ISO10646_SK)
|
||||
#define DISPLAY_CHARSET_ISO10646_1 // use the better font on full graphic displays.
|
||||
#endif
|
||||
|
||||
#include "../lcd/language/language_en.h"
|
||||
|
||||
#ifdef CUSTOM_USER_MENU_TITLE
|
||||
#undef MSG_USER_MENU
|
||||
#define MSG_USER_MENU CUSTOM_USER_MENU_TITLE
|
||||
#endif
|
||||
|
||||
+23
-25
@@ -21,11 +21,11 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define NUM_AXIS 4
|
||||
#define ABCE 4
|
||||
#define XYZE 4
|
||||
#define ABC 3
|
||||
#define XYZ 3
|
||||
#define XY 2
|
||||
|
||||
#define _AXIS(A) (A##_AXIS)
|
||||
|
||||
@@ -205,25 +205,29 @@
|
||||
}while(0)
|
||||
|
||||
// Macros for initializing arrays
|
||||
#define ARRAY_16(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,...) { A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P }
|
||||
#define ARRAY_15(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,...) { A,B,C,D,E,F,G,H,I,J,K,L,M,N,O }
|
||||
#define ARRAY_14(A,B,C,D,E,F,G,H,I,J,K,L,M,N,...) { A,B,C,D,E,F,G,H,I,J,K,L,M,N }
|
||||
#define ARRAY_13(A,B,C,D,E,F,G,H,I,J,K,L,M,...) { A,B,C,D,E,F,G,H,I,J,K,L,M }
|
||||
#define ARRAY_12(A,B,C,D,E,F,G,H,I,J,K,L,...) { A,B,C,D,E,F,G,H,I,J,K,L }
|
||||
#define ARRAY_11(A,B,C,D,E,F,G,H,I,J,K,...) { A,B,C,D,E,F,G,H,I,J,K }
|
||||
#define ARRAY_10(A,B,C,D,E,F,G,H,I,J,...) { A,B,C,D,E,F,G,H,I,J }
|
||||
#define ARRAY_9( A,B,C,D,E,F,G,H,I,...) { A,B,C,D,E,F,G,H,I }
|
||||
#define ARRAY_8( A,B,C,D,E,F,G,H,...) { A,B,C,D,E,F,G,H }
|
||||
#define ARRAY_7( A,B,C,D,E,F,G,...) { A,B,C,D,E,F,G }
|
||||
#define ARRAY_6( A,B,C,D,E,F,...) { A,B,C,D,E,F }
|
||||
#define ARRAY_5( A,B,C,D,E,...) { A,B,C,D,E }
|
||||
#define ARRAY_4( A,B,C,D,...) { A,B,C,D }
|
||||
#define ARRAY_3( A,B,C,...) { A,B,C }
|
||||
#define ARRAY_2( A,B,...) { A,B }
|
||||
#define ARRAY_1( A,...) { A }
|
||||
#define LIST_16(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P
|
||||
#define LIST_15(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O
|
||||
#define LIST_14(A,B,C,D,E,F,G,H,I,J,K,L,M,N,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N
|
||||
#define LIST_13(A,B,C,D,E,F,G,H,I,J,K,L,M,...) A,B,C,D,E,F,G,H,I,J,K,L,M
|
||||
#define LIST_12(A,B,C,D,E,F,G,H,I,J,K,L,...) A,B,C,D,E,F,G,H,I,J,K,L
|
||||
#define LIST_11(A,B,C,D,E,F,G,H,I,J,K,...) A,B,C,D,E,F,G,H,I,J,K
|
||||
#define LIST_10(A,B,C,D,E,F,G,H,I,J,...) A,B,C,D,E,F,G,H,I,J
|
||||
#define LIST_9( A,B,C,D,E,F,G,H,I,...) A,B,C,D,E,F,G,H,I
|
||||
#define LIST_8( A,B,C,D,E,F,G,H,...) A,B,C,D,E,F,G,H
|
||||
#define LIST_7( A,B,C,D,E,F,G,...) A,B,C,D,E,F,G
|
||||
#define LIST_6( A,B,C,D,E,F,...) A,B,C,D,E,F
|
||||
#define LIST_5( A,B,C,D,E,...) A,B,C,D,E
|
||||
#define LIST_4( A,B,C,D,...) A,B,C,D
|
||||
#define LIST_3( A,B,C,...) A,B,C
|
||||
#define LIST_2( A,B,...) A,B
|
||||
#define LIST_1( A,...) A
|
||||
|
||||
#define _ARRAY_N(N,V...) ARRAY_##N(V)
|
||||
#define ARRAY_N(N,V...) _ARRAY_N(N,V)
|
||||
#define _LIST_N(N,V...) LIST_##N(V)
|
||||
#define LIST_N(N,V...) _LIST_N(N,V)
|
||||
#define ARRAY_N(N,V...) { _LIST_N(N,V) }
|
||||
|
||||
#define _JOIN_1(O) (O)
|
||||
#define JOIN_N(N,C,V...) (DO(JOIN,C,LIST_N(N,V)))
|
||||
|
||||
// Macros for adding
|
||||
#define INC_0 1
|
||||
@@ -251,12 +255,6 @@
|
||||
#define DECREMENT_(n) DEC_##n
|
||||
#define DECREMENT(n) DECREMENT_(n)
|
||||
|
||||
// Feedrate
|
||||
typedef float feedRate_t;
|
||||
#define MMM_TO_MMS(MM_M) ((MM_M)/60.0f)
|
||||
#define MMS_TO_MMM(MM_S) ((MM_S)*60.0f)
|
||||
#define MMS_SCALED(V) ((V) * 0.01f * feedrate_percentage)
|
||||
|
||||
#define NOOP (void(0))
|
||||
|
||||
#define CEILING(x,y) (((x) + (y) - 1) / (y))
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/********************
|
||||
* multi_language.h *
|
||||
********************/
|
||||
|
||||
/****************************************************************************
|
||||
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* To view a copy of the GNU General Public License, go to the following *
|
||||
* location: <http://www.gnu.org/licenses/>. *
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
typedef const char Language_Str[];
|
||||
|
||||
#if defined(LCD_LANGUAGE_5)
|
||||
#define NUM_LANGUAGES 5
|
||||
#elif defined(LCD_LANGUAGE_4)
|
||||
#define NUM_LANGUAGES 4
|
||||
#elif defined(LCD_LANGUAGE_3)
|
||||
#define NUM_LANGUAGES 3
|
||||
#elif defined(LCD_LANGUAGE_2)
|
||||
#define NUM_LANGUAGES 2
|
||||
#else
|
||||
#define NUM_LANGUAGES 1
|
||||
#endif
|
||||
|
||||
// Setting the unused languages equal to each other allows
|
||||
// the compiler to optimize away the conditionals
|
||||
|
||||
#ifndef LCD_LANGUAGE_2
|
||||
#define LCD_LANGUAGE_2 LCD_LANGUAGE
|
||||
#endif
|
||||
|
||||
#ifndef LCD_LANGUAGE_3
|
||||
#define LCD_LANGUAGE_3 LCD_LANGUAGE_2
|
||||
#endif
|
||||
|
||||
#ifndef LCD_LANGUAGE_4
|
||||
#define LCD_LANGUAGE_4 LCD_LANGUAGE_3
|
||||
#endif
|
||||
|
||||
#ifndef LCD_LANGUAGE_5
|
||||
#define LCD_LANGUAGE_5 LCD_LANGUAGE_4
|
||||
#endif
|
||||
|
||||
#define _GET_LANG(LANG) Language_##LANG
|
||||
#define GET_LANG(LANG) _GET_LANG(LANG)
|
||||
|
||||
#if NUM_LANGUAGES > 1
|
||||
extern uint8_t lang;
|
||||
#define GET_TEXT(MSG) ( \
|
||||
lang == 0 ? GET_LANG(LCD_LANGUAGE)::MSG : \
|
||||
lang == 1 ? GET_LANG(LCD_LANGUAGE_2)::MSG : \
|
||||
lang == 2 ? GET_LANG(LCD_LANGUAGE_3)::MSG : \
|
||||
lang == 3 ? GET_LANG(LCD_LANGUAGE_4)::MSG : \
|
||||
GET_LANG(LCD_LANGUAGE_5)::MSG \
|
||||
)
|
||||
#define MAX_LANG_CHARSIZE _MAX(GET_LANG(LCD_LANGUAGE)::CHARSIZE, \
|
||||
GET_LANG(LCD_LANGUAGE_2)::CHARSIZE, \
|
||||
GET_LANG(LCD_LANGUAGE_3)::CHARSIZE, \
|
||||
GET_LANG(LCD_LANGUAGE_4)::CHARSIZE, \
|
||||
GET_LANG(LCD_LANGUAGE_5)::CHARSIZE)
|
||||
#else
|
||||
#define GET_TEXT(MSG) GET_LANG(LCD_LANGUAGE)::MSG
|
||||
#define MAX_LANG_CHARSIZE GET_LANG(LCD_LANGUAGE)::CHARSIZE
|
||||
#endif
|
||||
#define GET_TEXT_F(MSG) (const __FlashStringHelper*)GET_TEXT(MSG)
|
||||
|
||||
#define MSG_CONCAT(A,B) pgm_p_pair_t(GET_TEXT(A),GET_TEXT(B))
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#include "serial.h"
|
||||
#include "language.h"
|
||||
#include "enum.h"
|
||||
|
||||
uint8_t marlin_debug_flags = MARLIN_DEBUG_NONE;
|
||||
|
||||
@@ -68,12 +67,8 @@ void print_bin(const uint16_t val) {
|
||||
}
|
||||
}
|
||||
|
||||
void print_xyz(PGM_P const prefix, PGM_P const suffix, const float &x, const float &y, const float &z) {
|
||||
void print_xyz(const float &x, const float &y, const float &z, PGM_P const prefix/*=nullptr*/, PGM_P const suffix/*=nullptr*/) {
|
||||
serialprintPGM(prefix);
|
||||
SERIAL_ECHOPAIR(" " MSG_X, x, " " MSG_Y, y, " " MSG_Z, z);
|
||||
if (suffix) serialprintPGM(suffix); else SERIAL_EOL();
|
||||
}
|
||||
|
||||
void print_xyz(PGM_P const prefix, PGM_P const suffix, const float xyz[]) {
|
||||
print_xyz(prefix, suffix, xyz[X_AXIS], xyz[Y_AXIS], xyz[Z_AXIS]);
|
||||
}
|
||||
|
||||
@@ -139,14 +139,41 @@ extern uint8_t marlin_debug_flags;
|
||||
#define _SELP_21(a,b,V...) do{ _SEP_2(a,b); _SELP_19(V); }while(0)
|
||||
#define _SELP_22(a,b,V...) do{ _SEP_2(a,b); _SELP_20(V); }while(0)
|
||||
#define _SELP_23(a,b,V...) do{ _SEP_2(a,b); _SELP_21(V); }while(0)
|
||||
#define _SELP_24(a,b,V...) do{ _SEP_2(a,b); _SELP_22(V); }while(0)
|
||||
#define _SELP_24(a,b,V...) do{ _SEP_2(a,b); _SELP_22(V); }while(0) // Use up two, pass the rest up
|
||||
|
||||
#define SERIAL_ECHOLNPAIR(V...) _SELP_N(NUM_ARGS(V),V)
|
||||
|
||||
// Print up to 20 comma-separated pairs of values
|
||||
#define __SLST_N(N,V...) _SLST_##N(V)
|
||||
#define _SLST_N(N,V...) __SLST_N(N,V)
|
||||
#define _SLST_1(a) SERIAL_ECHO(a)
|
||||
#define _SLST_2(a,b) do{ SERIAL_ECHO(a); SERIAL_ECHOPAIR(", ",b); }while(0)
|
||||
#define _SLST_3(a,b,c) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_1(c); }while(0)
|
||||
#define _SLST_4(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_2(V); }while(0)
|
||||
#define _SLST_5(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_3(V); }while(0)
|
||||
#define _SLST_6(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_4(V); }while(0)
|
||||
#define _SLST_7(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_5(V); }while(0)
|
||||
#define _SLST_8(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_6(V); }while(0)
|
||||
#define _SLST_9(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_7(V); }while(0)
|
||||
#define _SLST_10(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_8(V); }while(0)
|
||||
#define _SLST_11(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_9(V); }while(0)
|
||||
#define _SLST_12(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_10(V); }while(0)
|
||||
#define _SLST_13(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_11(V); }while(0)
|
||||
#define _SLST_14(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_12(V); }while(0)
|
||||
#define _SLST_15(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_13(V); }while(0)
|
||||
#define _SLST_16(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_14(V); }while(0)
|
||||
#define _SLST_17(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_15(V); }while(0)
|
||||
#define _SLST_18(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_16(V); }while(0)
|
||||
#define _SLST_19(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_17(V); }while(0)
|
||||
#define _SLST_20(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_18(V); }while(0) // Use up two, pass the rest up
|
||||
|
||||
#define SERIAL_ECHOLIST(pre,V...) do{ SERIAL_ECHOPGM(pre); _SLST_N(NUM_ARGS(V),V); }while(0)
|
||||
#define SERIAL_ECHOLIST_N(N,V...) _SLST_N(N,LIST_N(N,V))
|
||||
|
||||
#define SERIAL_ECHOPGM(S) (serialprintPGM(PSTR(S)))
|
||||
#define SERIAL_ECHOLNPGM(S) (serialprintPGM(PSTR(S "\n")))
|
||||
|
||||
#define SERIAL_ECHOPAIR_F(S, V...) do{ SERIAL_ECHOPGM(S); SERIAL_ECHO_F(V); }while(0)
|
||||
#define SERIAL_ECHOPAIR_F(S,V...) do{ SERIAL_ECHOPGM(S); SERIAL_ECHO_F(V); }while(0)
|
||||
#define SERIAL_ECHOLNPAIR_F(V...) do{ SERIAL_ECHOPAIR_F(V); SERIAL_EOL(); }while(0)
|
||||
|
||||
#define SERIAL_ECHO_START() serial_echo_start()
|
||||
@@ -186,7 +213,11 @@ void serial_spaces(uint8_t count);
|
||||
|
||||
void print_bin(const uint16_t val);
|
||||
|
||||
void print_xyz(PGM_P const prefix, PGM_P const suffix, const float xyz[]);
|
||||
void print_xyz(PGM_P const prefix, PGM_P const suffix, const float &x, const float &y, const float &z);
|
||||
#define SERIAL_POS(SUFFIX,VAR) do { print_xyz(PSTR(" " STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n"), VAR); }while(0)
|
||||
#define SERIAL_XYZ(PREFIX,V...) do { print_xyz(PSTR(PREFIX), nullptr, V); }while(0)
|
||||
void print_xyz(const float &x, const float &y, const float &z, PGM_P const prefix=nullptr, PGM_P const suffix=nullptr);
|
||||
|
||||
inline void print_xyz(const xyz_pos_t &xyz, PGM_P const prefix=nullptr, PGM_P const suffix=nullptr) {
|
||||
print_xyz(xyz.x, xyz.y, xyz.z, prefix, suffix);
|
||||
}
|
||||
|
||||
#define SERIAL_POS(SUFFIX,VAR) do { print_xyz(VAR, PSTR(" " STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n")); }while(0)
|
||||
#define SERIAL_XYZ(PREFIX,V...) do { print_xyz(V, PSTR(PREFIX), nullptr); }while(0)
|
||||
|
||||
@@ -0,0 +1,486 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2019 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "millis_t.h"
|
||||
|
||||
//
|
||||
// Enumerated axis indices
|
||||
//
|
||||
// - X_AXIS, Y_AXIS, and Z_AXIS should be used for axes in Cartesian space
|
||||
// - A_AXIS, B_AXIS, and C_AXIS should be used for Steppers, corresponding to XYZ on Cartesians
|
||||
// - X_HEAD, Y_HEAD, and Z_HEAD should be used for Steppers on Core kinematics
|
||||
//
|
||||
enum AxisEnum : uint8_t {
|
||||
X_AXIS = 0, A_AXIS = 0,
|
||||
Y_AXIS = 1, B_AXIS = 1,
|
||||
Z_AXIS = 2, C_AXIS = 2,
|
||||
E_AXIS = 3,
|
||||
X_HEAD = 4, Y_HEAD = 5, Z_HEAD = 6,
|
||||
E0_AXIS = 3,
|
||||
E1_AXIS = 4,
|
||||
E2_AXIS = 5,
|
||||
E3_AXIS = 6,
|
||||
E4_AXIS = 7,
|
||||
E5_AXIS = 8,
|
||||
ALL_AXES = 0xFE, NO_AXIS = 0xFF
|
||||
};
|
||||
|
||||
//
|
||||
// Loop over XYZE axes
|
||||
//
|
||||
|
||||
#define LOOP_S_LE_N(VAR, S, N) for (uint8_t VAR=(S); VAR<=(N); VAR++)
|
||||
#define LOOP_S_L_N(VAR, S, N) for (uint8_t VAR=(S); VAR<(N); VAR++)
|
||||
#define LOOP_LE_N(VAR, N) LOOP_S_LE_N(VAR, 0, N)
|
||||
#define LOOP_L_N(VAR, N) LOOP_S_L_N(VAR, 0, N)
|
||||
|
||||
#define LOOP_XYZ(VAR) LOOP_S_LE_N(VAR, X_AXIS, Z_AXIS)
|
||||
#define LOOP_XYZE(VAR) LOOP_S_LE_N(VAR, X_AXIS, E_AXIS)
|
||||
#define LOOP_XYZE_N(VAR) LOOP_S_L_N(VAR, X_AXIS, XYZE_N)
|
||||
#define LOOP_ABC(VAR) LOOP_S_LE_N(VAR, A_AXIS, C_AXIS)
|
||||
#define LOOP_ABCE(VAR) LOOP_S_LE_N(VAR, A_AXIS, E_AXIS)
|
||||
#define LOOP_ABCE_N(VAR) LOOP_S_L_N(VAR, A_AXIS, XYZE_N)
|
||||
|
||||
//
|
||||
// Conditional type assignment magic. For example...
|
||||
//
|
||||
// typename IF<(MYOPT==12), int, float>::type myvar;
|
||||
//
|
||||
template <bool, class L, class R>
|
||||
struct IF { typedef R type; };
|
||||
template <class L, class R>
|
||||
struct IF<true, L, R> { typedef L type; };
|
||||
|
||||
//
|
||||
// feedRate_t is just a humble float
|
||||
//
|
||||
typedef float feedRate_t;
|
||||
|
||||
// Conversion macros
|
||||
#define MMM_TO_MMS(MM_M) feedRate_t(float(MM_M) / 60.0f)
|
||||
#define MMS_TO_MMM(MM_S) (float(MM_S) * 60.0f)
|
||||
#define MMS_SCALED(V) ((V) * 0.01f * feedrate_percentage)
|
||||
|
||||
//
|
||||
// Coordinates structures for XY, XYZ, XYZE...
|
||||
//
|
||||
|
||||
// Helpers
|
||||
#define _RECIP(N) ((N) ? 1.0f / float(N) : 0.0f)
|
||||
#define _ABS(N) ((N) < 0 ? -(N) : (N))
|
||||
#define _LS(N) (N = (T)(uint32_t(N) << v))
|
||||
#define _RS(N) (N = (T)(uint32_t(N) >> v))
|
||||
#define FI FORCE_INLINE
|
||||
|
||||
// Forward declarations
|
||||
template<typename T> struct XYval;
|
||||
template<typename T> struct XYZval;
|
||||
template<typename T> struct XYZEval;
|
||||
|
||||
typedef struct XYval<bool> xy_bool_t;
|
||||
typedef struct XYZval<bool> xyz_bool_t;
|
||||
typedef struct XYZEval<bool> xyze_bool_t;
|
||||
|
||||
typedef struct XYval<char> xy_char_t;
|
||||
typedef struct XYZval<char> xyz_char_t;
|
||||
typedef struct XYZEval<char> xyze_char_t;
|
||||
|
||||
typedef struct XYval<unsigned char> xy_uchar_t;
|
||||
typedef struct XYZval<unsigned char> xyz_uchar_t;
|
||||
typedef struct XYZEval<unsigned char> xyze_uchar_t;
|
||||
|
||||
typedef struct XYval<int8_t> xy_int8_t;
|
||||
typedef struct XYZval<int8_t> xyz_int8_t;
|
||||
typedef struct XYZEval<int8_t> xyze_int8_t;
|
||||
|
||||
typedef struct XYval<uint8_t> xy_uint8_t;
|
||||
typedef struct XYZval<uint8_t> xyz_uint8_t;
|
||||
typedef struct XYZEval<uint8_t> xyze_uint8_t;
|
||||
|
||||
typedef struct XYval<int16_t> xy_int_t;
|
||||
typedef struct XYZval<int16_t> xyz_int_t;
|
||||
typedef struct XYZEval<int16_t> xyze_int_t;
|
||||
|
||||
typedef struct XYval<uint16_t> xy_uint_t;
|
||||
typedef struct XYZval<uint16_t> xyz_uint_t;
|
||||
typedef struct XYZEval<uint16_t> xyze_uint_t;
|
||||
|
||||
typedef struct XYval<int32_t> xy_long_t;
|
||||
typedef struct XYZval<int32_t> xyz_long_t;
|
||||
typedef struct XYZEval<int32_t> xyze_long_t;
|
||||
|
||||
typedef struct XYval<uint32_t> xy_ulong_t;
|
||||
typedef struct XYZval<uint32_t> xyz_ulong_t;
|
||||
typedef struct XYZEval<uint32_t> xyze_ulong_t;
|
||||
|
||||
typedef struct XYZval<volatile int32_t> xyz_vlong_t;
|
||||
typedef struct XYZEval<volatile int32_t> xyze_vlong_t;
|
||||
|
||||
typedef struct XYval<float> xy_float_t;
|
||||
typedef struct XYZval<float> xyz_float_t;
|
||||
typedef struct XYZEval<float> xyze_float_t;
|
||||
|
||||
typedef struct XYval<feedRate_t> xy_feedrate_t;
|
||||
typedef struct XYZval<feedRate_t> xyz_feedrate_t;
|
||||
typedef struct XYZEval<feedRate_t> xyze_feedrate_t;
|
||||
|
||||
typedef xy_uint8_t xy_byte_t;
|
||||
typedef xyz_uint8_t xyz_byte_t;
|
||||
typedef xyze_uint8_t xyze_byte_t;
|
||||
|
||||
typedef xyz_long_t abc_long_t;
|
||||
typedef xyze_long_t abce_long_t;
|
||||
typedef xyz_ulong_t abc_ulong_t;
|
||||
typedef xyze_ulong_t abce_ulong_t;
|
||||
|
||||
typedef xy_float_t xy_pos_t;
|
||||
typedef xyz_float_t xyz_pos_t;
|
||||
typedef xyze_float_t xyze_pos_t;
|
||||
|
||||
typedef xy_float_t ab_float_t;
|
||||
typedef xyz_float_t abc_float_t;
|
||||
typedef xyze_float_t abce_float_t;
|
||||
|
||||
typedef ab_float_t ab_pos_t;
|
||||
typedef abc_float_t abc_pos_t;
|
||||
typedef abce_float_t abce_pos_t;
|
||||
|
||||
// External conversion methods
|
||||
void toLogical(xy_pos_t &raw);
|
||||
void toLogical(xyz_pos_t &raw);
|
||||
void toLogical(xyze_pos_t &raw);
|
||||
void toNative(xy_pos_t &raw);
|
||||
void toNative(xyz_pos_t &raw);
|
||||
void toNative(xyze_pos_t &raw);
|
||||
|
||||
//
|
||||
// XY coordinates, counters, etc.
|
||||
//
|
||||
template<typename T>
|
||||
struct XYval {
|
||||
union {
|
||||
struct { T x, y; };
|
||||
struct { T a, b; };
|
||||
T pos[2];
|
||||
};
|
||||
FI void set(const T px) { x = px; }
|
||||
FI void set(const T px, const T py) { x = px; y = py; }
|
||||
FI void reset() { x = y = 0; }
|
||||
FI T magnitude() const { return (T)sqrtf(x*x + y*y); }
|
||||
FI operator T* () { return pos; }
|
||||
FI operator bool() { return x || y; }
|
||||
FI XYval<T> copy() const { return *this; }
|
||||
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() const { return { int16_t(x), int16_t(y) }; }
|
||||
FI XYval<int32_t> asLong() { return { int32_t(x), int32_t(y) }; }
|
||||
FI XYval<int32_t> asLong() const { return { int32_t(x), int32_t(y) }; }
|
||||
FI XYval<float> asFloat() { return { float(x), float(y) }; }
|
||||
FI XYval<float> asFloat() const { return { float(x), float(y) }; }
|
||||
FI XYval<float> reciprocal() const { return { _RECIP(x), _RECIP(y) }; }
|
||||
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 operator XYZval<T>() { return { x, y }; }
|
||||
FI operator XYZval<T>() const { return { x, y }; }
|
||||
FI operator XYZEval<T>() { return { x, y }; }
|
||||
FI operator XYZEval<T>() const { return { x, y }; }
|
||||
FI T& operator[](const int i) { return pos[i]; }
|
||||
FI const T& operator[](const int i) const { return pos[i]; }
|
||||
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 XYZEval<T> &rs) { set(rs.x, rs.y); return *this; }
|
||||
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) 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) 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) 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 XYZval<T> &rs) const { XYval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
|
||||
FI XYval<T> operator+ (const XYZval<T> &rs) { XYval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
|
||||
FI XYval<T> operator- (const XYZval<T> &rs) const { XYval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; }
|
||||
FI XYval<T> operator- (const XYZval<T> &rs) { XYval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; }
|
||||
FI XYval<T> operator* (const XYZval<T> &rs) const { XYval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; }
|
||||
FI XYval<T> operator* (const XYZval<T> &rs) { XYval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; }
|
||||
FI XYval<T> operator/ (const XYZval<T> &rs) const { XYval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
|
||||
FI XYval<T> operator/ (const XYZval<T> &rs) { XYval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
|
||||
FI XYval<T> operator+ (const XYZEval<T> &rs) const { XYval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
|
||||
FI XYval<T> operator+ (const XYZEval<T> &rs) { XYval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
|
||||
FI XYval<T> operator- (const XYZEval<T> &rs) const { XYval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; }
|
||||
FI XYval<T> operator- (const XYZEval<T> &rs) { XYval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; }
|
||||
FI XYval<T> operator* (const XYZEval<T> &rs) const { XYval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; }
|
||||
FI XYval<T> operator* (const XYZEval<T> &rs) { XYval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; }
|
||||
FI XYval<T> operator/ (const XYZEval<T> &rs) const { XYval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
|
||||
FI XYval<T> operator/ (const XYZEval<T> &rs) { XYval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
|
||||
FI XYval<T> operator* (const float &v) const { XYval<T> ls = *this; ls.x *= v; ls.y *= v; return ls; }
|
||||
FI XYval<T> operator* (const float &v) { XYval<T> ls = *this; ls.x *= v; ls.y *= v; return ls; }
|
||||
FI XYval<T> operator* (const int &v) const { XYval<T> ls = *this; ls.x *= v; ls.y *= v; return ls; }
|
||||
FI XYval<T> operator* (const int &v) { XYval<T> ls = *this; ls.x *= v; ls.y *= v; return ls; }
|
||||
FI XYval<T> operator/ (const float &v) const { XYval<T> ls = *this; ls.x /= v; ls.y /= v; return ls; }
|
||||
FI XYval<T> operator/ (const float &v) { XYval<T> ls = *this; ls.x /= v; ls.y /= v; return ls; }
|
||||
FI XYval<T> operator/ (const int &v) const { XYval<T> ls = *this; ls.x /= v; ls.y /= v; return ls; }
|
||||
FI XYval<T> operator/ (const int &v) { XYval<T> ls = *this; ls.x /= v; ls.y /= v; return ls; }
|
||||
FI XYval<T> operator>>(const int &v) const { 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) { XYval<T> ls = *this; _LS(ls.x); _LS(ls.y); return ls; }
|
||||
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 XYZval<T> &rs) { x += rs.x; y += rs.y; return *this; }
|
||||
FI XYval<T>& operator-=(const XYZval<T> &rs) { x -= rs.x; y -= rs.y; return *this; }
|
||||
FI XYval<T>& operator*=(const XYZval<T> &rs) { x *= rs.x; y *= rs.y; return *this; }
|
||||
FI XYval<T>& operator+=(const XYZEval<T> &rs) { x += rs.x; y += rs.y; return *this; }
|
||||
FI XYval<T>& operator-=(const XYZEval<T> &rs) { x -= rs.x; y -= rs.y; return *this; }
|
||||
FI XYval<T>& operator*=(const XYZEval<T> &rs) { x *= rs.x; y *= rs.y; return *this; }
|
||||
FI XYval<T>& operator*=(const float &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) { _LS(x); _LS(y); return *this; }
|
||||
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 XYZEval<T> &rs) { return x == rs.x && y == rs.y; }
|
||||
FI bool operator==(const XYval<T> &rs) const { return x == rs.x && y == rs.y; }
|
||||
FI bool operator==(const XYZval<T> &rs) const { return x == rs.x && y == rs.y; }
|
||||
FI bool operator==(const XYZEval<T> &rs) const { return x == rs.x && y == rs.y; }
|
||||
FI bool operator!=(const XYval<T> &rs) { return !operator==(rs); }
|
||||
FI bool operator!=(const XYZval<T> &rs) { return !operator==(rs); }
|
||||
FI bool operator!=(const XYZEval<T> &rs) { 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 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; }
|
||||
};
|
||||
|
||||
//
|
||||
// XYZ coordinates, counters, etc.
|
||||
//
|
||||
template<typename T>
|
||||
struct XYZval {
|
||||
union {
|
||||
struct { T x, y, z; };
|
||||
struct { T a, b, c; };
|
||||
T pos[3];
|
||||
};
|
||||
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, const T pz) { x = px; y = py; z = pz; }
|
||||
FI void set(const XYval<T> pxy, const T pz) { x = pxy.x; y = pxy.y; z = pz; }
|
||||
FI void reset() { x = y = z = 0; }
|
||||
FI T magnitude() const { return (T)sqrtf(x*x + y*y + z*z); }
|
||||
FI operator T* () { return pos; }
|
||||
FI operator bool() { return z || x || y; }
|
||||
FI XYZval<T> copy() const { XYZval<T> o = *this; return o; }
|
||||
FI XYZval<T> ABS() const { return { T(_ABS(x)), T(_ABS(y)), T(_ABS(z)) }; }
|
||||
FI XYZval<int16_t> asInt() { return { int16_t(x), int16_t(y), int16_t(z) }; }
|
||||
FI XYZval<int16_t> asInt() const { return { int16_t(x), int16_t(y), int16_t(z) }; }
|
||||
FI XYZval<int32_t> asLong() { return { int32_t(x), int32_t(y), int32_t(z) }; }
|
||||
FI XYZval<int32_t> asLong() const { return { int32_t(x), int32_t(y), int32_t(z) }; }
|
||||
FI XYZval<float> asFloat() { return { float(x), float(y), float(z) }; }
|
||||
FI XYZval<float> asFloat() const { return { float(x), float(y), float(z) }; }
|
||||
FI XYZval<float> reciprocal() const { return { _RECIP(x), _RECIP(y), _RECIP(z) }; }
|
||||
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 operator XYval<T>&() { return *(XYval<T>*)this; }
|
||||
FI operator const XYval<T>&() const { return *(const XYval<T>*)this; }
|
||||
FI operator XYZEval<T>() const { return { x, y, z }; }
|
||||
FI T& operator[](const int i) { return pos[i]; }
|
||||
FI const T& operator[](const int i) const { return pos[i]; }
|
||||
FI XYZval<T>& operator= (const T v) { set(v, v, v ); 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(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; }
|
||||
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; ls.x -= rs.x; ls.y -= rs.y; 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; ls.x *= rs.x; ls.y *= rs.y; 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; ls.x /= rs.x; ls.y /= rs.y; 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 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; ls.x /= rs.x; ls.y /= rs.y; ls.z /= rs.z; return ls; }
|
||||
FI XYZval<T> operator* (const float &v) const { XYZval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= z; return ls; }
|
||||
FI XYZval<T> operator* (const float &v) { XYZval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= z; return ls; }
|
||||
FI XYZval<T> operator* (const int &v) const { XYZval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= z; return ls; }
|
||||
FI XYZval<T> operator* (const int &v) { XYZval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= z; return ls; }
|
||||
FI XYZval<T> operator/ (const float &v) const { XYZval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= z; return ls; }
|
||||
FI XYZval<T> operator/ (const float &v) { XYZval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= z; return ls; }
|
||||
FI XYZval<T> operator/ (const int &v) const { XYZval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= z; return ls; }
|
||||
FI XYZval<T> operator/ (const int &v) { XYZval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= z; 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; _RS(ls.x); _RS(ls.y); _RS(ls.z); 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; _LS(ls.x); _LS(ls.y); _LS(ls.z); return ls; }
|
||||
FI XYZval<T>& operator+=(const XYval<T> &rs) { x += rs.x; y += rs.y; return *this; }
|
||||
FI XYZval<T>& operator-=(const XYval<T> &rs) { x -= rs.x; y -= rs.y; return *this; }
|
||||
FI XYZval<T>& operator*=(const XYval<T> &rs) { x *= rs.x; y *= rs.y; return *this; }
|
||||
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; }
|
||||
FI XYZval<T>& operator-=(const XYZval<T> &rs) { x -= rs.x; y -= rs.y; z -= rs.z; 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 XYZval<T> &rs) { x /= rs.x; y /= rs.y; z /= rs.z; 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 XYZEval<T> &rs) { x -= rs.x; y -= rs.y; z -= rs.z; 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 XYZEval<T> &rs) { x /= rs.x; y /= rs.y; z /= rs.z; return *this; }
|
||||
FI XYZval<T>& operator*=(const float &v) { x *= v; y *= v; z *= v; return *this; }
|
||||
FI XYZval<T>& operator*=(const int &v) { x *= v; y *= v; z *= v; return *this; }
|
||||
FI XYZval<T>& operator>>=(const int &v) { _RS(x); _RS(y); _RS(z); return *this; }
|
||||
FI XYZval<T>& operator<<=(const int &v) { _LS(x); _LS(y); _LS(z); return *this; }
|
||||
FI bool operator==(const XYZEval<T> &rs) { return x == rs.x && y == rs.y && z == rs.z; }
|
||||
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 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; }
|
||||
};
|
||||
|
||||
//
|
||||
// XYZE coordinates, counters, etc.
|
||||
//
|
||||
template<typename T>
|
||||
struct XYZEval {
|
||||
union {
|
||||
struct{ T x, y, z, e; };
|
||||
struct{ T a, b, c; };
|
||||
T pos[4];
|
||||
};
|
||||
FI void reset() { x = y = z = e = 0; }
|
||||
FI T magnitude() const { return (T)sqrtf(x*x + y*y + z*z + e*e); }
|
||||
FI operator T* () { return pos; }
|
||||
FI operator bool() { return e || z || x || y; }
|
||||
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, const T pz) { x = px; y = py; z = pz; }
|
||||
FI void set(const T px, const T py, const T pz, const T pe) { x = px; y = py; z = pz; e = pe; }
|
||||
FI void set(const XYval<T> pxy) { x = pxy.x; y = pxy.y; }
|
||||
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 XYZEval<T> copy() const { return *this; }
|
||||
FI XYZEval<T> ABS() const { return { T(_ABS(x)), T(_ABS(y)), T(_ABS(z)), T(_ABS(e)) }; }
|
||||
FI XYZEval<int16_t> asInt() { return { int16_t(x), int16_t(y), int16_t(z), int16_t(e) }; }
|
||||
FI XYZEval<int16_t> asInt() const { return { int16_t(x), int16_t(y), int16_t(z), int16_t(e) }; }
|
||||
FI XYZEval<int32_t> asLong() const { return { int32_t(x), int32_t(y), int32_t(z), int32_t(e) }; }
|
||||
FI XYZEval<int32_t> asLong() { return { int32_t(x), int32_t(y), int32_t(z), int32_t(e) }; }
|
||||
FI XYZEval<float> asFloat() { return { float(x), float(y), float(z), float(e) }; }
|
||||
FI XYZEval<float> asFloat() const { return { float(x), float(y), float(z), float(e) }; }
|
||||
FI XYZEval<float> reciprocal() const { return { _RECIP(x), _RECIP(y), _RECIP(z), _RECIP(e) }; }
|
||||
FI XYZEval<float> asLogical() const { XYZEval<float> o = asFloat(); toLogical(o); return o; }
|
||||
FI XYZEval<float> asNative() const { XYZEval<float> o = asFloat(); toNative(o); return o; }
|
||||
FI operator XYval<T>&() { return *(XYval<T>*)this; }
|
||||
FI operator const XYval<T>&() const { return *(const XYval<T>*)this; }
|
||||
FI operator XYZval<T>&() { return *(XYZval<T>*)this; }
|
||||
FI operator const XYZval<T>&() const { return *(const XYZval<T>*)this; }
|
||||
FI T& operator[](const int i) { return pos[i]; }
|
||||
FI const T& operator[](const int i) const { return pos[i]; }
|
||||
FI XYZEval<T>& operator= (const T v) { set(v, v, v, v); return *this; }
|
||||
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; }
|
||||
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) { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; 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 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) const { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; 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) const { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; 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 XYZval<T> &rs) const { 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) { 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; }
|
||||
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; }
|
||||
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; }
|
||||
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; }
|
||||
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; }
|
||||
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; }
|
||||
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; }
|
||||
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 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 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; }
|
||||
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 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 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; }
|
||||
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 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 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 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 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) { 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) { x += rs.x; y += rs.y; z += rs.z; return *this; }
|
||||
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) { x *= rs.x; y *= rs.y; z *= rs.z; return *this; }
|
||||
FI XYZEval<T>& operator/=(const XYZval<T> &rs) { x /= rs.x; y /= rs.y; z /= rs.z; return *this; }
|
||||
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 XYZEval<T> &rs) { x -= rs.x; y -= rs.y; z -= rs.z; e -= rs.e; return *this; }
|
||||
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 XYZEval<T> &rs) { x /= rs.x; y /= rs.y; z /= rs.z; e /= rs.e; return *this; }
|
||||
FI XYZEval<T>& operator*=(const T &v) { x *= v; y *= v; z *= v; e *= v; return *this; }
|
||||
FI XYZEval<T>& operator>>=(const int &v) { _RS(x); _RS(y); _RS(z); _RS(e); return *this; }
|
||||
FI XYZEval<T>& operator<<=(const int &v) { _LS(x); _LS(y); _LS(z); _LS(e); return *this; }
|
||||
FI bool operator==(const XYZval<T> &rs) { return x == rs.x && y == rs.y && z == rs.z; }
|
||||
FI bool operator!=(const XYZval<T> &rs) { return !operator==(rs); }
|
||||
FI bool operator==(const XYZval<T> &rs) const { return x == rs.x && y == rs.y && z == rs.z; }
|
||||
FI bool operator!=(const XYZval<T> &rs) const { return !operator==(rs); }
|
||||
FI XYZEval<T> operator-() { return { -x, -y, -z, -e }; }
|
||||
FI const XYZEval<T> operator-() const { return { -x, -y, -z, -e }; }
|
||||
};
|
||||
|
||||
#undef _RECIP
|
||||
#undef _ABS
|
||||
#undef _LS
|
||||
#undef _RS
|
||||
#undef FI
|
||||
|
||||
const xyze_char_t axis_codes { 'X', 'Y', 'Z', 'E' };
|
||||
+20
-30
@@ -79,36 +79,36 @@ void safe_delay(millis_t ms) {
|
||||
);
|
||||
|
||||
#if HAS_BED_PROBE
|
||||
SERIAL_ECHOPAIR("Probe Offset X:", probe_offset[X_AXIS], " Y:", probe_offset[Y_AXIS], " Z:", probe_offset[Z_AXIS]);
|
||||
if (probe_offset[X_AXIS] > 0)
|
||||
SERIAL_ECHOPAIR("Probe Offset X", probe_offset.x, " Y", probe_offset.y, " Z", probe_offset.z);
|
||||
if (probe_offset.x > 0)
|
||||
SERIAL_ECHOPGM(" (Right");
|
||||
else if (probe_offset[X_AXIS] < 0)
|
||||
else if (probe_offset.x < 0)
|
||||
SERIAL_ECHOPGM(" (Left");
|
||||
else if (probe_offset[Y_AXIS] != 0)
|
||||
else if (probe_offset.y != 0)
|
||||
SERIAL_ECHOPGM(" (Middle");
|
||||
else
|
||||
SERIAL_ECHOPGM(" (Aligned With");
|
||||
|
||||
if (probe_offset[Y_AXIS] > 0) {
|
||||
if (probe_offset.y > 0) {
|
||||
#if IS_SCARA
|
||||
SERIAL_ECHOPGM("-Distal");
|
||||
#else
|
||||
SERIAL_ECHOPGM("-Back");
|
||||
#endif
|
||||
}
|
||||
else if (probe_offset[Y_AXIS] < 0) {
|
||||
else if (probe_offset.y < 0) {
|
||||
#if IS_SCARA
|
||||
SERIAL_ECHOPGM("-Proximal");
|
||||
#else
|
||||
SERIAL_ECHOPGM("-Front");
|
||||
#endif
|
||||
}
|
||||
else if (probe_offset[X_AXIS] != 0)
|
||||
else if (probe_offset.x != 0)
|
||||
SERIAL_ECHOPGM("-Center");
|
||||
|
||||
if (probe_offset[Z_AXIS] < 0)
|
||||
if (probe_offset.z < 0)
|
||||
SERIAL_ECHOPGM(" & Below");
|
||||
else if (probe_offset[Z_AXIS] > 0)
|
||||
else if (probe_offset.z > 0)
|
||||
SERIAL_ECHOPGM(" & Above");
|
||||
else
|
||||
SERIAL_ECHOPGM(" & Same Z as");
|
||||
@@ -134,24 +134,18 @@ void safe_delay(millis_t ms) {
|
||||
SERIAL_ECHOLNPAIR("Z Fade: ", planner.z_fade_height);
|
||||
#endif
|
||||
#if ABL_PLANAR
|
||||
const float diff[XYZ] = {
|
||||
planner.get_axis_position_mm(X_AXIS) - current_position[X_AXIS],
|
||||
planner.get_axis_position_mm(Y_AXIS) - current_position[Y_AXIS],
|
||||
planner.get_axis_position_mm(Z_AXIS) - current_position[Z_AXIS]
|
||||
};
|
||||
SERIAL_ECHOPGM("ABL Adjustment X");
|
||||
if (diff[X_AXIS] > 0) SERIAL_CHAR('+');
|
||||
SERIAL_ECHO(diff[X_AXIS]);
|
||||
SERIAL_ECHOPGM(" Y");
|
||||
if (diff[Y_AXIS] > 0) SERIAL_CHAR('+');
|
||||
SERIAL_ECHO(diff[Y_AXIS]);
|
||||
SERIAL_ECHOPGM(" Z");
|
||||
if (diff[Z_AXIS] > 0) SERIAL_CHAR('+');
|
||||
SERIAL_ECHO(diff[Z_AXIS]);
|
||||
LOOP_XYZ(a) {
|
||||
float v = planner.get_axis_position_mm(AxisEnum(a)) - current_position[a];
|
||||
SERIAL_CHAR(' ');
|
||||
SERIAL_CHAR('X' + char(a));
|
||||
if (v > 0) SERIAL_CHAR('+');
|
||||
SERIAL_ECHO(v);
|
||||
}
|
||||
#else
|
||||
#if ENABLED(AUTO_BED_LEVELING_UBL)
|
||||
SERIAL_ECHOPGM("UBL Adjustment Z");
|
||||
const float rz = ubl.get_z_correction(current_position[X_AXIS], current_position[Y_AXIS]);
|
||||
const float rz = ubl.get_z_correction(current_position);
|
||||
#elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
|
||||
SERIAL_ECHOPGM("ABL Adjustment Z");
|
||||
const float rz = bilinear_z_offset(current_position);
|
||||
@@ -159,7 +153,7 @@ void safe_delay(millis_t ms) {
|
||||
SERIAL_ECHO(ftostr43sign(rz, '+'));
|
||||
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
|
||||
if (planner.z_fade_height) {
|
||||
SERIAL_ECHOPAIR(" (", ftostr43sign(rz * planner.fade_scaling_factor_for_z(current_position[Z_AXIS]), '+'));
|
||||
SERIAL_ECHOPAIR(" (", ftostr43sign(rz * planner.fade_scaling_factor_for_z(current_position.z), '+'));
|
||||
SERIAL_CHAR(')');
|
||||
}
|
||||
#endif
|
||||
@@ -175,15 +169,11 @@ void safe_delay(millis_t ms) {
|
||||
SERIAL_ECHOPGM("Mesh Bed Leveling");
|
||||
if (planner.leveling_active) {
|
||||
SERIAL_ECHOLNPGM(" (enabled)");
|
||||
SERIAL_ECHOPAIR("MBL Adjustment Z", ftostr43sign(mbl.get_z(current_position[X_AXIS], current_position[Y_AXIS]
|
||||
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
|
||||
, 1.0
|
||||
#endif
|
||||
), '+'));
|
||||
SERIAL_ECHOPAIR("MBL Adjustment Z", ftostr43sign(mbl.get_z(current_position), '+'));
|
||||
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
|
||||
if (planner.z_fade_height) {
|
||||
SERIAL_ECHOPAIR(" (", ftostr43sign(
|
||||
mbl.get_z(current_position[X_AXIS], current_position[Y_AXIS], planner.fade_scaling_factor_for_z(current_position[Z_AXIS])), '+'
|
||||
mbl.get_z(current_position, planner.fade_scaling_factor_for_z(current_position.z)), '+'
|
||||
));
|
||||
SERIAL_CHAR(')');
|
||||
}
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../inc/MarlinConfigPre.h"
|
||||
|
||||
constexpr char axis_codes[XYZE] = { 'X', 'Y', 'Z', 'E' };
|
||||
#include "../core/types.h"
|
||||
|
||||
// Delay that ensures heaters and watchdog are kept alive
|
||||
void safe_delay(millis_t ms);
|
||||
@@ -37,10 +36,25 @@ inline void serial_delay(const millis_t ms) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// 16x16 bit arrays
|
||||
FORCE_INLINE void bitmap_clear(uint16_t bits[16], const uint8_t x, const uint8_t y) { CBI(bits[y], x); }
|
||||
FORCE_INLINE void bitmap_set(uint16_t bits[16], const uint8_t x, const uint8_t y) { SBI(bits[y], x); }
|
||||
FORCE_INLINE bool is_bitmap_set(uint16_t bits[16], const uint8_t x, const uint8_t y) { return TEST(bits[y], x); }
|
||||
#if GRID_MAX_POINTS_X && GRID_MAX_POINTS_Y
|
||||
|
||||
// 16x16 bit arrays
|
||||
template <int W, int H>
|
||||
struct FlagBits {
|
||||
typename IF<(W>8), uint16_t, uint8_t>::type bits[H];
|
||||
void fill() { memset(bits, 0xFF, sizeof(bits)); }
|
||||
void reset() { memset(bits, 0x00, sizeof(bits)); }
|
||||
void unmark(const uint8_t x, const uint8_t y) { CBI(bits[y], x); }
|
||||
void mark(const uint8_t x, const uint8_t y) { SBI(bits[y], x); }
|
||||
bool marked(const uint8_t x, const uint8_t y) { return TEST(bits[y], x); }
|
||||
inline void unmark(const xy_int8_t &xy) { unmark(xy.y, xy.x); }
|
||||
inline void mark(const xy_int8_t &xy) { mark(xy.y, xy.x); }
|
||||
inline bool marked(const xy_int8_t &xy) { return marked(xy.y, xy.x); }
|
||||
};
|
||||
|
||||
typedef FlagBits<GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y> MeshFlags;
|
||||
|
||||
#endif
|
||||
|
||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||
void log_machine_info();
|
||||
|
||||
@@ -326,25 +326,23 @@ bool I2CPositionEncoder::test_axis() {
|
||||
//only works on XYZ cartesian machines for the time being
|
||||
if (!(encoderAxis == X_AXIS || encoderAxis == Y_AXIS || encoderAxis == Z_AXIS)) return false;
|
||||
|
||||
float startCoord[NUM_AXIS] = { 0 }, endCoord[NUM_AXIS] = { 0 };
|
||||
|
||||
const float startPosition = soft_endstop[encoderAxis].min + 10,
|
||||
endPosition = soft_endstop[encoderAxis].max - 10;
|
||||
const float startPosition = soft_endstop.min[encoderAxis] + 10,
|
||||
endPosition = soft_endstop.max[encoderAxis] - 10;
|
||||
const feedRate_t fr_mm_s = FLOOR(MMM_TO_MMS((encoderAxis == Z_AXIS) ? HOMING_FEEDRATE_Z : HOMING_FEEDRATE_XY));
|
||||
|
||||
ec = false;
|
||||
|
||||
LOOP_XYZ(i) {
|
||||
startCoord[i] = planner.get_axis_position_mm((AxisEnum)i);
|
||||
endCoord[i] = planner.get_axis_position_mm((AxisEnum)i);
|
||||
xyze_pos_t startCoord, endCoord;
|
||||
LOOP_XYZ(a) {
|
||||
startCoord[a] = planner.get_axis_position_mm((AxisEnum)a);
|
||||
endCoord[a] = planner.get_axis_position_mm((AxisEnum)a);
|
||||
}
|
||||
startCoord[encoderAxis] = startPosition;
|
||||
endCoord[encoderAxis] = endPosition;
|
||||
|
||||
planner.synchronize();
|
||||
|
||||
planner.buffer_line(startCoord[X_AXIS], startCoord[Y_AXIS], startCoord[Z_AXIS],
|
||||
planner.get_axis_position_mm(E_AXIS), fr_mm_s, 0);
|
||||
startCoord.e = planner.get_axis_position_mm(E_AXIS);
|
||||
planner.buffer_line(startCoord, fr_mm_s, 0);
|
||||
planner.synchronize();
|
||||
|
||||
// if the module isn't currently trusted, wait until it is (or until it should be if things are working)
|
||||
@@ -355,8 +353,8 @@ bool I2CPositionEncoder::test_axis() {
|
||||
}
|
||||
|
||||
if (trusted) { // if trusted, commence test
|
||||
planner.buffer_line(endCoord[X_AXIS], endCoord[Y_AXIS], endCoord[Z_AXIS],
|
||||
planner.get_axis_position_mm(E_AXIS), fr_mm_s, 0);
|
||||
endCoord.e = planner.get_axis_position_mm(E_AXIS);
|
||||
planner.buffer_line(endCoord, fr_mm_s, 0);
|
||||
planner.synchronize();
|
||||
}
|
||||
|
||||
@@ -376,8 +374,7 @@ void I2CPositionEncoder::calibrate_steps_mm(const uint8_t iter) {
|
||||
|
||||
float old_steps_mm, new_steps_mm,
|
||||
startDistance, endDistance,
|
||||
travelDistance, travelledDistance, total = 0,
|
||||
startCoord[NUM_AXIS] = { 0 }, endCoord[NUM_AXIS] = { 0 };
|
||||
travelDistance, travelledDistance, total = 0;
|
||||
|
||||
int32_t startCount, stopCount;
|
||||
|
||||
@@ -387,31 +384,31 @@ void I2CPositionEncoder::calibrate_steps_mm(const uint8_t iter) {
|
||||
ec = false;
|
||||
|
||||
startDistance = 20;
|
||||
endDistance = soft_endstop[encoderAxis].max - 20;
|
||||
endDistance = soft_endstop.max[encoderAxis] - 20;
|
||||
travelDistance = endDistance - startDistance;
|
||||
|
||||
xyze_pos_t startCoord, endCoord;
|
||||
LOOP_XYZ(a) {
|
||||
startCoord[a] = planner.get_axis_position_mm((AxisEnum)a);
|
||||
endCoord[a] = planner.get_axis_position_mm((AxisEnum)a);
|
||||
}
|
||||
|
||||
startCoord[encoderAxis] = startDistance;
|
||||
endCoord[encoderAxis] = endDistance;
|
||||
|
||||
planner.synchronize();
|
||||
|
||||
LOOP_L_N(i, iter) {
|
||||
planner.buffer_line(startCoord[X_AXIS], startCoord[Y_AXIS], startCoord[Z_AXIS],
|
||||
planner.get_axis_position_mm(E_AXIS), fr_mm_s, 0);
|
||||
startCoord.e = planner.get_axis_position_mm(E_AXIS);
|
||||
planner.buffer_line(startCoord, fr_mm_s, 0);
|
||||
planner.synchronize();
|
||||
|
||||
delay(250);
|
||||
startCount = get_position();
|
||||
|
||||
//do_blocking_move_to(endCoord[X_AXIS],endCoord[Y_AXIS],endCoord[Z_AXIS]);
|
||||
//do_blocking_move_to(endCoord);
|
||||
|
||||
planner.buffer_line(endCoord[X_AXIS], endCoord[Y_AXIS], endCoord[Z_AXIS],
|
||||
planner.get_axis_position_mm(E_AXIS), fr_mm_s, 0);
|
||||
endCoord.e = planner.get_axis_position_mm(E_AXIS);
|
||||
planner.buffer_line(endCoord, fr_mm_s, 0);
|
||||
planner.synchronize();
|
||||
|
||||
//Read encoder distance
|
||||
|
||||
@@ -93,8 +93,6 @@
|
||||
#define LOOP_PE(VAR) LOOP_L_N(VAR, I2CPE_ENCODER_CNT)
|
||||
#define CHECK_IDX() do{ if (!WITHIN(idx, 0, I2CPE_ENCODER_CNT - 1)) return; }while(0)
|
||||
|
||||
extern const char axis_codes[XYZE];
|
||||
|
||||
typedef union {
|
||||
volatile int32_t val = 0;
|
||||
uint8_t bval[4];
|
||||
|
||||
@@ -75,7 +75,7 @@ class Max7219 {
|
||||
public:
|
||||
static uint8_t led_line[MAX7219_LINES];
|
||||
|
||||
Max7219() { }
|
||||
Max7219() {}
|
||||
|
||||
static void init();
|
||||
static void register_setup();
|
||||
|
||||
@@ -36,13 +36,10 @@
|
||||
Babystep babystep;
|
||||
|
||||
volatile int16_t Babystep::steps[BS_TODO_AXIS(Z_AXIS) + 1];
|
||||
|
||||
#if HAS_LCD_MENU || ENABLED(EXTENSIBLE_UI)
|
||||
int16_t Babystep::accum;
|
||||
#if ENABLED(BABYSTEP_DISPLAY_TOTAL)
|
||||
int16_t Babystep::axis_total[BS_TOTAL_AXIS(Z_AXIS) + 1];
|
||||
#endif
|
||||
#if ENABLED(BABYSTEP_DISPLAY_TOTAL)
|
||||
int16_t Babystep::axis_total[BS_TOTAL_AXIS(Z_AXIS) + 1];
|
||||
#endif
|
||||
int16_t Babystep::accum;
|
||||
|
||||
void Babystep::step_axis(const AxisEnum axis) {
|
||||
const int16_t curTodo = steps[BS_TODO_AXIS(axis)]; // get rid of volatile for performance
|
||||
@@ -75,11 +72,9 @@ void Babystep::add_steps(const AxisEnum axis, const int16_t distance) {
|
||||
|
||||
if (!CAN_BABYSTEP(axis)) return;
|
||||
|
||||
#if HAS_LCD_MENU || ENABLED(EXTENSIBLE_UI)
|
||||
accum += distance; // Count up babysteps for the UI
|
||||
#if ENABLED(BABYSTEP_DISPLAY_TOTAL)
|
||||
axis_total[BS_TOTAL_AXIS(axis)] += distance;
|
||||
#endif
|
||||
accum += distance; // Count up babysteps for the UI
|
||||
#if ENABLED(BABYSTEP_DISPLAY_TOTAL)
|
||||
axis_total[BS_TOTAL_AXIS(axis)] += distance;
|
||||
#endif
|
||||
|
||||
#if ENABLED(BABYSTEP_ALWAYS_AVAILABLE)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#define BS_TODO_AXIS(A) 0
|
||||
#endif
|
||||
|
||||
#if (HAS_LCD_MENU || ENABLED(EXTENSIBLE_UI)) && ENABLED(BABYSTEP_DISPLAY_TOTAL)
|
||||
#if ENABLED(BABYSTEP_DISPLAY_TOTAL)
|
||||
#if ENABLED(BABYSTEP_XY)
|
||||
#define BS_TOTAL_AXIS(A) A
|
||||
#else
|
||||
@@ -40,22 +40,17 @@
|
||||
class Babystep {
|
||||
public:
|
||||
static volatile int16_t steps[BS_TODO_AXIS(Z_AXIS) + 1];
|
||||
static int16_t accum; // Total babysteps in current edit
|
||||
|
||||
#if HAS_LCD_MENU || ENABLED(EXTENSIBLE_UI)
|
||||
|
||||
static int16_t accum; // Total babysteps in current edit
|
||||
|
||||
#if ENABLED(BABYSTEP_DISPLAY_TOTAL)
|
||||
static int16_t axis_total[BS_TOTAL_AXIS(Z_AXIS) + 1]; // Total babysteps since G28
|
||||
static inline void reset_total(const AxisEnum axis) {
|
||||
if (true
|
||||
#if ENABLED(BABYSTEP_XY)
|
||||
&& axis == Z_AXIS
|
||||
#endif
|
||||
) axis_total[BS_TOTAL_AXIS(axis)] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLED(BABYSTEP_DISPLAY_TOTAL)
|
||||
static int16_t axis_total[BS_TOTAL_AXIS(Z_AXIS) + 1]; // Total babysteps since G28
|
||||
static inline void reset_total(const AxisEnum axis) {
|
||||
if (true
|
||||
#if ENABLED(BABYSTEP_XY)
|
||||
&& axis == Z_AXIS
|
||||
#endif
|
||||
) axis_total[BS_TOTAL_AXIS(axis)] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void add_steps(const AxisEnum axis, const int16_t distance);
|
||||
|
||||
@@ -31,9 +31,9 @@
|
||||
|
||||
#ifdef BACKLASH_DISTANCE_MM
|
||||
#if ENABLED(BACKLASH_GCODE)
|
||||
float Backlash::distance_mm[XYZ] = BACKLASH_DISTANCE_MM;
|
||||
xyz_float_t Backlash::distance_mm = BACKLASH_DISTANCE_MM;
|
||||
#else
|
||||
const float Backlash::distance_mm[XYZ] = BACKLASH_DISTANCE_MM;
|
||||
const xyz_float_t Backlash::distance_mm = BACKLASH_DISTANCE_MM;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -45,8 +45,8 @@
|
||||
#endif
|
||||
|
||||
#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
|
||||
float Backlash::measured_mm[XYZ] = { 0 };
|
||||
uint8_t Backlash::measured_count[XYZ] = { 0 };
|
||||
xyz_float_t Backlash::measured_mm{0};
|
||||
xyz_uint8_t Backlash::measured_count{0};
|
||||
#endif
|
||||
|
||||
Backlash backlash;
|
||||
@@ -80,12 +80,12 @@ void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const
|
||||
|
||||
// Residual error carried forward across multiple segments, so correction can be applied
|
||||
// to segments where there is no direction change.
|
||||
static int32_t residual_error[XYZ] = { 0 };
|
||||
static xyz_long_t residual_error{0};
|
||||
#else
|
||||
// No direction change, no correction.
|
||||
if (!changed_dir) return;
|
||||
// No leftover residual error from segment to segment
|
||||
int32_t residual_error[XYZ] = { 0 };
|
||||
xyz_long_t residual_error{0};
|
||||
#endif
|
||||
|
||||
const float f_corr = float(correction) / 255.0f;
|
||||
@@ -123,7 +123,7 @@ void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const
|
||||
}
|
||||
|
||||
#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
|
||||
#if USES_Z_MIN_PROBE_ENDSTOP
|
||||
#if HAS_CUSTOM_PROBE_PIN
|
||||
#define TEST_PROBE_PIN (READ(Z_MIN_PROBE_PIN) != Z_MIN_PROBE_ENDSTOP_INVERTING)
|
||||
#else
|
||||
#define TEST_PROBE_PIN (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING)
|
||||
@@ -131,15 +131,15 @@ void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const
|
||||
|
||||
// Measure Z backlash by raising nozzle in increments until probe deactivates
|
||||
void Backlash::measure_with_probe() {
|
||||
if (measured_count[Z_AXIS] == 255) return;
|
||||
if (measured_count.z == 255) return;
|
||||
|
||||
float start_height = current_position[Z_AXIS];
|
||||
while (current_position[Z_AXIS] < (start_height + BACKLASH_MEASUREMENT_LIMIT) && TEST_PROBE_PIN)
|
||||
do_blocking_move_to_z(current_position[Z_AXIS] + BACKLASH_MEASUREMENT_RESOLUTION, MMM_TO_MMS(BACKLASH_MEASUREMENT_FEEDRATE));
|
||||
const float start_height = current_position.z;
|
||||
while (current_position.z < (start_height + BACKLASH_MEASUREMENT_LIMIT) && TEST_PROBE_PIN)
|
||||
do_blocking_move_to_z(current_position.z + BACKLASH_MEASUREMENT_RESOLUTION, MMM_TO_MMS(BACKLASH_MEASUREMENT_FEEDRATE));
|
||||
|
||||
// The backlash from all probe points is averaged, so count the number of measurements
|
||||
measured_mm[Z_AXIS] += current_position[Z_AXIS] - start_height;
|
||||
measured_count[Z_AXIS]++;
|
||||
measured_mm.z += current_position.z - start_height;
|
||||
measured_count.z++;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ constexpr uint8_t all_on = 0xFF, all_off = 0x00;
|
||||
class Backlash {
|
||||
public:
|
||||
#if ENABLED(BACKLASH_GCODE)
|
||||
static float distance_mm[XYZ];
|
||||
static xyz_float_t distance_mm;
|
||||
static uint8_t correction;
|
||||
#ifdef BACKLASH_SMOOTHING_MM
|
||||
static float smoothing_mm;
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
static inline float get_correction() { return float(ui8_to_percent(correction)) / 100.0f; }
|
||||
#else
|
||||
static constexpr uint8_t correction = (BACKLASH_CORRECTION) * 0xFF;
|
||||
static const float distance_mm[XYZ];
|
||||
static const xyz_float_t distance_mm;
|
||||
#ifdef BACKLASH_SMOOTHING_MM
|
||||
static constexpr float smoothing_mm = BACKLASH_SMOOTHING_MM;
|
||||
#endif
|
||||
@@ -47,8 +47,8 @@ public:
|
||||
|
||||
#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
|
||||
private:
|
||||
static float measured_mm[XYZ];
|
||||
static uint8_t measured_count[XYZ];
|
||||
static xyz_float_t measured_mm;
|
||||
static xyz_uint8_t measured_count;
|
||||
public:
|
||||
static void measure_with_probe();
|
||||
#endif
|
||||
|
||||
@@ -35,9 +35,9 @@
|
||||
#include "../../../lcd/extensible_ui/ui_api.h"
|
||||
#endif
|
||||
|
||||
int bilinear_grid_spacing[2], bilinear_start[2];
|
||||
float bilinear_grid_factor[2],
|
||||
z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
|
||||
xy_int_t bilinear_grid_spacing, bilinear_start;
|
||||
xy_float_t bilinear_grid_factor;
|
||||
bed_mesh_t z_values;
|
||||
|
||||
/**
|
||||
* Extrapolate a single point from its neighbors
|
||||
@@ -153,8 +153,8 @@ void print_bilinear_leveling_grid() {
|
||||
#define ABL_TEMP_POINTS_X (GRID_MAX_POINTS_X + 2)
|
||||
#define ABL_TEMP_POINTS_Y (GRID_MAX_POINTS_Y + 2)
|
||||
float z_values_virt[ABL_GRID_POINTS_VIRT_X][ABL_GRID_POINTS_VIRT_Y];
|
||||
int bilinear_grid_spacing_virt[2] = { 0 };
|
||||
float bilinear_grid_factor_virt[2] = { 0 };
|
||||
xy_int_t bilinear_grid_spacing_virt;
|
||||
xy_float_t bilinear_grid_factor_virt;
|
||||
|
||||
void print_bilinear_leveling_grid_virt() {
|
||||
SERIAL_ECHOLNPGM("Subdivided with CATMULL ROM Leveling Grid:");
|
||||
@@ -207,7 +207,7 @@ void print_bilinear_leveling_grid() {
|
||||
+ p[i] * (2 - 5 * sq(t) + 3 * t * sq(t))
|
||||
+ p[i+1] * t * (1 + 4 * t - 3 * sq(t))
|
||||
- p[i+2] * sq(t) * (1 - t)
|
||||
) * 0.5;
|
||||
) * 0.5f;
|
||||
}
|
||||
|
||||
static float bed_level_virt_2cmr(const uint8_t x, const uint8_t y, const float &tx, const float &ty) {
|
||||
@@ -222,10 +222,8 @@ void print_bilinear_leveling_grid() {
|
||||
}
|
||||
|
||||
void bed_level_virt_interpolate() {
|
||||
bilinear_grid_spacing_virt[X_AXIS] = bilinear_grid_spacing[X_AXIS] / (BILINEAR_SUBDIVISIONS);
|
||||
bilinear_grid_spacing_virt[Y_AXIS] = bilinear_grid_spacing[Y_AXIS] / (BILINEAR_SUBDIVISIONS);
|
||||
bilinear_grid_factor_virt[X_AXIS] = RECIPROCAL(bilinear_grid_spacing_virt[X_AXIS]);
|
||||
bilinear_grid_factor_virt[Y_AXIS] = RECIPROCAL(bilinear_grid_spacing_virt[Y_AXIS]);
|
||||
bilinear_grid_spacing_virt = bilinear_grid_spacing / (BILINEAR_SUBDIVISIONS);
|
||||
bilinear_grid_factor_virt = bilinear_grid_spacing_virt.reciprocal();
|
||||
for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++)
|
||||
for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++)
|
||||
for (uint8_t ty = 0; ty < BILINEAR_SUBDIVISIONS; ty++)
|
||||
@@ -245,40 +243,38 @@ void print_bilinear_leveling_grid() {
|
||||
|
||||
// Refresh after other values have been updated
|
||||
void refresh_bed_level() {
|
||||
bilinear_grid_factor[X_AXIS] = RECIPROCAL(bilinear_grid_spacing[X_AXIS]);
|
||||
bilinear_grid_factor[Y_AXIS] = RECIPROCAL(bilinear_grid_spacing[Y_AXIS]);
|
||||
bilinear_grid_factor = bilinear_grid_spacing.reciprocal();
|
||||
#if ENABLED(ABL_BILINEAR_SUBDIVISION)
|
||||
bed_level_virt_interpolate();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ENABLED(ABL_BILINEAR_SUBDIVISION)
|
||||
#define ABL_BG_SPACING(A) bilinear_grid_spacing_virt[A]
|
||||
#define ABL_BG_FACTOR(A) bilinear_grid_factor_virt[A]
|
||||
#define ABL_BG_SPACING(A) bilinear_grid_spacing_virt.A
|
||||
#define ABL_BG_FACTOR(A) bilinear_grid_factor_virt.A
|
||||
#define ABL_BG_POINTS_X ABL_GRID_POINTS_VIRT_X
|
||||
#define ABL_BG_POINTS_Y ABL_GRID_POINTS_VIRT_Y
|
||||
#define ABL_BG_GRID(X,Y) z_values_virt[X][Y]
|
||||
#else
|
||||
#define ABL_BG_SPACING(A) bilinear_grid_spacing[A]
|
||||
#define ABL_BG_FACTOR(A) bilinear_grid_factor[A]
|
||||
#define ABL_BG_SPACING(A) bilinear_grid_spacing.A
|
||||
#define ABL_BG_FACTOR(A) bilinear_grid_factor.A
|
||||
#define ABL_BG_POINTS_X GRID_MAX_POINTS_X
|
||||
#define ABL_BG_POINTS_Y GRID_MAX_POINTS_Y
|
||||
#define ABL_BG_GRID(X,Y) z_values[X][Y]
|
||||
#endif
|
||||
|
||||
// Get the Z adjustment for non-linear bed leveling
|
||||
float bilinear_z_offset(const float raw[XYZ]) {
|
||||
float bilinear_z_offset(const xy_pos_t &raw) {
|
||||
|
||||
static float z1, d2, z3, d4, L, D, ratio_x, ratio_y,
|
||||
last_x = -999.999, last_y = -999.999;
|
||||
static float z1, d2, z3, d4, L, D;
|
||||
|
||||
static xy_pos_t prev { -999.999, -999.999 }, ratio;
|
||||
|
||||
// Whole units for the grid line indices. Constrained within bounds.
|
||||
static int8_t gridx, gridy, nextx, nexty,
|
||||
last_gridx = -99, last_gridy = -99;
|
||||
static xy_int8_t thisg, nextg, lastg { -99, -99 };
|
||||
|
||||
// XY relative to the probed area
|
||||
const float rx = raw[X_AXIS] - bilinear_start[X_AXIS],
|
||||
ry = raw[Y_AXIS] - bilinear_start[Y_AXIS];
|
||||
xy_pos_t rel = raw - bilinear_start.asFloat();
|
||||
|
||||
#if ENABLED(EXTRAPOLATE_BEYOND_GRID)
|
||||
#define FAR_EDGE_OR_BOX 2 // Keep using the last grid box
|
||||
@@ -286,63 +282,62 @@ float bilinear_z_offset(const float raw[XYZ]) {
|
||||
#define FAR_EDGE_OR_BOX 1 // Just use the grid far edge
|
||||
#endif
|
||||
|
||||
if (last_x != rx) {
|
||||
last_x = rx;
|
||||
ratio_x = rx * ABL_BG_FACTOR(X_AXIS);
|
||||
const float gx = constrain(FLOOR(ratio_x), 0, ABL_BG_POINTS_X - (FAR_EDGE_OR_BOX));
|
||||
ratio_x -= gx; // Subtract whole to get the ratio within the grid box
|
||||
if (prev.x != rel.x) {
|
||||
prev.x = rel.x;
|
||||
ratio.x = rel.x * ABL_BG_FACTOR(x);
|
||||
const float gx = constrain(FLOOR(ratio.x), 0, ABL_BG_POINTS_X - (FAR_EDGE_OR_BOX));
|
||||
ratio.x -= gx; // Subtract whole to get the ratio within the grid box
|
||||
|
||||
#if DISABLED(EXTRAPOLATE_BEYOND_GRID)
|
||||
// Beyond the grid maintain height at grid edges
|
||||
NOLESS(ratio_x, 0); // Never < 0.0. (> 1.0 is ok when nextx==gridx.)
|
||||
NOLESS(ratio.x, 0); // Never <0 (>1 is ok when nextg.x==thisg.x)
|
||||
#endif
|
||||
|
||||
gridx = gx;
|
||||
nextx = _MIN(gridx + 1, ABL_BG_POINTS_X - 1);
|
||||
thisg.x = gx;
|
||||
nextg.x = _MIN(thisg.x + 1, ABL_BG_POINTS_X - 1);
|
||||
}
|
||||
|
||||
if (last_y != ry || last_gridx != gridx) {
|
||||
if (prev.y != rel.y || lastg.x != thisg.x) {
|
||||
|
||||
if (last_y != ry) {
|
||||
last_y = ry;
|
||||
ratio_y = ry * ABL_BG_FACTOR(Y_AXIS);
|
||||
const float gy = constrain(FLOOR(ratio_y), 0, ABL_BG_POINTS_Y - (FAR_EDGE_OR_BOX));
|
||||
ratio_y -= gy;
|
||||
if (prev.y != rel.y) {
|
||||
prev.y = rel.y;
|
||||
ratio.y = rel.y * ABL_BG_FACTOR(y);
|
||||
const float gy = constrain(FLOOR(ratio.y), 0, ABL_BG_POINTS_Y - (FAR_EDGE_OR_BOX));
|
||||
ratio.y -= gy;
|
||||
|
||||
#if DISABLED(EXTRAPOLATE_BEYOND_GRID)
|
||||
// Beyond the grid maintain height at grid edges
|
||||
NOLESS(ratio_y, 0); // Never < 0.0. (> 1.0 is ok when nexty==gridy.)
|
||||
NOLESS(ratio.y, 0); // Never < 0.0. (> 1.0 is ok when nextg.y==thisg.y.)
|
||||
#endif
|
||||
|
||||
gridy = gy;
|
||||
nexty = _MIN(gridy + 1, ABL_BG_POINTS_Y - 1);
|
||||
thisg.y = gy;
|
||||
nextg.y = _MIN(thisg.y + 1, ABL_BG_POINTS_Y - 1);
|
||||
}
|
||||
|
||||
if (last_gridx != gridx || last_gridy != gridy) {
|
||||
last_gridx = gridx;
|
||||
last_gridy = gridy;
|
||||
if (lastg != thisg) {
|
||||
lastg = thisg;
|
||||
// Z at the box corners
|
||||
z1 = ABL_BG_GRID(gridx, gridy); // left-front
|
||||
d2 = ABL_BG_GRID(gridx, nexty) - z1; // left-back (delta)
|
||||
z3 = ABL_BG_GRID(nextx, gridy); // right-front
|
||||
d4 = ABL_BG_GRID(nextx, nexty) - z3; // right-back (delta)
|
||||
z1 = ABL_BG_GRID(thisg.x, thisg.y); // left-front
|
||||
d2 = ABL_BG_GRID(thisg.x, nextg.y) - z1; // left-back (delta)
|
||||
z3 = ABL_BG_GRID(nextg.x, thisg.y); // right-front
|
||||
d4 = ABL_BG_GRID(nextg.x, nextg.y) - z3; // right-back (delta)
|
||||
}
|
||||
|
||||
// Bilinear interpolate. Needed since ry or gridx has changed.
|
||||
L = z1 + d2 * ratio_y; // Linear interp. LF -> LB
|
||||
const float R = z3 + d4 * ratio_y; // Linear interp. RF -> RB
|
||||
// Bilinear interpolate. Needed since rel.y or thisg.x has changed.
|
||||
L = z1 + d2 * ratio.y; // Linear interp. LF -> LB
|
||||
const float R = z3 + d4 * ratio.y; // Linear interp. RF -> RB
|
||||
|
||||
D = R - L;
|
||||
}
|
||||
|
||||
const float offset = L + ratio_x * D; // the offset almost always changes
|
||||
const float offset = L + ratio.x * D; // the offset almost always changes
|
||||
|
||||
/*
|
||||
static float last_offset = 0;
|
||||
if (ABS(last_offset - offset) > 0.2) {
|
||||
SERIAL_ECHOLNPAIR("Sudden Shift at x=", rx, " / ", bilinear_grid_spacing[X_AXIS], " -> gridx=", gridx);
|
||||
SERIAL_ECHOLNPAIR(" y=", ry, " / ", bilinear_grid_spacing[Y_AXIS], " -> gridy=", gridy);
|
||||
SERIAL_ECHOLNPAIR(" ratio_x=", ratio_x, " ratio_y=", ratio_y);
|
||||
SERIAL_ECHOLNPAIR("Sudden Shift at x=", rel.x, " / ", bilinear_grid_spacing.x, " -> thisg.x=", thisg.x);
|
||||
SERIAL_ECHOLNPAIR(" y=", rel.y, " / ", bilinear_grid_spacing.y, " -> thisg.y=", thisg.y);
|
||||
SERIAL_ECHOLNPAIR(" ratio.x=", ratio.x, " ratio.y=", ratio.y);
|
||||
SERIAL_ECHOLNPAIR(" z1=", z1, " z2=", z2, " z3=", z3, " z4=", z4);
|
||||
SERIAL_ECHOLNPAIR(" L=", L, " R=", R, " offset=", offset);
|
||||
}
|
||||
@@ -354,7 +349,7 @@ float bilinear_z_offset(const float raw[XYZ]) {
|
||||
|
||||
#if IS_CARTESIAN && DISABLED(SEGMENT_LEVELED_MOVES)
|
||||
|
||||
#define CELL_INDEX(A,V) ((V - bilinear_start[_AXIS(A)]) * ABL_BG_FACTOR(_AXIS(A)))
|
||||
#define CELL_INDEX(A,V) ((V - bilinear_start.A) * ABL_BG_FACTOR(A))
|
||||
|
||||
/**
|
||||
* Prepare a bilinear-leveled linear move on Cartesian,
|
||||
@@ -362,62 +357,61 @@ float bilinear_z_offset(const float raw[XYZ]) {
|
||||
*/
|
||||
void bilinear_line_to_destination(const feedRate_t scaled_fr_mm_s, uint16_t x_splits, uint16_t y_splits) {
|
||||
// Get current and destination cells for this line
|
||||
int cx1 = CELL_INDEX(X, current_position[X_AXIS]),
|
||||
cy1 = CELL_INDEX(Y, current_position[Y_AXIS]),
|
||||
cx2 = CELL_INDEX(X, destination[X_AXIS]),
|
||||
cy2 = CELL_INDEX(Y, destination[Y_AXIS]);
|
||||
LIMIT(cx1, 0, ABL_BG_POINTS_X - 2);
|
||||
LIMIT(cy1, 0, ABL_BG_POINTS_Y - 2);
|
||||
LIMIT(cx2, 0, ABL_BG_POINTS_X - 2);
|
||||
LIMIT(cy2, 0, ABL_BG_POINTS_Y - 2);
|
||||
xy_int_t c1 { CELL_INDEX(x, current_position.x), CELL_INDEX(y, current_position.y) },
|
||||
c2 { CELL_INDEX(x, destination.x), CELL_INDEX(y, destination.y) };
|
||||
LIMIT(c1.x, 0, ABL_BG_POINTS_X - 2);
|
||||
LIMIT(c1.y, 0, ABL_BG_POINTS_Y - 2);
|
||||
LIMIT(c2.x, 0, ABL_BG_POINTS_X - 2);
|
||||
LIMIT(c2.y, 0, ABL_BG_POINTS_Y - 2);
|
||||
|
||||
// Start and end in the same cell? No split needed.
|
||||
if (cx1 == cx2 && cy1 == cy2) {
|
||||
set_current_from_destination();
|
||||
if (c1 == c2) {
|
||||
current_position = destination;
|
||||
line_to_current_position(scaled_fr_mm_s);
|
||||
return;
|
||||
}
|
||||
|
||||
#define LINE_SEGMENT_END(A) (current_position[_AXIS(A)] + (destination[_AXIS(A)] - current_position[_AXIS(A)]) * normalized_dist)
|
||||
#define LINE_SEGMENT_END(A) (current_position.A + (destination.A - current_position.A) * normalized_dist)
|
||||
|
||||
float normalized_dist, end[XYZE];
|
||||
const int8_t gcx = _MAX(cx1, cx2), gcy = _MAX(cy1, cy2);
|
||||
float normalized_dist;
|
||||
xyze_pos_t end;
|
||||
const xy_int8_t gc { _MAX(c1.x, c2.x), _MAX(c1.y, c2.y) };
|
||||
|
||||
// Crosses on the X and not already split on this X?
|
||||
// The x_splits flags are insurance against rounding errors.
|
||||
if (cx2 != cx1 && TEST(x_splits, gcx)) {
|
||||
if (c2.x != c1.x && TEST(x_splits, gc.x)) {
|
||||
// Split on the X grid line
|
||||
CBI(x_splits, gcx);
|
||||
COPY(end, destination);
|
||||
destination[X_AXIS] = bilinear_start[X_AXIS] + ABL_BG_SPACING(X_AXIS) * gcx;
|
||||
normalized_dist = (destination[X_AXIS] - current_position[X_AXIS]) / (end[X_AXIS] - current_position[X_AXIS]);
|
||||
destination[Y_AXIS] = LINE_SEGMENT_END(Y);
|
||||
CBI(x_splits, gc.x);
|
||||
end = destination;
|
||||
destination.x = bilinear_start.x + ABL_BG_SPACING(x) * gc.x;
|
||||
normalized_dist = (destination.x - current_position.x) / (end.x - current_position.x);
|
||||
destination.y = LINE_SEGMENT_END(y);
|
||||
}
|
||||
// Crosses on the Y and not already split on this Y?
|
||||
else if (cy2 != cy1 && TEST(y_splits, gcy)) {
|
||||
else if (c2.y != c1.y && TEST(y_splits, gc.y)) {
|
||||
// Split on the Y grid line
|
||||
CBI(y_splits, gcy);
|
||||
COPY(end, destination);
|
||||
destination[Y_AXIS] = bilinear_start[Y_AXIS] + ABL_BG_SPACING(Y_AXIS) * gcy;
|
||||
normalized_dist = (destination[Y_AXIS] - current_position[Y_AXIS]) / (end[Y_AXIS] - current_position[Y_AXIS]);
|
||||
destination[X_AXIS] = LINE_SEGMENT_END(X);
|
||||
CBI(y_splits, gc.y);
|
||||
end = destination;
|
||||
destination.y = bilinear_start.y + ABL_BG_SPACING(y) * gc.y;
|
||||
normalized_dist = (destination.y - current_position.y) / (end.y - current_position.y);
|
||||
destination.x = LINE_SEGMENT_END(x);
|
||||
}
|
||||
else {
|
||||
// Must already have been split on these border(s)
|
||||
// This should be a rare case.
|
||||
set_current_from_destination();
|
||||
current_position = destination;
|
||||
line_to_current_position(scaled_fr_mm_s);
|
||||
return;
|
||||
}
|
||||
|
||||
destination[Z_AXIS] = LINE_SEGMENT_END(Z);
|
||||
destination[E_AXIS] = LINE_SEGMENT_END(E);
|
||||
destination.z = LINE_SEGMENT_END(z);
|
||||
destination.e = LINE_SEGMENT_END(e);
|
||||
|
||||
// Do the split and look for more borders
|
||||
bilinear_line_to_destination(scaled_fr_mm_s, x_splits, y_splits);
|
||||
|
||||
// Restore destination from stack
|
||||
COPY(destination, end);
|
||||
destination = end;
|
||||
bilinear_line_to_destination(scaled_fr_mm_s, x_splits, y_splits);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,10 +23,10 @@
|
||||
|
||||
#include "../../../inc/MarlinConfigPre.h"
|
||||
|
||||
extern int bilinear_grid_spacing[2], bilinear_start[2];
|
||||
extern float bilinear_grid_factor[2],
|
||||
z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
|
||||
float bilinear_z_offset(const float raw[XYZ]);
|
||||
extern xy_int_t bilinear_grid_spacing, bilinear_start;
|
||||
extern xy_float_t bilinear_grid_factor;
|
||||
extern bed_mesh_t z_values;
|
||||
float bilinear_z_offset(const xy_pos_t &raw);
|
||||
|
||||
void extrapolate_unprobed_bed_level();
|
||||
void print_bilinear_leveling_grid();
|
||||
@@ -40,6 +40,6 @@ void refresh_bed_level();
|
||||
void bilinear_line_to_destination(const feedRate_t &scaled_fr_mm_s, uint16_t x_splits=0xFFFF, uint16_t y_splits=0xFFFF);
|
||||
#endif
|
||||
|
||||
#define _GET_MESH_X(I) (bilinear_start[X_AXIS] + (I) * bilinear_grid_spacing[X_AXIS])
|
||||
#define _GET_MESH_Y(J) (bilinear_start[Y_AXIS] + (J) * bilinear_grid_spacing[Y_AXIS])
|
||||
#define _GET_MESH_X(I) float(bilinear_start.x + (I) * bilinear_grid_spacing.x)
|
||||
#define _GET_MESH_Y(J) float(bilinear_start.y + (J) * bilinear_grid_spacing.y)
|
||||
#define Z_VALUES_ARR z_values
|
||||
|
||||
@@ -51,7 +51,7 @@ bool leveling_is_valid() {
|
||||
#if ENABLED(MESH_BED_LEVELING)
|
||||
mbl.has_mesh()
|
||||
#elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
|
||||
!!bilinear_grid_spacing[X_AXIS]
|
||||
!!bilinear_grid_spacing.x
|
||||
#elif ENABLED(AUTO_BED_LEVELING_UBL)
|
||||
ubl.mesh_is_valid()
|
||||
#else // 3POINT, LINEAR
|
||||
@@ -81,13 +81,13 @@ void set_bed_leveling_enabled(const bool enable/*=true*/) {
|
||||
|
||||
#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
|
||||
// Force bilinear_z_offset to re-calculate next time
|
||||
const float reset[XYZ] = { -9999.999, -9999.999, 0 };
|
||||
const xyz_pos_t reset { -9999.999, -9999.999, 0 };
|
||||
(void)bilinear_z_offset(reset);
|
||||
#endif
|
||||
|
||||
if (planner.leveling_active) { // leveling from on to off
|
||||
// change unleveled current_position to physical current_position without moving steppers.
|
||||
planner.apply_leveling(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS]);
|
||||
planner.apply_leveling(current_position);
|
||||
planner.leveling_active = false; // disable only AFTER calling apply_leveling
|
||||
}
|
||||
else { // leveling from off to on
|
||||
@@ -116,9 +116,9 @@ TemporaryBedLevelingState::TemporaryBedLevelingState(const bool enable) : saved(
|
||||
planner.set_z_fade_height(zfh);
|
||||
|
||||
if (leveling_was_active) {
|
||||
const float oldpos[] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] };
|
||||
const xyz_pos_t oldpos = current_position;
|
||||
set_bed_leveling_enabled(true);
|
||||
if (do_report && memcmp(oldpos, current_position, sizeof(oldpos)))
|
||||
if (do_report && oldpos != current_position)
|
||||
report_current_position();
|
||||
}
|
||||
}
|
||||
@@ -137,8 +137,8 @@ void reset_bed_level() {
|
||||
#if ENABLED(MESH_BED_LEVELING)
|
||||
mbl.reset();
|
||||
#elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
|
||||
bilinear_start[X_AXIS] = bilinear_start[Y_AXIS] =
|
||||
bilinear_grid_spacing[X_AXIS] = bilinear_grid_spacing[Y_AXIS] = 0;
|
||||
bilinear_start.reset();
|
||||
bilinear_grid_spacing.reset();
|
||||
for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++)
|
||||
for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) {
|
||||
z_values[x][y] = NAN;
|
||||
@@ -223,25 +223,25 @@ void reset_bed_level() {
|
||||
|
||||
#if EITHER(MESH_BED_LEVELING, PROBE_MANUALLY)
|
||||
|
||||
void _manual_goto_xy(const float &rx, const float &ry) {
|
||||
void _manual_goto_xy(const xy_pos_t &pos) {
|
||||
|
||||
#ifdef MANUAL_PROBE_START_Z
|
||||
constexpr float startz = _MAX(0, MANUAL_PROBE_START_Z);
|
||||
#if MANUAL_PROBE_HEIGHT > 0
|
||||
do_blocking_move_to(rx, ry, MANUAL_PROBE_HEIGHT);
|
||||
do_blocking_move_to_z(_MAX(0,MANUAL_PROBE_START_Z));
|
||||
do_blocking_move_to_xy_z(pos, MANUAL_PROBE_HEIGHT);
|
||||
do_blocking_move_to_z(startz);
|
||||
#else
|
||||
do_blocking_move_to(rx, ry, _MAX(0,MANUAL_PROBE_START_Z));
|
||||
do_blocking_move_to_xy_z(pos, startz);
|
||||
#endif
|
||||
#elif MANUAL_PROBE_HEIGHT > 0
|
||||
const float prev_z = current_position[Z_AXIS];
|
||||
do_blocking_move_to(rx, ry, MANUAL_PROBE_HEIGHT);
|
||||
const float prev_z = current_position.z;
|
||||
do_blocking_move_to_xy_z(pos, MANUAL_PROBE_HEIGHT);
|
||||
do_blocking_move_to_z(prev_z);
|
||||
#else
|
||||
do_blocking_move_to_xy(rx, ry);
|
||||
do_blocking_move_to_xy(pos);
|
||||
#endif
|
||||
|
||||
current_position[X_AXIS] = rx;
|
||||
current_position[Y_AXIS] = ry;
|
||||
current_position = pos;
|
||||
|
||||
#if ENABLED(LCD_BED_LEVELING)
|
||||
ui.wait_for_bl_move = false;
|
||||
|
||||
@@ -38,7 +38,7 @@ void reset_bed_level();
|
||||
#endif
|
||||
|
||||
#if EITHER(MESH_BED_LEVELING, PROBE_MANUALLY)
|
||||
void _manual_goto_xy(const float &x, const float &y);
|
||||
void _manual_goto_xy(const xy_pos_t &pos);
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -57,11 +57,6 @@ class TemporaryBedLevelingState {
|
||||
|
||||
typedef float bed_mesh_t[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
|
||||
|
||||
typedef struct {
|
||||
int8_t x_index, y_index;
|
||||
float distance; // When populated, the distance from the search location
|
||||
} mesh_index_pair;
|
||||
|
||||
#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
|
||||
#include "abl/abl.h"
|
||||
#elif ENABLED(AUTO_BED_LEVELING_UBL)
|
||||
@@ -71,6 +66,7 @@ class TemporaryBedLevelingState {
|
||||
#endif
|
||||
|
||||
#define Z_VALUES(X,Y) Z_VALUES_ARR[X][Y]
|
||||
#define _GET_MESH_POS(M) { _GET_MESH_X(M.a), _GET_MESH_Y(M.b) }
|
||||
|
||||
#if EITHER(AUTO_BED_LEVELING_BILINEAR, MESH_BED_LEVELING)
|
||||
|
||||
@@ -85,4 +81,18 @@ class TemporaryBedLevelingState {
|
||||
|
||||
#endif
|
||||
|
||||
struct mesh_index_pair {
|
||||
xy_int8_t pos;
|
||||
float distance; // When populated, the distance from the search location
|
||||
void invalidate() { pos = -1; }
|
||||
bool valid() const { return pos.x >= 0 && pos.y >= 0; }
|
||||
#if ENABLED(AUTO_BED_LEVELING_UBL)
|
||||
xy_pos_t meshpos() {
|
||||
return { ubl.mesh_index_to_xpos(pos.x), ubl.mesh_index_to_ypos(pos.y) };
|
||||
}
|
||||
#endif
|
||||
operator xy_int8_t&() { return pos; }
|
||||
operator const xy_int8_t&() const { return pos; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,10 +24,9 @@
|
||||
|
||||
#if ENABLED(MESH_BED_LEVELING)
|
||||
|
||||
#include "mesh_bed_leveling.h"
|
||||
#include "../bedlevel.h"
|
||||
|
||||
#include "../../../module/motion.h"
|
||||
#include "../../../feature/bedlevel/bedlevel.h"
|
||||
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
#include "../../../lcd/extensible_ui/ui_api.h"
|
||||
@@ -66,62 +65,60 @@
|
||||
*/
|
||||
void mesh_bed_leveling::line_to_destination(const feedRate_t &scaled_fr_mm_s, uint8_t x_splits, uint8_t y_splits) {
|
||||
// Get current and destination cells for this line
|
||||
int cx1 = cell_index_x(current_position[X_AXIS]),
|
||||
cy1 = cell_index_y(current_position[Y_AXIS]),
|
||||
cx2 = cell_index_x(destination[X_AXIS]),
|
||||
cy2 = cell_index_y(destination[Y_AXIS]);
|
||||
NOMORE(cx1, GRID_MAX_POINTS_X - 2);
|
||||
NOMORE(cy1, GRID_MAX_POINTS_Y - 2);
|
||||
NOMORE(cx2, GRID_MAX_POINTS_X - 2);
|
||||
NOMORE(cy2, GRID_MAX_POINTS_Y - 2);
|
||||
xy_int8_t scel = cell_indexes(current_position), ecel = cell_indexes(destination);
|
||||
NOMORE(scel.x, GRID_MAX_POINTS_X - 2);
|
||||
NOMORE(scel.y, GRID_MAX_POINTS_Y - 2);
|
||||
NOMORE(ecel.x, GRID_MAX_POINTS_X - 2);
|
||||
NOMORE(ecel.y, GRID_MAX_POINTS_Y - 2);
|
||||
|
||||
// Start and end in the same cell? No split needed.
|
||||
if (cx1 == cx2 && cy1 == cy2) {
|
||||
if (scel == ecel) {
|
||||
line_to_destination(scaled_fr_mm_s);
|
||||
set_current_from_destination();
|
||||
current_position = destination;
|
||||
return;
|
||||
}
|
||||
|
||||
#define MBL_SEGMENT_END(A) (current_position[_AXIS(A)] + (destination[_AXIS(A)] - current_position[_AXIS(A)]) * normalized_dist)
|
||||
#define MBL_SEGMENT_END(A) (current_position.A + (destination.A - current_position.A) * normalized_dist)
|
||||
|
||||
float normalized_dist, end[XYZE];
|
||||
const int8_t gcx = _MAX(cx1, cx2), gcy = _MAX(cy1, cy2);
|
||||
float normalized_dist;
|
||||
xyze_pos_t dest;
|
||||
const int8_t gcx = _MAX(scel.x, ecel.x), gcy = _MAX(scel.y, ecel.y);
|
||||
|
||||
// Crosses on the X and not already split on this X?
|
||||
// The x_splits flags are insurance against rounding errors.
|
||||
if (cx2 != cx1 && TEST(x_splits, gcx)) {
|
||||
if (ecel.x != scel.x && TEST(x_splits, gcx)) {
|
||||
// Split on the X grid line
|
||||
CBI(x_splits, gcx);
|
||||
COPY(end, destination);
|
||||
destination[X_AXIS] = index_to_xpos[gcx];
|
||||
normalized_dist = (destination[X_AXIS] - current_position[X_AXIS]) / (end[X_AXIS] - current_position[X_AXIS]);
|
||||
destination[Y_AXIS] = MBL_SEGMENT_END(Y);
|
||||
dest = destination;
|
||||
destination.x = index_to_xpos[gcx];
|
||||
normalized_dist = (destination.x - current_position.x) / (dest.x - current_position.x);
|
||||
destination.y = MBL_SEGMENT_END(y);
|
||||
}
|
||||
// Crosses on the Y and not already split on this Y?
|
||||
else if (cy2 != cy1 && TEST(y_splits, gcy)) {
|
||||
else if (ecel.y != scel.y && TEST(y_splits, gcy)) {
|
||||
// Split on the Y grid line
|
||||
CBI(y_splits, gcy);
|
||||
COPY(end, destination);
|
||||
destination[Y_AXIS] = index_to_ypos[gcy];
|
||||
normalized_dist = (destination[Y_AXIS] - current_position[Y_AXIS]) / (end[Y_AXIS] - current_position[Y_AXIS]);
|
||||
destination[X_AXIS] = MBL_SEGMENT_END(X);
|
||||
dest = destination;
|
||||
destination.y = index_to_ypos[gcy];
|
||||
normalized_dist = (destination.y - current_position.y) / (dest.y - current_position.y);
|
||||
destination.x = MBL_SEGMENT_END(x);
|
||||
}
|
||||
else {
|
||||
// Must already have been split on these border(s)
|
||||
// This should be a rare case.
|
||||
line_to_destination(scaled_fr_mm_s);
|
||||
set_current_from_destination();
|
||||
current_position = destination;
|
||||
return;
|
||||
}
|
||||
|
||||
destination[Z_AXIS] = MBL_SEGMENT_END(Z);
|
||||
destination[E_AXIS] = MBL_SEGMENT_END(E);
|
||||
destination.z = MBL_SEGMENT_END(z);
|
||||
destination.e = MBL_SEGMENT_END(e);
|
||||
|
||||
// Do the split and look for more borders
|
||||
line_to_destination(scaled_fr_mm_s, x_splits, y_splits);
|
||||
|
||||
// Restore destination from stack
|
||||
COPY(destination, end);
|
||||
destination = dest;
|
||||
line_to_destination(scaled_fr_mm_s, x_splits, y_splits);
|
||||
}
|
||||
|
||||
|
||||
@@ -76,21 +76,27 @@ public:
|
||||
int8_t cx = (x - (MESH_MIN_X)) * RECIPROCAL(MESH_X_DIST);
|
||||
return constrain(cx, 0, (GRID_MAX_POINTS_X) - 2);
|
||||
}
|
||||
|
||||
static int8_t cell_index_y(const float &y) {
|
||||
int8_t cy = (y - (MESH_MIN_Y)) * RECIPROCAL(MESH_Y_DIST);
|
||||
return constrain(cy, 0, (GRID_MAX_POINTS_Y) - 2);
|
||||
}
|
||||
static inline xy_int8_t cell_indexes(const float &x, const float &y) {
|
||||
return { cell_index_x(x), cell_index_y(y) };
|
||||
}
|
||||
static inline xy_int8_t cell_indexes(const xy_pos_t &xy) { return cell_indexes(xy.x, xy.y); }
|
||||
|
||||
static int8_t probe_index_x(const float &x) {
|
||||
int8_t px = (x - (MESH_MIN_X) + 0.5f * (MESH_X_DIST)) * RECIPROCAL(MESH_X_DIST);
|
||||
return WITHIN(px, 0, GRID_MAX_POINTS_X - 1) ? px : -1;
|
||||
}
|
||||
|
||||
static int8_t probe_index_y(const float &y) {
|
||||
int8_t py = (y - (MESH_MIN_Y) + 0.5f * (MESH_Y_DIST)) * RECIPROCAL(MESH_Y_DIST);
|
||||
return WITHIN(py, 0, GRID_MAX_POINTS_Y - 1) ? py : -1;
|
||||
}
|
||||
static inline xy_int8_t probe_indexes(const float &x, const float &y) {
|
||||
return { probe_index_x(x), probe_index_y(y) };
|
||||
}
|
||||
static inline xy_int8_t probe_indexes(const xy_pos_t &xy) { return probe_indexes(xy.x, xy.y); }
|
||||
|
||||
static float calc_z0(const float &a0, const float &a1, const float &z1, const float &a2, const float &z2) {
|
||||
const float delta_z = (z2 - z1) / (a2 - a1),
|
||||
@@ -98,21 +104,21 @@ public:
|
||||
return z1 + delta_a * delta_z;
|
||||
}
|
||||
|
||||
static float get_z(const float &x0, const float &y0
|
||||
static float get_z(const xy_pos_t &pos
|
||||
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
|
||||
, const float &factor
|
||||
, const float &factor=1.0f
|
||||
#endif
|
||||
) {
|
||||
const int8_t cx = cell_index_x(x0), cy = cell_index_y(y0);
|
||||
const float z1 = calc_z0(x0, index_to_xpos[cx], z_values[cx][cy], index_to_xpos[cx + 1], z_values[cx + 1][cy]),
|
||||
z2 = calc_z0(x0, index_to_xpos[cx], z_values[cx][cy + 1], index_to_xpos[cx + 1], z_values[cx + 1][cy + 1]),
|
||||
z0 = calc_z0(y0, index_to_ypos[cy], z1, index_to_ypos[cy + 1], z2);
|
||||
#if DISABLED(ENABLE_LEVELING_FADE_HEIGHT)
|
||||
constexpr float factor = 1.0f;
|
||||
#endif
|
||||
const xy_int8_t ind = cell_indexes(pos);
|
||||
const float x1 = index_to_xpos[ind.x], x2 = index_to_xpos[ind.x+1],
|
||||
y1 = index_to_xpos[ind.y], y2 = index_to_xpos[ind.y+1],
|
||||
z1 = calc_z0(pos.x, x1, z_values[ind.x][ind.y ], x2, z_values[ind.x+1][ind.y ]),
|
||||
z2 = calc_z0(pos.x, x1, z_values[ind.x][ind.y+1], x2, z_values[ind.x+1][ind.y+1]);
|
||||
|
||||
return z_offset + z0
|
||||
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
|
||||
* factor
|
||||
#endif
|
||||
;
|
||||
return z_offset + calc_z0(pos.y, y1, z1, y2, z2) * factor;
|
||||
}
|
||||
|
||||
#if IS_CARTESIAN && DISABLED(SEGMENT_LEVELED_MOVES)
|
||||
|
||||
@@ -176,8 +176,7 @@
|
||||
// Add XY probe offset from extruder because probe_at_point() subtracts them when
|
||||
// moving to the XY position to be measured. This ensures better agreement between
|
||||
// the current Z position after G28 and the mesh values.
|
||||
const float current_xi = find_closest_x_index(current_position[X_AXIS] + probe_offset[X_AXIS]),
|
||||
current_yi = find_closest_y_index(current_position[Y_AXIS] + probe_offset[Y_AXIS]);
|
||||
const xy_int8_t curr = closest_indexes(xy_pos_t(current_position) + xy_pos_t(probe_offset));
|
||||
|
||||
if (!lcd) SERIAL_EOL();
|
||||
for (int8_t j = GRID_MAX_POINTS_Y - 1; j >= 0; j--) {
|
||||
@@ -193,7 +192,7 @@
|
||||
for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
|
||||
|
||||
// Opening Brace or Space
|
||||
const bool is_current = i == current_xi && j == current_yi;
|
||||
const bool is_current = i == curr.x && j == curr.y;
|
||||
if (human) SERIAL_CHAR(is_current ? '[' : ' ');
|
||||
|
||||
// Z Value at current I, J
|
||||
|
||||
@@ -32,15 +32,12 @@
|
||||
#define UBL_OK false
|
||||
#define UBL_ERR true
|
||||
|
||||
#define USE_NOZZLE_AS_REFERENCE 0
|
||||
#define USE_PROBE_AS_REFERENCE 1
|
||||
|
||||
// ubl_G29.cpp
|
||||
|
||||
enum MeshPointType : char { INVALID, REAL, SET_IN_BITMAP };
|
||||
|
||||
// External references
|
||||
|
||||
struct mesh_index_pair;
|
||||
|
||||
#define MESH_X_DIST (float(MESH_MAX_X - (MESH_MIN_X)) / float(GRID_MAX_POINTS_X - 1))
|
||||
#define MESH_Y_DIST (float(MESH_MAX_Y - (MESH_MIN_Y)) / float(GRID_MAX_POINTS_Y - 1))
|
||||
|
||||
@@ -52,10 +49,11 @@ class unified_bed_leveling {
|
||||
g29_repetition_cnt,
|
||||
g29_storage_slot,
|
||||
g29_map_type;
|
||||
static bool g29_c_flag, g29_x_flag, g29_y_flag;
|
||||
static float g29_x_pos, g29_y_pos,
|
||||
g29_card_thickness,
|
||||
static bool g29_c_flag;
|
||||
static float g29_card_thickness,
|
||||
g29_constant;
|
||||
static xy_pos_t g29_pos;
|
||||
static xy_bool_t xy_seen;
|
||||
|
||||
#if HAS_BED_PROBE
|
||||
static int g29_grid_size;
|
||||
@@ -65,16 +63,19 @@ class unified_bed_leveling {
|
||||
static void move_z_with_encoder(const float &multiplier);
|
||||
static float measure_point_with_encoder();
|
||||
static float measure_business_card_thickness(float in_height);
|
||||
static void manually_probe_remaining_mesh(const float&, const float&, const float&, const float&, const bool) _O0;
|
||||
static void fine_tune_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map) _O0;
|
||||
static void manually_probe_remaining_mesh(const xy_pos_t&, const float&, const float&, const bool) _O0;
|
||||
static void fine_tune_mesh(const xy_pos_t &pos, const bool do_ubl_mesh_map) _O0;
|
||||
#endif
|
||||
|
||||
static bool g29_parameter_parsing() _O0;
|
||||
static void shift_mesh_height();
|
||||
static void probe_entire_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map, const bool stow_probe, const bool do_furthest) _O0;
|
||||
static void probe_entire_mesh(const xy_pos_t &near, const bool do_ubl_mesh_map, const bool stow_probe, const bool do_furthest) _O0;
|
||||
static void tilt_mesh_based_on_3pts(const float &z1, const float &z2, const float &z3);
|
||||
static void tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map);
|
||||
static bool smart_fill_one(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir);
|
||||
static inline bool smart_fill_one(const xy_uint8_t &pos, const xy_uint8_t &dir) {
|
||||
return smart_fill_one(pos.x, pos.y, dir.x, dir.y);
|
||||
}
|
||||
static void smart_fill_mesh();
|
||||
|
||||
#if ENABLED(UBL_DEVEL_DEBUGGING)
|
||||
@@ -91,7 +92,7 @@ class unified_bed_leveling {
|
||||
static void save_ubl_active_state_and_disable();
|
||||
static void restore_ubl_active_state_and_leave();
|
||||
static void display_map(const int) _O0;
|
||||
static mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType, const float&, const float&, const bool, uint16_t[16]) _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 void reset();
|
||||
static void invalidate();
|
||||
@@ -118,14 +119,14 @@ class unified_bed_leveling {
|
||||
|
||||
FORCE_INLINE static void set_z(const int8_t px, const int8_t py, const float &z) { z_values[px][py] = z; }
|
||||
|
||||
static int8_t get_cell_index_x(const float &x) {
|
||||
static int8_t cell_index_x(const float &x) {
|
||||
const int8_t cx = (x - (MESH_MIN_X)) * RECIPROCAL(MESH_X_DIST);
|
||||
return constrain(cx, 0, (GRID_MAX_POINTS_X) - 1); // -1 is appropriate if we want all movement to the X_MAX
|
||||
} // position. But with this defined this way, it is possible
|
||||
// to extrapolate off of this point even further out. Probably
|
||||
// that is OK because something else should be keeping that from
|
||||
// happening and should not be worried about at this level.
|
||||
static int8_t get_cell_index_y(const float &y) {
|
||||
static int8_t cell_index_y(const float &y) {
|
||||
const int8_t cy = (y - (MESH_MIN_Y)) * RECIPROCAL(MESH_Y_DIST);
|
||||
return constrain(cy, 0, (GRID_MAX_POINTS_Y) - 1); // -1 is appropriate if we want all movement to the Y_MAX
|
||||
} // position. But with this defined this way, it is possible
|
||||
@@ -133,15 +134,22 @@ class unified_bed_leveling {
|
||||
// that is OK because something else should be keeping that from
|
||||
// happening and should not be worried about at this level.
|
||||
|
||||
static int8_t find_closest_x_index(const float &x) {
|
||||
static inline xy_int8_t cell_indexes(const float &x, const float &y) {
|
||||
return { cell_index_x(x), cell_index_y(y) };
|
||||
}
|
||||
static inline xy_int8_t cell_indexes(const xy_pos_t &xy) { return cell_indexes(xy.x, xy.y); }
|
||||
|
||||
static int8_t closest_x_index(const float &x) {
|
||||
const int8_t px = (x - (MESH_MIN_X) + (MESH_X_DIST) * 0.5) * RECIPROCAL(MESH_X_DIST);
|
||||
return WITHIN(px, 0, GRID_MAX_POINTS_X - 1) ? px : -1;
|
||||
}
|
||||
|
||||
static int8_t find_closest_y_index(const float &y) {
|
||||
static int8_t closest_y_index(const float &y) {
|
||||
const int8_t py = (y - (MESH_MIN_Y) + (MESH_Y_DIST) * 0.5) * RECIPROCAL(MESH_Y_DIST);
|
||||
return WITHIN(py, 0, GRID_MAX_POINTS_Y - 1) ? py : -1;
|
||||
}
|
||||
static inline xy_int8_t closest_indexes(const xy_pos_t &xy) {
|
||||
return { closest_x_index(xy.x), closest_y_index(xy.y) };
|
||||
}
|
||||
|
||||
/**
|
||||
* z2 --|
|
||||
@@ -228,8 +236,7 @@ class unified_bed_leveling {
|
||||
* on the Y position within the cell.
|
||||
*/
|
||||
static float get_z_correction(const float &rx0, const float &ry0) {
|
||||
const int8_t cx = get_cell_index_x(rx0),
|
||||
cy = get_cell_index_y(ry0); // return values are clamped
|
||||
const int8_t cx = cell_index_x(rx0), cy = cell_index_y(ry0); // return values are clamped
|
||||
|
||||
/**
|
||||
* Check if the requested location is off the mesh. If so, and
|
||||
@@ -275,11 +282,11 @@ class unified_bed_leveling {
|
||||
}
|
||||
return z0;
|
||||
}
|
||||
static inline float get_z_correction(const xy_pos_t &pos) { return get_z_correction(pos.x, pos.y); }
|
||||
|
||||
static inline float mesh_index_to_xpos(const uint8_t i) {
|
||||
return i < GRID_MAX_POINTS_X ? pgm_read_float(&_mesh_index_to_xpos[i]) : MESH_MIN_X + i * (MESH_X_DIST);
|
||||
}
|
||||
|
||||
static inline float mesh_index_to_ypos(const uint8_t i) {
|
||||
return i < GRID_MAX_POINTS_Y ? pgm_read_float(&_mesh_index_to_ypos[i]) : MESH_MIN_Y + i * (MESH_Y_DIST);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -35,12 +35,6 @@
|
||||
#include "../../../Marlin.h"
|
||||
#include <math.h>
|
||||
|
||||
#if AVR_AT90USB1286_FAMILY // Teensyduino & Printrboard IDE extensions have compile errors without this
|
||||
inline void set_current_from_destination() { COPY(current_position, destination); }
|
||||
#else
|
||||
extern void set_current_from_destination();
|
||||
#endif
|
||||
|
||||
#if !UBL_SEGMENTED
|
||||
|
||||
void unified_bed_leveling::line_to_destination_cartesian(const feedRate_t &scaled_fr_mm_s, const uint8_t extruder) {
|
||||
@@ -50,60 +44,57 @@
|
||||
* just do the required Z-Height correction, call the Planner's buffer_line() routine, and leave
|
||||
*/
|
||||
#if HAS_POSITION_MODIFIERS
|
||||
float start[XYZE] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS] },
|
||||
end[XYZE] = { destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS] };
|
||||
xyze_pos_t start = current_position, end = destination;
|
||||
planner.apply_modifiers(start);
|
||||
planner.apply_modifiers(end);
|
||||
#else
|
||||
const float (&start)[XYZE] = current_position,
|
||||
(&end)[XYZE] = destination;
|
||||
const xyze_pos_t &start = current_position, &end = destination;
|
||||
#endif
|
||||
|
||||
const int cell_start_xi = get_cell_index_x(start[X_AXIS]),
|
||||
cell_start_yi = get_cell_index_y(start[Y_AXIS]),
|
||||
cell_dest_xi = get_cell_index_x(end[X_AXIS]),
|
||||
cell_dest_yi = get_cell_index_y(end[Y_AXIS]);
|
||||
const xy_int8_t istart = cell_indexes(start), iend = cell_indexes(end);
|
||||
|
||||
// A move within the same cell needs no splitting
|
||||
if (cell_start_xi == cell_dest_xi && cell_start_yi == cell_dest_yi) {
|
||||
if (istart == iend) {
|
||||
|
||||
// For a move off the bed, use a constant Z raise
|
||||
if (!WITHIN(cell_dest_xi, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(cell_dest_yi, 0, GRID_MAX_POINTS_Y - 1)) {
|
||||
if (!WITHIN(iend.x, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(iend.y, 0, GRID_MAX_POINTS_Y - 1)) {
|
||||
|
||||
// Note: There is no Z Correction in this case. We are off the grid and don't know what
|
||||
// a reasonable correction would be. If the user has specified a UBL_Z_RAISE_WHEN_OFF_MESH
|
||||
// value, that will be used instead of a calculated (Bi-Linear interpolation) correction.
|
||||
|
||||
const float z_raise = 0.0
|
||||
#ifdef UBL_Z_RAISE_WHEN_OFF_MESH
|
||||
+ UBL_Z_RAISE_WHEN_OFF_MESH
|
||||
#endif
|
||||
;
|
||||
planner.buffer_segment(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + z_raise, end[E_AXIS], scaled_fr_mm_s, extruder);
|
||||
set_current_from_destination();
|
||||
#ifdef UBL_Z_RAISE_WHEN_OFF_MESH
|
||||
end.z += UBL_Z_RAISE_WHEN_OFF_MESH;
|
||||
#endif
|
||||
planner.buffer_segment(end, scaled_fr_mm_s, extruder);
|
||||
current_position = destination;
|
||||
return;
|
||||
}
|
||||
|
||||
FINAL_MOVE:
|
||||
|
||||
// The distance is always MESH_X_DIST so multiply by the constant reciprocal.
|
||||
const float xratio = (end[X_AXIS] - mesh_index_to_xpos(cell_dest_xi)) * RECIPROCAL(MESH_X_DIST);
|
||||
const float xratio = (end.x - mesh_index_to_xpos(iend.x)) * RECIPROCAL(MESH_X_DIST);
|
||||
|
||||
float z1 = z_values[cell_dest_xi ][cell_dest_yi ] + xratio *
|
||||
(z_values[cell_dest_xi + 1][cell_dest_yi ] - z_values[cell_dest_xi][cell_dest_yi ]),
|
||||
z2 = z_values[cell_dest_xi ][cell_dest_yi + 1] + xratio *
|
||||
(z_values[cell_dest_xi + 1][cell_dest_yi + 1] - z_values[cell_dest_xi][cell_dest_yi + 1]);
|
||||
|
||||
if (cell_dest_xi >= GRID_MAX_POINTS_X - 1) z1 = z2 = 0.0;
|
||||
float z1, z2;
|
||||
if (iend.x >= GRID_MAX_POINTS_X - 1)
|
||||
z1 = z2 = 0.0;
|
||||
else {
|
||||
z1 = z_values[iend.x ][iend.y ] + xratio *
|
||||
(z_values[iend.x + 1][iend.y ] - z_values[iend.x][iend.y ]),
|
||||
z2 = z_values[iend.x ][iend.y + 1] + xratio *
|
||||
(z_values[iend.x + 1][iend.y + 1] - z_values[iend.x][iend.y + 1]);
|
||||
}
|
||||
|
||||
// X cell-fraction done. Interpolate the two Z offsets with the Y fraction for the final Z offset.
|
||||
const float yratio = (end[Y_AXIS] - mesh_index_to_ypos(cell_dest_yi)) * RECIPROCAL(MESH_Y_DIST),
|
||||
z0 = cell_dest_yi < GRID_MAX_POINTS_Y - 1 ? (z1 + (z2 - z1) * yratio) * planner.fade_scaling_factor_for_z(end[Z_AXIS]) : 0.0;
|
||||
const float yratio = (end.y - mesh_index_to_ypos(iend.y)) * RECIPROCAL(MESH_Y_DIST),
|
||||
z0 = iend.y < GRID_MAX_POINTS_Y - 1 ? (z1 + (z2 - z1) * yratio) * planner.fade_scaling_factor_for_z(end.z) : 0.0;
|
||||
|
||||
// Undefined parts of the Mesh in z_values[][] are NAN.
|
||||
// Replace NAN corrections with 0.0 to prevent NAN propagation.
|
||||
planner.buffer_segment(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + (isnan(z0) ? 0.0 : z0), end[E_AXIS], scaled_fr_mm_s, extruder);
|
||||
set_current_from_destination();
|
||||
if (!isnan(z0)) end.z += z0;
|
||||
planner.buffer_segment(end, scaled_fr_mm_s, extruder);
|
||||
current_position = destination;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -112,17 +103,11 @@
|
||||
* case - crossing only one X or Y line - after details are worked out to reduce computation.
|
||||
*/
|
||||
|
||||
const float dx = end[X_AXIS] - start[X_AXIS],
|
||||
dy = end[Y_AXIS] - start[Y_AXIS];
|
||||
|
||||
const int left_flag = dx < 0.0 ? 1 : 0,
|
||||
down_flag = dy < 0.0 ? 1 : 0;
|
||||
|
||||
const float adx = left_flag ? -dx : dx,
|
||||
ady = down_flag ? -dy : dy;
|
||||
|
||||
const int dxi = cell_start_xi == cell_dest_xi ? 0 : left_flag ? -1 : 1,
|
||||
dyi = cell_start_yi == cell_dest_yi ? 0 : down_flag ? -1 : 1;
|
||||
const xy_float_t dist = end - start;
|
||||
const xy_bool_t neg { dist.x < 0, dist.y < 0 };
|
||||
const xy_int8_t ineg { int8_t(neg.x), int8_t(neg.y) };
|
||||
const xy_float_t sign { neg.x ? -1.0f : 1.0f, neg.y ? -1.0f : 1.0f };
|
||||
const xy_int8_t iadd { int8_t(iend.x == istart.x ? 0 : sign.x), int8_t(iend.y == istart.y ? 0 : sign.y) };
|
||||
|
||||
/**
|
||||
* Compute the extruder scaling factor for each partial move, checking for
|
||||
@@ -132,64 +117,64 @@
|
||||
* components. The larger of the two is used to preserve precision.
|
||||
*/
|
||||
|
||||
const bool use_x_dist = adx > ady;
|
||||
const xy_float_t ad = sign * dist;
|
||||
const bool use_x_dist = ad.x > ad.y;
|
||||
|
||||
float on_axis_distance = use_x_dist ? dx : dy,
|
||||
e_position = end[E_AXIS] - start[E_AXIS],
|
||||
z_position = end[Z_AXIS] - start[Z_AXIS];
|
||||
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 e_normalized_dist = e_position / on_axis_distance,
|
||||
const float e_normalized_dist = e_position / on_axis_distance, // Allow divide by zero
|
||||
z_normalized_dist = z_position / on_axis_distance;
|
||||
|
||||
int current_xi = cell_start_xi,
|
||||
current_yi = cell_start_yi;
|
||||
xy_int8_t icell = istart;
|
||||
|
||||
const float m = dy / dx,
|
||||
c = start[Y_AXIS] - m * start[X_AXIS];
|
||||
const float ratio = dist.y / dist.x, // Allow divide by zero
|
||||
c = start.y - ratio * start.x;
|
||||
|
||||
const bool inf_normalized_flag = (isinf(e_normalized_dist) != 0),
|
||||
inf_m_flag = (isinf(m) != 0);
|
||||
const bool inf_normalized_flag = isinf(e_normalized_dist),
|
||||
inf_ratio_flag = isinf(ratio);
|
||||
|
||||
/**
|
||||
* Handle vertical lines that stay within one column.
|
||||
* These need not be perfectly vertical.
|
||||
*/
|
||||
if (dxi == 0) { // Vertical line?
|
||||
current_yi += down_flag; // Line going down? Just go to the bottom.
|
||||
while (current_yi != cell_dest_yi + down_flag) {
|
||||
current_yi += dyi;
|
||||
const float next_mesh_line_y = mesh_index_to_ypos(current_yi);
|
||||
if (iadd.x == 0) { // Vertical line?
|
||||
icell.y += ineg.y; // Line going down? Just go to the bottom.
|
||||
while (icell.y != iend.y + ineg.y) {
|
||||
icell.y += iadd.y;
|
||||
const float next_mesh_line_y = mesh_index_to_ypos(icell.y);
|
||||
|
||||
/**
|
||||
* Skip the calculations for an infinite slope.
|
||||
* For others the next X is the same so this can continue.
|
||||
* Calculate X at the next Y mesh line.
|
||||
*/
|
||||
const float rx = inf_m_flag ? start[X_AXIS] : (next_mesh_line_y - c) / m;
|
||||
const float rx = inf_ratio_flag ? start.x : (next_mesh_line_y - c) / ratio;
|
||||
|
||||
float z0 = z_correction_for_x_on_horizontal_mesh_line(rx, current_xi, current_yi)
|
||||
* planner.fade_scaling_factor_for_z(end[Z_AXIS]);
|
||||
float z0 = z_correction_for_x_on_horizontal_mesh_line(rx, icell.x, icell.y)
|
||||
* planner.fade_scaling_factor_for_z(end.z);
|
||||
|
||||
// Undefined parts of the Mesh in z_values[][] are NAN.
|
||||
// Replace NAN corrections with 0.0 to prevent NAN propagation.
|
||||
if (isnan(z0)) z0 = 0.0;
|
||||
|
||||
const float ry = mesh_index_to_ypos(current_yi);
|
||||
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
|
||||
* 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.
|
||||
*/
|
||||
if (ry != start[Y_AXIS]) {
|
||||
if (!inf_normalized_flag) {
|
||||
on_axis_distance = use_x_dist ? rx - start[X_AXIS] : ry - start[Y_AXIS];
|
||||
e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist;
|
||||
z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist;
|
||||
if (ry != start.y) {
|
||||
if (!inf_normalized_flag) { // fall-through faster than branch
|
||||
on_axis_distance = use_x_dist ? rx - start.x : ry - start.y;
|
||||
e_position = start.e + on_axis_distance * e_normalized_dist;
|
||||
z_position = start.z + on_axis_distance * z_normalized_dist;
|
||||
}
|
||||
else {
|
||||
e_position = end[E_AXIS];
|
||||
z_position = end[Z_AXIS];
|
||||
e_position = end.e;
|
||||
z_position = end.z;
|
||||
}
|
||||
|
||||
planner.buffer_segment(rx, ry, z_position + z0, e_position, scaled_fr_mm_s, extruder);
|
||||
@@ -197,10 +182,10 @@
|
||||
}
|
||||
|
||||
// At the final destination? Usually not, but when on a Y Mesh Line it's completed.
|
||||
if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS])
|
||||
if (xy_pos_t(current_position) != xy_pos_t(end))
|
||||
goto FINAL_MOVE;
|
||||
|
||||
set_current_from_destination();
|
||||
current_position = destination;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -208,36 +193,34 @@
|
||||
* Handle horizontal lines that stay within one row.
|
||||
* These need not be perfectly horizontal.
|
||||
*/
|
||||
if (dyi == 0) { // Horizontal line?
|
||||
current_xi += left_flag; // Heading left? Just go to the left edge of the cell for the first move.
|
||||
while (current_xi != cell_dest_xi + left_flag) {
|
||||
current_xi += dxi;
|
||||
const float next_mesh_line_x = mesh_index_to_xpos(current_xi),
|
||||
ry = m * next_mesh_line_x + c; // Calculate Y at the next X mesh 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.
|
||||
while (icell.x != iend.x + ineg.x) {
|
||||
icell.x += iadd.x;
|
||||
const float rx = mesh_index_to_xpos(icell.x);
|
||||
const float ry = ratio * rx + c; // Calculate Y at the next X mesh line
|
||||
|
||||
float z0 = z_correction_for_y_on_vertical_mesh_line(ry, current_xi, current_yi)
|
||||
* planner.fade_scaling_factor_for_z(end[Z_AXIS]);
|
||||
float z0 = z_correction_for_y_on_vertical_mesh_line(ry, icell.x, icell.y)
|
||||
* planner.fade_scaling_factor_for_z(end.z);
|
||||
|
||||
// Undefined parts of the Mesh in z_values[][] are NAN.
|
||||
// Replace NAN corrections with 0.0 to prevent NAN propagation.
|
||||
if (isnan(z0)) z0 = 0.0;
|
||||
|
||||
const float rx = mesh_index_to_xpos(current_xi);
|
||||
|
||||
/**
|
||||
* Without this check, it's possible to generate a zero length move, as in the case where
|
||||
* 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.
|
||||
*/
|
||||
if (rx != start[X_AXIS]) {
|
||||
if (rx != start.x) {
|
||||
if (!inf_normalized_flag) {
|
||||
on_axis_distance = use_x_dist ? rx - start[X_AXIS] : ry - start[Y_AXIS];
|
||||
e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist; // is based on X or Y because this is a horizontal move
|
||||
z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist;
|
||||
on_axis_distance = use_x_dist ? rx - start.x : ry - start.y;
|
||||
e_position = start.e + on_axis_distance * e_normalized_dist; // is based on X or Y because this is a horizontal move
|
||||
z_position = start.z + on_axis_distance * z_normalized_dist;
|
||||
}
|
||||
else {
|
||||
e_position = end[E_AXIS];
|
||||
z_position = end[Z_AXIS];
|
||||
e_position = end.e;
|
||||
z_position = end.z;
|
||||
}
|
||||
|
||||
if (!planner.buffer_segment(rx, ry, z_position + z0, e_position, scaled_fr_mm_s, extruder))
|
||||
@@ -245,93 +228,88 @@
|
||||
} //else printf("FIRST MOVE PRUNED ");
|
||||
}
|
||||
|
||||
if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS])
|
||||
if (xy_pos_t(current_position) != xy_pos_t(end))
|
||||
goto FINAL_MOVE;
|
||||
|
||||
set_current_from_destination();
|
||||
current_position = destination;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Handle the generic case of a line crossing both X and Y Mesh lines.
|
||||
* Generic case of a line crossing both X and Y Mesh lines.
|
||||
*
|
||||
*/
|
||||
|
||||
int xi_cnt = cell_start_xi - cell_dest_xi,
|
||||
yi_cnt = cell_start_yi - cell_dest_yi;
|
||||
xy_int8_t cnt = (istart - iend).ABS();
|
||||
|
||||
if (xi_cnt < 0) xi_cnt = -xi_cnt;
|
||||
if (yi_cnt < 0) yi_cnt = -yi_cnt;
|
||||
icell += ineg;
|
||||
|
||||
current_xi += left_flag;
|
||||
current_yi += down_flag;
|
||||
while (cnt) {
|
||||
|
||||
while (xi_cnt || yi_cnt) {
|
||||
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),
|
||||
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.)
|
||||
|
||||
const float next_mesh_line_x = mesh_index_to_xpos(current_xi + dxi),
|
||||
next_mesh_line_y = mesh_index_to_ypos(current_yi + dyi),
|
||||
ry = m * next_mesh_line_x + c, // Calculate Y at the next X mesh line
|
||||
rx = (next_mesh_line_y - c) / m; // Calculate X at the next Y mesh line
|
||||
// (No need to worry about m being zero.
|
||||
// If that was the case, it was already detected
|
||||
// as a vertical line move above.)
|
||||
|
||||
if (left_flag == (rx > next_mesh_line_x)) { // Check if we hit the Y line first
|
||||
if (neg.x == (rx > next_mesh_line_x)) { // Check if we hit the Y line first
|
||||
// Yes! Crossing a Y Mesh Line next
|
||||
float z0 = z_correction_for_x_on_horizontal_mesh_line(rx, current_xi - left_flag, current_yi + dyi)
|
||||
* planner.fade_scaling_factor_for_z(end[Z_AXIS]);
|
||||
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);
|
||||
|
||||
// Undefined parts of the Mesh in z_values[][] are NAN.
|
||||
// Replace NAN corrections with 0.0 to prevent NAN propagation.
|
||||
if (isnan(z0)) z0 = 0.0;
|
||||
|
||||
if (!inf_normalized_flag) {
|
||||
on_axis_distance = use_x_dist ? rx - start[X_AXIS] : next_mesh_line_y - start[Y_AXIS];
|
||||
e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist;
|
||||
z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist;
|
||||
on_axis_distance = use_x_dist ? rx - start.x : next_mesh_line_y - start.y;
|
||||
e_position = start.e + on_axis_distance * e_normalized_dist;
|
||||
z_position = start.z + on_axis_distance * z_normalized_dist;
|
||||
}
|
||||
else {
|
||||
e_position = end[E_AXIS];
|
||||
z_position = end[Z_AXIS];
|
||||
e_position = end.e;
|
||||
z_position = end.z;
|
||||
}
|
||||
if (!planner.buffer_segment(rx, next_mesh_line_y, z_position + z0, e_position, scaled_fr_mm_s, extruder))
|
||||
break;
|
||||
current_yi += dyi;
|
||||
yi_cnt--;
|
||||
icell.y += iadd.y;
|
||||
cnt.y--;
|
||||
}
|
||||
else {
|
||||
// Yes! Crossing a X Mesh Line next
|
||||
float z0 = z_correction_for_y_on_vertical_mesh_line(ry, current_xi + dxi, current_yi - down_flag)
|
||||
* planner.fade_scaling_factor_for_z(end[Z_AXIS]);
|
||||
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);
|
||||
|
||||
// Undefined parts of the Mesh in z_values[][] are NAN.
|
||||
// Replace NAN corrections with 0.0 to prevent NAN propagation.
|
||||
if (isnan(z0)) z0 = 0.0;
|
||||
|
||||
if (!inf_normalized_flag) {
|
||||
on_axis_distance = use_x_dist ? next_mesh_line_x - start[X_AXIS] : ry - start[Y_AXIS];
|
||||
e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist;
|
||||
z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist;
|
||||
on_axis_distance = use_x_dist ? next_mesh_line_x - start.x : ry - start.y;
|
||||
e_position = start.e + on_axis_distance * e_normalized_dist;
|
||||
z_position = start.z + on_axis_distance * z_normalized_dist;
|
||||
}
|
||||
else {
|
||||
e_position = end[E_AXIS];
|
||||
z_position = end[Z_AXIS];
|
||||
e_position = end.e;
|
||||
z_position = end.z;
|
||||
}
|
||||
|
||||
if (!planner.buffer_segment(next_mesh_line_x, ry, z_position + z0, e_position, scaled_fr_mm_s, extruder))
|
||||
break;
|
||||
current_xi += dxi;
|
||||
xi_cnt--;
|
||||
icell.x += iadd.x;
|
||||
cnt.x--;
|
||||
}
|
||||
|
||||
if (xi_cnt < 0 || yi_cnt < 0) break; // Too far! Exit the loop and go to FINAL_MOVE
|
||||
if (cnt.x < 0 || cnt.y < 0) break; // Too far! Exit the loop and go to FINAL_MOVE
|
||||
}
|
||||
|
||||
if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS])
|
||||
if (xy_pos_t(current_position) != xy_pos_t(end))
|
||||
goto FINAL_MOVE;
|
||||
|
||||
set_current_from_destination();
|
||||
current_position = destination;
|
||||
}
|
||||
|
||||
#else // UBL_SEGMENTED
|
||||
@@ -356,56 +334,42 @@
|
||||
|
||||
bool _O2 unified_bed_leveling::line_to_destination_segmented(const feedRate_t &scaled_fr_mm_s) {
|
||||
|
||||
if (!position_is_reachable(destination[X_AXIS], destination[Y_AXIS])) // fail if moving outside reachable boundary
|
||||
return true; // did not move, so current_position still accurate
|
||||
if (!position_is_reachable(destination)) // fail if moving outside reachable boundary
|
||||
return true; // did not move, so current_position still accurate
|
||||
|
||||
const float total[XYZE] = {
|
||||
destination[X_AXIS] - current_position[X_AXIS],
|
||||
destination[Y_AXIS] - current_position[Y_AXIS],
|
||||
destination[Z_AXIS] - current_position[Z_AXIS],
|
||||
destination[E_AXIS] - current_position[E_AXIS]
|
||||
};
|
||||
const xyze_pos_t total = destination - current_position;
|
||||
|
||||
const float cartesian_xy_mm = HYPOT(total[X_AXIS], total[Y_AXIS]); // total horizontal xy distance
|
||||
const float cart_xy_mm_2 = HYPOT2(total.x, total.y),
|
||||
cart_xy_mm = SQRT(cart_xy_mm_2); // Total XY distance
|
||||
|
||||
#if IS_KINEMATIC
|
||||
const float seconds = cartesian_xy_mm / scaled_fr_mm_s; // Duration of XY move at requested rate
|
||||
uint16_t segments = LROUND(delta_segments_per_second * seconds), // Preferred number of segments for distance @ feedrate
|
||||
seglimit = LROUND(cartesian_xy_mm * RECIPROCAL(DELTA_SEGMENT_MIN_LENGTH)); // Number of segments at minimum segment length
|
||||
NOMORE(segments, seglimit); // Limit to minimum segment length (fewer segments)
|
||||
const float seconds = cart_xy_mm / scaled_fr_mm_s; // Duration of XY move at requested rate
|
||||
uint16_t segments = LROUND(delta_segments_per_second * seconds), // Preferred number of segments for distance @ feedrate
|
||||
seglimit = LROUND(cart_xy_mm * RECIPROCAL(DELTA_SEGMENT_MIN_LENGTH)); // Number of segments at minimum segment length
|
||||
NOMORE(segments, seglimit); // Limit to minimum segment length (fewer segments)
|
||||
#else
|
||||
uint16_t segments = LROUND(cartesian_xy_mm * RECIPROCAL(DELTA_SEGMENT_MIN_LENGTH)); // cartesian fixed segment length
|
||||
uint16_t segments = LROUND(cart_xy_mm * RECIPROCAL(DELTA_SEGMENT_MIN_LENGTH)); // Cartesian fixed segment length
|
||||
#endif
|
||||
|
||||
NOLESS(segments, 1U); // must have at least one segment
|
||||
const float inv_segments = 1.0f / segments; // divide once, multiply thereafter
|
||||
NOLESS(segments, 1U); // Must have at least one segment
|
||||
const float inv_segments = 1.0f / segments, // Reciprocal to save calculation
|
||||
segment_xyz_mm = SQRT(cart_xy_mm_2 + sq(total.z)) * inv_segments; // Length of each segment
|
||||
|
||||
const float segment_xyz_mm = HYPOT(cartesian_xy_mm, total[Z_AXIS]) * inv_segments; // length of each segment
|
||||
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||
const float inv_duration = scaled_fr_mm_s / segment_xyz_mm;
|
||||
#endif
|
||||
|
||||
const float diff[XYZE] = {
|
||||
total[X_AXIS] * inv_segments,
|
||||
total[Y_AXIS] * inv_segments,
|
||||
total[Z_AXIS] * inv_segments,
|
||||
total[E_AXIS] * inv_segments
|
||||
};
|
||||
xyze_float_t diff = total * inv_segments;
|
||||
|
||||
// Note that E segment distance could vary slightly as z mesh height
|
||||
// changes for each segment, but small enough to ignore.
|
||||
|
||||
float raw[XYZE] = {
|
||||
current_position[X_AXIS],
|
||||
current_position[Y_AXIS],
|
||||
current_position[Z_AXIS],
|
||||
current_position[E_AXIS]
|
||||
};
|
||||
xyze_pos_t raw = current_position;
|
||||
|
||||
// Just do plain segmentation if UBL is inactive or the target is above the fade height
|
||||
if (!planner.leveling_active || !planner.leveling_active_at_z(destination[Z_AXIS])) {
|
||||
if (!planner.leveling_active || !planner.leveling_active_at_z(destination.z)) {
|
||||
while (--segments) {
|
||||
LOOP_XYZE(i) raw[i] += diff[i];
|
||||
raw += diff;
|
||||
planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, segment_xyz_mm
|
||||
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||
, inv_duration
|
||||
@@ -417,17 +381,17 @@
|
||||
, inv_duration
|
||||
#endif
|
||||
);
|
||||
return false; // moved but did not set_current_from_destination();
|
||||
return false; // Did not set current from destination
|
||||
}
|
||||
|
||||
// Otherwise perform per-segment leveling
|
||||
|
||||
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
|
||||
const float fade_scaling_factor = planner.fade_scaling_factor_for_z(destination[Z_AXIS]);
|
||||
const float fade_scaling_factor = planner.fade_scaling_factor_for_z(destination.z);
|
||||
#endif
|
||||
|
||||
// increment to first segment destination
|
||||
LOOP_XYZE(i) raw[i] += diff[i];
|
||||
// Move to first segment destination
|
||||
raw += diff;
|
||||
|
||||
for (;;) { // for each mesh cell encountered during the move
|
||||
|
||||
@@ -438,75 +402,68 @@
|
||||
// in top of loop and again re-find same adjacent cell and use it, just less efficient
|
||||
// for mesh inset area.
|
||||
|
||||
int8_t cell_xi = (raw[X_AXIS] - (MESH_MIN_X)) * RECIPROCAL(MESH_X_DIST),
|
||||
cell_yi = (raw[Y_AXIS] - (MESH_MIN_Y)) * RECIPROCAL(MESH_Y_DIST);
|
||||
xy_int8_t icell = {
|
||||
int8_t((raw.x - (MESH_MIN_X)) * RECIPROCAL(MESH_X_DIST)),
|
||||
int8_t((raw.y - (MESH_MIN_Y)) * RECIPROCAL(MESH_Y_DIST))
|
||||
};
|
||||
LIMIT(icell.x, 0, (GRID_MAX_POINTS_X) - 1);
|
||||
LIMIT(icell.y, 0, (GRID_MAX_POINTS_Y) - 1);
|
||||
|
||||
LIMIT(cell_xi, 0, (GRID_MAX_POINTS_X) - 1);
|
||||
LIMIT(cell_yi, 0, (GRID_MAX_POINTS_Y) - 1);
|
||||
|
||||
const float x0 = mesh_index_to_xpos(cell_xi), // 64 byte table lookup avoids mul+add
|
||||
y0 = mesh_index_to_ypos(cell_yi);
|
||||
|
||||
float z_x0y0 = z_values[cell_xi ][cell_yi ], // z at lower left corner
|
||||
z_x1y0 = z_values[cell_xi+1][cell_yi ], // z at upper left corner
|
||||
z_x0y1 = z_values[cell_xi ][cell_yi+1], // z at lower right corner
|
||||
z_x1y1 = z_values[cell_xi+1][cell_yi+1]; // z at upper right corner
|
||||
float z_x0y0 = z_values[icell.x ][icell.y ], // z at lower left corner
|
||||
z_x1y0 = z_values[icell.x+1][icell.y ], // z at upper left corner
|
||||
z_x0y1 = z_values[icell.x ][icell.y+1], // z at lower right corner
|
||||
z_x1y1 = z_values[icell.x+1][icell.y+1]; // z at upper right corner
|
||||
|
||||
if (isnan(z_x0y0)) z_x0y0 = 0; // ideally activating planner.leveling_active (G29 A)
|
||||
if (isnan(z_x1y0)) z_x1y0 = 0; // should refuse if any invalid mesh points
|
||||
if (isnan(z_x0y1)) z_x0y1 = 0; // in order to avoid isnan tests per cell,
|
||||
if (isnan(z_x1y1)) z_x1y1 = 0; // thus guessing zero for undefined points
|
||||
|
||||
float cx = raw[X_AXIS] - x0, // cell-relative x and y
|
||||
cy = raw[Y_AXIS] - y0;
|
||||
const xy_pos_t pos = { mesh_index_to_xpos(icell.x), mesh_index_to_ypos(icell.y) };
|
||||
xy_pos_t cell = raw - pos;
|
||||
|
||||
const float z_xmy0 = (z_x1y0 - z_x0y0) * RECIPROCAL(MESH_X_DIST), // z slope per x along y0 (lower left to lower right)
|
||||
z_xmy1 = (z_x1y1 - z_x0y1) * RECIPROCAL(MESH_X_DIST); // z slope per x along y1 (upper left to upper right)
|
||||
|
||||
float z_cxy0 = z_x0y0 + z_xmy0 * cx; // z height along y0 at cx (changes for each cx in cell)
|
||||
float z_cxy0 = z_x0y0 + z_xmy0 * cell.x; // z height along y0 at cell.x (changes for each cell.x in cell)
|
||||
|
||||
const float z_cxy1 = z_x0y1 + z_xmy1 * cx, // z height along y1 at cx
|
||||
z_cxyd = z_cxy1 - z_cxy0; // z height difference along cx from y0 to y1
|
||||
const float z_cxy1 = z_x0y1 + z_xmy1 * cell.x, // z height along y1 at cell.x
|
||||
z_cxyd = z_cxy1 - z_cxy0; // z height difference along cell.x from y0 to y1
|
||||
|
||||
float z_cxym = z_cxyd * RECIPROCAL(MESH_Y_DIST); // z slope per y along cx from y0 to y1 (changes for each cx in cell)
|
||||
float z_cxym = z_cxyd * RECIPROCAL(MESH_Y_DIST); // z slope per y along cell.x from pos.y to y1 (changes for each cell.x in cell)
|
||||
|
||||
// float z_cxcy = z_cxy0 + z_cxym * cy; // interpolated mesh z height along cx at cy (do inside the segment loop)
|
||||
// float z_cxcy = z_cxy0 + z_cxym * cell.y; // interpolated mesh z height along cell.x at cell.y (do inside the segment loop)
|
||||
|
||||
// As subsequent segments step through this cell, the z_cxy0 intercept will change
|
||||
// and the z_cxym slope will change, both as a function of cx within the cell, and
|
||||
// and the z_cxym slope will change, both as a function of cell.x within the cell, and
|
||||
// each change by a constant for fixed segment lengths.
|
||||
|
||||
const float z_sxy0 = z_xmy0 * diff[X_AXIS], // per-segment adjustment to z_cxy0
|
||||
z_sxym = (z_xmy1 - z_xmy0) * RECIPROCAL(MESH_Y_DIST) * diff[X_AXIS]; // per-segment adjustment to z_cxym
|
||||
const float z_sxy0 = z_xmy0 * diff.x, // per-segment adjustment to z_cxy0
|
||||
z_sxym = (z_xmy1 - z_xmy0) * RECIPROCAL(MESH_Y_DIST) * diff.x; // per-segment adjustment to z_cxym
|
||||
|
||||
for (;;) { // for all segments within this mesh cell
|
||||
|
||||
if (--segments == 0) COPY(raw, destination); // if this is last segment, use destination for exact
|
||||
if (--segments == 0) raw = destination; // if this is last segment, use destination for exact
|
||||
|
||||
const float z_cxcy = (z_cxy0 + z_cxym * cy) // interpolated mesh z height along cx at cy
|
||||
const float z_cxcy = (z_cxy0 + z_cxym * cell.y) // interpolated mesh z height along cell.x at cell.y
|
||||
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
|
||||
* fade_scaling_factor // apply fade factor to interpolated mesh height
|
||||
#endif
|
||||
;
|
||||
|
||||
const float z = raw[Z_AXIS];
|
||||
raw[Z_AXIS] += z_cxcy;
|
||||
planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, segment_xyz_mm
|
||||
planner.buffer_line(raw.x, raw.y, raw.z + z_cxcy, raw.e, scaled_fr_mm_s, active_extruder, segment_xyz_mm
|
||||
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||
, inv_duration
|
||||
#endif
|
||||
);
|
||||
raw[Z_AXIS] = z;
|
||||
|
||||
if (segments == 0) // done with last segment
|
||||
return false; // did not set_current_from_destination()
|
||||
return false; // didn't set current from destination
|
||||
|
||||
LOOP_XYZE(i) raw[i] += diff[i];
|
||||
raw += diff;
|
||||
cell += diff;
|
||||
|
||||
cx += diff[X_AXIS];
|
||||
cy += diff[Y_AXIS];
|
||||
|
||||
if (!WITHIN(cx, 0, MESH_X_DIST) || !WITHIN(cy, 0, MESH_Y_DIST)) // done within this cell, break to next
|
||||
if (!WITHIN(cell.x, 0, MESH_X_DIST) || !WITHIN(cell.y, 0, MESH_Y_DIST)) // done within this cell, break to next
|
||||
break;
|
||||
|
||||
// Next segment still within same mesh cell, adjust the per-segment
|
||||
|
||||
@@ -306,6 +306,9 @@ public:
|
||||
PORT_REDIRECT(card.transfer_port_index);
|
||||
#endif
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
|
||||
while (PENDING(millis(), transfer_window)) {
|
||||
switch (stream_state) {
|
||||
/**
|
||||
@@ -439,6 +442,8 @@ public:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
}
|
||||
|
||||
void dispatch() {
|
||||
|
||||
@@ -71,7 +71,13 @@ void update_case_light() {
|
||||
|
||||
#if DISABLED(CASE_LIGHT_NO_BRIGHTNESS)
|
||||
if (PWM_PIN(CASE_LIGHT_PIN))
|
||||
analogWrite(pin_t(CASE_LIGHT_PIN), n10ct);
|
||||
analogWrite(pin_t(CASE_LIGHT_PIN),
|
||||
#if CASE_LIGHT_MAX_PWM == 255
|
||||
n10ct
|
||||
#else
|
||||
map(n10ct, 0, 255, 0, CASE_LIGHT_MAX_PWM)
|
||||
#endif
|
||||
);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
#include "dac_mcp4728.h"
|
||||
|
||||
uint16_t mcp4728_values[XYZE];
|
||||
xyze_uint_t mcp4728_values;
|
||||
|
||||
/**
|
||||
* Begin I2C, get current values (input register and eeprom) of mcp4728
|
||||
@@ -121,8 +121,8 @@ uint8_t mcp4728_getDrvPct(const uint8_t channel) { return uint8_t(100.0 * mcp472
|
||||
* Receives all Drive strengths as 0-100 percent values, updates
|
||||
* DAC Values array and calls fastwrite to update the DAC.
|
||||
*/
|
||||
void mcp4728_setDrvPct(uint8_t pct[XYZE]) {
|
||||
LOOP_XYZE(i) mcp4728_values[i] = 0.01 * pct[i] * (DAC_STEPPER_MAX);
|
||||
void mcp4728_setDrvPct(xyze_uint8_t &pct) {
|
||||
mcp4728_values *= 0.01 * pct * (DAC_STEPPER_MAX);
|
||||
mcp4728_fastWrite();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
* Arduino library for MicroChip MCP4728 I2C D/A converter.
|
||||
*/
|
||||
|
||||
#include "../../core/types.h"
|
||||
|
||||
#include <Wire.h>
|
||||
|
||||
#define defaultVDD DAC_STEPPER_MAX //was 5000 but differs with internal Vref
|
||||
@@ -54,4 +56,4 @@ uint16_t mcp4728_getValue(const uint8_t channel);
|
||||
uint8_t mcp4728_fastWrite();
|
||||
uint8_t mcp4728_simpleCommand(const byte simpleCommand);
|
||||
uint8_t mcp4728_getDrvPct(const uint8_t channel);
|
||||
void mcp4728_setDrvPct(uint8_t pct[XYZE]);
|
||||
void mcp4728_setDrvPct(xyze_uint8_t &pct);
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
#include "stepper_dac.h"
|
||||
|
||||
bool dac_present = false;
|
||||
const uint8_t dac_order[NUM_AXIS] = DAC_STEPPER_ORDER;
|
||||
uint8_t dac_channel_pct[XYZE] = DAC_MOTOR_CURRENT_DEFAULT;
|
||||
constexpr xyze_uint8_t dac_order = DAC_STEPPER_ORDER;
|
||||
xyze_uint8_t dac_channel_pct = DAC_MOTOR_CURRENT_DEFAULT;
|
||||
|
||||
int dac_init() {
|
||||
#if PIN_EXISTS(DAC_DISABLE)
|
||||
@@ -77,8 +77,8 @@ void dac_current_raw(uint8_t channel, uint16_t val) {
|
||||
static float dac_perc(int8_t n) { return 100.0 * mcp4728_getValue(dac_order[n]) * RECIPROCAL(DAC_STEPPER_MAX); }
|
||||
static float dac_amps(int8_t n) { return mcp4728_getDrvPct(dac_order[n]) * (DAC_STEPPER_MAX) * 0.125 * RECIPROCAL(DAC_STEPPER_SENSE); }
|
||||
|
||||
uint8_t dac_current_get_percent(AxisEnum axis) { return mcp4728_getDrvPct(dac_order[axis]); }
|
||||
void dac_current_set_percents(const uint8_t pct[XYZE]) {
|
||||
uint8_t dac_current_get_percent(const AxisEnum axis) { return mcp4728_getDrvPct(dac_order[axis]); }
|
||||
void dac_current_set_percents(xyze_uint8_t &pct) {
|
||||
LOOP_XYZE(i) dac_channel_pct[i] = pct[dac_order[i]];
|
||||
mcp4728_setDrvPct(dac_channel_pct);
|
||||
}
|
||||
|
||||
@@ -33,4 +33,4 @@ void dac_current_raw(uint8_t channel, uint16_t val);
|
||||
void dac_print_values();
|
||||
void dac_commit_eeprom();
|
||||
uint8_t dac_current_get_percent(AxisEnum axis);
|
||||
void dac_current_set_percents(const uint8_t pct[XYZE]);
|
||||
void dac_current_set_percents(xyze_uint8_t &pct);
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#if MB(5DPRINT)
|
||||
#define DIGIPOT_I2C_FACTOR 117.96
|
||||
#define DIGIPOT_I2C_MAX_CURRENT 1.736
|
||||
#elif MB(AZTEEG_X5_MINI) || MB(AZTEEG_X5_MINI_WIFI)
|
||||
#elif MB(AZTEEG_X5_MINI, AZTEEG_X5_MINI_WIFI)
|
||||
#define DIGIPOT_I2C_FACTOR 113.5
|
||||
#define DIGIPOT_I2C_MAX_CURRENT 2.0
|
||||
#else
|
||||
|
||||
@@ -123,8 +123,8 @@ void FWRetract::retract(const bool retracting
|
||||
SERIAL_ECHOLNPAIR("retracted_swap[", i, "] ", retracted_swap[i]);
|
||||
#endif
|
||||
}
|
||||
SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]);
|
||||
SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_AXIS]);
|
||||
SERIAL_ECHOLNPAIR("current_position.z ", current_position.z);
|
||||
SERIAL_ECHOLNPAIR("current_position.e ", current_position.e);
|
||||
SERIAL_ECHOLNPAIR("current_hop ", current_hop);
|
||||
//*/
|
||||
|
||||
@@ -136,7 +136,7 @@ void FWRetract::retract(const bool retracting
|
||||
);
|
||||
|
||||
// The current position will be the destination for E and Z moves
|
||||
set_destination_from_current();
|
||||
destination = current_position;
|
||||
|
||||
#if ENABLED(RETRACT_SYNC_MIXING)
|
||||
const uint8_t old_mixing_tool = mixer.get_current_vtool();
|
||||
@@ -147,7 +147,7 @@ void FWRetract::retract(const bool retracting
|
||||
if (retracting) {
|
||||
// Retract by moving from a faux E position back to the current E position
|
||||
current_retract[active_extruder] = base_retract;
|
||||
prepare_internal_move_to_destination( // set_current_to_destination
|
||||
prepare_internal_move_to_destination( // set current to destination
|
||||
settings.retract_feedrate_mm_s
|
||||
#if ENABLED(RETRACT_SYNC_MIXING)
|
||||
* (MIXING_STEPPERS)
|
||||
@@ -171,7 +171,7 @@ void FWRetract::retract(const bool retracting
|
||||
|
||||
const float extra_recover = swapping ? settings.swap_retract_recover_extra : settings.retract_recover_extra;
|
||||
if (extra_recover) {
|
||||
current_position[E_AXIS] -= extra_recover; // Adjust the current E position by the extra amount to recover
|
||||
current_position.e -= extra_recover; // Adjust the current E position by the extra amount to recover
|
||||
sync_plan_position_e(); // Sync the planner position so the extra amount is recovered
|
||||
}
|
||||
|
||||
@@ -207,8 +207,8 @@ void FWRetract::retract(const bool retracting
|
||||
SERIAL_ECHOLNPAIR("retracted_swap[", i, "] ", retracted_swap[i]);
|
||||
#endif
|
||||
}
|
||||
SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]);
|
||||
SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_AXIS]);
|
||||
SERIAL_ECHOLNPAIR("current_position.z ", current_position.z);
|
||||
SERIAL_ECHOLNPAIR("current_position.e ", current_position.e);
|
||||
SERIAL_ECHOLNPAIR("current_hop ", current_hop);
|
||||
//*/
|
||||
}
|
||||
|
||||
@@ -102,8 +102,8 @@ void host_action(const char * const pstr, const bool eol) {
|
||||
|
||||
void host_response_handler(const uint8_t response) {
|
||||
#ifdef DEBUG_HOST_ACTIONS
|
||||
SERIAL_ECHOLNPAIR("M86 Handle Reason: ", host_prompt_reason);
|
||||
SERIAL_ECHOLNPAIR("M86 Handle Response: ", response);
|
||||
SERIAL_ECHOLNPAIR("M876 Handle Reason: ", host_prompt_reason);
|
||||
SERIAL_ECHOLNPAIR("M876 Handle Response: ", response);
|
||||
#endif
|
||||
const char *msg = PSTR("UNKNOWN STATE");
|
||||
const PromptReason hpr = host_prompt_reason;
|
||||
|
||||
@@ -71,35 +71,35 @@ Joystick joystick;
|
||||
|
||||
#if HAS_JOY_ADC_X || HAS_JOY_ADC_Y || HAS_JOY_ADC_Z
|
||||
|
||||
void Joystick::calculate(float (&norm_jog)[XYZ]) {
|
||||
void Joystick::calculate(xyz_float_t &norm_jog) {
|
||||
// Do nothing if enable pin (active-low) is not LOW
|
||||
#if HAS_JOY_ADC_EN
|
||||
if (READ(JOY_EN_PIN)) return;
|
||||
#endif
|
||||
|
||||
auto _normalize_joy = [](float &norm_jog, const int16_t raw, const int16_t (&joy_limits)[4]) {
|
||||
auto _normalize_joy = [](float &axis_jog, const int16_t raw, const int16_t (&joy_limits)[4]) {
|
||||
if (WITHIN(raw, joy_limits[0], joy_limits[3])) {
|
||||
// within limits, check deadzone
|
||||
if (raw > joy_limits[2])
|
||||
norm_jog = (raw - joy_limits[2]) / float(joy_limits[3] - joy_limits[2]);
|
||||
axis_jog = (raw - joy_limits[2]) / float(joy_limits[3] - joy_limits[2]);
|
||||
else if (raw < joy_limits[1])
|
||||
norm_jog = (raw - joy_limits[1]) / float(joy_limits[1] - joy_limits[0]); // negative value
|
||||
axis_jog = (raw - joy_limits[1]) / float(joy_limits[1] - joy_limits[0]); // negative value
|
||||
// Map normal to jog value via quadratic relationship
|
||||
norm_jog = SIGN(norm_jog) * sq(norm_jog);
|
||||
axis_jog = SIGN(axis_jog) * sq(axis_jog);
|
||||
}
|
||||
};
|
||||
|
||||
#if HAS_JOY_ADC_X
|
||||
static constexpr int16_t joy_x_limits[4] = JOY_X_LIMITS;
|
||||
_normalize_joy(norm_jog[X_AXIS], x.raw, joy_x_limits);
|
||||
_normalize_joy(norm_jog.x, x.raw, joy_x_limits);
|
||||
#endif
|
||||
#if HAS_JOY_ADC_Y
|
||||
static constexpr int16_t joy_y_limits[4] = JOY_Y_LIMITS;
|
||||
_normalize_joy(norm_jog[Y_AXIS], y.raw, joy_y_limits);
|
||||
_normalize_joy(norm_jog.y, y.raw, joy_y_limits);
|
||||
#endif
|
||||
#if HAS_JOY_ADC_Z
|
||||
static constexpr int16_t joy_z_limits[4] = JOY_Z_LIMITS;
|
||||
_normalize_joy(norm_jog[Z_AXIS], z.raw, joy_z_limits);
|
||||
_normalize_joy(norm_jog.z, z.raw, joy_z_limits);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -112,10 +112,10 @@ Joystick joystick;
|
||||
static bool injecting_now; // = false;
|
||||
if (injecting_now) return;
|
||||
|
||||
static constexpr int QUEUE_DEPTH = 5; // Insert up to this many movements
|
||||
static constexpr float target_lag = 0.25f, // Aim for 1/4 second lag
|
||||
seg_time = target_lag / QUEUE_DEPTH; // 0.05 seconds, short segments inserted every 1/20th of a second
|
||||
static constexpr millis_t timer_limit_ms = millis_t(seg_time * 500); // 25 ms minimum delay between insertions
|
||||
static constexpr int QUEUE_DEPTH = 5; // Insert up to this many movements
|
||||
static constexpr float target_lag = 0.25f, // Aim for 1/4 second lag
|
||||
seg_time = target_lag / QUEUE_DEPTH; // 0.05 seconds, short segments inserted every 1/20th of a second
|
||||
static constexpr millis_t timer_limit_ms = millis_t(seg_time * 500); // 25 ms minimum delay between insertions
|
||||
|
||||
// The planner can merge/collapse small moves, so the movement queue is unreliable to control the lag
|
||||
static millis_t next_run = 0;
|
||||
@@ -129,7 +129,7 @@ Joystick joystick;
|
||||
// Normalized jog values are 0 for no movement and -1 or +1 for as max feedrate (nonlinear relationship)
|
||||
// Jog are initialized to zero and handling input can update values but doesn't have to
|
||||
// You could use a two-axis joystick and a one-axis keypad and they might work together
|
||||
float norm_jog[XYZ] = { 0 };
|
||||
xyz_float_t norm_jog{0};
|
||||
|
||||
// Use ADC values and defined limits. The active zone is normalized: -1..0 (dead) 0..1
|
||||
#if HAS_JOY_ADC_X || HAS_JOY_ADC_Y || HAS_JOY_ADC_Z
|
||||
@@ -143,16 +143,13 @@ Joystick joystick;
|
||||
ExtUI::_joystick_update(norm_jog);
|
||||
#endif
|
||||
|
||||
#if EITHER(ULTIPANEL, EXTENSIBLE_UI)
|
||||
constexpr float manual_feedrate[XYZE] = MANUAL_FEEDRATE;
|
||||
#endif
|
||||
|
||||
// norm_jog values of [-1 .. 1] maps linearly to [-feedrate .. feedrate]
|
||||
float move_dist[XYZ] = { 0 }, hypot2 = 0;
|
||||
xyz_float_t move_dist{0};
|
||||
float hypot2 = 0;
|
||||
LOOP_XYZ(i) if (norm_jog[i]) {
|
||||
move_dist[i] = seg_time * norm_jog[i] *
|
||||
#if EITHER(ULTIPANEL, EXTENSIBLE_UI)
|
||||
MMM_TO_MMS(manual_feedrate[i]);
|
||||
MMM_TO_MMS(manual_feedrate_mm_m[i]);
|
||||
#else
|
||||
planner.settings.max_feedrate_mm_s[i];
|
||||
#endif
|
||||
@@ -160,7 +157,7 @@ Joystick joystick;
|
||||
}
|
||||
|
||||
if (!UNEAR_ZERO(hypot2)) {
|
||||
LOOP_XYZ(i) current_position[i] += move_dist[i];
|
||||
current_position += move_dist;
|
||||
const float length = sqrt(hypot2);
|
||||
injecting_now = true;
|
||||
planner.buffer_line(current_position, length / seg_time, active_extruder, length);
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
* joystick.h - joystick input / jogging
|
||||
*/
|
||||
|
||||
#include "../inc/MarlinConfigPre.h"
|
||||
#include "../core/types.h"
|
||||
#include "../core/macros.h"
|
||||
#include "../module/temperature.h"
|
||||
|
||||
@@ -46,7 +48,7 @@ class Joystick {
|
||||
#if ENABLED(JOYSTICK_DEBUG)
|
||||
static void report();
|
||||
#endif
|
||||
static void calculate(float (&norm_jog)[XYZ]);
|
||||
static void calculate(xyz_float_t &norm_jog);
|
||||
static void inject_jog_moves();
|
||||
};
|
||||
|
||||
|
||||
@@ -66,11 +66,9 @@ public:
|
||||
static void set_color_startup(const uint32_t c);
|
||||
|
||||
static void set_color(const uint32_t c);
|
||||
static void set_color_background();
|
||||
//bool set_led_color(const uint8_t r, const uint8_t g, const uint8_t b, const uint8_t w, const uint8_t p);
|
||||
|
||||
#ifdef NEOPIXEL_BKGD_LED_INDEX
|
||||
static void set_pixel_color(const uint16_t n, const uint32_t c);
|
||||
static void set_color_background();
|
||||
#endif
|
||||
|
||||
static inline void begin() {
|
||||
@@ -107,6 +105,10 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool set_led_color(const uint8_t r, const uint8_t g, const uint8_t b, const uint8_t w, const uint8_t p);
|
||||
#endif
|
||||
|
||||
// Accessors
|
||||
static inline uint16_t pixels() { return adaneo1.numPixels(); }
|
||||
static inline uint8_t brightness() { return adaneo1.getBrightness(); }
|
||||
|
||||
@@ -138,8 +138,7 @@ void pca9632_set_led_color(const LEDColor &color) {
|
||||
|
||||
#if ENABLED(PCA9632_BUZZER)
|
||||
|
||||
void pca9632_buzz(const long duration, const uint16_t freq) {
|
||||
UNUSED(duration); UNUSED(freq);
|
||||
void pca9632_buzz(const long, const uint16_t) {
|
||||
uint8_t data[] = PCA9632_BUZZER_DATA;
|
||||
Wire.beginTransmission(I2C_ADDRESS(PCA9632_ADDRESS));
|
||||
Wire.write(data, sizeof(data));
|
||||
|
||||
@@ -142,13 +142,19 @@ class Mixer {
|
||||
static inline void copy_mix_to_color(mixer_comp_t (&tcolor)[MIXING_STEPPERS]) {
|
||||
// Scale each component to the largest one in terms of COLOR_A_MASK
|
||||
// So the largest component will be COLOR_A_MASK and the other will be in proportion to it
|
||||
const float scale = (COLOR_A_MASK) * RECIPROCAL(float(_MAX(mix[0], mix[1])));
|
||||
const float scale = (COLOR_A_MASK) * RECIPROCAL(_MAX(
|
||||
LIST_N(MIXING_STEPPERS, mix[0], mix[1], mix[2], mix[3], mix[4], mix[5])
|
||||
));
|
||||
|
||||
// Scale all values so their maximum is COLOR_A_MASK
|
||||
MIXER_STEPPER_LOOP(i) tcolor[i] = mix[i] * scale;
|
||||
|
||||
#ifdef MIXER_NORMALIZER_DEBUG
|
||||
SERIAL_ECHOLNPAIR("Mix [", int(mix[0]), ", ", int(mix[1]), "] to Color [", int(tcolor[0]), ", ", int(tcolor[1]), "]");
|
||||
SERIAL_ECHOPGM("Mix [ ");
|
||||
SERIAL_ECHOLIST_N(MIXING_STEPPERS, int(mix[0]), int(mix[1]), int(mix[2]), int(mix[3]), int(mix[4]), int(mix[5]));
|
||||
SERIAL_ECHOPGM(" ] to Color [ ");
|
||||
SERIAL_ECHOLIST_N(MIXING_STEPPERS, int(tcolor[0]), int(tcolor[1]), int(tcolor[2]), int(tcolor[3]), int(tcolor[4]), int(tcolor[5]));
|
||||
SERIAL_ECHOLNPGM(" ]");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -156,10 +162,14 @@ class Mixer {
|
||||
float ctot = 0;
|
||||
MIXER_STEPPER_LOOP(i) ctot += color[j][i];
|
||||
//MIXER_STEPPER_LOOP(i) mix[i] = 100.0f * color[j][i] / ctot;
|
||||
mix[0] = mixer_perc_t(100.0f * color[j][0] / ctot);
|
||||
mix[1] = 100 - mix[0];
|
||||
MIXER_STEPPER_LOOP(i) mix[i] = mixer_perc_t(100.0f * color[j][i] / ctot);
|
||||
|
||||
#ifdef MIXER_NORMALIZER_DEBUG
|
||||
SERIAL_ECHOLNPAIR("V-tool ", int(j), " [", int(color[j][0]), ", ", int(color[j][1]), "] to Mix [", int(mix[0]), ", ", int(mix[1]), "]");
|
||||
SERIAL_ECHOPAIR("V-tool ", int(j), " [ ");
|
||||
SERIAL_ECHOLIST_N(MIXING_STEPPERS, int(color[j][0]), int(color[j][1]), int(color[j][2]), int(color[j][3]), int(color[j][4]), int(color[j][5]));
|
||||
SERIAL_ECHOPGM(" ] to Mix [ ");
|
||||
SERIAL_ECHOLIST_N(MIXING_STEPPERS, int(mix[0]), int(mix[1]), int(mix[2]), int(mix[3]), int(mix[4]), int(mix[5]));
|
||||
SERIAL_ECHOLNPGM(" ]");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -199,10 +209,14 @@ class Mixer {
|
||||
static inline void update_mix_from_gradient() {
|
||||
float ctot = 0;
|
||||
MIXER_STEPPER_LOOP(i) ctot += gradient.color[i];
|
||||
mix[0] = (mixer_perc_t)CEIL(100.0f * gradient.color[0] / ctot);
|
||||
mix[1] = 100 - mix[0];
|
||||
MIXER_STEPPER_LOOP(i) mix[i] = (mixer_perc_t)CEIL(100.0f * gradient.color[i] / ctot);
|
||||
|
||||
#ifdef MIXER_NORMALIZER_DEBUG
|
||||
SERIAL_ECHOLNPAIR("Gradient [", int(gradient.color[0]), ", ", int(gradient.color[1]), "] to Mix [", int(mix[0]), ", ", int(mix[1]), "]");
|
||||
SERIAL_ECHOPGM("Gradient [ ");
|
||||
SERIAL_ECHOLIST_N(MIXING_STEPPERS, int(gradient.color[0]), int(gradient.color[1]), int(gradient.color[2]), int(gradient.color[3]), int(gradient.color[4]), int(gradient.color[5]));
|
||||
SERIAL_ECHOPGM(" ] to Mix [ ");
|
||||
SERIAL_ECHOLIST_N(MIXING_STEPPERS, int(mix[0]), int(mix[1]), int(mix[2]), int(mix[3]), int(mix[4]), int(mix[5]));
|
||||
SERIAL_ECHOLNPGM(" ]");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "../lcd/extensible_ui/ui_api.h"
|
||||
#endif
|
||||
|
||||
#include "../core/language.h"
|
||||
#include "../lcd/ultralcd.h"
|
||||
|
||||
#if HAS_BUZZER
|
||||
@@ -64,7 +65,7 @@
|
||||
|
||||
// private:
|
||||
|
||||
static float resume_position[XYZE];
|
||||
static xyze_pos_t resume_position;
|
||||
|
||||
PauseMode pause_mode = PAUSE_MODE_PAUSE_PRINT;
|
||||
|
||||
@@ -76,6 +77,12 @@ fil_change_settings_t fc_settings[EXTRUDERS];
|
||||
#include "../sd/cardreader.h"
|
||||
#endif
|
||||
|
||||
#if ENABLED(EMERGENCY_PARSER)
|
||||
#define _PMSG(L) L##_M108
|
||||
#else
|
||||
#define _PMSG(L) L##_LCD
|
||||
#endif
|
||||
|
||||
#if HAS_BUZZER
|
||||
static void filament_change_beep(const int8_t max_beep_count, const bool init=false) {
|
||||
if (pause_mode == PAUSE_MODE_PAUSE_PRINT) return;
|
||||
@@ -126,8 +133,8 @@ void do_pause_e_move(const float &length, const feedRate_t &fr_mm_s) {
|
||||
#if HAS_FILAMENT_SENSOR
|
||||
runout.reset();
|
||||
#endif
|
||||
current_position[E_AXIS] += length / planner.e_factor[active_extruder];
|
||||
planner.buffer_line(current_position, fr_mm_s, active_extruder);
|
||||
current_position.e += length / planner.e_factor[active_extruder];
|
||||
line_to_current_position(fr_mm_s);
|
||||
planner.synchronize();
|
||||
}
|
||||
|
||||
@@ -163,7 +170,7 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
|
||||
#if HAS_LCD_MENU
|
||||
if (show_lcd) lcd_pause_show_message(PAUSE_MESSAGE_INSERT, mode);
|
||||
#endif
|
||||
SERIAL_ECHO_MSG(MSG_FILAMENT_CHANGE_INSERT);
|
||||
SERIAL_ECHO_MSG(_PMSG(MSG_FILAMENT_CHANGE_INSERT));
|
||||
|
||||
#if HAS_BUZZER
|
||||
filament_change_beep(max_beep_count, true);
|
||||
@@ -188,7 +195,7 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
|
||||
host_action_prompt_show();
|
||||
#endif
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::onUserConfirmRequired(PSTR("Load Filament"));
|
||||
ExtUI::onUserConfirmRequired_P(PSTR("Load Filament"));
|
||||
#endif
|
||||
while (wait_for_user) {
|
||||
#if HAS_BUZZER
|
||||
@@ -240,10 +247,10 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
|
||||
|
||||
wait_for_user = true;
|
||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Continuous Purge Running..."), PSTR("Continue"));
|
||||
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Filament Purge Running..."), PSTR("Continue"));
|
||||
#endif
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::onUserConfirmRequired(PSTR("Continuous Purge Running..."));
|
||||
ExtUI::onUserConfirmRequired_P(PSTR("Filament Purge Running..."));
|
||||
#endif
|
||||
for (float purge_count = purge_length; purge_count > 0 && wait_for_user; --purge_count)
|
||||
do_pause_e_move(1, ADVANCED_PAUSE_PURGE_FEEDRATE);
|
||||
@@ -381,11 +388,11 @@ bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/,
|
||||
* - Park the nozzle at the given position
|
||||
* - Call unload_filament (if a length was specified)
|
||||
*
|
||||
* Returns 'true' if pause was completed, 'false' for abort
|
||||
* Return 'true' if pause was completed, 'false' for abort
|
||||
*/
|
||||
uint8_t did_pause_print = 0;
|
||||
|
||||
bool pause_print(const float &retract, const point_t &park_point, const float &unload_length/*=0*/, const bool show_lcd/*=false*/ DXC_ARGS) {
|
||||
bool pause_print(const float &retract, const xyz_pos_t &park_point, const float &unload_length/*=0*/, const bool show_lcd/*=false*/ DXC_ARGS) {
|
||||
|
||||
#if !HAS_LCD_MENU
|
||||
UNUSED(show_lcd);
|
||||
@@ -432,7 +439,7 @@ bool pause_print(const float &retract, const point_t &park_point, const float &u
|
||||
print_job_timer.pause();
|
||||
|
||||
// Save current position
|
||||
COPY(resume_position, current_position);
|
||||
resume_position = current_position;
|
||||
|
||||
// Wait for buffered blocks to complete
|
||||
planner.synchronize();
|
||||
@@ -481,14 +488,6 @@ bool pause_print(const float &retract, const point_t &park_point, const float &u
|
||||
* Used by M125 and M600
|
||||
*/
|
||||
|
||||
#if (HAS_LCD_MENU || ENABLED(EXTENSIBLE_UI)) && ENABLED(EMERGENCY_PARSER)
|
||||
#define _PMSG(L) L
|
||||
#elif ENABLED(EMERGENCY_PARSER)
|
||||
#define _PMSG(L) L##_M108
|
||||
#else
|
||||
#define _PMSG(L) L##_LCD
|
||||
#endif
|
||||
|
||||
void show_continue_prompt(const bool is_reload) {
|
||||
#if HAS_LCD_MENU
|
||||
lcd_pause_show_message(is_reload ? PAUSE_MESSAGE_INSERT : PAUSE_MESSAGE_WAITING);
|
||||
@@ -527,7 +526,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
|
||||
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Nozzle Parked"), PSTR("Continue"));
|
||||
#endif
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::onUserConfirmRequired(PSTR("Nozzle Parked"));
|
||||
ExtUI::onUserConfirmRequired_P(PSTR("Nozzle Parked"));
|
||||
#endif
|
||||
while (wait_for_user) {
|
||||
#if HAS_BUZZER
|
||||
@@ -551,7 +550,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
|
||||
#endif
|
||||
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::onUserConfirmRequired(PSTR("HeaterTimeout"));
|
||||
ExtUI::onUserConfirmRequired_P(PSTR("HeaterTimeout"));
|
||||
#endif
|
||||
|
||||
// Wait for LCD click or M108
|
||||
@@ -581,7 +580,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
|
||||
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Reheat Done"), PSTR("Continue"));
|
||||
#endif
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::onUserConfirmRequired("Reheat finished.");
|
||||
ExtUI::onUserConfirmRequired_P(PSTR("Reheat finished."));
|
||||
#endif
|
||||
wait_for_user = true;
|
||||
nozzle_timed_out = false;
|
||||
@@ -603,7 +602,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
|
||||
/**
|
||||
* Resume or Start print procedure
|
||||
*
|
||||
* - Abort if not paused
|
||||
* - If not paused, do nothing and return
|
||||
* - Reset heater idle timers
|
||||
* - Load filament if specified, but only if:
|
||||
* - a nozzle timed out, or
|
||||
@@ -611,10 +610,10 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
|
||||
* - Display "wait for print to resume"
|
||||
* - Re-prime the nozzle...
|
||||
* - FWRETRACT: Recover/prime from the prior G10.
|
||||
* - !FWRETRACT: Retract by resume_position[E], if negative.
|
||||
* - !FWRETRACT: Retract by resume_position.e, if negative.
|
||||
* Not sure how this logic comes into use.
|
||||
* - Move the nozzle back to resume_position
|
||||
* - Sync the planner E to resume_position[E]
|
||||
* - Sync the planner E to resume_position.e
|
||||
* - Send host action for resume, if configured
|
||||
* - Resume the current SD print job, if any
|
||||
*/
|
||||
@@ -652,13 +651,13 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le
|
||||
#endif
|
||||
|
||||
// If resume_position is negative
|
||||
if (resume_position[E_AXIS] < 0) do_pause_e_move(resume_position[E_AXIS], feedRate_t(PAUSE_PARK_RETRACT_FEEDRATE));
|
||||
if (resume_position.e < 0) do_pause_e_move(resume_position.e, feedRate_t(PAUSE_PARK_RETRACT_FEEDRATE));
|
||||
|
||||
// Move XY to starting position, then Z
|
||||
do_blocking_move_to_xy(resume_position[X_AXIS], resume_position[Y_AXIS], feedRate_t(NOZZLE_PARK_XY_FEEDRATE));
|
||||
do_blocking_move_to_xy(resume_position, feedRate_t(NOZZLE_PARK_XY_FEEDRATE));
|
||||
|
||||
// Move Z_AXIS to saved position
|
||||
do_blocking_move_to_z(resume_position[Z_AXIS], feedRate_t(NOZZLE_PARK_Z_FEEDRATE));
|
||||
do_blocking_move_to_z(resume_position.z, feedRate_t(NOZZLE_PARK_Z_FEEDRATE));
|
||||
|
||||
#if ADVANCED_PAUSE_RESUME_PRIME != 0
|
||||
do_pause_e_move(ADVANCED_PAUSE_RESUME_PRIME, feedRate_t(ADVANCED_PAUSE_PURGE_FEEDRATE));
|
||||
@@ -666,7 +665,7 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le
|
||||
|
||||
// Now all extrusion positions are resumed and ready to be confirmed
|
||||
// Set extruder to saved position
|
||||
planner.set_e_position_mm((destination[E_AXIS] = current_position[E_AXIS] = resume_position[E_AXIS]));
|
||||
planner.set_e_position_mm((destination.e = current_position.e = resume_position.e));
|
||||
|
||||
#if HAS_LCD_MENU
|
||||
lcd_pause_show_message(PAUSE_MESSAGE_STATUS);
|
||||
|
||||
@@ -39,6 +39,7 @@ typedef struct {
|
||||
enum PauseMode : char {
|
||||
PAUSE_MODE_SAME,
|
||||
PAUSE_MODE_PAUSE_PRINT,
|
||||
PAUSE_MODE_CHANGE_FILAMENT,
|
||||
PAUSE_MODE_LOAD_FILAMENT,
|
||||
PAUSE_MODE_UNLOAD_FILAMENT
|
||||
};
|
||||
@@ -83,7 +84,7 @@ extern uint8_t did_pause_print;
|
||||
|
||||
void do_pause_e_move(const float &length, const feedRate_t &fr_mm_s);
|
||||
|
||||
bool pause_print(const float &retract, const point_t &park_point, const float &unload_length=0, const bool show_lcd=false DXC_PARAMS);
|
||||
bool pause_print(const float &retract, const xyz_pos_t &park_point, const float &unload_length=0, const bool show_lcd=false DXC_PARAMS);
|
||||
|
||||
void wait_for_confirmation(const bool is_reload=false, const int8_t max_beep_count=0 DXC_PARAMS);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user