diff --git a/.circleci/config.yml b/.circleci/config.yml
deleted file mode 100644
index 5369e2f4d5..0000000000
--- a/.circleci/config.yml
+++ /dev/null
@@ -1,274 +0,0 @@
-# Python CircleCI 2.0 configuration file
-#
-# Check https://circleci.com/docs/2.0/language-python/ for more details
-#
-version: 2
-jobs:
- build:
- docker:
- # specify the version you desire here
- # use `-browsers` prefix for selenium tests, e.g. `3.6.1-browsers`
- - image: circleci/python:2.7.13
-
- # Specify service dependencies here if necessary
- # CircleCI maintains a library of pre-built images
- # documented at https://circleci.com/docs/2.0/circleci-images/
- # - image: circleci/postgres:9.4
- environment:
- TEST_PLATFORM: "-e megaatmega2560"
-
- working_directory: ~/Marlin
-
- steps:
- - checkout
-
- - restore_cache:
- paths:
- - ~/.platformio
- - ~/Marlin/.piolibdeps
- keys:
- - v1-dependencies-{{ checksum "~/Marlin/platformio.ini" }}
- # fallback to using the latest cache if no exact match is found
- - v1-dependencies-
-
- - run:
- name: install dependencies
- command: |
- sudo pip install -U platformio
-
- # run tests!
- - run:
- name: run tests
- command: |
- #
- #
- # Fetch the tag information for the current branch
- ls -la
- git fetch origin --tags
- #
- # Publish the buildroot script folder
- chmod +x buildroot/bin/*
- export PATH=`pwd`/buildroot/bin/:${PATH}
-
- # Generate custom version include
- generate_version ./Marlin/src/inc
- cat ./Marlin/src/inc/_Version.h
- #
- # Back up pins_RAMPS.h
- #
- backup_ramps
-
- env_backup
-
- #################################
- # Build all sample configurations
- #################################
-
- echo testing megaatmega2560 targets...
- export TEST_PLATFORM="-e megaatmega2560"
- echo use_example_configs adafruit/ST7565
- use_example_configs adafruit/ST7565
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs BQ/Hephestos
- use_example_configs BQ/Hephestos
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs BQ/Hephestos_2
- use_example_configs BQ/Hephestos_2
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs BQ/WITBOX
- use_example_configs BQ/WITBOX
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs AliExpress/CL-260
- use_example_configs AliExpress/CL-260
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- #echo use_example_configs Cartesio
- #use_example_configs Cartesio
- #build_marlin_pio ./ ${TEST_PLATFORM}
- #restore_configs
- echo use_example_configs delta/FLSUN/auto_calibrate
- use_example_configs delta/FLSUN/auto_calibrate
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs delta/FLSUN/kossel_mini
- use_example_configs delta/FLSUN/kossel_mini
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs delta/generic
- use_example_configs delta/generic
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs delta/kossel_mini
- use_example_configs delta/kossel_mini
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs delta/kossel_xl
- use_example_configs delta/kossel_xl
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs Felix
- use_example_configs Felix
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs Felix/DUAL
- use_example_configs Felix/DUAL
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs FolgerTech/i3-2020
- use_example_configs FolgerTech/i3-2020
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs gCreate/gMax1.5+
- use_example_configs gCreate/gMax1.5+
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs Geeetech/GT2560
- use_example_configs Geeetech/GT2560
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- #echo use_example_configs Geeetech/I3_Pro_X-GT2560
- #use_example_configs Geeetech/I3_Pro_X-GT2560
- #build_marlin_pio ./ ${TEST_PLATFORM}
- #restore_configs
- echo use_example_configs Infitary/i3-M508
- use_example_configs Infitary/i3-M508
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- use_example_configs Malyan/M200
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs Micromake/C1/basic
- use_example_configs Micromake/C1/basic
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs Micromake/C1/enhanced
- use_example_configs Micromake/C1/enhanced
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs RepRapWorld/Megatronics
- use_example_configs RepRapWorld/Megatronics
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs RigidBot
- use_example_configs RigidBot
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs SCARA
- use_example_configs SCARA
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs Velleman/K8200
- use_example_configs Velleman/K8200
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs Velleman/K8400/Dual-head
- use_example_configs Velleman/K8400/Dual-head
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs Velleman/K8400
- use_example_configs Velleman/K8400
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs Wanhao/Duplicator6
- use_example_configs Wanhao/Duplicator6
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- # Requires manual load of https://github.com/stawel/SlowSoftI2CMaster
- #use_example_configs wt150
- #build_marlin_pio ./ ${TEST_PLATFORM}
- #restore_configs
- echo testing melzi targets...
- export TEST_PLATFORM="-e melzi"
- echo use_example_configs Anet/A6
- use_example_configs Anet/A6
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs Anet/A8
- use_example_configs Anet/A8
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs Creality/CR-10
- use_example_configs Creality/CR-10
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs Malyan/M150
- use_example_configs Malyan/M150
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs Sanguinololu
- use_example_configs Sanguinololu
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs TinyBoy2
- use_example_configs TinyBoy2
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
-
- echo testing rambo targets...
- export TEST_PLATFORM="-e rambo"
- echo use_example_configs AlephObjects/TAZ4
- use_example_configs AlephObjects/TAZ4
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
-
- echo testing at90usb1286_* targets...
- export TEST_PLATFORM="-e at90usb1286_dfu"
- #echo se_example_configs delta/kossel_pro
- #use_example_configs delta/kossel_pro
- #build_marlin_pio ./ ${TEST_PLATFORM}
- #restore_configs
- echo use_example_configs makibox
- use_example_configs makibox
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
-
- echo testing sanguino_atmega644p targets...
- export TEST_PLATFORM="-e sanguino_atmega644p"
- echo use_example_configs tvrrug/Round2
- use_example_configs tvrrug/Round2
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
-
- echo testing LPC1768 targets...
- export TEST_PLATFORM="-e LPC1768"
- echo use_example_configs Mks/Sbase
- use_example_configs Mks/Sbase
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo testing STM32F1 targets...
- export TEST_PLATFORM="-e STM32F103RE"
- restore_configs
- echo use_example_configs STM32/STM32F103RE
- use_example_configs STM32/STM32F103RE
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
- echo use_example_configs STM32/stm32f103ret6
- use_example_configs STM32/stm32f103ret6
- build_marlin_pio ./ ${TEST_PLATFORM}
- restore_configs
-
- echo testing DUE targets...
- export TEST_PLATFORM="-e DUE"
- #echo use_example_configs UltiMachine/Archim2
- #use_example_configs UltiMachine/Archim2
- #build_marlin_pio ./ ${TEST_PLATFORM}
- #restore_configs
-
- #
- # Remove temp files from dependencies tree prior to caching
- rm -rf ~/Marlin/.piolibdeps/_tmp_*
-
- #
- # Restore the environment
- #
- env_restore
-
- - save_cache:
- paths:
- - ~/.platformio
- - ~/Marlin/.piolibdeps
- key: v1-dependencies-{{ checksum "~/Marlin/platformio.ini" }}
diff --git a/.github/workflows/bump-date.yml b/.github/workflows/bump-date.yml
new file mode 100644
index 0000000000..df2ac5fbdd
--- /dev/null
+++ b/.github/workflows/bump-date.yml
@@ -0,0 +1,25 @@
+#
+# bump-date.yml
+# Bump the distribution date once per day
+#
+
+name: Bump Distribution Date
+
+on:
+ schedule:
+ - cron: '0 0 * * *'
+
+jobs:
+ bump_date:
+
+ runs-on: ubuntu-latest
+
+ steps:
+
+ - name: Check out bugfix-2.0.x
+ uses: actions/checkout@v2
+ with:
+ ref: bugfix-2.0.x
+
+ - name: Bump Distribution Date
+ run: source ./buildroot/bin/bump_date
diff --git a/.github/workflows/test-builds.yml b/.github/workflows/test-builds.yml
new file mode 100644
index 0000000000..f7412b3945
--- /dev/null
+++ b/.github/workflows/test-builds.yml
@@ -0,0 +1,100 @@
+#
+# test-builds.yml
+# Do test builds to catch compile errors
+#
+
+name: CI
+
+on:
+ pull_request:
+ branches:
+ - bugfix-2.0.x
+ - dev-2.1.x
+ paths-ignore:
+ - config/**
+ - data/**
+ - docs/**
+ - '**/*.md'
+
+jobs:
+ test_builds:
+
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ test-platform:
+ # Base Environments
+
+ - DUE
+ - esp32
+ - linux_native
+ - megaatmega2560
+ - teensy31
+ - teensy35
+
+ # Extended AVR Environments
+
+ - FYSETC_F6_13
+ - megaatmega1280
+ - rambo
+ - sanguino_atmega1284p
+ - sanguino_atmega644p
+
+ # Extended STM32 Environments
+
+ - STM32F103RC_bigtree
+ - STM32F103RC_bigtree_USB
+ - STM32F103RE_bigtree
+ - STM32F103RE_bigtree_USB
+ - STM32F103RC_fysetc
+ - jgaurora_a5s_a1
+ - STM32F103VE_longer
+ - STM32F407VE_black
+ - BIGTREE_SKR_PRO
+ - mks_robin
+ - ARMED
+
+ # Put lengthy tests last
+
+ - LPC1768
+ - LPC1769
+
+ # STM32 with non-STM framework. both broken for now. they should use HAL_STM32 which is working.
+
+ #- STM32F4
+ #- STM32F7
+
+ # Non-working environment tests
+
+ #- BIGTREE_BTT002
+ #- at90usb1286_cdc
+ #- at90usb1286_dfu
+ #- STM32F103CB_malyan
+ #- mks_robin_lite
+ #- mks_robin_mini
+ #- mks_robin_nano
+ #- SAMD51_grandcentral_m4
+
+ steps:
+
+ - name: Select Python 3.7
+ uses: actions/setup-python@v1
+ with:
+ python-version: '3.7' # Version range or exact version of a Python version to use, using semvers version range syntax.
+ architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
+
+ - name: Install PlatformIO
+ run: |
+ pip install -U https://github.com/platformio/platformio-core/archive/master.zip
+ platformio update
+
+ - name: Check out the PR
+ uses: actions/checkout@v2
+
+ - name: Run ${{ matrix.test-platform }} Tests
+ run: |
+ chmod +x buildroot/bin/*
+ chmod +x buildroot/share/tests/*
+ export PATH=./buildroot/bin/:./buildroot/share/tests/:${PATH}
+ run_tests . ${{ matrix.test-platform }}
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 4bfadbcc6b..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,80 +0,0 @@
-dist: bionic
-sudo: false
-
-language: python
-python:
- - "3.7"
-
-notifications:
- email: false
-
-env:
- # Base Environments
- - TEST_PLATFORM="DUE"
- - TEST_PLATFORM="esp32"
- - TEST_PLATFORM="linux_native"
- - TEST_PLATFORM="LPC1768"
- - TEST_PLATFORM="LPC1769"
- - TEST_PLATFORM="megaatmega2560"
- - TEST_PLATFORM="STM32F103RE"
- - TEST_PLATFORM="teensy31"
- - TEST_PLATFORM="teensy35"
-
- # Extended AVR Environments
- - TEST_PLATFORM="fysetc_f6_13"
- - TEST_PLATFORM="megaatmega1280"
- - TEST_PLATFORM="rambo"
- - TEST_PLATFORM="sanguino_atmega1284p"
- - TEST_PLATFORM="sanguino_atmega644p"
-
- # Extended STM32 Environments
- - TEST_PLATFORM="ARMED"
- - TEST_PLATFORM="BIGTREE_BTT002"
- - TEST_PLATFORM="BIGTREE_SKR_PRO"
- - TEST_PLATFORM="STM32F103RC_bigtree"
- - TEST_PLATFORM="jgaurora_a5s_a1"
- - TEST_PLATFORM="STM32F103VE_longer"
- - TEST_PLATFORM="STM32F407VE_black"
-
- # Non-working environment tests
- #- TEST_PLATFORM="at90usb1286_cdc"
- #- TEST_PLATFORM="at90usb1286_dfu"
- #- TEST_PLATFORM="STM32F103CB_malyan"
- #- TEST_PLATFORM="mks_robin"
- #- TEST_PLATFORM="mks_robin_lite"
- #- TEST_PLATFORM="mks_robin_mini"
- #- TEST_PLATFORM="mks_robin_nano"
- #- TEST_PLATFORM="SAMD51_grandcentral_m4"
- #- TEST_PLATFORM="STM32F103RC_bigtree"
- #- TEST_PLATFORM="STM32F103RC_bigtree_USB"
- #- TEST_PLATFORM="STM32F103RC_fysetc"
- #- TEST_PLATFORM="STM32F4"
- #- TEST_PLATFORM="STM32F7"
-
-before_install:
- #
- # Fetch the tag information for the current branch
- - git fetch origin --tags
- #
- # Publish the buildroot script folder
- - chmod +x ${TRAVIS_BUILD_DIR}/buildroot/bin/*
- - chmod +x ${TRAVIS_BUILD_DIR}/buildroot/share/tests/*
- - export PATH=${TRAVIS_BUILD_DIR}/buildroot/bin/:${TRAVIS_BUILD_DIR}/buildroot/share/tests/:${PATH}
-
-install:
- #- pip install -U platformio
- - pip install -U https://github.com/platformio/platformio-core/archive/master.zip
-
-before_script:
- # Update PlatformIO packages
- - platformio update
- #
- # Change current working directory to the build dir
- - 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
- #
-script:
- - run_tests ${TRAVIS_BUILD_DIR} ${TEST_PLATFORM}
diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 812df3c208..9e0970a56e 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -72,6 +72,7 @@
// Author info of this build printed to the host during boot and M115
#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes.
+//#define CUSTOM_VERSION_FILE Version.h // Path from the root directory (no quotes)
/**
* *** VENDORS PLEASE READ ***
@@ -324,13 +325,14 @@
//#define PSU_NAME "Power Supply"
#if ENABLED(PSU_CONTROL)
- #define PSU_ACTIVE_HIGH false // Set 'false' for ATX (1), 'true' for X-Box (2)
+ #define PSU_ACTIVE_HIGH false // Set 'false' for ATX, 'true' for X-Box
- //#define PS_DEFAULT_OFF // Keep power off until enabled directly with M80
+ //#define PSU_DEFAULT_OFF // Keep power off until enabled directly with M80
+ //#define PSU_POWERUP_DELAY 100 // (ms) Delay for the PSU to warm up to full power
- //#define AUTO_POWER_CONTROL // Enable automatic control of the PS_ON pin
+ //#define AUTO_POWER_CONTROL // Enable automatic control of the PS_ON pin
#if ENABLED(AUTO_POWER_CONTROL)
- #define AUTO_POWER_FANS // Turn on PSU if fans need power
+ #define AUTO_POWER_FANS // Turn on PSU if fans need power
#define AUTO_POWER_E_FANS
#define AUTO_POWER_CONTROLLERFAN
#define AUTO_POWER_CHAMBER_FAN
@@ -351,9 +353,10 @@
*
* Temperature sensors available:
*
+ * -5 : PT100 / PT1000 with MAX31865 (only for sensors 0-1)
+ * -3 : thermocouple with MAX31855 (only for sensors 0-1)
+ * -2 : thermocouple with MAX6675 (only for sensors 0-1)
* -4 : thermocouple with AD8495
- * -3 : thermocouple with MAX31855 (only for sensor 0)
- * -2 : thermocouple with MAX6675 (only for sensor 0)
* -1 : thermocouple with AD595
* 0 : not used
* 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup)
@@ -383,6 +386,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)
@@ -400,8 +404,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" }
*/
#define TEMP_SENSOR_0 1
#define TEMP_SENSOR_1 0
@@ -714,14 +716,14 @@
/**
* Default Axis Steps Per Unit (steps/mm)
* Override with M92
- * X, Y, Z, E0 [, E1[, E2[, E3[, E4[, E5]]]]]
+ * X, Y, Z, E0 [, E1[, E2...]]
*/
#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 4000, 500 }
/**
* Default Max Feed Rate (mm/s)
* Override with M203
- * X, Y, Z, E0 [, E1[, E2[, E3[, E4[, E5]]]]]
+ * X, Y, Z, E0 [, E1[, E2...]]
*/
#define DEFAULT_MAX_FEEDRATE { 300, 300, 5, 25 }
@@ -734,7 +736,7 @@
* Default Max Acceleration (change/s) change = mm/s
* (Maximum start speed for accelerated moves)
* Override with M201
- * X, Y, Z, E0 [, E1[, E2[, E3[, E4[, E5]]]]]
+ * X, Y, Z, E0 [, E1[, E2...]]
*/
#define DEFAULT_MAX_ACCELERATION { 3000, 3000, 100, 10000 }
@@ -756,28 +758,15 @@
#define DEFAULT_TRAVEL_ACCELERATION 3000 // 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.02 // (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
@@ -790,6 +779,17 @@
#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.013 // (mm) Distance from real junction edge
+#endif
+
/**
* S-Curve Acceleration
*
@@ -855,6 +855,12 @@
*/
//#define FIX_MOUNTED_PROBE
+/**
+ * Use the nozzle as the probe, as with a conductive
+ * nozzle system or a piezo-electric smart effector.
+ */
+//#define NOZZLE_AS_PROBE
+
/**
* Z Servo Probe, such as an endstop switch on a rotating arm.
*/
@@ -923,7 +929,8 @@
*/
#define NOZZLE_TO_PROBE_OFFSET { 10, 10, 0 }
-// Certain types of probes need to stay away from edges
+// Most probes should stay away from the edges of the bed, but
+// with NOZZLE_AS_PROBE this can be negative for a wider probing area.
#define MIN_PROBE_EDGE 10
// X and Y axis travel speed (mm/m) between probes
@@ -1573,10 +1580,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
@@ -1769,7 +1776,7 @@
//
// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller
-// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html
+// https://www.aliexpress.com/item/32765887917.html
//
//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602
@@ -1943,7 +1950,7 @@
//
// Factory display for Creality CR-10
-// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html
+// https://www.aliexpress.com/item/32833148327.html
//
// This is RAMPS-compatible using a single 10-pin connector.
// (For CR-10 owners who want to replace the Melzi Creality board but retain the display)
@@ -1961,7 +1968,7 @@
//
// AZSMZ 12864 LCD with SD
-// https://www.aliexpress.com/store/product/3D-printer-smart-controller-SMART-RAMPS-OR-RAMPS-1-4-LCD-12864-LCD-control-panel-green/2179173_32213636460.html
+// https://www.aliexpress.com/item/32837222770.html
//
//#define AZSMZ_12864
@@ -2028,10 +2035,10 @@
//#define MALYAN_LCD
//
-// LulzBot Color Touch UI for FTDI EVE (FT800/FT810) displays
+// Touch UI for FTDI EVE (FT800/FT810) displays
// See Configuration_adv.h for all configuration options.
//
-//#define LULZBOT_TOUCH_UI
+//#define TOUCH_UI_FTDI_EVE
//
// Third-party or vendor-customized controller interfaces.
diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index 9120ffa0aa..fc08d6ec12 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -197,6 +197,56 @@
#define DEFAULT_Kc (100) //heating power=Kc*(e_speed)
#define LPQ_MAX_LEN 50
#endif
+
+ /**
+ * Add an experimental additional term to the heater power, proportional to the fan speed.
+ * A well-chosen Kf value should add just enough power to compensate for power-loss from the cooling fan.
+ * You can either just add a constant compensation with the DEFAULT_Kf value
+ * or follow the instruction below to get speed-dependent compensation.
+ *
+ * Constant compensation (use only with fanspeeds of 0% and 100%)
+ * ---------------------------------------------------------------------
+ * A good starting point for the Kf-value comes from the calculation:
+ * kf = (power_fan * eff_fan) / power_heater * 255
+ * where eff_fan is between 0.0 and 1.0, based on fan-efficiency and airflow to the nozzle / heater.
+ *
+ * Example:
+ * Heater: 40W, Fan: 0.1A * 24V = 2.4W, eff_fan = 0.8
+ * Kf = (2.4W * 0.8) / 40W * 255 = 12.24
+ *
+ * Fan-speed dependent compensation
+ * --------------------------------
+ * 1. To find a good Kf value, set the hotend temperature, wait for it to settle, and enable the fan (100%).
+ * Make sure PID_FAN_SCALING_LIN_FACTOR is 0 and PID_FAN_SCALING_ALTERNATIVE_DEFINITION is not enabled.
+ * If you see the temperature drop repeat the test, increasing the Kf value slowly, until the temperature
+ * drop goes away. If the temperature overshoots after enabling the fan, the Kf value is too big.
+ * 2. Note the Kf-value for fan-speed at 100%
+ * 3. Determine a good value for PID_FAN_SCALING_MIN_SPEED, which is around the speed, where the fan starts moving.
+ * 4. Repeat step 1. and 2. for this fan speed.
+ * 5. Enable PID_FAN_SCALING_ALTERNATIVE_DEFINITION and enter the two identified Kf-values in
+ * PID_FAN_SCALING_AT_FULL_SPEED and PID_FAN_SCALING_AT_MIN_SPEED. Enter the minimum speed in PID_FAN_SCALING_MIN_SPEED
+ */
+ //#define PID_FAN_SCALING
+ #if ENABLED(PID_FAN_SCALING)
+ //#define PID_FAN_SCALING_ALTERNATIVE_DEFINITION
+ #if ENABLED(PID_FAN_SCALING_ALTERNATIVE_DEFINITION)
+ // The alternative definition is used for an easier configuration.
+ // Just figure out Kf at fullspeed (255) and PID_FAN_SCALING_MIN_SPEED.
+ // DEFAULT_Kf and PID_FAN_SCALING_LIN_FACTOR are calculated accordingly.
+
+ #define PID_FAN_SCALING_AT_FULL_SPEED 13.0 //=PID_FAN_SCALING_LIN_FACTOR*255+DEFAULT_Kf
+ #define PID_FAN_SCALING_AT_MIN_SPEED 6.0 //=PID_FAN_SCALING_LIN_FACTOR*PID_FAN_SCALING_MIN_SPEED+DEFAULT_Kf
+ #define PID_FAN_SCALING_MIN_SPEED 10.0 // Minimum fan speed at which to enable PID_FAN_SCALING
+
+ #define DEFAULT_Kf (255.0*PID_FAN_SCALING_AT_MIN_SPEED-PID_FAN_SCALING_AT_FULL_SPEED*PID_FAN_SCALING_MIN_SPEED)/(255.0-PID_FAN_SCALING_MIN_SPEED)
+ #define PID_FAN_SCALING_LIN_FACTOR (PID_FAN_SCALING_AT_FULL_SPEED-DEFAULT_Kf)/255.0
+
+ #else
+ #define PID_FAN_SCALING_LIN_FACTOR (0) // Power loss due to cooling = Kf * (fan_speed)
+ #define DEFAULT_Kf 10 // A constant value added to the PID-tuner
+ #define PID_FAN_SCALING_MIN_SPEED 10 // Minimum fan speed at which to enable PID_FAN_SCALING
+ #endif
+ #endif
#endif
/**
@@ -290,6 +340,9 @@
// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu)
//#define FAN_KICKSTART_TIME 100
+// Some coolers may require a non-zero "off" state.
+//#define FAN_OFF_PWM 1
+
/**
* PWM Fan Scaling
*
@@ -603,18 +656,32 @@
//#define Z_STEPPER_AUTO_ALIGN
#if ENABLED(Z_STEPPER_AUTO_ALIGN)
// Define probe X and Y positions for Z1, Z2 [, Z3]
- #define Z_STEPPER_ALIGN_XY { { 10, 290 }, { 150, 10 }, { 290, 290 } } // Set number of iterations to align
+ #define Z_STEPPER_ALIGN_XY { { 10, 190 }, { 100, 10 }, { 190, 190 } }
+
+ // 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 3
+
// Enable to restore leveling setup after operation
#define RESTORE_LEVELING_AFTER_G34
// On a 300mm bed a 5% grade would give a misalignment of ~1.5cm
#define G34_MAX_GRADE 5 // (%) 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
@@ -888,6 +955,18 @@
// Add an 'M73' G-code to set the current percentage
//#define LCD_SET_PROGRESS_MANUALLY
+// Show the E position (filament used) during printing
+//#define LCD_SHOW_E_TOTAL
+
+#if HAS_GRAPHICAL_LCD && HAS_PRINT_PROGRESS
+ //#define PRINT_PROGRESS_SHOW_DECIMALS // Show progress with decimal digits
+ //#define SHOW_REMAINING_TIME // Display estimated time to completion
+ #if ENABLED(SHOW_REMAINING_TIME)
+ //#define USE_M73_REMAINING_TIME // Use remaining time from M73 command instead of estimation
+ //#define ROTATE_PROGRESS_DISPLAY // Display (P)rogress, (E)lapsed, and (R)emaining time
+ #endif
+#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)
@@ -931,6 +1010,8 @@
*/
//#define POWER_LOSS_RECOVERY
#if ENABLED(POWER_LOSS_RECOVERY)
+ //#define BACKUP_POWER_SUPPLY // Backup power / UPS to move the steppers on power loss
+ //#define POWER_LOSS_ZRAISE 2 // (mm) Z axis raise on resume (on power loss with UPS)
//#define POWER_LOSS_PIN 44 // Pin to detect power loss
//#define POWER_LOSS_STATE HIGH // State of pin indicating power loss
//#define POWER_LOSS_PULL // Set pullup / pulldown as appropriate
@@ -1163,9 +1244,9 @@
#endif // HAS_GRAPHICAL_LCD
//
-// Lulzbot Touch UI
+// Touch UI for the FTDI Embedded Video Engine (EVE)
//
-#if ENABLED(LULZBOT_TOUCH_UI)
+#if ENABLED(TOUCH_UI_FTDI_EVE)
// Display board used
//#define LCD_FTDI_VM800B35A // FTDI 3.5" with FT800 (320x240)
//#define LCD_4DSYSTEMS_4DLCD_FT843 // 4D Systems 4.3" (480x272)
@@ -1243,6 +1324,9 @@
// Output extra debug info for Touch UI events
//#define TOUCH_UI_DEBUG
+
+ // Developer menu (accessed by touching "About Printer" copyright text)
+ //#define TOUCH_UI_DEVELOPER_MENU
#endif
//
@@ -1287,7 +1371,8 @@
//#define BABYSTEP_WITHOUT_HOMING
//#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA!
#define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way
- #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion.
+ #define BABYSTEP_MULTIPLICATOR_Z 1 // Babysteps are very small. Increase for faster motion.
+ #define BABYSTEP_MULTIPLICATOR_XY 1
//#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping.
#if ENABLED(DOUBLECLICK_FOR_Z_BABYSTEPPING)
@@ -1353,7 +1438,8 @@
* Override MIN_PROBE_EDGE for each side of the build plate
* Useful to get probe points to exact positions on targets or
* to allow leveling to avoid plate clamps on only specific
- * sides of the bed.
+ * sides of the bed. With NOZZLE_AS_PROBE negative values are
+ * allowed, to permit probing outside the bed.
*
* If you are replacing the prior *_PROBE_BED_POSITION options,
* LEFT and FRONT values in most cases will map directly over
@@ -1365,7 +1451,7 @@
* probe points will follow. This prevents any change from causing
* the probe to be unable to reach any points.
*/
-#if PROBE_SELECTED && !IS_KINEMATIC && !IS_KINEMATIC
+#if PROBE_SELECTED && !IS_KINEMATIC
//#define MIN_PROBE_EDGE_LEFT MIN_PROBE_EDGE
//#define MIN_PROBE_EDGE_RIGHT MIN_PROBE_EDGE
//#define MIN_PROBE_EDGE_FRONT MIN_PROBE_EDGE
@@ -1463,12 +1549,12 @@
/**
* Maximum stepping rate (in Hz) the stepper driver allows
* If undefined, defaults to 1MHz / (2 * MINIMUM_STEPPER_PULSE)
- * 500000 : Maximum for A4988 stepper driver
- * 400000 : Maximum for TMC2xxx stepper drivers
- * 250000 : Maximum for DRV8825 stepper driver
- * 200000 : Maximum for LV8729 stepper driver
- * 150000 : Maximum for TB6600 stepper driver
- * 15000 : Maximum for TB6560 stepper driver
+ * 5000000 : Maximum for TMC2xxx stepper drivers
+ * 1000000 : Maximum for LV8729 stepper driver
+ * 500000 : Maximum for A4988 stepper driver
+ * 250000 : Maximum for DRV8825 stepper driver
+ * 150000 : Maximum for TB6600 stepper driver
+ * 15000 : Maximum for TB6560 stepper driver
*
* Override the default value based on the driver type set in Configuration.h.
*/
@@ -1666,9 +1752,10 @@
//#define ADVANCED_PAUSE_FANS_PAUSE // Turn off print-cooling fans while the machine is paused.
// Filament Unload does a Retract, Delay, and Purge first:
- #define FILAMENT_UNLOAD_RETRACT_LENGTH 13 // (mm) Unload initial retract length.
- #define FILAMENT_UNLOAD_DELAY 5000 // (ms) Delay for the filament to cool after retract.
+ #define FILAMENT_UNLOAD_PURGE_RETRACT 13 // (mm) Unload initial retract length.
+ #define FILAMENT_UNLOAD_PURGE_DELAY 5000 // (ms) Delay for the filament to cool after retract.
#define FILAMENT_UNLOAD_PURGE_LENGTH 8 // (mm) An unretract is done, then this length is purged.
+ #define FILAMENT_UNLOAD_PURGE_FEEDRATE 25 // (mm/s) feedrate to purge before unload
#define PAUSE_PARK_NOZZLE_TIMEOUT 45 // (seconds) Time limit before the nozzle is turned off for safety.
#define FILAMENT_CHANGE_ALERT_BEEPS 10 // Number of alert beeps to play when a response is needed.
@@ -1795,94 +1882,101 @@
#define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256
#if AXIS_IS_TMC(X)
- #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 -1 // <=0 : Not chained. 1 : MCU MOSI connected. 2 : Next in chain, ...
+ #define X_CURRENT 800 // (mA) RMS current. Multiply by 1.414 for peak current.
+ #define X_CURRENT_HOME X_CURRENT // (mA) RMS current for sensorless homing
+ #define X_MICROSTEPS 16 // 0..256
+ #define X_RSENSE 0.11
+ #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 -1
+ #define X2_CURRENT 800
+ #define X2_CURRENT_HOME X2_CURRENT
+ #define X2_MICROSTEPS 16
+ #define X2_RSENSE 0.11
+ #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 -1
+ #define Y_CURRENT 800
+ #define Y_CURRENT_HOME Y_CURRENT
+ #define Y_MICROSTEPS 16
+ #define Y_RSENSE 0.11
+ #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 -1
+ #define Y2_CURRENT 800
+ #define Y2_CURRENT_HOME Y2_CURRENT
+ #define Y2_MICROSTEPS 16
+ #define Y2_RSENSE 0.11
+ #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 -1
+ #define Z_CURRENT 800
+ #define Z_CURRENT_HOME Z_CURRENT
+ #define Z_MICROSTEPS 16
+ #define Z_RSENSE 0.11
+ #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 -1
+ #define Z2_CURRENT 800
+ #define Z2_CURRENT_HOME Z2_CURRENT
+ #define Z2_MICROSTEPS 16
+ #define Z2_RSENSE 0.11
+ #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 -1
+ #define Z3_CURRENT 800
+ #define Z3_CURRENT_HOME Z3_CURRENT
+ #define Z3_MICROSTEPS 16
+ #define Z3_RSENSE 0.11
+ #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 -1
+ #define E0_CURRENT 800
+ #define E0_MICROSTEPS 16
+ #define E0_RSENSE 0.11
+ #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 -1
+ #define E1_CURRENT 800
+ #define E1_MICROSTEPS 16
+ #define E1_RSENSE 0.11
+ #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 -1
+ #define E2_CURRENT 800
+ #define E2_MICROSTEPS 16
+ #define E2_RSENSE 0.11
+ #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 -1
+ #define E3_CURRENT 800
+ #define E3_MICROSTEPS 16
+ #define E3_RSENSE 0.11
+ #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 -1
+ #define E4_CURRENT 800
+ #define E4_MICROSTEPS 16
+ #define E4_RSENSE 0.11
+ #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 -1
+ #define E5_CURRENT 800
+ #define E5_MICROSTEPS 16
+ #define E5_RSENSE 0.11
+ #define E5_CHAIN_POS -1
#endif
/**
@@ -2076,8 +2170,8 @@
*
* Example:
* #define TMC_ADV() { \
- * stepperX.diag0_temp_prewarn(1); \
- * stepperY.interpolate(0); \
+ * stepperX.diag0_otpw(1); \
+ * stepperY.intpol(0); \
* }
*/
#define TMC_ADV() { }
@@ -2534,6 +2628,13 @@
//#define HOST_PROMPT_SUPPORT
#endif
+/**
+ * Cancel Objects
+ *
+ * Implement M486 to allow Marlin to skip objects
+ */
+//#define CANCEL_OBJECTS
+
/**
* I2C position encoders for closed loop control.
* Developed by Chris Barr at Aus3D.
diff --git a/Marlin/Makefile b/Marlin/Makefile
index d765fc19da..1a9bb22087 100644
--- a/Marlin/Makefile
+++ b/Marlin/Makefile
@@ -92,6 +92,9 @@ U8GLIB ?= 1
# this defines whether to include the Trinamic TMCStepper library
TMC ?= 1
+# this defines whether to include the AdaFruit NeoPixel library
+NEOPIXEL ?= 0
+
############
# Try to automatically determine whether RELOC_WORKAROUND is needed based
# on GCC versions:
@@ -185,7 +188,7 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1109)
else ifeq ($(HARDWARE_MOTHERBOARD),1110)
# zrib V2.0 control board (Chinese knock off RAMPS replica)
else ifeq ($(HARDWARE_MOTHERBOARD),1111)
-# Bigtreetech or BIQU KFB2.0
+# BigTreeTech or BIQU KFB2.0
else ifeq ($(HARDWARE_MOTHERBOARD),1112)
# Felix 2.0+ Electronics Board (RAMPS like)
else ifeq ($(HARDWARE_MOTHERBOARD),1113)
@@ -255,6 +258,10 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1143)
else ifeq ($(HARDWARE_MOTHERBOARD),1144)
# ADIMLab Gantry v2
else ifeq ($(HARDWARE_MOTHERBOARD),1145)
+# BIQU Tango V1
+else ifeq ($(HARDWARE_MOTHERBOARD),1146)
+# MKS GEN L V2
+else ifeq ($(HARDWARE_MOTHERBOARD),1147)
#
# RAMBo and derivatives
diff --git a/Marlin/Version.h b/Marlin/Version.h
new file mode 100644
index 0000000000..d18176f27f
--- /dev/null
+++ b/Marlin/Version.h
@@ -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 .
+ *
+ */
+#pragma once
+
+////////////////////////////
+// VENDOR VERSION EXAMPLE //
+////////////////////////////
+
+/**
+ * Marlin release version identifier
+ */
+//#define SHORT_BUILD_VERSION "bugfix-2.0.x"
+
+/**
+ * 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 " (Github)"
+
+/**
+ * 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-07-10"
+
+/**
+ * Defines a generic printer name to be output to the LCD after booting Marlin.
+ */
+//#define MACHINE_NAME "3D Printer"
+
+/**
+ * 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/MarlinFirmware/Marlin"
+
+/**
+ * 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 "http://marlinfw.org"
+
+/**
+ * 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
diff --git a/Marlin/src/HAL/HAL.h b/Marlin/src/HAL/HAL.h
index cecdd8b67b..5ad1393110 100644
--- a/Marlin/src/HAL/HAL.h
+++ b/Marlin/src/HAL/HAL.h
@@ -25,6 +25,8 @@
#include HAL_PATH(.,HAL.h)
+#define HAL_ADC_RANGE _BV(HAL_ADC_RESOLUTION)
+
inline void watchdog_refresh() {
#if ENABLED(USE_WATCHDOG)
HAL_watchdog_refresh();
diff --git a/Marlin/src/HAL/HAL_AVR/HAL.h b/Marlin/src/HAL/HAL_AVR/HAL.h
index 246353677f..d739a379e8 100644
--- a/Marlin/src/HAL/HAL_AVR/HAL.h
+++ b/Marlin/src/HAL/HAL_AVR/HAL.h
@@ -25,7 +25,7 @@
#include "math.h"
#ifdef USBCON
- #include "HardwareSerial.h"
+ #include
#else
#define HardwareSerial_h // Hack to prevent HardwareSerial.h header inclusion
#include "MarlinSerial.h"
@@ -38,6 +38,14 @@
#include
#include
+#ifndef pgm_read_ptr
+ // Compatibility for avr-libc 1.8.0-4.1 included with Ubuntu for
+ // Windows Subsystem for Linux on Windows 10 as of 10/18/2019
+ #define pgm_read_ptr_far(address_long) (void*)__ELPM_word((uint32_t)(address_long))
+ #define pgm_read_ptr_near(address_short) (void*)__LPM_word((uint16_t)(address_short))
+ #define pgm_read_ptr(address_short) pgm_read_ptr_near(address_short)
+#endif
+
// ------------------------
// Defines
// ------------------------
@@ -83,19 +91,19 @@ typedef int8_t pin_t;
#define NUM_SERIAL 1
#else
#if !WITHIN(SERIAL_PORT, -1, 3)
- #error "SERIAL_PORT must be from -1 to 3"
+ #error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#define MYSERIAL0 customizedSerial1
#ifdef SERIAL_PORT_2
#if !WITHIN(SERIAL_PORT_2, -1, 3)
- #error "SERIAL_PORT_2 must be from -1 to 3"
+ #error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#elif SERIAL_PORT_2 == SERIAL_PORT
- #error "SERIAL_PORT_2 must be different than SERIAL_PORT"
+ #error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration."
#endif
- #define NUM_SERIAL 2
#define MYSERIAL1 customizedSerial2
+ #define NUM_SERIAL 2
#else
#define NUM_SERIAL 1
#endif
@@ -357,6 +365,7 @@ inline void HAL_adc_init() {
#define HAL_START_ADC(pin) ADCSRB = 0; SET_ADMUX_ADCSRA(pin)
#endif
+#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() ADC
#define HAL_ADC_READY() !TEST(ADCSRA, ADSC)
diff --git a/Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp b/Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp
index 3502aa6b0c..dbf85bce10 100644
--- a/Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp
+++ b/Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp
@@ -41,7 +41,7 @@
#if !defined(USBCON) && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H))
#include "MarlinSerial.h"
- #include "../../Marlin.h"
+ #include "../../MarlinCore.h"
template typename MarlinSerial::ring_buffer_r MarlinSerial::rx_buffer = { 0, 0, { 0 } };
template typename MarlinSerial::ring_buffer_t MarlinSerial::tx_buffer = { 0 };
diff --git a/Marlin/src/HAL/HAL_AVR/endstop_interrupts.h b/Marlin/src/HAL/HAL_AVR/endstop_interrupts.h
index b80fee610d..77fa581632 100644
--- a/Marlin/src/HAL/HAL_AVR/endstop_interrupts.h
+++ b/Marlin/src/HAL/HAL_AVR/endstop_interrupts.h
@@ -46,39 +46,55 @@ void endstop_ISR() { endstops.update(); }
/**
* Patch for pins_arduino.h (...\Arduino\hardware\arduino\avr\variants\mega\pins_arduino.h)
*
- * These macros for the Arduino MEGA do not include the two connected pins on Port J (D13, D14).
+ * These macros for the Arduino MEGA do not include the two connected pins on Port J (D14, D15).
* So we extend them here because these are the normal pins for Y_MIN and Y_MAX on RAMPS.
* There are more PCI-enabled processor pins on Port J, but they are not connected to Arduino MEGA.
*/
#if defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_AVR_MEGA)
+
+ #define digitalPinHasPCICR(p) (WITHIN(p, 10, 15) || WITHIN(p, 50, 53) || WITHIN(p, 62, 69))
+
#undef digitalPinToPCICR
- #define digitalPinToPCICR(p) ( WITHIN(p, 10, 15) || \
- WITHIN(p, 50, 53) || \
- WITHIN(p, 62, 69) ? &PCICR : nullptr )
+ #define digitalPinToPCICR(p) (digitalPinHasPCICR(p) ? (&PCICR) : nullptr)
+
#undef digitalPinToPCICRbit
- #define digitalPinToPCICRbit(p) ( WITHIN(p, 10, 13) || WITHIN(p, 50, 53) ? 0 : \
- WITHIN(p, 14, 15) ? 1 : \
- WITHIN(p, 62, 69) ? 2 : \
- 0 )
+ #define digitalPinToPCICRbit(p) (WITHIN(p, 10, 13) || WITHIN(p, 50, 53) ? 0 : \
+ WITHIN(p, 14, 15) ? 1 : \
+ WITHIN(p, 62, 69) ? 2 : \
+ 0)
+
#undef digitalPinToPCMSK
- #define digitalPinToPCMSK(p) ( WITHIN(p, 10, 13) || WITHIN(p, 50, 53) ? &PCMSK0 : \
- WITHIN(p, 14, 15) ? &PCMSK1 : \
- WITHIN(p, 62, 69) ? &PCMSK2 : \
- nullptr )
+ #define digitalPinToPCMSK(p) (WITHIN(p, 10, 13) || WITHIN(p, 50, 53) ? (&PCMSK0) : \
+ WITHIN(p, 14, 15) ? (&PCMSK1) : \
+ WITHIN(p, 62, 69) ? (&PCMSK2) : \
+ nullptr)
+
#undef digitalPinToPCMSKbit
- #define digitalPinToPCMSKbit(p) ( WITHIN(p, 10, 13) ? ((p) - 6) : \
- (p) == 14 || (p) == 51 ? 2 : \
- (p) == 15 || (p) == 52 ? 1 : \
- (p) == 50 ? 3 : \
- (p) == 53 ? 0 : \
- WITHIN(p, 62, 69) ? ((p) - 62) : \
- 0 )
+ #define digitalPinToPCMSKbit(p) (WITHIN(p, 10, 13) ? ((p) - 6) : \
+ (p) == 14 || (p) == 51 ? 2 : \
+ (p) == 15 || (p) == 52 ? 1 : \
+ (p) == 50 ? 3 : \
+ (p) == 53 ? 0 : \
+ WITHIN(p, 62, 69) ? ((p) - 62) : \
+ 0)
+
+#elif defined(__AVR_ATmega164A__) || defined(__AVR_ATmega164P__) || defined(__AVR_ATmega324A__) || \
+ defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega324PB__) || \
+ defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284__) || \
+ defined(__AVR_ATmega1284P__)
+
+ #define digitalPinHasPCICR(p) WITHIN(p, 0, NUM_DIGITAL_PINS)
+
+#else
+
+ #error "Unsupported AVR variant!"
+
#endif
// Install Pin change interrupt for a pin. Can be called multiple times.
void pciSetup(const int8_t pin) {
- if (digitalPinToPCMSK(pin) != nullptr) {
+ if (digitalPinHasPCICR(pin)) {
SBI(*digitalPinToPCMSK(pin), digitalPinToPCMSKbit(pin)); // enable pin
SBI(PCIFR, digitalPinToPCICRbit(pin)); // clear any outstanding interrupt
SBI(PCICR, digitalPinToPCICRbit(pin)); // enable interrupt for the group
@@ -108,7 +124,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(X_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X_MAX_PIN);
#else
- static_assert(digitalPinToPCICR(X_MAX_PIN), "X_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(X_MAX_PIN), "X_MAX_PIN is not interrupt-capable");
pciSetup(X_MAX_PIN);
#endif
#endif
@@ -116,7 +132,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(X_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X_MIN_PIN);
#else
- static_assert(digitalPinToPCICR(X_MIN_PIN), "X_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(X_MIN_PIN), "X_MIN_PIN is not interrupt-capable");
pciSetup(X_MIN_PIN);
#endif
#endif
@@ -124,7 +140,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y_MAX_PIN);
#else
- static_assert(digitalPinToPCICR(Y_MAX_PIN), "Y_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Y_MAX_PIN), "Y_MAX_PIN is not interrupt-capable");
pciSetup(Y_MAX_PIN);
#endif
#endif
@@ -132,7 +148,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y_MIN_PIN);
#else
- static_assert(digitalPinToPCICR(Y_MIN_PIN), "Y_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Y_MIN_PIN), "Y_MIN_PIN is not interrupt-capable");
pciSetup(Y_MIN_PIN);
#endif
#endif
@@ -140,7 +156,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z_MAX_PIN);
#else
- static_assert(digitalPinToPCICR(Z_MAX_PIN), "Z_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z_MAX_PIN), "Z_MAX_PIN is not interrupt-capable");
pciSetup(Z_MAX_PIN);
#endif
#endif
@@ -148,7 +164,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z_MIN_PIN);
#else
- static_assert(digitalPinToPCICR(Z_MIN_PIN), "Z_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z_MIN_PIN), "Z_MIN_PIN is not interrupt-capable");
pciSetup(Z_MIN_PIN);
#endif
#endif
@@ -156,7 +172,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(X2_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X2_MAX_PIN);
#else
- static_assert(digitalPinToPCICR(X2_MAX_PIN), "X2_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(X2_MAX_PIN), "X2_MAX_PIN is not interrupt-capable");
pciSetup(X2_MAX_PIN);
#endif
#endif
@@ -164,7 +180,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(X2_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X2_MIN_PIN);
#else
- static_assert(digitalPinToPCICR(X2_MIN_PIN), "X2_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(X2_MIN_PIN), "X2_MIN_PIN is not interrupt-capable");
pciSetup(X2_MIN_PIN);
#endif
#endif
@@ -172,7 +188,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y2_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y2_MAX_PIN);
#else
- static_assert(digitalPinToPCICR(Y2_MAX_PIN), "Y2_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Y2_MAX_PIN), "Y2_MAX_PIN is not interrupt-capable");
pciSetup(Y2_MAX_PIN);
#endif
#endif
@@ -180,7 +196,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y2_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y2_MIN_PIN);
#else
- static_assert(digitalPinToPCICR(Y2_MIN_PIN), "Y2_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Y2_MIN_PIN), "Y2_MIN_PIN is not interrupt-capable");
pciSetup(Y2_MIN_PIN);
#endif
#endif
@@ -188,7 +204,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z2_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z2_MAX_PIN);
#else
- static_assert(digitalPinToPCICR(Z2_MAX_PIN), "Z2_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z2_MAX_PIN), "Z2_MAX_PIN is not interrupt-capable");
pciSetup(Z2_MAX_PIN);
#endif
#endif
@@ -196,7 +212,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z2_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z2_MIN_PIN);
#else
- static_assert(digitalPinToPCICR(Z2_MIN_PIN), "Z2_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z2_MIN_PIN), "Z2_MIN_PIN is not interrupt-capable");
pciSetup(Z2_MIN_PIN);
#endif
#endif
@@ -204,7 +220,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z3_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z3_MAX_PIN);
#else
- static_assert(digitalPinToPCICR(Z3_MAX_PIN), "Z3_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z3_MAX_PIN), "Z3_MAX_PIN is not interrupt-capable");
pciSetup(Z3_MAX_PIN);
#endif
#endif
@@ -212,7 +228,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z3_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z3_MIN_PIN);
#else
- static_assert(digitalPinToPCICR(Z3_MIN_PIN), "Z3_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z3_MIN_PIN), "Z3_MIN_PIN is not interrupt-capable");
pciSetup(Z3_MIN_PIN);
#endif
#endif
@@ -220,7 +236,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z_MIN_PROBE_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z_MIN_PROBE_PIN);
#else
- static_assert(digitalPinToPCICR(Z_MIN_PROBE_PIN), "Z_MIN_PROBE_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z_MIN_PROBE_PIN), "Z_MIN_PROBE_PIN is not interrupt-capable");
pciSetup(Z_MIN_PROBE_PIN);
#endif
#endif
diff --git a/Marlin/src/HAL/HAL_AVR/fast_pwm.cpp b/Marlin/src/HAL/HAL_AVR/fast_pwm.cpp
index 282b70de71..4884ede63f 100644
--- a/Marlin/src/HAL/HAL_AVR/fast_pwm.cpp
+++ b/Marlin/src/HAL/HAL_AVR/fast_pwm.cpp
@@ -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__
diff --git a/Marlin/src/HAL/HAL_AVR/inc/SanityCheck.h b/Marlin/src/HAL/HAL_AVR/inc/SanityCheck.h
index 93fadf20a5..a6bff05ce7 100644
--- a/Marlin/src/HAL/HAL_AVR/inc/SanityCheck.h
+++ b/Marlin/src/HAL/HAL_AVR/inc/SanityCheck.h
@@ -39,7 +39,7 @@
* Checks for FAST PWM
*/
#if ENABLED(FAST_PWM_FAN) && (ENABLED(USE_OCR2A_AS_TOP) && defined(TCCR2))
- #error "USE_OCR2A_AS_TOP does not apply to devices with a single output TIMER2"
+ #error "USE_OCR2A_AS_TOP does not apply to devices with a single output TIMER2"
#endif
/**
diff --git a/Marlin/src/HAL/HAL_AVR/pinsDebug.h b/Marlin/src/HAL/HAL_AVR/pinsDebug.h
index e4738e0332..8e083494d9 100644
--- a/Marlin/src/HAL/HAL_AVR/pinsDebug.h
+++ b/Marlin/src/HAL/HAL_AVR/pinsDebug.h
@@ -26,7 +26,10 @@
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
+#define AVR_ATmega2560_FAMILY_PLUS_70 MB(BQ_ZUM_MEGA_3D, MIGHTYBOARD_REVE, MINIRAMBO, SCOOVO_X9H)
+
#if AVR_AT90USB1286_FAMILY
+
// Working with Teensyduino extension so need to re-define some things
#include "pinsDebug_Teensyduino.h"
// Can't use the "digitalPinToPort" function from the Teensyduino type IDEs
@@ -35,7 +38,9 @@
#define digitalPinToBitMask_DEBUG(p) digitalPinToBitMask(p)
#define digitalPinToPort_DEBUG(p) digitalPinToPort_Teensy(p)
#define GET_PINMODE(pin) (*portModeRegister(pin) & digitalPinToBitMask_DEBUG(pin))
+
#elif AVR_ATmega2560_FAMILY_PLUS_70 // So we can access/display all the pins on boards using more than 70
+
#include "pinsDebug_plus_70.h"
#define digitalPinToTimer_DEBUG(p) digitalPinToTimer_plus_70(p)
#define digitalPinToBitMask_DEBUG(p) digitalPinToBitMask_plus_70(p)
@@ -43,11 +48,13 @@
bool GET_PINMODE(int8_t pin) {return *portModeRegister(digitalPinToPort_DEBUG(pin)) & digitalPinToBitMask_DEBUG(pin); }
#else
+
#define digitalPinToTimer_DEBUG(p) digitalPinToTimer(p)
#define digitalPinToBitMask_DEBUG(p) digitalPinToBitMask(p)
#define digitalPinToPort_DEBUG(p) digitalPinToPort(p)
bool GET_PINMODE(int8_t pin) {return *portModeRegister(digitalPinToPort_DEBUG(pin)) & digitalPinToBitMask_DEBUG(pin); }
#define GET_ARRAY_PIN(p) pgm_read_byte(&pin_array[p].pin)
+
#endif
#define VALID_PIN(pin) (pin >= 0 && pin < NUM_DIGITAL_PINS ? 1 : 0)
diff --git a/Marlin/src/HAL/HAL_AVR/watchdog.cpp b/Marlin/src/HAL/HAL_AVR/watchdog.cpp
index 63a5031966..c7d487ebd1 100644
--- a/Marlin/src/HAL/HAL_AVR/watchdog.cpp
+++ b/Marlin/src/HAL/HAL_AVR/watchdog.cpp
@@ -28,7 +28,7 @@
#include "watchdog.h"
-#include "../../Marlin.h"
+#include "../../MarlinCore.h"
// Initialize watchdog with 8s timeout, if possible. Otherwise, make it 4s.
void watchdog_init() {
diff --git a/Marlin/src/HAL/HAL_DUE/HAL.h b/Marlin/src/HAL/HAL_DUE/HAL.h
index 2be95b683a..3f38ae0a36 100644
--- a/Marlin/src/HAL/HAL_DUE/HAL.h
+++ b/Marlin/src/HAL/HAL_DUE/HAL.h
@@ -38,22 +38,38 @@
#include
-// 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 customizedSerial1
+#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."
+ #elif SERIAL_PORT_2 == -1
+ #define MYSERIAL1 customizedSerial2
+ #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
@@ -116,6 +132,7 @@ extern uint16_t HAL_adc_result; // result of last ADC conversion
inline void HAL_adc_init() {}//todo
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
+#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
diff --git a/Marlin/src/HAL/HAL_DUE/MarlinSerial.cpp b/Marlin/src/HAL/HAL_DUE/MarlinSerial.cpp
index 7b88b6d43e..83a9c64fae 100644
--- a/Marlin/src/HAL/HAL_DUE/MarlinSerial.cpp
+++ b/Marlin/src/HAL/HAL_DUE/MarlinSerial.cpp
@@ -31,7 +31,7 @@
#include "MarlinSerial.h"
#include "InterruptVectors.h"
-#include "../../Marlin.h"
+#include "../../MarlinCore.h"
template typename MarlinSerial::ring_buffer_r MarlinSerial::rx_buffer = { 0, 0, { 0 } };
template typename MarlinSerial::ring_buffer_t MarlinSerial::tx_buffer = { 0 };
diff --git a/Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp b/Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp
index 5e5a4e5fc1..2501bab78e 100644
--- a/Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp
+++ b/Marlin/src/HAL/HAL_DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp
@@ -63,7 +63,7 @@
#include
-#include "../../../Marlin.h"
+#include "../../../MarlinCore.h"
void spiBegin();
void spiInit(uint8_t spiRate);
diff --git a/Marlin/src/HAL/HAL_DUE/inc/SanityCheck.h b/Marlin/src/HAL/HAL_DUE/inc/SanityCheck.h
index a8d51edfab..44bf8e4473 100644
--- a/Marlin/src/HAL/HAL_DUE/inc/SanityCheck.h
+++ b/Marlin/src/HAL/HAL_DUE/inc/SanityCheck.h
@@ -55,3 +55,7 @@
#if ENABLED(FAST_PWM_FAN)
#error "FAST_PWM_FAN is not yet implemented for this platform."
#endif
+
+#if TMC_HAS_SW_SERIAL
+ #error "TMC220x Software Serial is not supported on this platform."
+#endif
diff --git a/Marlin/src/HAL/HAL_DUE/usb/compiler.h b/Marlin/src/HAL/HAL_DUE/usb/compiler.h
index 7719c129c3..33df080e2f 100644
--- a/Marlin/src/HAL/HAL_DUE/usb/compiler.h
+++ b/Marlin/src/HAL/HAL_DUE/usb/compiler.h
@@ -444,8 +444,8 @@ typedef struct
#define ENABLE 1
#ifndef __cplusplus
#ifndef __bool_true_false_are_defined
-#define false 0
-#define true 1
+#define false (1==0)
+#define true (1==1)
#endif
#endif
#ifndef PASS
diff --git a/Marlin/src/HAL/HAL_DUE/usb/conf_usb.h b/Marlin/src/HAL/HAL_DUE/usb/conf_usb.h
index 6934494e57..8d5924d375 100644
--- a/Marlin/src/HAL/HAL_DUE/usb/conf_usb.h
+++ b/Marlin/src/HAL/HAL_DUE/usb/conf_usb.h
@@ -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
diff --git a/Marlin/src/HAL/HAL_DUE/usb/sd_mmc_spi_mem.cpp b/Marlin/src/HAL/HAL_DUE/usb/sd_mmc_spi_mem.cpp
index b85a2b09a1..ea2936359d 100644
--- a/Marlin/src/HAL/HAL_DUE/usb/sd_mmc_spi_mem.cpp
+++ b/Marlin/src/HAL/HAL_DUE/usb/sd_mmc_spi_mem.cpp
@@ -19,6 +19,9 @@ void sd_mmc_spi_mem_init() {
}
Ctrl_status sd_mmc_spi_test_unit_ready() {
+ #ifdef DISABLE_DUE_SD_MMC
+ return CTRL_NO_PRESENT;
+ #endif
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted())
return CTRL_NO_PRESENT;
return CTRL_GOOD;
@@ -55,6 +58,9 @@ uint8_t sector_buf[SD_MMC_BLOCK_SIZE];
// #define DEBUG_MMC
Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector) {
+ #ifdef DISABLE_DUE_SD_MMC
+ return CTRL_NO_PRESENT;
+ #endif
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted())
return CTRL_NO_PRESENT;
@@ -92,6 +98,9 @@ Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector) {
}
Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) {
+ #ifdef DISABLE_DUE_SD_MMC
+ return CTRL_NO_PRESENT;
+ #endif
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted())
return CTRL_NO_PRESENT;
diff --git a/Marlin/src/HAL/HAL_DUE/usb/usb_task.c b/Marlin/src/HAL/HAL_DUE/usb/usb_task.c
index b735858018..29d02faef7 100644
--- a/Marlin/src/HAL/HAL_DUE/usb/usb_task.c
+++ b/Marlin/src/HAL/HAL_DUE/usb/usb_task.c
@@ -45,11 +45,12 @@
#ifdef ARDUINO_ARCH_SAM
-#include "conf_usb.h"
-#include "udc.h"
#include
#include
+#include "conf_usb.h"
+#include "udc.h"
+
#if ENABLED(SDSUPPORT)
static volatile bool main_b_msc_enable = false;
#endif
diff --git a/Marlin/src/HAL/HAL_DUE/watchdog.cpp b/Marlin/src/HAL/HAL_DUE/watchdog.cpp
index 1f51b75c18..dd80f8c713 100644
--- a/Marlin/src/HAL/HAL_DUE/watchdog.cpp
+++ b/Marlin/src/HAL/HAL_DUE/watchdog.cpp
@@ -23,7 +23,7 @@
#ifdef ARDUINO_ARCH_SAM
#include "../../inc/MarlinConfig.h"
-#include "../../Marlin.h"
+#include "../../MarlinCore.h"
#include "watchdog.h"
// Override Arduino runtime to either config or disable the watchdog
diff --git a/Marlin/src/HAL/HAL_ESP32/HAL.cpp b/Marlin/src/HAL/HAL_ESP32/HAL.cpp
index 9bf41c2e84..c3e6f09649 100644
--- a/Marlin/src/HAL/HAL_ESP32/HAL.cpp
+++ b/Marlin/src/HAL/HAL_ESP32/HAL.cpp
@@ -30,7 +30,7 @@
#include "../../inc/MarlinConfigPre.h"
-#if EITHER(EEPROM_SETTINGS, WEBSUPPORT)
+#if ENABLED(WEBSUPPORT)
#include "spiffs.h"
#endif
@@ -83,7 +83,7 @@ void HAL_init() {
}
void HAL_init_board() {
- #if EITHER(EEPROM_SETTINGS, WEBSUPPORT)
+ #if ENABLED(WEBSUPPORT)
spiffs_init();
#endif
@@ -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) {
diff --git a/Marlin/src/HAL/HAL_ESP32/HAL.h b/Marlin/src/HAL/HAL_ESP32/HAL.h
index 0736ff3c59..b5f2d3e204 100644
--- a/Marlin/src/HAL/HAL_ESP32/HAL.h
+++ b/Marlin/src/HAL/HAL_ESP32/HAL.h
@@ -48,8 +48,8 @@ extern portMUX_TYPE spinlock;
#define MYSERIAL0 flushableSerial
#if ENABLED(WIFISUPPORT)
- #define NUM_SERIAL 2
#define MYSERIAL1 webSocketSerial
+ #define NUM_SERIAL 2
#else
#define NUM_SERIAL 1
#endif
@@ -111,6 +111,7 @@ void eeprom_update_block (const void *__src, void *__dst, size_t __n);
void HAL_adc_init();
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
+#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
diff --git a/Marlin/src/HAL/HAL_ESP32/WebSocketSerial.h b/Marlin/src/HAL/HAL_ESP32/WebSocketSerial.h
index 9590271b01..3d22c4d1b2 100644
--- a/Marlin/src/HAL/HAL_ESP32/WebSocketSerial.h
+++ b/Marlin/src/HAL/HAL_ESP32/WebSocketSerial.h
@@ -23,16 +23,18 @@
#include "../../inc/MarlinConfig.h"
-#include "Stream.h"
+#include
-#ifndef RX_BUFFER_SIZE
- #define RX_BUFFER_SIZE 128
-#endif
#ifndef TX_BUFFER_SIZE
#define TX_BUFFER_SIZE 32
#endif
-#if TX_BUFFER_SIZE <= 0
- #error "TX_BUFFER_SIZE is required for the WebSocket."
+#if ENABLED(WIFISUPPORT)
+ #ifndef RX_BUFFER_SIZE
+ #define RX_BUFFER_SIZE 128
+ #endif
+ #if TX_BUFFER_SIZE <= 0
+ #error "TX_BUFFER_SIZE is required for the WebSocket."
+ #endif
#endif
typedef uint16_t ring_buffer_pos_t;
diff --git a/Marlin/src/HAL/HAL_ESP32/i2s.cpp b/Marlin/src/HAL/HAL_ESP32/i2s.cpp
index 1f7c508cf1..33a503455c 100644
--- a/Marlin/src/HAL/HAL_ESP32/i2s.cpp
+++ b/Marlin/src/HAL/HAL_ESP32/i2s.cpp
@@ -26,10 +26,10 @@
#include "i2s.h"
#include "../shared/Marduino.h"
-#include "driver/periph_ctrl.h"
-#include "rom/lldesc.h"
-#include "soc/i2s_struct.h"
-#include "freertos/queue.h"
+#include
+#include
+#include
+#include
#include "../../module/stepper.h"
#define DMA_BUF_COUNT 8 // number of DMA buffers to store data
diff --git a/Marlin/src/HAL/HAL_ESP32/inc/SanityCheck.h b/Marlin/src/HAL/HAL_ESP32/inc/SanityCheck.h
index 9c62a353e7..c5b0bc0537 100644
--- a/Marlin/src/HAL/HAL_ESP32/inc/SanityCheck.h
+++ b/Marlin/src/HAL/HAL_ESP32/inc/SanityCheck.h
@@ -28,3 +28,7 @@
#if ENABLED(FAST_PWM_FAN)
#error "FAST_PWM_FAN is not yet implemented for this platform."
#endif
+
+#if TMC_HAS_SW_SERIAL
+ #error "TMC220x Software Serial is not supported on this platform."
+#endif
diff --git a/Marlin/src/HAL/HAL_ESP32/ota.cpp b/Marlin/src/HAL/HAL_ESP32/ota.cpp
index 98ea3b5eb7..377856f8d8 100644
--- a/Marlin/src/HAL/HAL_ESP32/ota.cpp
+++ b/Marlin/src/HAL/HAL_ESP32/ota.cpp
@@ -27,7 +27,7 @@
#include
#include
#include
-#include "driver/timer.h"
+#include
void OTA_init() {
ArduinoOTA
diff --git a/Marlin/src/HAL/HAL_ESP32/persistent_store_impl.cpp b/Marlin/src/HAL/HAL_ESP32/persistent_store_impl.cpp
new file mode 100644
index 0000000000..a65a4301a0
--- /dev/null
+++ b/Marlin/src/HAL/HAL_ESP32/persistent_store_impl.cpp
@@ -0,0 +1,63 @@
+/**
+ * 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 .
+ *
+ */
+
+#ifdef ARDUINO_ARCH_ESP32
+
+#include "../../inc/MarlinConfig.h"
+
+#if ENABLED(EEPROM_SETTINGS) && DISABLED(FLASH_EEPROM_EMULATION)
+
+#include "../shared/persistent_store_api.h"
+#include "EEPROM.h"
+
+#define EEPROM_SIZE 4096
+
+bool PersistentStore::access_start() {
+ return EEPROM.begin(EEPROM_SIZE);
+}
+
+bool PersistentStore::access_finish() {
+ EEPROM.end();
+ return true;
+}
+
+bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
+ for (size_t i = 0; i < size; i++) {
+ EEPROM.write(pos++, value[i]);
+ crc16(crc, &value[i], 1);
+ }
+ return false;
+}
+
+bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+ for (size_t i = 0; i < size; i++) {
+ uint8_t c = EEPROM.read(pos++);
+ if (writing) value[i] = c;
+ crc16(crc, &c, 1);
+ }
+ return false;
+}
+
+size_t PersistentStore::capacity() { return EEPROM_SIZE; }
+
+#endif // EEPROM_SETTINGS
+#endif // ARDUINO_ARCH_ESP32
diff --git a/Marlin/src/HAL/HAL_ESP32/persistent_store_spiffs.cpp b/Marlin/src/HAL/HAL_ESP32/persistent_store_spiffs.cpp
deleted file mode 100644
index 5227da3568..0000000000
--- a/Marlin/src/HAL/HAL_ESP32/persistent_store_spiffs.cpp
+++ /dev/null
@@ -1,106 +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 .
- *
- */
-
-#ifdef ARDUINO_ARCH_ESP32
-
-#include "../../inc/MarlinConfig.h"
-
-#if ENABLED(EEPROM_SETTINGS) && DISABLED(FLASH_EEPROM_EMULATION)
-
-#include "../shared/persistent_store_api.h"
-
-#include
-#include
-#include "spiffs.h"
-
-#define HAL_ESP32_EEPROM_SIZE 4096
-#define HAL_ESP32_EEPROM_FILE_PATH "/eeprom.dat"
-
-File eeprom_file;
-
-bool PersistentStore::access_start() {
- if (spiffs_initialized) {
- eeprom_file = SPIFFS.open(HAL_ESP32_EEPROM_FILE_PATH, "r+");
-
- size_t file_size = eeprom_file.size();
- if (file_size < HAL_ESP32_EEPROM_SIZE) {
- SERIAL_ECHO_MSG("SPIFFS EEPROM settings file " HAL_ESP32_EEPROM_FILE_PATH " is too small or did not exist, expanding.");
- SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR(" file size: ", file_size, ", required size: ", HAL_ESP32_EEPROM_SIZE);
-
- // mode r+ does not allow to expand the file (at least on ESP32 SPIFFS9, so we close, reopen "a", append, close, reopen "r+"
- eeprom_file.close();
-
- eeprom_file = SPIFFS.open(HAL_ESP32_EEPROM_FILE_PATH, "a");
- for (size_t i = eeprom_file.size(); i < HAL_ESP32_EEPROM_SIZE; i++)
- eeprom_file.write(0xFF);
- eeprom_file.close();
-
- eeprom_file = SPIFFS.open(HAL_ESP32_EEPROM_FILE_PATH, "r+");
- file_size = eeprom_file.size();
- if (file_size < HAL_ESP32_EEPROM_SIZE) {
- SERIAL_ERROR_MSG("Failed to expand " HAL_ESP32_EEPROM_FILE_PATH " to required size. SPIFFS partition full?");
- SERIAL_ERROR_START(); SERIAL_ECHOLNPAIR(" file size: ", file_size, ", required size: ", HAL_ESP32_EEPROM_SIZE);
- SERIAL_ERROR_START(); SERIAL_ECHOLNPAIR(" SPIFFS used bytes: ", SPIFFS.usedBytes(), ", total bytes: ", SPIFFS.totalBytes());
- }
- }
- return true;
- }
- return false;
-}
-
-bool PersistentStore::access_finish() {
- eeprom_file.close();
- return true;
-}
-
-bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
- if (!eeprom_file.seek(pos)) return true; // return true for any error
- if (eeprom_file.write(value, size) != size) return true;
-
- crc16(crc, value, size);
- pos += size;
-
- return false;
-}
-
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
- if (!eeprom_file.seek(pos)) return true; // return true for any error
-
- if (writing) {
- if (eeprom_file.read(value, size) != size) return true;
- crc16(crc, value, size);
- }
- else {
- uint8_t tmp[size];
- if (eeprom_file.read(tmp, size) != size) return true;
- crc16(crc, tmp, size);
- }
-
- pos += size;
-
- return false;
-}
-
-size_t PersistentStore::capacity() { return HAL_ESP32_EEPROM_SIZE; }
-
-#endif // EEPROM_SETTINGS
-#endif // ARDUINO_ARCH_ESP32
diff --git a/Marlin/src/HAL/HAL_ESP32/spiffs.cpp b/Marlin/src/HAL/HAL_ESP32/spiffs.cpp
index a3e1bd8a25..1a542580b0 100644
--- a/Marlin/src/HAL/HAL_ESP32/spiffs.cpp
+++ b/Marlin/src/HAL/HAL_ESP32/spiffs.cpp
@@ -24,7 +24,7 @@
#include "../../inc/MarlinConfigPre.h"
-#if EITHER(WEBSUPPORT, EEPROM_SETTINGS)
+#if ENABLED(WEBSUPPORT)
#include "../../core/serial.h"
diff --git a/Marlin/src/HAL/HAL_ESP32/timers.cpp b/Marlin/src/HAL/HAL_ESP32/timers.cpp
index 79a79e37cd..543889760e 100644
--- a/Marlin/src/HAL/HAL_ESP32/timers.cpp
+++ b/Marlin/src/HAL/HAL_ESP32/timers.cpp
@@ -23,10 +23,10 @@
#ifdef ARDUINO_ARCH_ESP32
#include
-#include "esp_types.h"
-#include "soc/timer_group_struct.h"
-#include "driver/periph_ctrl.h"
-#include "driver/timer.h"
+#include
+#include
+#include
+#include
#include "HAL.h"
diff --git a/Marlin/src/HAL/HAL_ESP32/timers.h b/Marlin/src/HAL/HAL_ESP32/timers.h
index 4b01f4ba7c..e6e3495bea 100644
--- a/Marlin/src/HAL/HAL_ESP32/timers.h
+++ b/Marlin/src/HAL/HAL_ESP32/timers.h
@@ -22,7 +22,7 @@
#pragma once
#include
-#include "driver/timer.h"
+#include
// Includes needed to get I2S_STEPPER_STREAM. Note that pins.h
// is included in case this header is being included early.
@@ -51,8 +51,8 @@ typedef uint64_t hal_timer_t;
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs // wrong would be 0.25
#else
#define STEPPER_TIMER_PRESCALE 40
- #define STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // frequency of stepper timer, 2MHz
- #define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
+ #define STEPPER_TIMER_RATE ((HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE)) // frequency of stepper timer, 2MHz
+ #define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
#endif
#define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts
diff --git a/Marlin/src/HAL/HAL_ESP32/watchdog.h b/Marlin/src/HAL/HAL_ESP32/watchdog.h
index 6647ecefe6..9fb39ff9a5 100644
--- a/Marlin/src/HAL/HAL_ESP32/watchdog.h
+++ b/Marlin/src/HAL/HAL_ESP32/watchdog.h
@@ -21,8 +21,18 @@
*/
#pragma once
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+ esp_err_t esp_task_wdt_reset();
+
+#ifdef __cplusplus
+ }
+#endif
+
// Initialize watchdog with a 4 second interrupt time
void watchdog_init();
// Reset watchdog.
-inline void HAL_watchdog_refresh() {}
+inline void HAL_watchdog_refresh() { esp_task_wdt_reset(); }
diff --git a/Marlin/src/HAL/HAL_LINUX/HAL.h b/Marlin/src/HAL/HAL_LINUX/HAL.h
index 5bd283e5c1..37b3b479bc 100644
--- a/Marlin/src/HAL/HAL_LINUX/HAL.h
+++ b/Marlin/src/HAL/HAL_LINUX/HAL.h
@@ -89,6 +89,7 @@ int freeMemory();
// ADC
#define HAL_ANALOG_SELECT(pin) HAL_adc_enable_channel(pin)
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
+#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_get_result()
#define HAL_ADC_READY() true
diff --git a/Marlin/src/HAL/HAL_LINUX/inc/SanityCheck.h b/Marlin/src/HAL/HAL_LINUX/inc/SanityCheck.h
index 776fa2f139..3b18dec730 100644
--- a/Marlin/src/HAL/HAL_LINUX/inc/SanityCheck.h
+++ b/Marlin/src/HAL/HAL_LINUX/inc/SanityCheck.h
@@ -33,3 +33,7 @@
#if ENABLED(FAST_PWM_FAN)
#error "FAST_PWM_FAN is not yet implemented for this platform."
#endif
+
+#if TMC_HAS_SW_SERIAL
+ #error "TMC220x Software Serial is not supported on this platform."
+#endif
diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL.cpp b/Marlin/src/HAL/HAL_LPC1768/HAL.cpp
index 2607ecfb46..4da55c2f3d 100644
--- a/Marlin/src/HAL/HAL_LPC1768/HAL.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/HAL.cpp
@@ -30,6 +30,8 @@
#include "watchdog.h"
#endif
+uint32_t HAL_adc_reading = 0;
+
// U8glib required functions
extern "C" void u8g_xMicroDelay(uint16_t val) {
DELAY_US(val);
@@ -61,7 +63,7 @@ int freeMemory() {
// return dval if not found or not a valid pin.
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) {
const uint16_t val = (uint16_t)parser.intval(code, -1), port = val / 100, pin = val % 100;
- const int16_t ind = (port < ((NUM_DIGITAL_PINS) >> 5) && pin < 32) ? GET_PIN_MAP_INDEX((port << 5) | pin) : -2;
+ const int16_t ind = (port < ((NUM_DIGITAL_PINS) >> 5) && pin < 32) ? ((port << 5) | pin) : -2;
return ind > -1 ? ind : dval;
}
diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL.h b/Marlin/src/HAL/HAL_LPC1768/HAL.h
index 7ea6d288be..a85379ad99 100644
--- a/Marlin/src/HAL/HAL_LPC1768/HAL.h
+++ b/Marlin/src/HAL/HAL_LPC1768/HAL.h
@@ -61,10 +61,6 @@ extern "C" volatile uint32_t _millis;
#define ST7920_DELAY_3 DELAY_NS(750)
#endif
-#if !WITHIN(SERIAL_PORT, -1, 3)
- #error "SERIAL_PORT must be from -1 to 3"
-#endif
-
#if SERIAL_PORT == -1
#define MYSERIAL0 UsbSerial
#elif SERIAL_PORT == 0
@@ -75,16 +71,14 @@ extern "C" volatile uint32_t _millis;
#define MYSERIAL0 MSerial2
#elif SERIAL_PORT == 3
#define MYSERIAL0 MSerial3
+#else
+ #error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#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"
- #endif
- #define NUM_SERIAL 2
- #if SERIAL_PORT_2 == -1
+ #if SERIAL_PORT_2 == SERIAL_PORT
+ #error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration."
+ #elif SERIAL_PORT_2 == -1
#define MYSERIAL1 UsbSerial
#elif SERIAL_PORT_2 == 0
#define MYSERIAL1 MSerial
@@ -94,7 +88,10 @@ extern "C" volatile uint32_t _millis;
#define MYSERIAL1 MSerial2
#elif SERIAL_PORT_2 == 3
#define MYSERIAL1 MSerial3
+ #else
+ #error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#endif
+ #define NUM_SERIAL 2
#else
#define NUM_SERIAL 1
#endif
@@ -131,12 +128,43 @@ int freeMemory();
// K = 6, 565 samples, 500Hz sample rate, 1.13s convergence on full range step
// Memory usage per ADC channel (bytes): 4 (32 Bytes for 8 channels)
+#define HAL_ADC_RESOLUTION 12 // 15 bit maximum, raw temperature is stored as int16_t
+#define HAL_ADC_FILTERED // Disable oversampling done in Marlin as ADC values already filtered in HAL
+
using FilteredADC = LPC176x::ADC;
-#define HAL_adc_init() FilteredADC::init()
+extern uint32_t HAL_adc_reading;
+[[gnu::always_inline]] inline void HAL_start_adc(const pin_t pin) {
+ HAL_adc_reading = FilteredADC::read(pin) >> (16 - HAL_ADC_RESOLUTION); // returns 16bit value, reduce to required bits
+}
+[[gnu::always_inline]] inline uint16_t HAL_read_adc() {
+ return HAL_adc_reading;
+}
+
+#define HAL_adc_init()
#define HAL_ANALOG_SELECT(pin) FilteredADC::enable_channel(pin)
-#define HAL_START_ADC(pin) FilteredADC::start_conversion(pin)
-#define HAL_READ_ADC() FilteredADC::get_result()
-#define HAL_ADC_READY() FilteredADC::finished_conversion()
+#define HAL_START_ADC(pin) HAL_start_adc(pin)
+#define HAL_READ_ADC() HAL_read_adc()
+#define HAL_ADC_READY() (true)
+
+// Test whether the pin is valid
+constexpr bool VALID_PIN(const pin_t pin) {
+ return LPC176x::pin_is_valid(pin);
+}
+
+// Get the analog index for a digital pin
+constexpr int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t pin) {
+ return (LPC176x::pin_is_valid(pin) && LPC176x::pin_has_adc(pin)) ? pin : -1;
+}
+
+// Return the index of a pin number
+constexpr int16_t GET_PIN_MAP_INDEX(const pin_t pin) {
+ return LPC176x::pin_index(pin);
+}
+
+// Get the pin number at the given index
+constexpr pin_t GET_PIN_MAP_PIN(const int16_t index) {
+ return LPC176x::pin_index(index);
+}
// Parse a G-code word into a pin index
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval);
diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL_SPI.cpp b/Marlin/src/HAL/HAL_LPC1768/HAL_SPI.cpp
index 5652db988b..5f32c7874d 100644
--- a/Marlin/src/HAL/HAL_LPC1768/HAL_SPI.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/HAL_SPI.cpp
@@ -56,7 +56,7 @@
// ------------------------
#if ENABLED(LPC_SOFTWARE_SPI)
- #include "SoftwareSPI.h"
+ #include
// Software SPI
@@ -125,18 +125,18 @@
PinCfg.Funcnum = 2;
PinCfg.OpenDrain = 0;
PinCfg.Pinmode = 0;
- PinCfg.Pinnum = LPC1768_PIN_PIN(SCK_PIN);
- PinCfg.Portnum = LPC1768_PIN_PORT(SCK_PIN);
+ PinCfg.Pinnum = LPC176x::pin_bit(SCK_PIN);
+ PinCfg.Portnum = LPC176x::pin_port(SCK_PIN);
PINSEL_ConfigPin(&PinCfg);
SET_OUTPUT(SCK_PIN);
- PinCfg.Pinnum = LPC1768_PIN_PIN(MISO_PIN);
- PinCfg.Portnum = LPC1768_PIN_PORT(MISO_PIN);
+ PinCfg.Pinnum = LPC176x::pin_bit(MISO_PIN);
+ PinCfg.Portnum = LPC176x::pin_port(MISO_PIN);
PINSEL_ConfigPin(&PinCfg);
SET_INPUT(MISO_PIN);
- PinCfg.Pinnum = LPC1768_PIN_PIN(MOSI_PIN);
- PinCfg.Portnum = LPC1768_PIN_PORT(MOSI_PIN);
+ PinCfg.Pinnum = LPC176x::pin_bit(MOSI_PIN);
+ PinCfg.Portnum = LPC176x::pin_port(MOSI_PIN);
PINSEL_ConfigPin(&PinCfg);
SET_OUTPUT(MOSI_PIN);
// divide PCLK by 2 for SSP0
diff --git a/Marlin/src/HAL/HAL_LPC1768/endstop_interrupts.h b/Marlin/src/HAL/HAL_LPC1768/endstop_interrupts.h
index 53e4b15809..f1d4fc754f 100644
--- a/Marlin/src/HAL/HAL_LPC1768/endstop_interrupts.h
+++ b/Marlin/src/HAL/HAL_LPC1768/endstop_interrupts.h
@@ -42,6 +42,8 @@ void endstop_ISR() { endstops.update(); }
void setup_endstop_interrupts() {
#define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE)
+ #define LPC1768_PIN_INTERRUPT_M(pin) ((pin >> 0x5 & 0x7) == 0 || (pin >> 0x5 & 0x7) == 2)
+
#if HAS_X_MAX
#if !LPC1768_PIN_INTERRUPT_M(X_MAX_PIN)
#error "X_MAX_PIN is not INTERRUPT-capable."
diff --git a/Marlin/src/HAL/HAL_LPC1768/fast_pwm.cpp b/Marlin/src/HAL/HAL_LPC1768/fast_pwm.cpp
index 7af3a07eea..6c7de9bb1d 100644
--- a/Marlin/src/HAL/HAL_LPC1768/fast_pwm.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/fast_pwm.cpp
@@ -24,17 +24,17 @@
#include "../../inc/MarlinConfigPre.h"
-#if ENABLED(FAST_PWM_FAN)
+#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_PWM
#include
void set_pwm_frequency(const pin_t pin, int f_desired) {
- pwm_set_frequency(pin, f_desired);
+ LPC176x::pwm_set_frequency(pin, f_desired);
}
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
- pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size);
+ LPC176x::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
diff --git a/Marlin/src/HAL/HAL_LPC1768/fastio.h b/Marlin/src/HAL/HAL_LPC1768/fastio.h
index a00a4946c1..8b90ec20d3 100644
--- a/Marlin/src/HAL/HAL_LPC1768/fastio.h
+++ b/Marlin/src/HAL/HAL_LPC1768/fastio.h
@@ -37,19 +37,19 @@
#define PWM_PIN(P) true // all pins are PWM capable
-#define LPC_PIN(pin) gpio_pin(pin)
-#define LPC_GPIO(port) gpio_port(port)
+#define LPC_PIN(pin) LPC176x::gpio_pin(pin)
+#define LPC_GPIO(port) LPC176x::gpio_port(port)
-#define SET_DIR_INPUT(IO) gpio_set_input(IO)
-#define SET_DIR_OUTPUT(IO) gpio_set_output(IO)
+#define SET_DIR_INPUT(IO) LPC176x::gpio_set_input(IO)
+#define SET_DIR_OUTPUT(IO) LPC176x::gpio_set_output(IO)
#define SET_MODE(IO, mode) pinMode(IO, mode)
-#define WRITE_PIN_SET(IO) gpio_set(IO)
-#define WRITE_PIN_CLR(IO) gpio_clear(IO)
+#define WRITE_PIN_SET(IO) LPC176x::gpio_set(IO)
+#define WRITE_PIN_CLR(IO) LPC176x::gpio_clear(IO)
-#define READ_PIN(IO) gpio_get(IO)
-#define WRITE_PIN(IO,V) gpio_set(IO, V)
+#define READ_PIN(IO) LPC176x::gpio_get(IO)
+#define WRITE_PIN(IO,V) LPC176x::gpio_set(IO, V)
/**
* Magic I/O routines
@@ -81,10 +81,10 @@
#define _PULLDOWN(IO,V) pinMode(IO, (V) ? INPUT_PULLDOWN : INPUT)
/// check if pin is an input
-#define _IS_INPUT(IO) (!gpio_get_dir(IO))
+#define _IS_INPUT(IO) (!LPC176x::gpio_get_dir(IO))
/// check if pin is an output
-#define _IS_OUTPUT(IO) (gpio_get_dir(IO))
+#define _IS_OUTPUT(IO) (LPC176x::gpio_get_dir(IO))
/// Read a pin wrapper
#define READ(IO) _READ(IO)
diff --git a/Marlin/src/HAL/HAL_LPC1768/inc/SanityCheck.h b/Marlin/src/HAL/HAL_LPC1768/inc/SanityCheck.h
index 6223e006df..b32b05eac0 100644
--- a/Marlin/src/HAL/HAL_LPC1768/inc/SanityCheck.h
+++ b/Marlin/src/HAL/HAL_LPC1768/inc/SanityCheck.h
@@ -21,6 +21,42 @@
*/
#pragma once
+#if PIO_PLATFORM_VERSION < 1001
+ #error "nxplpc-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries. You may need to remove the platform and let it reinstall automatically."
+#endif
+#if PIO_FRAMEWORK_VERSION < 2002
+ #error "framework-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries."
+#endif
+
+/**
+ * Detect an old pins file by checking for old ADC pins values.
+ */
+#define _OLD_TEMP_PIN(P) PIN_EXISTS(P) && _CAT(P,_PIN) <= 7 && _CAT(P,_PIN) != 2 && _CAT(P,_PIN) != 3
+#if _OLD_TEMP_PIN(TEMP_BED)
+ #error "TEMP_BED_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
+#elif _OLD_TEMP_PIN(TEMP_0)
+ #error "TEMP_0_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
+#elif _OLD_TEMP_PIN(TEMP_1)
+ #error "TEMP_1_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
+#elif _OLD_TEMP_PIN(TEMP_2)
+ #error "TEMP_2_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
+#elif _OLD_TEMP_PIN(TEMP_3)
+ #error "TEMP_3_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
+#elif _OLD_TEMP_PIN(TEMP_4)
+ #error "TEMP_4_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
+#elif _OLD_TEMP_PIN(TEMP_5)
+ #error "TEMP_5_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
+#endif
+#undef _OLD_TEMP_PIN
+
+/**
+ * Because PWM hardware channels all share the same frequency, along with the
+ * fallback software channels, FAST_PWM_FAN is incompatible with Servos.
+ */
+#if NUM_SERVOS > 0 && ENABLED(FAST_PWM_FAN)
+ #error "BLTOUCH and Servos are incompatible with FAST_PWM_FAN on LPC176x boards."
+#endif
+
/**
* Test LPC176x-specific configuration values for errors at compile-time.
*/
@@ -32,3 +68,7 @@
#if IS_RE_ARM_BOARD && ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) && HAS_DRIVER(TMC2130) && DISABLED(TMC_USE_SW_SPI)
#error "Re-ARM with REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER and TMC2130 require TMC_USE_SW_SPI"
#endif
+
+#if ENABLED(BAUD_RATE_GCODE)
+ #error "BAUD_RATE_GCODE is not yet supported on LPC176x."
+#endif
diff --git a/Marlin/src/HAL/HAL_LPC1768/persistent_store_flash.cpp b/Marlin/src/HAL/HAL_LPC1768/persistent_store_flash.cpp
index dac7d7a3a9..3de02022eb 100644
--- a/Marlin/src/HAL/HAL_LPC1768/persistent_store_flash.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/persistent_store_flash.cpp
@@ -46,7 +46,7 @@
#if ENABLED(FLASH_EEPROM_EMULATION)
extern "C" {
- #include "lpc17xx_iap.h"
+ #include
}
#define SECTOR_START(sector) ((sector < 16) ? (sector * 0x1000) : ((sector - 14) * 0x8000))
diff --git a/Marlin/src/HAL/HAL_LPC1768/pinsDebug.h b/Marlin/src/HAL/HAL_LPC1768/pinsDebug.h
index e39f2d2453..133cd11be2 100644
--- a/Marlin/src/HAL/HAL_LPC1768/pinsDebug.h
+++ b/Marlin/src/HAL/HAL_LPC1768/pinsDebug.h
@@ -33,52 +33,21 @@
#define PRINT_PORT(p)
#define GET_ARRAY_PIN(p) pin_array[p].pin
#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0)
-#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%d.%02d"), LPC1768_PIN_PORT(p), LPC1768_PIN_PIN(p)); SERIAL_ECHO(buffer); }while(0)
+#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%d.%02d"), LPC176x::pin_port(p), LPC176x::pin_bit(p)); SERIAL_ECHO(buffer); }while(0)
#define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin
// pins that will cause hang/reset/disconnect in M43 Toggle and Watch utilities
-// uses pin index
#ifndef M43_NEVER_TOUCH
- #define M43_NEVER_TOUCH(Q) ((Q) == 29 || (Q) == 30 || (Q) == 73) // USB pins
+ #define M43_NEVER_TOUCH(Q) ((Q) == P0_29 || (Q) == P0_30 || (Q) == P2_09) // USB pins
#endif
-// active ADC function/mode/code values for PINSEL registers
-constexpr int8_t ADC_pin_mode(pin_t pin) {
- return (LPC1768_PIN_PORT(pin) == 0 && LPC1768_PIN_PIN(pin) == 2 ? 2 :
- LPC1768_PIN_PORT(pin) == 0 && LPC1768_PIN_PIN(pin) == 3 ? 2 :
- LPC1768_PIN_PORT(pin) == 0 && LPC1768_PIN_PIN(pin) == 23 ? 1 :
- LPC1768_PIN_PORT(pin) == 0 && LPC1768_PIN_PIN(pin) == 24 ? 1 :
- LPC1768_PIN_PORT(pin) == 0 && LPC1768_PIN_PIN(pin) == 25 ? 1 :
- LPC1768_PIN_PORT(pin) == 0 && LPC1768_PIN_PIN(pin) == 26 ? 1 :
- LPC1768_PIN_PORT(pin) == 1 && LPC1768_PIN_PIN(pin) == 30 ? 3 :
- LPC1768_PIN_PORT(pin) == 1 && LPC1768_PIN_PIN(pin) == 31 ? 3 : -1);
-}
-
-int8_t get_pin_mode(pin_t pin) {
- if (!VALID_PIN(pin)) return -1;
- uint8_t pin_port = LPC1768_PIN_PORT(pin);
- uint8_t pin_port_pin = LPC1768_PIN_PIN(pin);
- //get appropriate PINSEL register
- volatile uint32_t * pinsel_reg = (pin_port == 0 && pin_port_pin <= 15) ? &LPC_PINCON->PINSEL0 :
- (pin_port == 0) ? &LPC_PINCON->PINSEL1 :
- (pin_port == 1 && pin_port_pin <= 15) ? &LPC_PINCON->PINSEL2 :
- pin_port == 1 ? &LPC_PINCON->PINSEL3 :
- pin_port == 2 ? &LPC_PINCON->PINSEL4 :
- pin_port == 3 ? &LPC_PINCON->PINSEL7 : &LPC_PINCON->PINSEL9;
- uint8_t pinsel_start_bit = pin_port_pin > 15 ? 2 * (pin_port_pin - 16) : 2 * pin_port_pin;
- int8_t pin_mode = (int8_t) ((*pinsel_reg >> pinsel_start_bit) & 0x3);
- return pin_mode;
-}
-
-bool GET_PINMODE(pin_t pin) {
- int8_t pin_mode = get_pin_mode(pin);
- if (pin_mode == -1 || pin_mode == ADC_pin_mode(pin)) // found an invalid pin or active analog pin
+bool GET_PINMODE(const pin_t pin) {
+ if (!LPC176x::pin_is_valid(pin) || LPC176x::pin_adc_enabled(pin)) // found an invalid pin or active analog pin
return false;
- uint32_t * FIO_reg[5] PROGMEM = {(uint32_t*) 0x2009C000,(uint32_t*) 0x2009C020,(uint32_t*) 0x2009C040,(uint32_t*) 0x2009C060,(uint32_t*) 0x2009C080};
- return ((*FIO_reg[LPC1768_PIN_PORT(pin)] >> LPC1768_PIN_PIN(pin) & 1) != 0); //input/output state
+ return LPC176x::gpio_direction(pin);
}
-bool GET_ARRAY_IS_DIGITAL(pin_t pin) {
- return (!IS_ANALOG(pin) || get_pin_mode(pin) != ADC_pin_mode(pin));
+bool GET_ARRAY_IS_DIGITAL(const pin_t pin) {
+ return (!LPC176x::pin_has_adc(pin) || !LPC176x::pin_adc_enabled(pin));
}
diff --git a/Marlin/src/HAL/HAL_LPC1768/timers.h b/Marlin/src/HAL/HAL_LPC1768/timers.h
index 73ea728af1..5f4e06265e 100644
--- a/Marlin/src/HAL/HAL_LPC1768/timers.h
+++ b/Marlin/src/HAL/HAL_LPC1768/timers.h
@@ -59,7 +59,7 @@
typedef uint32_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF
-#define HAL_TIMER_RATE ((SystemCoreClock) / 4) // frequency of timers peripherals
+#define HAL_TIMER_RATE ((F_CPU) / 4) // frequency of timers peripherals
#define STEP_TIMER_NUM 0 // Timer Index for Stepper
#define TEMP_TIMER_NUM 1 // Timer Index for Temperature
diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/LCD_I2C_routines.c b/Marlin/src/HAL/HAL_LPC1768/u8g/LCD_I2C_routines.cpp
similarity index 97%
rename from Marlin/src/HAL/HAL_LPC1768/u8g/LCD_I2C_routines.c
rename to Marlin/src/HAL/HAL_LPC1768/u8g/LCD_I2C_routines.cpp
index dc81396b09..9a95b1b660 100644
--- a/Marlin/src/HAL/HAL_LPC1768/u8g/LCD_I2C_routines.c
+++ b/Marlin/src/HAL/HAL_LPC1768/u8g/LCD_I2C_routines.cpp
@@ -25,6 +25,8 @@
#ifdef TARGET_LPC1768
+extern int millis();
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -35,6 +37,7 @@
#include "../../../core/millis_t.h"
+
//////////////////////////////////////////////////////////////////////////////////////
// These two routines are exact copies of the lpc17xx_i2c.c routines. Couldn't link to
@@ -151,14 +154,13 @@ void u8g_i2c_init(uint8_t clock_option) {
u8g_i2c_start(0); // send slave address and write bit
}
-volatile extern millis_t _millis;
uint8_t u8g_i2c_send_byte(uint8_t data) {
#define I2C_TIMEOUT 3
LPC_I2C1->I2DAT = data & I2C_I2DAT_BITMASK; // transmit data
LPC_I2C1->I2CONSET = I2C_I2CONSET_AA;
LPC_I2C1->I2CONCLR = I2C_I2CONCLR_SIC;
- const millis_t timeout = _millis + I2C_TIMEOUT;
- while ((I2C_status != I2C_I2STAT_M_TX_DAT_ACK) && (I2C_status != I2C_I2STAT_M_TX_DAT_NACK) && PENDING(_millis, timeout)); // wait for xmit to finish
+ const millis_t timeout = millis() + I2C_TIMEOUT;
+ while ((I2C_status != I2C_I2STAT_M_TX_DAT_ACK) && (I2C_status != I2C_I2STAT_M_TX_DAT_NACK) && PENDING(millis(), timeout)); // wait for xmit to finish
// had hangs with SH1106 so added time out - have seen temporary screen corruption when this happens
return 1;
}
diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp b/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp
index 59414e896b..0a1bd84875 100644
--- a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp
@@ -60,7 +60,7 @@
#if ENABLED(U8GLIB_ST7920)
#include
-#include "SoftwareSPI.h"
+#include
#include "../../shared/Delay.h"
#undef SPI_SPEED
diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp b/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp
index e243d40013..7b6557148a 100644
--- a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp
@@ -59,7 +59,7 @@
#if HAS_GRAPHICAL_LCD && DISABLED(U8GLIB_ST7920)
-#include "SoftwareSPI.h"
+#include
#undef SPI_SPEED
#define SPI_SPEED 2 // About 2 MHz
@@ -75,25 +75,25 @@ uint8_t swSpiTransfer_mode_0(uint8_t b, const uint8_t spi_speed, const pin_t sck
for (uint8_t i = 0; i < 8; i++) {
if (spi_speed == 0) {
- gpio_set(mosi_pin, !!(b & 0x80));
- gpio_set(sck_pin, HIGH);
+ LPC176x::gpio_set(mosi_pin, !!(b & 0x80));
+ LPC176x::gpio_set(sck_pin, HIGH);
b <<= 1;
- if (miso_pin >= 0 && gpio_get(miso_pin)) b |= 1;
- gpio_set(sck_pin, LOW);
+ if (miso_pin >= 0 && LPC176x::gpio_get(miso_pin)) b |= 1;
+ LPC176x::gpio_set(sck_pin, LOW);
}
else {
const uint8_t state = (b & 0x80) ? HIGH : LOW;
for (uint8_t j = 0; j < spi_speed; j++)
- gpio_set(mosi_pin, state);
+ LPC176x::gpio_set(mosi_pin, state);
for (uint8_t j = 0; j < spi_speed + (miso_pin >= 0 ? 0 : 1); j++)
- gpio_set(sck_pin, HIGH);
+ LPC176x::gpio_set(sck_pin, HIGH);
b <<= 1;
- if (miso_pin >= 0 && gpio_get(miso_pin)) b |= 1;
+ if (miso_pin >= 0 && LPC176x::gpio_get(miso_pin)) b |= 1;
for (uint8_t j = 0; j < spi_speed; j++)
- gpio_set(sck_pin, LOW);
+ LPC176x::gpio_set(sck_pin, LOW);
}
}
@@ -105,23 +105,23 @@ uint8_t swSpiTransfer_mode_3(uint8_t b, const uint8_t spi_speed, const pin_t sck
for (uint8_t i = 0; i < 8; i++) {
const uint8_t state = (b & 0x80) ? HIGH : LOW;
if (spi_speed == 0) {
- gpio_set(sck_pin, LOW);
- gpio_set(mosi_pin, state);
- gpio_set(mosi_pin, state); // need some setup time
- gpio_set(sck_pin, HIGH);
+ LPC176x::gpio_set(sck_pin, LOW);
+ LPC176x::gpio_set(mosi_pin, state);
+ LPC176x::gpio_set(mosi_pin, state); // need some setup time
+ LPC176x::gpio_set(sck_pin, HIGH);
}
else {
for (uint8_t j = 0; j < spi_speed + (miso_pin >= 0 ? 0 : 1); j++)
- gpio_set(sck_pin, LOW);
+ LPC176x::gpio_set(sck_pin, LOW);
for (uint8_t j = 0; j < spi_speed; j++)
- gpio_set(mosi_pin, state);
+ LPC176x::gpio_set(mosi_pin, state);
for (uint8_t j = 0; j < spi_speed; j++)
- gpio_set(sck_pin, HIGH);
+ LPC176x::gpio_set(sck_pin, HIGH);
}
b <<= 1;
- if (miso_pin >= 0 && gpio_get(miso_pin)) b |= 1;
+ if (miso_pin >= 0 && LPC176x::gpio_get(miso_pin)) b |= 1;
}
return b;
@@ -130,7 +130,7 @@ uint8_t swSpiTransfer_mode_3(uint8_t b, const uint8_t spi_speed, const pin_t sck
static uint8_t SPI_speed = 0;
static void u8g_sw_spi_HAL_LPC1768_shift_out(uint8_t dataPin, uint8_t clockPin, uint8_t val) {
- #if ENABLED(FYSETC_MINI_12864)
+ #if EITHER(FYSETC_MINI_12864, MKS_MINI_12864)
swSpiTransfer_mode_3(val, SPI_speed, clockPin, -1, dataPin);
#else
swSpiTransfer_mode_0(val, SPI_speed, clockPin, -1, dataPin);
@@ -158,10 +158,10 @@ uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val,
break;
case U8G_COM_MSG_CHIP_SELECT:
- #if ENABLED(FYSETC_MINI_12864) // LCD SPI is running mode 3 while SD card is running mode 0
- if (arg_val) { // SCK idle state needs to be set to the proper idle state before
- // the next chip select goes active
- u8g_SetPILevel(u8g, U8G_PI_SCK, 1); // Set SCK to mode 3 idle state before CS goes active
+ #if EITHER(FYSETC_MINI_12864, MKS_MINI_12864) // LCD SPI is running mode 3 while SD card is running mode 0
+ if (arg_val) { // SCK idle state needs to be set to the proper idle state before
+ // the next chip select goes active
+ u8g_SetPILevel(u8g, U8G_PI_SCK, 1); // Set SCK to mode 3 idle state before CS goes active
u8g_SetPILevel(u8g, U8G_PI_CS, LOW);
}
else {
diff --git a/Marlin/src/HAL/HAL_LPC1768/upload_extra_script.py b/Marlin/src/HAL/HAL_LPC1768/upload_extra_script.py
old mode 100644
new mode 100755
index 44e0f09ad0..b3ab59026e
--- a/Marlin/src/HAL/HAL_LPC1768/upload_extra_script.py
+++ b/Marlin/src/HAL/HAL_LPC1768/upload_extra_script.py
@@ -31,9 +31,11 @@ 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 = str(subprocess.check_output("fsutil fsinfo drives"))
# typical result (string): 'C:\ D:\ E:\ F:\ G:\ H:\ I:\ J:\ K:\ L:\ M:\ Y:\ Z:\'
- driveStr = driveStr.strip().lstrip('Drives: ')
+ # driveStr = driveStr.strip().lstrip('Drives: ') <- Doesn't work in other Languages as English. In German is "Drives:" = "Laufwerke:"
+ FirstFound = driveStr.find(':',0,-1) # Find the first ":" and
+ driveStr = driveStr[FirstFound + 1 : -1] # truncate to the rest
# typical result (array of stings): ['C:\\', 'D:\\', 'E:\\', 'F:\\',
# 'G:\\', 'H:\\', 'I:\\', 'J:\\', 'K:\\', 'L:\\', 'M:\\', 'Y:\\', 'Z:\\']
drives = driveStr.split()
@@ -44,7 +46,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 = str(subprocess.check_output('cmd /C dir ' + final_drive_name, stderr=subprocess.STDOUT))
except Exception as e:
continue
else:
diff --git a/Marlin/src/HAL/HAL_LPC1768/watchdog.cpp b/Marlin/src/HAL/HAL_LPC1768/watchdog.cpp
index f122bf9984..6d0200e9f1 100644
--- a/Marlin/src/HAL/HAL_LPC1768/watchdog.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/watchdog.cpp
@@ -26,7 +26,7 @@
#if ENABLED(USE_WATCHDOG)
-#include "lpc17xx_wdt.h"
+#include
#include "watchdog.h"
void watchdog_init() {
diff --git a/Marlin/src/HAL/HAL_SAMD51/HAL.cpp b/Marlin/src/HAL/HAL_SAMD51/HAL.cpp
index 1d7521270f..1c53042f8d 100644
--- a/Marlin/src/HAL/HAL_SAMD51/HAL.cpp
+++ b/Marlin/src/HAL/HAL_SAMD51/HAL.cpp
@@ -22,8 +22,8 @@
#ifdef __SAMD51__
#include "../../inc/MarlinConfig.h"
-#include "Adafruit_ZeroDMA.h"
-#include "wiring_private.h"
+#include
+#include
// ------------------------
// Local defines
@@ -442,9 +442,11 @@ void HAL_adc_init() {
// Preloaded data (fixed for all ADC instances hence not loaded by DMA)
adc->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_AREFA_Val; // VRefA pin
SYNC(adc->SYNCBUSY.bit.REFCTRL);
- adc->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_10BIT_Val;
+ adc->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_12BIT_Val;
SYNC(adc->SYNCBUSY.bit.CTRLB);
adc->SAMPCTRL.bit.SAMPLEN = (6 - 1); // Sampling clocks
+ adc->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM_16 | ADC_AVGCTRL_ADJRES(4); // 16 Accumulated conversions and shift 4 to get oversampled 12 bits result
+ SYNC(adc->SYNCBUSY.bit.AVGCTRL);
// Registers loaded by DMA
adc->DSEQCTRL.bit.INPUTCTRL = true;
diff --git a/Marlin/src/HAL/HAL_SAMD51/HAL.h b/Marlin/src/HAL/HAL_SAMD51/HAL.h
index 3489a4d285..9551352200 100644
--- a/Marlin/src/HAL/HAL_SAMD51/HAL.h
+++ b/Marlin/src/HAL/HAL_SAMD51/HAL.h
@@ -33,11 +33,9 @@
#include "MarlinSerial_AGCM4.h"
// Serial ports
- #if !WITHIN(SERIAL_PORT, -1, 3)
- #error "SERIAL_PORT must be from -1 to 3"
- #endif
// MYSERIAL0 required before MarlinSerial includes!
+
#if SERIAL_PORT == -1
#define MYSERIAL0 Serial
#elif SERIAL_PORT == 0
@@ -46,18 +44,16 @@
#define MYSERIAL0 Serial2
#elif SERIAL_PORT == 2
#define MYSERIAL0 Serial3
- #else
+ #elif SERIAL_PORT == 3
#define MYSERIAL0 Serial4
+ #else
+ #error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#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"
- #endif
- #define NUM_SERIAL 2
- #if SERIAL_PORT_2 == -1
+ #if SERIAL_PORT_2 == SERIAL_PORT
+ #error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration."
+ #elif SERIAL_PORT_2 == -1
#define MYSERIAL1 Serial
#elif SERIAL_PORT_2 == 0
#define MYSERIAL1 Serial1
@@ -65,9 +61,12 @@
#define MYSERIAL1 Serial2
#elif SERIAL_PORT_2 == 2
#define MYSERIAL1 Serial3
- #else
+ #elif SERIAL_PORT_2 == 3
#define MYSERIAL1 Serial4
+ #else
+ #error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#endif
+ #define NUM_SERIAL 2
#else
#define NUM_SERIAL 1
#endif
@@ -109,6 +108,8 @@ extern uint16_t HAL_adc_result; // result of last ADC conversion
void HAL_adc_init();
+#define HAL_ADC_FILTERED // Disable oversampling done in Marlin as ADC values already filtered in HAL
+#define HAL_ADC_RESOLUTION 12
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
diff --git a/Marlin/src/HAL/HAL_SAMD51/inc/SanityCheck.h b/Marlin/src/HAL/HAL_SAMD51/inc/SanityCheck.h
index 0f27d8bf35..0c1e83115e 100644
--- a/Marlin/src/HAL/HAL_SAMD51/inc/SanityCheck.h
+++ b/Marlin/src/HAL/HAL_SAMD51/inc/SanityCheck.h
@@ -36,7 +36,7 @@
#endif
#if ENABLED(SDIO_SUPPORT)
- #error "SDIO_SUPPORT is not supported."
+ #error "SDIO_SUPPORT is not supported on SAMD51."
#endif
#if ENABLED(FAST_PWM_FAN)
@@ -46,3 +46,7 @@
#if ENABLED(EEPROM_SETTINGS) && NONE(SPI_EEPROM, I2C_EEPROM)
#warning "Did you activate the SmartEEPROM? See https://github.com/GMagician/SAMD51-SmartEEprom-Activator"
#endif
+
+#if TMC_HAS_SW_SERIAL
+ #error "TMC220x Software Serial is not supported on this platform."
+#endif
diff --git a/Marlin/src/HAL/HAL_SAMD51/timers.cpp b/Marlin/src/HAL/HAL_SAMD51/timers.cpp
index 63902c3c5e..2434043966 100644
--- a/Marlin/src/HAL/HAL_SAMD51/timers.cpp
+++ b/Marlin/src/HAL/HAL_SAMD51/timers.cpp
@@ -99,7 +99,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
SYNC(tc->COUNT32.SYNCBUSY.bit.CTRLB);
// Set compare value
- tc->COUNT32.COUNT.reg = tc->COUNT32.CC[0].reg = HAL_TIMER_RATE / frequency;
+ tc->COUNT32.COUNT.reg = tc->COUNT32.CC[0].reg = (HAL_TIMER_RATE) / frequency;
// And start timer
tc->COUNT32.CTRLA.bit.ENABLE = true;
diff --git a/Marlin/src/HAL/HAL_STM32/HAL.cpp b/Marlin/src/HAL/HAL_STM32/HAL.cpp
index edc161a5d3..1e9129b63f 100644
--- a/Marlin/src/HAL/HAL_STM32/HAL.cpp
+++ b/Marlin/src/HAL/HAL_STM32/HAL.cpp
@@ -28,11 +28,15 @@
#include "../../inc/MarlinConfig.h"
#include "../shared/Delay.h"
+#if TMC_HAS_SW_SERIAL
+ #include "SoftwareSerial.h"
+#endif
+
#if ENABLED(SRAM_EEPROM_EMULATION)
#if STM32F7xx
- #include "stm32f7xx_ll_pwr.h"
+ #include
#elif STM32F4xx
- #include "stm32f4xx_ll_pwr.h"
+ #include
#else
#error "SRAM_EEPROM_EMULATION is currently only supported for STM32F4xx and STM32F7xx"
#endif
@@ -82,6 +86,10 @@ void HAL_init() {
// Wait until backup regulator is initialized
while (!LL_PWR_IsActiveFlag_BRR());
#endif // EEPROM_EMULATED_SRAM
+
+ #if TMC_HAS_SW_SERIAL
+ SoftwareSerial::setInterruptPriority(SWSERIAL_TIMER_IRQ_PRIO, 0);
+ #endif
}
void HAL_clear_reset_source() { __HAL_RCC_CLEAR_RESET_FLAGS(); }
diff --git a/Marlin/src/HAL/HAL_STM32/HAL.h b/Marlin/src/HAL/HAL_STM32/HAL.h
index dae75d42f2..b27e5c6d62 100644
--- a/Marlin/src/HAL/HAL_STM32/HAL.h
+++ b/Marlin/src/HAL/HAL_STM32/HAL.h
@@ -44,13 +44,8 @@
// ------------------------
#if SERIAL_PORT == 0
- #error "Serial port 0 does not exist"
-#endif
-
-#if !WITHIN(SERIAL_PORT, -1, 6)
- #error "SERIAL_PORT must be from -1 to 6"
-#endif
-#if SERIAL_PORT == -1
+ #error "SERIAL_PORT cannot be 0. (Port 0 does not exist.) Please update your configuration."
+#elif SERIAL_PORT == -1
#define MYSERIAL0 SerialUSB
#elif SERIAL_PORT == 1
#define MYSERIAL0 Serial1
@@ -64,20 +59,17 @@
#define MYSERIAL0 Serial5
#elif SERIAL_PORT == 6
#define MYSERIAL0 Serial6
+#else
+ #error "SERIAL_PORT must be from -1 to 6. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
- #if SERIAL_PORT_2 == 0
- #error "Serial port 0 does not exist"
- #endif
-
- #if !WITHIN(SERIAL_PORT_2, -1, 6)
- #error "SERIAL_PORT_2 must be from -1 to 6"
- #elif SERIAL_PORT_2 == SERIAL_PORT
- #error "SERIAL_PORT_2 must be different than SERIAL_PORT"
- #endif
#define NUM_SERIAL 2
- #if SERIAL_PORT_2 == -1
+ #if SERIAL_PORT_2 == 0
+ #error "SERIAL_PORT_2 cannot be 0. (Port 0 does not exist.) Please update your configuration."
+ #elif SERIAL_PORT_2 == SERIAL_PORT
+ #error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration."
+ #elif SERIAL_PORT_2 == -1
#define MYSERIAL1 SerialUSB
#elif SERIAL_PORT_2 == 1
#define MYSERIAL1 Serial1
@@ -91,6 +83,8 @@
#define MYSERIAL1 Serial5
#elif SERIAL_PORT_2 == 6
#define MYSERIAL1 Serial6
+ #else
+ #error "SERIAL_PORT_2 must be from -1 to 6. Please update your configuration."
#endif
#else
#define NUM_SERIAL 1
@@ -188,6 +182,7 @@ void eeprom_update_block(const void *__src, void *__dst, size_t __n);
inline void HAL_adc_init() {}
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
+#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
diff --git a/Marlin/src/HAL/HAL_STM32/HAL_SPI.cpp b/Marlin/src/HAL/HAL_STM32/HAL_SPI.cpp
index 45bd26d720..82cae9b75c 100644
--- a/Marlin/src/HAL/HAL_STM32/HAL_SPI.cpp
+++ b/Marlin/src/HAL/HAL_STM32/HAL_SPI.cpp
@@ -83,6 +83,13 @@ void spiInit(uint8_t spiRate) {
}
spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0);
+ #if ENABLED(CUSTOM_SPI_PINS)
+ SPI.setMISO(MISO_PIN);
+ SPI.setMOSI(MOSI_PIN);
+ SPI.setSCLK(SCK_PIN);
+ SPI.setSSEL(SS_PIN);
+ #endif
+
SPI.begin();
}
diff --git a/Marlin/src/HAL/HAL_STM32/Servo.cpp b/Marlin/src/HAL/HAL_STM32/Servo.cpp
index 2882f071ac..9af8ba6184 100644
--- a/Marlin/src/HAL/HAL_STM32/Servo.cpp
+++ b/Marlin/src/HAL/HAL_STM32/Servo.cpp
@@ -28,25 +28,30 @@
#include "Servo.h"
-uint8_t servoPin[MAX_SERVOS] = { 0 };
+static uint_fast8_t servoCount = 0;
+constexpr millis_t servoDelay[] = SERVO_DELAY;
+static_assert(COUNT(servoDelay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long.");
+
+libServo::libServo()
+: delay(servoDelay[servoCount++])
+{}
int8_t libServo::attach(const int pin) {
- if (servoIndex >= MAX_SERVOS) return -1;
- if (pin > 0) servoPin[servoIndex] = pin;
- return super::attach(servoPin[servoIndex]);
+ if (servoCount >= MAX_SERVOS) return -1;
+ if (pin > 0) servo_pin = pin;
+ return super::attach(servo_pin);
}
int8_t libServo::attach(const int pin, const int min, const int max) {
- if (pin > 0) servoPin[servoIndex] = pin;
- return super::attach(servoPin[servoIndex], min, max);
+ if (servoCount >= MAX_SERVOS) return -1;
+ if (pin > 0) servo_pin = pin;
+ return super::attach(servo_pin, min, max);
}
void libServo::move(const int value) {
- constexpr uint16_t servo_delay[] = SERVO_DELAY;
- static_assert(COUNT(servo_delay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long.");
if (attach(0) >= 0) {
write(value);
- safe_delay(servo_delay[servoIndex]);
+ safe_delay(delay);
#if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE)
detach();
#endif
diff --git a/Marlin/src/HAL/HAL_STM32/Servo.h b/Marlin/src/HAL/HAL_STM32/Servo.h
index 592f3a0662..ec4b6be131 100644
--- a/Marlin/src/HAL/HAL_STM32/Servo.h
+++ b/Marlin/src/HAL/HAL_STM32/Servo.h
@@ -27,11 +27,13 @@
// Inherit and expand on the official library
class libServo : public Servo {
public:
+ libServo();
int8_t attach(const int pin);
int8_t attach(const int pin, const int min, const int max);
void move(const int value);
private:
typedef Servo super;
- uint16_t min_ticks, max_ticks;
- uint8_t servoIndex; // index into the channel data for this servo
+
+ int servo_pin = 0;
+ millis_t delay = 0;
};
diff --git a/Marlin/src/HAL/HAL_STM32/SoftwareSerial.cpp b/Marlin/src/HAL/HAL_STM32/SoftwareSerial.cpp
new file mode 100644
index 0000000000..f6363aa1cf
--- /dev/null
+++ b/Marlin/src/HAL/HAL_STM32/SoftwareSerial.cpp
@@ -0,0 +1,395 @@
+/*
+ * SoftwareSerial.cpp (formerly NewSoftSerial.cpp)
+ *
+ * Multi-instance software serial library for Arduino/Wiring
+ * -- Interrupt-driven receive and other improvements by ladyada
+ * (http://ladyada.net)
+ * -- Tuning, circular buffer, derivation from class Print/Stream,
+ * multi-instance support, porting to 8MHz processors,
+ * various optimizations, PROGMEM delay tables, inverse logic and
+ * direct port writing by Mikal Hart (http://www.arduiniana.org)
+ * -- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
+ * -- 20MHz processor support by Garrett Mace (http://www.macetech.com)
+ * -- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)
+ * -- STM32 support by Armin van der Togt
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * The latest version of this library can always be found at
+ * http://arduiniana.org.
+ */
+
+//
+// Includes
+//
+#if defined(PLATFORMIO) && defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
+
+#include "SoftwareSerial.h"
+#include "timers.h"
+
+#define OVERSAMPLE 3 // in RX, Timer will generate interruption OVERSAMPLE time during a bit. Thus OVERSAMPLE ticks in a bit. (interrupt not synchonized with edge).
+
+// defined in bit-periods
+#define HALFDUPLEX_SWITCH_DELAY 5
+// It's best to define TIMER_SERIAL in variant.h. If not defined, we choose one here
+// The order is based on (lack of) features and compare channels, we choose the simplest available
+// because we only need an update interrupt
+#if !defined(TIMER_SERIAL)
+#if defined (TIM18_BASE)
+#define TIMER_SERIAL TIM18
+#elif defined (TIM7_BASE)
+#define TIMER_SERIAL TIM7
+#elif defined (TIM6_BASE)
+#define TIMER_SERIAL TIM6
+#elif defined (TIM22_BASE)
+#define TIMER_SERIAL TIM22
+#elif defined (TIM21_BASE)
+#define TIMER_SERIAL TIM21
+#elif defined (TIM17_BASE)
+#define TIMER_SERIAL TIM17
+#elif defined (TIM16_BASE)
+#define TIMER_SERIAL TIM16
+#elif defined (TIM15_BASE)
+#define TIMER_SERIAL TIM15
+#elif defined (TIM14_BASE)
+#define TIMER_SERIAL TIM14
+#elif defined (TIM13_BASE)
+#define TIMER_SERIAL TIM13
+#elif defined (TIM11_BASE)
+#define TIMER_SERIAL TIM11
+#elif defined (TIM10_BASE)
+#define TIMER_SERIAL TIM10
+#elif defined (TIM12_BASE)
+#define TIMER_SERIAL TIM12
+#elif defined (TIM19_BASE)
+#define TIMER_SERIAL TIM19
+#elif defined (TIM9_BASE)
+#define TIMER_SERIAL TIM9
+#elif defined (TIM5_BASE)
+#define TIMER_SERIAL TIM5
+#elif defined (TIM4_BASE)
+#define TIMER_SERIAL TIM4
+#elif defined (TIM3_BASE)
+#define TIMER_SERIAL TIM3
+#elif defined (TIM2_BASE)
+#define TIMER_SERIAL TIM2
+#elif defined (TIM20_BASE)
+#define TIMER_SERIAL TIM20
+#elif defined (TIM8_BASE)
+#define TIMER_SERIAL TIM8
+#elif defined (TIM1_BASE)
+#define TIMER_SERIAL TIM1
+#else
+#error No suitable timer found for SoftwareSerial, define TIMER_SERIAL in variant.h
+#endif
+#endif
+//
+// Statics
+//
+HardwareTimer SoftwareSerial::timer(TIMER_SERIAL);
+const IRQn_Type SoftwareSerial::timer_interrupt_number = static_cast(getTimerUpIrq(TIMER_SERIAL));
+uint32_t SoftwareSerial::timer_interrupt_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), TIM_IRQ_PRIO, TIM_IRQ_SUBPRIO);
+SoftwareSerial *SoftwareSerial::active_listener = nullptr;
+SoftwareSerial *volatile SoftwareSerial::active_out = nullptr;
+SoftwareSerial *volatile SoftwareSerial::active_in = nullptr;
+int32_t SoftwareSerial::tx_tick_cnt = 0; // OVERSAMPLE ticks needed for a bit
+int32_t volatile SoftwareSerial::rx_tick_cnt = 0; // OVERSAMPLE ticks needed for a bit
+uint32_t SoftwareSerial::tx_buffer = 0;
+int32_t SoftwareSerial::tx_bit_cnt = 0;
+uint32_t SoftwareSerial::rx_buffer = 0;
+int32_t SoftwareSerial::rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit
+uint32_t SoftwareSerial::cur_speed = 0;
+
+void SoftwareSerial::setInterruptPriority(uint32_t preemptPriority, uint32_t subPriority) {
+ timer_interrupt_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), preemptPriority, subPriority);
+}
+
+//
+// Private methods
+//
+
+void SoftwareSerial::setSpeed(uint32_t speed) {
+ if (speed != cur_speed) {
+ timer.pause();
+ if (speed != 0) {
+ // Disable the timer
+ uint32_t clock_rate, cmp_value;
+ // Get timer clock
+ clock_rate = timer.getTimerClkFreq();
+ int pre = 1;
+ // Calculate prescale an compare value
+ do {
+ cmp_value = clock_rate / (speed * OVERSAMPLE);
+ if (cmp_value >= UINT16_MAX) {
+ clock_rate /= 2;
+ pre *= 2;
+ }
+ } while (cmp_value >= UINT16_MAX);
+ timer.setPrescaleFactor(pre);
+ timer.setOverflow(cmp_value);
+ timer.setCount(0);
+ timer.attachInterrupt(&handleInterrupt);
+ timer.resume();
+ NVIC_SetPriority(timer_interrupt_number, timer_interrupt_priority);
+ }
+ else
+ timer.detachInterrupt();
+ cur_speed = speed;
+ }
+}
+
+// This function sets the current object as the "listening"
+// one and returns true if it replaces another
+bool SoftwareSerial::listen() {
+ if (active_listener != this) {
+ // wait for any transmit to complete as we may change speed
+ while (active_out);
+ active_listener->stopListening();
+ rx_tick_cnt = 1; // 1 : next interrupt will decrease rx_tick_cnt to 0 which means RX pin level will be considered.
+ rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit
+ setSpeed(_speed);
+ active_listener = this;
+ if (!_half_duplex) active_in = this;
+ return true;
+ }
+ return false;
+}
+
+// Stop listening. Returns true if we were actually listening.
+bool SoftwareSerial::stopListening() {
+ if (active_listener == this) {
+ // wait for any output to complete
+ while (active_out);
+ if (_half_duplex) setRXTX(false);
+ active_listener = nullptr;
+ active_in = nullptr;
+ // turn off ints
+ setSpeed(0);
+ return true;
+ }
+ return false;
+}
+
+inline void SoftwareSerial::setTX() {
+ if (_inverse_logic)
+ LL_GPIO_ResetOutputPin(_transmitPinPort, _transmitPinNumber);
+ else
+ LL_GPIO_SetOutputPin(_transmitPinPort, _transmitPinNumber);
+ pinMode(_transmitPin, OUTPUT);
+}
+
+inline void SoftwareSerial::setRX() {
+ pinMode(_receivePin, _inverse_logic ? INPUT_PULLDOWN : INPUT_PULLUP); // pullup for normal logic!
+}
+
+inline void SoftwareSerial::setRXTX(bool input) {
+ if (_half_duplex) {
+ if (input) {
+ if (active_in != this) {
+ setRX();
+ rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit
+ rx_tick_cnt = 2; // 2 : next interrupt will be discarded. 2 interrupts required to consider RX pin level
+ active_in = this;
+ }
+ }
+ else {
+ if (active_in == this) {
+ setTX();
+ active_in = nullptr;
+ }
+ }
+ }
+}
+
+inline void SoftwareSerial::send() {
+ if (--tx_tick_cnt <= 0) { // if tx_tick_cnt > 0 interrupt is discarded. Only when tx_tick_cnt reaches 0 is TX pin set.
+ if (tx_bit_cnt++ < 10) { // tx_bit_cnt < 10 transmission is not finished (10 = 1 start +8 bits + 1 stop)
+ // Send data (including start and stop bits)
+ if (tx_buffer & 1)
+ LL_GPIO_SetOutputPin(_transmitPinPort, _transmitPinNumber);
+ else
+ LL_GPIO_ResetOutputPin(_transmitPinPort, _transmitPinNumber);
+ tx_buffer >>= 1;
+ tx_tick_cnt = OVERSAMPLE; // Wait OVERSAMPLE ticks to send next bit
+ }
+ else { // Transmission finished
+ tx_tick_cnt = 1;
+ if (_output_pending) {
+ active_out = nullptr;
+
+ // In half-duplex mode wait HALFDUPLEX_SWITCH_DELAY bit-periods after the byte has
+ // been transmitted before allowing the switch to RX mode
+ }
+ else if (tx_bit_cnt > 10 + OVERSAMPLE * HALFDUPLEX_SWITCH_DELAY) {
+ if (_half_duplex && active_listener == this) setRXTX(true);
+ active_out = nullptr;
+ }
+ }
+ }
+}
+
+//
+// The receive routine called by the interrupt handler
+//
+inline void SoftwareSerial::recv() {
+ if (--rx_tick_cnt <= 0) { // if rx_tick_cnt > 0 interrupt is discarded. Only when rx_tick_cnt reaches 0 is RX pin considered
+ bool inbit = LL_GPIO_IsInputPinSet(_receivePinPort, _receivePinNumber) ^ _inverse_logic;
+ if (rx_bit_cnt == -1) { // rx_bit_cnt = -1 : waiting for start bit
+ if (!inbit) {
+ // got start bit
+ rx_bit_cnt = 0; // rx_bit_cnt == 0 : start bit received
+ rx_tick_cnt = OVERSAMPLE + 1; // Wait 1 bit (OVERSAMPLE ticks) + 1 tick in order to sample RX pin in the middle of the edge (and not too close to the edge)
+ rx_buffer = 0;
+ }
+ else
+ rx_tick_cnt = 1; // Waiting for start bit, but wrong level. Wait for next Interrupt to check RX pin level
+ }
+ else if (rx_bit_cnt >= 8) { // rx_bit_cnt >= 8 : waiting for stop bit
+ if (inbit) {
+ // Stop-bit read complete. Add to buffer.
+ uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
+ if (next != _receive_buffer_head) {
+ // save new data in buffer: tail points to byte destination
+ _receive_buffer[_receive_buffer_tail] = rx_buffer; // save new byte
+ _receive_buffer_tail = next;
+ }
+ else // rx_bit_cnt = x with x = [0..7] correspond to new bit x received
+ _buffer_overflow = true;
+ }
+ // Full trame received. Restart waiting for start bit at next interrupt
+ rx_tick_cnt = 1;
+ rx_bit_cnt = -1;
+ }
+ else {
+ // data bits
+ rx_buffer >>= 1;
+ if (inbit) rx_buffer |= 0x80;
+ rx_bit_cnt++; // Prepare for next bit
+ rx_tick_cnt = OVERSAMPLE; // Wait OVERSAMPLE ticks before sampling next bit
+ }
+ }
+}
+
+//
+// Interrupt handling
+//
+
+/* static */
+inline void SoftwareSerial::handleInterrupt(HardwareTimer*) {
+ if (active_in) active_in->recv();
+ if (active_out) active_out->send();
+}
+
+//
+// Constructor
+//
+SoftwareSerial::SoftwareSerial(uint16_t receivePin, uint16_t transmitPin, bool inverse_logic /* = false */) :
+ _receivePin(receivePin),
+ _transmitPin(transmitPin),
+ _receivePinPort(digitalPinToPort(receivePin)),
+ _receivePinNumber(STM_LL_GPIO_PIN(digitalPinToPinName(receivePin))),
+ _transmitPinPort(digitalPinToPort(transmitPin)),
+ _transmitPinNumber(STM_LL_GPIO_PIN(digitalPinToPinName(transmitPin))),
+ _speed(0),
+ _buffer_overflow(false),
+ _inverse_logic(inverse_logic),
+ _half_duplex(receivePin == transmitPin),
+ _output_pending(0),
+ _receive_buffer_tail(0),
+ _receive_buffer_head(0)
+{
+ if ((receivePin < NUM_DIGITAL_PINS) || (transmitPin < NUM_DIGITAL_PINS)) {
+ /* Enable GPIO clock for tx and rx pin*/
+ set_GPIO_Port_Clock(STM_PORT(digitalPinToPinName(transmitPin)));
+ set_GPIO_Port_Clock(STM_PORT(digitalPinToPinName(receivePin)));
+ }
+ else
+ _Error_Handler("ERROR: invalid pin number\n", -1);
+}
+
+//
+// Destructor
+//
+SoftwareSerial::~SoftwareSerial() { end(); }
+
+//
+// Public methods
+//
+
+void SoftwareSerial::begin(long speed) {
+ #ifdef FORCE_BAUD_RATE
+ speed = FORCE_BAUD_RATE;
+ #endif
+ _speed = speed;
+ if (!_half_duplex) {
+ setTX();
+ setRX();
+ listen();
+ }
+ else
+ setTX();
+}
+
+void SoftwareSerial::end() {
+ stopListening();
+}
+
+// Read data from buffer
+int SoftwareSerial::read() {
+ // Empty buffer?
+ if (_receive_buffer_head == _receive_buffer_tail) return -1;
+
+ // Read from "head"
+ uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
+ _receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF;
+ return d;
+}
+
+int SoftwareSerial::available() {
+ return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF;
+}
+
+size_t SoftwareSerial::write(uint8_t b) {
+ // wait for previous transmit to complete
+ _output_pending = 1;
+ while (active_out) { /* nada */ }
+ // add start and stop bits.
+ tx_buffer = b << 1 | 0x200;
+ if (_inverse_logic) tx_buffer = ~tx_buffer;
+ tx_bit_cnt = 0;
+ tx_tick_cnt = OVERSAMPLE;
+ setSpeed(_speed);
+ if (_half_duplex) setRXTX(false);
+ _output_pending = 0;
+ // make us active
+ active_out = this;
+ return 1;
+}
+
+void SoftwareSerial::flush() {
+ noInterrupts();
+ _receive_buffer_head = _receive_buffer_tail = 0;
+ interrupts();
+}
+
+int SoftwareSerial::peek() {
+ // Empty buffer?
+ if (_receive_buffer_head == _receive_buffer_tail) return -1;
+
+ // Read from "head"
+ return _receive_buffer[_receive_buffer_head];
+}
+
+#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
diff --git a/Marlin/src/HAL/HAL_STM32/SoftwareSerial.h b/Marlin/src/HAL/HAL_STM32/SoftwareSerial.h
new file mode 100644
index 0000000000..3799701cfe
--- /dev/null
+++ b/Marlin/src/HAL/HAL_STM32/SoftwareSerial.h
@@ -0,0 +1,119 @@
+/**
+ * SoftwareSerial.h (formerly NewSoftSerial.h)
+ *
+ * Multi-instance software serial library for Arduino/Wiring
+ * -- Interrupt-driven receive and other improvements by ladyada
+ * (http://ladyada.net)
+ * -- Tuning, circular buffer, derivation from class Print/Stream,
+ * multi-instance support, porting to 8MHz processors,
+ * various optimizations, PROGMEM delay tables, inverse logic and
+ * direct port writing by Mikal Hart (http://www.arduiniana.org)
+ * -- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
+ * -- 20MHz processor support by Garrett Mace (http://www.macetech.com)
+ * -- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * The latest version of this library can always be found at
+ * http://arduiniana.org.
+ */
+
+#ifndef SOFTWARESERIAL_H
+#define SOFTWARESERIAL_H
+
+#include
+
+/******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+#define _SS_MAX_RX_BUFF 64 // RX buffer size
+
+class SoftwareSerial : public Stream {
+ private:
+ // per object data
+ uint16_t _receivePin;
+ uint16_t _transmitPin;
+ GPIO_TypeDef *_receivePinPort;
+ uint32_t _receivePinNumber;
+ GPIO_TypeDef *_transmitPinPort;
+ uint32_t _transmitPinNumber;
+ uint32_t _speed;
+
+ uint16_t _buffer_overflow: 1;
+ uint16_t _inverse_logic: 1;
+ uint16_t _half_duplex: 1;
+ uint16_t _output_pending: 1;
+
+ unsigned char _receive_buffer[_SS_MAX_RX_BUFF];
+ volatile uint8_t _receive_buffer_tail;
+ volatile uint8_t _receive_buffer_head;
+
+ uint32_t delta_start = 0;
+
+ // static data
+ static bool initialised;
+ static HardwareTimer timer;
+ static const IRQn_Type timer_interrupt_number;
+ static uint32_t timer_interrupt_priority;
+ static SoftwareSerial *active_listener;
+ static SoftwareSerial *volatile active_out;
+ static SoftwareSerial *volatile active_in;
+ static int32_t tx_tick_cnt;
+ static volatile int32_t rx_tick_cnt;
+ static uint32_t tx_buffer;
+ static int32_t tx_bit_cnt;
+ static uint32_t rx_buffer;
+ static int32_t rx_bit_cnt;
+ static uint32_t cur_speed;
+
+ // private methods
+ void send();
+ void recv();
+ void setTX();
+ void setRX();
+ void setSpeed(uint32_t speed);
+ void setRXTX(bool input);
+ static void handleInterrupt(HardwareTimer *timer);
+
+ public:
+ // public methods
+
+ SoftwareSerial(uint16_t receivePin, uint16_t transmitPin, bool inverse_logic = false);
+ virtual ~SoftwareSerial();
+ void begin(long speed);
+ bool listen();
+ void end();
+ bool isListening() { return active_listener == this; }
+ bool stopListening();
+ bool overflow() {
+ bool ret = _buffer_overflow;
+ if (ret) _buffer_overflow = false;
+ return ret;
+ }
+ int peek();
+
+ virtual size_t write(uint8_t byte);
+ virtual int read();
+ virtual int available();
+ virtual void flush();
+ operator bool() { return true; }
+
+ static void setInterruptPriority(uint32_t preemptPriority, uint32_t subPriority);
+
+ using Print::write;
+};
+
+#endif // SOFTWARESERIAL_H
diff --git a/Marlin/src/HAL/HAL_STM32/persistent_store_flash.cpp b/Marlin/src/HAL/HAL_STM32/persistent_store_flash.cpp
new file mode 100644
index 0000000000..0242b78aeb
--- /dev/null
+++ b/Marlin/src/HAL/HAL_STM32/persistent_store_flash.cpp
@@ -0,0 +1,265 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
+ * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
+ * Copyright (c) 2016 Victor Perez victor_pv@hotmail.com
+ *
+ * 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 .
+ *
+ */
+
+#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
+
+#include "../../inc/MarlinConfig.h"
+
+#if BOTH(EEPROM_SETTINGS, FLASH_EEPROM_EMULATION)
+
+#include "../shared/persistent_store_api.h"
+
+
+// Only STM32F4 can support wear leveling at this time
+#ifndef STM32F4xx
+ #undef FLASH_EEPROM_LEVELING
+#endif
+
+/**
+ * The STM32 HAL supports chips that deal with "pages" and some with "sectors" and some that
+ * even have multiple "banks" of flash.
+ *
+ * This code is a bit of a mashup of
+ * framework-arduinoststm32/cores/arduino/stm32/stm32_eeprom.c
+ * hal/hal_lpc1768/persistent_store_flash.cpp
+ *
+ * This has only be written against those that use a single "sector" design.
+ *
+ * Those that deal with "pages" could be made to work. Looking at the STM32F07 for example, there are
+ * 128 "pages", each 2kB in size. If we continued with our EEPROM being 4Kb, we'd always need to operate
+ * on 2 of these pages. Each write, we'd use 2 different pages from a pool of pages until we are done.
+ */
+
+#if ENABLED(FLASH_EEPROM_LEVELING)
+
+ #include "stm32_def.h"
+
+ #define DEBUG_OUT ENABLED(EEPROM_CHITCHAT)
+ #include "src/core/debug_out.h"
+
+ #ifndef EEPROM_SIZE
+ #define EEPROM_SIZE 0x1000 // 4kB
+ #endif
+
+ #ifndef FLASH_SECTOR
+ #define FLASH_SECTOR (FLASH_SECTOR_TOTAL - 1)
+ #endif
+ #ifndef FLASH_UNIT_SIZE
+ #define FLASH_UNIT_SIZE 0x20000 // 128kB
+ #endif
+
+ #define FLASH_ADDRESS_START (FLASH_END - ((FLASH_SECTOR_TOTAL - FLASH_SECTOR) * FLASH_UNIT_SIZE) + 1)
+ #define FLASH_ADDRESS_END (FLASH_ADDRESS_START + FLASH_UNIT_SIZE - 1)
+
+ #define EEPROM_SLOTS (FLASH_UNIT_SIZE/EEPROM_SIZE)
+ #define SLOT_ADDRESS(slot) (FLASH_ADDRESS_START + (slot * EEPROM_SIZE))
+
+ #define UNLOCK_FLASH() if (!flash_unlocked) { \
+ HAL_FLASH_Unlock(); \
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | \
+ FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR); \
+ flash_unlocked = true; \
+ }
+ #define LOCK_FLASH() if (flash_unlocked) { HAL_FLASH_Lock(); flash_unlocked = false; }
+
+ #define EMPTY_UINT32 ((uint32_t)-1)
+ #define EMPTY_UINT8 ((uint8_t)-1)
+
+ static uint8_t ram_eeprom[EEPROM_SIZE] __attribute__((aligned(4))) = {0};
+ static int current_slot = -1;
+
+ static_assert(0 == EEPROM_SIZE % 4, "EEPROM_SIZE must be a multiple of 4"); // Ensure copying as uint32_t is safe
+ static_assert(0 == FLASH_UNIT_SIZE % EEPROM_SIZE, "EEPROM_SIZE must divide evenly into your FLASH_UNIT_SIZE");
+ static_assert(FLASH_UNIT_SIZE >= EEPROM_SIZE, "FLASH_UNIT_SIZE must be greater than or equal to your EEPROM_SIZE");
+ static_assert(IS_FLASH_SECTOR(FLASH_SECTOR), "FLASH_SECTOR is invalid");
+ static_assert(IS_POWER_OF_2(FLASH_UNIT_SIZE), "FLASH_UNIT_SIZE should be a power of 2, please check your chip's spec sheet");
+
+#endif
+
+static bool eeprom_data_written = false;
+
+bool PersistentStore::access_start() {
+
+ #if ENABLED(FLASH_EEPROM_LEVELING)
+
+ if (current_slot == -1 || eeprom_data_written) {
+ // This must be the first time since power on that we have accessed the storage, or someone
+ // loaded and called write_data and never called access_finish.
+ // Lets go looking for the slot that holds our configuration.
+ if (eeprom_data_written) DEBUG_ECHOLN("Dangling EEPROM write_data");
+ uint32_t address = FLASH_ADDRESS_START;
+ while (address <= FLASH_ADDRESS_END) {
+ uint32_t address_value = (*(__IO uint32_t*)address);
+ if (address_value != EMPTY_UINT32) {
+ current_slot = (address - FLASH_ADDRESS_START) / EEPROM_SIZE;
+ break;
+ }
+ address += sizeof(uint32_t);
+ }
+ if (current_slot == -1) {
+ // We didn't find anything, so we'll just intialize to empty
+ for (int i = 0; i < EEPROM_SIZE; i++) ram_eeprom[i] = EMPTY_UINT8;
+ current_slot = EEPROM_SLOTS;
+ }
+ else {
+ // load current settings
+ uint8_t *eeprom_data = (uint8_t *)SLOT_ADDRESS(current_slot);
+ for (int i = 0; i < EEPROM_SIZE; i++) ram_eeprom[i] = eeprom_data[i];
+ DEBUG_ECHOLNPAIR("EEPROM loaded from slot ", current_slot, ".");
+ }
+ eeprom_data_written = false;
+ }
+
+ #else
+ eeprom_buffer_fill();
+ #endif
+
+ return true;
+}
+
+bool PersistentStore::access_finish() {
+
+ if (eeprom_data_written) {
+
+ #if ENABLED(FLASH_EEPROM_LEVELING)
+
+ HAL_StatusTypeDef status = HAL_ERROR;
+ bool flash_unlocked = false;
+
+ if (--current_slot < 0) {
+ // all slots have been used, erase everything and start again
+
+ FLASH_EraseInitTypeDef EraseInitStruct;
+ uint32_t SectorError = 0;
+
+ EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
+ EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
+ EraseInitStruct.Sector = FLASH_SECTOR;
+ EraseInitStruct.NbSectors = 1;
+
+ current_slot = EEPROM_SLOTS - 1;
+ UNLOCK_FLASH();
+
+ status = HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);
+ if (status != HAL_OK) {
+ DEBUG_ECHOLNPAIR("HAL_FLASHEx_Erase=", status);
+ DEBUG_ECHOLNPAIR("GetError=", HAL_FLASH_GetError());
+ DEBUG_ECHOLNPAIR("SectorError=", SectorError);
+ LOCK_FLASH();
+ return false;
+ }
+ }
+
+ UNLOCK_FLASH();
+
+ uint32_t offset = 0;
+ uint32_t address = SLOT_ADDRESS(current_slot);
+ uint32_t address_end = address + EEPROM_SIZE;
+ uint32_t data = 0;
+
+ bool success = true;
+
+ while (address < address_end) {
+ memcpy(&data, ram_eeprom + offset, sizeof(uint32_t));
+ status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data);
+ if (status == HAL_OK) {
+ address += sizeof(uint32_t);
+ offset += sizeof(uint32_t);
+ }
+ else {
+ DEBUG_ECHOLNPAIR("HAL_FLASH_Program=", status);
+ DEBUG_ECHOLNPAIR("GetError=", HAL_FLASH_GetError());
+ DEBUG_ECHOLNPAIR("address=", address);
+ success = false;
+ break;
+ }
+ }
+
+ LOCK_FLASH();
+
+ if (success) {
+ eeprom_data_written = false;
+ DEBUG_ECHOLNPAIR("EEPROM saved to slot ", current_slot, ".");
+ }
+
+ return success;
+
+ #else
+ eeprom_buffer_flush();
+ eeprom_data_written = false;
+ #endif
+ }
+
+ return true;
+}
+
+bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
+ while (size--) {
+ uint8_t v = *value;
+ #if ENABLED(FLASH_EEPROM_LEVELING)
+ if (v != ram_eeprom[pos]) {
+ ram_eeprom[pos] = v;
+ eeprom_data_written = true;
+ }
+ #else
+ if (v != eeprom_buffered_read_byte(pos)) {
+ eeprom_buffered_write_byte(pos, v);
+ eeprom_data_written = true;
+ }
+ #endif
+ crc16(crc, &v, 1);
+ pos++;
+ value++;
+ }
+ return false;
+}
+
+bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+ do {
+ const uint8_t c = (
+ #if ENABLED(FLASH_EEPROM_LEVELING)
+ ram_eeprom[pos]
+ #else
+ eeprom_buffered_read_byte(pos)
+ #endif
+ );
+ if (writing) *value = c;
+ crc16(crc, &c, 1);
+ pos++;
+ value++;
+ } while (--size);
+ return false;
+}
+
+size_t PersistentStore::capacity() {
+ return (
+ #if ENABLED(FLASH_EEPROM_LEVELING)
+ EEPROM_SIZE
+ #else
+ E2END + 1
+ #endif
+ );
+}
+
+#endif // EEPROM_SETTINGS && FLASH_EEPROM_EMULATION
+#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
diff --git a/Marlin/src/HAL/HAL_STM32/persistent_store_impl.cpp b/Marlin/src/HAL/HAL_STM32/persistent_store_impl.cpp
index c94bce3b65..44f01cb88f 100644
--- a/Marlin/src/HAL/HAL_STM32/persistent_store_impl.cpp
+++ b/Marlin/src/HAL/HAL_STM32/persistent_store_impl.cpp
@@ -24,29 +24,15 @@
#include "../../inc/MarlinConfig.h"
-#if ENABLED(EEPROM_SETTINGS) && ANY(FLASH_EEPROM_EMULATION, SRAM_EEPROM_EMULATION, SPI_EEPROM, I2C_EEPROM)
+#if ENABLED(EEPROM_SETTINGS) && ANY(SRAM_EEPROM_EMULATION, SPI_EEPROM, I2C_EEPROM)
#include "../shared/persistent_store_api.h"
-#if ENABLED(FLASH_EEPROM_EMULATION)
- #include
- static bool eeprom_data_written = false;
-#endif
-
bool PersistentStore::access_start() {
- #if ENABLED(FLASH_EEPROM_EMULATION)
- eeprom_buffer_fill();
- #endif
return true;
}
bool PersistentStore::access_finish() {
- #if ENABLED(FLASH_EEPROM_EMULATION)
- if (eeprom_data_written) {
- eeprom_buffer_flush();
- eeprom_data_written = false;
- }
- #endif
return true;
}
@@ -66,8 +52,6 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return true;
}
}
- #elif ENABLED(FLASH_EEPROM_EMULATION)
- eeprom_buffered_write_byte(pos, v);
#else
*(__IO uint8_t *)(BKPSRAM_BASE + (uint8_t * const)pos) = v;
#endif
@@ -76,9 +60,6 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
pos++;
value++;
};
- #if ENABLED(FLASH_EEPROM_EMULATION)
- eeprom_data_written = true;
- #endif
return false;
}
@@ -89,8 +70,6 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t
const uint8_t c = (
#if EITHER(SPI_EEPROM, I2C_EEPROM)
eeprom_read_byte((uint8_t*)pos)
- #elif ENABLED(FLASH_EEPROM_EMULATION)
- eeprom_buffered_read_byte(pos)
#else
(*(__IO uint8_t *)(BKPSRAM_BASE + ((uint8_t*)pos)))
#endif
@@ -114,5 +93,5 @@ size_t PersistentStore::capacity() {
);
}
-#endif // EEPROM_SETTINGS && (FLASH_EEPROM_EMULATION || SRAM_EEPROM_EMULATION || SPI_EEPROM || I2C_EEPROM)
+#endif // EEPROM_SETTINGS && (SRAM_EEPROM_EMULATION || SPI_EEPROM || I2C_EEPROM)
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
diff --git a/Marlin/src/HAL/HAL_STM32/timers.cpp b/Marlin/src/HAL/HAL_STM32/timers.cpp
index 51f84e657f..c2a4cbdc0e 100644
--- a/Marlin/src/HAL/HAL_STM32/timers.cpp
+++ b/Marlin/src/HAL/HAL_STM32/timers.cpp
@@ -32,62 +32,108 @@
#define NUM_HARDWARE_TIMERS 2
+#define __TIMER_DEV(X) TIM##X
+#define _TIMER_DEV(X) __TIMER_DEV(X)
+#define STEP_TIMER_DEV _TIMER_DEV(STEP_TIMER)
+#define TEMP_TIMER_DEV _TIMER_DEV(TEMP_TIMER)
+
// ------------------------
// Private Variables
// ------------------------
-stm32_timer_t TimerHandle[NUM_HARDWARE_TIMERS];
+HardwareTimer *timer_instance[NUM_HARDWARE_TIMERS] = { NULL };
+bool timer_enabled[NUM_HARDWARE_TIMERS] = { false };
// ------------------------
// Public functions
// ------------------------
-bool timers_initialized[NUM_HARDWARE_TIMERS] = { false };
-
+// frequency is in Hertz
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
+ if (!HAL_timer_initialized(timer_num)) {
+ switch (timer_num) {
+ case STEP_TIMER_NUM: // STEPPER TIMER - use a 32bit timer if possible
+ timer_instance[timer_num] = new HardwareTimer(STEP_TIMER_DEV);
+ /* Set the prescaler to the final desired value.
+ * This will change the effective ISR callback frequency but when
+ * HAL_timer_start(timer_num=0) is called in the core for the first time
+ * the real frequency isn't important as long as, after boot, the ISR
+ * gets called with the correct prescaler and count register. So here
+ * we set the prescaler to the correct, final value and ignore the frequency
+ * asked. We will call back the ISR in 1 second to start at full speed.
+ *
+ * The proper fix, however, would be a correct initialization OR a
+ * HAL_timer_change(const uint8_t timer_num, const uint32_t frequency)
+ * which changes the prescaler when an IRQ frequency change is needed
+ * (for example when steppers are turned on)
+ */
+ timer_instance[timer_num]->setPrescaleFactor(STEPPER_TIMER_PRESCALE); //the -1 is done internally
+ timer_instance[timer_num]->setOverflow(_MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE) /* /frequency */), TICK_FORMAT);
+ break;
+ case TEMP_TIMER_NUM: // TEMP TIMER - any available 16bit timer
+ timer_instance[timer_num] = new HardwareTimer(TEMP_TIMER_DEV);
+ // The prescale factor is computed automatically for HERTZ_FORMAT
+ timer_instance[timer_num]->setOverflow(frequency, HERTZ_FORMAT);
+ break;
+ }
- if (!timers_initialized[timer_num]) {
- uint32_t step_prescaler = STEPPER_TIMER_PRESCALE - 1,
- temp_prescaler = TEMP_TIMER_PRESCALE - 1;
+ HAL_timer_enable_interrupt(timer_num);
+
+ /*
+ * Initializes (and unfortunately starts) the timer.
+ * This is needed to set correct IRQ priority at the moment but causes
+ * no harm since every call to HAL_timer_start() is actually followed by
+ * a call to HAL_timer_enable_interrupt() which means that there isn't
+ * a case in which you want the timer to run without a callback.
+ */
+ timer_instance[timer_num]->resume(); // First call to resume() MUST follow the attachInterrupt()
+
+ // This is fixed in Arduino_Core_STM32 1.8.
+ // These calls can be removed and replaced with
+ // timer_instance[timer_num]->setInterruptPriority
switch (timer_num) {
case STEP_TIMER_NUM:
- // STEPPER TIMER - use a 32bit timer if possible
- TimerHandle[timer_num].timer = STEP_TIMER_DEV;
- TimerHandle[timer_num].irqHandle = Step_Handler;
- TimerHandleInit(&TimerHandle[timer_num], (((HAL_TIMER_RATE) / step_prescaler) / frequency) - 1, step_prescaler);
HAL_NVIC_SetPriority(STEP_TIMER_IRQ_NAME, STEP_TIMER_IRQ_PRIO, 0);
break;
-
case TEMP_TIMER_NUM:
- // TEMP TIMER - any available 16bit Timer
- TimerHandle[timer_num].timer = TEMP_TIMER_DEV;
- TimerHandle[timer_num].irqHandle = Temp_Handler;
- TimerHandleInit(&TimerHandle[timer_num], (((HAL_TIMER_RATE) / temp_prescaler) / frequency) - 1, temp_prescaler);
HAL_NVIC_SetPriority(TEMP_TIMER_IRQ_NAME, TEMP_TIMER_IRQ_PRIO, 0);
break;
}
- timers_initialized[timer_num] = true;
}
}
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
- const IRQn_Type IRQ_Id = IRQn_Type(getTimerIrq(TimerHandle[timer_num].timer));
- HAL_NVIC_EnableIRQ(IRQ_Id);
+ if (HAL_timer_initialized(timer_num) && !timer_enabled[timer_num]) {
+ timer_enabled[timer_num] = true;
+ switch (timer_num) {
+ case STEP_TIMER_NUM:
+ timer_instance[timer_num]->attachInterrupt(Step_Handler);
+ break;
+ case TEMP_TIMER_NUM:
+ timer_instance[timer_num]->attachInterrupt(Temp_Handler);
+ break;
+ }
+ }
}
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
- const IRQn_Type IRQ_Id = IRQn_Type(getTimerIrq(TimerHandle[timer_num].timer));
- HAL_NVIC_DisableIRQ(IRQ_Id);
-
- // We NEED memory barriers to ensure Interrupts are actually disabled!
- // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
- __DSB();
- __ISB();
+ if (HAL_timer_interrupt_enabled(timer_num)) {
+ timer_instance[timer_num]->detachInterrupt();
+ timer_enabled[timer_num] = false;
+ }
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
- const uint32_t IRQ_Id = getTimerIrq(TimerHandle[timer_num].timer);
- return NVIC->ISER[IRQ_Id >> 5] & _BV32(IRQ_Id & 0x1F);
+ return HAL_timer_initialized(timer_num) && timer_enabled[timer_num];
+}
+
+// Only for use within the HAL
+TIM_TypeDef * HAL_timer_device(const uint8_t timer_num) {
+ switch (timer_num) {
+ case STEP_TIMER_NUM: return STEP_TIMER_DEV;
+ case TEMP_TIMER_NUM: return TEMP_TIMER_DEV;
+ }
+ return nullptr;
}
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
diff --git a/Marlin/src/HAL/HAL_STM32/timers.h b/Marlin/src/HAL/HAL_STM32/timers.h
index aefe880b4e..1d2c095f2b 100644
--- a/Marlin/src/HAL/HAL_STM32/timers.h
+++ b/Marlin/src/HAL/HAL_STM32/timers.h
@@ -33,6 +33,7 @@
#define hal_timer_t uint32_t
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF // Timers can be 16 or 32 bit
+
#ifdef STM32F0xx
#define HAL_TIMER_RATE (F_CPU) // frequency of timer peripherals
@@ -66,27 +67,30 @@
#endif
#ifndef TEMP_TIMER
- #define TEMP_TIMER 7
+ #define TEMP_TIMER 14 // TIM7 is consumed by Software Serial if used.
#endif
#endif
+#ifndef SWSERIAL_TIMER_IRQ_PRIO
+ #define SWSERIAL_TIMER_IRQ_PRIO 1
+#endif
+
#ifndef STEP_TIMER_IRQ_PRIO
- #define STEP_TIMER_IRQ_PRIO 1
+ #define STEP_TIMER_IRQ_PRIO 2
#endif
#ifndef TEMP_TIMER_IRQ_PRIO
- #define TEMP_TIMER_IRQ_PRIO 2
+ #define TEMP_TIMER_IRQ_PRIO 14 //14 = after hardware ISRs
#endif
#define STEP_TIMER_NUM 0 // index of timer to use for stepper
#define TEMP_TIMER_NUM 1 // index of timer to use for temperature
#define PULSE_TIMER_NUM STEP_TIMER_NUM
-#define TEMP_TIMER_RATE 72000 // 72 Khz
-#define TEMP_TIMER_PRESCALE ((HAL_TIMER_RATE)/(TEMP_TIMER_RATE))
-#define TEMP_TIMER_FREQUENCY 1000
+#define TEMP_TIMER_FREQUENCY 1000 //Temperature::isr() is expected to be called at around 1kHz
+//TODO: get rid of manual rate/prescale/ticks/cycles taken for procedures in stepper.cpp
#define STEPPER_TIMER_RATE 2000000 // 2 Mhz
#define STEPPER_TIMER_PRESCALE ((HAL_TIMER_RATE)/(STEPPER_TIMER_RATE))
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
@@ -95,17 +99,6 @@
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
-#define __TIMER_DEV(X) TIM##X
-#define _TIMER_DEV(X) __TIMER_DEV(X)
-#define STEP_TIMER_DEV _TIMER_DEV(STEP_TIMER)
-#define TEMP_TIMER_DEV _TIMER_DEV(TEMP_TIMER)
-
-#define __TIMER_CALLBACK(X) TIM##X##_IRQHandler
-#define _TIMER_CALLBACK(X) __TIMER_CALLBACK(X)
-
-#define STEP_TIMER_CALLBACK _TIMER_CALLBACK(STEP_TIMER)
-#define TEMP_TIMER_CALLBACK _TIMER_CALLBACK(TEMP_TIMER)
-
#define __TIMER_IRQ_NAME(X) TIM##X##_IRQn
#define _TIMER_IRQ_NAME(X) __TIMER_IRQ_NAME(X)
@@ -119,22 +112,16 @@
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
-extern void Step_Handler(stimer_t *htim);
-extern void Temp_Handler(stimer_t *htim);
-#define HAL_STEP_TIMER_ISR() void Step_Handler(stimer_t *htim)
-#define HAL_TEMP_TIMER_ISR() void Temp_Handler(stimer_t *htim)
-
-// ------------------------
-// Types
-// ------------------------
-
-typedef stimer_t stm32_timer_t;
+extern void Step_Handler(HardwareTimer *htim);
+extern void Temp_Handler(HardwareTimer *htim);
+#define HAL_STEP_TIMER_ISR() void Step_Handler(HardwareTimer *htim)
+#define HAL_TEMP_TIMER_ISR() void Temp_Handler(HardwareTimer *htim)
// ------------------------
// Public Variables
// ------------------------
-extern stm32_timer_t TimerHandle[];
+extern HardwareTimer *timer_instance[];
// ------------------------
// Public functions
@@ -145,18 +132,26 @@ void HAL_timer_enable_interrupt(const uint8_t timer_num);
void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
-FORCE_INLINE static uint32_t HAL_timer_get_count(const uint8_t timer_num) {
- return __HAL_TIM_GET_COUNTER(&TimerHandle[timer_num].handle);
+//TIM_TypeDef* HAL_timer_device(const uint8_t timer_num); no need to be public for now. not public = not used externally
+
+// FORCE_INLINE because these are used in performance-critical situations
+FORCE_INLINE bool HAL_timer_initialized(const uint8_t timer_num) {
+ return timer_instance[timer_num] != NULL;
+}
+FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
+ return HAL_timer_initialized(timer_num) ? timer_instance[timer_num]->getCount() : 0;
}
-FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const uint32_t compare) {
- __HAL_TIM_SET_AUTORELOAD(&TimerHandle[timer_num].handle, compare);
- if (HAL_timer_get_count(timer_num) >= compare)
- TimerHandle[timer_num].handle.Instance->EGR |= TIM_EGR_UG; // Generate an immediate update interrupt
-}
-
-FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
- return __HAL_TIM_GET_AUTORELOAD(&TimerHandle[timer_num].handle);
+// NOTE: Method name may be misleading.
+// STM32 has an Auto-Reload Register (ARR) as opposed to a "compare" register
+FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t overflow) {
+ if (HAL_timer_initialized(timer_num)) {
+ timer_instance[timer_num]->setOverflow(overflow + 1, TICK_FORMAT); // Value decremented by setOverflow()
+ // wiki: "force all registers (Autoreload, prescaler, compare) to be taken into account"
+ // So, if the new overflow value is less than the count it will trigger a rollover interrupt.
+ if (overflow < timer_instance[timer_num]->getCount()) // Added 'if' here because reports say it won't boot without it
+ timer_instance[timer_num]->refresh();
+ }
}
#define HAL_timer_isr_prologue(TIMER_NUM)
diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL.cpp b/Marlin/src/HAL/HAL_STM32F1/HAL.cpp
index 802a489101..9dcb77ae4f 100644
--- a/Marlin/src/HAL/HAL_STM32F1/HAL.cpp
+++ b/Marlin/src/HAL/HAL_STM32F1/HAL.cpp
@@ -27,8 +27,8 @@
#ifdef __STM32F1__
-#include "HAL.h"
#include "../../inc/MarlinConfig.h"
+#include "HAL.h"
#include
@@ -121,6 +121,9 @@ const uint8_t adc_pins[] = {
#if ENABLED(FILAMENT_WIDTH_SENSOR)
FILWIDTH_PIN,
#endif
+ #if ENABLED(ADC_KEYPAD)
+ ADC_KEYPAD_PIN,
+ #endif
#if HAS_JOY_ADC_X
JOY_X_PIN,
#endif
@@ -160,6 +163,9 @@ enum TEMP_PINS : char {
#if ENABLED(FILAMENT_WIDTH_SENSOR)
FILWIDTH,
#endif
+ #if ENABLED(ADC_KEYPAD)
+ ADC_KEY,
+ #endif
#if HAS_JOY_ADC_X
JOY_X,
#endif
@@ -272,7 +278,7 @@ extern "C" {
// return free memory between end of heap (or end bss) and whatever is current
/*
-#include "wirish/syscalls.c"
+#include
//extern caddr_t _sbrk(int incr);
#ifndef CONFIG_HEAP_END
extern char _lm_heap_end;
@@ -352,6 +358,9 @@ void HAL_adc_start_conversion(const uint8_t adc_pin) {
#if ENABLED(FILAMENT_WIDTH_SENSOR)
case FILWIDTH_PIN: pin_index = FILWIDTH; break;
#endif
+ #if ENABLED(ADC_KEYPAD)
+ case ADC_KEYPAD_PIN: pin_index = ADC_KEY; break;
+ #endif
}
HAL_adc_result = (HAL_adc_results[(int)pin_index] >> 2) & 0x3FF; // shift to get 10 bits only.
}
diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL.h b/Marlin/src/HAL/HAL_STM32F1/HAL.h
index f1017c82df..fea5ff86e8 100644
--- a/Marlin/src/HAL/HAL_STM32F1/HAL.h
+++ b/Marlin/src/HAL/HAL_STM32F1/HAL.h
@@ -51,6 +51,14 @@
// Defines
// ------------------------
+#ifndef STM32_FLASH_SIZE
+ #ifdef MCU_STM32F103RE
+ #define STM32_FLASH_SIZE 512
+ #else
+ #define STM32_FLASH_SIZE 256
+ #endif
+#endif
+
#ifdef SERIAL_USB
#ifndef USE_USB_COMPOSITE
#define UsbSerial Serial
@@ -70,13 +78,10 @@
#define MSerial5 Serial4
#endif
-#if !WITHIN(SERIAL_PORT, -1, 5)
- #error "SERIAL_PORT must be from -1 to 5"
-#endif
-#if SERIAL_PORT == -1
+#if SERIAL_PORT == 0
+ #error "SERIAL_PORT cannot be 0. (Port 0 does not exist.) Please update your configuration."
+#elif SERIAL_PORT == -1
#define MYSERIAL0 UsbSerial
-#elif SERIAL_PORT == 0
- #error "Serial port 0 does not exist"
#elif SERIAL_PORT == 1
#define MYSERIAL0 MSerial1
#elif SERIAL_PORT == 2
@@ -87,19 +92,17 @@
#define MYSERIAL0 MSerial4
#elif SERIAL_PORT == 5
#define MYSERIAL0 MSerial5
+#else
+ #error "SERIAL_PORT must be from -1 to 5. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
- #if !WITHIN(SERIAL_PORT_2, -1, 5)
- #error "SERIAL_PORT_2 must be from -1 to 5"
+ #if SERIAL_PORT_2 == 0
+ #error "SERIAL_PORT_2 cannot be 0. (Port 0 does not exist.) Please update your configuration."
#elif SERIAL_PORT_2 == SERIAL_PORT
- #error "SERIAL_PORT_2 must be different than SERIAL_PORT"
- #endif
- #define NUM_SERIAL 2
- #if SERIAL_PORT_2 == -1
+ #error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration."
+ #elif SERIAL_PORT_2 == -1
#define MYSERIAL1 UsbSerial
- #elif SERIAL_PORT_2 == 0
- #error "Serial port 0 does not exist"
#elif SERIAL_PORT_2 == 1
#define MYSERIAL1 MSerial1
#elif SERIAL_PORT_2 == 2
@@ -110,7 +113,10 @@
#define MYSERIAL1 MSerial4
#elif SERIAL_PORT_2 == 5
#define MYSERIAL1 MSerial5
+ #else
+ #error "SERIAL_PORT_2 must be from -1 to 5. Please update your configuration."
#endif
+ #define NUM_SERIAL 2
#else
#define NUM_SERIAL 1
#endif
@@ -238,6 +244,7 @@ void eeprom_update_block(const void *__src, void *__dst, size_t __n);
void HAL_adc_init();
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
+#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
diff --git a/Marlin/src/HAL/HAL_STM32F1/SPI.cpp b/Marlin/src/HAL/HAL_STM32F1/SPI.cpp
index 101b42a53a..8eb8f9aa88 100644
--- a/Marlin/src/HAL/HAL_STM32F1/SPI.cpp
+++ b/Marlin/src/HAL/HAL_STM32F1/SPI.cpp
@@ -53,7 +53,7 @@ static const spi_pins* dev_to_spi_pins(spi_dev *dev);
static void configure_gpios(spi_dev *dev, bool as_master);
static spi_baud_rate determine_baud_rate(spi_dev *dev, uint32_t freq);
-#if (BOARD_NR_SPI >= 3) && !defined(STM32_HIGH_DENSITY)
+#if BOARD_NR_SPI >= 3 && !defined(STM32_HIGH_DENSITY)
#error "The SPI library is misconfigured: 3 SPI ports only available on high density STM32 devices"
#endif
diff --git a/Marlin/src/HAL/HAL_STM32F1/SoftwareSerial.h b/Marlin/src/HAL/HAL_STM32F1/SoftwareSerial.h
index 0692b7e9f3..330d7d632d 100644
--- a/Marlin/src/HAL/HAL_STM32F1/SoftwareSerial.h
+++ b/Marlin/src/HAL/HAL_STM32F1/SoftwareSerial.h
@@ -20,7 +20,9 @@
#include
-#define SW_SERIAL_PLACEHOLDER 1
+#ifndef HAVE_SW_SERIAL
+ #define SW_SERIAL_PLACEHOLDER 1
+#endif
class SoftwareSerial {
public:
diff --git a/Marlin/src/HAL/HAL_STM32F1/build_flags.py b/Marlin/src/HAL/HAL_STM32F1/build_flags.py
old mode 100644
new mode 100755
diff --git a/Marlin/src/HAL/HAL_STM32F1/dogm/u8g_com_stm32duino_fsmc.cpp b/Marlin/src/HAL/HAL_STM32F1/dogm/u8g_com_stm32duino_fsmc.cpp
index 9d569772fa..a16b379b30 100644
--- a/Marlin/src/HAL/HAL_STM32F1/dogm/u8g_com_stm32duino_fsmc.cpp
+++ b/Marlin/src/HAL/HAL_STM32F1/dogm/u8g_com_stm32duino_fsmc.cpp
@@ -49,6 +49,7 @@
void LCD_IO_Init(uint8_t cs, uint8_t rs);
void LCD_IO_WriteData(uint16_t RegValue);
void LCD_IO_WriteReg(uint16_t Reg);
+uint16_t LCD_IO_ReadData(uint16_t RegValue);
uint32_t LCD_IO_ReadData(uint16_t RegValue, uint8_t ReadSize);
#ifdef LCD_USE_DMA_FSMC
void LCD_IO_WriteMultiple(uint16_t data, uint32_t count);
@@ -79,8 +80,11 @@ uint8_t u8g_com_stm32duino_fsmc_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, voi
LCD_IO_Init(u8g->pin_list[U8G_PI_CS], u8g->pin_list[U8G_PI_A0]);
u8g_Delay(50);
- if (arg_ptr)
- *((uint32_t *)arg_ptr) = LCD_IO_ReadData(LCD_READ_ID, 3);
+ if (arg_ptr) {
+ *((uint32_t *)arg_ptr) = LCD_IO_ReadData(0x0000);
+ if (*((uint32_t *)arg_ptr) == 0)
+ *((uint32_t *)arg_ptr) = (LCD_READ_ID << 24) | LCD_IO_ReadData(LCD_READ_ID, 3);
+ }
isCommand = 0;
break;
@@ -265,6 +269,13 @@ void LCD_IO_WriteReg(uint16_t Reg) {
__DSB();
}
+uint16_t LCD_IO_ReadData(uint16_t RegValue) {
+ LCD->REG = RegValue;
+ __DSB();
+
+ return LCD->RAM;
+}
+
uint32_t LCD_IO_ReadData(uint16_t RegValue, uint8_t ReadSize) {
volatile uint32_t data;
LCD->REG = RegValue;
diff --git a/Marlin/src/HAL/HAL_STM32F1/fastio.h b/Marlin/src/HAL/HAL_STM32F1/fastio.h
index 463d951c1e..3aafb9de39 100644
--- a/Marlin/src/HAL/HAL_STM32F1/fastio.h
+++ b/Marlin/src/HAL/HAL_STM32F1/fastio.h
@@ -29,32 +29,33 @@
#include
-#define READ(IO) (PIN_MAP[IO].gpio_device->regs->IDR & (1U << PIN_MAP[IO].gpio_bit) ? HIGH : LOW)
-#define WRITE(IO,V) (PIN_MAP[IO].gpio_device->regs->BSRR = (1U << PIN_MAP[IO].gpio_bit) << ((V) ? 0 : 16))
-#define TOGGLE(IO) (PIN_MAP[IO].gpio_device->regs->ODR = PIN_MAP[IO].gpio_device->regs->ODR ^ (1U << PIN_MAP[IO].gpio_bit))
+#define READ(IO) (PIN_MAP[IO].gpio_device->regs->IDR & (1U << PIN_MAP[IO].gpio_bit) ? HIGH : LOW)
+#define WRITE(IO,V) (PIN_MAP[IO].gpio_device->regs->BSRR = (1U << PIN_MAP[IO].gpio_bit) << ((V) ? 0 : 16))
+#define TOGGLE(IO) (PIN_MAP[IO].gpio_device->regs->ODR = PIN_MAP[IO].gpio_device->regs->ODR ^ (1U << PIN_MAP[IO].gpio_bit))
-#define _GET_MODE(IO) gpio_get_mode(PIN_MAP[IO].gpio_device, PIN_MAP[IO].gpio_bit)
-#define _SET_MODE(IO,M) gpio_set_mode(PIN_MAP[IO].gpio_device, PIN_MAP[IO].gpio_bit, M)
-#define _SET_OUTPUT(IO) _SET_MODE(IO, GPIO_OUTPUT_PP)
-#define _SET_OUTPUT_OD(IO) _SET_MODE(IO, GPIO_OUTPUT_OD)
+#define _GET_MODE(IO) gpio_get_mode(PIN_MAP[IO].gpio_device, PIN_MAP[IO].gpio_bit)
+#define _SET_MODE(IO,M) gpio_set_mode(PIN_MAP[IO].gpio_device, PIN_MAP[IO].gpio_bit, M)
+#define _SET_OUTPUT(IO) _SET_MODE(IO, GPIO_OUTPUT_PP)
+#define _SET_OUTPUT_OD(IO) _SET_MODE(IO, GPIO_OUTPUT_OD)
-#define OUT_WRITE(IO,V) do{ _SET_OUTPUT(IO); WRITE(IO,V); }while(0)
-#define OUT_WRITE_OD(IO,V) do{ _SET_OUTPUT_OD(IO); WRITE(IO,V); }while(0)
+#define OUT_WRITE(IO,V) do{ _SET_OUTPUT(IO); WRITE(IO,V); }while(0)
+#define OUT_WRITE_OD(IO,V) do{ _SET_OUTPUT_OD(IO); WRITE(IO,V); }while(0)
-#define SET_INPUT(IO) _SET_MODE(IO, GPIO_INPUT_FLOATING)
-#define SET_INPUT_PULLUP(IO) _SET_MODE(IO, GPIO_INPUT_PU)
-#define SET_OUTPUT(IO) OUT_WRITE(IO, LOW)
-#define SET_PWM(IO) pinMode(IO, PWM) // do{ gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, GPIO_AF_OUTPUT_PP); timer_set_mode(PIN_MAP[pin].timer_device, PIN_MAP[pin].timer_channel, TIMER_PWM); }while(0)
-#define SET_PWM_OD(IO) pinMode(IO, PWM_OPEN_DRAIN)
+#define SET_INPUT(IO) _SET_MODE(IO, GPIO_INPUT_FLOATING)
+#define SET_INPUT_PULLUP(IO) _SET_MODE(IO, GPIO_INPUT_PU)
+#define SET_INPUT_PULLDOWN(IO) _SET_MODE(IO, GPIO_INPUT_PD)
+#define SET_OUTPUT(IO) OUT_WRITE(IO, LOW)
+#define SET_PWM(IO) pinMode(IO, PWM) // do{ gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, GPIO_AF_OUTPUT_PP); timer_set_mode(PIN_MAP[pin].timer_device, PIN_MAP[pin].timer_channel, TIMER_PWM); }while(0)
+#define SET_PWM_OD(IO) pinMode(IO, PWM_OPEN_DRAIN)
-#define IS_INPUT(IO) (_GET_MODE(IO) == GPIO_INPUT_FLOATING || _GET_MODE(IO) == GPIO_INPUT_ANALOG || _GET_MODE(IO) == GPIO_INPUT_PU || _GET_MODE(IO) == GPIO_INPUT_PD)
-#define IS_OUTPUT(IO) (_GET_MODE(IO) == GPIO_OUTPUT_PP || _GET_MODE(IO) == GPIO_OUTPUT_OD)
+#define IS_INPUT(IO) (_GET_MODE(IO) == GPIO_INPUT_FLOATING || _GET_MODE(IO) == GPIO_INPUT_ANALOG || _GET_MODE(IO) == GPIO_INPUT_PU || _GET_MODE(IO) == GPIO_INPUT_PD)
+#define IS_OUTPUT(IO) (_GET_MODE(IO) == GPIO_OUTPUT_PP || _GET_MODE(IO) == GPIO_OUTPUT_OD)
-#define PWM_PIN(IO) (PIN_MAP[IO].timer_device != nullptr)
+#define PWM_PIN(IO) (PIN_MAP[IO].timer_device != nullptr)
// digitalRead/Write wrappers
-#define extDigitalRead(IO) digitalRead(IO)
-#define extDigitalWrite(IO,V) digitalWrite(IO,V)
+#define extDigitalRead(IO) digitalRead(IO)
+#define extDigitalWrite(IO,V) digitalWrite(IO,V)
//
// Pins Definitions
diff --git a/Marlin/src/HAL/HAL_STM32F1/inc/SanityCheck.h b/Marlin/src/HAL/HAL_STM32F1/inc/SanityCheck.h
index f356c0da07..7673d8673a 100644
--- a/Marlin/src/HAL/HAL_STM32F1/inc/SanityCheck.h
+++ b/Marlin/src/HAL/HAL_STM32F1/inc/SanityCheck.h
@@ -36,3 +36,8 @@
#if ENABLED(FAST_PWM_FAN)
#error "FAST_PWM_FAN is not yet implemented for this platform."
#endif
+
+#if !defined(HAVE_SW_SERIAL) && TMC_HAS_SW_SERIAL
+ #warning "With TMC2208/9 consider using SoftwareSerialM with HAVE_SW_SERIAL and appropriate SS_TIMER."
+ #error "Missing SoftwareSerial implementation."
+#endif
diff --git a/Marlin/src/HAL/HAL_STM32F1/onboard_sd.cpp b/Marlin/src/HAL/HAL_STM32F1/onboard_sd.cpp
index 6e9432896d..c5b4f34cd2 100644
--- a/Marlin/src/HAL/HAL_STM32F1/onboard_sd.cpp
+++ b/Marlin/src/HAL/HAL_STM32F1/onboard_sd.cpp
@@ -36,8 +36,8 @@
#define SPI_CLOCK_MAX SPI_BAUD_PCLK_DIV_2
#endif
-#define CS_LOW() {WRITE(ONBOARD_SD_CS_PIN, LOW);} /* Set OnBoardSPI cs low */
-#define CS_HIGH() {WRITE(ONBOARD_SD_CS_PIN, HIGH);} /* Set OnBoardSPI cs high */
+#define CS_LOW() WRITE(ONBOARD_SD_CS_PIN, LOW) /* Set OnBoardSPI cs low */
+#define CS_HIGH() WRITE(ONBOARD_SD_CS_PIN, HIGH) /* Set OnBoardSPI cs high */
#define FCLK_FAST() ONBOARD_SD_SPI.setClockDivider(SPI_CLOCK_MAX)
#define FCLK_SLOW() ONBOARD_SD_SPI.setClockDivider(SPI_BAUD_PCLK_DIV_256)
diff --git a/Marlin/src/HAL/HAL_STM32F1/persistent_store_flash.cpp b/Marlin/src/HAL/HAL_STM32F1/persistent_store_flash.cpp
index 8097a28487..bbca1cb391 100644
--- a/Marlin/src/HAL/HAL_STM32F1/persistent_store_flash.cpp
+++ b/Marlin/src/HAL/HAL_STM32F1/persistent_store_flash.cpp
@@ -40,53 +40,73 @@
#include
// Store settings in the last two pages
-// Flash pages must be erased before writing, so keep track.
-bool firstWrite = false;
+#define EEPROM_SIZE (EEPROM_PAGE_SIZE * 2)
+#define ACCESS_FINISHED(TF) do{ FLASH_Lock(); eeprom_dirty = false; return TF; }while(0)
+
+static uint8_t ram_eeprom[EEPROM_SIZE] __attribute__((aligned(4))) = {0};
+static bool eeprom_dirty = false;
bool PersistentStore::access_start() {
- firstWrite = true;
+ const uint32_t* source = reinterpret_cast(EEPROM_PAGE0_BASE);
+ uint32_t* destination = reinterpret_cast(ram_eeprom);
+
+ static_assert(0 == EEPROM_SIZE % 4, "EEPROM_SIZE is corrupted. (Must be a multiple of 4.)"); // Ensure copying as uint32_t is safe
+ constexpr size_t eeprom_size_u32 = EEPROM_SIZE / 4;
+
+ for (size_t i = 0; i < eeprom_size_u32; ++i, ++destination, ++source)
+ *destination = *source;
+
+ eeprom_dirty = false;
return true;
}
bool PersistentStore::access_finish() {
- FLASH_Lock();
- firstWrite = false;
+
+ if (eeprom_dirty) {
+ FLASH_Status status;
+
+ // Instead of erasing all (both) pages, maybe in the loop we check what page we are in, and if the
+ // data has changed in that page. We then erase the first time we "detect" a change. In theory, if
+ // nothing changed in a page, we wouldn't need to erase/write it.
+ // Or, instead of checking at this point, turn eeprom_dirty into an array of bool the size of number
+ // of pages. Inside write_data, we set the flag to true at that time if something in that
+ // page changes...either way, something to look at later.
+ FLASH_Unlock();
+
+ status = FLASH_ErasePage(EEPROM_PAGE0_BASE);
+ if (status != FLASH_COMPLETE) ACCESS_FINISHED(true);
+ status = FLASH_ErasePage(EEPROM_PAGE1_BASE);
+ if (status != FLASH_COMPLETE) ACCESS_FINISHED(true);
+
+ const uint16_t *source = reinterpret_cast(ram_eeprom);
+ for (size_t i = 0; i < EEPROM_SIZE; i += 2, ++source) {
+ if (FLASH_ProgramHalfWord(EEPROM_PAGE0_BASE + i, *source) != FLASH_COMPLETE)
+ ACCESS_FINISHED(false);
+ }
+
+ ACCESS_FINISHED(true);
+ }
+
return true;
}
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
- FLASH_Status status;
-
- if (firstWrite) {
- FLASH_Unlock();
- status = FLASH_ErasePage(EEPROM_PAGE0_BASE);
- if (status != FLASH_COMPLETE) return true;
- status = FLASH_ErasePage(EEPROM_PAGE1_BASE);
- if (status != FLASH_COMPLETE) return true;
- firstWrite = false;
- }
-
- for (size_t i = 0; i < size; i++) {
- if (FLASH_ProgramHalfWord(EEPROM_PAGE0_BASE + (pos + i) * 2, value[i]) != FLASH_COMPLETE)
- return true;
- }
-
+ for (size_t i = 0; i < size; ++i) ram_eeprom[pos + i] = value[i];
+ eeprom_dirty = true;
crc16(crc, value, size);
pos += size;
- return false;
+ return false; // return true for any error
}
bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uint16_t *crc, const bool writing/*=true*/) {
- for (size_t i = 0; i < size; i++) {
- uint8_t v = *(uint16_t *)(EEPROM_PAGE0_BASE + (pos + i) * 2);
- if (writing) value[i] = v;
- crc16(crc, &v, 1);
- }
+ const uint8_t * const buff = writing ? &value[0] : &ram_eeprom[pos];
+ if (writing) for (size_t i = 0; i < size; i++) value[i] = ram_eeprom[pos + i];
+ crc16(crc, buff, size);
pos += size;
- return false;
+ return false; // return true for any error
}
-size_t PersistentStore::capacity() { return size_t(E2END + 1); }
+size_t PersistentStore::capacity() { return EEPROM_SIZE; }
#endif // EEPROM_SETTINGS && EEPROM FLASH
#endif // __STM32F1__
diff --git a/Marlin/src/HAL/HAL_STM32F1/timers.cpp b/Marlin/src/HAL/HAL_STM32F1/timers.cpp
index a21dc12c12..051f0323c6 100644
--- a/Marlin/src/HAL/HAL_STM32F1/timers.cpp
+++ b/Marlin/src/HAL/HAL_STM32F1/timers.cpp
@@ -26,8 +26,8 @@
#ifdef __STM32F1__
+#include "../../inc/MarlinConfig.h"
#include "HAL.h"
-
#include "timers.h"
// ------------------------
@@ -57,7 +57,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
case 3: irq_num = NVIC_TIMER3; break;
case 4: irq_num = NVIC_TIMER4; break;
case 5: irq_num = NVIC_TIMER5; break;
- #if ENABLED(STM32_HIGH_DENSITY)
+ #ifdef STM32_HIGH_DENSITY
// 6 & 7 are basic timers, avoid them
case 8: irq_num = NVIC_TIMER8_CC; break;
#endif
@@ -82,7 +82,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
timer_set_prescaler(STEP_TIMER_DEV, (uint16_t)(STEPPER_TIMER_PRESCALE - 1));
timer_set_reload(STEP_TIMER_DEV, 0xFFFF);
timer_oc_set_mode(STEP_TIMER_DEV, STEP_TIMER_CHAN, TIMER_OC_MODE_FROZEN, TIMER_OC_NO_PRELOAD); // no output pin change
- timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, _MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (STEPPER_TIMER_RATE / frequency)));
+ timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, _MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (STEPPER_TIMER_RATE) / frequency));
timer_no_ARR_preload_ARPE(STEP_TIMER_DEV); // Need to be sure no preload on ARR register
timer_attach_interrupt(STEP_TIMER_DEV, STEP_TIMER_CHAN, stepTC_Handler);
nvic_irq_set_priority(irq_num, STEP_TIMER_IRQ_PRIO);
@@ -95,7 +95,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
timer_set_count(TEMP_TIMER_DEV, 0);
timer_set_prescaler(TEMP_TIMER_DEV, (uint16_t)(TEMP_TIMER_PRESCALE - 1));
timer_set_reload(TEMP_TIMER_DEV, 0xFFFF);
- timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, _MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), ((F_CPU / TEMP_TIMER_PRESCALE) / frequency)));
+ timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, _MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (F_CPU) / (TEMP_TIMER_PRESCALE) / frequency));
timer_attach_interrupt(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, tempTC_Handler);
nvic_irq_set_priority(irq_num, TEMP_TIMER_IRQ_PRIO);
timer_generate_update(TEMP_TIMER_DEV);
diff --git a/Marlin/src/HAL/HAL_STM32F1/timers.h b/Marlin/src/HAL/HAL_STM32F1/timers.h
index 69793f4302..d5d02a3dc6 100644
--- a/Marlin/src/HAL/HAL_STM32F1/timers.h
+++ b/Marlin/src/HAL/HAL_STM32F1/timers.h
@@ -27,6 +27,7 @@
#include
#include
+#include "../../core/boards.h"
// ------------------------
// Defines
@@ -46,6 +47,20 @@ typedef uint16_t hal_timer_t;
#define STEP_TIMER_CHAN 1 // Channel of the timer to use for compare and interrupts
#define TEMP_TIMER_CHAN 1 // Channel of the timer to use for compare and interrupts
+/**
+ * Note: Timers may be used by platforms and libraries
+ *
+ * FAN PWMs:
+ * With FAN_SOFT_PWM disabled the Temperature class uses
+ * FANx_PIN timers to generate FAN PWM signals.
+ *
+ * Speaker:
+ * When SPEAKER is enabled, one timer is allocated by maple/tone.cpp.
+ * - If BEEPER_PIN has a timer channel (and USE_PIN_TIMER is
+ * defined in tone.cpp) it uses the pin's own timer.
+ * - Otherwise it uses Timer 8 on boards with STM32_HIGH_DENSITY
+ * or Timer 4 on other boards.
+ */
#if defined(MCU_STM32F103CB) || defined(MCU_STM32F103C8)
#define STEP_TIMER_NUM 4 // For C8/CB boards, use timer 4
#else
@@ -54,7 +69,17 @@ 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(BTT_SKR_MINI_E3_V1_0, 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.
+ #ifdef STM32_HIGH_DENSITY
+ #define SERVO0_TIMER_NUM 8 // tone.cpp uses Timer 4
+ #else
+ #define SERVO0_TIMER_NUM 3 // tone.cpp uses Timer 8
+ #endif
+#else
+ #define SERVO0_TIMER_NUM 1 // SERVO0 or BLTOUCH
+#endif
#define STEP_TIMER_IRQ_PRIO 1
#define TEMP_TIMER_IRQ_PRIO 2
diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/HAL.cpp b/Marlin/src/HAL/HAL_STM32_F4_F7/HAL.cpp
index 7ed6e2c10f..e24483f642 100644
--- a/Marlin/src/HAL/HAL_STM32_F4_F7/HAL.cpp
+++ b/Marlin/src/HAL/HAL_STM32_F4_F7/HAL.cpp
@@ -64,7 +64,7 @@ extern "C" {
// return free memory between end of heap (or end bss) and whatever is current
/*
-#include "wirish/syscalls.c"
+#include
//extern caddr_t _sbrk(int incr);
#ifndef CONFIG_HEAP_END
extern char _lm_heap_end;
diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/HAL.h b/Marlin/src/HAL/HAL_STM32_F4_F7/HAL.h
index d4ca01e022..f4a581991e 100644
--- a/Marlin/src/HAL/HAL_STM32_F4_F7/HAL.h
+++ b/Marlin/src/HAL/HAL_STM32_F4_F7/HAL.h
@@ -24,16 +24,15 @@
#define CPU_32_BIT
+#include "../../inc/MarlinConfigPre.h"
+
#include "../shared/Marduino.h"
#include "../shared/math_32bit.h"
#include "../shared/HAL_SPI.h"
#include "fastio.h"
-#include "watchdog.h"
-
#include "timers.h"
-
-#include "../../inc/MarlinConfigPre.h"
+#include "watchdog.h"
#include
@@ -45,17 +44,12 @@
// Defines
// ------------------------
-//Serial override
+// Serial override
//extern HalSerial usb_serial;
#if defined(STM32F4) && SERIAL_PORT == 0
- #error "Serial port 0 does not exist"
-#endif
-
-#if !WITHIN(SERIAL_PORT, -1, 6)
- #error "SERIAL_PORT must be from -1 to 6"
-#endif
-#if SERIAL_PORT == -1
+ #error "SERIAL_PORT cannot be 0. (Port 0 does not exist.) Please update your configuration."
+#elif SERIAL_PORT == -1
#define MYSERIAL0 SerialUSB
#elif SERIAL_PORT == 1
#define MYSERIAL0 SerialUART1
@@ -69,19 +63,16 @@
#define MYSERIAL0 SerialUART5
#elif SERIAL_PORT == 6
#define MYSERIAL0 SerialUART6
+#else
+ #error "SERIAL_PORT must be from -1 to 6. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
#if defined(STM32F4) && SERIAL_PORT_2 == 0
- #error "Serial port 0 does not exist"
- #endif
- #if !WITHIN(SERIAL_PORT_2, -1, 6)
- #error "SERIAL_PORT_2 must be from -1 to 6"
+ #error "SERIAL_PORT_2 cannot be 0. (Port 0 does not exist.) Please update your configuration."
#elif SERIAL_PORT_2 == SERIAL_PORT
- #error "SERIAL_PORT_2 must be different than SERIAL_PORT"
- #endif
- #define NUM_SERIAL 2
- #if SERIAL_PORT_2 == -1
+ #error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration."
+ #elif SERIAL_PORT_2 == -1
#define MYSERIAL1 SerialUSB
#elif SERIAL_PORT_2 == 1
#define MYSERIAL1 SerialUART1
@@ -95,7 +86,10 @@
#define MYSERIAL1 SerialUART5
#elif SERIAL_PORT_2 == 6
#define MYSERIAL1 SerialUART6
+ #else
+ #error "SERIAL_PORT_2 must be from -1 to 6. Please update your configuration."
#endif
+ #define NUM_SERIAL 2
#else
#define NUM_SERIAL 1
#endif
@@ -208,6 +202,7 @@ void eeprom_update_block (const void *__src, void *__dst, size_t __n);
inline void HAL_adc_init() {}
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
+#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.cpp b/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.cpp
index 3117321ac7..b030459029 100644
--- a/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.cpp
+++ b/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.cpp
@@ -36,7 +36,7 @@
#include "TMC2660.h"
#include "../../../inc/MarlinConfig.h"
-#include "../../../Marlin.h"
+#include "../../../MarlinCore.h"
#include "../../../module/stepper/indirection.h"
#include "../../../module/printcounter.h"
#include "../../../libs/duration_t.h"
diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/inc/SanityCheck.h b/Marlin/src/HAL/HAL_STM32_F4_F7/inc/SanityCheck.h
index 7b8d29aa7d..c647ea0c03 100644
--- a/Marlin/src/HAL/HAL_STM32_F4_F7/inc/SanityCheck.h
+++ b/Marlin/src/HAL/HAL_STM32_F4_F7/inc/SanityCheck.h
@@ -35,3 +35,7 @@
#if ENABLED(FAST_PWM_FAN)
#error "FAST_PWM_FAN is not yet implemented for this platform."
#endif
+
+#if TMC_HAS_SW_SERIAL
+ #error "TMC220x Software Serial is not supported on this platform."
+#endif
diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/watchdog.cpp b/Marlin/src/HAL/HAL_STM32_F4_F7/watchdog.cpp
index e51af618c9..900d1ef6a6 100644
--- a/Marlin/src/HAL/HAL_STM32_F4_F7/watchdog.cpp
+++ b/Marlin/src/HAL/HAL_STM32_F4_F7/watchdog.cpp
@@ -38,7 +38,7 @@
//Error_Handler();
}
else {
- #if PIN_EXISTS(LED) && !ENABLED(PINS_DEBUGGING)
+ #if PIN_EXISTS(LED) && DISABLED(PINS_DEBUGGING)
TOGGLE(LED_PIN); // heartbeat indicator
#endif
}
diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/HAL.h b/Marlin/src/HAL/HAL_TEENSY31_32/HAL.h
index e2df8df86b..684afa58f4 100644
--- a/Marlin/src/HAL/HAL_TEENSY31_32/HAL.h
+++ b/Marlin/src/HAL/HAL_TEENSY31_32/HAL.h
@@ -109,6 +109,7 @@ extern "C" {
void HAL_adc_init();
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
+#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_get_result()
#define HAL_ADC_READY() true
diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/inc/SanityCheck.h b/Marlin/src/HAL/HAL_TEENSY31_32/inc/SanityCheck.h
index 389d27824e..b680a1a445 100644
--- a/Marlin/src/HAL/HAL_TEENSY31_32/inc/SanityCheck.h
+++ b/Marlin/src/HAL/HAL_TEENSY31_32/inc/SanityCheck.h
@@ -32,3 +32,7 @@
#if ENABLED(FAST_PWM_FAN)
#error "FAST_PWM_FAN is not yet implemented for this platform."
#endif
+
+#if TMC_HAS_SW_SERIAL
+ #error "TMC220x Software Serial is not supported on this platform."
+#endif
diff --git a/Marlin/src/HAL/HAL_TEENSY31_32/timers.cpp b/Marlin/src/HAL/HAL_TEENSY31_32/timers.cpp
index 1ae4bcf4f0..e4ccf33a4b 100644
--- a/Marlin/src/HAL/HAL_TEENSY31_32/timers.cpp
+++ b/Marlin/src/HAL/HAL_TEENSY31_32/timers.cpp
@@ -53,7 +53,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
FTM0_SC = 0x00; // Set this to zero before changing the modulus
FTM0_CNT = 0x0000; // Reset the count to zero
FTM0_MOD = 0xFFFF; // max modulus = 65535
- FTM0_C0V = FTM0_TIMER_RATE / frequency; // Initial FTM Channel 0 compare value
+ FTM0_C0V = (FTM0_TIMER_RATE) / frequency; // Initial FTM Channel 0 compare value
FTM0_SC = (FTM_SC_CLKS(0b1) & FTM_SC_CLKS_MASK) | (FTM_SC_PS(FTM0_TIMER_PRESCALE_BITS) & FTM_SC_PS_MASK); // Bus clock 60MHz divided by prescaler 8
FTM0_C0SC = FTM_CSC_CHIE | FTM_CSC_MSA | FTM_CSC_ELSA;
break;
@@ -62,7 +62,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
FTM1_SC = 0x00; // Set this to zero before changing the modulus
FTM1_CNT = 0x0000; // Reset the count to zero
FTM1_MOD = 0xFFFF; // max modulus = 65535
- FTM1_C0V = FTM1_TIMER_RATE / frequency; // Initial FTM Channel 0 compare value 65535
+ FTM1_C0V = (FTM1_TIMER_RATE) / frequency; // Initial FTM Channel 0 compare value 65535
FTM1_SC = (FTM_SC_CLKS(0b1) & FTM_SC_CLKS_MASK) | (FTM_SC_PS(FTM1_TIMER_PRESCALE_BITS) & FTM_SC_PS_MASK); // Bus clock 60MHz divided by prescaler 4
FTM1_C0SC = FTM_CSC_CHIE | FTM_CSC_MSA | FTM_CSC_ELSA;
break;
diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/HAL.h b/Marlin/src/HAL/HAL_TEENSY35_36/HAL.h
index 9fc4ff6633..97763bf205 100644
--- a/Marlin/src/HAL/HAL_TEENSY35_36/HAL.h
+++ b/Marlin/src/HAL/HAL_TEENSY35_36/HAL.h
@@ -115,6 +115,7 @@ extern "C" {
void HAL_adc_init();
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
+#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_get_result()
#define HAL_ADC_READY() true
diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/inc/SanityCheck.h b/Marlin/src/HAL/HAL_TEENSY35_36/inc/SanityCheck.h
index 6a126b683e..5cb2cbfc8c 100644
--- a/Marlin/src/HAL/HAL_TEENSY35_36/inc/SanityCheck.h
+++ b/Marlin/src/HAL/HAL_TEENSY35_36/inc/SanityCheck.h
@@ -32,3 +32,7 @@
#if ENABLED(FAST_PWM_FAN)
#error "FAST_PWM_FAN is not yet implemented for this platform."
#endif
+
+#if TMC_HAS_SW_SERIAL
+ #error "TMC220x Software Serial is not supported on this platform."
+#endif
diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/timers.cpp b/Marlin/src/HAL/HAL_TEENSY35_36/timers.cpp
index 6ee6118208..6bbc16dcb5 100644
--- a/Marlin/src/HAL/HAL_TEENSY35_36/timers.cpp
+++ b/Marlin/src/HAL/HAL_TEENSY35_36/timers.cpp
@@ -54,7 +54,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
FTM0_SC = 0x00; // Set this to zero before changing the modulus
FTM0_CNT = 0x0000; // Reset the count to zero
FTM0_MOD = 0xFFFF; // max modulus = 65535
- FTM0_C0V = FTM0_TIMER_RATE / frequency; // Initial FTM Channel 0 compare value
+ FTM0_C0V = (FTM0_TIMER_RATE) / frequency; // Initial FTM Channel 0 compare value
FTM0_SC = (FTM_SC_CLKS(0b1) & FTM_SC_CLKS_MASK) | (FTM_SC_PS(FTM0_TIMER_PRESCALE_BITS) & FTM_SC_PS_MASK); // Bus clock 60MHz divided by prescaler 8
FTM0_C0SC = FTM_CSC_CHIE | FTM_CSC_MSA | FTM_CSC_ELSA;
break;
@@ -63,7 +63,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
FTM1_SC = 0x00; // Set this to zero before changing the modulus
FTM1_CNT = 0x0000; // Reset the count to zero
FTM1_MOD = 0xFFFF; // max modulus = 65535
- FTM1_C0V = FTM1_TIMER_RATE / frequency; // Initial FTM Channel 0 compare value 65535
+ FTM1_C0V = (FTM1_TIMER_RATE) / frequency; // Initial FTM Channel 0 compare value 65535
FTM1_SC = (FTM_SC_CLKS(0b1) & FTM_SC_CLKS_MASK) | (FTM_SC_PS(FTM1_TIMER_PRESCALE_BITS) & FTM_SC_PS_MASK); // Bus clock 60MHz divided by prescaler 4
FTM1_C0SC = FTM_CSC_CHIE | FTM_CSC_MSA | FTM_CSC_ELSA;
break;
diff --git a/Marlin/src/HAL/shared/Delay.h b/Marlin/src/HAL/shared/Delay.h
index b3f8f246fb..b1dafbb0f5 100644
--- a/Marlin/src/HAL/shared/Delay.h
+++ b/Marlin/src/HAL/shared/Delay.h
@@ -36,14 +36,15 @@
#if __CORTEX_M == 7
- // Cortex-M7 can use the cycle counter of the DWT unit
+ // Cortex-M3 through M7 can use the cycle counter of the DWT unit
// http://www.anthonyvh.com/2017/05/18/cortex_m-cycle_counter/
FORCE_INLINE static void enableCycleCounter() {
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
- // Unlock DWT.
- DWT->LAR = 0xC5ACCE55;
+ #if __CORTEX_M == 7
+ DWT->LAR = 0xC5ACCE55; // Unlock DWT on the M7
+ #endif
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
diff --git a/Marlin/src/HAL/shared/backtrace/backtrace.cpp b/Marlin/src/HAL/shared/backtrace/backtrace.cpp
index fc265615d0..7a8377f789 100644
--- a/Marlin/src/HAL/shared/backtrace/backtrace.cpp
+++ b/Marlin/src/HAL/shared/backtrace/backtrace.cpp
@@ -20,10 +20,9 @@
*
*/
-#include "backtrace.h"
-
#if defined(__arm__) || defined(__thumb__)
+#include "backtrace.h"
#include "unwinder.h"
#include "unwmemaccess.h"
diff --git a/Marlin/src/HAL/shared/backtrace/unwinder.h b/Marlin/src/HAL/shared/backtrace/unwinder.h
index 604854ad0f..cae1379513 100644
--- a/Marlin/src/HAL/shared/backtrace/unwinder.h
+++ b/Marlin/src/HAL/shared/backtrace/unwinder.h
@@ -164,7 +164,7 @@ typedef struct {
* link register (i.e. not a normal register) and the stack pointer value
* supplied.
*
- * -If the program was compiled with -funwind-tables , it will use them to
+ * -If the program was compiled with -funwind-tables it will use them to
* perform the traceback. Otherwise, brute force will be employed
* -If the program was compiled with -mpoke-function-name, then you will
* get function names in the traceback. Otherwise, you will not.
diff --git a/Marlin/src/Marlin.cpp b/Marlin/src/MarlinCore.cpp
similarity index 88%
rename from Marlin/src/Marlin.cpp
rename to Marlin/src/MarlinCore.cpp
index 5e734795e9..0609e785ac 100644
--- a/Marlin/src/Marlin.cpp
+++ b/Marlin/src/MarlinCore.cpp
@@ -28,7 +28,7 @@
* - https://github.com/grbl/grbl
*/
-#include "Marlin.h"
+#include "MarlinCore.h"
#include "core/utility.h"
#include "lcd/ultralcd.h"
@@ -110,7 +110,7 @@
#include "feature/I2CPositionEncoder.h"
#endif
-#if HAS_TRINAMIC && DISABLED(PS_DEFAULT_OFF)
+#if HAS_TRINAMIC && DISABLED(PSU_DEFAULT_OFF)
#include "feature/tmc_util.h"
#endif
@@ -145,6 +145,10 @@
#include "feature/power_loss_recovery.h"
#endif
+#if ENABLED(CANCEL_OBJECTS)
+ #include "feature/cancel_object.h"
+#endif
+
#if HAS_FILAMENT_SENSOR
#include "feature/runout.h"
#endif
@@ -177,6 +181,16 @@
#include "libs/L6470/L6470_Marlin.h"
#endif
+const char NUL_STR[] PROGMEM = "",
+ G28_STR[] PROGMEM = "G28",
+ M21_STR[] PROGMEM = "M21",
+ M23_STR[] PROGMEM = "M23 %s",
+ M24_STR[] PROGMEM = "M24",
+ SP_X_STR[] PROGMEM = " X",
+ SP_Y_STR[] PROGMEM = " Y",
+ SP_Z_STR[] PROGMEM = " Z",
+ SP_E_STR[] PROGMEM = " E";
+
bool Running = true;
// For M109 and M190, this flag may be cleared (by M108) to exit the wait loop
@@ -217,10 +231,10 @@ void setup_killpin() {
void setup_powerhold() {
#if HAS_SUICIDE
- OUT_WRITE(SUICIDE_PIN, HIGH);
+ OUT_WRITE(SUICIDE_PIN, !SUICIDE_PIN_INVERTING);
#endif
- #if HAS_POWER_SWITCH
- #if ENABLED(PS_DEFAULT_OFF)
+ #if ENABLED(PSU_CONTROL)
+ #if ENABLED(PSU_DEFAULT_OFF)
powersupply_on = true; PSU_OFF();
#else
powersupply_on = false; PSU_ON();
@@ -275,6 +289,11 @@ void quickstop_stepper() {
sync_plan_position();
}
+void enable_e_steppers() {
+ #define _ENA_E(N) enable_E##N();
+ REPEAT(E_STEPPERS, _ENA_E)
+}
+
void enable_all_steppers() {
#if ENABLED(AUTO_POWER_CONTROL)
powerManager.power_on();
@@ -282,40 +301,18 @@ 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();
+ #define _DIS_E(N) disable_E##N();
+ REPEAT(E_STEPPERS, _DIS_E)
}
void disable_e_stepper(const uint8_t e) {
+ #define _CASE_DIS_E(N) case N: disable_E##N(); break;
switch (e) {
- case 0: disable_E0(); break;
- case 1: disable_E1(); break;
- case 2: disable_E2(); break;
- case 3: disable_E3(); break;
- case 4: disable_E4(); break;
- case 5: disable_E5(); break;
+ REPEAT(EXTRUDERS, _CASE_DIS_E)
}
}
@@ -339,7 +336,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
}
@@ -357,20 +354,67 @@ void disable_all_steppers() {
#endif
+#if ENABLED(ADVANCED_PAUSE_FEATURE)
+ #include "feature/pause.h"
+#else
+ constexpr bool did_pause_print = false;
+#endif
+
/**
* Printing is active when the print job timer is running
*/
bool printingIsActive() {
- return print_job_timer.isRunning() || IS_SD_PRINTING();
+ return !did_pause_print && (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();
+ return did_pause_print || print_job_timer.isPaused() || IS_SD_PAUSED();
}
+void startOrResumeJob() {
+ if (!printingIsPaused()) {
+ #if ENABLED(CANCEL_OBJECTS)
+ cancelable.reset();
+ #endif
+ #if ENABLED(LCD_SHOW_E_TOTAL)
+ e_move_accumulator = 0;
+ #endif
+ #if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME)
+ ui.reset_remaining_time();
+ #endif
+ }
+ print_job_timer.start();
+}
+
+#if ENABLED(SDSUPPORT)
+
+ void abortSDPrinting() {
+ card.stopSDPrint(
+ #if SD_RESORT
+ true
+ #endif
+ );
+ queue.clear();
+ quickstop_stepper();
+ print_job_timer.stop();
+ #if DISABLED(SD_ABORT_NO_COOLDOWN)
+ thermalManager.disable_all_heaters();
+ #endif
+ thermalManager.zero_fan_speeds();
+ wait_for_heatup = false;
+ #if ENABLED(POWER_LOSS_RECOVERY)
+ card.removeJobRecoveryFile();
+ #endif
+ #ifdef EVENT_GCODE_SD_STOP
+ queue.inject_P(PSTR(EVENT_GCODE_SD_STOP));
+ #endif
+ }
+
+#endif
+
/**
* Manage several activities:
* - Check for Filament Runout
@@ -476,7 +520,7 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) {
if (ELAPSED(ms, next_home_key_ms)) {
next_home_key_ms = ms + HOME_DEBOUNCE_DELAY;
LCD_MESSAGEPGM(MSG_AUTO_HOME);
- queue.enqueue_now_P(PSTR("G28"));
+ queue.enqueue_now_P(G28_STR);
}
}
#endif
@@ -508,24 +552,11 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) {
#else // !SWITCHING_EXTRUDER
bool oldstatus;
switch (active_extruder) {
- default: oldstatus = E0_ENABLE_READ(); enable_E0(); break;
- #if E_STEPPERS > 1
- case 1: oldstatus = E1_ENABLE_READ(); enable_E1(); break;
- #if E_STEPPERS > 2
- case 2: oldstatus = E2_ENABLE_READ(); enable_E2(); break;
- #if E_STEPPERS > 3
- case 3: oldstatus = E3_ENABLE_READ(); enable_E3(); break;
- #if E_STEPPERS > 4
- case 4: oldstatus = E4_ENABLE_READ(); enable_E4(); break;
- #if E_STEPPERS > 5
- case 5: oldstatus = E5_ENABLE_READ(); enable_E5(); break;
- #endif // E_STEPPERS > 5
- #endif // E_STEPPERS > 4
- #endif // E_STEPPERS > 3
- #endif // E_STEPPERS > 2
- #endif // E_STEPPERS > 1
+ default:
+ #define _CASE_EN(N) case N: oldstatus = E##N##_ENABLE_READ(); enable_E##N(); break;
+ REPEAT(E_STEPPERS, _CASE_EN);
}
- #endif // !SWITCHING_EXTRUDER
+ #endif
const float olde = current_position.e;
current_position.e += EXTRUDER_RUNOUT_EXTRUDE;
@@ -546,22 +577,8 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) {
}
#else // !SWITCHING_EXTRUDER
switch (active_extruder) {
- case 0: E0_ENABLE_WRITE(oldstatus); break;
- #if E_STEPPERS > 1
- case 1: E1_ENABLE_WRITE(oldstatus); break;
- #if E_STEPPERS > 2
- case 2: E2_ENABLE_WRITE(oldstatus); break;
- #if E_STEPPERS > 3
- case 3: E3_ENABLE_WRITE(oldstatus); break;
- #if E_STEPPERS > 4
- case 4: E4_ENABLE_WRITE(oldstatus); break;
- #if E_STEPPERS > 5
- case 5: E5_ENABLE_WRITE(oldstatus); break;
- #endif // E_STEPPERS > 5
- #endif // E_STEPPERS > 4
- #endif // E_STEPPERS > 3
- #endif // E_STEPPERS > 2
- #endif // E_STEPPERS > 1
+ #define _CASE_RESTORE(N) case N: E##N##_ENABLE_WRITE(oldstatus); break;
+ REPEAT(E_STEPPERS, _CASE_RESTORE);
}
#endif // !SWITCHING_EXTRUDER
@@ -584,7 +601,7 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) {
#endif
#if ENABLED(MONITOR_DRIVER_STATUS)
- monitor_tmc_driver();
+ monitor_tmc_drivers();
#endif
#if ENABLED(MONITOR_L6470_DRIVER_STATUS)
@@ -701,15 +718,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 ?: PSTR(MSG_KILLED));
+ ui.kill_screen(lcd_error ?: GET_TEXT(MSG_KILLED), lcd_component ?: NUL_STR);
#else
- UNUSED(lcd_msg);
+ UNUSED(lcd_error);
+ UNUSED(lcd_component);
#endif
#ifdef ACTION_ON_KILL
@@ -735,7 +753,7 @@ void minkill(const bool steppers_off/*=false*/) {
// Power off all steppers (for M112) or just the E steppers
steppers_off ? disable_all_steppers() : disable_e_steppers();
- #if HAS_POWER_SWITCH
+ #if ENABLED(PSU_CONTROL)
PSU_OFF();
#endif
@@ -915,8 +933,6 @@ void setup() {
#endif
ui.init();
- ui.reset_status();
-
#if HAS_SPI_LCD && ENABLED(SHOW_BOOTSCREEN)
ui.show_bootscreen();
#endif
@@ -945,6 +961,8 @@ void setup() {
print_job_timer.init(); // Initial setup of print job timer
+ ui.reset_status(); // Print startup message after print statistics are loaded
+
endstops.init(); // Init endstops and pullups
stepper.init(); // Init stepper. This enables interrupts!
@@ -1092,7 +1110,7 @@ void setup() {
host_action_prompt_end();
#endif
- #if HAS_TRINAMIC && DISABLED(PS_DEFAULT_OFF)
+ #if HAS_TRINAMIC && DISABLED(PSU_DEFAULT_OFF)
test_tmc_connection(true, true, true, true);
#endif
@@ -1110,40 +1128,22 @@ void setup() {
* - Call inactivity manager
*/
void loop() {
+ do {
- for (;;) {
-
- idle(); // Do an idle first so boot is slightly faster
+ idle();
#if ENABLED(SDSUPPORT)
-
card.checkautostart();
-
- if (card.flag.abort_sd_printing) {
- card.stopSDPrint(
- #if SD_RESORT
- true
- #endif
- );
- queue.clear();
- quickstop_stepper();
- print_job_timer.stop();
- #if DISABLED(SD_ABORT_NO_COOLDOWN)
- thermalManager.disable_all_heaters();
- #endif
- thermalManager.zero_fan_speeds();
- wait_for_heatup = false;
- #if ENABLED(POWER_LOSS_RECOVERY)
- card.removeJobRecoveryFile();
- #endif
- #ifdef EVENT_GCODE_SD_STOP
- queue.inject_P(PSTR(EVENT_GCODE_SD_STOP));
- #endif
- }
-
- #endif // SDSUPPORT
+ if (card.flag.abort_sd_printing) abortSDPrinting();
+ #endif
queue.advance();
+
endstops.event_handler();
- }
+
+ } while (false // Return to caller for best compatibility
+ #ifdef __AVR__
+ || true // Loop forever on slower (AVR) boards
+ #endif
+ );
}
diff --git a/Marlin/src/Marlin.h b/Marlin/src/MarlinCore.h
similarity index 51%
rename from Marlin/src/Marlin.h
rename to Marlin/src/MarlinCore.h
index 8b64c9a2cb..8b44298a91 100644
--- a/Marlin/src/Marlin.h
+++ b/Marlin/src/MarlinCore.h
@@ -51,96 +51,96 @@ void manage_inactivity(const bool ignore_stepper_queue=false);
//
#if AXIS_DRIVER_TYPE_X(L6470)
extern L6470 stepperX;
- #define X_enable NOOP
- #define X_disable stepperX.free()
+ #define X_enable() NOOP
+ #define X_disable() stepperX.free()
#elif HAS_X_ENABLE
- #define X_enable X_ENABLE_WRITE( X_ENABLE_ON)
- #define X_disable X_ENABLE_WRITE(!X_ENABLE_ON)
+ #define X_enable() X_ENABLE_WRITE( X_ENABLE_ON)
+ #define X_disable() X_ENABLE_WRITE(!X_ENABLE_ON)
#else
- #define X_enable NOOP
- #define X_disable NOOP
+ #define X_enable() NOOP
+ #define X_disable() NOOP
#endif
#if AXIS_DRIVER_TYPE_X2(L6470)
extern L6470 stepperX2;
- #define X2_enable NOOP
- #define X2_disable stepperX2.free()
+ #define X2_enable() NOOP
+ #define X2_disable() stepperX2.free()
#elif HAS_X2_ENABLE
- #define X2_enable X2_ENABLE_WRITE( X_ENABLE_ON)
- #define X2_disable X2_ENABLE_WRITE(!X_ENABLE_ON)
+ #define X2_enable() X2_ENABLE_WRITE( X_ENABLE_ON)
+ #define X2_disable() X2_ENABLE_WRITE(!X_ENABLE_ON)
#else
- #define X2_enable NOOP
- #define X2_disable NOOP
+ #define X2_enable() NOOP
+ #define X2_disable() NOOP
#endif
-#define enable_X() do{ X_enable; X2_enable; }while(0)
-#define disable_X() do{ X_disable; X2_disable; CBI(axis_known_position, X_AXIS); }while(0)
+#define enable_X() do{ X_enable(); X2_enable(); }while(0)
+#define disable_X() do{ X_disable(); X2_disable(); CBI(axis_known_position, X_AXIS); }while(0)
#if AXIS_DRIVER_TYPE_Y(L6470)
extern L6470 stepperY;
- #define Y_enable NOOP
- #define Y_disable stepperY.free()
+ #define Y_enable() NOOP
+ #define Y_disable() stepperY.free()
#elif HAS_Y_ENABLE
- #define Y_enable Y_ENABLE_WRITE( Y_ENABLE_ON)
- #define Y_disable Y_ENABLE_WRITE(!Y_ENABLE_ON)
+ #define Y_enable() Y_ENABLE_WRITE( Y_ENABLE_ON)
+ #define Y_disable() Y_ENABLE_WRITE(!Y_ENABLE_ON)
#else
- #define Y_enable NOOP
- #define Y_disable NOOP
+ #define Y_enable() NOOP
+ #define Y_disable() NOOP
#endif
#if AXIS_DRIVER_TYPE_Y2(L6470)
extern L6470 stepperY2;
- #define Y2_enable NOOP
- #define Y2_disable stepperY2.free()
+ #define Y2_enable() NOOP
+ #define Y2_disable() stepperY2.free()
#elif HAS_Y2_ENABLE
- #define Y2_enable Y2_ENABLE_WRITE( Y_ENABLE_ON)
- #define Y2_disable Y2_ENABLE_WRITE(!Y_ENABLE_ON)
+ #define Y2_enable() Y2_ENABLE_WRITE( Y_ENABLE_ON)
+ #define Y2_disable() Y2_ENABLE_WRITE(!Y_ENABLE_ON)
#else
- #define Y2_enable NOOP
- #define Y2_disable NOOP
+ #define Y2_enable() NOOP
+ #define Y2_disable() NOOP
#endif
-#define enable_Y() do{ Y_enable; Y2_enable; }while(0)
-#define disable_Y() do{ Y_disable; Y2_disable; CBI(axis_known_position, Y_AXIS); }while(0)
+#define enable_Y() do{ Y_enable(); Y2_enable(); }while(0)
+#define disable_Y() do{ Y_disable(); Y2_disable(); CBI(axis_known_position, Y_AXIS); }while(0)
#if AXIS_DRIVER_TYPE_Z(L6470)
extern L6470 stepperZ;
- #define Z_enable NOOP
- #define Z_disable stepperZ.free()
+ #define Z_enable() NOOP
+ #define Z_disable() stepperZ.free()
#elif HAS_Z_ENABLE
- #define Z_enable Z_ENABLE_WRITE( Z_ENABLE_ON)
- #define Z_disable Z_ENABLE_WRITE(!Z_ENABLE_ON)
+ #define Z_enable() Z_ENABLE_WRITE( Z_ENABLE_ON)
+ #define Z_disable() Z_ENABLE_WRITE(!Z_ENABLE_ON)
#else
- #define Z_enable NOOP
- #define Z_disable NOOP
+ #define Z_enable() NOOP
+ #define Z_disable() NOOP
#endif
#if AXIS_DRIVER_TYPE_Z2(L6470)
extern L6470 stepperZ2;
- #define Z2_enable NOOP
- #define Z2_disable stepperZ2.free()
+ #define Z2_enable() NOOP
+ #define Z2_disable() stepperZ2.free()
#elif HAS_Z2_ENABLE
- #define Z2_enable Z2_ENABLE_WRITE( Z_ENABLE_ON)
- #define Z2_disable Z2_ENABLE_WRITE(!Z_ENABLE_ON)
+ #define Z2_enable() Z2_ENABLE_WRITE( Z_ENABLE_ON)
+ #define Z2_disable() Z2_ENABLE_WRITE(!Z_ENABLE_ON)
#else
- #define Z2_enable NOOP
- #define Z2_disable NOOP
+ #define Z2_enable() NOOP
+ #define Z2_disable() NOOP
#endif
#if AXIS_DRIVER_TYPE_Z3(L6470)
extern L6470 stepperZ3;
- #define Z3_enable NOOP
- #define Z3_disable stepperZ3.free()
+ #define Z3_enable() NOOP
+ #define Z3_disable() stepperZ3.free()
#elif HAS_Z3_ENABLE
- #define Z3_enable Z3_ENABLE_WRITE( Z_ENABLE_ON)
- #define Z3_disable Z3_ENABLE_WRITE(!Z_ENABLE_ON)
+ #define Z3_enable() Z3_ENABLE_WRITE( Z_ENABLE_ON)
+ #define Z3_disable() Z3_ENABLE_WRITE(!Z_ENABLE_ON)
#else
- #define Z3_enable NOOP
- #define Z3_disable NOOP
+ #define Z3_enable() NOOP
+ #define Z3_disable() NOOP
#endif
-#define enable_Z() do{ Z_enable; Z2_enable; Z3_enable; }while(0)
-#define disable_Z() do{ Z_disable; Z2_disable; Z3_disable; CBI(axis_known_position, Z_AXIS); }while(0)
+#define enable_Z() do{ Z_enable(); Z2_enable(); Z3_enable(); }while(0)
+#define disable_Z() do{ Z_disable(); Z2_disable(); Z3_disable(); CBI(axis_known_position, Z_AXIS); }while(0)
//
// Extruder Stepper enable / disable
@@ -149,74 +149,74 @@ void manage_inactivity(const bool ignore_stepper_queue=false);
// define the individual enables/disables
#if AXIS_DRIVER_TYPE_E0(L6470)
extern L6470 stepperE0;
- #define E0_enable NOOP
- #define E0_disable do{ stepperE0.free(); CBI(axis_known_position, E_AXIS); }while(0)
+ #define E0_enable() NOOP
+ #define E0_disable() do{ stepperE0.free(); CBI(axis_known_position, E_AXIS); }while(0)
#elif HAS_E0_ENABLE
- #define E0_enable E0_ENABLE_WRITE( E_ENABLE_ON)
- #define E0_disable E0_ENABLE_WRITE(!E_ENABLE_ON)
+ #define E0_enable() E0_ENABLE_WRITE( E_ENABLE_ON)
+ #define E0_disable() E0_ENABLE_WRITE(!E_ENABLE_ON)
#else
- #define E0_enable NOOP
- #define E0_disable NOOP
+ #define E0_enable() NOOP
+ #define E0_disable() NOOP
#endif
#if AXIS_DRIVER_TYPE_E1(L6470)
extern L6470 stepperE1;
- #define E1_enable NOOP
- #define E1_disable do{ stepperE1.free(); CBI(axis_known_position, E_AXIS); }while(0)
+ #define E1_enable() NOOP
+ #define E1_disable() do{ stepperE1.free(); CBI(axis_known_position, E_AXIS); }while(0)
#elif E_STEPPERS > 1 && HAS_E1_ENABLE
- #define E1_enable E1_ENABLE_WRITE( E_ENABLE_ON)
- #define E1_disable E1_ENABLE_WRITE(!E_ENABLE_ON)
+ #define E1_enable() E1_ENABLE_WRITE( E_ENABLE_ON)
+ #define E1_disable() E1_ENABLE_WRITE(!E_ENABLE_ON)
#else
- #define E1_enable NOOP
- #define E1_disable NOOP
+ #define E1_enable() NOOP
+ #define E1_disable() NOOP
#endif
#if AXIS_DRIVER_TYPE_E2(L6470)
extern L6470 stepperE2;
- #define E2_enable NOOP
- #define E2_disable do{ stepperE2.free(); CBI(axis_known_position, E_AXIS); }while(0)
+ #define E2_enable() NOOP
+ #define E2_disable() do{ stepperE2.free(); CBI(axis_known_position, E_AXIS); }while(0)
#elif E_STEPPERS > 2 && HAS_E2_ENABLE
- #define E2_enable E2_ENABLE_WRITE( E_ENABLE_ON)
- #define E2_disable E2_ENABLE_WRITE(!E_ENABLE_ON)
+ #define E2_enable() E2_ENABLE_WRITE( E_ENABLE_ON)
+ #define E2_disable() E2_ENABLE_WRITE(!E_ENABLE_ON)
#else
- #define E2_enable NOOP
- #define E2_disable NOOP
+ #define E2_enable() NOOP
+ #define E2_disable() NOOP
#endif
#if AXIS_DRIVER_TYPE_E3(L6470)
extern L6470 stepperE3;
- #define E3_enable NOOP
- #define E3_disable do{ stepperE3.free(); CBI(axis_known_position, E_AXIS); }while(0)
+ #define E3_enable() NOOP
+ #define E3_disable() do{ stepperE3.free(); CBI(axis_known_position, E_AXIS); }while(0)
#elif E_STEPPERS > 3 && HAS_E3_ENABLE
- #define E3_enable E3_ENABLE_WRITE( E_ENABLE_ON)
- #define E3_disable E3_ENABLE_WRITE(!E_ENABLE_ON)
+ #define E3_enable() E3_ENABLE_WRITE( E_ENABLE_ON)
+ #define E3_disable() E3_ENABLE_WRITE(!E_ENABLE_ON)
#else
- #define E3_enable NOOP
- #define E3_disable NOOP
+ #define E3_enable() NOOP
+ #define E3_disable() NOOP
#endif
#if AXIS_DRIVER_TYPE_E4(L6470)
extern L6470 stepperE4;
- #define E4_enable NOOP
- #define E4_disable do{ stepperE4.free(); CBI(axis_known_position, E_AXIS); }while(0)
+ #define E4_enable() NOOP
+ #define E4_disable() do{ stepperE4.free(); CBI(axis_known_position, E_AXIS); }while(0)
#elif E_STEPPERS > 4 && HAS_E4_ENABLE
- #define E4_enable E4_ENABLE_WRITE( E_ENABLE_ON)
- #define E4_disable E4_ENABLE_WRITE(!E_ENABLE_ON)
+ #define E4_enable() E4_ENABLE_WRITE( E_ENABLE_ON)
+ #define E4_disable() E4_ENABLE_WRITE(!E_ENABLE_ON)
#else
- #define E4_enable NOOP
- #define E4_disable NOOP
+ #define E4_enable() NOOP
+ #define E4_disable() NOOP
#endif
#if AXIS_DRIVER_TYPE_E5(L6470)
extern L6470 stepperE5;
- #define E5_enable NOOP
- #define E5_disable do{ stepperE5.free(); CBI(axis_known_position, E_AXIS); }while(0)
+ #define E5_enable() NOOP
+ #define E5_disable() do{ stepperE5.free(); CBI(axis_known_position, E_AXIS); }while(0)
#elif E_STEPPERS > 5 && HAS_E5_ENABLE
- #define E5_enable E5_ENABLE_WRITE( E_ENABLE_ON)
- #define E5_disable E5_ENABLE_WRITE(!E_ENABLE_ON)
+ #define E5_enable() E5_ENABLE_WRITE( E_ENABLE_ON)
+ #define E5_disable() E5_ENABLE_WRITE(!E_ENABLE_ON)
#else
- #define E5_enable NOOP
- #define E5_disable NOOP
+ #define E5_enable() NOOP
+ #define E5_disable() NOOP
#endif
#if ENABLED(MIXING_EXTRUDER)
@@ -225,20 +225,20 @@ void manage_inactivity(const bool ignore_stepper_queue=false);
* Mixing steppers synchronize their enable (and direction) together
*/
#if MIXING_STEPPERS > 5
- #define enable_E0() { E0_enable; E1_enable; E2_enable; E3_enable; E4_enable; E5_enable; }
- #define disable_E0() { E0_disable; E1_disable; E2_disable; E3_disable; E4_disable; E5_disable; }
+ #define enable_E0() { E0_enable(); E1_enable(); E2_enable(); E3_enable(); E4_enable(); E5_enable(); }
+ #define disable_E0() { E0_disable(); E1_disable(); E2_disable(); E3_disable(); E4_disable(); E5_disable(); }
#elif MIXING_STEPPERS > 4
- #define enable_E0() { E0_enable; E1_enable; E2_enable; E3_enable; E4_enable; }
- #define disable_E0() { E0_disable; E1_disable; E2_disable; E3_disable; E4_disable; }
+ #define enable_E0() { E0_enable(); E1_enable(); E2_enable(); E3_enable(); E4_enable(); }
+ #define disable_E0() { E0_disable(); E1_disable(); E2_disable(); E3_disable(); E4_disable(); }
#elif MIXING_STEPPERS > 3
- #define enable_E0() { E0_enable; E1_enable; E2_enable; E3_enable; }
- #define disable_E0() { E0_disable; E1_disable; E2_disable; E3_disable; }
+ #define enable_E0() { E0_enable(); E1_enable(); E2_enable(); E3_enable(); }
+ #define disable_E0() { E0_disable(); E1_disable(); E2_disable(); E3_disable(); }
#elif MIXING_STEPPERS > 2
- #define enable_E0() { E0_enable; E1_enable; E2_enable; }
- #define disable_E0() { E0_disable; E1_disable; E2_disable; }
+ #define enable_E0() { E0_enable(); E1_enable(); E2_enable(); }
+ #define disable_E0() { E0_disable(); E1_disable(); E2_disable(); }
#else
- #define enable_E0() { E0_enable; E1_enable; }
- #define disable_E0() { E0_disable; E1_disable; }
+ #define enable_E0() { E0_enable(); E1_enable(); }
+ #define disable_E0() { E0_disable(); E1_disable(); }
#endif
#define enable_E1() NOOP
#define disable_E1() NOOP
@@ -254,48 +254,48 @@ void manage_inactivity(const bool ignore_stepper_queue=false);
#else // !MIXING_EXTRUDER
#if HAS_E0_ENABLE
- #define enable_E0() E0_enable
- #define disable_E0() E0_disable
+ #define enable_E0() E0_enable()
+ #define disable_E0() E0_disable()
#else
#define enable_E0() NOOP
#define disable_E0() NOOP
#endif
#if E_STEPPERS > 1 && HAS_E1_ENABLE
- #define enable_E1() E1_enable
- #define disable_E1() E1_disable
+ #define enable_E1() E1_enable()
+ #define disable_E1() E1_disable()
#else
#define enable_E1() NOOP
#define disable_E1() NOOP
#endif
#if E_STEPPERS > 2 && HAS_E2_ENABLE
- #define enable_E2() E2_enable
- #define disable_E2() E2_disable
+ #define enable_E2() E2_enable()
+ #define disable_E2() E2_disable()
#else
#define enable_E2() NOOP
#define disable_E2() NOOP
#endif
#if E_STEPPERS > 3 && HAS_E3_ENABLE
- #define enable_E3() E3_enable
- #define disable_E3() E3_disable
+ #define enable_E3() E3_enable()
+ #define disable_E3() E3_disable()
#else
#define enable_E3() NOOP
#define disable_E3() NOOP
#endif
#if E_STEPPERS > 4 && HAS_E4_ENABLE
- #define enable_E4() E4_enable
- #define disable_E4() E4_disable
+ #define enable_E4() E4_enable()
+ #define disable_E4() E4_disable()
#else
#define enable_E4() NOOP
#define disable_E4() NOOP
#endif
#if E_STEPPERS > 5 && HAS_E5_ENABLE
- #define enable_E5() E5_enable
- #define disable_E5() E5_disable
+ #define enable_E5() E5_enable()
+ #define disable_E5() E5_disable()
#else
#define enable_E5() NOOP
#define disable_E5() NOOP
@@ -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();
@@ -333,6 +333,7 @@ inline bool IsStopped() { return !Running; }
bool printingIsActive();
bool printingIsPaused();
+void startOrResumeJob();
extern bool wait_for_heatup;
@@ -351,7 +352,7 @@ extern millis_t max_inactive_time, stepper_inactive_time;
extern uint8_t controllerfan_speed;
#endif
-#if HAS_POWER_SWITCH
+#if ENABLED(PSU_CONTROL)
extern bool powersupply_on;
#define PSU_PIN_ON() do{ OUT_WRITE(PS_ON_PIN, PSU_ACTIVE_HIGH); powersupply_on = true; }while(0)
#define PSU_PIN_OFF() do{ OUT_WRITE(PS_ON_PIN, !PSU_ACTIVE_HIGH); powersupply_on = false; }while(0)
@@ -368,10 +369,13 @@ bool pin_is_protected(const pin_t pin);
void protected_pin_err();
#if HAS_SUICIDE
- inline void suicide() { OUT_WRITE(SUICIDE_PIN, LOW); }
+ inline void suicide() { OUT_WRITE(SUICIDE_PIN, SUICIDE_PIN_INVERTING); }
#endif
#if ENABLED(G29_RETRY_AND_RECOVER)
void event_probe_recover();
void event_probe_failure();
#endif
+
+extern const char NUL_STR[], G28_STR[], M21_STR[], M23_STR[], M24_STR[],
+ SP_X_STR[], SP_Y_STR[], SP_Z_STR[], SP_E_STR[];
diff --git a/Marlin/src/core/boards.h b/Marlin/src/core/boards.h
index d3d7b18925..875ab85b2d 100644
--- a/Marlin/src/core/boards.h
+++ b/Marlin/src/core/boards.h
@@ -21,6 +21,8 @@
*/
#pragma once
+#include "macros.h"
+
#define BOARD_UNKNOWN -1
//
@@ -62,7 +64,7 @@
#define BOARD_MKS_BASE_HEROIC 1108 // MKS BASE 1.0 with Heroic HR4982 stepper drivers
#define BOARD_MKS_GEN_13 1109 // MKS GEN v1.3 or 1.4
#define BOARD_MKS_GEN_L 1110 // MKS GEN L
-#define BOARD_KFB_2 1111 // Bigtreetech or BIQU KFB2.0
+#define BOARD_KFB_2 1111 // BigTreeTech or BIQU KFB2.0
#define BOARD_ZRIB_V20 1112 // zrib V2.0 control board (Chinese knock off RAMPS replica)
#define BOARD_FELIX2 1113 // Felix 2.0+ Electronics Board (RAMPS like)
#define BOARD_RIGIDBOARD 1114 // Invent-A-Part RigidBoard
@@ -97,6 +99,8 @@
#define BOARD_OVERLORD 1143 // Overlord/Overlord Pro
#define BOARD_HJC2560C_REV1 1144 // ADIMLab Gantry v1
#define BOARD_HJC2560C_REV2 1145 // ADIMLab Gantry v2
+#define BOARD_TANGO 1146 // BIQU Tango V1
+#define BOARD_MKS_GEN_L_V2 1147 // MKS GEN L V2
//
// RAMBo and derivatives
@@ -197,21 +201,28 @@
#define BOARD_RAMPS_14_RE_ARM_SF 2004 // Re-ARM with RAMPS 1.4 (Power outputs: Spindle, Controller Fan)
#define BOARD_MKS_SBASE 2005 // MKS-Sbase (Power outputs: Hotend0, Hotend1, Bed, Fan)
#define BOARD_AZSMZ_MINI 2006 // AZSMZ Mini
-#define BOARD_AZTEEG_X5_GT 2007 // Azteeg X5 GT (Power outputs: Hotend0, Hotend1, Bed, Fan)
-#define BOARD_BIQU_BQ111_A4 2008 // BIQU BQ111-A4 (Power outputs: Hotend, Fan, Bed)
-#define BOARD_SELENA_COMPACT 2009 // Selena Compact (Power outputs: Hotend0, Hotend1, Bed0, Bed1, Fan0, Fan1)
-#define BOARD_COHESION3D_REMIX 2010 // Cohesion3D ReMix
-#define BOARD_COHESION3D_MINI 2011 // Cohesion3D Mini
-#define BOARD_SMOOTHIEBOARD 2012 // Smoothieboard
-#define BOARD_AZTEEG_X5_MINI_WIFI 2013 // Azteeg X5 Mini Wifi (Power outputs: Hotend0, Bed, Fan)
-#define BOARD_BIGTREE_SKR_V1_1 2014 // BIGTREE SKR_V1.1 (Power outputs: Hotend0,Hotend1, Fan, Bed)
-#define BOARD_BIQU_B300_V1_0 2015 // BIQU B300_V1.0 (Power outputs: Hotend0, Fan, Bed, SPI Driver)
-#define BOARD_BIGTREE_SKR_V1_3 2016 // BIGTREE SKR_V1.3 (Power outputs: Hotend0, Hotend1, Fan, Bed)
-#define BOARD_AZTEEG_X5_MINI 2017 // Azteeg X5 Mini (Power outputs: Hotend0, Bed, Fan)
-#define BOARD_MKS_SGEN 2018 // MKS-SGen (Power outputs: Hotend0, Hotend1, Bed, Fan)
-#define BOARD_MKS_SGEN_L 2019 // MKS-SGen-L (Power outputs: Hotend0, Hotend1, Bed, Fan)
-#define BOARD_TH3D_EZBOARD 2020 // TH3D EZBoard v1.0
-#define BOARD_GMARSH_X6_REV1 2021 // GMARSH X6 board, revision 1 prototype
+#define BOARD_BIQU_BQ111_A4 2007 // BIQU BQ111-A4 (Power outputs: Hotend, Fan, Bed)
+#define BOARD_SELENA_COMPACT 2008 // Selena Compact (Power outputs: Hotend0, Hotend1, Bed0, Bed1, Fan0, Fan1)
+#define BOARD_BIQU_B300_V1_0 2009 // BIQU B300_V1.0 (Power outputs: Hotend0, Fan, Bed, SPI Driver)
+#define BOARD_MKS_SGEN_L 2010 // MKS-SGen-L (Power outputs: Hotend0, Hotend1, Bed, Fan)
+#define BOARD_GMARSH_X6_REV1 2011 // GMARSH X6 board, revision 1 prototype
+#define BOARD_BIGTREE_SKR_V1_1 2012 // BigTreeTech SKR v1.1 (Power outputs: Hotend0, Hotend1, Fan, Bed)
+#define BOARD_BIGTREE_SKR_V1_3 2013 // BigTreeTech SKR v1.3 (Power outputs: Hotend0, Hotend1, Fan, Bed)
+#define BOARD_BIGTREE_SKR_V1_4 2014 // BigTreeTech SKR v1.4 (Power outputs: Hotend0, Hotend1, Fan, Bed)
+
+//
+// LPC1769 ARM Cortex M3
+//
+
+#define BOARD_MKS_SGEN 2500 // MKS-SGen (Power outputs: Hotend0, Hotend1, Bed, Fan)
+#define BOARD_AZTEEG_X5_GT 2501 // Azteeg X5 GT (Power outputs: Hotend0, Hotend1, Bed, Fan)
+#define BOARD_AZTEEG_X5_MINI 2502 // Azteeg X5 Mini (Power outputs: Hotend0, Bed, Fan)
+#define BOARD_AZTEEG_X5_MINI_WIFI 2503 // Azteeg X5 Mini Wifi (Power outputs: Hotend0, Bed, Fan)
+#define BOARD_COHESION3D_REMIX 2504 // Cohesion3D ReMix
+#define BOARD_COHESION3D_MINI 2505 // Cohesion3D Mini
+#define BOARD_SMOOTHIEBOARD 2506 // Smoothieboard
+#define BOARD_TH3D_EZBOARD 2507 // TH3D EZBoard v1.0
+#define BOARD_BIGTREE_SKR_V1_4_TURBO 2508 // BigTreeTech SKR v1.4 TURBO (Power outputs: Hotend0, Hotend1, Fan, Bed)
//
// SAM3X8E ARM Cortex M3
@@ -265,15 +276,21 @@
#define BOARD_MKS_ROBIN_MINI 4007 // MKS Robin Mini (STM32F103VET6)
#define BOARD_MKS_ROBIN_NANO 4008 // MKS Robin Nano (STM32F103VET6)
#define BOARD_MKS_ROBIN_LITE 4009 // MKS Robin Lite/Lite2 (STM32F103RCT6)
-#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_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
+#define BOARD_MKS_ROBIN_LITE3 4010 // MKS Robin Lite3 (STM32F103RCT6)
+#define BOARD_MKS_ROBIN_PRO 4011 // MKS Robin Pro (STM32F103ZET6)
+#define BOARD_BIGTREE_SKR_MINI_V1_1 4012 // BigTreeTech SKR Mini v1.1 (STM32F103RC)
+#define BOARD_BTT_SKR_MINI_E3_V1_0 4013 // BigTreeTech SKR Mini E3 (STM32F103RC)
+#define BOARD_BTT_SKR_MINI_E3_V1_2 4014 // BigTreeTech SKR Mini E3 V1.2 (STM32F103RC)
+#define BOARD_BIGTREE_SKR_E3_DIP 4015 // BigTreeTech SKR E3 DIP V1.0 (STM32F103RC / STM32F103RE)
+#define BOARD_JGAURORA_A5S_A1 4016 // JGAurora A5S A1 (STM32F103ZET6)
+#define BOARD_FYSETC_AIO_II 4017 // FYSETC AIO_II
+#define BOARD_FYSETC_CHEETAH 4018 // FYSETC Cheetah
+#define BOARD_FYSETC_CHEETAH_V12 4019 // FYSETC Cheetah V1.2
+#define BOARD_LONGER3D_LK 4020 // Alfawise U20/U20+/U30 (Longer3D LK1/2) / STM32F103VET6
+#define BOARD_GTM32_MINI 4021 // STM32F103VET6 controller
+#define BOARD_GTM32_MINI_A30 4022 // STM32F103VET6 controller
+#define BOARD_GTM32_REV_B 4023 // STM32F103VET6 controller
+
//
// ARM Cortex-M4F
@@ -287,16 +304,20 @@
//
#define BOARD_BEAST 4200 // STM32F4xxVxT6 Libmaple-based STM32F4 controller
-#define BOARD_STM32F4 4201 // STM32 STM32GENERIC-based STM32F4 controller
+#define BOARD_GENERIC_STM32F4 4201 // STM32 STM32GENERIC-based STM32F4 controller
#define BOARD_ARMED 4202 // Arm'ed STM32F4-based controller
#define BOARD_RUMBA32 4203 // RUMBA32 STM32F4-based controller
#define BOARD_BLACK_STM32F407VE 4204 // BLACK_STM32F407VE
#define BOARD_BLACK_STM32F407ZE 4205 // BLACK_STM32F407ZE
-#define BOARD_STEVAL 4206 // STEVAL-3DP001V1 3D PRINTER BOARD
+#define BOARD_STEVAL_3DP001V1 4206 // STEVAL-3DP001V1 3D PRINTER BOARD
#define BOARD_BIGTREE_SKR_PRO_V1_1 4207 // BigTreeTech SKR Pro v1.1 (STM32F407ZG)
#define BOARD_BIGTREE_BTT002_V1_0 4208 // BigTreeTech BTT002 v1.0 (STM32F407VE)
#define BOARD_LERDGE_K 4209 // Lerdge K (STM32F407ZG)
#define BOARD_LERDGE_X 4210 // Lerdge X (STM32F407VE)
+#define BOARD_VAKE403D 4211 // VAkE 403D (STM32F446VET6)
+#define BOARD_FYSETC_S6 4212 // FYSETC S6 board
+#define BOARD_FLYF407ZG 4213 // FLYF407ZG board (STM32F407ZG)
+#define BOARD_MKS_ROBIN2 4214 // MKS_ROBIN2 (STM32F407ZE)
//
// ARM Cortex M7
@@ -308,7 +329,9 @@
//
// Espressif ESP32 WiFi
//
-#define BOARD_ESP32 6000
+#define BOARD_ESPRESSIF_ESP32 6000
+#define BOARD_MRR_ESPA 6001
+#define BOARD_MRR_ESPE 6002
//
// Simulations
@@ -316,4 +339,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)
diff --git a/Marlin/src/core/debug_out.h b/Marlin/src/core/debug_out.h
index 7eb93a7020..07bdad7ff2 100644
--- a/Marlin/src/core/debug_out.h
+++ b/Marlin/src/core/debug_out.h
@@ -19,7 +19,6 @@
* along with this program. If not, see .
*
*/
-#pragma once
//
// Serial aliases for debugging.
@@ -37,9 +36,13 @@
#undef DEBUG_ECHOPGM
#undef DEBUG_ECHOLNPGM
#undef DEBUG_ECHOPAIR
+#undef DEBUG_ECHOPAIR_P
#undef DEBUG_ECHOPAIR_F
+#undef DEBUG_ECHOPAIR_F_P
#undef DEBUG_ECHOLNPAIR
+#undef DEBUG_ECHOLNPAIR_P
#undef DEBUG_ECHOLNPAIR_F
+#undef DEBUG_ECHOLNPAIR_F_P
#undef DEBUG_ECHO_MSG
#undef DEBUG_ERROR_MSG
#undef DEBUG_EOL
@@ -58,9 +61,13 @@
#define DEBUG_ECHOPGM SERIAL_ECHOPGM
#define DEBUG_ECHOLNPGM SERIAL_ECHOLNPGM
#define DEBUG_ECHOPAIR SERIAL_ECHOPAIR
+ #define DEBUG_ECHOPAIR_P SERIAL_ECHOPAIR_P
#define DEBUG_ECHOPAIR_F SERIAL_ECHOPAIR_F
+ #define DEBUG_ECHOPAIR_F_P SERIAL_ECHOPAIR_F_P
#define DEBUG_ECHOLNPAIR SERIAL_ECHOLNPAIR
+ #define DEBUG_ECHOLNPAIR_P SERIAL_ECHOLNPAIR_P
#define DEBUG_ECHOLNPAIR_F SERIAL_ECHOLNPAIR_F
+ #define DEBUG_ECHOLNPAIR_F_P SERIAL_ECHOLNPAIR_F_P
#define DEBUG_ECHO_MSG SERIAL_ECHO_MSG
#define DEBUG_ERROR_MSG SERIAL_ERROR_MSG
#define DEBUG_EOL SERIAL_EOL
@@ -68,25 +75,29 @@
#define DEBUG_XYZ SERIAL_XYZ
#define DEBUG_DELAY(ms) serial_delay(ms)
#else
- #define DEBUG_PRINT_P(P) NOOP
- #define DEBUG_ECHO_START() NOOP
- #define DEBUG_ERROR_START() NOOP
- #define DEBUG_CHAR(...) NOOP
- #define DEBUG_ECHO(...) NOOP
- #define DEBUG_ECHO_F(...) NOOP
- #define DEBUG_ECHOLN(...) NOOP
- #define DEBUG_ECHOPGM(...) NOOP
- #define DEBUG_ECHOLNPGM(...) NOOP
- #define DEBUG_ECHOPAIR(...) NOOP
- #define DEBUG_ECHOPAIR_F(...) NOOP
- #define DEBUG_ECHOLNPAIR(...) NOOP
- #define DEBUG_ECHOLNPAIR_F(...) NOOP
- #define DEBUG_ECHO_MSG(...) NOOP
- #define DEBUG_ERROR_MSG(...) NOOP
- #define DEBUG_EOL() NOOP
- #define DEBUG_POS(...) NOOP
- #define DEBUG_XYZ(...) NOOP
- #define DEBUG_DELAY(...) NOOP
+ #define DEBUG_PRINT_P(P) NOOP
+ #define DEBUG_ECHO_START() NOOP
+ #define DEBUG_ERROR_START() NOOP
+ #define DEBUG_CHAR(...) NOOP
+ #define DEBUG_ECHO(...) NOOP
+ #define DEBUG_ECHO_F(...) NOOP
+ #define DEBUG_ECHOLN(...) NOOP
+ #define DEBUG_ECHOPGM(...) NOOP
+ #define DEBUG_ECHOLNPGM(...) NOOP
+ #define DEBUG_ECHOPAIR(...) NOOP
+ #define DEBUG_ECHOPAIR_P(...) NOOP
+ #define DEBUG_ECHOPAIR_F(...) NOOP
+ #define DEBUG_ECHOPAIR_F_P(...) NOOP
+ #define DEBUG_ECHOLNPAIR(...) NOOP
+ #define DEBUG_ECHOLNPAIR_P(...) NOOP
+ #define DEBUG_ECHOLNPAIR_F(...) NOOP
+ #define DEBUG_ECHOLNPAIR_F_P(...) NOOP
+ #define DEBUG_ECHO_MSG(...) NOOP
+ #define DEBUG_ERROR_MSG(...) NOOP
+ #define DEBUG_EOL() NOOP
+ #define DEBUG_POS(...) NOOP
+ #define DEBUG_XYZ(...) NOOP
+ #define DEBUG_DELAY(...) NOOP
#endif
#undef DEBUG_OUT
diff --git a/Marlin/src/core/drivers.h b/Marlin/src/core/drivers.h
index 005ffb7da5..56f4a6fa4a 100644
--- a/Marlin/src/core/drivers.h
+++ b/Marlin/src/core/drivers.h
@@ -86,6 +86,18 @@
|| HAS_DRIVER(TMC5130) \
|| HAS_DRIVER(TMC5160) )
+#define HAS_TRINAMIC_STANDALONE ( HAS_DRIVER(TMC2130_STANDALONE) \
+ || HAS_DRIVER(TMC2208_STANDALONE) \
+ || HAS_DRIVER(TMC2209_STANDALONE) \
+ || HAS_DRIVER(TMC26X_STANDALONE) \
+ || HAS_DRIVER(TMC2660_STANDALONE) \
+ || HAS_DRIVER(TMC5130_STANDALONE) \
+ || HAS_DRIVER(TMC5160_STANDALONE) \
+ || HAS_DRIVER(TMC2160_STANDALONE) )
+
+#define HAS_TMCX1X0 ( HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2160) \
+ || HAS_DRIVER(TMC5130) || HAS_DRIVER(TMC5160))
+
#define HAS_TMC220x (HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209))
#define AXIS_IS_TMC(A) ( AXIS_DRIVER_TYPE(A,TMC2130) \
@@ -107,6 +119,8 @@
#define AXIS_HAS_UART(A) ( AXIS_DRIVER_TYPE(A,TMC2208) \
|| AXIS_DRIVER_TYPE(A,TMC2209) )
+#define AXIS_HAS_SW_SERIAL(A) ((AXIS_HAS_UART(A) && !defined(A##_HARDWARE_SERIAL)))
+
#define AXIS_HAS_STALLGUARD(A) ( AXIS_DRIVER_TYPE(A,TMC2130) \
|| AXIS_DRIVER_TYPE(A,TMC2160) \
|| AXIS_DRIVER_TYPE(A,TMC2209) \
@@ -121,6 +135,19 @@
|| AXIS_DRIVER_TYPE(A,TMC5130) \
|| AXIS_DRIVER_TYPE(A,TMC5160) )
+#define ANY_AXIS_HAS(T) ( AXIS_HAS_##T(X) || AXIS_HAS_##T(X2) \
+ || AXIS_HAS_##T(Y) || AXIS_HAS_##T(Y2) \
+ || AXIS_HAS_##T(Z) || AXIS_HAS_##T(Z2) \
+ || AXIS_HAS_##T(Z3) \
+ || AXIS_HAS_##T(E0) || AXIS_HAS_##T(E1) \
+ || AXIS_HAS_##T(E2) || AXIS_HAS_##T(E3) \
+ || AXIS_HAS_##T(E4) || AXIS_HAS_##T(E5) )
+
+#define HAS_STEALTHCHOP ANY_AXIS_HAS(STEALTHCHOP)
+#define HAS_STALLGUARD ANY_AXIS_HAS(STALLGUARD)
+#define TMC_HAS_SPI ANY_AXIS_HAS(SPI)
+#define TMC_HAS_SW_SERIAL ANY_AXIS_HAS(SW_SERIAL)
+
//
// Stretching 'drivers.h' to include LPC/SAMD51 SD options
//
diff --git a/Marlin/src/core/language.h b/Marlin/src/core/language.h
index ee4e23fa76..cfce9d9ae1 100644
--- a/Marlin/src/core/language.h
+++ b/Marlin/src/core/language.h
@@ -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,17 +252,15 @@
#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: "
-#define MSG_KILL_BUTTON "KILL caused by KILL button/pin"
+#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: "
+#define MSG_KILL_BUTTON "!! KILL caused by KILL button/pin"
// temperature.cpp strings
-#define MSG_PID_AUTOTUNE "PID Autotune"
-#define MSG_PID_AUTOTUNE_START MSG_PID_AUTOTUNE " start"
-#define MSG_PID_AUTOTUNE_FAILED MSG_PID_AUTOTUNE " failed!"
+#define MSG_PID_AUTOTUNE_PREFIX "PID Autotune"
+#define MSG_PID_AUTOTUNE_START MSG_PID_AUTOTUNE_PREFIX " start"
+#define MSG_PID_AUTOTUNE_FAILED MSG_PID_AUTOTUNE_PREFIX " failed!"
#define MSG_PID_BAD_EXTRUDER_NUM MSG_PID_AUTOTUNE_FAILED " Bad extruder number"
#define MSG_PID_TEMP_TOO_HIGH MSG_PID_AUTOTUNE_FAILED " Temperature too high"
#define MSG_PID_TIMEOUT MSG_PID_AUTOTUNE_FAILED " timeout"
@@ -279,7 +275,7 @@
#define MSG_KI " Ki: "
#define MSG_KD " Kd: "
#define MSG_AT " @:"
-#define MSG_PID_AUTOTUNE_FINISHED MSG_PID_AUTOTUNE " finished! Put the last Kp, Ki and Kd constants from below into Configuration.h"
+#define MSG_PID_AUTOTUNE_FINISHED MSG_PID_AUTOTUNE_PREFIX " finished! Put the last Kp, Ki and Kd constants from below into Configuration.h"
#define MSG_PID_DEBUG " PID_DEBUG "
#define MSG_PID_DEBUG_INPUT ": Input "
#define MSG_PID_DEBUG_OUTPUT " Output "
@@ -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,54 @@
#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_FIRST_TOOL '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_FIRST_TOOL '1'
+ #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 +393,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
diff --git a/Marlin/src/core/macros.h b/Marlin/src/core/macros.h
index b93bae79f6..f3c9f3a818 100644
--- a/Marlin/src/core/macros.h
+++ b/Marlin/src/core/macros.h
@@ -165,6 +165,7 @@
// Macros to support option testing
#define _CAT(a,V...) a##V
+#define CAT(a,V...) _CAT(a,V)
#define SWITCH_ENABLED_false 0
#define SWITCH_ENABLED_true 1
#define SWITCH_ENABLED_0 0
@@ -229,32 +230,6 @@
#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
-#define INC_1 2
-#define INC_2 3
-#define INC_3 4
-#define INC_4 5
-#define INC_5 6
-#define INC_6 7
-#define INC_7 8
-#define INC_8 9
-#define INCREMENT_(n) INC_##n
-#define INCREMENT(n) INCREMENT_(n)
-
-// Macros for subtracting
-#define DEC_1 0
-#define DEC_2 1
-#define DEC_3 2
-#define DEC_4 3
-#define DEC_5 4
-#define DEC_6 5
-#define DEC_7 6
-#define DEC_8 7
-#define DEC_9 8
-#define DECREMENT_(n) DEC_##n
-#define DECREMENT(n) DECREMENT_(n)
-
#define NOOP (void(0))
#define CEILING(x,y) (((x) + (y) - 1) / (y))
@@ -276,10 +251,11 @@
//
// Maths macros that can be overridden by HAL
//
+#define ACOS(x) acosf(x)
#define ATAN2(y, x) atan2f(y, x)
#define POW(x, y) powf(x, y)
#define SQRT(x) sqrtf(x)
-#define RSQRT(x) (1 / sqrtf(x))
+#define RSQRT(x) (1.0f / sqrtf(x))
#define CEIL(x) ceilf(x)
#define FLOOR(x) floorf(x)
#define LROUND(x) lroundf(x)
@@ -346,3 +322,127 @@
#define _MAX(V...) _MAX_N(NUM_ARGS(V), V)
#endif
+
+// Macros for adding
+#define INC_0 1
+#define INC_1 2
+#define INC_2 3
+#define INC_3 4
+#define INC_4 5
+#define INC_5 6
+#define INC_6 7
+#define INC_7 8
+#define INC_8 9
+#define INCREMENT_(n) INC_##n
+#define INCREMENT(n) INCREMENT_(n)
+
+#define ADD0(N) N
+#define ADD1(N) INCREMENT_(N)
+#define ADD2(N) ADD1(ADD1(N))
+#define ADD3(N) ADD1(ADD2(N))
+#define ADD4(N) ADD2(ADD2(N))
+#define ADD5(N) ADD2(ADD3(N))
+#define ADD6(N) ADD3(ADD3(N))
+#define ADD7(N) ADD3(ADD4(N))
+#define ADD8(N) ADD4(ADD4(N))
+#define ADD9(N) ADD4(ADD5(N))
+#define ADD10(N) ADD5(ADD5(N))
+
+// Macros for subtracting
+#define DEC_0 0
+#define DEC_1 0
+#define DEC_2 1
+#define DEC_3 2
+#define DEC_4 3
+#define DEC_5 4
+#define DEC_6 5
+#define DEC_7 6
+#define DEC_8 7
+#define DEC_9 8
+#define DECREMENT_(n) DEC_##n
+#define DECREMENT(n) DECREMENT_(n)
+
+#define SUB0(N) N
+#define SUB1(N) DECREMENT_(N)
+#define SUB2(N) SUB1(SUB1(N))
+#define SUB3(N) SUB1(SUB2(N))
+#define SUB4(N) SUB2(SUB2(N))
+#define SUB5(N) SUB2(SUB3(N))
+#define SUB6(N) SUB3(SUB3(N))
+#define SUB7(N) SUB3(SUB4(N))
+#define SUB8(N) SUB4(SUB4(N))
+#define SUB9(N) SUB4(SUB5(N))
+#define SUB10(N) SUB5(SUB5(N))
+
+//
+// Primitives supporting precompiler REPEAT
+//
+#define FIRST(a,...) a
+#define SECOND(a,b,...) b
+
+// Defer expansion
+#define EMPTY()
+#define DEFER(M) M EMPTY()
+#define DEFER2(M) M EMPTY EMPTY()()
+#define DEFER3(M) M EMPTY EMPTY EMPTY()()()
+#define DEFER4(M) M EMPTY EMPTY EMPTY EMPTY()()()()
+
+// Force define expansion
+#define EVAL(V...) EVAL16(V)
+#define EVAL1024(V...) EVAL512(EVAL512(V))
+#define EVAL512(V...) EVAL256(EVAL256(V))
+#define EVAL256(V...) EVAL128(EVAL128(V))
+#define EVAL128(V...) EVAL64(EVAL64(V))
+#define EVAL64(V...) EVAL32(EVAL32(V))
+#define EVAL32(V...) EVAL16(EVAL16(V))
+#define EVAL16(V...) EVAL8(EVAL8(V))
+#define EVAL8(V...) EVAL4(EVAL4(V))
+#define EVAL4(V...) EVAL2(EVAL2(V))
+#define EVAL2(V...) EVAL1(EVAL1(V))
+#define EVAL1(V...) V
+
+#define IS_PROBE(V...) SECOND(V, 0) // Get the second item passed, or 0
+#define PROBE() ~, 1 // Second item will be 1 if this is passed
+#define _NOT_0 PROBE()
+#define NOT(x) IS_PROBE(_CAT(_NOT_, x)) // NOT('0') gets '1'. Anything else gets '0'.
+#define _BOOL(x) NOT(NOT(x)) // NOT('0') gets '0'. Anything else gets '1'.
+
+#define IF_ELSE(TF) _IF_ELSE(_BOOL(TF))
+#define _IF_ELSE(TF) _CAT(_IF_, TF)
+
+#define _IF_1(V...) V _IF_1_ELSE
+#define _IF_0(...) _IF_0_ELSE
+
+#define _IF_1_ELSE(...)
+#define _IF_0_ELSE(V...) V
+
+#define HAS_ARGS(V...) _BOOL(FIRST(_END_OF_ARGUMENTS_ V)())
+#define _END_OF_ARGUMENTS_() 0
+
+//
+// REPEAT core macros. Recurse N times with ascending I.
+//
+
+// Call OP(I) N times with ascending counter.
+#define _REPEAT(_RPT_I,_RPT_N,_RPT_OP) \
+ _RPT_OP(_RPT_I) \
+ IF_ELSE(SUB1(_RPT_N)) \
+ ( DEFER2(__REPEAT)()(ADD1(_RPT_I),SUB1(_RPT_N),_RPT_OP) ) \
+ ( /* Do nothing */ )
+#define __REPEAT() _REPEAT
+
+// Call OP(I, ...) N times with ascending counter.
+#define _REPEAT2(_RPT_I,_RPT_N,_RPT_OP,V...) \
+ _RPT_OP(_RPT_I,V) \
+ IF_ELSE(SUB1(_RPT_N)) \
+ ( DEFER2(__REPEAT2)()(ADD1(_RPT_I),SUB1(_RPT_N),_RPT_OP,V) ) \
+ ( /* Do nothing */ )
+#define __REPEAT2() _REPEAT2
+
+// Repeat a macro passing S...N-1.
+#define REPEAT_S(S,N,OP) EVAL(_REPEAT(S,SUB##S(N),OP))
+#define REPEAT(N,OP) REPEAT_S(0,N,OP)
+
+// Repeat a macro passing 0...N-1 plus additional arguments.
+#define REPEAT2_S(S,N,OP,V...) EVAL(_REPEAT2(S,SUB##S(N),OP,V))
+#define REPEAT2(N,OP,V...) REPEAT2_S(0,N,OP,V)
diff --git a/Marlin/src/core/multi_language.cpp b/Marlin/src/core/multi_language.cpp
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/language/language.h b/Marlin/src/core/multi_language.h
similarity index 71%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/language/language.h
rename to Marlin/src/core/multi_language.h
index 694a94b908..98020b1e8d 100644
--- a/Marlin/src/lcd/extensible_ui/lib/lulzbot/language/language.h
+++ b/Marlin/src/core/multi_language.h
@@ -1,6 +1,6 @@
-/**************
- * language.h *
- **************/
+/********************
+ * multi_language.h *
+ ********************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
@@ -22,8 +22,6 @@
typedef const char Language_Str[];
-// Count how many languages are defined.
-
#if defined(LCD_LANGUAGE_5)
#define NUM_LANGUAGES 5
#elif defined(LCD_LANGUAGE_4)
@@ -36,15 +34,11 @@ typedef const char Language_Str[];
#define NUM_LANGUAGES 1
#endif
-// Set undefined languages equal to the last and
-// let the compiler optimize out the duplicates
-
-#ifndef LCD_LANGUAGE_1
- #define LCD_LANGUAGE_1 LCD_LANGUAGE
-#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_1
+ #define LCD_LANGUAGE_2 LCD_LANGUAGE
#endif
#ifndef LCD_LANGUAGE_3
@@ -59,31 +53,27 @@ typedef const char Language_Str[];
#define LCD_LANGUAGE_5 LCD_LANGUAGE_4
#endif
-// Indirection required to paste together the namespace name
-
#define _GET_LANG(LANG) Language_##LANG
#define GET_LANG(LANG) _GET_LANG(LANG)
#if NUM_LANGUAGES > 1
extern uint8_t lang;
- // The compiler does a good job of "flattening" out this
- // if statement when there are fewer than five languages.
#define GET_TEXT(MSG) ( \
- lang == 0 ? GET_LANG(LCD_LANGUAGE_1)::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_1)::MSG
+ #define GET_TEXT(MSG) GET_LANG(LCD_LANGUAGE)::MSG
+ #define MAX_LANG_CHARSIZE GET_LANG(LCD_LANGUAGE)::CHARSIZE
#endif
-#define GET_TEXT_F(MSG) reinterpret_cast(GET_TEXT(MSG))
+#define GET_TEXT_F(MSG) (const __FlashStringHelper*)GET_TEXT(MSG)
-#define GET_LANGUAGE_NAME(N) GET_LANG(LCD_LANGUAGE_##N)::LANGUAGE
-
-// All the language tables go here
-
-#include "language_en.h"
-#include "language_de.h"
-#include "language_fr.h"
+#define MSG_CONCAT(A,B) pgm_p_pair_t(GET_TEXT(A),GET_TEXT(B))
diff --git a/Marlin/src/core/serial.cpp b/Marlin/src/core/serial.cpp
index 2369c3acbf..4a5214f5c0 100644
--- a/Marlin/src/core/serial.cpp
+++ b/Marlin/src/core/serial.cpp
@@ -67,8 +67,10 @@ void print_bin(const uint16_t val) {
}
}
+extern const char SP_X_STR[], SP_Y_STR[], SP_Z_STR[];
+
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);
+ SERIAL_ECHOPAIR_P(SP_X_STR, x, SP_Y_STR, y, SP_Z_STR, z);
if (suffix) serialprintPGM(suffix); else SERIAL_EOL();
}
diff --git a/Marlin/src/core/serial.h b/Marlin/src/core/serial.h
index f4c2570ca7..bdf3ba4686 100644
--- a/Marlin/src/core/serial.h
+++ b/Marlin/src/core/serial.h
@@ -75,7 +75,7 @@ extern uint8_t marlin_debug_flags;
#define SERIAL_PRINTF(V...) SERIAL_OUT(printf, V)
#define SERIAL_FLUSH() SERIAL_OUT(flush)
-#ifdef __STM32F1__
+#ifdef ARDUINO_ARCH_STM32
#define SERIAL_FLUSHTX() SERIAL_OUT(flush)
#elif TX_BUFFER_SIZE > 0
#define SERIAL_FLUSHTX() SERIAL_OUT(flushTX)
@@ -83,7 +83,7 @@ extern uint8_t marlin_debug_flags;
#define SERIAL_FLUSHTX()
#endif
-// Print up to 12 pairs of values
+// Print up to 12 pairs of values. Odd elements auto-wrapped in PSTR().
#define __SEP_N(N,V...) _SEP_##N(V)
#define _SEP_N(N,V...) __SEP_N(N,V)
#define _SEP_1(PRE) SERIAL_ECHOPGM(PRE)
@@ -113,6 +113,36 @@ extern uint8_t marlin_debug_flags;
#define SERIAL_ECHOPAIR(V...) _SEP_N(NUM_ARGS(V),V)
+// Print up to 12 pairs of values. Odd elements must be PSTR pointers.
+#define __SEP_N_P(N,V...) _SEP_##N##_P(V)
+#define _SEP_N_P(N,V...) __SEP_N_P(N,V)
+#define _SEP_1_P(PRE) serialprintPGM(PRE)
+#define _SEP_2_P(PRE,V) serial_echopair_PGM(PRE,V)
+#define _SEP_3_P(a,b,c) do{ _SEP_2_P(a,b); serialprintPGM(c); }while(0)
+#define _SEP_4_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_2_P(V); }while(0)
+#define _SEP_5_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_3_P(V); }while(0)
+#define _SEP_6_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_4_P(V); }while(0)
+#define _SEP_7_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_5_P(V); }while(0)
+#define _SEP_8_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_6_P(V); }while(0)
+#define _SEP_9_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_7_P(V); }while(0)
+#define _SEP_10_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_8_P(V); }while(0)
+#define _SEP_11_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_9_P(V); }while(0)
+#define _SEP_12_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_10_P(V); }while(0)
+#define _SEP_13_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_11_P(V); }while(0)
+#define _SEP_14_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_12_P(V); }while(0)
+#define _SEP_15_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_13_P(V); }while(0)
+#define _SEP_16_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_14_P(V); }while(0)
+#define _SEP_17_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_15_P(V); }while(0)
+#define _SEP_18_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_16_P(V); }while(0)
+#define _SEP_19_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_17_P(V); }while(0)
+#define _SEP_20_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_18_P(V); }while(0)
+#define _SEP_21_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_19_P(V); }while(0)
+#define _SEP_22_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_20_P(V); }while(0)
+#define _SEP_23_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_21_P(V); }while(0)
+#define _SEP_24_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_22_P(V); }while(0)
+
+#define SERIAL_ECHOPAIR_P(V...) _SEP_N_P(NUM_ARGS(V),V)
+
// Print up to 12 pairs of values followed by newline
#define __SELP_N(N,V...) _SELP_##N(V)
#define _SELP_N(N,V...) __SELP_N(N,V)
@@ -139,10 +169,40 @@ 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) // Use up two, pass the rest up
+#define _SELP_24(a,b,V...) do{ _SEP_2(a,b); _SELP_22(V); }while(0) // Eat two args, pass the rest up
#define SERIAL_ECHOLNPAIR(V...) _SELP_N(NUM_ARGS(V),V)
+// Print up to 12 pairs of values followed by newline
+#define __SELP_N_P(N,V...) _SELP_##N##_P(V)
+#define _SELP_N_P(N,V...) __SELP_N_P(N,V)
+#define _SELP_1_P(PRE) serialprintPGM(PRE)
+#define _SELP_2_P(PRE,V) do{ serial_echopair_PGM(PRE,V); SERIAL_EOL(); }while(0)
+#define _SELP_3_P(a,b,c) do{ _SEP_2_P(a,b); serialprintPGM(c); }while(0)
+#define _SELP_4_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_2_P(V); }while(0)
+#define _SELP_5_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_3_P(V); }while(0)
+#define _SELP_6_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_4_P(V); }while(0)
+#define _SELP_7_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_5_P(V); }while(0)
+#define _SELP_8_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_6_P(V); }while(0)
+#define _SELP_9_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_7_P(V); }while(0)
+#define _SELP_10_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_8_P(V); }while(0)
+#define _SELP_11_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_9_P(V); }while(0)
+#define _SELP_12_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_10_P(V); }while(0)
+#define _SELP_13_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_11_P(V); }while(0)
+#define _SELP_14_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_12_P(V); }while(0)
+#define _SELP_15_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_13_P(V); }while(0)
+#define _SELP_16_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_14_P(V); }while(0)
+#define _SELP_17_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_15_P(V); }while(0)
+#define _SELP_18_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_16_P(V); }while(0)
+#define _SELP_19_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_17_P(V); }while(0)
+#define _SELP_20_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_18_P(V); }while(0)
+#define _SELP_21_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_19_P(V); }while(0)
+#define _SELP_22_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_20_P(V); }while(0)
+#define _SELP_23_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_21_P(V); }while(0)
+#define _SELP_24_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_22_P(V); }while(0) // Eat two args, pass the rest up
+
+#define SERIAL_ECHOLNPAIR_P(V...) _SELP_N_P(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)
@@ -165,15 +225,20 @@ extern uint8_t marlin_debug_flags;
#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 _SLST_20(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_18(V); }while(0) // Eat two args, 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_ECHO_P(P) (serialprintPGM(P))
-#define SERIAL_ECHOPAIR_F(S,V...) do{ SERIAL_ECHOPGM(S); SERIAL_ECHO_F(V); }while(0)
+#define SERIAL_ECHOPGM(S) (SERIAL_ECHO_P(PSTR(S)))
+#define SERIAL_ECHOLNPGM(S) (SERIAL_ECHO_P(PSTR(S "\n")))
+
+#define SERIAL_ECHOPAIR_F_P(P,V...) do{ serialprintPGM(P); SERIAL_ECHO_F(V); }while(0)
+#define SERIAL_ECHOLNPAIR_F_P(V...) do{ SERIAL_ECHOPAIR_F_P(V); SERIAL_EOL(); }while(0)
+
+#define SERIAL_ECHOPAIR_F(S,V...) SERIAL_ECHOPAIR_F_P(PSTR(S),V)
#define SERIAL_ECHOLNPAIR_F(V...) do{ SERIAL_ECHOPAIR_F(V); SERIAL_EOL(); }while(0)
#define SERIAL_ECHO_START() serial_echo_start()
diff --git a/Marlin/src/core/types.h b/Marlin/src/core/types.h
index 567b35c8b9..72578faaaf 100644
--- a/Marlin/src/core/types.h
+++ b/Marlin/src/core/types.h
@@ -26,6 +26,9 @@
#include "millis_t.h"
+class __FlashStringHelper;
+typedef const __FlashStringHelper *progmem_str;
+
//
// Enumerated axis indices
//
diff --git a/Marlin/src/core/utility.cpp b/Marlin/src/core/utility.cpp
index ca8cd67ccf..4d5f5b2c38 100644
--- a/Marlin/src/core/utility.cpp
+++ b/Marlin/src/core/utility.cpp
@@ -22,7 +22,7 @@
#include "utility.h"
-#include "../Marlin.h"
+#include "../MarlinCore.h"
#include "../module/temperature.h"
void safe_delay(millis_t ms) {
@@ -59,6 +59,8 @@ void safe_delay(millis_t ms) {
SERIAL_ECHOLNPGM("Probe: "
#if ENABLED(PROBE_MANUALLY)
"PROBE_MANUALLY"
+ #elif ENABLED(NOZZLE_AS_PROBE)
+ "NOZZLE_AS_PROBE"
#elif ENABLED(FIX_MOUNTED_PROBE)
"FIX_MOUNTED_PROBE"
#elif ENABLED(BLTOUCH)
@@ -79,7 +81,7 @@ void safe_delay(millis_t ms) {
);
#if HAS_BED_PROBE
- SERIAL_ECHOPAIR("Probe Offset X", probe_offset.x, " Y", probe_offset.y, " Z", probe_offset.z);
+ SERIAL_ECHOPAIR_P(PSTR("Probe Offset X"), probe_offset.x, SP_Y_STR, probe_offset.y, SP_Z_STR, probe_offset.z);
if (probe_offset.x > 0)
SERIAL_ECHOPGM(" (Right");
else if (probe_offset.x < 0)
diff --git a/Marlin/src/core/utility.h b/Marlin/src/core/utility.h
index 2956f92892..f430da50d6 100644
--- a/Marlin/src/core/utility.h
+++ b/Marlin/src/core/utility.h
@@ -47,9 +47,9 @@ inline void serial_delay(const millis_t ms) {
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); }
+ inline void unmark(const xy_int8_t &xy) { unmark(xy.x, xy.y); }
+ inline void mark(const xy_int8_t &xy) { mark(xy.x, xy.y); }
+ inline bool marked(const xy_int8_t &xy) { return marked(xy.x, xy.y); }
};
typedef FlagBits MeshFlags;
diff --git a/Marlin/src/feature/Max7219_Debug_LEDs.cpp b/Marlin/src/feature/Max7219_Debug_LEDs.cpp
index 9ba67d6caa..63013057bc 100644
--- a/Marlin/src/feature/Max7219_Debug_LEDs.cpp
+++ b/Marlin/src/feature/Max7219_Debug_LEDs.cpp
@@ -45,7 +45,7 @@
#include "../module/planner.h"
#include "../module/stepper.h"
-#include "../Marlin.h"
+#include "../MarlinCore.h"
#include "../HAL/shared/Delay.h"
#define HAS_SIDE_BY_SIDE (ENABLED(MAX7219_SIDE_BY_SIDE) && MAX7219_NUMBER_UNITS > 1)
@@ -455,15 +455,19 @@ void Max7219::register_setup() {
#ifdef MAX7219_INIT_TEST
#if MAX7219_INIT_TEST == 2
+ #define MAX7219_LEDS (MAX7219_X_LEDS * MAX7219_Y_LEDS)
+
void Max7219::spiral(const bool on, const uint16_t del) {
- constexpr int8_t way[] = { 1, 0, 0, 1, -1, 0, 0, -1 };
+ constexpr int8_t way[][2] = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };
int8_t px = 0, py = 0, dir = 0;
- for (uint8_t i = MAX7219_X_LEDS * MAX7219_Y_LEDS; i--;) {
+ for (IF<(MAX7219_LEDS > 255), uint16_t, uint8_t>::type i = MAX7219_LEDS; i--;) {
led_set(px, py, on);
delay(del);
- const int8_t x = px + way[dir], y = py + way[dir + 1];
- if (!WITHIN(x, 0, MAX7219_X_LEDS - 1) || !WITHIN(y, 0, MAX7219_Y_LEDS - 1) || BIT_7219(x, y) == on) dir = (dir + 2) & 0x7;
- px += way[dir]; py += way[dir + 1];
+ const int8_t x = px + way[dir][0], y = py + way[dir][1];
+ if (!WITHIN(x, 0, MAX7219_X_LEDS - 1) || !WITHIN(y, 0, MAX7219_Y_LEDS - 1) || BIT_7219(x, y) == on)
+ dir = (dir + 1) & 0x3;
+ px += way[dir][0];
+ py += way[dir][1];
}
}
diff --git a/Marlin/src/feature/babystep.cpp b/Marlin/src/feature/babystep.cpp
index 1fc2499110..510950095f 100644
--- a/Marlin/src/feature/babystep.cpp
+++ b/Marlin/src/feature/babystep.cpp
@@ -25,7 +25,7 @@
#if ENABLED(BABYSTEPPING)
#include "babystep.h"
-#include "../Marlin.h"
+#include "../MarlinCore.h"
#include "../module/planner.h"
#include "../module/stepper.h"
diff --git a/Marlin/src/feature/backlash.cpp b/Marlin/src/feature/backlash.cpp
index f1a14df49d..43e6d36bec 100644
--- a/Marlin/src/feature/backlash.cpp
+++ b/Marlin/src/feature/backlash.cpp
@@ -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)
diff --git a/Marlin/src/feature/bedlevel/abl/abl.cpp b/Marlin/src/feature/bedlevel/abl/abl.cpp
index d5c5532ad4..738a9526f6 100644
--- a/Marlin/src/feature/bedlevel/abl/abl.cpp
+++ b/Marlin/src/feature/bedlevel/abl/abl.cpp
@@ -35,7 +35,7 @@
#include "../../../lcd/extensible_ui/ui_api.h"
#endif
-xy_int_t bilinear_grid_spacing, bilinear_start;
+xy_pos_t bilinear_grid_spacing, bilinear_start;
xy_float_t bilinear_grid_factor;
bed_mesh_t z_values;
@@ -153,7 +153,7 @@ 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];
- xy_int_t bilinear_grid_spacing_virt;
+ xy_pos_t bilinear_grid_spacing_virt;
xy_float_t bilinear_grid_factor_virt;
void print_bilinear_leveling_grid_virt() {
diff --git a/Marlin/src/feature/bedlevel/abl/abl.h b/Marlin/src/feature/bedlevel/abl/abl.h
index 84ab853f8f..15e988fe0a 100644
--- a/Marlin/src/feature/bedlevel/abl/abl.h
+++ b/Marlin/src/feature/bedlevel/abl/abl.h
@@ -23,7 +23,7 @@
#include "../../../inc/MarlinConfigPre.h"
-extern xy_int_t bilinear_grid_spacing, bilinear_start;
+extern xy_pos_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);
diff --git a/Marlin/src/feature/bedlevel/ubl/ubl.cpp b/Marlin/src/feature/bedlevel/ubl/ubl.cpp
index 259ee10966..66eff703c3 100644
--- a/Marlin/src/feature/bedlevel/ubl/ubl.cpp
+++ b/Marlin/src/feature/bedlevel/ubl/ubl.cpp
@@ -51,7 +51,7 @@
if (!isnan(z_values[x][y])) {
SERIAL_ECHO_START();
SERIAL_ECHOPAIR(" M421 I", int(x), " J", int(y));
- SERIAL_ECHOLNPAIR_F(" Z", z_values[x][y], 4);
+ SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, z_values[x][y], 4);
serial_delay(75); // Prevent Printrun from exploding
}
}
diff --git a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp
index d016667e44..ba494aefc5 100644
--- a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp
+++ b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp
@@ -26,7 +26,7 @@
#include "../bedlevel.h"
- #include "../../../Marlin.h"
+ #include "../../../MarlinCore.h"
#include "../../../HAL/shared/persistent_store_api.h"
#include "../../../libs/hex_print_routines.h"
#include "../../../module/configuration_store.h"
@@ -338,7 +338,7 @@
}
z_values[cpos.x][cpos.y] = NAN;
#if ENABLED(EXTENSIBLE_UI)
- ExtUI::onMeshUpdate(closest, 0);
+ ExtUI::onMeshUpdate(cpos, 0.0f);
#endif
cnt++;
}
@@ -541,7 +541,7 @@
else {
z_values[cpos.x][cpos.y] = g29_constant;
#if ENABLED(EXTENSIBLE_UI)
- ExtUI::onMeshUpdate(closest, g29_constant);
+ ExtUI::onMeshUpdate(cpos, g29_constant);
#endif
}
}
@@ -741,13 +741,13 @@
* This attempts to fill in locations closest to the nozzle's start location first.
*/
void unified_bed_leveling::probe_entire_mesh(const xy_pos_t &near, const bool do_ubl_mesh_map, const bool stow_probe, const bool do_furthest) {
+ DEPLOY_PROBE(); // Deploy before ui.capture() to allow for PAUSE_BEFORE_DEPLOY_STOW
+
#if HAS_LCD_MENU
ui.capture();
#endif
save_ubl_active_state_and_disable(); // No bed level correction so only raw data is obtained
- DEPLOY_PROBE();
-
uint8_t count = GRID_MAX_POINTS;
mesh_index_pair best;
@@ -757,17 +757,17 @@
const int point_num = (GRID_MAX_POINTS) - count + 1;
SERIAL_ECHOLNPAIR("\nProbing mesh point ", point_num, "/", int(GRID_MAX_POINTS), ".\n");
#if HAS_DISPLAY
- ui.status_printf_P(0, PSTR(MSG_PROBING_MESH " %i/%i"), point_num, int(GRID_MAX_POINTS));
+ ui.status_printf_P(0, PSTR(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_MESH), point_num, int(GRID_MAX_POINTS));
#endif
#if HAS_LCD_MENU
if (ui.button_pressed()) {
ui.quick_feedback(false); // Preserve button state for click-and-hold
SERIAL_ECHOLNPGM("\nMesh only partially populated.\n");
- STOW_PROBE();
ui.wait_for_release();
ui.quick_feedback();
ui.release();
+ STOW_PROBE(); // Release UI before stow to allow for PAUSE_BEFORE_DEPLOY_STOW
return restore_ubl_active_state_and_leave();
}
#endif
@@ -783,14 +783,20 @@
);
z_values[best.pos.x][best.pos.y] = measured_z;
#if ENABLED(EXTENSIBLE_UI)
- ExtUI::onMeshUpdate(best, measured_z);
+ ExtUI::onMeshUpdate(best.pos, measured_z);
#endif
}
SERIAL_FLUSH(); // Prevent host M105 buffer overrun.
} while (best.pos.x >= 0 && --count);
- STOW_PROBE();
+ #if HAS_LCD_MENU
+ ui.release();
+ #endif
+ STOW_PROBE(); // Release UI during stow to allow for PAUSE_BEFORE_DEPLOY_STOW
+ #if HAS_LCD_MENU
+ ui.capture();
+ #endif
#ifdef Z_AFTER_PROBING
move_z_after_probing();
@@ -849,7 +855,9 @@
static void echo_and_take_a_measurement() { SERIAL_ECHOLNPGM(" and take a measurement."); }
float unified_bed_leveling::measure_business_card_thickness(float in_height) {
- ui.capture();
+ #if HAS_LCD_MENU
+ ui.capture();
+ #endif
save_ubl_active_state_and_disable(); // Disable bed level correction for probing
do_blocking_move_to(0.5f * (MESH_MAX_X - (MESH_MIN_X)), 0.5f * (MESH_MAX_Y - (MESH_MIN_Y)), in_height);
@@ -888,8 +896,9 @@
}
void unified_bed_leveling::manually_probe_remaining_mesh(const xy_pos_t &pos, const float &z_clearance, const float &thick, const bool do_ubl_mesh_map) {
-
- ui.capture();
+ #if HAS_LCD_MENU
+ ui.capture();
+ #endif
save_ubl_active_state_and_disable(); // No bed level correction so only raw data is obtained
do_blocking_move_to_xy_z(current_position, z_clearance);
@@ -917,11 +926,13 @@
do_blocking_move_to_z(z_clearance);
KEEPALIVE_STATE(PAUSED_FOR_USER);
- ui.capture();
+ #if HAS_LCD_MENU
+ ui.capture();
+ #endif
if (do_ubl_mesh_map) display_map(g29_map_type); // show user where we're probing
- serialprintPGM(parser.seen('B') ? PSTR(MSG_UBL_BC_INSERT) : PSTR(MSG_UBL_BC_INSERT2));
+ serialprintPGM(parser.seen('B') ? GET_TEXT(MSG_UBL_BC_INSERT) : GET_TEXT(MSG_UBL_BC_INSERT2));
const float z_step = 0.01f; // existing behavior: 0.01mm per click, occasionally step
//const float z_step = planner.steps_to_mm[Z_AXIS]; // approx one step each click
@@ -959,7 +970,7 @@
void abort_fine_tune() {
ui.return_to_status();
do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
- set_message_with_feedback(PSTR(MSG_EDITING_STOPPED));
+ set_message_with_feedback(GET_TEXT(MSG_EDITING_STOPPED));
}
void unified_bed_leveling::fine_tune_mesh(const xy_pos_t &pos, const bool do_ubl_mesh_map) {
@@ -984,8 +995,9 @@
save_ubl_active_state_and_disable();
LCD_MESSAGEPGM(MSG_UBL_FINE_TUNE_MESH);
- ui.capture(); // Take over control of the LCD encoder
-
+ #if HAS_LCD_MENU
+ ui.capture(); // Take over control of the LCD encoder
+ #endif
do_blocking_move_to_xy_z(pos, Z_CLEARANCE_BETWEEN_PROBES); // Move to the given XY with probe clearance
#if ENABLED(UBL_MESH_EDIT_MOVES_Z)
@@ -1072,7 +1084,7 @@
bool err_flag = false;
#if HAS_LCD_MENU
- set_message_with_feedback(PSTR(MSG_UBL_DOING_G29));
+ set_message_with_feedback(GET_TEXT(MSG_UBL_DOING_G29));
#endif
g29_constant = 0;
@@ -1196,7 +1208,7 @@
if (ubl_state_recursion_chk != 1) {
SERIAL_ECHOLNPGM("save_ubl_active_state_and_disabled() called multiple times in a row.");
#if HAS_LCD_MENU
- set_message_with_feedback(PSTR(MSG_UBL_SAVE_ERROR));
+ set_message_with_feedback(GET_TEXT(MSG_UBL_SAVE_ERROR));
#endif
return;
}
@@ -1210,7 +1222,7 @@
if (--ubl_state_recursion_chk) {
SERIAL_ECHOLNPGM("restore_ubl_active_state_and_leave() called too many times.");
#if HAS_LCD_MENU
- set_message_with_feedback(PSTR(MSG_UBL_RESTORE_ERROR));
+ set_message_with_feedback(GET_TEXT(MSG_UBL_RESTORE_ERROR));
#endif
return;
}
@@ -1335,7 +1347,7 @@
if (!isnan(v2)) {
z_values[x][y] = v1 < v2 ? v1 : v1 + v1 - v2;
#if ENABLED(EXTENSIBLE_UI)
- ExtUI::onMeshUpdate(x, y, z_values[pos.x][pos.y]);
+ ExtUI::onMeshUpdate(x, y, z_values[x][y]);
#endif
return true;
}
@@ -1385,17 +1397,8 @@
dx = (x_max - x_min) / (g29_grid_size - 1),
dy = (y_max - y_min) / (g29_grid_size - 1);
- const vector_3 points[3] = {
- #if ENABLED(HAS_FIXED_3POINT)
- { PROBE_PT_1_X, PROBE_PT_1_Y, 0 },
- { PROBE_PT_2_X, PROBE_PT_2_Y, 0 },
- { PROBE_PT_3_X, PROBE_PT_3_Y, 0 }
- #else
- { x_min, y_min, 0 },
- { x_max, y_min, 0 },
- { (x_max - x_min) / 2, y_max, 0 }
- #endif
- };
+ xy_float_t points[3];
+ get_three_probe_points(points);
float measured_z;
bool abort_flag = false;
@@ -1410,7 +1413,7 @@
if (do_3_pt_leveling) {
SERIAL_ECHOLNPGM("Tilting mesh (1/3)");
#if HAS_DISPLAY
- ui.status_printf_P(0, PSTR(MSG_LCD_TILTING_MESH " 1/3"));
+ ui.status_printf_P(0, PSTR(S_FMT " 1/3"), GET_TEXT(MSG_LCD_TILTING_MESH));
#endif
measured_z = probe_at_point(points[0], PROBE_PT_RAISE, g29_verbose_level);
@@ -1431,7 +1434,7 @@
if (!abort_flag) {
SERIAL_ECHOLNPGM("Tilting mesh (2/3)");
#if HAS_DISPLAY
- ui.status_printf_P(0, PSTR(MSG_LCD_TILTING_MESH " 2/3"));
+ ui.status_printf_P(0, PSTR(S_FMT " 2/3"), GET_TEXT(MSG_LCD_TILTING_MESH));
#endif
measured_z = probe_at_point(points[1], PROBE_PT_RAISE, g29_verbose_level);
@@ -1453,7 +1456,7 @@
if (!abort_flag) {
SERIAL_ECHOLNPGM("Tilting mesh (3/3)");
#if HAS_DISPLAY
- ui.status_printf_P(0, PSTR(MSG_LCD_TILTING_MESH " 3/3"));
+ ui.status_printf_P(0, PSTR(S_FMT " 3/3"), GET_TEXT(MSG_LCD_TILTING_MESH));
#endif
measured_z = probe_at_point(points[2], PROBE_PT_STOW, g29_verbose_level);
@@ -1497,25 +1500,27 @@
if (!abort_flag) {
SERIAL_ECHOLNPAIR("Tilting mesh point ", point_num, "/", total_points, "\n");
#if HAS_DISPLAY
- ui.status_printf_P(0, PSTR(MSG_LCD_TILTING_MESH " %i/%i"), point_num, total_points);
+ ui.status_printf_P(0, PSTR(S_FMT " %i/%i"), GET_TEXT(MSG_LCD_TILTING_MESH), point_num, total_points);
#endif
measured_z = probe_at_point(rpos, parser.seen('E') ? PROBE_PT_STOW : PROBE_PT_RAISE, g29_verbose_level); // TODO: Needs error handling
abort_flag = isnan(measured_z);
- if (DEBUGGING(LEVELING)) {
- const xy_pos_t lpos = rpos.asLogical();
- DEBUG_CHAR('(');
- DEBUG_ECHO_F(rpos.x, 7);
- DEBUG_CHAR(',');
- DEBUG_ECHO_F(rpos.y, 7);
- DEBUG_ECHOPAIR_F(") logical: (", lpos.x, 7);
- DEBUG_CHAR(',');
- DEBUG_ECHO_F(lpos.y, 7);
- DEBUG_ECHOPAIR_F(") measured: ", measured_z, 7);
- DEBUG_ECHOPAIR_F(" correction: ", get_z_correction(rpos), 7);
- }
+ #if ENABLED(DEBUG_LEVELING_FEATURE)
+ if (DEBUGGING(LEVELING)) {
+ const xy_pos_t lpos = rpos.asLogical();
+ DEBUG_CHAR('(');
+ DEBUG_ECHO_F(rpos.x, 7);
+ DEBUG_CHAR(',');
+ DEBUG_ECHO_F(rpos.y, 7);
+ DEBUG_ECHOPAIR_F(") logical: (", lpos.x, 7);
+ DEBUG_CHAR(',');
+ DEBUG_ECHO_F(lpos.y, 7);
+ DEBUG_ECHOPAIR_F(") measured: ", measured_z, 7);
+ DEBUG_ECHOPAIR_F(" correction: ", get_z_correction(rpos), 7);
+ }
+ #endif
measured_z -= get_z_correction(rpos) /* + probe_offset.z */ ;
diff --git a/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp b/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp
index a0d5518c45..f464d0fd6f 100644
--- a/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp
+++ b/Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp
@@ -32,7 +32,7 @@
#include "../../../module/delta.h"
#endif
-#include "../../../Marlin.h"
+#include "../../../MarlinCore.h"
#include
#if !UBL_SEGMENTED
diff --git a/Marlin/src/feature/binary_protocol.h b/Marlin/src/feature/binary_protocol.h
index 56f45003a1..8e69ab7a75 100644
--- a/Marlin/src/feature/binary_protocol.h
+++ b/Marlin/src/feature/binary_protocol.h
@@ -77,7 +77,7 @@ private:
static bool file_open(char* filename) {
if (!dummy_transfer) {
card.mount();
- card.openFile(filename, false);
+ card.openFileWrite(filename);
if (!card.isFileOpen()) return false;
}
transfer_active = true;
@@ -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() {
diff --git a/Marlin/src/feature/cancel_object.cpp b/Marlin/src/feature/cancel_object.cpp
new file mode 100644
index 0000000000..a066815e85
--- /dev/null
+++ b/Marlin/src/feature/cancel_object.cpp
@@ -0,0 +1,83 @@
+/**
+ * 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 .
+ *
+ */
+#include "../inc/MarlinConfig.h"
+
+#if ENABLED(CANCEL_OBJECTS)
+
+#include "cancel_object.h"
+#include "../gcode/gcode.h"
+#include "../lcd/ultralcd.h"
+
+CancelObject cancelable;
+
+int8_t CancelObject::object_count, // = 0
+ CancelObject::active_object = -1;
+uint32_t CancelObject::canceled; // = 0x0000
+bool CancelObject::skipping; // = false
+
+void CancelObject::set_active_object(const int8_t obj) {
+ active_object = obj;
+ if (WITHIN(obj, 0, 31)) {
+ if (obj >= object_count) object_count = obj + 1;
+ skipping = TEST(canceled, obj);
+ }
+ else
+ skipping = false;
+
+ #if HAS_DISPLAY
+ if (active_object >= 0)
+ ui.status_printf_P(0, PSTR(S_FMT " %i"), GET_TEXT(MSG_PRINTING_OBJECT), int(active_object + 1));
+ else
+ ui.reset_status();
+ #endif
+}
+
+void CancelObject::cancel_object(const int8_t obj) {
+ if (WITHIN(obj, 0, 31)) {
+ SBI(canceled, obj);
+ if (obj == active_object) skipping = true;
+ }
+}
+
+void CancelObject::uncancel_object(const int8_t obj) {
+ if (WITHIN(obj, 0, 31)) {
+ CBI(canceled, obj);
+ if (obj == active_object) skipping = false;
+ }
+}
+
+void CancelObject::report() {
+ if (active_object >= 0) {
+ SERIAL_ECHO_START();
+ SERIAL_ECHOLNPAIR("Active Object: ", int(active_object));
+ }
+
+ if (canceled) {
+ SERIAL_ECHO_START();
+ SERIAL_ECHOPGM("Canceled:");
+ for (int i = 0; i < object_count; i++)
+ if (TEST(canceled, i)) { SERIAL_CHAR(' '); SERIAL_ECHO(i); }
+ SERIAL_EOL();
+ }
+}
+
+#endif // CANCEL_OBJECTS
diff --git a/Marlin/src/feature/cancel_object.h b/Marlin/src/feature/cancel_object.h
new file mode 100644
index 0000000000..f32283b46d
--- /dev/null
+++ b/Marlin/src/feature/cancel_object.h
@@ -0,0 +1,41 @@
+/**
+ * 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 .
+ *
+ */
+#pragma once
+
+#include
+
+class CancelObject {
+public:
+ static bool skipping;
+ static int8_t object_count, active_object;
+ static uint32_t canceled;
+ static void set_active_object(const int8_t obj);
+ static void cancel_object(const int8_t obj);
+ static void uncancel_object(const int8_t obj);
+ static void report();
+ static inline bool is_canceled(const int8_t obj) { return TEST(canceled, obj); }
+ static inline void clear_active_object() { set_active_object(-1); }
+ static inline void cancel_active_object() { cancel_object(active_object); }
+ static inline void reset() { canceled = 0x0000; object_count = 0; clear_active_object(); }
+};
+
+extern CancelObject cancelable;
diff --git a/Marlin/src/feature/controllerfan.cpp b/Marlin/src/feature/controllerfan.cpp
index 1a458a2a55..7e4312bab1 100644
--- a/Marlin/src/feature/controllerfan.cpp
+++ b/Marlin/src/feature/controllerfan.cpp
@@ -56,23 +56,9 @@ void controllerfan_update() {
|| Z3_ENABLE_READ() == Z_ENABLE_ON
#endif
#if E_STEPPERS
- || E0_ENABLE_READ() == E_ENABLE_ON
- #if E_STEPPERS > 1
- || E1_ENABLE_READ() == E_ENABLE_ON
- #if E_STEPPERS > 2
- || E2_ENABLE_READ() == E_ENABLE_ON
- #if E_STEPPERS > 3
- || E3_ENABLE_READ() == E_ENABLE_ON
- #if E_STEPPERS > 4
- || E4_ENABLE_READ() == E_ENABLE_ON
- #if E_STEPPERS > 5
- || E5_ENABLE_READ() == E_ENABLE_ON
- #endif // E_STEPPERS > 5
- #endif // E_STEPPERS > 4
- #endif // E_STEPPERS > 3
- #endif // E_STEPPERS > 2
- #endif // E_STEPPERS > 1
- #endif // E_STEPPERS
+ #define _OR_ENABLED_E(N) || E##N##_ENABLE_READ() == E_ENABLE_ON
+ REPEAT(E_STEPPERS, _OR_ENABLED_E)
+ #endif
) {
lastMotorOn = ms; //... set time to NOW so the fan will turn on
}
diff --git a/Marlin/src/feature/dac/dac_dac084s085.cpp b/Marlin/src/feature/dac/dac_dac084s085.cpp
index eb3a67de2a..a07dc071dd 100644
--- a/Marlin/src/feature/dac/dac_dac084s085.cpp
+++ b/Marlin/src/feature/dac/dac_dac084s085.cpp
@@ -10,7 +10,7 @@
#include "dac_dac084s085.h"
-#include "../../Marlin.h"
+#include "../../MarlinCore.h"
#include "../../module/stepper.h"
#include "../../HAL/shared/Delay.h"
diff --git a/Marlin/src/feature/digipot/digipot_mcp4451.cpp b/Marlin/src/feature/digipot/digipot_mcp4451.cpp
index 1b9672251f..b04406f4be 100644
--- a/Marlin/src/feature/digipot/digipot_mcp4451.cpp
+++ b/Marlin/src/feature/digipot/digipot_mcp4451.cpp
@@ -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
diff --git a/Marlin/src/feature/filwidth.h b/Marlin/src/feature/filwidth.h
index 74671b295b..7255428fdf 100644
--- a/Marlin/src/feature/filwidth.h
+++ b/Marlin/src/feature/filwidth.h
@@ -23,6 +23,7 @@
#include "../inc/MarlinConfig.h"
#include "../module/planner.h"
+#include "../module/thermistor/thermistors.h"
class FilamentWidthSensor {
public:
@@ -66,7 +67,7 @@ public:
}
// Convert raw measurement to mm
- static inline float raw_to_mm(const uint16_t v) { return v * 5.0f * RECIPROCAL(16383.0f); }
+ static inline float raw_to_mm(const uint16_t v) { return v * 5.0f * RECIPROCAL(float(MAX_RAW_THERMISTOR_VALUE)); }
static inline float raw_to_mm() { return raw_to_mm(raw); }
// A scaled reading is ready
diff --git a/Marlin/src/feature/host_actions.cpp b/Marlin/src/feature/host_actions.cpp
index b39b0fbc3c..30ec8bfb1d 100644
--- a/Marlin/src/feature/host_actions.cpp
+++ b/Marlin/src/feature/host_actions.cpp
@@ -64,12 +64,20 @@ void host_action(const char * const pstr, const bool eol) {
#if ENABLED(HOST_PROMPT_SUPPORT)
+ const char CONTINUE_STR[] PROGMEM = "Continue";
+
#if HAS_RESUME_CONTINUE
extern bool wait_for_user;
#endif
PromptReason host_prompt_reason = PROMPT_NOT_DEFINED;
+ void host_action_notify(const char * const message) {
+ host_action(PSTR("notification "), false);
+ serialprintPGM(message);
+ SERIAL_EOL();
+ }
+
void host_action_prompt(const char * const ptype, const bool eol=true) {
host_action(PSTR("prompt_"), false);
serialprintPGM(ptype);
@@ -102,8 +110,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;
@@ -126,7 +134,7 @@ void host_action(const char * const pstr, const bool eol) {
host_action_prompt_button(PSTR("DisableRunout"));
else {
host_prompt_reason = PROMPT_FILAMENT_RUNOUT;
- host_action_prompt_button(PSTR("Continue"));
+ host_action_prompt_button(CONTINUE_STR);
}
host_action_prompt_show();
}
@@ -151,7 +159,8 @@ void host_action(const char * const pstr, const bool eol) {
case PROMPT_PAUSE_RESUME:
msg = PSTR("LCD_PAUSE_RESUME");
#if ENABLED(ADVANCED_PAUSE_FEATURE)
- queue.inject_P(PSTR("M24"));
+ extern const char M24_STR[];
+ queue.inject_P(M24_STR);
#endif
break;
case PROMPT_INFO:
diff --git a/Marlin/src/feature/host_actions.h b/Marlin/src/feature/host_actions.h
index 7477b6e6df..57af59eb2e 100644
--- a/Marlin/src/feature/host_actions.h
+++ b/Marlin/src/feature/host_actions.h
@@ -46,6 +46,8 @@ void host_action(const char * const pstr, const bool eol=true);
#if ENABLED(HOST_PROMPT_SUPPORT)
+ extern const char CONTINUE_STR[];
+
enum PromptReason : uint8_t {
PROMPT_NOT_DEFINED,
PROMPT_FILAMENT_RUNOUT,
@@ -58,6 +60,7 @@ void host_action(const char * const pstr, const bool eol=true);
extern PromptReason host_prompt_reason;
void host_response_handler(const uint8_t response);
+ void host_action_notify(const char * const message);
void host_action_prompt_begin(const char * const pstr, const bool eol=true);
void host_action_prompt_button(const char * const pstr);
void host_action_prompt_end();
diff --git a/Marlin/src/feature/joystick.cpp b/Marlin/src/feature/joystick.cpp
index 7ae3f1389e..abfd77f438 100644
--- a/Marlin/src/feature/joystick.cpp
+++ b/Marlin/src/feature/joystick.cpp
@@ -54,13 +54,13 @@ Joystick joystick;
void Joystick::report() {
SERIAL_ECHOPGM("Joystick");
#if HAS_JOY_ADC_X
- SERIAL_ECHOPAIR(" X", x.raw);
+ SERIAL_ECHOPAIR_P(SP_X_STR, x.raw);
#endif
#if HAS_JOY_ADC_Y
- SERIAL_ECHOPAIR(" Y", y.raw);
+ SERIAL_ECHOPAIR_P(SP_Y_STR, y.raw);
#endif
#if HAS_JOY_ADC_Z
- SERIAL_ECHOPAIR(" Z", z.raw);
+ SERIAL_ECHOPAIR_P(SP_Z_STR, z.raw);
#endif
#if HAS_JOY_ADC_EN
SERIAL_ECHO_TERNARY(READ(JOY_EN_PIN), " EN=", "HIGH (dis", "LOW (en", "abled)");
@@ -148,7 +148,7 @@ Joystick joystick;
float hypot2 = 0;
LOOP_XYZ(i) if (norm_jog[i]) {
move_dist[i] = seg_time * norm_jog[i] *
- #if EITHER(ULTIPANEL, EXTENSIBLE_UI)
+ #if ENABLED(EXTENSIBLE_UI)
MMM_TO_MMS(manual_feedrate_mm_m[i]);
#else
planner.settings.max_feedrate_mm_s[i];
diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp
index b319bbab6e..10a1ba6a96 100644
--- a/Marlin/src/feature/pause.cpp
+++ b/Marlin/src/feature/pause.cpp
@@ -29,7 +29,7 @@
#if ENABLED(ADVANCED_PAUSE_FEATURE)
-#include "../Marlin.h"
+#include "../MarlinCore.h"
#include "../gcode/gcode.h"
#include "../module/motion.h"
#include "../module/planner.h"
@@ -53,6 +53,7 @@
#include "../lcd/extensible_ui/ui_api.h"
#endif
+#include "../core/language.h"
#include "../lcd/ultralcd.h"
#if HAS_BUZZER
@@ -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;
@@ -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);
@@ -184,11 +191,11 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
host_action_prompt_begin(PSTR("Load Filament T"), false);
SERIAL_CHAR(tool);
SERIAL_EOL();
- host_action_prompt_button(PSTR("Continue"));
+ host_action_prompt_button(CONTINUE_STR);
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("Filament Purge Running..."), PSTR("Continue"));
+ host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Filament Purge Running..."), CONTINUE_STR);
#endif
#if ENABLED(EXTENSIBLE_UI)
- ExtUI::onUserConfirmRequired(PSTR("Filament 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);
@@ -276,7 +283,7 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
host_action_prompt_button(PSTR("DisableRunout"));
else {
host_prompt_reason = PROMPT_FILAMENT_RUNOUT;
- host_action_prompt_button(PSTR("Continue"));
+ host_action_prompt_button(CONTINUE_STR);
}
host_action_prompt_show();
#endif
@@ -338,14 +345,14 @@ bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/,
#endif
// Retract filament
- do_pause_e_move(-(FILAMENT_UNLOAD_RETRACT_LENGTH) * mix_multiplier, (PAUSE_PARK_RETRACT_FEEDRATE) * mix_multiplier);
+ do_pause_e_move(-(FILAMENT_UNLOAD_PURGE_RETRACT) * mix_multiplier, (PAUSE_PARK_RETRACT_FEEDRATE) * mix_multiplier);
// Wait for filament to cool
- safe_delay(FILAMENT_UNLOAD_DELAY);
+ safe_delay(FILAMENT_UNLOAD_PURGE_DELAY);
// Quickly purge
- do_pause_e_move((FILAMENT_UNLOAD_RETRACT_LENGTH + FILAMENT_UNLOAD_PURGE_LENGTH) * mix_multiplier,
- planner.settings.max_feedrate_mm_s[E_AXIS] * mix_multiplier);
+ do_pause_e_move((FILAMENT_UNLOAD_PURGE_RETRACT + FILAMENT_UNLOAD_PURGE_LENGTH) * mix_multiplier,
+ (FILAMENT_UNLOAD_PURGE_FEEDRATE) * mix_multiplier);
// Unload filament
#if FILAMENT_CHANGE_UNLOAD_ACCEL > 0
@@ -457,7 +464,7 @@ bool pause_print(const float &retract, const xyz_pos_t &park_point, const float
#endif
if (unload_length) // Unload the filament
- unload_filament(unload_length, show_lcd);
+ unload_filament(unload_length, show_lcd, PAUSE_MODE_CHANGE_FILAMENT);
#if ENABLED(DUAL_X_CARRIAGE)
active_extruder = saved_ext;
@@ -481,14 +488,6 @@ bool pause_print(const float &retract, const xyz_pos_t &park_point, const float
* 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);
@@ -524,10 +523,10 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
KEEPALIVE_STATE(PAUSED_FOR_USER);
wait_for_user = true; // LCD click or M108 will clear this
#if ENABLED(HOST_PROMPT_SUPPORT)
- host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Nozzle Parked"), PSTR("Continue"));
+ host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Nozzle Parked"), CONTINUE_STR);
#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
@@ -578,10 +577,10 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
HOTEND_LOOP() thermalManager.hotend_idle[e].start(nozzle_timeout);
#if ENABLED(HOST_PROMPT_SUPPORT)
- host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Reheat Done"), PSTR("Continue"));
+ host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Reheat Done"), CONTINUE_STR);
#endif
#if ENABLED(EXTENSIBLE_UI)
- ExtUI::onUserConfirmRequired("Reheat finished.");
+ ExtUI::onUserConfirmRequired_P(PSTR("Reheat finished."));
#endif
wait_for_user = true;
nozzle_timed_out = false;
@@ -638,7 +637,7 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le
}
if (nozzle_timed_out || thermalManager.hotEnoughToExtrude(active_extruder)) // Load the new filament
- load_filament(slow_load_length, fast_load_length, purge_length, max_beep_count, true, nozzle_timed_out, PAUSE_MODE_PAUSE_PRINT DXC_PASS);
+ load_filament(slow_load_length, fast_load_length, purge_length, max_beep_count, true, nozzle_timed_out, PAUSE_MODE_SAME DXC_PASS);
#if HAS_LCD_MENU
lcd_pause_show_message(PAUSE_MESSAGE_RESUME);
@@ -695,6 +694,10 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le
thermalManager.set_fans_paused(false);
#endif
+ #if HAS_FILAMENT_SENSOR
+ runout.reset();
+ #endif
+
// Resume the print job timer if it was running
if (print_job_timer.isPaused()) print_job_timer.start();
diff --git a/Marlin/src/feature/power.cpp b/Marlin/src/feature/power.cpp
index 777c7a052e..4a61f8a412 100644
--- a/Marlin/src/feature/power.cpp
+++ b/Marlin/src/feature/power.cpp
@@ -31,7 +31,7 @@
#include "power.h"
#include "../module/temperature.h"
#include "../module/stepper/indirection.h"
-#include "../Marlin.h"
+#include "../MarlinCore.h"
Power powerManager;
@@ -59,33 +59,19 @@ bool Power::is_power_needed() {
#if HAS_HEATED_BED
|| thermalManager.temp_bed.soft_pwm_amount > 0
#endif
- #if HAS_X2_ENABLE
- || X2_ENABLE_READ() == X_ENABLE_ON
- #endif
- #if HAS_Y2_ENABLE
- || Y2_ENABLE_READ() == Y_ENABLE_ON
- #endif
- #if HAS_Z2_ENABLE
- || Z2_ENABLE_READ() == Z_ENABLE_ON
- #endif
- #if E_STEPPERS
- || E0_ENABLE_READ() == E_ENABLE_ON
- #if E_STEPPERS > 1
- || E1_ENABLE_READ() == E_ENABLE_ON
- #if E_STEPPERS > 2
- || E2_ENABLE_READ() == E_ENABLE_ON
- #if E_STEPPERS > 3
- || E3_ENABLE_READ() == E_ENABLE_ON
- #if E_STEPPERS > 4
- || E4_ENABLE_READ() == E_ENABLE_ON
- #if E_STEPPERS > 5
- || E5_ENABLE_READ() == E_ENABLE_ON
- #endif // E_STEPPERS > 5
- #endif // E_STEPPERS > 4
- #endif // E_STEPPERS > 3
- #endif // E_STEPPERS > 2
- #endif // E_STEPPERS > 1
- #endif // E_STEPPERS
+ #if HAS_X2_ENABLE
+ || X2_ENABLE_READ() == X_ENABLE_ON
+ #endif
+ #if HAS_Y2_ENABLE
+ || Y2_ENABLE_READ() == Y_ENABLE_ON
+ #endif
+ #if HAS_Z2_ENABLE
+ || Z2_ENABLE_READ() == Z_ENABLE_ON
+ #endif
+ #if E_STEPPERS
+ #define _OR_ENABLED_E(N) || E##N##_ENABLE_READ() == E_ENABLE_ON
+ REPEAT(E_STEPPERS, _OR_ENABLED_E)
+ #endif
) return true;
HOTEND_LOOP() if (thermalManager.degTargetHotend(e) > 0) return true;
@@ -123,7 +109,7 @@ void Power::power_on() {
PSU_PIN_ON();
#if HAS_TRINAMIC
- delay(100); // Wait for power to settle
+ delay(PSU_POWERUP_DELAY); // Wait for power to settle
restore_stepper_drivers();
#endif
}
diff --git a/Marlin/src/feature/power_loss_recovery.cpp b/Marlin/src/feature/power_loss_recovery.cpp
index bf13bb4b1a..0cf0fc5885 100644
--- a/Marlin/src/feature/power_loss_recovery.cpp
+++ b/Marlin/src/feature/power_loss_recovery.cpp
@@ -65,6 +65,9 @@ PrintJobRecovery recovery;
#ifndef POWER_LOSS_RETRACT_LEN
#define POWER_LOSS_RETRACT_LEN 0
#endif
+#ifndef POWER_LOSS_ZRAISE
+ #define POWER_LOSS_ZRAISE 2
+#endif
/**
* Clear the recovery info
@@ -183,6 +186,15 @@ void PrintJobRecovery::save(const bool force/*=false*/, const bool save_queue/*=
info.active_extruder = active_extruder;
#endif
+ #if DISABLED(NO_VOLUMETRICS)
+ info.volumetric_enabled = parser.volumetric_enabled;
+ #if EXTRUDERS > 1
+ for (int8_t e = 0; e < EXTRUDERS; e++) info.filament_size[e] = planner.filament_size[e];
+ #else
+ if (parser.volumetric_enabled) info.filament_size = planner.filament_size[active_extruder];
+ #endif
+ #endif
+
#if EXTRUDERS
HOTEND_LOOP() info.target_temperature[e] = thermalManager.temp_hotend[e].target;
#endif
@@ -226,10 +238,34 @@ void PrintJobRecovery::save(const bool force/*=false*/, const bool save_queue/*=
}
#if PIN_EXISTS(POWER_LOSS)
+
void PrintJobRecovery::_outage() {
- save(true);
- kill(PSTR(MSG_OUTAGE_RECOVERY));
+ #if ENABLED(BACKUP_POWER_SUPPLY)
+ static bool lock = false;
+ if (lock) return; // No re-entrance from idle() during raise_z()
+ lock = true;
+ #endif
+ if (IS_SD_PRINTING()) save(true);
+ #if ENABLED(BACKUP_POWER_SUPPLY)
+ raise_z();
+ #endif
+
+ kill(GET_TEXT(MSG_OUTAGE_RECOVERY));
}
+
+ #if ENABLED(BACKUP_POWER_SUPPLY)
+
+ void PrintJobRecovery::raise_z() {
+ // Disable all heaters to reduce power loss
+ thermalManager.disable_all_heaters();
+ quickstop_stepper();
+ // Raise Z axis
+ gcode.process_subcommands_now_P(PSTR("G91\nG0 Z" STRINGIFY(POWER_LOSS_ZRAISE)));
+ planner.synchronize();
+ }
+
+ #endif
+
#endif
/**
@@ -251,8 +287,6 @@ void PrintJobRecovery::write() {
*/
void PrintJobRecovery::resume() {
- #define RECOVERY_ZRAISE 2
-
const uint32_t resume_sdpos = info.sdpos; // Get here before the stepper ISR overwrites it
#if HAS_LEVELING
@@ -263,15 +297,27 @@ void PrintJobRecovery::resume() {
// Reset E, raise Z, home XY...
gcode.process_subcommands_now_P(PSTR("G92.9 E0"
#if Z_HOME_DIR > 0
- // If Z homing goes to max, reset E and home all
- "\nG28R0"
+
+ // If Z homing goes to max, just reset E and home all
+ "\n"
+ "G28R0"
#if ENABLED(MARLIN_DEV_MODE)
"S"
#endif
- #else
+
+ #else // "G92.9 E0 ..."
+
// Set Z to 0, raise Z by RECOVERY_ZRAISE, and Home (XY only for Cartesian)
// with no raise. (Only do simulated homing in Marlin Dev Mode.)
- "Z0\nG1Z" STRINGIFY(RECOVERY_ZRAISE) "\nG28R0"
+ #if ENABLED(BACKUP_POWER_SUPPLY)
+ "Z" STRINGIFY(POWER_LOSS_ZRAISE) // Z-axis was already raised at outage
+ #else
+ "Z0\n" // Set Z=0
+ "G1Z" STRINGIFY(POWER_LOSS_ZRAISE) // Raise Z
+ #endif
+ "\n"
+
+ "G28R0"
#if ENABLED(MARLIN_DEV_MODE)
"S"
#elif !IS_KINEMATIC
@@ -291,6 +337,27 @@ void PrintJobRecovery::resume() {
gcode.process_subcommands_now(cmd);
#endif
+ // Recover volumetric extrusion state
+ #if DISABLED(NO_VOLUMETRICS)
+ #if EXTRUDERS > 1
+ for (int8_t e = 0; e < EXTRUDERS; e++) {
+ dtostrf(info.filament_size[e], 1, 3, str_1);
+ sprintf_P(cmd, PSTR("M200 T%i D%s"), e, str_1);
+ gcode.process_subcommands_now(cmd);
+ }
+ if (!info.volumetric_enabled) {
+ sprintf_P(cmd, PSTR("M200 T%i D0"), info.active_extruder);
+ gcode.process_subcommands_now(cmd);
+ }
+ #else
+ if (info.volumetric_enabled) {
+ dtostrf(info.filament_size, 1, 3, str_1);
+ sprintf_P(cmd, PSTR("M200 D%s"), str_1);
+ gcode.process_subcommands_now(cmd);
+ }
+ #endif
+ #endif
+
#if HAS_HEATED_BED
const int16_t bt = info.target_temperature_bed;
if (bt) {
@@ -327,9 +394,10 @@ void PrintJobRecovery::resume() {
// Restore retract and hop state
#if ENABLED(FWRETRACT)
for (uint8_t e = 0; e < EXTRUDERS; e++) {
- if (info.retract[e] != 0.0)
+ if (info.retract[e] != 0.0) {
fwretract.current_retract[e] = info.retract[e];
fwretract.retracted[e] = true;
+ }
}
fwretract.current_hop = info.retract_hop;
#endif
@@ -406,7 +474,8 @@ void PrintJobRecovery::resume() {
// Resume the SD file from the last position
char *fn = info.sd_filename;
- sprintf_P(cmd, PSTR("M23 %s"), fn);
+ extern const char M23_STR[];
+ sprintf_P(cmd, M23_STR, fn);
gcode.process_subcommands_now(cmd);
sprintf_P(cmd, PSTR("M24 S%ld T%ld"), resume_sdpos, info.print_job_elapsed);
gcode.process_subcommands_now(cmd);
diff --git a/Marlin/src/feature/power_loss_recovery.h b/Marlin/src/feature/power_loss_recovery.h
index 9f947701e3..771fce44df 100644
--- a/Marlin/src/feature/power_loss_recovery.h
+++ b/Marlin/src/feature/power_loss_recovery.h
@@ -59,6 +59,15 @@ typedef struct {
uint8_t active_extruder;
#endif
+ #if DISABLED(NO_VOLUMETRICS)
+ bool volumetric_enabled;
+ #if EXTRUDERS > 1
+ float filament_size[EXTRUDERS];
+ #else
+ float filament_size;
+ #endif
+ #endif
+
#if HOTENDS
int16_t target_temperature[HOTENDS];
#endif
@@ -159,7 +168,7 @@ class PrintJobRecovery {
#if PIN_EXISTS(POWER_LOSS)
static inline void outage() {
- if (enabled && IS_SD_PRINTING() && READ(POWER_LOSS_PIN) == POWER_LOSS_STATE)
+ if (enabled && READ(POWER_LOSS_PIN) == POWER_LOSS_STATE)
_outage();
}
#endif
@@ -175,6 +184,10 @@ class PrintJobRecovery {
private:
static void write();
+ #if ENABLED(BACKUP_POWER_SUPPLY)
+ static void raise_z();
+ #endif
+
#if PIN_EXISTS(POWER_LOSS)
static void _outage();
#endif
diff --git a/Marlin/src/feature/prusa_MMU2/mmu2.cpp b/Marlin/src/feature/prusa_MMU2/mmu2.cpp
index dd0b2c681c..0e25c86708 100644
--- a/Marlin/src/feature/prusa_MMU2/mmu2.cpp
+++ b/Marlin/src/feature/prusa_MMU2/mmu2.cpp
@@ -36,7 +36,7 @@ MMU2 mmu2;
#include "../../module/temperature.h"
#include "../../module/planner.h"
#include "../../module/stepper/indirection.h"
-#include "../../Marlin.h"
+#include "../../MarlinCore.h"
#if ENABLED(HOST_PROMPT_SUPPORT)
#include "../../feature/host_actions.h"
@@ -97,7 +97,7 @@ volatile int8_t MMU2::finda = 1;
volatile bool MMU2::finda_runout_valid;
int16_t MMU2::version = -1, MMU2::buildnr = -1;
millis_t MMU2::last_request, MMU2::next_P0_request;
-char MMU2::rx_buffer[16], MMU2::tx_buffer[16];
+char MMU2::rx_buffer[MMU_RX_SIZE], MMU2::tx_buffer[MMU_TX_SIZE];
#if HAS_LCD_MENU && ENABLED(MMU2_MENUS)
@@ -433,7 +433,7 @@ bool MMU2::rx_ok() {
void MMU2::check_version() {
if (buildnr < MMU_REQUIRED_FW_BUILDNR) {
SERIAL_ERROR_MSG("Invalid MMU2 firmware. Version >= " STRINGIFY(MMU_REQUIRED_FW_BUILDNR) " required.");
- kill(MSG_MMU2_WRONG_FIRMWARE);
+ kill(GET_TEXT(MSG_MMU2_WRONG_FIRMWARE));
}
}
@@ -449,7 +449,7 @@ void MMU2::tool_change(uint8_t index) {
if (index != extruder) {
disable_E0();
- ui.status_printf_P(0, PSTR(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
+ ui.status_printf_P(0, GET_TEXT(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
command(MMU_CMD_T0 + index);
@@ -709,10 +709,10 @@ void MMU2::filament_runout() {
BUZZ(200, 404);
wait_for_user = true;
#if ENABLED(HOST_PROMPT_SUPPORT)
- host_prompt_do(PROMPT_USER_CONTINUE, PSTR("MMU2 Eject Recover"), PSTR("Continue"));
+ host_prompt_do(PROMPT_USER_CONTINUE, PSTR("MMU2 Eject Recover"), CONTINUE_STR);
#endif
#if ENABLED(EXTENSIBLE_UI)
- ExtUI::onUserConfirmRequired(PSTR("MMU2 Eject Recover"));
+ ExtUI::onUserConfirmRequired_P(PSTR("MMU2 Eject Recover"));
#endif
while (wait_for_user) idle();
BUZZ(200, 404);
diff --git a/Marlin/src/feature/prusa_MMU2/mmu2.h b/Marlin/src/feature/prusa_MMU2/mmu2.h
index e102481c19..9628c4be7f 100644
--- a/Marlin/src/feature/prusa_MMU2/mmu2.h
+++ b/Marlin/src/feature/prusa_MMU2/mmu2.h
@@ -27,6 +27,14 @@
#include "../runout.h"
#endif
+#if SERIAL_USB
+ #define MMU_RX_SIZE 256
+ #define MMU_TX_SIZE 256
+#else
+ #define MMU_RX_SIZE 16
+ #define MMU_TX_SIZE 16
+#endif
+
struct E_Step;
class MMU2 {
@@ -79,7 +87,7 @@ private:
static volatile bool finda_runout_valid;
static int16_t version, buildnr;
static millis_t last_request, next_P0_request;
- static char rx_buffer[16], tx_buffer[16];
+ static char rx_buffer[MMU_RX_SIZE], tx_buffer[MMU_TX_SIZE];
static inline void set_runout_valid(const bool valid) {
finda_runout_valid = valid;
diff --git a/Marlin/src/feature/runout.cpp b/Marlin/src/feature/runout.cpp
index 6b8905c3b9..700854ad2d 100644
--- a/Marlin/src/feature/runout.cpp
+++ b/Marlin/src/feature/runout.cpp
@@ -61,7 +61,7 @@ void FilamentSensorBase::filament_present(const uint8_t extruder) {
//
// Filament Runout event handler
//
-#include "../Marlin.h"
+#include "../MarlinCore.h"
#include "../gcode/queue.h"
#if ENABLED(HOST_ACTION_COMMANDS)
diff --git a/Marlin/src/feature/spindle_laser.cpp b/Marlin/src/feature/spindle_laser.cpp
index 81865fddb6..775e7a864a 100644
--- a/Marlin/src/feature/spindle_laser.cpp
+++ b/Marlin/src/feature/spindle_laser.cpp
@@ -34,14 +34,16 @@ SpindleLaser cutter;
cutter_power_t SpindleLaser::power; // = 0
+#define SPINDLE_LASER_PWM_OFF ((SPINDLE_LASER_PWM_INVERT) ? 255 : 0)
+
void SpindleLaser::init() {
OUT_WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_HIGH); // Init spindle to off
#if ENABLED(SPINDLE_CHANGE_DIR)
OUT_WRITE(SPINDLE_DIR_PIN, SPINDLE_INVERT_DIR ? 255 : 0); // Init rotation to clockwise (M3)
#endif
- #if ENABLED(SPINDLE_LASER_PWM) && PIN_EXISTS(SPINDLE_LASER_PWM)
+ #if ENABLED(SPINDLE_LASER_PWM)
SET_PWM(SPINDLE_LASER_PWM_PIN);
- analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_INVERT ? 255 : 0); // set to lowest speed
+ analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // set to lowest speed
#endif
}
@@ -54,34 +56,34 @@ void SpindleLaser::init() {
*/
void SpindleLaser::set_ocr(const uint8_t ocr) {
WRITE(SPINDLE_LASER_ENA_PIN, SPINDLE_LASER_ACTIVE_HIGH); // turn spindle on (active low)
- #if ENABLED(SPINDLE_LASER_PWM)
- analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), (SPINDLE_LASER_PWM_INVERT) ? 255 - ocr : ocr);
- #endif
+ analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), ocr ^ SPINDLE_LASER_PWM_OFF);
}
#endif
-void SpindleLaser::update_output() {
- const bool ena = enabled();
+void SpindleLaser::apply_power(const cutter_power_t inpow) {
+ static cutter_power_t last_power_applied = 0;
+ if (inpow == last_power_applied) return;
+ last_power_applied = inpow;
#if ENABLED(SPINDLE_LASER_PWM)
- if (ena) {
+ if (enabled()) {
+ #define _scaled(F) ((F - (SPEED_POWER_INTERCEPT)) * inv_slope)
constexpr float inv_slope = RECIPROCAL(SPEED_POWER_SLOPE),
- min_ocr = (SPEED_POWER_MIN - (SPEED_POWER_INTERCEPT)) * inv_slope, // Minimum allowed
- max_ocr = (SPEED_POWER_MAX - (SPEED_POWER_INTERCEPT)) * inv_slope; // Maximum allowed
+ min_ocr = _scaled(SPEED_POWER_MIN),
+ max_ocr = _scaled(SPEED_POWER_MAX);
int16_t ocr_val;
- if (power <= SPEED_POWER_MIN) ocr_val = min_ocr; // Use minimum if set below
- else if (power >= SPEED_POWER_MAX) ocr_val = max_ocr; // Use maximum if set above
- else ocr_val = (power - (SPEED_POWER_INTERCEPT)) * inv_slope; // Use calculated OCR value
- set_ocr(ocr_val & 0xFF); // ...limited to Atmel PWM max
+ if (inpow <= SPEED_POWER_MIN) ocr_val = min_ocr; // Use minimum if set below
+ else if (inpow >= SPEED_POWER_MAX) ocr_val = max_ocr; // Use maximum if set above
+ else ocr_val = _scaled(inpow); // Use calculated OCR value
+ set_ocr(ocr_val & 0xFF); // ...limited to Atmel PWM max
}
- else { // Convert RPM to PWM duty cycle
- WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_HIGH); // Turn spindle off (active low)
- analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_INVERT ? 255 : 0); // Only write low byte
+ else {
+ WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_HIGH); // Turn spindle off (active low)
+ analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // Only write low byte
}
#else
- WRITE(SPINDLE_LASER_ENA_PIN, ena ? SPINDLE_LASER_ACTIVE_HIGH : !SPINDLE_LASER_ACTIVE_HIGH);
+ WRITE(SPINDLE_LASER_ENA_PIN, (SPINDLE_LASER_ACTIVE_HIGH) ? enabled() : !enabled());
#endif
- power_delay(ena);
}
#if ENABLED(SPINDLE_CHANGE_DIR)
diff --git a/Marlin/src/feature/spindle_laser.h b/Marlin/src/feature/spindle_laser.h
index 133152a911..26d7c301b4 100644
--- a/Marlin/src/feature/spindle_laser.h
+++ b/Marlin/src/feature/spindle_laser.h
@@ -36,24 +36,33 @@
#define MSG_CUTTER(M) _MSG_CUTTER(M)
#if SPEED_POWER_MAX > 255
- #define cutter_power_t uint16_t
+ typedef uint16_t cutter_power_t;
#define CUTTER_MENU_TYPE uint16_5
#else
- #define cutter_power_t uint8_t
+ typedef uint8_t cutter_power_t;
#define CUTTER_MENU_TYPE uint8
#endif
class SpindleLaser {
public:
static cutter_power_t power;
+ static inline uint8_t powerPercent(const uint8_t pp) { return ui8_to_percent(pp); } // for display
static void init();
static inline bool enabled() { return !!power; }
- static inline void set_power(const uint8_t pwr) { power = pwr; update_output(); }
+ static inline void set_power(const cutter_power_t pwr) { power = pwr; }
- static inline void set_enabled(const bool enable) { set_power(enable ? 255 : 0); }
+ static inline void refresh() { apply_power(power); }
+
+ static inline void set_enabled(const bool enable) {
+ const bool was = enabled();
+ set_power(enable ? 255 : 0);
+ if (was != enable) power_delay();
+ }
+
+ static void apply_power(const cutter_power_t inpow);
//static bool active() { return READ(SPINDLE_LASER_ENA_PIN) == SPINDLE_LASER_ACTIVE_HIGH; }
@@ -61,11 +70,15 @@ public:
#if ENABLED(SPINDLE_LASER_PWM)
static void set_ocr(const uint8_t ocr);
- static inline void set_ocr_power(const uint8_t pwr) { power = pwr; set_ocr(pwr); }
+ static inline void set_ocr_power(const cutter_power_t pwr) { power = pwr; set_ocr(pwr); }
#endif
// Wait for spindle to spin up or spin down
- static inline void power_delay(const bool on) { safe_delay(on ? SPINDLE_LASER_POWERUP_DELAY : SPINDLE_LASER_POWERDOWN_DELAY); }
+ static inline void power_delay() {
+ #if SPINDLE_LASER_POWERUP_DELAY || SPINDLE_LASER_POWERDOWN_DELAY
+ safe_delay(enabled() ? SPINDLE_LASER_POWERUP_DELAY : SPINDLE_LASER_POWERDOWN_DELAY);
+ #endif
+ }
#if ENABLED(SPINDLE_CHANGE_DIR)
static void set_direction(const bool reverse);
diff --git a/Marlin/src/feature/tmc_util.cpp b/Marlin/src/feature/tmc_util.cpp
index 6b97168f98..f50371d73b 100644
--- a/Marlin/src/feature/tmc_util.cpp
+++ b/Marlin/src/feature/tmc_util.cpp
@@ -25,7 +25,7 @@
#if HAS_TRINAMIC
#include "tmc_util.h"
-#include "../Marlin.h"
+#include "../MarlinCore.h"
#include "../module/stepper/indirection.h"
#include "../module/printcounter.h"
@@ -265,10 +265,30 @@
SERIAL_CHAR('\t');
}
+ #if CURRENT_STEP_DOWN > 0
+
+ template
+ void step_current_down(TMC &st) {
+ if (st.isEnabled()) {
+ const uint16_t I_rms = st.getMilliamps() - (CURRENT_STEP_DOWN);
+ if (I_rms > 50) {
+ st.rms_current(I_rms);
+ #if ENABLED(REPORT_CURRENT_CHANGE)
+ st.printLabel();
+ SERIAL_ECHOLNPAIR(" current decreased to ", I_rms);
+ #endif
+ }
+ }
+ }
+
+ #endif
+
template
- void monitor_tmc_driver(TMC &st, const bool need_update_error_counters, const bool need_debug_reporting) {
+ bool monitor_tmc_driver(TMC &st, const bool need_update_error_counters, const bool need_debug_reporting) {
TMC_driver_data data = get_driver_data(st);
- if (data.drv_status == 0xFFFFFFFF || data.drv_status == 0x0) return;
+ if (data.drv_status == 0xFFFFFFFF || data.drv_status == 0x0) return false;
+
+ bool did_step_down = false;
if (need_update_error_counters) {
if (data.is_ot /* | data.s2ga | data.s2gb*/) st.error_count++;
@@ -288,15 +308,9 @@
#if CURRENT_STEP_DOWN > 0
// Decrease current if is_otpw is true and driver is enabled and there's been more than 4 warnings
- if (data.is_otpw && st.otpw_count > 4) {
- uint16_t I_rms = st.getMilliamps();
- if (st.isEnabled() && I_rms > 100) {
- st.rms_current(I_rms - (CURRENT_STEP_DOWN));
- #if ENABLED(REPORT_CURRENT_CHANGE)
- st.printLabel();
- SERIAL_ECHOLNPAIR(" current decreased to ", st.getMilliamps());
- #endif
- }
+ if (data.is_otpw && st.otpw_count > 4 && st.isEnabled()) {
+ step_current_down(st);
+ did_step_down = true;
}
#endif
@@ -308,64 +322,105 @@
}
#if ENABLED(TMC_DEBUG)
- if (need_debug_reporting)
- report_polled_driver_data(st, data);
+ if (need_debug_reporting) report_polled_driver_data(st, data);
#endif
+
+ return did_step_down;
}
- void monitor_tmc_driver() {
- static millis_t next_poll = 0;
+ void monitor_tmc_drivers() {
const millis_t ms = millis();
- bool need_update_error_counters = ELAPSED(ms, next_poll);
- bool need_debug_reporting = false;
- if (need_update_error_counters)
- next_poll = ms + MONITOR_DRIVER_STATUS_INTERVAL_MS;
+
+ // Poll TMC drivers at the configured interval
+ static millis_t next_poll = 0;
+ const bool need_update_error_counters = ELAPSED(ms, next_poll);
+ if (need_update_error_counters) next_poll = ms + MONITOR_DRIVER_STATUS_INTERVAL_MS;
+
+ // Also poll at intervals for debugging
#if ENABLED(TMC_DEBUG)
static millis_t next_debug_reporting = 0;
- if (report_tmc_status_interval && ELAPSED(ms, next_debug_reporting)) {
- need_debug_reporting = true;
- next_debug_reporting = ms + report_tmc_status_interval;
- }
+ const bool need_debug_reporting = report_tmc_status_interval && ELAPSED(ms, next_debug_reporting);
+ if (need_debug_reporting) next_debug_reporting = ms + report_tmc_status_interval;
+ #else
+ constexpr bool need_debug_reporting = false;
#endif
+
if (need_update_error_counters || need_debug_reporting) {
#if AXIS_IS_TMC(X)
- monitor_tmc_driver(stepperX, need_update_error_counters, need_debug_reporting);
- #endif
- #if AXIS_IS_TMC(Y)
- monitor_tmc_driver(stepperY, need_update_error_counters, need_debug_reporting);
- #endif
- #if AXIS_IS_TMC(Z)
- monitor_tmc_driver(stepperZ, need_update_error_counters, need_debug_reporting);
+ if (monitor_tmc_driver(stepperX, need_update_error_counters, need_debug_reporting)) {
+ #if AXIS_IS_TMC(X2)
+ step_current_down(stepperX2);
+ #endif
+ }
#endif
#if AXIS_IS_TMC(X2)
- monitor_tmc_driver(stepperX2, need_update_error_counters, need_debug_reporting);
+ if (monitor_tmc_driver(stepperX2, need_update_error_counters, need_debug_reporting)) {
+ #if AXIS_IS_TMC(X)
+ step_current_down(stepperX);
+ #endif
+ }
+ #endif
+ #if AXIS_IS_TMC(Y)
+ if (monitor_tmc_driver(stepperY, need_update_error_counters, need_debug_reporting)) {
+ #if AXIS_IS_TMC(Y2)
+ step_current_down(stepperY2);
+ #endif
+ }
#endif
#if AXIS_IS_TMC(Y2)
- monitor_tmc_driver(stepperY2, need_update_error_counters, need_debug_reporting);
+ if (monitor_tmc_driver(stepperY2, need_update_error_counters, need_debug_reporting)) {
+ #if AXIS_IS_TMC(Y)
+ step_current_down(stepperY);
+ #endif
+ }
+ #endif
+ #if AXIS_IS_TMC(Z)
+ if (monitor_tmc_driver(stepperZ, need_update_error_counters, need_debug_reporting)) {
+ #if AXIS_IS_TMC(Z2)
+ step_current_down(stepperZ2);
+ #endif
+ #if AXIS_IS_TMC(Z3)
+ step_current_down(stepperZ3);
+ #endif
+ }
#endif
#if AXIS_IS_TMC(Z2)
- monitor_tmc_driver(stepperZ2, need_update_error_counters, need_debug_reporting);
+ if (monitor_tmc_driver(stepperZ2, need_update_error_counters, need_debug_reporting)) {
+ #if AXIS_IS_TMC(Z)
+ step_current_down(stepperZ);
+ #endif
+ #if AXIS_IS_TMC(Z3)
+ step_current_down(stepperZ3);
+ #endif
+ }
#endif
#if AXIS_IS_TMC(Z3)
- monitor_tmc_driver(stepperZ3, need_update_error_counters, need_debug_reporting);
+ if (monitor_tmc_driver(stepperZ3, need_update_error_counters, need_debug_reporting)) {
+ #if AXIS_IS_TMC(Z)
+ step_current_down(stepperZ);
+ #endif
+ #if AXIS_IS_TMC(Z2)
+ step_current_down(stepperZ2);
+ #endif
+ }
#endif
#if AXIS_IS_TMC(E0)
- monitor_tmc_driver(stepperE0, need_update_error_counters, need_debug_reporting);
+ (void)monitor_tmc_driver(stepperE0, need_update_error_counters, need_debug_reporting);
#endif
#if AXIS_IS_TMC(E1)
- monitor_tmc_driver(stepperE1, need_update_error_counters, need_debug_reporting);
+ (void)monitor_tmc_driver(stepperE1, need_update_error_counters, need_debug_reporting);
#endif
#if AXIS_IS_TMC(E2)
- monitor_tmc_driver(stepperE2, need_update_error_counters, need_debug_reporting);
+ (void)monitor_tmc_driver(stepperE2, need_update_error_counters, need_debug_reporting);
#endif
#if AXIS_IS_TMC(E3)
- monitor_tmc_driver(stepperE3, need_update_error_counters, need_debug_reporting);
+ (void)monitor_tmc_driver(stepperE3, need_update_error_counters, need_debug_reporting);
#endif
#if AXIS_IS_TMC(E4)
- monitor_tmc_driver(stepperE4, need_update_error_counters, need_debug_reporting);
+ (void)monitor_tmc_driver(stepperE4, need_update_error_counters, need_debug_reporting);
#endif
#if AXIS_IS_TMC(E5)
- monitor_tmc_driver(stepperE5, need_update_error_counters, need_debug_reporting);
+ (void)monitor_tmc_driver(stepperE5, need_update_error_counters, need_debug_reporting);
#endif
#if ENABLED(TMC_DEBUG)
@@ -967,7 +1022,7 @@
#if USE_SENSORLESS
bool tmc_enable_stallguard(TMC2130Stepper &st) {
- bool stealthchop_was_enabled = st.en_pwm_mode();
+ const bool stealthchop_was_enabled = st.en_pwm_mode();
st.TCOOLTHRS(0xFFFFF);
st.en_pwm_mode(false);
@@ -983,9 +1038,10 @@
bool tmc_enable_stallguard(TMC2209Stepper &st) {
st.TCOOLTHRS(0xFFFFF);
- return true;
+ return !st.en_spreadCycle();
}
- void tmc_disable_stallguard(TMC2209Stepper &st, const bool restore_stealth _UNUSED) {
+ void tmc_disable_stallguard(TMC2209Stepper &st, const bool restore_stealth) {
+ st.en_spreadCycle(!restore_stealth);
st.TCOOLTHRS(0);
}
@@ -1118,7 +1174,7 @@ void test_tmc_connection(const bool test_x, const bool test_y, const bool test_z
#endif
}
- if (axis_connection) ui.set_status_P(PSTR(MSG_ERROR_TMC));
+ if (axis_connection) ui.set_status_P(GET_TEXT(MSG_ERROR_TMC));
}
#endif // HAS_TRINAMIC
diff --git a/Marlin/src/feature/tmc_util.h b/Marlin/src/feature/tmc_util.h
index 8d0435b4a6..8fa143387a 100644
--- a/Marlin/src/feature/tmc_util.h
+++ b/Marlin/src/feature/tmc_util.h
@@ -169,7 +169,7 @@ template
class TMCMarlin : public TMC2208Stepper, public TMCStorage {
public:
TMCMarlin(Stream * SerialPort, const float RS, const uint8_t) :
- TMC2208Stepper(SerialPort, RS, /*has_rx=*/true)
+ TMC2208Stepper(SerialPort, RS)
{}
TMCMarlin(const uint16_t RX, const uint16_t TX, const float RS, const uint8_t, const bool has_rx=true) :
TMC2208Stepper(RX, TX, RS, has_rx)
@@ -345,7 +345,7 @@ void tmc_print_current(TMC &st) {
}
#endif
-void monitor_tmc_driver();
+void monitor_tmc_drivers();
void test_tmc_connection(const bool test_x, const bool test_y, const bool test_z, const bool test_e);
#if ENABLED(TMC_DEBUG)
@@ -393,34 +393,16 @@ void test_tmc_connection(const bool test_x, const bool test_y, const bool test_z
template
bool TMCMarlin::test_stall_status() {
- uint16_t sg_result = 0;
-
this->switchCSpin(LOW);
- if (this->TMC_SW_SPI != nullptr) {
- this->TMC_SW_SPI->transfer(TMC2130_n::DRV_STATUS_t::address);
- this->TMC_SW_SPI->transfer16(0);
- // We only care about the last 10 bits
- sg_result = this->TMC_SW_SPI->transfer(0);
- sg_result <<= 8;
- sg_result |= this->TMC_SW_SPI->transfer(0);
- }
- else {
- SPI.beginTransaction(SPISettings(16000000/8, MSBFIRST, SPI_MODE3));
- // Read DRV_STATUS
- SPI.transfer(TMC2130_n::DRV_STATUS_t::address);
- SPI.transfer16(0);
- // We only care about the last 10 bits
- sg_result = SPI.transfer(0);
- sg_result <<= 8;
- sg_result |= SPI.transfer(0);
- SPI.endTransaction();
- }
+ // read stallGuard flag from TMC library, will handle HW and SW SPI
+ TMC2130_n::DRV_STATUS_t drv_status{0};
+ drv_status.sr = this->DRV_STATUS();
+
this->switchCSpin(HIGH);
- return (sg_result & 0x3FF) == 0;
+ return drv_status.stallGuard;
}
-
#endif // SPI_ENDSTOPS
#endif // USE_SENSORLESS
diff --git a/Marlin/src/feature/twibus.h b/Marlin/src/feature/twibus.h
index cc40476374..211711ba85 100644
--- a/Marlin/src/feature/twibus.h
+++ b/Marlin/src/feature/twibus.h
@@ -62,7 +62,7 @@ class TWIBus {
* @brief Internal buffer
* @details A fixed buffer. TWI commands can be no longer than this.
*/
- char buffer[TWIBUS_BUFFER_SIZE];
+ uint8_t buffer[TWIBUS_BUFFER_SIZE];
public:
diff --git a/Marlin/src/gcode/bedlevel/G26.cpp b/Marlin/src/gcode/bedlevel/G26.cpp
index 46001411c8..709960ee78 100644
--- a/Marlin/src/gcode/bedlevel/G26.cpp
+++ b/Marlin/src/gcode/bedlevel/G26.cpp
@@ -34,7 +34,7 @@
#include "../../gcode/gcode.h"
#include "../../feature/bedlevel/bedlevel.h"
-#include "../../Marlin.h"
+#include "../../MarlinCore.h"
#include "../../module/planner.h"
#include "../../module/stepper.h"
#include "../../module/motion.h"
@@ -168,7 +168,7 @@ int8_t g26_prime_flag;
*/
bool user_canceled() {
if (!ui.button_pressed()) return false; // Return if the button isn't pressed
- ui.set_status_P(PSTR(MSG_G26_CANCELED), 99);
+ ui.set_status_P(GET_TEXT(MSG_G26_CANCELED), 99);
#if HAS_LCD_MENU
ui.quick_feedback();
#endif
@@ -370,7 +370,7 @@ inline bool turn_on_heaters() {
if (g26_bed_temp > 25) {
#if HAS_SPI_LCD
- ui.set_status_P(PSTR(MSG_G26_HEATING_BED), 99);
+ ui.set_status_P(GET_TEXT(MSG_G26_HEATING_BED), 99);
ui.quick_feedback();
#if HAS_LCD_MENU
ui.capture();
@@ -391,7 +391,7 @@ inline bool turn_on_heaters() {
// Start heating the active nozzle
#if HAS_SPI_LCD
- ui.set_status_P(PSTR(MSG_G26_HEATING_NOZZLE), 99);
+ ui.set_status_P(GET_TEXT(MSG_G26_HEATING_NOZZLE), 99);
ui.quick_feedback();
#endif
thermalManager.setTargetHotend(g26_hotend_temp, active_extruder);
@@ -424,9 +424,10 @@ inline bool prime_nozzle() {
#endif
if (g26_prime_flag == -1) { // The user wants to control how much filament gets purged
-
- ui.capture();
- ui.set_status_P(PSTR(MSG_G26_MANUAL_PRIME), 99);
+ #if HAS_LCD_MENU
+ ui.capture();
+ #endif
+ ui.set_status_P(GET_TEXT(MSG_G26_MANUAL_PRIME), 99);
ui.chirp();
destination = current_position;
@@ -450,7 +451,7 @@ inline bool prime_nozzle() {
ui.wait_for_release();
- ui.set_status_P(PSTR(MSG_G26_PRIME_DONE), 99);
+ ui.set_status_P(GET_TEXT(MSG_G26_PRIME_DONE), 99);
ui.quick_feedback();
ui.release();
}
@@ -458,7 +459,7 @@ inline bool prime_nozzle() {
#endif
{
#if HAS_SPI_LCD
- ui.set_status_P(PSTR(MSG_G26_FIXED_LENGTH), 99);
+ ui.set_status_P(GET_TEXT(MSG_G26_FIXED_LENGTH), 99);
ui.quick_feedback();
#endif
destination = current_position;
@@ -827,7 +828,7 @@ void GcodeSuite::G26() {
} while (--g26_repeats && location.valid());
LEAVE:
- ui.set_status_P(PSTR(MSG_G26_LEAVING), -1);
+ ui.set_status_P(GET_TEXT(MSG_G26_LEAVING), -1);
retract_filament(destination);
destination.z = Z_CLEARANCE_BETWEEN_PROBES;
diff --git a/Marlin/src/gcode/bedlevel/G42.cpp b/Marlin/src/gcode/bedlevel/G42.cpp
index 424e5a6995..b285c798f6 100644
--- a/Marlin/src/gcode/bedlevel/G42.cpp
+++ b/Marlin/src/gcode/bedlevel/G42.cpp
@@ -25,7 +25,7 @@
#if HAS_MESH
#include "../gcode.h"
-#include "../../Marlin.h" // for IsRunning()
+#include "../../MarlinCore.h" // for IsRunning()
#include "../../module/motion.h"
#include "../../module/probe.h" // for probe_offset
#include "../../feature/bedlevel/bedlevel.h"
diff --git a/Marlin/src/gcode/bedlevel/M420.cpp b/Marlin/src/gcode/bedlevel/M420.cpp
index 7794908407..9e96b456e3 100644
--- a/Marlin/src/gcode/bedlevel/M420.cpp
+++ b/Marlin/src/gcode/bedlevel/M420.cpp
@@ -27,6 +27,7 @@
#include "../gcode.h"
#include "../../feature/bedlevel/bedlevel.h"
#include "../../module/planner.h"
+#include "../../module/probe.h"
#if ENABLED(EEPROM_SETTINGS)
#include "../../module/configuration_store.h"
@@ -63,9 +64,9 @@ void GcodeSuite::M420() {
#if ENABLED(MARLIN_DEV_MODE)
if (parser.intval('S') == 2) {
+ const float x_min = probe_min_x(), x_max = probe_max_x(),
+ y_min = probe_min_y(), y_max = probe_max_y();
#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
- const float x_min = probe_min_x(), x_max = probe_max_x(),
- y_min = probe_min_y(), y_max = probe_max_y();
bilinear_start.set(x_min, y_min);
bilinear_grid_spacing.set((x_max - x_min) / (GRID_MAX_POINTS_X - 1),
(y_max - y_min) / (GRID_MAX_POINTS_Y - 1));
diff --git a/Marlin/src/gcode/bedlevel/abl/G29.cpp b/Marlin/src/gcode/bedlevel/abl/G29.cpp
index 5f1ef2e9a3..4503a51cb7 100644
--- a/Marlin/src/gcode/bedlevel/abl/G29.cpp
+++ b/Marlin/src/gcode/bedlevel/abl/G29.cpp
@@ -228,7 +228,7 @@ G29_TYPE GcodeSuite::G29() {
ABL_VAR xy_int8_t meshCount;
#endif
- ABL_VAR xy_int_t probe_position_lf, probe_position_rb;
+ ABL_VAR xy_float_t probe_position_lf, probe_position_rb;
ABL_VAR xy_float_t gridSpacing = { 0, 0 };
#if ENABLED(AUTO_BED_LEVELING_LINEAR)
@@ -263,20 +263,8 @@ G29_TYPE GcodeSuite::G29() {
int constexpr abl_points = 3; // used to show total points
#endif
- // Probe at 3 arbitrary points
- const float x_min = probe_min_x(), x_max = probe_max_x(), y_min = probe_min_y(), y_max = probe_max_y();
-
- ABL_VAR vector_3 points[3] = {
- #if ENABLED(HAS_FIXED_3POINT)
- { PROBE_PT_1_X, PROBE_PT_1_Y, 0 },
- { PROBE_PT_2_X, PROBE_PT_2_Y, 0 },
- { PROBE_PT_3_X, PROBE_PT_3_Y, 0 }
- #else
- { x_min, y_min, 0 },
- { x_max, y_min, 0 },
- { (x_max - x_min) / 2, y_max, 0 }
- #endif
- };
+ vector_3 points[3];
+ get_three_probe_points(points);
#endif // AUTO_BED_LEVELING_3POINT
@@ -415,13 +403,14 @@ G29_TYPE GcodeSuite::G29() {
}
else {
probe_position_lf.set(
- parser.seenval('L') ? (int)RAW_X_POSITION(parser.value_linear_units()) : _MAX(X_CENTER - (X_BED_SIZE) / 2, x_min),
- parser.seenval('F') ? (int)RAW_Y_POSITION(parser.value_linear_units()) : _MAX(Y_CENTER - (Y_BED_SIZE) / 2, y_min)
+ parser.seenval('L') ? (int)RAW_X_POSITION(parser.value_linear_units()) : (_MAX(x_min, X_CENTER - (X_BED_SIZE) / 2) + MIN_PROBE_EDGE_LEFT),
+ parser.seenval('F') ? (int)RAW_Y_POSITION(parser.value_linear_units()) : (_MAX(y_min, Y_CENTER - (Y_BED_SIZE) / 2) + MIN_PROBE_EDGE_FRONT)
);
probe_position_rb.set(
- parser.seenval('R') ? (int)RAW_X_POSITION(parser.value_linear_units()) : _MIN(probe_position_lf.x + X_BED_SIZE, x_max),
- parser.seenval('B') ? (int)RAW_Y_POSITION(parser.value_linear_units()) : _MIN(probe_position_lf.y + Y_BED_SIZE, y_max)
+ parser.seenval('R') ? (int)RAW_X_POSITION(parser.value_linear_units()) : (_MIN(x_max, probe_position_lf.x + X_BED_SIZE) - MIN_PROBE_EDGE_RIGHT),
+ parser.seenval('B') ? (int)RAW_Y_POSITION(parser.value_linear_units()) : (_MIN(y_max, probe_position_lf.y + Y_BED_SIZE) - MIN_PROBE_EDGE_BACK)
);
+ SERIAL_ECHOLN("Set Trail 1");
}
if (
@@ -477,7 +466,7 @@ G29_TYPE GcodeSuite::G29() {
reset_bed_level();
// Initialize a grid with the given dimensions
- bilinear_grid_spacing = gridSpacing.asInt();
+ bilinear_grid_spacing = gridSpacing;
bilinear_start = probe_position_lf;
// Can't re-enable (on error) until the new grid is written
@@ -572,7 +561,7 @@ G29_TYPE GcodeSuite::G29() {
ExtUI::onMeshUpdate(meshCount, newz);
#endif
- if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Save X", meshCount.x, " Y", meshCount.y, " Z", measured_z + zoffset);
+ if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR_P(PSTR("Save X"), meshCount.x, SP_Y_STR, meshCount.y, SP_Z_STR, measured_z + zoffset);
#endif
}
@@ -595,10 +584,7 @@ G29_TYPE GcodeSuite::G29() {
if (zig) PR_INNER_VAR = (PR_INNER_END - 1) - PR_INNER_VAR;
- const xy_pos_t base = probe_position_lf.asFloat() + gridSpacing * meshCount.asFloat();
-
- probePos.set(FLOOR(base.x + (base.x < 0 ? 0 : 0.5)),
- FLOOR(base.y + (base.y < 0 ? 0 : 0.5)));
+ probePos = probe_position_lf + gridSpacing * meshCount.asFloat();
#if ENABLED(AUTO_BED_LEVELING_LINEAR)
indexIntoAB[meshCount.x][meshCount.y] = abl_probe_index;
@@ -686,15 +672,15 @@ G29_TYPE GcodeSuite::G29() {
int8_t inStart, inStop, inInc;
- if (zig) { // away from origin
- inStart = 0;
- inStop = PR_INNER_END;
- inInc = 1;
+ if (zig) { // Zig away from origin
+ inStart = 0; // Left or front
+ inStop = PR_INNER_END; // Right or back
+ inInc = 1; // Zig right
}
- else { // towards origin
- inStart = PR_INNER_END - 1;
- inStop = -1;
- inInc = -1;
+ else { // Zag towards origin
+ inStart = PR_INNER_END - 1; // Right or back
+ inStop = -1; // Left or front
+ inInc = -1; // Zag left
}
zig ^= true; // zag
@@ -706,10 +692,7 @@ G29_TYPE GcodeSuite::G29() {
// Inner loop is X with PROBE_Y_FIRST disabled
for (PR_INNER_VAR = inStart; PR_INNER_VAR != inStop; pt_index++, PR_INNER_VAR += inInc) {
- const xy_pos_t base = probe_position_lf.asFloat() + gridSpacing * meshCount.asFloat();
-
- probePos.set(FLOOR(base.x + (base.x < 0 ? 0 : 0.5)),
- FLOOR(base.y + (base.y < 0 ? 0 : 0.5)));
+ probePos = probe_position_lf + gridSpacing * meshCount.asFloat();
#if ENABLED(AUTO_BED_LEVELING_LINEAR)
indexIntoAB[meshCount.x][meshCount.y] = ++abl_probe_index; // 0...
@@ -722,10 +705,10 @@ G29_TYPE GcodeSuite::G29() {
if (verbose_level) SERIAL_ECHOLNPAIR("Probing mesh point ", int(pt_index), "/", int(GRID_MAX_POINTS), ".");
#if HAS_DISPLAY
- ui.status_printf_P(0, PSTR(S_FMT " %i/%i"), PSTR(MSG_PROBING_MESH), int(pt_index), int(GRID_MAX_POINTS));
+ ui.status_printf_P(0, PSTR(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_MESH), int(pt_index), int(GRID_MAX_POINTS));
#endif
- measured_z = faux ? 0.001 * random(-100, 101) : probe_at_point(probePos, raise_after, verbose_level);
+ measured_z = faux ? 0.001f * random(-100, 101) : probe_at_point(probePos, raise_after, verbose_level);
if (isnan(measured_z)) {
set_bed_leveling_enabled(abl_should_enable);
@@ -746,7 +729,7 @@ G29_TYPE GcodeSuite::G29() {
z_values[meshCount.x][meshCount.y] = measured_z + zoffset;
#if ENABLED(EXTENSIBLE_UI)
- ExtUI::onMeshUpdate(meshCount.x, meshCount.y, z_values[meshCount.x][meshCount.y]);
+ ExtUI::onMeshUpdate(meshCount, z_values[meshCount.x][meshCount.y]);
#endif
#endif
@@ -764,7 +747,7 @@ G29_TYPE GcodeSuite::G29() {
for (uint8_t i = 0; i < 3; ++i) {
if (verbose_level) SERIAL_ECHOLNPAIR("Probing point ", int(i), "/3.");
#if HAS_DISPLAY
- ui.status_printf_P(0, PSTR(MSG_PROBING_MESH " %i/3"), int(i));
+ ui.status_printf_P(0, PSTR(S_FMT " %i/3"), GET_TEXT(MSG_PROBING_MESH), int(i));
#endif
// Retain the last probe position
diff --git a/Marlin/src/gcode/calibrate/G28.cpp b/Marlin/src/gcode/calibrate/G28.cpp
index 7f1fb7705e..b6c0389b31 100644
--- a/Marlin/src/gcode/calibrate/G28.cpp
+++ b/Marlin/src/gcode/calibrate/G28.cpp
@@ -118,7 +118,7 @@
// Disallow Z homing if X or Y are unknown
if (!TEST(axis_known_position, X_AXIS) || !TEST(axis_known_position, Y_AXIS)) {
LCD_MESSAGEPGM(MSG_ERR_Z_HOMING);
- SERIAL_ECHO_MSG(MSG_ERR_Z_HOMING);
+ SERIAL_ECHO_MSG(MSG_ERR_Z_HOMING_SER);
return;
}
@@ -154,7 +154,7 @@
}
else {
LCD_MESSAGEPGM(MSG_ZPROBE_OUT);
- SERIAL_ECHO_MSG(MSG_ZPROBE_OUT);
+ SERIAL_ECHO_MSG(MSG_ZPROBE_OUT_SER);
}
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< home_z_safely");
@@ -162,6 +162,33 @@
#endif // Z_SAFE_HOMING
+#if ENABLED(IMPROVE_HOMING_RELIABILITY)
+
+ slow_homing_t begin_slow_homing() {
+ slow_homing_t slow_homing{0};
+ slow_homing.acceleration.set(planner.settings.max_acceleration_mm_per_s2[X_AXIS],
+ planner.settings.max_acceleration_mm_per_s2[Y_AXIS]);
+ planner.settings.max_acceleration_mm_per_s2[X_AXIS] = 100;
+ planner.settings.max_acceleration_mm_per_s2[Y_AXIS] = 100;
+ #if HAS_CLASSIC_JERK
+ slow_homing.jerk_xy = planner.max_jerk;
+ planner.max_jerk.set(0, 0);
+ #endif
+ planner.reset_acceleration_rates();
+ return slow_homing;
+ }
+
+ void end_slow_homing(const slow_homing_t &slow_homing) {
+ planner.settings.max_acceleration_mm_per_s2[X_AXIS] = slow_homing.acceleration.x;
+ planner.settings.max_acceleration_mm_per_s2[Y_AXIS] = slow_homing.acceleration.y;
+ #if HAS_CLASSIC_JERK
+ planner.max_jerk = slow_homing.jerk_xy;
+ #endif
+ planner.reset_acceleration_rates();
+ }
+
+#endif // IMPROVE_HOMING_RELIABILITY
+
/**
* G28: Home all axes according to settings
*
@@ -203,6 +230,7 @@ void GcodeSuite::G28(const bool always_home_all) {
}
#endif
+ // Home (O)nly if position is unknown
if (!homing_needed() && parser.boolval('O')) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> homing not needed, skip\n<<< G28");
return;
@@ -229,18 +257,37 @@ void GcodeSuite::G28(const bool always_home_all) {
workspace_plane = PLANE_XY;
#endif
- #if ENABLED(IMPROVE_HOMING_RELIABILITY)
- slow_homing_t slow_homing{0};
- slow_homing.acceleration.set(planner.settings.max_acceleration_mm_per_s2[X_AXIS],
- planner.settings.max_acceleration_mm_per_s2[Y_AXIS]);
- planner.settings.max_acceleration_mm_per_s2[X_AXIS] = 100;
- planner.settings.max_acceleration_mm_per_s2[Y_AXIS] = 100;
- #if HAS_CLASSIC_JERK
- slow_homing.jerk_xy = planner.max_jerk;
- planner.max_jerk.set(0, 0);
- #endif
+ #define HAS_CURRENT_HOME(N) (defined(N##_CURRENT_HOME) && N##_CURRENT_HOME != N##_CURRENT)
+ #define HAS_HOMING_CURRENT (HAS_CURRENT_HOME(X) || HAS_CURRENT_HOME(X2) || HAS_CURRENT_HOME(Y) || HAS_CURRENT_HOME(Y2))
- planner.reset_acceleration_rates();
+ #if HAS_HOMING_CURRENT
+ auto debug_current = [](const char * const s, const int16_t a, const int16_t b){
+ DEBUG_ECHO(s); DEBUG_ECHOLNPAIR(" current: ", a, " -> ", b);
+ };
+ #if HAS_CURRENT_HOME(X)
+ const int16_t tmc_save_current_X = stepperX.getMilliamps();
+ stepperX.rms_current(X_CURRENT_HOME);
+ if (DEBUGGING(LEVELING)) debug_current("X", tmc_save_current_X, X_CURRENT_HOME);
+ #endif
+ #if HAS_CURRENT_HOME(X2)
+ const int16_t tmc_save_current_X2 = stepperX2.getMilliamps();
+ stepperX2.rms_current(X2_CURRENT_HOME);
+ if (DEBUGGING(LEVELING)) debug_current("X2", tmc_save_current_X2, X2_CURRENT_HOME);
+ #endif
+ #if HAS_CURRENT_HOME(Y)
+ const int16_t tmc_save_current_Y = stepperY.getMilliamps();
+ stepperY.rms_current(Y_CURRENT_HOME);
+ if (DEBUGGING(LEVELING)) debug_current("Y", tmc_save_current_Y, Y_CURRENT_HOME);
+ #endif
+ #if HAS_CURRENT_HOME(Y2)
+ const int16_t tmc_save_current_Y2 = stepperY2.getMilliamps();
+ stepperY2.rms_current(Y2_CURRENT_HOME);
+ if (DEBUGGING(LEVELING)) debug_current("Y2", tmc_save_current_Y2, Y2_CURRENT_HOME);
+ #endif
+ #endif
+
+ #if ENABLED(IMPROVE_HOMING_RELIABILITY)
+ slow_homing_t slow_homing = begin_slow_homing();
#endif
// Always home with tool 0 active
@@ -264,6 +311,10 @@ void GcodeSuite::G28(const bool always_home_all) {
home_delta();
UNUSED(always_home_all);
+ #if ENABLED(IMPROVE_HOMING_RELIABILITY)
+ end_slow_homing(slow_homing);
+ #endif
+
#else // NOT DELTA
const bool homeX = parser.seen('X'), homeY = parser.seen('Y'), homeZ = parser.seen('Z'),
@@ -287,7 +338,7 @@ void GcodeSuite::G28(const bool always_home_all) {
if (z_homing_height && (doX || doY)) {
// Raise Z before homing any other axes and z is not already high enough (never lower z)
- destination.z = z_homing_height;
+ destination.z = z_homing_height + (TEST(axis_known_position, Z_AXIS) ? 0.0f : current_position.z);
if (destination.z > current_position.z) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Raise Z (before homing) to ", destination.z);
do_blocking_move_to_z(destination.z);
@@ -348,6 +399,10 @@ void GcodeSuite::G28(const bool always_home_all) {
if (doY) homeaxis(Y_AXIS);
#endif
+ #if ENABLED(IMPROVE_HOMING_RELIABILITY)
+ end_slow_homing(slow_homing);
+ #endif
+
// Home Z last if homing towards the bed
#if Z_HOME_DIR < 0
if (doZ) {
@@ -381,6 +436,10 @@ void GcodeSuite::G28(const bool always_home_all) {
if (dxc_is_duplicating()) {
+ #if ENABLED(IMPROVE_HOMING_RELIABILITY)
+ slow_homing = begin_slow_homing();
+ #endif
+
// Always home the 2nd (right) extruder first
active_extruder = 1;
homeaxis(X_AXIS);
@@ -397,10 +456,12 @@ void GcodeSuite::G28(const bool always_home_all) {
delayed_move_time = 0;
active_extruder_parked = true;
extruder_duplication_enabled = IDEX_saved_duplication_state;
- extruder_duplication_enabled = false;
-
dual_x_carriage_mode = IDEX_saved_mode;
stepper.set_directions();
+
+ #if ENABLED(IMPROVE_HOMING_RELIABILITY)
+ end_slow_homing(slow_homing);
+ #endif
}
#endif // DUAL_X_CARRIAGE
@@ -433,13 +494,20 @@ void GcodeSuite::G28(const bool always_home_all) {
tool_change(old_tool_index, NO_FETCH);
#endif
- #if ENABLED(IMPROVE_HOMING_RELIABILITY)
- planner.settings.max_acceleration_mm_per_s2[X_AXIS] = slow_homing.acceleration.x;
- planner.settings.max_acceleration_mm_per_s2[Y_AXIS] = slow_homing.acceleration.y;
- #if HAS_CLASSIC_JERK
- planner.max_jerk = slow_homing.jerk_xy;
+ #if HAS_HOMING_CURRENT
+ if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Restore driver current...");
+ #if HAS_CURRENT_HOME(X)
+ stepperX.rms_current(tmc_save_current_X);
+ #endif
+ #if HAS_CURRENT_HOME(X2)
+ stepperX2.rms_current(tmc_save_current_X2);
+ #endif
+ #if HAS_CURRENT_HOME(Y)
+ stepperY.rms_current(tmc_save_current_Y);
+ #endif
+ #if HAS_CURRENT_HOME(Y2)
+ stepperY2.rms_current(tmc_save_current_Y2);
#endif
- planner.reset_acceleration_rates();
#endif
ui.refresh();
diff --git a/Marlin/src/gcode/calibrate/G33.cpp b/Marlin/src/gcode/calibrate/G33.cpp
index f961302fb5..1931d226af 100644
--- a/Marlin/src/gcode/calibrate/G33.cpp
+++ b/Marlin/src/gcode/calibrate/G33.cpp
@@ -190,7 +190,7 @@ static float std_dev_points(float z_pt[NPP + 1], const bool _0p_cal, const bool
*/
static float calibration_probe(const xy_pos_t &xy, const bool stow) {
#if HAS_BED_PROBE
- return probe_at_point(xy, stow ? PROBE_PT_STOW : PROBE_PT_RAISE, 0, false);
+ return probe_at_point(xy, stow ? PROBE_PT_STOW : PROBE_PT_RAISE, 0, true);
#else
UNUSED(stow);
return lcd_probe_pt(xy);
@@ -222,6 +222,8 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
if (!_0p_calibration) {
+ const float dcr = delta_calibration_radius();
+
if (!_7p_no_intermediates && !_7p_4_intermediates && !_7p_11_intermediates) { // probe the center
const xy_pos_t center{0};
z_pt[CEN] += calibration_probe(center, stow_after_each);
@@ -233,7 +235,7 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
steps = _7p_9_center ? _4P_STEP / 3.0f : _7p_6_center ? _7P_STEP : _4P_STEP;
I_LOOP_CAL_PT(rad, start, steps) {
const float a = RADIANS(210 + (360 / NPP) * (rad - 1)),
- r = delta_calibration_radius * 0.1;
+ r = dcr * 0.1;
const xy_pos_t vec = { cos(a), sin(a) };
z_pt[CEN] += calibration_probe(vec * r, stow_after_each);
if (isnan(z_pt[CEN])) return false;
@@ -257,7 +259,7 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
const int8_t offset = _7p_9_center ? 2 : 0;
for (int8_t circle = 0; circle <= offset; circle++) {
const float a = RADIANS(210 + (360 / NPP) * (rad - 1)),
- r = delta_calibration_radius * (1 - 0.1 * (zig_zag ? offset - circle : circle)),
+ r = dcr * (1 - 0.1 * (zig_zag ? offset - circle : circle)),
interpol = FMOD(rad, 1);
const xy_pos_t vec = { cos(a), sin(a) };
const float z_temp = calibration_probe(vec * r, stow_after_each);
@@ -287,9 +289,10 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
static void reverse_kinematics_probe_points(float z_pt[NPP + 1], abc_float_t mm_at_pt_axis[NPP + 1]) {
xyz_pos_t pos{0};
+ const float dcr = delta_calibration_radius();
LOOP_CAL_ALL(rad) {
const float a = RADIANS(210 + (360 / NPP) * (rad - 1)),
- r = (rad == CEN ? 0.0f : delta_calibration_radius);
+ r = (rad == CEN ? 0.0f : dcr);
pos.set(cos(a) * r, sin(a) * r, z_pt[rad]);
inverse_kinematics(pos);
mm_at_pt_axis[rad] = delta;
@@ -297,7 +300,7 @@ static void reverse_kinematics_probe_points(float z_pt[NPP + 1], abc_float_t mm_
}
static void forward_kinematics_probe_points(abc_float_t mm_at_pt_axis[NPP + 1], float z_pt[NPP + 1]) {
- const float r_quot = delta_calibration_radius / delta_radius;
+ const float r_quot = delta_calibration_radius() / delta_radius;
#define ZPP(N,I,A) (((1.0f + r_quot * (N)) / 3.0f) * mm_at_pt_axis[I].A)
#define Z00(I, A) ZPP( 0, I, A)
@@ -338,7 +341,7 @@ static void calc_kinematics_diff_probe_points(float z_pt[NPP + 1], abc_float_t d
}
static float auto_tune_h() {
- const float r_quot = delta_calibration_radius / delta_radius;
+ const float r_quot = delta_calibration_radius() / delta_radius;
return RECIPROCAL(r_quot / (2.0f / 3.0f)); // (2/3)/CR
}
@@ -450,12 +453,13 @@ void GcodeSuite::G33() {
SERIAL_ECHOLNPGM("G33 Auto Calibrate");
+ const float dcr = delta_calibration_radius();
+
if (!_1p_calibration && !_0p_calibration) { // test if the outer radius is reachable
LOOP_CAL_RAD(axis) {
- const float a = RADIANS(210 + (360 / NPP) * (axis - 1)),
- r = delta_calibration_radius;
- if (!position_is_reachable(cos(a) * r, sin(a) * r)) {
- SERIAL_ECHOLNPGM("?(M665 B)ed radius implausible.");
+ const float a = RADIANS(210 + (360 / NPP) * (axis - 1));
+ if (!position_is_reachable(cos(a) * dcr, sin(a) * dcr)) {
+ SERIAL_ECHOLNPGM("?Bed calibration radius implausible.");
return;
}
}
@@ -522,12 +526,11 @@ void GcodeSuite::G33() {
#define Z0(I) ZP(0, I)
// calculate factors
- const float cr_old = delta_calibration_radius;
- if (_7p_9_center) delta_calibration_radius *= 0.9f;
+ if (_7p_9_center) calibration_radius_factor = 0.9f;
h_factor = auto_tune_h();
r_factor = auto_tune_r();
a_factor = auto_tune_a();
- delta_calibration_radius = cr_old;
+ calibration_radius_factor = 1.0f;
switch (probe_points) {
case 0:
diff --git a/Marlin/src/gcode/calibrate/G34_M422.cpp b/Marlin/src/gcode/calibrate/G34_M422.cpp
index 48ed8fe986..418633f03f 100644
--- a/Marlin/src/gcode/calibrate/G34_M422.cpp
+++ b/Marlin/src/gcode/calibrate/G34_M422.cpp
@@ -25,37 +25,82 @@
#if ENABLED(Z_STEPPER_AUTO_ALIGN)
#include "../gcode.h"
-#include "../../module/delta.h"
-#include "../../module/motion.h"
+#include "../../module/planner.h"
#include "../../module/stepper.h"
-#include "../../module/endstops.h"
+#include "../../module/motion.h"
+#include "../../module/probe.h"
#if HOTENDS > 1
#include "../../module/tool_change.h"
#endif
-#if HAS_BED_PROBE
- #include "../../module/probe.h"
-#endif
-
#if HAS_LEVELING
#include "../../feature/bedlevel/bedlevel.h"
#endif
+#if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
+ #include "../../libs/least_squares_fit.h"
+#endif
+
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
#include "../../core/debug_out.h"
-// Sanity-check
-constexpr xy_pos_t sanity_arr_z_align[] = Z_STEPPER_ALIGN_XY;
-static_assert(COUNT(sanity_arr_z_align) == Z_STEPPER_COUNT,
- #if ENABLED(Z_TRIPLE_STEPPER_DRIVERS)
- "Z_STEPPER_ALIGN_XY requires three {X,Y} entries (Z, Z2, and Z3)."
- #else
- "Z_STEPPER_ALIGN_XY requires two {X,Y} entries (Z and Z2)."
- #endif
-);
+//
+// Sanity check G34 / M422 settings
+//
+constexpr xy_pos_t test_z_stepper_align_xy[] = Z_STEPPER_ALIGN_XY;
-xy_pos_t z_auto_align_pos[Z_STEPPER_COUNT] = Z_STEPPER_ALIGN_XY;
+#if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
+
+ static_assert(COUNT(test_z_stepper_align_xy) >= Z_STEPPER_COUNT,
+ "Z_STEPPER_ALIGN_XY requires at least three {X,Y} entries (Z, Z2, Z3, ...)."
+ );
+
+ constexpr float test_z_stepper_align_stepper_xy[][XY] = Z_STEPPER_ALIGN_STEPPER_XY;
+ static_assert(
+ COUNT(test_z_stepper_align_stepper_xy) == Z_STEPPER_COUNT,
+ "Z_STEPPER_ALIGN_STEPPER_XY requires three {X,Y} entries (one per Z stepper)."
+ );
+
+#else
+
+ static_assert(COUNT(test_z_stepper_align_xy) == Z_STEPPER_COUNT,
+ #if ENABLED(Z_TRIPLE_STEPPER_DRIVERS)
+ "Z_STEPPER_ALIGN_XY requires three {X,Y} entries (Z, Z2, and Z3)."
+ #else
+ "Z_STEPPER_ALIGN_XY requires two {X,Y} entries (Z and Z2)."
+ #endif
+ );
+
+#endif
+
+constexpr xyz_pos_t dpo = NOZZLE_TO_PROBE_OFFSET;
+
+#define LTEST(N) (test_z_stepper_align_xy[N].x >= _MAX(X_MIN_BED + MIN_PROBE_EDGE_LEFT, X_MIN_POS + dpo.x) - 0.00001f)
+#define RTEST(N) (test_z_stepper_align_xy[N].x <= _MIN(X_MAX_BED - MIN_PROBE_EDGE_RIGHT, X_MAX_POS + dpo.x) + 0.00001f)
+#define FTEST(N) (test_z_stepper_align_xy[N].y >= _MAX(Y_MIN_BED + MIN_PROBE_EDGE_FRONT, Y_MIN_POS + dpo.y) - 0.00001f)
+#define BTEST(N) (test_z_stepper_align_xy[N].y <= _MIN(Y_MAX_BED - MIN_PROBE_EDGE_BACK, Y_MAX_POS + dpo.y) + 0.00001f)
+
+static_assert(LTEST(0) && RTEST(0), "The 1st Z_STEPPER_ALIGN_XY X is unreachable with the default probe X offset.");
+static_assert(FTEST(0) && BTEST(0), "The 1st Z_STEPPER_ALIGN_XY Y is unreachable with the default probe Y offset.");
+static_assert(LTEST(1) && RTEST(1), "The 2nd Z_STEPPER_ALIGN_XY X is unreachable with the default probe X offset.");
+static_assert(FTEST(1) && BTEST(1), "The 2nd Z_STEPPER_ALIGN_XY Y is unreachable with the default probe Y offset.");
+
+#if ENABLED(Z_TRIPLE_STEPPER_DRIVERS)
+ static_assert(LTEST(2) && RTEST(2), "The 3rd Z_STEPPER_ALIGN_XY X is unreachable with the default probe X offset.");
+ static_assert(FTEST(2) && BTEST(2), "The 3rd Z_STEPPER_ALIGN_XY Y is unreachable with the default probe Y offset.");
+#endif
+
+//
+// G34 / M422 shared data
+//
+static xy_pos_t z_stepper_align_pos[] = Z_STEPPER_ALIGN_XY;
+
+#if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
+ static xy_pos_t z_stepper_align_stepper_pos[] = Z_STEPPER_ALIGN_STEPPER_XY;
+#endif
+
+#define G34_PROBE_COUNT COUNT(z_stepper_align_pos)
inline void set_all_z_lock(const bool lock) {
stepper.set_z_lock(lock);
@@ -68,7 +113,9 @@ inline void set_all_z_lock(const bool lock) {
/**
* G34: Z-Stepper automatic alignment
*
- * Parameters: I T A
+ * I
+ * T
+ * A
*/
void GcodeSuite::G34() {
if (DEBUGGING(LEVELING)) {
@@ -90,11 +137,18 @@ void GcodeSuite::G34() {
break;
}
- const float z_auto_align_amplification = parser.floatval('A', Z_STEPPER_ALIGN_AMP);
- if (!WITHIN(ABS(z_auto_align_amplification), 0.5f, 2.0f)) {
- SERIAL_ECHOLNPGM("?(A)mplification out of bounds (0.5-2.0).");
- break;
- }
+ const float z_auto_align_amplification =
+ #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
+ Z_STEPPER_ALIGN_AMP;
+ #else
+ parser.floatval('A', Z_STEPPER_ALIGN_AMP);
+ if (!WITHIN(ABS(z_auto_align_amplification), 0.5f, 2.0f)) {
+ SERIAL_ECHOLNPGM("?(A)mplification out of bounds (0.5-2.0).");
+ break;
+ }
+ #endif
+
+ const ProbePtRaise raise_after = parser.boolval('E') ? PROBE_PT_STOW : PROBE_PT_RAISE;
// Wait for planner moves to finish!
planner.synchronize();
@@ -130,13 +184,15 @@ void GcodeSuite::G34() {
#define Z_BASIC_CLEARANCE Z_CLEARANCE_BETWEEN_PROBES
#endif
+ // Compute a worst-case clearance height to probe from. After the first
+ // iteration this will be re-calculated based on the actual bed position
float z_probe = Z_BASIC_CLEARANCE + (G34_MAX_GRADE) * 0.01f * (
#if ENABLED(Z_TRIPLE_STEPPER_DRIVERS)
- SQRT(_MAX(HYPOT2(z_auto_align_pos[0].x - z_auto_align_pos[0].y, z_auto_align_pos[1].x - z_auto_align_pos[1].y),
- HYPOT2(z_auto_align_pos[1].x - z_auto_align_pos[1].y, z_auto_align_pos[2].x - z_auto_align_pos[2].y),
- HYPOT2(z_auto_align_pos[2].x - z_auto_align_pos[2].y, z_auto_align_pos[0].x - z_auto_align_pos[0].y)))
+ SQRT(_MAX(HYPOT2(z_stepper_align_pos[0].x - z_stepper_align_pos[0].y, z_stepper_align_pos[1].x - z_stepper_align_pos[1].y),
+ HYPOT2(z_stepper_align_pos[1].x - z_stepper_align_pos[1].y, z_stepper_align_pos[2].x - z_stepper_align_pos[2].y),
+ HYPOT2(z_stepper_align_pos[2].x - z_stepper_align_pos[2].y, z_stepper_align_pos[0].x - z_stepper_align_pos[0].y)))
#else
- HYPOT(z_auto_align_pos[0].x - z_auto_align_pos[0].y, z_auto_align_pos[1].x - z_auto_align_pos[1].y)
+ HYPOT(z_stepper_align_pos[0].x - z_stepper_align_pos[0].y, z_stepper_align_pos[1].x - z_stepper_align_pos[1].y)
#endif
);
@@ -147,12 +203,10 @@ void GcodeSuite::G34() {
current_position.z -= z_probe * 0.5f;
float last_z_align_move[Z_STEPPER_COUNT] = ARRAY_N(Z_STEPPER_COUNT, 10000.0f, 10000.0f, 10000.0f),
- z_measured[Z_STEPPER_COUNT] = { 0 },
+ z_measured[G34_PROBE_COUNT] = { 0 },
z_maxdiff = 0.0f,
amplification = z_auto_align_amplification;
- const ProbePtRaise raise_after = parser.boolval('E') ? PROBE_PT_STOW : PROBE_PT_RAISE;
-
uint8_t iteration;
bool err_break = false;
for (iteration = 0; iteration < z_auto_align_iterations; ++iteration) {
@@ -161,17 +215,19 @@ void GcodeSuite::G34() {
SERIAL_ECHOLNPAIR("\nITERATION: ", int(iteration + 1));
// Initialize minimum value
- float z_measured_min = 100000.0f;
+ float z_measured_min = 100000.0f,
+ z_measured_max = -100000.0f;
+
// Probe all positions (one per Z-Stepper)
- for (uint8_t izstepper = 0; izstepper < Z_STEPPER_COUNT; ++izstepper) {
+ for (uint8_t i = 0; i < G34_PROBE_COUNT; ++i) {
// iteration odd/even --> downward / upward stepper sequence
- const uint8_t zstepper = (iteration & 1) ? Z_STEPPER_COUNT - 1 - izstepper : izstepper;
+ const uint8_t iprobe = (iteration & 1) ? G34_PROBE_COUNT - 1 - i : i;
// Safe clearance even on an incline
- if (iteration == 0 || izstepper > 0) do_blocking_move_to_z(z_probe);
+ if (iteration == 0 || i > 0) do_blocking_move_to_z(z_probe);
// Probe a Z height for each stepper.
- const float z_probed_height = probe_at_point(z_auto_align_pos[zstepper], raise_after, 0, true);
+ const float z_probed_height = probe_at_point(z_stepper_align_pos[iprobe], raise_after, 0, true);
if (isnan(z_probed_height)) {
SERIAL_ECHOLNPGM("Probing failed.");
err_break = true;
@@ -180,35 +236,58 @@ void GcodeSuite::G34() {
// Add height to each value, to provide a more useful target height for
// the next iteration of probing. This allows adjustments to be made away from the bed.
- z_measured[zstepper] = z_probed_height + Z_CLEARANCE_BETWEEN_PROBES;
+ z_measured[iprobe] = z_probed_height + Z_CLEARANCE_BETWEEN_PROBES;
- if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("> Z", int(zstepper + 1), " measured position is ", z_measured[zstepper]);
+ if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("> Z", int(iprobe + 1), " measured position is ", z_measured[iprobe]);
// Remember the minimum measurement to calculate the correction later on
- z_measured_min = _MIN(z_measured_min, z_measured[zstepper]);
- } // for (zstepper)
+ z_measured_min = _MIN(z_measured_min, z_measured[iprobe]);
+ z_measured_max = _MAX(z_measured_max, z_measured[iprobe]);
+ } // for (i)
if (err_break) break;
// Adapt the next probe clearance height based on the new measurements.
// Safe_height = lowest distance to bed (= highest measurement) plus highest measured misalignment.
- #if ENABLED(Z_TRIPLE_STEPPER_DRIVERS)
- z_maxdiff = _MAX(ABS(z_measured[0] - z_measured[1]), ABS(z_measured[1] - z_measured[2]), ABS(z_measured[2] - z_measured[0]));
- z_probe = Z_BASIC_CLEARANCE + _MAX(z_measured[0], z_measured[1], z_measured[2]) + z_maxdiff;
- #else
- z_maxdiff = ABS(z_measured[0] - z_measured[1]);
- z_probe = Z_BASIC_CLEARANCE + _MAX(z_measured[0], z_measured[1]) + z_maxdiff;
+ z_maxdiff = z_measured_max - z_measured_min;
+ z_probe = Z_BASIC_CLEARANCE + z_measured_max + z_maxdiff;
+
+ #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
+ // Replace the initial values in z_measured with calculated heights at
+ // each stepper position. This allows the adjustment algorithm to be
+ // shared between both possible probing mechanisms.
+
+ // This must be done after the next z_probe height is calculated, so that
+ // the height is calculated from actual print area positions, and not
+ // extrapolated motor movements.
+
+ // Compute the least-squares fit for all probed points.
+ // Calculate the Z position of each stepper and store it in z_measured.
+ // This allows the actual adjustment logic to be shared by both algorithms.
+ linear_fit_data lfd;
+ incremental_LSF_reset(&lfd);
+ for (uint8_t i = 0; i < G34_PROBE_COUNT; ++i) {
+ SERIAL_ECHOLNPAIR("PROBEPT_", int(i + 1), ": ", z_measured[i]);
+ incremental_LSF(&lfd, z_stepper_align_pos[i], z_measured[i]);
+ }
+ finish_incremental_LSF(&lfd);
+
+ z_measured_min = 100000.0f;
+ for (uint8_t i = 0; i < Z_STEPPER_COUNT; ++i) {
+ z_measured[i] = -(lfd.A * z_stepper_align_stepper_pos[i].x + lfd.B * z_stepper_align_stepper_pos[i].y);
+ z_measured_min = _MIN(z_measured_min, z_measured[i]);
+ }
+
+ SERIAL_ECHOLNPAIR("CALCULATED STEPPER POSITIONS: Z1=", z_measured[0], " Z2=", z_measured[1], " Z3=", z_measured[2]);
#endif
- SERIAL_ECHOPAIR("\n"
+ SERIAL_ECHOLNPAIR("\n"
"DIFFERENCE Z1-Z2=", ABS(z_measured[0] - z_measured[1])
#if ENABLED(Z_TRIPLE_STEPPER_DRIVERS)
, " Z2-Z3=", ABS(z_measured[1] - z_measured[2])
, " Z3-Z1=", ABS(z_measured[2] - z_measured[0])
#endif
);
- SERIAL_EOL();
- SERIAL_EOL();
// The following correction actions are to be enabled for select Z-steppers only
stepper.set_separate_multi_axis(true);
@@ -220,8 +299,10 @@ void GcodeSuite::G34() {
const float z_align_move = z_measured[zstepper] - z_measured_min,
z_align_abs = ABS(z_align_move);
- // Optimize one iterations correction based on the first measurements
- if (z_align_abs > 0.0f) amplification = iteration == 1 ? _MIN(last_z_align_move[zstepper] / z_align_abs, 2.0f) : z_auto_align_amplification;
+ #if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
+ // Optimize one iteration's correction based on the first measurements
+ if (z_align_abs > 0.0f) amplification = iteration == 1 ? _MIN(last_z_align_move[zstepper] / z_align_abs, 2.0f) : z_auto_align_amplification;
+ #endif
// Check for less accuracy compared to last move
if (last_z_align_move[zstepper] < z_align_abs - 1.0) {
@@ -266,7 +347,6 @@ void GcodeSuite::G34() {
SERIAL_ECHOLNPAIR("Did ", int(iteration + (iteration != z_auto_align_iterations)), " iterations of ", int(z_auto_align_iterations));
SERIAL_ECHOLNPAIR_F("Accuracy: ", z_maxdiff);
- SERIAL_EOL();
// Restore the active tool after homing
#if HOTENDS > 1
@@ -299,31 +379,97 @@ void GcodeSuite::G34() {
}
/**
- * M422: Z-Stepper automatic alignment parameter selection
+ * M422: Set a Z-Stepper automatic alignment XY point.
+ * Use repeatedly to set multiple points.
+ *
+ * S : Index of the probe point to set
+ *
+ * With Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS:
+ * W : Index of the Z stepper position to set
+ * The W and S parameters may not be combined.
+ *
+ * S and W require an X and/or Y parameter
+ * X : X position to set (Unchanged if omitted)
+ * Y : Y position to set (Unchanged if omitted)
*/
void GcodeSuite::M422() {
- const int8_t zstepper = parser.intval('S') - 1;
- if (!WITHIN(zstepper, 0, Z_STEPPER_COUNT - 1)) {
- SERIAL_ECHOLNPGM("?(S) Z-Stepper index invalid.");
+ if (!parser.seen_any()) {
+ for (uint8_t i = 0; i < G34_PROBE_COUNT; ++i)
+ SERIAL_ECHOLNPAIR_P(PSTR("M422 S"), i + 1, SP_X_STR, z_stepper_align_pos[i].x, SP_Y_STR, z_stepper_align_pos[i].y);
+ #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
+ for (uint8_t i = 0; i < Z_STEPPER_COUNT; ++i)
+ SERIAL_ECHOLNPAIR_P(PSTR("M422 W"), i + 1, SP_X_STR, z_stepper_align_stepper_pos[i].x, SP_Y_STR, z_stepper_align_stepper_pos[i].y);
+ #endif
return;
}
+ const bool is_probe_point = parser.seen('S');
+
+ #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
+ if (is_probe_point && parser.seen('W')) {
+ SERIAL_ECHOLNPGM("?(S) and (W) may not be combined.");
+ return;
+ }
+ #endif
+
+ xy_pos_t *pos_dest = (
+ #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
+ !is_probe_point ? z_stepper_align_stepper_pos :
+ #endif
+ z_stepper_align_pos
+ );
+
+ if (!is_probe_point
+ #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
+ && !parser.seen('W')
+ #endif
+ ) {
+ SERIAL_ECHOLNPGM(
+ #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
+ "?(S) or (W) is required."
+ #else
+ "?(S) is required."
+ #endif
+ );
+ return;
+ }
+
+ // Get the Probe Position Index or Z Stepper Index
+ int8_t position_index;
+ if (is_probe_point) {
+ position_index = parser.intval('S') - 1;
+ if (!WITHIN(position_index, 0, int8_t(G34_PROBE_COUNT) - 1)) {
+ SERIAL_ECHOLNPGM("?(S) Z-ProbePosition index invalid.");
+ return;
+ }
+ }
+ else {
+ #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
+ position_index = parser.intval('W') - 1;
+ if (!WITHIN(position_index, 0, Z_STEPPER_COUNT - 1)) {
+ SERIAL_ECHOLNPGM("?(W) Z-Stepper index invalid.");
+ return;
+ }
+ #endif
+ }
+
const xy_pos_t pos = {
- parser.floatval('X', z_auto_align_pos[zstepper].x),
- parser.floatval('Y', z_auto_align_pos[zstepper].y)
+ parser.floatval('X', pos_dest[position_index].x),
+ parser.floatval('Y', pos_dest[position_index].y)
};
- if (!WITHIN(pos.x, X_MIN_POS, X_MAX_POS)) {
- SERIAL_ECHOLNPGM("?(X) out of bounds.");
- return;
+ if (is_probe_point) {
+ if (!position_is_reachable_by_probe(pos.x, Y_CENTER)) {
+ SERIAL_ECHOLNPGM("?(X) out of bounds.");
+ return;
+ }
+ if (!position_is_reachable_by_probe(pos)) {
+ SERIAL_ECHOLNPGM("?(Y) out of bounds.");
+ return;
+ }
}
- if (!WITHIN(pos.y, Y_MIN_POS, Y_MAX_POS)) {
- SERIAL_ECHOLNPGM("?(Y) out of bounds.");
- return;
- }
-
- z_auto_align_pos[zstepper] = pos;
+ pos_dest[position_index] = pos;
}
#endif // Z_STEPPER_AUTO_ALIGN
diff --git a/Marlin/src/gcode/calibrate/G425.cpp b/Marlin/src/gcode/calibrate/G425.cpp
index 2b2c16657d..28a3276dfd 100644
--- a/Marlin/src/gcode/calibrate/G425.cpp
+++ b/Marlin/src/gcode/calibrate/G425.cpp
@@ -20,7 +20,7 @@
*
*/
-#include "../../Marlin.h"
+#include "../../MarlinCore.h"
#if ENABLED(CALIBRATION_GCODE)
@@ -326,12 +326,12 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
inline void report_measured_center(const measurements_t &m) {
SERIAL_ECHOLNPGM("Center:");
#if HAS_X_CENTER
- SERIAL_ECHOLNPAIR(" X", m.obj_center.x);
+ SERIAL_ECHOLNPAIR_P(SP_X_STR, m.obj_center.x);
#endif
#if HAS_Y_CENTER
- SERIAL_ECHOLNPAIR(" Y", m.obj_center.y);
+ SERIAL_ECHOLNPAIR_P(SP_Y_STR, m.obj_center.y);
#endif
- SERIAL_ECHOLNPAIR(" Z", m.obj_center.z);
+ SERIAL_ECHOLNPAIR_P(SP_Z_STR, m.obj_center.z);
SERIAL_EOL();
}
@@ -358,12 +358,12 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
SERIAL_ECHO(int(active_extruder));
SERIAL_ECHOLNPGM(" Positional Error:");
#if HAS_X_CENTER
- SERIAL_ECHOLNPAIR(" X", m.pos_error.x);
+ SERIAL_ECHOLNPAIR_P(SP_X_STR, m.pos_error.x);
#endif
#if HAS_Y_CENTER
- SERIAL_ECHOLNPAIR(" Y", m.pos_error.y);
+ SERIAL_ECHOLNPAIR_P(SP_Y_STR, m.pos_error.y);
#endif
- SERIAL_ECHOLNPAIR(" Z", m.pos_error.z);
+ SERIAL_ECHOLNPAIR_P(SP_Z_STR, m.pos_error.z);
SERIAL_EOL();
}
@@ -371,10 +371,10 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
SERIAL_ECHOLNPGM("Nozzle Tip Outer Dimensions:");
#if HAS_X_CENTER || HAS_Y_CENTER
#if HAS_X_CENTER
- SERIAL_ECHOLNPAIR(" X", m.nozzle_outer_dimension.x);
+ SERIAL_ECHOLNPAIR_P(SP_X_STR, m.nozzle_outer_dimension.x);
#endif
#if HAS_Y_CENTER
- SERIAL_ECHOLNPAIR(" Y", m.nozzle_outer_dimension.y);
+ SERIAL_ECHOLNPAIR_P(SP_Y_STR, m.nozzle_outer_dimension.y);
#endif
#else
UNUSED(m);
@@ -388,7 +388,7 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
//
inline void report_hotend_offsets() {
for (uint8_t e = 1; e < HOTENDS; e++)
- SERIAL_ECHOLNPAIR("T", int(e), " Hotend Offset X", hotend_offset[e].x, " Y", hotend_offset[e].y, " Z", hotend_offset[e].z);
+ SERIAL_ECHOLNPAIR_P(PSTR("T"), int(e), PSTR(" Hotend Offset X"), hotend_offset[e].x, SP_Y_STR, hotend_offset[e].y, SP_Z_STR, hotend_offset[e].z);
}
#endif
diff --git a/Marlin/src/gcode/calibrate/M100.cpp b/Marlin/src/gcode/calibrate/M100.cpp
index a6f4f8f5d2..0318af0a68 100644
--- a/Marlin/src/gcode/calibrate/M100.cpp
+++ b/Marlin/src/gcode/calibrate/M100.cpp
@@ -28,7 +28,7 @@
#include "../queue.h"
#include "../../libs/hex_print_routines.h"
-#include "../../Marlin.h" // for idle()
+#include "../../MarlinCore.h" // for idle()
/**
* M100 Free Memory Watcher
@@ -51,7 +51,7 @@
* Also, there are two support functions that can be called from a developer's C code.
*
* uint16_t check_for_free_memory_corruption(PGM_P const free_memory_start);
- * void M100_dump_routine(PGM_P const title, char *start, char *end);
+ * void M100_dump_routine(PGM_P const title, const char * const start, const char * const end);
*
* Initial version by Roxy-3D
*/
@@ -151,8 +151,8 @@ inline int32_t count_test_bytes(const char * const start_free_memory) {
// Start and end the dump on a nice 16 byte boundary
// (even though the values are not 16-byte aligned).
//
- start_free_memory = (char*)((ptr_int_t)((uint32_t)start_free_memory & 0xFFFFFFF0)); // Align to 16-byte boundary
- end_free_memory = (char*)((ptr_int_t)((uint32_t)end_free_memory | 0x0000000F)); // Align end_free_memory to the 15th byte (at or above end_free_memory)
+ start_free_memory = (char*)(ptr_int_t(uint32_t(start_free_memory) & ~0xFUL)); // Align to 16-byte boundary
+ end_free_memory = (char*)(ptr_int_t(uint32_t(end_free_memory) | 0xFUL)); // Align end_free_memory to the 15th byte (at or above end_free_memory)
// Dump command main loop
while (start_free_memory < end_free_memory) {
@@ -177,15 +177,16 @@ inline int32_t count_test_bytes(const char * const start_free_memory) {
}
}
- void M100_dump_routine(PGM_P const title, char *start, char *end) {
+ void M100_dump_routine(PGM_P const title, const char * const start, const char * const end) {
serialprintPGM(title);
SERIAL_EOL();
//
// Round the start and end locations to produce full lines of output
//
- start = (char*)((ptr_int_t)((uint32_t)start & 0xFFFFFFF0)); // Align to 16-byte boundary
- end = (char*)((ptr_int_t)((uint32_t)end | 0x0000000F)); // Align end_free_memory to the 15th byte (at or above end_free_memory)
- dump_free_memory(start, end);
+ dump_free_memory(
+ (char*)(ptr_int_t(uint32_t(start) & ~0xFUL)), // Align to 16-byte boundary
+ (char*)(ptr_int_t(uint32_t(end) | 0xFUL)) // Align end_free_memory to the 15th byte (at or above end_free_memory)
+ );
}
#endif // M100_FREE_MEMORY_DUMPER
@@ -211,7 +212,7 @@ inline int check_for_free_memory_corruption(PGM_P const title) {
// idle();
serial_delay(20);
#if ENABLED(M100_FREE_MEMORY_DUMPER)
- M100_dump_routine(PSTR(" Memory corruption detected with end_free_memory 5.0) ? -1 : 1; // clockwise or counter clockwise
@@ -178,12 +178,12 @@ void GcodeSuite::M48() {
while (!position_is_reachable_by_probe(next_pos)) {
next_pos *= 0.8f;
if (verbose_level > 3)
- SERIAL_ECHOLNPAIR("Moving inward: X", next_pos.x, " Y", next_pos.y);
+ SERIAL_ECHOLNPAIR_P(PSTR("Moving inward: X"), next_pos.x, SP_Y_STR, next_pos.y);
}
#endif
if (verbose_level > 3)
- SERIAL_ECHOLNPAIR("Going to: X", next_pos.x, " Y", next_pos.y);
+ SERIAL_ECHOLNPAIR_P(PSTR("Going to: X"), next_pos.x, SP_Y_STR, next_pos.y);
do_blocking_move_to_xy(next_pos);
} // n_legs loop
@@ -252,7 +252,7 @@ void GcodeSuite::M48() {
#if HAS_SPI_LCD
// Display M48 results in the status bar
char sigma_str[8];
- ui.status_printf_P(0, PSTR(MSG_M48_DEVIATION ": %s"), dtostrf(sigma, 2, 6, sigma_str));
+ ui.status_printf_P(0, PSTR(S_FMT ": %s"), GET_TEXT(MSG_M48_DEVIATION), dtostrf(sigma, 2, 6, sigma_str));
#endif
}
diff --git a/Marlin/src/gcode/calibrate/M665.cpp b/Marlin/src/gcode/calibrate/M665.cpp
index 1b37fa8bb6..6234265b3d 100644
--- a/Marlin/src/gcode/calibrate/M665.cpp
+++ b/Marlin/src/gcode/calibrate/M665.cpp
@@ -37,7 +37,6 @@
* L = diagonal rod
* R = delta radius
* S = segments per second
- * B = delta calibration radius
* X = Alpha (Tower 1) angle trim
* Y = Beta (Tower 2) angle trim
* Z = Gamma (Tower 3) angle trim
@@ -47,7 +46,6 @@
if (parser.seen('L')) delta_diagonal_rod = parser.value_linear_units();
if (parser.seen('R')) delta_radius = parser.value_linear_units();
if (parser.seen('S')) delta_segments_per_second = parser.value_float();
- if (parser.seen('B')) delta_calibration_radius = parser.value_float();
if (parser.seen('X')) delta_tower_angle_trim.a = parser.value_float();
if (parser.seen('Y')) delta_tower_angle_trim.b = parser.value_float();
if (parser.seen('Z')) delta_tower_angle_trim.c = parser.value_float();
diff --git a/Marlin/src/gcode/calibrate/M852.cpp b/Marlin/src/gcode/calibrate/M852.cpp
index 156d1f5bf6..4bb068e5b2 100644
--- a/Marlin/src/gcode/calibrate/M852.cpp
+++ b/Marlin/src/gcode/calibrate/M852.cpp
@@ -93,13 +93,13 @@ void GcodeSuite::M852() {
if (!ijk) {
SERIAL_ECHO_START();
- SERIAL_ECHOLNPAIR_F(MSG_SKEW_FACTOR " XY: ", planner.skew_factor.xy, 6);
+ serialprintPGM(GET_TEXT(MSG_SKEW_FACTOR));
+ SERIAL_ECHOPAIR_F(" XY: ", planner.skew_factor.xy, 6);
#if ENABLED(SKEW_CORRECTION_FOR_Z)
- SERIAL_ECHOPAIR(" XZ: ", planner.skew_factor.xz);
- SERIAL_ECHOLNPAIR(" YZ: ", planner.skew_factor.yz);
- #else
- SERIAL_EOL();
+ SERIAL_ECHOPAIR_F(" XZ: ", planner.skew_factor.xz, 6);
+ SERIAL_ECHOPAIR_F(" YZ: ", planner.skew_factor.yz, 6);
#endif
+ SERIAL_EOL();
}
}
diff --git a/Marlin/src/gcode/config/M200-M205.cpp b/Marlin/src/gcode/config/M200-M205.cpp
index e3cd42feb0..594813e038 100644
--- a/Marlin/src/gcode/config/M200-M205.cpp
+++ b/Marlin/src/gcode/config/M200-M205.cpp
@@ -21,7 +21,7 @@
*/
#include "../gcode.h"
-#include "../../Marlin.h"
+#include "../../MarlinCore.h"
#include "../../module/planner.h"
#if DISABLED(NO_VOLUMETRICS)
@@ -117,10 +117,10 @@ void GcodeSuite::M204() {
* Y = Max Y Jerk (units/sec^2)
* Z = Max Z Jerk (units/sec^2)
* E = Max E Jerk (units/sec^2)
- * J = Junction Deviation (mm) (Requires JUNCTION_DEVIATION)
+ * J = Junction Deviation (mm) (If not using CLASSIC_JERK)
*/
void GcodeSuite::M205() {
- #if ENABLED(JUNCTION_DEVIATION)
+ #if DISABLED(CLASSIC_JERK)
#define J_PARAM "J"
#else
#define J_PARAM
@@ -136,7 +136,7 @@ void GcodeSuite::M205() {
if (parser.seen('B')) planner.settings.min_segment_time_us = parser.value_ulong();
if (parser.seen('S')) planner.settings.min_feedrate_mm_s = parser.value_linear_units();
if (parser.seen('T')) planner.settings.min_travel_feedrate_mm_s = parser.value_linear_units();
- #if ENABLED(JUNCTION_DEVIATION)
+ #if DISABLED(CLASSIC_JERK)
if (parser.seen('J')) {
const float junc_dev = parser.value_linear_units();
if (WITHIN(junc_dev, 0.01f, 0.3f)) {
@@ -159,7 +159,7 @@ void GcodeSuite::M205() {
SERIAL_ECHOLNPGM("WARNING! Low Z Jerk may lead to unwanted pauses.");
#endif
}
- #if !BOTH(JUNCTION_DEVIATION, LIN_ADVANCE)
+ #if HAS_CLASSIC_E_JERK
if (parser.seen('E')) planner.set_max_jerk(E_AXIS, parser.value_linear_units());
#endif
#endif
diff --git a/Marlin/src/gcode/config/M217.cpp b/Marlin/src/gcode/config/M217.cpp
index ade8c280f7..57178950cb 100644
--- a/Marlin/src/gcode/config/M217.cpp
+++ b/Marlin/src/gcode/config/M217.cpp
@@ -27,18 +27,22 @@
#include "../gcode.h"
#include "../../module/tool_change.h"
+#include "../../MarlinCore.h" // for SP_X_STR, etc.
+
+extern const char SP_X_STR[], SP_Y_STR[], SP_Z_STR[];
+
void M217_report(const bool eeprom=false) {
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
serialprintPGM(eeprom ? PSTR(" M217") : PSTR("Toolchange:"));
SERIAL_ECHOPAIR(" S", LINEAR_UNIT(toolchange_settings.swap_length));
- SERIAL_ECHOPAIR(" E", LINEAR_UNIT(toolchange_settings.extra_prime));
+ SERIAL_ECHOPAIR_P(SP_E_STR, LINEAR_UNIT(toolchange_settings.extra_prime));
SERIAL_ECHOPAIR(" P", LINEAR_UNIT(toolchange_settings.prime_speed));
SERIAL_ECHOPAIR(" R", LINEAR_UNIT(toolchange_settings.retract_speed));
#if ENABLED(TOOLCHANGE_PARK)
- SERIAL_ECHOPAIR(" X", LINEAR_UNIT(toolchange_settings.change_point.x));
- SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(toolchange_settings.change_point.y));
+ SERIAL_ECHOPAIR_P(SP_X_STR, LINEAR_UNIT(toolchange_settings.change_point.x));
+ SERIAL_ECHOPAIR_P(SP_Y_STR, LINEAR_UNIT(toolchange_settings.change_point.y));
#endif
#else
@@ -47,7 +51,7 @@ void M217_report(const bool eeprom=false) {
#endif
- SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(toolchange_settings.z_raise));
+ SERIAL_ECHOPAIR_P(SP_Z_STR, LINEAR_UNIT(toolchange_settings.z_raise));
SERIAL_EOL();
}
diff --git a/Marlin/src/gcode/config/M220.cpp b/Marlin/src/gcode/config/M220.cpp
index 50939b279b..3710a30ab9 100644
--- a/Marlin/src/gcode/config/M220.cpp
+++ b/Marlin/src/gcode/config/M220.cpp
@@ -24,11 +24,23 @@
#include "../../module/motion.h"
/**
- * M220: Set speed percentage factor, aka "Feed Rate" (M220 S95)
+ * M220: Set speed percentage factor, aka "Feed Rate"
+ *
+ * Parameters
+ * S : Set the feed rate percentage factor
+ *
+ * With PRUSA_MMU2...
+ * B : Flag to back up the current factor
+ * R : Flag to restore the last-saved factor
*/
void GcodeSuite::M220() {
- if (parser.seenval('S'))
- feedrate_percentage = parser.value_int();
+ #if ENABLED(PRUSA_MMU2)
+ static int16_t backup_feedrate_percentage = 100;
+ if (parser.seen('B')) backup_feedrate_percentage = feedrate_percentage;
+ if (parser.seen('R')) feedrate_percentage = backup_feedrate_percentage;
+ #endif
+
+ if (parser.seenval('S')) feedrate_percentage = parser.value_int();
}
diff --git a/Marlin/src/gcode/config/M301.cpp b/Marlin/src/gcode/config/M301.cpp
index 25a15d7728..0449293bf5 100644
--- a/Marlin/src/gcode/config/M301.cpp
+++ b/Marlin/src/gcode/config/M301.cpp
@@ -38,6 +38,10 @@
*
* C[float] Kc term
* L[int] LPQ length
+ *
+ * With PID_FAN_SCALING:
+ *
+ * F[float] Kf term
*/
void GcodeSuite::M301() {
@@ -56,6 +60,10 @@ void GcodeSuite::M301() {
NOLESS(thermalManager.lpq_len, 0);
#endif
+ #if ENABLED(PID_FAN_SCALING)
+ if (parser.seen('F')) PID_PARAM(Kf, e) = parser.value_float();
+ #endif
+
thermalManager.updatePID();
SERIAL_ECHO_START();
#if ENABLED(PID_PARAMS_PER_HOTEND)
@@ -65,9 +73,12 @@ void GcodeSuite::M301() {
" i:", unscalePID_i(PID_PARAM(Ki, e)),
" d:", unscalePID_d(PID_PARAM(Kd, e)));
#if ENABLED(PID_EXTRUSION_SCALING)
- //Kc does not have scaling applied above, or in resetting defaults
SERIAL_ECHOPAIR(" c:", PID_PARAM(Kc, e));
#endif
+ #if ENABLED(PID_FAN_SCALING)
+ SERIAL_ECHOPAIR(" f:", PID_PARAM(Kf, e));
+ #endif
+
SERIAL_EOL();
}
else
diff --git a/Marlin/src/gcode/config/M43.cpp b/Marlin/src/gcode/config/M43.cpp
index 34d42ed499..5937b4c721 100644
--- a/Marlin/src/gcode/config/M43.cpp
+++ b/Marlin/src/gcode/config/M43.cpp
@@ -25,7 +25,7 @@
#if ENABLED(PINS_DEBUGGING)
#include "../gcode.h"
-#include "../../Marlin.h" // for pin_is_protected
+#include "../../MarlinCore.h" // for pin_is_protected
#include "../../pins/pinsDebug.h"
#include "../../module/endstops.h"
@@ -331,10 +331,10 @@ void GcodeSuite::M43() {
KEEPALIVE_STATE(PAUSED_FOR_USER);
wait_for_user = true;
#if ENABLED(HOST_PROMPT_SUPPORT)
- host_prompt_do(PROMPT_USER_CONTINUE, PSTR("M43 Wait Called"), PSTR("Continue"));
+ host_prompt_do(PROMPT_USER_CONTINUE, PSTR("M43 Wait Called"), CONTINUE_STR);
#endif
#if ENABLED(EXTENSIBLE_UI)
- ExtUI::onUserConfirmRequired(PSTR("M43 Wait Called"));
+ ExtUI::onUserConfirmRequired_P(PSTR("M43 Wait Called"));
#endif
#endif
diff --git a/Marlin/src/gcode/config/M92.cpp b/Marlin/src/gcode/config/M92.cpp
index 8626864b6c..212b6f83b7 100644
--- a/Marlin/src/gcode/config/M92.cpp
+++ b/Marlin/src/gcode/config/M92.cpp
@@ -25,11 +25,11 @@
void report_M92(const bool echo=true, const int8_t e=-1) {
if (echo) SERIAL_ECHO_START(); else SERIAL_CHAR(' ');
- SERIAL_ECHOPAIR(" M92 X", LINEAR_UNIT(planner.settings.axis_steps_per_mm[X_AXIS]),
- " Y", LINEAR_UNIT(planner.settings.axis_steps_per_mm[Y_AXIS]),
- " Z", LINEAR_UNIT(planner.settings.axis_steps_per_mm[Z_AXIS]));
+ SERIAL_ECHOPAIR_P(PSTR(" M92 X"), LINEAR_UNIT(planner.settings.axis_steps_per_mm[X_AXIS]),
+ SP_Y_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Y_AXIS]),
+ SP_Z_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Z_AXIS]));
#if DISABLED(DISTINCT_E_FACTORS)
- SERIAL_ECHOPAIR(" E", VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS]));
+ SERIAL_ECHOPAIR_P(SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS]));
#endif
SERIAL_EOL();
@@ -37,8 +37,8 @@ void report_M92(const bool echo=true, const int8_t e=-1) {
for (uint8_t i = 0; i < E_STEPPERS; i++) {
if (e >= 0 && i != e) continue;
if (echo) SERIAL_ECHO_START(); else SERIAL_CHAR(' ');
- SERIAL_ECHOLNPAIR(" M92 T", (int)i,
- " E", VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS_N(i)]));
+ SERIAL_ECHOLNPAIR_P(PSTR(" M92 T"), (int)i,
+ SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS_N(i)]));
}
#endif
@@ -76,7 +76,7 @@ void GcodeSuite::M92() {
const float value = parser.value_per_axis_units((AxisEnum)(E_AXIS_N(target_extruder)));
if (value < 20) {
float factor = planner.settings.axis_steps_per_mm[E_AXIS_N(target_extruder)] / value; // increase e constants if M92 E14 is given for netfab.
- #if HAS_CLASSIC_JERK && !BOTH(JUNCTION_DEVIATION, LIN_ADVANCE)
+ #if HAS_CLASSIC_JERK && HAS_CLASSIC_E_JERK
planner.max_jerk.e *= factor;
#endif
planner.settings.max_feedrate_mm_s[E_AXIS_N(target_extruder)] *= factor;
diff --git a/Marlin/src/gcode/control/M108_M112_M410.cpp b/Marlin/src/gcode/control/M108_M112_M410.cpp
index 9b6193bd93..e083dd0978 100644
--- a/Marlin/src/gcode/control/M108_M112_M410.cpp
+++ b/Marlin/src/gcode/control/M108_M112_M410.cpp
@@ -25,7 +25,7 @@
#if DISABLED(EMERGENCY_PARSER)
#include "../gcode.h"
-#include "../../Marlin.h" // for wait_for_heatup, kill, quickstop_stepper
+#include "../../MarlinCore.h" // for wait_for_heatup, kill, quickstop_stepper
/**
* M108: Stop the waiting for heaters in M109, M190, M303. Does not affect the target temperature.
@@ -41,7 +41,7 @@ void GcodeSuite::M108() {
* M112: Full Shutdown
*/
void GcodeSuite::M112() {
- kill(PSTR("M112 Shutdown"), true);
+ kill(PSTR("M112 Shutdown"), nullptr, true);
}
/**
diff --git a/Marlin/src/gcode/control/M17_M18_M84.cpp b/Marlin/src/gcode/control/M17_M18_M84.cpp
index de6eab4f74..081ca18d89 100644
--- a/Marlin/src/gcode/control/M17_M18_M84.cpp
+++ b/Marlin/src/gcode/control/M17_M18_M84.cpp
@@ -21,7 +21,7 @@
*/
#include "../gcode.h"
-#include "../../Marlin.h" // for stepper_inactive_time, disable_e_steppers
+#include "../../MarlinCore.h" // for stepper_inactive_time, disable_e_steppers
#include "../../lcd/ultralcd.h"
#include "../../module/stepper.h"
diff --git a/Marlin/src/gcode/control/M226.cpp b/Marlin/src/gcode/control/M226.cpp
index 5bcf55b2f7..3dbc5984f9 100644
--- a/Marlin/src/gcode/control/M226.cpp
+++ b/Marlin/src/gcode/control/M226.cpp
@@ -21,7 +21,7 @@
*/
#include "../gcode.h"
-#include "../../Marlin.h" // for pin_is_protected and idle()
+#include "../../MarlinCore.h" // for pin_is_protected and idle()
#include "../../module/stepper.h"
/**
diff --git a/Marlin/src/gcode/control/M3-M5.cpp b/Marlin/src/gcode/control/M3-M5.cpp
index b5e789a92f..81e1645193 100644
--- a/Marlin/src/gcode/control/M3-M5.cpp
+++ b/Marlin/src/gcode/control/M3-M5.cpp
@@ -29,10 +29,20 @@
#include "../../module/stepper.h"
/**
- * M3 - Cutter ON (Clockwise)
- * M4 - Cutter ON (Counter-clockwise)
+ * Laser:
*
- * S - Set power. S0 turns it off.
+ * M3 - Laser ON/Power (Ramped power)
+ * M4 - Laser ON/Power (Continuous power)
+ *
+ * S - Set power. S0 will turn the laser off.
+ * O - Set power and OCR
+ *
+ * Spindle:
+ *
+ * M3 - Spindle ON (Clockwise)
+ * M4 - Spindle ON (Counter-clockwise)
+ *
+ * S - Set power. S0 will turn the spindle off.
* O - Set power and OCR
*
* If no PWM pin is defined then M3/M4 just turns it on.
@@ -61,12 +71,14 @@
*/
void GcodeSuite::M3_M4(const bool is_M4) {
- planner.synchronize(); // Wait for previous movement commands (G0/G0/G2/G3) to complete before changing power
+ #if ENABLED(SPINDLE_FEATURE)
+ planner.synchronize(); // Wait for movement to complete before changing power
+ #endif
cutter.set_direction(is_M4);
#if ENABLED(SPINDLE_LASER_PWM)
- if (parser.seen('O'))
+ if (parser.seenval('O'))
cutter.set_ocr_power(parser.value_byte()); // The OCR is a value from 0 to 255 (uint8_t)
else
cutter.set_power(parser.intval('S', 255));
@@ -79,7 +91,9 @@ void GcodeSuite::M3_M4(const bool is_M4) {
* M5 - Cutter OFF
*/
void GcodeSuite::M5() {
- planner.synchronize();
+ #if ENABLED(SPINDLE_FEATURE)
+ planner.synchronize();
+ #endif
cutter.set_enabled(false);
}
diff --git a/Marlin/src/gcode/control/M42.cpp b/Marlin/src/gcode/control/M42.cpp
index 0ee2ef7079..1e6145f5b5 100644
--- a/Marlin/src/gcode/control/M42.cpp
+++ b/Marlin/src/gcode/control/M42.cpp
@@ -21,7 +21,7 @@
*/
#include "../gcode.h"
-#include "../../Marlin.h" // for pin_is_protected
+#include "../../MarlinCore.h" // for pin_is_protected
#include "../../inc/MarlinConfig.h"
#if FAN_COUNT > 0
diff --git a/Marlin/src/gcode/control/M80_M81.cpp b/Marlin/src/gcode/control/M80_M81.cpp
index 03f73fe877..d2b395e8d8 100644
--- a/Marlin/src/gcode/control/M80_M81.cpp
+++ b/Marlin/src/gcode/control/M80_M81.cpp
@@ -32,10 +32,10 @@
#endif
#if HAS_SUICIDE
- #include "../../Marlin.h"
+ #include "../../MarlinCore.h"
#endif
-#if HAS_POWER_SWITCH
+#if ENABLED(PSU_CONTROL)
#if ENABLED(AUTO_POWER_CONTROL)
#include "../../feature/power.h"
@@ -68,11 +68,11 @@
* a print without suicide...
*/
#if HAS_SUICIDE
- OUT_WRITE(SUICIDE_PIN, HIGH);
+ OUT_WRITE(SUICIDE_PIN, !SUICIDE_PIN_INVERTING);
#endif
#if DISABLED(AUTO_POWER_CONTROL)
- delay(100); // Wait for power to settle
+ delay(PSU_POWERUP_DELAY); // Wait for power to settle
restore_stepper_drivers();
#endif
@@ -81,7 +81,7 @@
#endif
}
-#endif // HAS_POWER_SWITCH
+#endif // ENABLED(PSU_CONTROL)
/**
* M81: Turn off Power, including Power Supply, if there is one.
@@ -105,11 +105,11 @@ void GcodeSuite::M81() {
#if HAS_SUICIDE
suicide();
- #elif HAS_POWER_SWITCH
+ #elif ENABLED(PSU_CONTROL)
PSU_OFF();
#endif
#if HAS_LCD_MENU
- LCD_MESSAGEPGM(MACHINE_NAME " " MSG_OFF ".");
+ LCD_MESSAGEPGM_P(PSTR(MACHINE_NAME " " MSG_OFF "."));
#endif
}
diff --git a/Marlin/src/gcode/control/M85.cpp b/Marlin/src/gcode/control/M85.cpp
index bc5a91c375..5bb2f356d1 100644
--- a/Marlin/src/gcode/control/M85.cpp
+++ b/Marlin/src/gcode/control/M85.cpp
@@ -21,7 +21,7 @@
*/
#include "../gcode.h"
-#include "../../Marlin.h" // for max_inactive_time
+#include "../../MarlinCore.h" // for max_inactive_time
/**
* M85: Set inactivity shutdown timer with parameter S. To disable set zero (default)
diff --git a/Marlin/src/gcode/control/M999.cpp b/Marlin/src/gcode/control/M999.cpp
index 2972e086d1..ac46311067 100644
--- a/Marlin/src/gcode/control/M999.cpp
+++ b/Marlin/src/gcode/control/M999.cpp
@@ -23,7 +23,7 @@
#include "../gcode.h"
#include "../../lcd/ultralcd.h" // for lcd_reset_alert_level
-#include "../../Marlin.h" // for Running
+#include "../../MarlinCore.h" // for Running
#include "../queue.h" // for flush_and_request_resend
/**
diff --git a/Marlin/src/gcode/feature/L6470/M906.cpp b/Marlin/src/gcode/feature/L6470/M906.cpp
index 143a6fea8d..72de90fc50 100644
--- a/Marlin/src/gcode/feature/L6470/M906.cpp
+++ b/Marlin/src/gcode/feature/L6470/M906.cpp
@@ -108,7 +108,7 @@ void L6470_report_current(L6470 &motor, const uint8_t axis) {
SERIAL_ECHO(temp_buf);
SERIAL_ECHOPGM(" Motor Status: ");
- const char * const stat_str;
+ const char *stat_str;
switch (motor_status) {
default:
case 0: stat_str = PSTR("stopped"); break;
@@ -124,7 +124,7 @@ void L6470_report_current(L6470 &motor, const uint8_t axis) {
SERIAL_ECHOPGM(" Vs_compensation: ");
serialprintPGM((motor.GetParam(L6470_CONFIG) & CONFIG_EN_VSCOMP) ? PSTR("ENABLED ") : PSTR("DISABLED"));
- SERIAL_ECHOLNPGM(" Compensation coefficient: ", dtostrf(comp_coef * 0.01f, 7, 2, numstr));
+ SERIAL_ECHOLNPAIR(" Compensation coefficient: ", dtostrf(comp_coef * 0.01f, 7, 2, numstr));
SERIAL_ECHOPAIR("...KVAL_HOLD: ", motor.GetParam(L6470_KVAL_HOLD));
SERIAL_ECHOPAIR(" KVAL_RUN : ", motor.GetParam(L6470_KVAL_RUN));
SERIAL_ECHOPAIR(" KVAL_ACC: ", motor.GetParam(L6470_KVAL_ACC));
diff --git a/Marlin/src/gcode/feature/L6470/M916-918.cpp b/Marlin/src/gcode/feature/L6470/M916-918.cpp
index 2077e937b9..96a27f3330 100644
--- a/Marlin/src/gcode/feature/L6470/M916-918.cpp
+++ b/Marlin/src/gcode/feature/L6470/M916-918.cpp
@@ -36,11 +36,11 @@ static void jiggle_axis(const char axis_char, const float &min, const float &max
char gcode_string[30], str1[11], str2[11];
// Turn the motor(s) both directions
- sprintf_P(gcode_string, PSTR("G0 %c%s F%s"), axis_char, dtostrf(min, 1, 3, str1), dtostrf(rate, 1, 3, str2));
- process_subcommands_now(gcode_string);
+ sprintf_P(gcode_string, PSTR("G0 %c%s F%s"), axis_char, dtostrf(min, 1, 3, str1), dtostrf(fr_mm_m, 1, 3, str2));
+ gcode.process_subcommands_now(gcode_string);
sprintf_P(gcode_string, PSTR("G0 %c%s F%s"), axis_char, dtostrf(max, 1, 3, str1), str2);
- process_subcommands_now(gcode_string);
+ gcode.process_subcommands_now(gcode_string);
planner.synchronize();
}
diff --git a/Marlin/src/gcode/feature/camera/M240.cpp b/Marlin/src/gcode/feature/camera/M240.cpp
index 6fb68d454e..46ee958ebd 100644
--- a/Marlin/src/gcode/feature/camera/M240.cpp
+++ b/Marlin/src/gcode/feature/camera/M240.cpp
@@ -31,6 +31,10 @@
millis_t chdk_timeout; // = 0
#endif
+#if defined(PHOTO_POSITION) && PHOTO_DELAY_MS > 0
+ #include "../../../MarlinCore.h" // for idle()
+#endif
+
#ifdef PHOTO_RETRACT_MM
#define _PHOTO_RETRACT_MM (PHOTO_RETRACT_MM + 0)
@@ -148,7 +152,7 @@ void GcodeSuite::M240() {
#if PIN_EXISTS(CHDK)
OUT_WRITE(CHDK_PIN, HIGH);
- chdk_timeout = millis() + PHOTO_SWITCH_MS;
+ chdk_timeout = millis() + parser.intval('D', PHOTO_SWITCH_MS);
#elif HAS_PHOTOGRAPH
@@ -160,7 +164,8 @@ void GcodeSuite::M240() {
#ifdef PHOTO_POSITION
#if PHOTO_DELAY_MS > 0
- safe_delay(parser.intval('P', PHOTO_DELAY_MS));
+ const millis_t timeout = millis() + parser.intval('P', PHOTO_DELAY_MS);
+ while (PENDING(millis(), timeout)) idle();
#endif
do_blocking_move_to(old_pos, fr_mm_s);
#ifdef PHOTO_RETRACT_MM
diff --git a/Marlin/src/gcode/feature/cancel/M486.cpp b/Marlin/src/gcode/feature/cancel/M486.cpp
new file mode 100644
index 0000000000..2fcb4840f6
--- /dev/null
+++ b/Marlin/src/gcode/feature/cancel/M486.cpp
@@ -0,0 +1,57 @@
+/**
+ * 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 .
+ *
+ */
+
+#include "../../../inc/MarlinConfig.h"
+
+#if ENABLED(CANCEL_OBJECTS)
+
+#include "../../gcode.h"
+#include "../../../feature/cancel_object.h"
+
+/**
+ * M486: A simple interface to cancel objects
+ *
+ * T[count] : Reset objects and/or set the count
+ * S : Start an object with the given index
+ * P : Cancel the object with the given index
+ * U : Un-cancel object with the given index
+ * C : Cancel the current object (the last index given by S)
+ * S-1 : Start a non-object like a brim or purge tower that should always print
+ */
+void GcodeSuite::M486() {
+
+ if (parser.seen('T')) {
+ cancelable.reset();
+ cancelable.object_count = parser.intval('T', 1);
+ }
+
+ if (parser.seen('S'))
+ cancelable.set_active_object(parser.value_int());
+
+ if (parser.seen('C')) cancelable.cancel_active_object();
+
+ if (parser.seen('P')) cancelable.cancel_object(parser.value_int());
+
+ if (parser.seen('U')) cancelable.uncancel_object(parser.value_int());
+}
+
+#endif // CANCEL_OBJECTS
diff --git a/Marlin/src/gcode/feature/filwidth/M404-M407.cpp b/Marlin/src/gcode/feature/filwidth/M404-M407.cpp
index 5b58416b43..36cac7857c 100644
--- a/Marlin/src/gcode/feature/filwidth/M404-M407.cpp
+++ b/Marlin/src/gcode/feature/filwidth/M404-M407.cpp
@@ -27,7 +27,7 @@
#include "../../../feature/filwidth.h"
#include "../../../module/planner.h"
#include "../../../module/temperature.h"
-#include "../../../Marlin.h"
+#include "../../../MarlinCore.h"
#include "../../gcode.h"
/**
diff --git a/Marlin/src/gcode/feature/i2c/M260_M261.cpp b/Marlin/src/gcode/feature/i2c/M260_M261.cpp
index 48ab48959a..05fa2d3466 100644
--- a/Marlin/src/gcode/feature/i2c/M260_M261.cpp
+++ b/Marlin/src/gcode/feature/i2c/M260_M261.cpp
@@ -26,7 +26,7 @@
#include "../../gcode.h"
-#include "../../../Marlin.h" // for i2c
+#include "../../../MarlinCore.h" // for i2c
/**
* M260: Send data to a I2C slave device
diff --git a/Marlin/src/gcode/feature/leds/M7219.cpp b/Marlin/src/gcode/feature/leds/M7219.cpp
index c8257f6581..c3d2643535 100644
--- a/Marlin/src/gcode/feature/leds/M7219.cpp
+++ b/Marlin/src/gcode/feature/leds/M7219.cpp
@@ -71,7 +71,7 @@ void GcodeSuite::M7219() {
}
else if (parser.seen('D')) {
const uint8_t uline = parser.value_byte() & 0x7,
- line = uline + parser.byteval('U') << 3;
+ line = uline + (parser.byteval('U') << 3);
if (line < MAX7219_LINES) {
max7219.led_line[line] = v;
return max7219.refresh_line(line);
diff --git a/Marlin/src/gcode/feature/mixing/M163-M165.cpp b/Marlin/src/gcode/feature/mixing/M163-M165.cpp
index 05654d389a..cc0a468366 100644
--- a/Marlin/src/gcode/feature/mixing/M163-M165.cpp
+++ b/Marlin/src/gcode/feature/mixing/M163-M165.cpp
@@ -79,20 +79,7 @@ void GcodeSuite::M164() {
// Get mixing parameters from the GCode
// The total "must" be 1.0 (but it will be normalized)
// If no mix factors are given, the old mix is preserved
- const char mixing_codes[] = { 'A', 'B'
- #if MIXING_STEPPERS > 2
- , 'C'
- #if MIXING_STEPPERS > 3
- , 'D'
- #if MIXING_STEPPERS > 4
- , 'H'
- #if MIXING_STEPPERS > 5
- , 'I'
- #endif // MIXING_STEPPERS > 5
- #endif // MIXING_STEPPERS > 4
- #endif // MIXING_STEPPERS > 3
- #endif // MIXING_STEPPERS > 2
- };
+ const char mixing_codes[] = { LIST_N(MIXING_STEPPERS, 'A', 'B', 'C', 'D', 'H', 'I') };
uint8_t mix_bits = 0;
MIXER_STEPPER_LOOP(i) {
if (parser.seenval(mixing_codes[i])) {
diff --git a/Marlin/src/gcode/feature/mixing/M166.cpp b/Marlin/src/gcode/feature/mixing/M166.cpp
index 8b74182cde..cb3541eb8f 100644
--- a/Marlin/src/gcode/feature/mixing/M166.cpp
+++ b/Marlin/src/gcode/feature/mixing/M166.cpp
@@ -35,7 +35,7 @@ inline void echo_mix() {
inline void echo_zt(const int t, const float &z) {
mixer.update_mix_from_vtool(t);
- SERIAL_ECHOPAIR(" Z", z, " T", t);
+ SERIAL_ECHOPAIR_P(SP_Z_STR, z, PSTR(" T"), t);
echo_mix();
}
diff --git a/Marlin/src/gcode/feature/pause/M701_M702.cpp b/Marlin/src/gcode/feature/pause/M701_M702.cpp
index b4bab7e86a..325b748aa9 100644
--- a/Marlin/src/gcode/feature/pause/M701_M702.cpp
+++ b/Marlin/src/gcode/feature/pause/M701_M702.cpp
@@ -25,9 +25,10 @@
#if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES)
#include "../../gcode.h"
-#include "../../../Marlin.h"
+#include "../../../MarlinCore.h"
#include "../../../module/motion.h"
#include "../../../module/temperature.h"
+#include "../../../feature/pause.h"
#if EXTRUDERS > 1
#include "../../../module/tool_change.h"
diff --git a/Marlin/src/gcode/feature/powerloss/M1000.cpp b/Marlin/src/gcode/feature/powerloss/M1000.cpp
index c454a34c05..f14dc60685 100644
--- a/Marlin/src/gcode/feature/powerloss/M1000.cpp
+++ b/Marlin/src/gcode/feature/powerloss/M1000.cpp
@@ -52,8 +52,13 @@ inline void plr_error(PGM_P const prefix) {
void GcodeSuite::M1000() {
if (recovery.valid()) {
- if (parser.seen('S'))
- ui.goto_screen(menu_job_recovery);
+ if (parser.seen('S')) {
+ #if HAS_LCD_MENU
+ ui.goto_screen(menu_job_recovery);
+ #else
+ SERIAL_ECHO_MSG("Resume requires LCD.");
+ #endif
+ }
else
recovery.resume();
}
diff --git a/Marlin/src/gcode/feature/trinamic/M569.cpp b/Marlin/src/gcode/feature/trinamic/M569.cpp
index e8239838d7..efe32666ae 100644
--- a/Marlin/src/gcode/feature/trinamic/M569.cpp
+++ b/Marlin/src/gcode/feature/trinamic/M569.cpp
@@ -44,7 +44,9 @@ void tmc_set_stealthChop(TMC &st, const bool enable) {
static void set_stealth_status(const bool enable, const int8_t target_extruder) {
#define TMC_SET_STEALTH(Q) tmc_set_stealthChop(stepper##Q, enable)
- #if AXIS_HAS_STEALTHCHOP(X) || AXIS_HAS_STEALTHCHOP(X2) || AXIS_HAS_STEALTHCHOP(Y) || AXIS_HAS_STEALTHCHOP(Y2) || AXIS_HAS_STEALTHCHOP(Z) || AXIS_HAS_STEALTHCHOP(Z2) || AXIS_HAS_STEALTHCHOP(Z3)
+ #if AXIS_HAS_STEALTHCHOP(X) || AXIS_HAS_STEALTHCHOP(X2) \
+ || AXIS_HAS_STEALTHCHOP(Y) || AXIS_HAS_STEALTHCHOP(Y2) \
+ || AXIS_HAS_STEALTHCHOP(Z) || AXIS_HAS_STEALTHCHOP(Z2) || AXIS_HAS_STEALTHCHOP(Z3)
const uint8_t index = parser.byteval('I');
#endif
diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp
index 32885af6ca..f07d2fbe40 100644
--- a/Marlin/src/gcode/gcode.cpp
+++ b/Marlin/src/gcode/gcode.cpp
@@ -45,7 +45,11 @@ GcodeSuite gcode;
#include "../feature/power_loss_recovery.h"
#endif
-#include "../Marlin.h" // for idle() and suspend_auto_report
+#if ENABLED(CANCEL_OBJECTS)
+ #include "../feature/cancel_object.h"
+#endif
+
+#include "../MarlinCore.h" // for idle() and suspend_auto_report
millis_t GcodeSuite::previous_move_ms;
@@ -114,15 +118,34 @@ int8_t GcodeSuite::get_target_e_stepper_from_command() {
*/
void GcodeSuite::get_destination_from_command() {
xyze_bool_t seen = { false, false, false, false };
- LOOP_XYZE(i) {
+
+ #if ENABLED(CANCEL_OBJECTS)
+ const bool &skip_move = cancelable.skipping;
+ #else
+ constexpr bool skip_move = false;
+ #endif
+
+ // Get new XYZ position, whether absolute or relative
+ LOOP_XYZ(i) {
if ( (seen[i] = parser.seenval(axis_codes[i])) ) {
const float v = parser.value_axis_units((AxisEnum)i);
- destination[i] = axis_is_relative(AxisEnum(i)) ? current_position[i] + v : (i == E_AXIS) ? v : LOGICAL_TO_NATIVE(v, i);
+ if (skip_move)
+ destination[i] = current_position[i];
+ else
+ destination[i] = axis_is_relative(AxisEnum(i)) ? current_position[i] + v : LOGICAL_TO_NATIVE(v, i);
}
else
destination[i] = current_position[i];
}
+ // Get new E position, whether absolute or relative
+ if ( (seen.e = parser.seenval('E')) ) {
+ const float v = parser.value_axis_units(E_AXIS);
+ destination.e = axis_is_relative(E_AXIS) ? current_position.e + v : v;
+ }
+ else
+ destination.e = current_position.e;
+
#if ENABLED(POWER_LOSS_RECOVERY) && !PIN_EXISTS(POWER_LOSS)
// Only update power loss recovery on moves with E
if (recovery.enabled && IS_SD_PRINTING() && seen.e && (seen.x || seen.y))
@@ -133,7 +156,7 @@ void GcodeSuite::get_destination_from_command() {
feedrate_mm_s = parser.value_feedrate();
#if ENABLED(PRINTCOUNTER)
- if (!DEBUGGING(DRYRUN))
+ if (!DEBUGGING(DRYRUN) && !skip_move)
print_job_timer.incFilamentUsed(destination.e - current_position.e);
#endif
@@ -186,7 +209,7 @@ void GcodeSuite::dwell(millis_t time) {
// Placeholders for non-migrated codes
//
#if ENABLED(M100_FREE_MEMORY_WATCHER)
- extern void M100_dump_routine(PGM_P const title, char *start, char *end);
+ extern void M100_dump_routine(PGM_P const title, const char * const start, const char * const end);
#endif
/**
@@ -322,6 +345,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
break;
case 'M': switch (parser.codenum) {
+
#if HAS_RESUME_CONTINUE
case 0: // M0: Unconditional stop - Wait for user button press on LCD
case 1: M0_M1(); break; // M1: Conditional stop - Wait for user button press on LCD
@@ -446,7 +470,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
#if HAS_HEATED_CHAMBER
case 141: M141(); break; // M141: Set chamber temperature
- //case 191: M191(); break; // M191: Wait for chamber temperature to reach target
+ case 191: M191(); break; // M191: Wait for chamber temperature to reach target
#endif
#if ENABLED(AUTO_REPORT_TEMPERATURES) && HAS_TEMP_SENSOR
@@ -471,7 +495,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
#endif
#endif // BARICUDA
- #if HAS_POWER_SWITCH
+ #if ENABLED(PSU_CONTROL)
case 80: M80(); break; // M80: Turn on Power Supply
#endif
case 81: M81(); break; // M81: Turn off Power, including Power Supply, if possible
@@ -667,6 +691,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 428: M428(); break; // M428: Apply current_position to home_offset
#endif
+ #if ENABLED(CANCEL_OBJECTS)
+ case 486: M486(); break; // M486: Identify and cancel objects
+ #endif
+
case 500: M500(); break; // M500: Store settings in EEPROM
case 501: M501(); break; // M501: Read settings from EEPROM
case 502: M502(); break; // M502: Revert to default settings
@@ -837,7 +865,7 @@ void GcodeSuite::process_next_command() {
SERIAL_ECHOLN(current_command);
#if ENABLED(M100_FREE_MEMORY_DUMPER)
SERIAL_ECHOPAIR("slot:", queue.index_r);
- M100_dump_routine(PSTR(" Command Queue:"), queue.command_buffer, queue.command_buffer + sizeof(queue.command_buffer));
+ M100_dump_routine(PSTR(" Command Queue:"), &queue.command_buffer[0][0], &queue.command_buffer[BUFSIZE - 1][MAX_CMD_SIZE - 1]);
#endif
}
diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h
index 619f50b61f..9f4675291f 100644
--- a/Marlin/src/gcode/gcode.h
+++ b/Marlin/src/gcode/gcode.h
@@ -177,6 +177,7 @@
* M217 - Set filament swap parameters: "M217 S P R". (Requires SINGLENOZZLE)
* M218 - Set/get a tool offset: "M218 T X Y". (Requires 2 or more extruders)
* M220 - Set Feedrate Percentage: "M220 S" (i.e., "FR" on the LCD)
+ * Use "M220 B" to back up the Feedrate Percentage and "M220 R" to restore it. (Requires PRUSA_MMU2)
* M221 - Set Flow Percentage: "M221 S"
* M226 - Wait until a pin is in a given state: "M226 P S"
* M240 - Trigger a camera to take a photograph. (Requires PHOTO_GCODE)
@@ -213,6 +214,7 @@
* M422 - Set Z Stepper automatic alignment position using probe. X Y A (Requires Z_STEPPER_AUTO_ALIGN)
* M425 - Enable/Disable and tune backlash correction. (Requires BACKLASH_COMPENSATION and BACKLASH_GCODE)
* M428 - Set the home_offset based on the current_position. Nearest edge applies. (Disabled by NO_WORKSPACE_OFFSETS or DELTA)
+ * M486 - Identify and cancel objects. (Requires CANCEL_OBJECTS)
* M500 - Store parameters in EEPROM. (Requires EEPROM_SETTINGS)
* M501 - Restore parameters from EEPROM. (Requires EEPROM_SETTINGS)
* M502 - Revert to the default "factory settings". ** Does not write them to EEPROM! **
@@ -339,7 +341,10 @@ public:
static void process_subcommands_now_P(PGM_P pgcode);
static void process_subcommands_now(char * gcode);
- static inline void home_all_axes() { process_subcommands_now_P(PSTR("G28")); }
+ static inline void home_all_axes() {
+ extern const char G28_STR[];
+ process_subcommands_now_P(G28_STR);
+ }
#if ENABLED(HOST_KEEPALIVE_FEATURE)
/**
@@ -548,7 +553,7 @@ private:
static void M78();
#endif
- #if HAS_POWER_SWITCH
+ #if ENABLED(PSU_CONTROL)
static void M80();
#endif
@@ -620,7 +625,7 @@ private:
#if HAS_HEATED_CHAMBER
static void M141();
- //static void M191();
+ static void M191();
#endif
#if HOTENDS && HAS_LCD_MENU
@@ -796,6 +801,10 @@ private:
static void M428();
#endif
+ #if ENABLED(CANCEL_OBJECTS)
+ static void M486();
+ #endif
+
static void M500();
static void M501();
static void M502();
diff --git a/Marlin/src/gcode/geometry/G92.cpp b/Marlin/src/gcode/geometry/G92.cpp
index 65ad06fe2c..2f69654b0e 100644
--- a/Marlin/src/gcode/geometry/G92.cpp
+++ b/Marlin/src/gcode/geometry/G92.cpp
@@ -33,12 +33,7 @@
*/
void GcodeSuite::G92() {
- bool didE = false;
- #if IS_SCARA || !HAS_POSITION_SHIFT
- bool didXYZ = false;
- #else
- constexpr bool didXYZ = false;
- #endif
+ bool sync_E = false, sync_XYZ = false;
#if USE_GCODE_SUBCODES
const uint8_t subcode_G92 = parser.subcode;
@@ -64,11 +59,7 @@ void GcodeSuite::G92() {
LOOP_XYZE(i) {
if (parser.seenval(axis_codes[i])) {
current_position[i] = parser.value_axis_units((AxisEnum)i);
- #if IS_SCARA || !HAS_POSITION_SHIFT
- if (i == E_AXIS) didE = true; else didXYZ = true;
- #elif HAS_POSITION_SHIFT
- if (i == E_AXIS) didE = true;
- #endif
+ if (i == E_AXIS) sync_E = true; else sync_XYZ = true;
}
}
} break;
@@ -81,12 +72,12 @@ void GcodeSuite::G92() {
d = v - current_position[i];
if (!NEAR_ZERO(d)) {
#if IS_SCARA || !HAS_POSITION_SHIFT
- if (i == E_AXIS) didE = true; else didXYZ = true;
+ if (i == E_AXIS) sync_E = true; else sync_XYZ = true;
current_position[i] = v; // Without workspaces revert to Marlin 1.0 behavior
#elif HAS_POSITION_SHIFT
if (i == E_AXIS) {
- didE = true;
- current_position.e = v; // When using coordinate spaces, only E is set directly
+ sync_E = true;
+ current_position.e = v; // When using coordinate spaces, only E is set directly
}
else {
position_shift[i] += d; // Other axes simply offset the coordinate space
@@ -105,8 +96,8 @@ void GcodeSuite::G92() {
coordinate_system[active_coordinate_system] = position_shift;
#endif
- if (didXYZ) sync_plan_position();
- else if (didE) sync_plan_position_e();
+ if (sync_XYZ) sync_plan_position();
+ else if (sync_E) sync_plan_position_e();
report_current_position();
}
diff --git a/Marlin/src/gcode/geometry/M206_M428.cpp b/Marlin/src/gcode/geometry/M206_M428.cpp
index e17f41f835..6e2b46081c 100644
--- a/Marlin/src/gcode/geometry/M206_M428.cpp
+++ b/Marlin/src/gcode/geometry/M206_M428.cpp
@@ -70,7 +70,7 @@ void GcodeSuite::M428() {
diff[i] = -current_position[i];
if (!WITHIN(diff[i], -20, 20)) {
SERIAL_ERROR_MSG(MSG_ERR_M428_TOO_FAR);
- LCD_ALERTMESSAGEPGM("Err: Too far!");
+ LCD_ALERTMESSAGEPGM_P(PSTR("Err: Too far!"));
BUZZ(200, 40);
return;
}
diff --git a/Marlin/src/gcode/host/M114.cpp b/Marlin/src/gcode/host/M114.cpp
index 8b65f2983a..68cbd2b8a4 100644
--- a/Marlin/src/gcode/host/M114.cpp
+++ b/Marlin/src/gcode/host/M114.cpp
@@ -188,6 +188,10 @@ void GcodeSuite::M114() {
report_current_position_detail();
return;
}
+ if (parser.seen('E')) {
+ SERIAL_ECHOLNPAIR("Count E:", stepper.position(E_AXIS));
+ return;
+ }
#endif
planner.synchronize();
diff --git a/Marlin/src/gcode/host/M115.cpp b/Marlin/src/gcode/host/M115.cpp
index eb32119ef9..8871644ff1 100644
--- a/Marlin/src/gcode/host/M115.cpp
+++ b/Marlin/src/gcode/host/M115.cpp
@@ -112,7 +112,7 @@ void GcodeSuite::M115() {
// SOFTWARE_POWER (M80, M81)
cap_line(PSTR("SOFTWARE_POWER")
- #if HAS_POWER_SWITCH
+ #if ENABLED(PSU_CONTROL)
, true
#endif
);
diff --git a/Marlin/src/gcode/host/M119.cpp b/Marlin/src/gcode/host/M119.cpp
index ec7dde7fcc..a13fa67b79 100644
--- a/Marlin/src/gcode/host/M119.cpp
+++ b/Marlin/src/gcode/host/M119.cpp
@@ -28,6 +28,6 @@
*/
void GcodeSuite::M119() {
- endstops.M119();
+ endstops.report_states();
}
diff --git a/Marlin/src/gcode/host/M16.cpp b/Marlin/src/gcode/host/M16.cpp
index 94ae79b263..0a076a7a47 100644
--- a/Marlin/src/gcode/host/M16.cpp
+++ b/Marlin/src/gcode/host/M16.cpp
@@ -25,7 +25,7 @@
#if ENABLED(EXPECTED_PRINTER_CHECK)
#include "../gcode.h"
-#include "../../Marlin.h"
+#include "../../MarlinCore.h"
/**
* M16: Expected Printer Check
@@ -33,7 +33,7 @@
void GcodeSuite::M16() {
if (strcmp_P(parser.string_arg, PSTR(MACHINE_NAME)))
- kill(PSTR(MSG_EXPECTED_PRINTER));
+ kill(GET_TEXT(MSG_EXPECTED_PRINTER));
}
diff --git a/Marlin/src/gcode/host/M876.cpp b/Marlin/src/gcode/host/M876.cpp
index e3360ac95d..057b010e72 100644
--- a/Marlin/src/gcode/host/M876.cpp
+++ b/Marlin/src/gcode/host/M876.cpp
@@ -25,7 +25,7 @@
#include "../../feature/host_actions.h"
#include "../gcode.h"
-#include "../../Marlin.h"
+#include "../../MarlinCore.h"
/**
* M876: Handle Prompt Response
diff --git a/Marlin/src/gcode/lcd/M0_M1.cpp b/Marlin/src/gcode/lcd/M0_M1.cpp
index 05fb7576fb..5bf9e94325 100644
--- a/Marlin/src/gcode/lcd/M0_M1.cpp
+++ b/Marlin/src/gcode/lcd/M0_M1.cpp
@@ -80,7 +80,10 @@ void GcodeSuite::M0_M1() {
#elif ENABLED(EXTENSIBLE_UI)
- ExtUI::onUserConfirmRequired(has_message ? args : MSG_USERWAIT); // SRAM string
+ if (has_message)
+ ExtUI::onUserConfirmRequired(args); // Can this take an SRAM string??
+ else
+ ExtUI::onUserConfirmRequired_P(GET_TEXT(MSG_USERWAIT));
#else
@@ -95,10 +98,7 @@ void GcodeSuite::M0_M1() {
wait_for_user = true;
#if ENABLED(HOST_PROMPT_SUPPORT)
- host_prompt_do(PROMPT_USER_CONTINUE, PSTR("M0/1 Break Called"), PSTR("Continue"));
- #endif
- #if ENABLED(EXTENSIBLE_UI)
- ExtUI::onUserConfirmRequired(PSTR("M0/1 Break Called"));
+ host_prompt_do(PROMPT_USER_CONTINUE, PSTR("M0/1 Break Called"), CONTINUE_STR);
#endif
if (ms > 0) {
diff --git a/Marlin/src/gcode/lcd/M73.cpp b/Marlin/src/gcode/lcd/M73.cpp
index 171d8bbad9..14d4d63813 100644
--- a/Marlin/src/gcode/lcd/M73.cpp
+++ b/Marlin/src/gcode/lcd/M73.cpp
@@ -39,7 +39,13 @@
*/
void GcodeSuite::M73() {
if (parser.seen('P'))
- ui.set_progress(parser.value_byte());
+ ui.set_progress((PROGRESS_SCALE) > 1
+ ? parser.value_float() * (PROGRESS_SCALE)
+ : parser.value_byte()
+ );
+ #if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME)
+ if (parser.seen('R')) ui.set_remaining_time(60 * parser.value_ulong());
+ #endif
}
#endif // LCD_SET_PROGRESS_MANUALLY
diff --git a/Marlin/src/gcode/motion/G0_G1.cpp b/Marlin/src/gcode/motion/G0_G1.cpp
index 36bc29026e..4dd13ca017 100644
--- a/Marlin/src/gcode/motion/G0_G1.cpp
+++ b/Marlin/src/gcode/motion/G0_G1.cpp
@@ -23,7 +23,7 @@
#include "../gcode.h"
#include "../../module/motion.h"
-#include "../../Marlin.h"
+#include "../../MarlinCore.h"
#if BOTH(FWRETRACT, FWRETRACT_AUTORETRACT)
#include "../../feature/fwretract.h"
diff --git a/Marlin/src/gcode/motion/G2_G3.cpp b/Marlin/src/gcode/motion/G2_G3.cpp
index e2240cbf23..6fecbdc0cc 100644
--- a/Marlin/src/gcode/motion/G2_G3.cpp
+++ b/Marlin/src/gcode/motion/G2_G3.cpp
@@ -285,12 +285,13 @@ void GcodeSuite::G2_G3(const bool clockwise) {
if (r) {
const xy_pos_t p1 = current_position, p2 = destination;
if (p1 != p2) {
- const xy_pos_t d = p2 - p1, m = (p1 + p2) * 0.5f; // XY distance and midpoint
- const float e = clockwise ^ (r < 0) ? -1 : 1, // clockwise -1/1, counterclockwise 1/-1
- len = d.magnitude(), // Total move length
- h = SQRT((r - d * 0.5f) * (r + d * 0.5f)); // Distance to the arc pivot-point
- const xy_pos_t s = { d.x, -d.y }; // Inverse Slope of the perpendicular bisector
- arc_offset = m + s * RECIPROCAL(len) * e * h - p1; // The calculated offset
+ const xy_pos_t d2 = (p2 - p1) * 0.5f; // XY vector to midpoint of move from current
+ const float e = clockwise ^ (r < 0) ? -1 : 1, // clockwise -1/1, counterclockwise 1/-1
+ len = d2.magnitude(), // Distance to mid-point of move from current
+ h2 = (r - len) * (r + len), // factored to reduce rounding error
+ h = (h2 >= 0) ? SQRT(h2) : 0.0f; // Distance to the arc pivot-point from midpoint
+ const xy_pos_t s = { -d2.y, d2.x }; // Perpendicular bisector. (Divide by len for unit vector.)
+ arc_offset = d2 + s / len * e * h; // The calculated offset (mid-point if |r| <= len)
}
}
}
diff --git a/Marlin/src/gcode/motion/G5.cpp b/Marlin/src/gcode/motion/G5.cpp
index 7125532e9b..03dd496c58 100644
--- a/Marlin/src/gcode/motion/G5.cpp
+++ b/Marlin/src/gcode/motion/G5.cpp
@@ -35,7 +35,7 @@
*/
#include "../gcode.h"
-#include "../../Marlin.h" // for IsRunning()
+#include "../../MarlinCore.h" // for IsRunning()
/**
* G5: Cubic B-spline
diff --git a/Marlin/src/gcode/motion/M290.cpp b/Marlin/src/gcode/motion/M290.cpp
index 7bf274a18d..e5b5b7e76d 100644
--- a/Marlin/src/gcode/motion/M290.cpp
+++ b/Marlin/src/gcode/motion/M290.cpp
@@ -103,12 +103,16 @@ void GcodeSuite::M290() {
#if ENABLED(BABYSTEP_HOTEND_Z_OFFSET)
{
- SERIAL_ECHOLNPAIR("Hotend ", int(active_extruder), "Offset"
+ SERIAL_ECHOLNPAIR_P(
+ PSTR("Hotend "), int(active_extruder)
#if ENABLED(BABYSTEP_XY)
- " X", hotend_offset[active_extruder].x,
- " Y", hotend_offset[active_extruder].y,
+ , PSTR("Offset X"), hotend_offset[active_extruder].x
+ , SP_Y_STR, hotend_offset[active_extruder].y
+ , SP_Z_STR
+ #else
+ , PSTR("Offset Z")
#endif
- " Z", hotend_offset[active_extruder].z
+ , hotend_offset[active_extruder].z
);
}
#endif
@@ -119,12 +123,15 @@ void GcodeSuite::M290() {
#if ENABLED(BABYSTEP_DISPLAY_TOTAL)
{
- SERIAL_ECHOLNPAIR("Babystep"
+ SERIAL_ECHOLNPAIR_P(
#if ENABLED(BABYSTEP_XY)
- " X", babystep.axis_total[X_AXIS],
- " Y", babystep.axis_total[Y_AXIS],
+ PSTR("Babystep X"), babystep.axis_total[X_AXIS]
+ , SP_Y_STR, babystep.axis_total[Y_AXIS]
+ , SP_Z_STR
+ #else
+ PSTR("Babystep Z")
#endif
- " Z", babystep.axis_total[Z_AXIS]
+ , babystep.axis_total[BS_TODO_AXIS(Z_AXIS)]
);
}
#endif
diff --git a/Marlin/src/gcode/parser.cpp b/Marlin/src/gcode/parser.cpp
index 8d70c64cc8..e2cfd9f70a 100644
--- a/Marlin/src/gcode/parser.cpp
+++ b/Marlin/src/gcode/parser.cpp
@@ -26,7 +26,7 @@
#include "parser.h"
-#include "../Marlin.h"
+#include "../MarlinCore.h"
#if NUM_SERIAL > 1
#include "queue.h"
@@ -138,7 +138,9 @@ void GCodeParser::parse(char *p) {
switch (letter) {
case 'G': case 'M': case 'T':
-
+ #if ENABLED(CANCEL_OBJECTS)
+ case 'O':
+ #endif
// Skip spaces to get the numeric part
while (*p == ' ') p++;
@@ -230,7 +232,14 @@ void GCodeParser::parse(char *p) {
case 23: case 28: case 30: case 117: case 118: case 928: string_arg = p; return;
default: break;
}
-
+/*
+ #if ENABLED(CANCEL_OBJECTS)
+ if (letter == 'O') switch (codenum) {
+ case 1: string_arg = p; return;
+ default: break;
+ }
+ #endif
+*/
#if ENABLED(DEBUG_GCODE_PARSER)
const bool debug = codenum == 800;
#endif
diff --git a/Marlin/src/gcode/probe/M851.cpp b/Marlin/src/gcode/probe/M851.cpp
index 19f96eecd2..431fe6fa09 100644
--- a/Marlin/src/gcode/probe/M851.cpp
+++ b/Marlin/src/gcode/probe/M851.cpp
@@ -28,6 +28,8 @@
#include "../../feature/bedlevel/bedlevel.h"
#include "../../module/probe.h"
+extern const char SP_Y_STR[], SP_Z_STR[];
+
/**
* M851: Set the nozzle-to-probe offsets in current units
*/
@@ -35,7 +37,7 @@ void GcodeSuite::M851() {
// Show usage with no parameters
if (!parser.seen("XYZ")) {
- SERIAL_ECHOLNPAIR(MSG_PROBE_OFFSET " X", probe_offset.x, " Y", probe_offset.y, " Z", probe_offset.z);
+ SERIAL_ECHOLNPAIR_P(PSTR(MSG_PROBE_OFFSET " X"), probe_offset.x, SP_Y_STR, probe_offset.y, SP_Z_STR, probe_offset.z);
return;
}
diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp
index a9bd714c1e..a026e479a9 100644
--- a/Marlin/src/gcode/queue.cpp
+++ b/Marlin/src/gcode/queue.cpp
@@ -33,7 +33,7 @@ GCodeQueue queue;
#include "../sd/cardreader.h"
#include "../module/planner.h"
#include "../module/temperature.h"
-#include "../Marlin.h"
+#include "../MarlinCore.h"
#if ENABLED(PRINTER_EVENT_LEDS)
#include "../feature/leds/printer_event_leds.h"
diff --git a/Marlin/src/gcode/scara/M360-M364.cpp b/Marlin/src/gcode/scara/M360-M364.cpp
index 0e6f51b628..6fd8306e07 100644
--- a/Marlin/src/gcode/scara/M360-M364.cpp
+++ b/Marlin/src/gcode/scara/M360-M364.cpp
@@ -27,7 +27,7 @@
#include "../gcode.h"
#include "../../module/scara.h"
#include "../../module/motion.h"
-#include "../../Marlin.h" // for IsRunning()
+#include "../../MarlinCore.h" // for IsRunning()
inline bool SCARA_move_to_cal(const uint8_t delta_a, const uint8_t delta_b) {
if (IsRunning()) {
diff --git a/Marlin/src/gcode/sdcard/M23.cpp b/Marlin/src/gcode/sdcard/M23.cpp
index f170345c57..7dd4ad9203 100644
--- a/Marlin/src/gcode/sdcard/M23.cpp
+++ b/Marlin/src/gcode/sdcard/M23.cpp
@@ -36,7 +36,7 @@
void GcodeSuite::M23() {
// Simplify3D includes the size, so zero out all spaces (#7227)
for (char *fn = parser.string_arg; *fn; ++fn) if (*fn == ' ') *fn = '\0';
- card.openFile(parser.string_arg, true);
+ card.openFileRead(parser.string_arg);
#if ENABLED(LCD_SET_PROGRESS_MANUALLY)
ui.set_progress(0);
diff --git a/Marlin/src/gcode/sdcard/M24_M25.cpp b/Marlin/src/gcode/sdcard/M24_M25.cpp
index 154a4f7c55..046df659cf 100644
--- a/Marlin/src/gcode/sdcard/M24_M25.cpp
+++ b/Marlin/src/gcode/sdcard/M24_M25.cpp
@@ -42,6 +42,8 @@
#include "../../feature/power_loss_recovery.h"
#endif
+#include "../../MarlinCore.h" // for startOrResumeJob
+
/**
* M24: Start or Resume SD Print
*/
@@ -54,14 +56,14 @@ void GcodeSuite::M24() {
#if ENABLED(PARK_HEAD_ON_PAUSE)
if (did_pause_print) {
- resume_print();
+ resume_print(); // will call print_job_timer.start()
return;
}
#endif
if (card.isFileOpen()) {
- card.startFileprint();
- print_job_timer.start();
+ card.startFileprint(); // SD card will now be read for commands
+ startOrResumeJob(); // Start (or resume) the print job timer
#if ENABLED(POWER_LOSS_RECOVERY)
recovery.prepare();
#endif
diff --git a/Marlin/src/gcode/sdcard/M28_M29.cpp b/Marlin/src/gcode/sdcard/M28_M29.cpp
index e23b0b4a14..c64ce7bb86 100644
--- a/Marlin/src/gcode/sdcard/M28_M29.cpp
+++ b/Marlin/src/gcode/sdcard/M28_M29.cpp
@@ -54,11 +54,11 @@ void GcodeSuite::M28() {
#endif
}
else
- card.openFile(p, false);
+ card.openFileWrite(p);
#else
- card.openFile(parser.string_arg, false);
+ card.openFileWrite(parser.string_arg);
#endif
}
diff --git a/Marlin/src/gcode/sdcard/M32.cpp b/Marlin/src/gcode/sdcard/M32.cpp
index 7e838fe2f5..2eb0717a4a 100644
--- a/Marlin/src/gcode/sdcard/M32.cpp
+++ b/Marlin/src/gcode/sdcard/M32.cpp
@@ -26,8 +26,9 @@
#include "../gcode.h"
#include "../../sd/cardreader.h"
-#include "../../module/printcounter.h"
-#include "../../module/planner.h"
+#include "../../module/planner.h" // for synchronize()
+
+#include "../../MarlinCore.h" // for startOrResumeJob
/**
* M32: Select file and start SD Print
@@ -43,16 +44,16 @@ void GcodeSuite::M32() {
if (IS_SD_PRINTING()) planner.synchronize();
if (card.isMounted()) {
- const bool call_procedure = parser.boolval('P');
+ const uint8_t call_procedure = parser.boolval('P');
- card.openFile(parser.string_arg, true, call_procedure);
+ card.openFileRead(parser.string_arg, call_procedure);
if (parser.seenval('S')) card.setIndex(parser.value_long());
card.startFileprint();
// Procedure calls count as normal print time.
- if (!call_procedure) print_job_timer.start();
+ if (!call_procedure) startOrResumeJob();
}
}
diff --git a/Marlin/src/gcode/stats/M75-M78.cpp b/Marlin/src/gcode/stats/M75-M78.cpp
index 85d36daa9b..6891a44df5 100644
--- a/Marlin/src/gcode/stats/M75-M78.cpp
+++ b/Marlin/src/gcode/stats/M75-M78.cpp
@@ -24,11 +24,13 @@
#include "../../module/printcounter.h"
#include "../../lcd/ultralcd.h"
+#include "../../MarlinCore.h" // for startOrResumeJob
+
/**
* M75: Start print timer
*/
void GcodeSuite::M75() {
- print_job_timer.start();
+ startOrResumeJob();
}
/**
@@ -42,7 +44,7 @@ void GcodeSuite::M76() {
* M77: Stop print timer
*/
void GcodeSuite::M77() {
- print_job_timer.stop();
+ print_job_timer.stop();
}
#if ENABLED(PRINTCOUNTER)
diff --git a/Marlin/src/gcode/temperature/M104_M109.cpp b/Marlin/src/gcode/temperature/M104_M109.cpp
index 86da46a89e..8c5827e83b 100644
--- a/Marlin/src/gcode/temperature/M104_M109.cpp
+++ b/Marlin/src/gcode/temperature/M104_M109.cpp
@@ -29,10 +29,14 @@
#include "../../module/motion.h"
#include "../../module/planner.h"
#include "../../lcd/ultralcd.h"
-#include "../../Marlin.h"
+
+#include "../../MarlinCore.h" // for startOrResumeJob, etc.
#if ENABLED(PRINTJOB_TIMER_AUTOSTART)
#include "../../module/printcounter.h"
+ #if ENABLED(CANCEL_OBJECTS)
+ #include "../../feature/cancel_object.h"
+ #endif
#endif
#if ENABLED(SINGLENOZZLE)
@@ -126,7 +130,7 @@ void GcodeSuite::M109() {
ui.reset_status();
}
else
- print_job_timer.start();
+ startOrResumeJob();
#endif
#if HAS_DISPLAY
diff --git a/Marlin/src/gcode/temperature/M105.cpp b/Marlin/src/gcode/temperature/M105.cpp
index bf11017a57..3dbbb5eb7b 100644
--- a/Marlin/src/gcode/temperature/M105.cpp
+++ b/Marlin/src/gcode/temperature/M105.cpp
@@ -31,16 +31,21 @@ void GcodeSuite::M105() {
const int8_t target_extruder = get_target_extruder_from_command();
if (target_extruder < 0) return;
+ SERIAL_ECHOPGM(MSG_OK);
+
#if HAS_TEMP_SENSOR
- SERIAL_ECHOPGM(MSG_OK);
+
thermalManager.print_heater_states(target_extruder
#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
, parser.boolval('R')
#endif
);
- #else // !HAS_TEMP_SENSOR
- SERIAL_ERROR_MSG(MSG_ERR_NO_THERMISTORS);
- #endif
- SERIAL_EOL();
+ SERIAL_EOL();
+
+ #else
+
+ SERIAL_ECHOLNPGM(" T:0"); // Some hosts send M105 to test the serial connection
+
+ #endif
}
diff --git a/Marlin/src/gcode/temperature/M140_M190.cpp b/Marlin/src/gcode/temperature/M140_M190.cpp
index a0d132f6b7..d6386cef50 100644
--- a/Marlin/src/gcode/temperature/M140_M190.cpp
+++ b/Marlin/src/gcode/temperature/M140_M190.cpp
@@ -37,7 +37,7 @@
#include "../../feature/leds/leds.h"
#endif
-#include "../../Marlin.h" // for wait_for_heatup and idle()
+#include "../../MarlinCore.h" // for wait_for_heatup, idle, startOrResumeJob
/**
* M140: Set bed temperature
@@ -59,12 +59,12 @@ void GcodeSuite::M190() {
thermalManager.setTargetBed(parser.value_celsius());
#if ENABLED(PRINTJOB_TIMER_AUTOSTART)
if (parser.value_celsius() > BED_MINTEMP)
- print_job_timer.start();
+ startOrResumeJob();
#endif
}
else return;
- ui.set_status_P(thermalManager.isHeatingBed() ? PSTR(MSG_BED_HEATING) : PSTR(MSG_BED_COOLING));
+ ui.set_status_P(thermalManager.isHeatingBed() ? GET_TEXT(MSG_BED_HEATING) : GET_TEXT(MSG_BED_COOLING));
thermalManager.wait_for_bed(no_wait_for_cooling);
}
diff --git a/Marlin/src/gcode/temperature/M141_M191.cpp b/Marlin/src/gcode/temperature/M141_M191.cpp
index 53deb25d2f..12eaa24bf9 100644
--- a/Marlin/src/gcode/temperature/M141_M191.cpp
+++ b/Marlin/src/gcode/temperature/M141_M191.cpp
@@ -27,7 +27,6 @@
#include "../gcode.h"
#include "../../module/temperature.h"
-/*
#include "../../module/motion.h"
#include "../../lcd/ultralcd.h"
@@ -39,8 +38,7 @@
#include "../../feature/leds/leds.h"
#endif
-#include "../../Marlin.h" // for wait_for_heatup and idle()
-*/
+#include "../../MarlinCore.h" // for wait_for_heatup, idle, startOrResumeJob
/**
* M141: Set chamber temperature
@@ -54,7 +52,6 @@ void GcodeSuite::M141() {
* M191: Sxxx Wait for chamber current temp to reach target temp. Waits only when heating
* Rxxx Wait for chamber current temp to reach target temp. Waits when heating and cooling
*/
-/*
void GcodeSuite::M191() {
if (DEBUGGING(DRYRUN)) return;
@@ -62,16 +59,17 @@ void GcodeSuite::M191() {
if (no_wait_for_cooling || parser.seenval('R')) {
thermalManager.setTargetChamber(parser.value_celsius());
#if ENABLED(PRINTJOB_TIMER_AUTOSTART)
- if (parser.value_celsius() > BED_MINTEMP)
- print_job_timer.start();
+ if (parser.value_celsius() > CHAMBER_MINTEMP)
+ startOrResumeJob();
#endif
}
else return;
- lcd_setstatusPGM(thermalManager.isHeatingChamber() ? PSTR(MSG_CHAMBER_HEATING) : PSTR(MSG_CHAMBER_COOLING));
-
- thermalManager.wait_for_chamber(no_wait_for_cooling);
+ const bool is_heating = thermalManager.isHeatingChamber();
+ if (is_heating || !no_wait_for_cooling) {
+ ui.set_status_P(is_heating ? GET_TEXT(MSG_CHAMBER_HEATING) : GET_TEXT(MSG_CHAMBER_COOLING));
+ thermalManager.wait_for_chamber(false);
+ }
}
-*/
#endif // HAS_HEATED_CHAMBER
diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h
index 101e085724..a471e3d8b1 100644
--- a/Marlin/src/inc/Conditionals_LCD.h
+++ b/Marlin/src/inc/Conditionals_LCD.h
@@ -120,7 +120,7 @@
#define DOGLCD
#define IS_ULTIPANEL
#define LED_COLORS_REDUCE_GREEN
- #if HAS_POWER_SWITCH && EITHER(FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1)
+ #if ENABLED(PSU_CONTROL) && EITHER(FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1)
#define LED_BACKLIGHT_TIMEOUT 10000
#endif
@@ -290,7 +290,7 @@
#ifndef STD_ENCODER_PULSES_PER_STEP
#if ENABLED(TOUCH_BUTTONS)
- #define STD_ENCODER_PULSES_PER_STEP 1
+ #define STD_ENCODER_PULSES_PER_STEP 2
#else
#define STD_ENCODER_PULSES_PER_STEP 5
#endif
@@ -347,7 +347,7 @@
#endif
// Extensible UI serial touch screens. (See src/lcd/extensible_ui)
-#if ANY(MALYAN_LCD, DGUS_LCD, LULZBOT_TOUCH_UI)
+#if ANY(MALYAN_LCD, DGUS_LCD, TOUCH_UI_FTDI_EVE)
#define IS_EXTUI
#define EXTENSIBLE_UI
#endif
@@ -416,7 +416,6 @@
#if EITHER(SINGLENOZZLE, MIXING_EXTRUDER) // One hotend, one thermistor, no XY offset
#undef HOTENDS
#define HOTENDS 1
- #undef TEMP_SENSOR_1_AS_REDUNDANT
#undef HOTEND_OFFSET_X
#undef HOTEND_OFFSET_Y
#endif
@@ -497,12 +496,12 @@
/**
* Set flags for enabled probes
*/
-#define HAS_BED_PROBE (HAS_Z_SERVO_PROBE || ANY(FIX_MOUNTED_PROBE, TOUCH_MI_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, SOLENOID_PROBE, SENSORLESS_PROBING, RACK_AND_PINION_PROBE))
+#define HAS_BED_PROBE (HAS_Z_SERVO_PROBE || ANY(FIX_MOUNTED_PROBE, NOZZLE_AS_PROBE, TOUCH_MI_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, SOLENOID_PROBE, SENSORLESS_PROBING, RACK_AND_PINION_PROBE))
#define PROBE_SELECTED (HAS_BED_PROBE || EITHER(PROBE_MANUALLY, MESH_BED_LEVELING))
#if HAS_BED_PROBE
- #define USES_Z_MIN_PROBE_ENDSTOP DISABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
- #define HOMING_Z_WITH_PROBE (Z_HOME_DIR < 0 && !USES_Z_MIN_PROBE_ENDSTOP)
+ #define HAS_CUSTOM_PROBE_PIN DISABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
+ #define HOMING_Z_WITH_PROBE (Z_HOME_DIR < 0 && !HAS_CUSTOM_PROBE_PIN)
#ifndef Z_PROBE_LOW_POINT
#define Z_PROBE_LOW_POINT -5
#endif
@@ -525,13 +524,14 @@
#define GRID_MAX_POINTS ((GRID_MAX_POINTS_X) * (GRID_MAX_POINTS_Y))
#endif
-#define HAS_SOFTWARE_ENDSTOPS EITHER(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS)
-#define HAS_RESUME_CONTINUE ANY(EXTENSIBLE_UI, NEWPANEL, EMERGENCY_PARSER)
-#define HAS_COLOR_LEDS ANY(BLINKM, RGB_LED, RGBW_LED, PCA9632, PCA9533, NEOPIXEL_LED)
-#define HAS_LEDS_OFF_FLAG (BOTH(PRINTER_EVENT_LEDS, SDSUPPORT) && HAS_RESUME_CONTINUE)
-#define HAS_PRINT_PROGRESS EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY)
-#define HAS_SERVICE_INTERVALS (ENABLED(PRINTCOUNTER) && (SERVICE_INTERVAL_1 > 0 || SERVICE_INTERVAL_2 > 0 || SERVICE_INTERVAL_3 > 0))
-#define HAS_FILAMENT_SENSOR ENABLED(FILAMENT_RUNOUT_SENSOR)
+#define HAS_SOFTWARE_ENDSTOPS EITHER(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS)
+#define HAS_RESUME_CONTINUE ANY(EXTENSIBLE_UI, NEWPANEL, EMERGENCY_PARSER)
+#define HAS_COLOR_LEDS ANY(BLINKM, RGB_LED, RGBW_LED, PCA9632, PCA9533, NEOPIXEL_LED)
+#define HAS_LEDS_OFF_FLAG (BOTH(PRINTER_EVENT_LEDS, SDSUPPORT) && HAS_RESUME_CONTINUE)
+#define HAS_PRINT_PROGRESS EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY)
+#define HAS_PRINT_PROGRESS_PERMYRIAD (HAS_PRINT_PROGRESS && EITHER(PRINT_PROGRESS_SHOW_DECIMALS, SHOW_REMAINING_TIME))
+#define HAS_SERVICE_INTERVALS (ENABLED(PRINTCOUNTER) && (SERVICE_INTERVAL_1 > 0 || SERVICE_INTERVAL_2 > 0 || SERVICE_INTERVAL_3 > 0))
+#define HAS_FILAMENT_SENSOR ENABLED(FILAMENT_RUNOUT_SENSOR)
#define Z_MULTI_STEPPER_DRIVERS EITHER(Z_DUAL_STEPPER_DRIVERS, Z_TRIPLE_STEPPER_DRIVERS)
#define Z_MULTI_ENDSTOPS EITHER(Z_DUAL_ENDSTOPS, Z_TRIPLE_ENDSTOPS)
@@ -561,6 +561,12 @@
#define BOOT_MARLIN_LOGO_SMALL
#endif
-#define IS_RE_ARM_BOARD (MB(RAMPS_14_RE_ARM_EFB) || MB(RAMPS_14_RE_ARM_EEB) || MB(RAMPS_14_RE_ARM_EFF) || MB(RAMPS_14_RE_ARM_EEF) || MB(RAMPS_14_RE_ARM_SF))
+#define IS_RE_ARM_BOARD MB(RAMPS_14_RE_ARM_EFB, RAMPS_14_RE_ARM_EEB, RAMPS_14_RE_ARM_EFF, RAMPS_14_RE_ARM_EEF, RAMPS_14_RE_ARM_SF)
#define HAS_SDCARD_CONNECTION EITHER(TARGET_LPC1768, ADAFRUIT_GRAND_CENTRAL_M4)
+
+#define HAS_LINEAR_E_JERK (DISABLED(CLASSIC_JERK) && ENABLED(LIN_ADVANCE))
+
+#ifndef SPI_SPEED
+ #define SPI_SPEED SPI_FULL_SPEED
+#endif
diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h
index 01b27f2c17..0f62a7b577 100644
--- a/Marlin/src/inc/Conditionals_adv.h
+++ b/Marlin/src/inc/Conditionals_adv.h
@@ -129,7 +129,7 @@
#endif
// Extensible UI pin mapping for RepRapDiscount
-#define TOUCH_UI_ULTIPANEL ENABLED(LULZBOT_TOUCH_UI) && ANY(AO_EXP1_PINMAP, AO_EXP2_PINMAP, CR10_TFT_PINMAP)
+#define TOUCH_UI_ULTIPANEL ENABLED(TOUCH_UI_FTDI_EVE) && ANY(AO_EXP1_PINMAP, AO_EXP2_PINMAP, CR10_TFT_PINMAP)
// Poll-based jogging for joystick and other devices
#if ENABLED(JOYSTICK)
diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h
index 6c1f173f94..28c1c93a0f 100644
--- a/Marlin/src/inc/Conditionals_post.h
+++ b/Marlin/src/inc/Conditionals_post.h
@@ -26,12 +26,9 @@
* Defines that depend on configuration but are not editable.
*/
-#define AVR_ATmega2560_FAMILY_PLUS_70 ( \
- MB(BQ_ZUM_MEGA_3D) \
- || MB(MIGHTYBOARD_REVE) \
- || MB(MINIRAMBO) \
- || MB(SCOOVO_X9H) \
-)
+#ifdef GITHUB_ACTIONS
+ // Extras for CI testing
+#endif
#ifdef TEENSYDUINO
#undef max
@@ -43,7 +40,8 @@
#define NOT_A_PIN 0 // For PINS_DEBUGGING
#endif
-#define HAS_CLASSIC_JERK (IS_KINEMATIC || DISABLED(JUNCTION_DEVIATION))
+#define HAS_CLASSIC_JERK (ENABLED(CLASSIC_JERK) || IS_KINEMATIC)
+#define HAS_CLASSIC_E_JERK (ENABLED(CLASSIC_JERK) || DISABLED(LIN_ADVANCE))
/**
* Axis lengths and center
@@ -131,10 +129,12 @@
/**
* SCARA cannot use SLOWDOWN and requires QUICKHOME
+ * Printable radius assumes joints can fully extend
*/
#if IS_SCARA
#undef SLOWDOWN
#define QUICK_HOME
+ #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2)
#endif
/**
@@ -220,11 +220,6 @@
#ifndef Z_SAFE_HOMING_Y_POINT
#define Z_SAFE_HOMING_Y_POINT _SAFE_POINT(Y)
#endif
- #define X_TILT_FULCRUM Z_SAFE_HOMING_X_POINT
- #define Y_TILT_FULCRUM Z_SAFE_HOMING_Y_POINT
-#else
- #define X_TILT_FULCRUM X_HOME_POS
- #define Y_TILT_FULCRUM Y_HOME_POS
#endif
/**
@@ -261,6 +256,9 @@
#elif ENABLED(AZSMZ_12864)
#define _LCD_CONTRAST_MIN 120
#define _LCD_CONTRAST_INIT 190
+#elif ENABLED(MKS_LCD12864B)
+ #define _LCD_CONTRAST_MIN 120
+ #define _LCD_CONTRAST_INIT 205
#elif ENABLED(MKS_MINI_12864)
#define _LCD_CONTRAST_MIN 120
#define _LCD_CONTRAST_INIT 195
@@ -323,21 +321,21 @@
#endif
/**
- * Power Supply Control
+ * Power Supply
*/
#ifndef PSU_NAME
- #if ENABLED(PSU_CONTROL)
- #if PSU_ACTIVE_HIGH
- #define PSU_NAME "XBox" // X-Box 360 (203W)
- #else
- #define PSU_NAME "ATX" // ATX style
- #endif
+ #if DISABLED(PSU_CONTROL)
+ #define PSU_NAME "Generic" // No control
+ #elif PSU_ACTIVE_HIGH
+ #define PSU_NAME "XBox" // X-Box 360 (203W)
#else
- #define PSU_NAME "Generic" // No control
+ #define PSU_NAME "ATX" // ATX style
#endif
#endif
-#define HAS_POWER_SWITCH (ENABLED(PSU_CONTROL) && PIN_EXISTS(PS_ON))
+#if !defined(PSU_POWERUP_DELAY) && ENABLED(PSU_CONTROL)
+ #define PSU_POWERUP_DELAY 100
+#endif
/**
* Temp Sensor defines
@@ -347,17 +345,22 @@
#define HAS_USER_THERMISTORS ANY_TEMP_SENSOR_IS(1000)
-#if TEMP_SENSOR_0 == -4
+#if TEMP_SENSOR_0 == -5 || TEMP_SENSOR_0 == -3 || TEMP_SENSOR_0 == -2
+ #define HEATER_0_USES_MAX6675
+ #if TEMP_SENSOR_0 == -3
+ #define HEATER_0_MAX6675_TMIN -270
+ #define HEATER_0_MAX6675_TMAX 1800
+ #else
+ #define HEATER_0_MAX6675_TMIN 0
+ #define HEATER_0_MAX6675_TMAX 1024
+ #endif
+ #if TEMP_SENSOR_0 == -5
+ #define MAX6675_IS_MAX31865
+ #elif TEMP_SENSOR_0 == -3
+ #define MAX6675_IS_MAX31855
+ #endif
+#elif TEMP_SENSOR_0 == -4
#define HEATER_0_USES_AD8495
-#elif TEMP_SENSOR_0 == -3
- #define HEATER_0_USES_MAX6675
- #define MAX6675_IS_MAX31855
- #define HEATER_0_MAX6675_TMIN -270
- #define HEATER_0_MAX6675_TMAX 1800
-#elif TEMP_SENSOR_0 == -2
- #define HEATER_0_USES_MAX6675
- #define HEATER_0_MAX6675_TMIN 0
- #define HEATER_0_MAX6675_TMAX 1024
#elif TEMP_SENSOR_0 == -1
#define HEATER_0_USES_AD595
#elif TEMP_SENSOR_0 > 0
@@ -371,22 +374,26 @@
#undef HEATER_0_MAXTEMP
#endif
-#if TEMP_SENSOR_1 == -4
+#if TEMP_SENSOR_1 == -5 || TEMP_SENSOR_1 == -3 || TEMP_SENSOR_1 == -2
+ #define HEATER_1_USES_MAX6675
+ #if TEMP_SENSOR_1 == -3
+ #define HEATER_1_MAX6675_TMIN -270
+ #define HEATER_1_MAX6675_TMAX 1800
+ #else
+ #define HEATER_1_MAX6675_TMIN 0
+ #define HEATER_1_MAX6675_TMAX 1024
+ #endif
+ #if TEMP_SENSOR_1 != TEMP_SENSOR_0
+ #if TEMP_SENSOR_1 == -5
+ #error "If MAX31865 Thermocouple (-5) is used for TEMP_SENSOR_1 then TEMP_SENSOR_0 must match."
+ #elif TEMP_SENSOR_1 == -3
+ #error "If MAX31855 Thermocouple (-3) is used for TEMP_SENSOR_1 then TEMP_SENSOR_0 must match."
+ #elif TEMP_SENSOR_1 == -2
+ #error "If MAX6675 Thermocouple (-2) is used for TEMP_SENSOR_1 then TEMP_SENSOR_0 must match."
+ #endif
+ #endif
+#elif TEMP_SENSOR_1 == -4
#define HEATER_1_USES_AD8495
-#elif TEMP_SENSOR_1 == -3
- #if TEMP_SENSOR_0 == -2
- #error "If MAX31855 Thermocouple (-3) is used for TEMP_SENSOR_1 then TEMP_SENSOR_0 must match."
- #endif
- #define HEATER_1_USES_MAX6675
- #define HEATER_1_MAX6675_TMIN -270
- #define HEATER_1_MAX6675_TMAX 1800
-#elif TEMP_SENSOR_1 == -2
- #if TEMP_SENSOR_0 == -3
- #error "If MAX31855 Thermocouple (-3) is used for TEMP_SENSOR_0 then TEMP_SENSOR_1 must match."
- #endif
- #define HEATER_1_USES_MAX6675
- #define HEATER_1_MAX6675_TMIN 0
- #define HEATER_1_MAX6675_TMAX 1024
#elif TEMP_SENSOR_1 == -1
#define HEATER_1_USES_AD595
#elif TEMP_SENSOR_1 > 0
@@ -549,8 +556,6 @@
* Preserve this ordering when adding new drivers.
*/
-#define TRINAMICS (HAS_TRINAMIC || HAS_DRIVER(TMC2130_STANDALONE) || HAS_DRIVER(TMC2208_STANDALONE) || HAS_DRIVER(TMC2209_STANDALONE) || HAS_DRIVER(TMC26X_STANDALONE) || HAS_DRIVER(TMC2660_STANDALONE) || HAS_DRIVER(TMC5130_STANDALONE) || HAS_DRIVER(TMC5160_STANDALONE) || HAS_DRIVER(TMC2160_STANDALONE))
-
#ifndef MINIMUM_STEPPER_POST_DIR_DELAY
#if HAS_DRIVER(TB6560)
#define MINIMUM_STEPPER_POST_DIR_DELAY 15000
@@ -564,7 +569,7 @@
#define MINIMUM_STEPPER_POST_DIR_DELAY 400
#elif HAS_DRIVER(A4988)
#define MINIMUM_STEPPER_POST_DIR_DELAY 200
- #elif TRINAMICS
+ #elif HAS_TRINAMIC || HAS_TRINAMIC_STANDALONE
#define MINIMUM_STEPPER_POST_DIR_DELAY 20
#else
#define MINIMUM_STEPPER_POST_DIR_DELAY 0 // Expect at least 10µS since one Stepper ISR must transpire
@@ -584,10 +589,10 @@
#define MINIMUM_STEPPER_PULSE 2
#elif HAS_DRIVER(A4988) || HAS_DRIVER(A5984)
#define MINIMUM_STEPPER_PULSE 1
- #elif HAS_DRIVER(LV8729)
- #define MINIMUM_STEPPER_PULSE 0
#elif TRINAMICS
#define MINIMUM_STEPPER_PULSE 0
+ #elif HAS_DRIVER(LV8729)
+ #define MINIMUM_STEPPER_PULSE 0
#else
#define MINIMUM_STEPPER_PULSE 2
#endif
@@ -598,14 +603,14 @@
#define MAXIMUM_STEPPER_RATE 15000
#elif HAS_DRIVER(TB6600)
#define MAXIMUM_STEPPER_RATE 150000
- #elif HAS_DRIVER(LV8729)
- #define MAXIMUM_STEPPER_RATE 200000
#elif HAS_DRIVER(DRV8825)
#define MAXIMUM_STEPPER_RATE 250000
- #elif TRINAMICS
- #define MAXIMUM_STEPPER_RATE 400000
#elif HAS_DRIVER(A4988)
#define MAXIMUM_STEPPER_RATE 500000
+ #elif HAS_DRIVER(LV8729)
+ #define MAXIMUM_STEPPER_RATE 1000000
+ #elif TRINAMICS
+ #define MAXIMUM_STEPPER_RATE 5000000
#else
#define MAXIMUM_STEPPER_RATE 250000
#endif
@@ -829,12 +834,12 @@
// Is an endstop plug used for the Z2 endstop or the bed probe?
#define IS_Z2_OR_PROBE(A,M) ( \
(Z_MULTI_ENDSTOPS && Z2_USE_ENDSTOP == _##A##M##_) \
- || (USES_Z_MIN_PROBE_ENDSTOP && Z_MIN_PROBE_PIN == A##_##M##_PIN ) )
+ || (HAS_CUSTOM_PROBE_PIN && Z_MIN_PROBE_PIN == A##_##M##_PIN ) )
// Is an endstop plug used for the Z3 endstop or the bed probe?
#define IS_Z3_OR_PROBE(A,M) ( \
(ENABLED(Z_TRIPLE_ENDSTOPS) && Z3_USE_ENDSTOP == _##A##M##_) \
- || (USES_Z_MIN_PROBE_ENDSTOP && Z_MIN_PROBE_PIN == A##_##M##_PIN ) )
+ || (HAS_CUSTOM_PROBE_PIN && Z_MIN_PROBE_PIN == A##_##M##_PIN ) )
/**
* Set ENDSTOPPULLUPS for active endstop switches
@@ -963,11 +968,6 @@
// Trinamic Stepper Drivers
#if HAS_TRINAMIC
- #define HAS_TMCX1X0 (HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2160) || HAS_DRIVER(TMC5130) || HAS_DRIVER(TMC5160))
- #define TMC_HAS_SPI (HAS_TMCX1X0 || HAS_DRIVER(TMC2660))
- #define HAS_STALLGUARD (HAS_TMCX1X0 || HAS_DRIVER(TMC2209) || HAS_DRIVER(TMC2660))
- #define HAS_STEALTHCHOP (HAS_TMCX1X0 || HAS_TMC220x)
-
#define STEALTHCHOP_ENABLED ANY(STEALTHCHOP_XY, STEALTHCHOP_Z, STEALTHCHOP_E)
#define USE_SENSORLESS EITHER(SENSORLESS_HOMING, SENSORLESS_PROBING)
// Disable Z axis sensorless homing if a probe is used to home the Z axis
@@ -1009,7 +1009,7 @@
#define HAS_Z2_MAX (PIN_EXISTS(Z2_MAX))
#define HAS_Z3_MIN (PIN_EXISTS(Z3_MIN))
#define HAS_Z3_MAX (PIN_EXISTS(Z3_MAX))
-#define HAS_Z_MIN_PROBE_PIN (USES_Z_MIN_PROBE_ENDSTOP && PIN_EXISTS(Z_MIN_PROBE))
+#define HAS_Z_MIN_PROBE_PIN (HAS_CUSTOM_PROBE_PIN && PIN_EXISTS(Z_MIN_PROBE))
#define HAS_CALIBRATION_PIN (PIN_EXISTS(CALIBRATION))
// ADC Temp Sensors (Thermistor or Thermocouple with amplifier ADC interface)
@@ -1023,7 +1023,7 @@
#define HAS_TEMP_ADC_BED HAS_ADC_TEST(BED)
#define HAS_TEMP_ADC_CHAMBER HAS_ADC_TEST(CHAMBER)
-#define HAS_TEMP_HOTEND (HAS_TEMP_ADC_0 || ENABLED(HEATER_0_USES_MAX6675))
+#define HAS_TEMP_HOTEND (HOTENDS > 0 && (HAS_TEMP_ADC_0 || ENABLED(HEATER_0_USES_MAX6675)))
#define HAS_TEMP_BED HAS_TEMP_ADC_BED
#define HAS_TEMP_CHAMBER HAS_TEMP_ADC_CHAMBER
#define HAS_HEATED_CHAMBER (HAS_TEMP_CHAMBER && PIN_EXISTS(HEATER_CHAMBER))
@@ -1076,14 +1076,9 @@
#define HAS_AUTO_CHAMBER_FAN (HAS_TEMP_CHAMBER && PIN_EXISTS(CHAMBER_AUTO_FAN))
#define HAS_AUTO_FAN (HAS_AUTO_FAN_0 || HAS_AUTO_FAN_1 || HAS_AUTO_FAN_2 || HAS_AUTO_FAN_3 || HAS_AUTO_FAN_4 || HAS_AUTO_FAN_5 || HAS_AUTO_CHAMBER_FAN)
+#define _FANOVERLAP(A,B) (A##_AUTO_FAN_PIN == E##B##_AUTO_FAN_PIN)
#if HAS_AUTO_FAN
- #define AUTO_CHAMBER_IS_0 (CHAMBER_AUTO_FAN_PIN == E0_AUTO_FAN_PIN)
- #define AUTO_CHAMBER_IS_1 (CHAMBER_AUTO_FAN_PIN == E1_AUTO_FAN_PIN)
- #define AUTO_CHAMBER_IS_2 (CHAMBER_AUTO_FAN_PIN == E2_AUTO_FAN_PIN)
- #define AUTO_CHAMBER_IS_3 (CHAMBER_AUTO_FAN_PIN == E3_AUTO_FAN_PIN)
- #define AUTO_CHAMBER_IS_4 (CHAMBER_AUTO_FAN_PIN == E4_AUTO_FAN_PIN)
- #define AUTO_CHAMBER_IS_5 (CHAMBER_AUTO_FAN_PIN == E5_AUTO_FAN_PIN)
- #define AUTO_CHAMBER_IS_E (AUTO_CHAMBER_IS_0 || AUTO_CHAMBER_IS_1 || AUTO_CHAMBER_IS_2 || AUTO_CHAMBER_IS_3 || AUTO_CHAMBER_IS_4 || AUTO_CHAMBER_IS_5)
+ #define AUTO_CHAMBER_IS_E (_FANOVERLAP(CHAMBER,0) || _FANOVERLAP(CHAMBER,1) || _FANOVERLAP(CHAMBER,2) || _FANOVERLAP(CHAMBER,3) || _FANOVERLAP(CHAMBER,4) || _FANOVERLAP(CHAMBER,5))
#endif
#if !HAS_AUTO_CHAMBER_FAN || AUTO_CHAMBER_IS_E
@@ -1313,8 +1308,15 @@
/**
* MIN/MAX fan PWM scaling
*/
+#ifndef FAN_OFF_PWM
+ #define FAN_OFF_PWM 0
+#endif
#ifndef FAN_MIN_PWM
- #define FAN_MIN_PWM 0
+ #if FAN_OFF_PWM > 0
+ #define FAN_MIN_PWM (FAN_OFF_PWM + 1)
+ #else
+ #define FAN_MIN_PWM 0
+ #endif
#endif
#ifndef FAN_MAX_PWM
#define FAN_MAX_PWM 255
@@ -1325,6 +1327,8 @@
#error "FAN_MAX_PWM must be a value from 0 to 255."
#elif FAN_MIN_PWM > FAN_MAX_PWM
#error "FAN_MIN_PWM must be less than or equal to FAN_MAX_PWM."
+#elif FAN_OFF_PWM > FAN_MIN_PWM
+ #error "FAN_OFF_PWM must be less than or equal to FAN_MIN_PWM."
#endif
/**
@@ -1365,6 +1369,9 @@
#define XY_PROBE_SPEED 4000
#endif
#endif
+ #ifndef NOZZLE_TO_PROBE_OFFSET
+ #define NOZZLE_TO_PROBE_OFFSET { 0, 0, 0 }
+ #endif
#else
#undef NOZZLE_TO_PROBE_OFFSET
#endif
@@ -1420,6 +1427,7 @@
#define PLANNER_LEVELING (HAS_LEVELING && DISABLED(AUTO_BED_LEVELING_UBL))
#define HAS_PROBING_PROCEDURE (HAS_ABL_OR_UBL || ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST))
#define HAS_POSITION_MODIFIERS (ENABLED(FWRETRACT) || HAS_LEVELING || ENABLED(SKEW_CORRECTION))
+#define NEEDS_THREE_PROBE_POINTS EITHER(AUTO_BED_LEVELING_UBL, AUTO_BED_LEVELING_3POINT)
#if ENABLED(AUTO_BED_LEVELING_UBL)
#undef LCD_BED_LEVELING
@@ -1456,41 +1464,41 @@
#endif
/**
- * Bed Probing rectangular bounds
- * These can be further constrained in code for Delta and SCARA
+ * Bed Probing bounds
*/
+
#ifndef MIN_PROBE_EDGE
#define MIN_PROBE_EDGE 0
#endif
-#ifndef MIN_PROBE_EDGE_LEFT
- #define MIN_PROBE_EDGE_LEFT MIN_PROBE_EDGE
-#endif
-#ifndef MIN_PROBE_EDGE_RIGHT
- #define MIN_PROBE_EDGE_RIGHT MIN_PROBE_EDGE
-#endif
-#ifndef MIN_PROBE_EDGE_FRONT
- #define MIN_PROBE_EDGE_FRONT MIN_PROBE_EDGE
-#endif
-#ifndef MIN_PROBE_EDGE_BACK
- #define MIN_PROBE_EDGE_BACK MIN_PROBE_EDGE
-#endif
-#ifndef NOZZLE_TO_PROBE_OFFSET
- #define NOZZLE_TO_PROBE_OFFSET { 0, 0, 0 }
+#if IS_KINEMATIC
+ #undef MIN_PROBE_EDGE_LEFT
+ #undef MIN_PROBE_EDGE_RIGHT
+ #undef MIN_PROBE_EDGE_FRONT
+ #undef MIN_PROBE_EDGE_BACK
+ #define MIN_PROBE_EDGE_LEFT 0
+ #define MIN_PROBE_EDGE_RIGHT 0
+ #define MIN_PROBE_EDGE_FRONT 0
+ #define MIN_PROBE_EDGE_BACK 0
+#else
+ #ifndef MIN_PROBE_EDGE_LEFT
+ #define MIN_PROBE_EDGE_LEFT MIN_PROBE_EDGE
+ #endif
+ #ifndef MIN_PROBE_EDGE_RIGHT
+ #define MIN_PROBE_EDGE_RIGHT MIN_PROBE_EDGE
+ #endif
+ #ifndef MIN_PROBE_EDGE_FRONT
+ #define MIN_PROBE_EDGE_FRONT MIN_PROBE_EDGE
+ #endif
+ #ifndef MIN_PROBE_EDGE_BACK
+ #define MIN_PROBE_EDGE_BACK MIN_PROBE_EDGE
+ #endif
#endif
#if ENABLED(DELTA)
/**
* Delta radius/rod trimmers/angle trimmers
*/
- #define _PROBE_RADIUS (DELTA_PRINTABLE_RADIUS - (MIN_PROBE_EDGE))
- #ifndef DELTA_CALIBRATION_RADIUS
- #ifdef NOZZLE_TO_PROBE_OFFSET
- #define DELTA_CALIBRATION_RADIUS (DELTA_PRINTABLE_RADIUS - _MAX(ABS(nozzle_to_probe_offset.x), ABS(nozzle_to_probe_offset.y), ABS(MIN_PROBE_EDGE)))
- #else
- #define DELTA_CALIBRATION_RADIUS _PROBE_RADIUS
- #endif
- #endif
#ifndef DELTA_ENDSTOP_ADJ
#define DELTA_ENDSTOP_ADJ { 0, 0, 0 }
#endif
@@ -1503,24 +1511,6 @@
#ifndef DELTA_DIAGONAL_ROD_TRIM_TOWER
#define DELTA_DIAGONAL_ROD_TRIM_TOWER { 0, 0, 0 }
#endif
-
- // Probing points may be verified at compile time within the radius
- // using static_assert(HYPOT2(X2-X1,Y2-Y1)<=sq(DELTA_PRINTABLE_RADIUS),"bad probe point!")
- // so that may be added to SanityCheck.h in the future.
- #define PROBE_X_MIN (X_CENTER - (_PROBE_RADIUS))
- #define PROBE_Y_MIN (Y_CENTER - (_PROBE_RADIUS))
- #define PROBE_X_MAX (X_CENTER + _PROBE_RADIUS)
- #define PROBE_Y_MAX (Y_CENTER + _PROBE_RADIUS)
-
-#elif IS_SCARA
-
- #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2)
- #define _PROBE_RADIUS (SCARA_PRINTABLE_RADIUS - (MIN_PROBE_EDGE))
- #define PROBE_X_MIN (X_CENTER - (SCARA_PRINTABLE_RADIUS) + MIN_PROBE_EDGE_LEFT)
- #define PROBE_Y_MIN (Y_CENTER - (SCARA_PRINTABLE_RADIUS) + MIN_PROBE_EDGE_FRONT)
- #define PROBE_X_MAX (X_CENTER + SCARA_PRINTABLE_RADIUS - (MIN_PROBE_EDGE_RIGHT))
- #define PROBE_Y_MAX (Y_CENTER + SCARA_PRINTABLE_RADIUS - (MIN_PROBE_EDGE_BACK))
-
#endif
#if ENABLED(SEGMENT_LEVELED_MOVES) && !defined(LEVELED_SEGMENT_LENGTH)
@@ -1530,7 +1520,7 @@
/**
* Default mesh area is an area with an inset margin on the print area.
*/
-#if HAS_LEVELING
+#if EITHER(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL)
#if IS_KINEMATIC
// Probing points may be verified at compile time within the radius
// using static_assert(HYPOT2(X2-X1,Y2-Y1)<=sq(DELTA_PRINTABLE_RADIUS),"bad probe point!")
@@ -1541,17 +1531,10 @@
#define _MESH_MAX_Y (Y_MAX_BED - (MESH_INSET))
#else
// Boundaries for Cartesian probing based on set limits
- #if EITHER(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL)
- #define _MESH_MIN_X (_MAX(X_MIN_BED + MESH_INSET, X_MIN_POS)) // UBL is careful not to probe off the bed. It does not
- #define _MESH_MIN_Y (_MAX(Y_MIN_BED + MESH_INSET, Y_MIN_POS)) // need NOZZLE_TO_PROBE_OFFSET in the mesh dimensions
- #define _MESH_MAX_X (_MIN(X_MAX_BED - (MESH_INSET), X_MAX_POS))
- #define _MESH_MAX_Y (_MIN(Y_MAX_BED - (MESH_INSET), Y_MAX_POS))
- #else
- #define _MESH_MIN_X (_MAX(X_MIN_BED + MESH_INSET, X_MIN_POS + nozzle_to_probe_offset.x))
- #define _MESH_MIN_Y (_MAX(Y_MIN_BED + MESH_INSET, Y_MIN_POS + nozzle_to_probe_offset.y))
- #define _MESH_MAX_X (_MIN(X_MAX_BED - (MESH_INSET), X_MAX_POS + nozzle_to_probe_offset.x))
- #define _MESH_MAX_Y (_MIN(Y_MAX_BED - (MESH_INSET), Y_MAX_POS + nozzle_to_probe_offset.y))
- #endif
+ #define _MESH_MIN_X (_MAX(X_MIN_BED + MESH_INSET, X_MIN_POS)) // UBL is careful not to probe off the bed. It does not
+ #define _MESH_MIN_Y (_MAX(Y_MIN_BED + MESH_INSET, Y_MIN_POS)) // need NOZZLE_TO_PROBE_OFFSET in the mesh dimensions
+ #define _MESH_MAX_X (_MIN(X_MAX_BED - (MESH_INSET), X_MAX_POS))
+ #define _MESH_MAX_Y (_MIN(Y_MAX_BED - (MESH_INSET), Y_MAX_POS))
#endif
// These may be overridden in Configuration.h if a smaller area is desired
@@ -1567,41 +1550,18 @@
#ifndef MESH_MAX_Y
#define MESH_MAX_Y _MESH_MAX_Y
#endif
-
-#endif // MESH_BED_LEVELING || AUTO_BED_LEVELING_UBL
-
-#if ALL(PROBE_PT_1_X, PROBE_PT_2_X, PROBE_PT_3_X, PROBE_PT_1_Y, PROBE_PT_2_Y, PROBE_PT_3_Y)
- #define HAS_FIXED_3POINT;
+#else
+ #undef MESH_MIN_X
+ #undef MESH_MIN_Y
+ #undef MESH_MAX_X
+ #undef MESH_MAX_Y
#endif
-#if EITHER(AUTO_BED_LEVELING_UBL, AUTO_BED_LEVELING_3POINT) && IS_KINEMATIC
- #define HAS_FIXED_3POINT
- #define SIN0 0.0
- #define SIN120 0.866025
- #define SIN240 -0.866025
- #define COS0 1.0
- #define COS120 -0.5
- #define COS240 -0.5
- #ifndef PROBE_PT_1_X
- #define PROBE_PT_1_X (X_CENTER + (_PROBE_RADIUS) * COS0)
- #endif
- #ifndef PROBE_PT_1_Y
- #define PROBE_PT_1_Y (Y_CENTER + (_PROBE_RADIUS) * SIN0)
- #endif
- #ifndef PROBE_PT_2_X
- #define PROBE_PT_2_X (X_CENTER + (_PROBE_RADIUS) * COS120)
- #endif
- #ifndef PROBE_PT_2_Y
- #define PROBE_PT_2_Y (Y_CENTER + (_PROBE_RADIUS) * SIN120)
- #endif
- #ifndef PROBE_PT_3_X
- #define PROBE_PT_3_X (X_CENTER + (_PROBE_RADIUS) * COS240)
- #endif
- #ifndef PROBE_PT_3_Y
- #define PROBE_PT_3_Y (Y_CENTER + (_PROBE_RADIUS) * SIN240)
- #endif
+#if (defined(PROBE_PT_1_X) && defined(PROBE_PT_2_X) && defined(PROBE_PT_3_X) && defined(PROBE_PT_1_Y) && defined(PROBE_PT_2_Y) && defined(PROBE_PT_3_Y))
+ #define HAS_FIXED_3POINT
#endif
+
/**
* Buzzer/Speaker
*/
@@ -1777,23 +1737,25 @@
#define Z_STEPPER_COUNT 1
#endif
-// Get LCD character width/height, which may be overridden by pins, configs, etc.
-#ifndef LCD_WIDTH
- #if HAS_GRAPHICAL_LCD
- #define LCD_WIDTH 21
- #elif ENABLED(ULTIPANEL)
- #define LCD_WIDTH 20
- #elif HAS_SPI_LCD
- #define LCD_WIDTH 16
+#if HAS_SPI_LCD
+ // Get LCD character width/height, which may be overridden by pins, configs, etc.
+ #ifndef LCD_WIDTH
+ #if HAS_GRAPHICAL_LCD
+ #define LCD_WIDTH 21
+ #elif ENABLED(ULTIPANEL)
+ #define LCD_WIDTH 20
+ #else
+ #define LCD_WIDTH 16
+ #endif
#endif
-#endif
-#ifndef LCD_HEIGHT
- #if HAS_GRAPHICAL_LCD
- #define LCD_HEIGHT 5
- #elif ENABLED(ULTIPANEL)
- #define LCD_HEIGHT 4
- #elif HAS_SPI_LCD
- #define LCD_HEIGHT 2
+ #ifndef LCD_HEIGHT
+ #if HAS_GRAPHICAL_LCD
+ #define LCD_HEIGHT 5
+ #elif ENABLED(ULTIPANEL)
+ #define LCD_HEIGHT 4
+ #else
+ #define LCD_HEIGHT 2
+ #endif
#endif
#endif
@@ -1815,3 +1777,10 @@
#if !NUM_SERIAL
#undef BAUD_RATE_GCODE
#endif
+
+#if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
+ #undef Z_STEPPER_ALIGN_AMP
+#endif
+#ifndef Z_STEPPER_ALIGN_AMP
+ #define Z_STEPPER_ALIGN_AMP 1.0
+#endif
diff --git a/Marlin/src/inc/MarlinConfigPre.h b/Marlin/src/inc/MarlinConfigPre.h
index e34b70376e..e11f171c6e 100644
--- a/Marlin/src/inc/MarlinConfigPre.h
+++ b/Marlin/src/inc/MarlinConfigPre.h
@@ -34,9 +34,20 @@
#include "../core/boards.h"
#include "../core/macros.h"
-#include "Version.h"
#include "../../Configuration.h"
+#ifdef CUSTOM_VERSION_FILE
+ #if defined(__has_include)
+ #if __has_include(XSTR(../../CUSTOM_VERSION_FILE))
+ #include XSTR(../../CUSTOM_VERSION_FILE)
+ #endif
+ #else
+ #include XSTR(../../CUSTOM_VERSION_FILE)
+ #endif
+#endif
+
+#include "Version.h"
+
#include "Conditionals_LCD.h"
#include HAL_PATH(../HAL, inc/Conditionals_LCD.h)
diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h
index e37e0b27cd..9c5b7893fc 100644
--- a/Marlin/src/inc/SanityCheck.h
+++ b/Marlin/src/inc/SanityCheck.h
@@ -74,7 +74,9 @@
#elif defined(CUSTOM_MENDEL_NAME)
#error "CUSTOM_MENDEL_NAME is now CUSTOM_MACHINE_NAME. Please update your configuration."
#elif defined(HAS_AUTOMATIC_VERSIONING)
- #error "HAS_AUTOMATIC_VERSIONING is now USE_AUTOMATIC_VERSIONING. Please update your configuration."
+ #error "HAS_AUTOMATIC_VERSIONING is now CUSTOM_VERSION_FILE. Please update your configuration."
+#elif defined(USE_AUTOMATIC_VERSIONING)
+ #error "USE_AUTOMATIC_VERSIONING is now CUSTOM_VERSION_FILE. Please update your configuration."
#elif defined(SDSLOW)
#error "SDSLOW deprecated. Set SPI_SPEED to SPI_HALF_SPEED instead."
#elif defined(SDEXTRASLOW)
@@ -227,6 +229,8 @@
#error "LCD_PIN_RESET is now LCD_RESET_PIN. Please update your pins definitions."
#elif defined(EXTRUDER_0_AUTO_FAN_PIN) || defined(EXTRUDER_1_AUTO_FAN_PIN) || defined(EXTRUDER_2_AUTO_FAN_PIN) || defined(EXTRUDER_3_AUTO_FAN_PIN)
#error "EXTRUDER_[0123]_AUTO_FAN_PIN is now E[0123]_AUTO_FAN_PIN. Please update your Configuration_adv.h."
+#elif defined(PID_FAN_SCALING) && FAN_COUNT <= 0
+ #error "PID_FAN_SCALING needs at least one fan enabled."
#elif defined(min_software_endstops) || defined(max_software_endstops)
#error "(min|max)_software_endstops are now (MIN|MAX)_SOFTWARE_ENDSTOPS. Please update your configuration."
#elif ENABLED(Z_PROBE_SLED) && defined(SLED_PIN)
@@ -243,6 +247,8 @@
#error "NEOPIXEL_RGBW_LED is now NEOPIXEL_LED. Please update your configuration."
#elif ENABLED(DELTA) && defined(DELTA_PROBEABLE_RADIUS)
#error "Remove DELTA_PROBEABLE_RADIUS and use MIN_PROBE_EDGE to inset the probe area instead."
+#elif ENABLED(DELTA) && defined(DELTA_CALIBRATION_RADIUS)
+ #error "Remove DELTA_CALIBRATION_RADIUS and use MIN_PROBE_EDGE to inset the probe area instead."
#elif defined(UBL_MESH_INSET)
#error "UBL_MESH_INSET is now just MESH_INSET. Please update your configuration."
#elif defined(UBL_MESH_MIN_X) || defined(UBL_MESH_MIN_Y) || defined(UBL_MESH_MAX_X) || defined(UBL_MESH_MAX_Y)
@@ -310,7 +316,7 @@
#error "LEVEL_BED_CORNERS requires a LEVEL_CORNERS_INSET value. Please update your Configuration.h."
#elif defined(BEZIER_JERK_CONTROL)
#error "BEZIER_JERK_CONTROL is now S_CURVE_ACCELERATION. Please update your configuration."
-#elif defined(JUNCTION_DEVIATION_FACTOR)
+#elif DISABLED(CLASSIC_JERK) && defined(JUNCTION_DEVIATION_FACTOR)
#error "JUNCTION_DEVIATION_FACTOR is now JUNCTION_DEVIATION_MM. Please update your configuration."
#elif defined(JUNCTION_ACCELERATION_FACTOR)
#error "JUNCTION_ACCELERATION_FACTOR is obsolete. Delete it from Configuration_adv.h."
@@ -404,38 +410,22 @@
#error "(MIN|MAX)_PROBE_[XY] are now calculated at runtime. Please remove them from Configuration.h."
#elif defined(Z_STEPPER_ALIGN_X) || defined(Z_STEPPER_ALIGN_X)
#error "Z_STEPPER_ALIGN_X and Z_STEPPER_ALIGN_Y are now combined as Z_STEPPER_ALIGN_XY. Please update your Configuration_adv.h."
+#elif defined(JUNCTION_DEVIATION)
+ #error "JUNCTION_DEVIATION is no longer required. (See CLASSIC_JERK). Please remove it from Configuration.h."
+#elif defined(BABYSTEP_MULTIPLICATOR)
+ #error "BABYSTEP_MULTIPLICATOR is now BABYSTEP_MULTIPLICATOR_[XY|Z]. Please update Configuration_adv.h."
+#elif defined(LULZBOT_TOUCH_UI)
+ #error "LULZBOT_TOUCH_UI is now TOUCH_UI_FTDI_EVE. Please update your configuration."
+#elif defined(PS_DEFAULT_OFF)
+ #error "PS_DEFAULT_OFF is now PSU_DEFAULT_OFF. Please update your configuration."
+#elif defined(FILAMENT_UNLOAD_RETRACT_LENGTH)
+ #error "FILAMENT_UNLOAD_RETRACT_LENGTH is now FILAMENT_UNLOAD_PURGE_RETRACT. Please update Configuration_adv.h."
+#elif defined(FILAMENT_UNLOAD_DELAY)
+ #error "FILAMENT_UNLOAD_DELAY is now FILAMENT_UNLOAD_PURGE_DELAY. Please update Configuration_adv.h."
+#elif defined(HOME_USING_SPREADCYCLE)
+ #error "HOME_USING_SPREADCYCLE is now obsolete. Please remove it from Configuration_adv.h."
#endif
-#define BOARD_MKS_13 -1000
-#define BOARD_TRIGORILLA -1001
-#define BOARD_RURAMPS4D -1002
-#define BOARD_FORMBOT_TREX2 -1003
-#define BOARD_BIQU_SKR_V1_1 -1004
-#define BOARD_STM32F1R -1005
-#define BOARD_STM32F103R -1006
-#if MB(MKS_13)
- #error "BOARD_MKS_13 has been renamed BOARD_MKS_GEN_13. Please update your configuration."
-#elif MB(TRIGORILLA)
- #error "BOARD_TRIGORILLA has been renamed BOARD_TRIGORILLA_13. Please update your configuration."
-#elif MB(RURAMPS4D)
- #error "BOARD_RURAMPS4D has been renamed BOARD_RURAMPS4D_11. Please update your configuration."
-#elif MB(FORMBOT_TREX2)
- #error "FORMBOT_TREX2 has been renamed BOARD_FORMBOT_TREX2PLUS. Please update your configuration."
-#elif MB(BIQU_SKR_V1_1)
- #error "BOARD_BIQU_SKR_V1_1 has been renamed BOARD_BIGTREE_SKR_V1_1. Please update your configuration."
-#elif MB(STM32F1R)
- #error "BOARD_STM32F1R has been renamed BOARD_STM32F103RE. Please update your configuration."
-#elif MB(STM32F103R)
- #error "BOARD_STM32F103R has been renamed BOARD_STM32F103RE. Please update your configuration."
-#endif
-#undef BOARD_MKS_13
-#undef BOARD_TRIGORILLA
-#undef BOARD_RURAMPS4D
-#undef BOARD_FORMBOT_TREX2
-#undef BOARD_BIQU_SKR_V1_1
-#undef BOARD_STM32F1R
-#undef BOARD_STM32F103R
-
/**
* Marlin release, version and default string
*/
@@ -588,8 +578,10 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
/**
* Custom Boot and Status screens
*/
-#if EITHER(SHOW_CUSTOM_BOOTSCREEN, CUSTOM_STATUS_SCREEN_IMAGE) && !HAS_GRAPHICAL_LCD
- #error "Graphical LCD is required for SHOW_CUSTOM_BOOTSCREEN and CUSTOM_STATUS_SCREEN_IMAGE."
+#if ENABLED(SHOW_CUSTOM_BOOTSCREEN) && !(HAS_GRAPHICAL_LCD || ENABLED(TOUCH_UI_FTDI_EVE))
+ #error "SHOW_CUSTOM_BOOTSCREEN requires Graphical LCD or TOUCH_UI_FTDI_EVE."
+#elif ENABLED(CUSTOM_STATUS_SCREEN_IMAGE) && !HAS_GRAPHICAL_LCD
+ #error "CUSTOM_STATUS_SCREEN_IMAGE requires a Graphical LCD."
#endif
/**
@@ -735,10 +727,6 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#error "Marlin supports a maximum of 6 EXTRUDERS."
#endif
- #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
- #error "EXTRUDERS must be 1 with TEMP_SENSOR_1_AS_REDUNDANT."
- #endif
-
#if ENABLED(HEATERS_PARALLEL)
#error "EXTRUDERS must be 1 with HEATERS_PARALLEL."
#endif
@@ -1040,10 +1028,10 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#endif
/**
- * Junction deviation is not compatible with kinematic systems.
+ * Junction deviation is incompatible with kinematic systems.
*/
-#if ENABLED(JUNCTION_DEVIATION) && IS_KINEMATIC
- #error "Junction deviation is only compatible with Cartesians."
+#if DISABLED(CLASSIC_JERK) && IS_KINEMATIC
+ #error "CLASSIC_JERK is required for DELTA and SCARA."
#endif
/**
@@ -1056,6 +1044,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#if 1 < 0 \
+ ENABLED(PROBE_MANUALLY) \
+ ENABLED(FIX_MOUNTED_PROBE) \
+ + ENABLED(NOZZLE_AS_PROBE) \
+ (HAS_Z_SERVO_PROBE && DISABLED(BLTOUCH)) \
+ ENABLED(BLTOUCH) \
+ ENABLED(TOUCH_MI_PROBE) \
@@ -1064,7 +1053,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
+ ENABLED(Z_PROBE_SLED) \
+ ENABLED(RACK_AND_PINION_PROBE) \
+ ENABLED(SENSORLESS_PROBING)
- #error "Please enable only one probe option: PROBE_MANUALLY, SENSORLESS_PROBING, BLTOUCH, FIX_MOUNTED_PROBE, TOUCH_MI_PROBE, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or Z Servo."
+ #error "Please enable only one probe option: PROBE_MANUALLY, SENSORLESS_PROBING, BLTOUCH, FIX_MOUNTED_PROBE, NOZZLE_AS_PROBE, TOUCH_MI_PROBE, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or Z Servo."
#endif
#if HAS_BED_PROBE
@@ -1109,7 +1098,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#if ENABLED(BLTOUCH)
#if BLTOUCH_DELAY < 200
#error "BLTOUCH_DELAY less than 200 is unsafe and is not supported."
- #elif DISABLED(BLTOUCH_SET_5V_MODE) && NONE(ENDSTOPPULLUPS, ENDSTOPPULLUP_ZMIN, ENDSTOPPULLUP_ZMIN_PROBE)
+ #elif DISABLED(BLTOUCH_SET_5V_MODE) && NONE(ONBOARD_ENDSTOPPULLUPS, ENDSTOPPULLUPS, ENDSTOPPULLUP_ZMIN, ENDSTOPPULLUP_ZMIN_PROBE)
#error "BLTOUCH without BLTOUCH_SET_5V_MODE requires ENDSTOPPULLUPS, ENDSTOPPULLUP_ZMIN or ENDSTOPPULLUP_ZMIN_PROBE."
#endif
#endif
@@ -1195,11 +1184,11 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
* Require some kind of probe for bed leveling and probe testing
*/
#if HAS_ABL_NOT_UBL && !PROBE_SELECTED
- #error "Auto Bed Leveling requires one of these: PROBE_MANUALLY, FIX_MOUNTED_PROBE, BLTOUCH, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or a Z Servo."
+ #error "Auto Bed Leveling requires one of these: PROBE_MANUALLY, FIX_MOUNTED_PROBE, NOZZLE_AS_PROBE, BLTOUCH, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or a Z Servo."
#endif
#if ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST)
- #error "Z_MIN_PROBE_REPEATABILITY_TEST requires a probe: FIX_MOUNTED_PROBE, BLTOUCH, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or Z Servo."
+ #error "Z_MIN_PROBE_REPEATABILITY_TEST requires a probe: FIX_MOUNTED_PROBE, NOZZLE_AS_PROBE, BLTOUCH, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or Z Servo."
#endif
#endif
@@ -1270,7 +1259,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#endif
#if HAS_MESH
- #if DISABLED(JUNCTION_DEVIATION)
+ #if HAS_CLASSIC_JERK
static_assert(DEFAULT_ZJERK > 0.1, "Low DEFAULT_ZJERK values are incompatible with mesh-based leveling.");
#endif
#elif ENABLED(G26_MESH_VALIDATION)
@@ -1493,6 +1482,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#error "TEMP_SENSOR_1 is required with 2 or more HOTENDS."
#elif !ANY_PIN(TEMP_1, MAX6675_SS2)
#error "TEMP_1_PIN not defined for this board."
+ #elif ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
+ #error "HOTENDS must be 1 with TEMP_SENSOR_1_AS_REDUNDANT."
#endif
#if HOTENDS > 2
#if TEMP_SENSOR_2 == 0
@@ -1583,7 +1574,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
/**
* LED Backlight Timeout
*/
-#if defined(LED_BACKLIGHT_TIMEOUT) && !(EITHER(FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1) && HAS_POWER_SWITCH)
+#if defined(LED_BACKLIGHT_TIMEOUT) && !(ENABLED(PSU_CONTROL) && EITHER(FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1))
#error "LED_BACKLIGHT_TIMEOUT requires a FYSETC Mini Panel and a Power Switch."
#endif
@@ -1906,7 +1897,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
+ ENABLED(OVERLORD_OLED) \
+ ENABLED(DGUS_LCD) \
+ ENABLED(MALYAN_LCD) \
- + ENABLED(LULZBOT_TOUCH_UI) \
+ + ENABLED(TOUCH_UI_FTDI_EVE) \
+ ENABLED(FSMC_GRAPHICAL_TFT)
#error "Please select no more than one LCD controller option."
#endif
@@ -1931,7 +1922,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
/**
* Check existing CS pins against enabled TMC SPI drivers.
*/
-#define INVALID_TMC_SPI(ST) (AXIS_HAS_SPI && !PIN_EXISTS(ST##_CS))
+#define INVALID_TMC_SPI(ST) (AXIS_HAS_SPI(ST) && !PIN_EXISTS(ST##_CS))
#if INVALID_TMC_SPI(X)
#error "An SPI driven TMC driver on X requires X_CS_PIN."
#elif INVALID_TMC_SPI(X2)
@@ -2027,32 +2018,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#endif
#undef INVALID_TMC_ADDRESS
-/**
- * TMC2208/2209 software UART and ENDSTOP_INTERRUPTS both use pin change interrupts (PCI)
- */
-#if HAS_TMC220x && !defined(TARGET_LPC1768) && ENABLED(ENDSTOP_INTERRUPTS_FEATURE) && !( \
- defined(X_HARDWARE_SERIAL ) || defined(X2_HARDWARE_SERIAL) \
- || defined(Y_HARDWARE_SERIAL ) || defined(Y2_HARDWARE_SERIAL) \
- || defined(Z_HARDWARE_SERIAL ) || defined(Z2_HARDWARE_SERIAL) \
- || defined(Z3_HARDWARE_SERIAL) || defined(E0_HARDWARE_SERIAL) \
- || defined(E1_HARDWARE_SERIAL) || defined(E2_HARDWARE_SERIAL) \
- || defined(E3_HARDWARE_SERIAL) || defined(E4_HARDWARE_SERIAL) \
- || defined(E5_HARDWARE_SERIAL) )
- #error "Select hardware UART for TMC2208 to use both TMC2208 and ENDSTOP_INTERRUPTS_FEATURE."
-#endif
-
-/**
- * TMC2208/2209 software UART is only supported on AVR, LPC, STM32F1 and STM32F4
- */
-#if HAS_TMC220x && !defined(__AVR__) && !defined(TARGET_LPC1768) && !defined(TARGET_STM32F1) && !defined(TARGET_STM32F4) && !( \
- defined(X_HARDWARE_SERIAL ) || defined(X2_HARDWARE_SERIAL) \
- || defined(Y_HARDWARE_SERIAL ) || defined(Y2_HARDWARE_SERIAL) \
- || defined(Z_HARDWARE_SERIAL ) || defined(Z2_HARDWARE_SERIAL) \
- || defined(Z3_HARDWARE_SERIAL) || defined(E0_HARDWARE_SERIAL) \
- || defined(E1_HARDWARE_SERIAL) || defined(E2_HARDWARE_SERIAL) \
- || defined(E3_HARDWARE_SERIAL) || defined(E4_HARDWARE_SERIAL) \
- || defined(E5_HARDWARE_SERIAL) )
- #error "TMC2208 Software Serial is supported only on AVR, LPC1768, STM32F1 and STM32F4 platforms."
+#if ENABLED(DELTA) && (ENABLED(STEALTHCHOP_XY) != ENABLED(STEALTHCHOP_Z))
+ #error "STEALTHCHOP_XY and STEALTHCHOP_Z must be the same on DELTA."
#endif
#if ENABLED(SENSORLESS_HOMING)
@@ -2069,17 +2036,17 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#if ENABLED(DELTA) && !BOTH(STEALTHCHOP_XY, STEALTHCHOP_Z)
#error "SENSORLESS_HOMING on DELTA currently requires STEALTHCHOP_XY and STEALTHCHOP_Z."
- #elif X_SENSORLESS && X_HOME_DIR < 0 && DISABLED(ENDSTOPPULLUPS, ENDSTOPPULLUP_XMIN)
+ #elif X_SENSORLESS && X_HOME_DIR < 0 && NONE(ONBOARD_ENDSTOPPULLUPS, ENDSTOPPULLUPS, ENDSTOPPULLUP_XMIN)
#error "SENSORLESS_HOMING requires ENDSTOPPULLUP_XMIN (or ENDSTOPPULLUPS) when homing to X_MIN."
- #elif X_SENSORLESS && X_HOME_DIR > 0 && DISABLED(ENDSTOPPULLUPS, ENDSTOPPULLUP_XMAX)
+ #elif X_SENSORLESS && X_HOME_DIR > 0 && NONE(ONBOARD_ENDSTOPPULLUPS, ENDSTOPPULLUPS, ENDSTOPPULLUP_XMAX)
#error "SENSORLESS_HOMING requires ENDSTOPPULLUP_XMAX (or ENDSTOPPULLUPS) when homing to X_MAX."
- #elif Y_SENSORLESS && Y_HOME_DIR < 0 && DISABLED(ENDSTOPPULLUPS, ENDSTOPPULLUP_YMIN)
+ #elif Y_SENSORLESS && Y_HOME_DIR < 0 && NONE(ONBOARD_ENDSTOPPULLUPS, ENDSTOPPULLUPS, ENDSTOPPULLUP_YMIN)
#error "SENSORLESS_HOMING requires ENDSTOPPULLUP_YMIN (or ENDSTOPPULLUPS) when homing to Y_MIN."
- #elif Y_SENSORLESS && Y_HOME_DIR > 0 && DISABLED(ENDSTOPPULLUPS, ENDSTOPPULLUP_YMAX)
+ #elif Y_SENSORLESS && Y_HOME_DIR > 0 && NONE(ONBOARD_ENDSTOPPULLUPS, ENDSTOPPULLUPS, ENDSTOPPULLUP_YMAX)
#error "SENSORLESS_HOMING requires ENDSTOPPULLUP_YMAX (or ENDSTOPPULLUPS) when homing to Y_MAX."
- #elif Z_SENSORLESS && Z_HOME_DIR < 0 && DISABLED(ENDSTOPPULLUPS, ENDSTOPPULLUP_ZMIN)
+ #elif Z_SENSORLESS && Z_HOME_DIR < 0 && NONE(ONBOARD_ENDSTOPPULLUPS, ENDSTOPPULLUPS, ENDSTOPPULLUP_ZMIN)
#error "SENSORLESS_HOMING requires ENDSTOPPULLUP_ZMIN (or ENDSTOPPULLUPS) when homing to Z_MIN."
- #elif Z_SENSORLESS && Z_HOME_DIR > 0 && DISABLED(ENDSTOPPULLUPS, ENDSTOPPULLUP_ZMAX)
+ #elif Z_SENSORLESS && Z_HOME_DIR > 0 && NONE(ONBOARD_ENDSTOPPULLUPS, ENDSTOPPULLUPS, ENDSTOPPULLUP_ZMAX)
#error "SENSORLESS_HOMING requires ENDSTOPPULLUP_ZMAX (or ENDSTOPPULLUPS) when homing to Z_MAX."
#elif X_SENSORLESS && X_HOME_DIR < 0 && X_MIN_ENDSTOP_INVERTING != X_ENDSTOP_INVERTING
#if X_ENDSTOP_INVERTING
@@ -2210,10 +2177,6 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#endif
#undef IN_CHAIN
-#if ENABLED(DELTA) && (ENABLED(STEALTHCHOP_XY) != ENABLED(STEALTHCHOP_Z))
- #error "STEALTHCHOP_XY and STEALTHCHOP_Z must be the same on DELTA."
-#endif
-
/**
* Digipot requirement
*/
@@ -2322,8 +2285,8 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
#endif
#endif
-#if ENABLED(POWER_LOSS_RECOVERY) && DISABLED(ULTIPANEL)
- #error "POWER_LOSS_RECOVERY currently requires an LCD Controller."
+#if ENABLED(BACKUP_POWER_SUPPLY) && !PIN_EXISTS(POWER_LOSS)
+ #error "BACKUP_POWER_SUPPLY requires a POWER_LOSS_PIN."
#endif
#if ENABLED(Z_STEPPER_AUTO_ALIGN)
@@ -2331,6 +2294,8 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
#error "Z_STEPPER_AUTO_ALIGN requires Z_DUAL_STEPPER_DRIVERS or Z_TRIPLE_STEPPER_DRIVERS."
#elif !HAS_BED_PROBE
#error "Z_STEPPER_AUTO_ALIGN requires a Z-bed probe."
+ #elif ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) && DISABLED(Z_TRIPLE_STEPPER_DRIVERS)
+ #error "Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS requires Z_TRIPLE_STEPPER_DRIVERS."
#endif
#endif
@@ -2446,8 +2411,14 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
/**
* Ensure this option is set intentionally
*/
-#if ENABLED(PSU_CONTROL) && !defined(PSU_ACTIVE_HIGH)
- #error "PSU_CONTROL requires PSU_ACTIVE_HIGH to be defined as 'true' or 'false'."
+#if ENABLED(PSU_CONTROL)
+ #ifndef PSU_ACTIVE_HIGH
+ #error "PSU_CONTROL requires PSU_ACTIVE_HIGH to be defined as 'true' or 'false'."
+ #elif !PIN_EXISTS(PS_ON)
+ #error "PSU_CONTROL requires PS_ON_PIN."
+ #endif
+#elif ENABLED(AUTO_POWER_CONTROL)
+ #error "AUTO_POWER_CONTROL requires PSU_CONTROL."
#endif
#if HAS_CUTTER
@@ -2509,3 +2480,11 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
#endif
#undef _PIN_CONFLICT
#endif
+
+#if !HAS_GRAPHICAL_LCD
+ #if ENABLED(PRINT_PROGRESS_SHOW_DECIMALS)
+ #error "PRINT_PROGRESS_SHOW_DECIMALS currently requires a Graphical LCD."
+ #elif ENABLED(SHOW_REMAINING_TIME)
+ #error "SHOW_REMAINING_TIME currently requires a Graphical LCD."
+ #endif
+#endif
diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h
index aea4727792..a82a8cdae8 100644
--- a/Marlin/src/inc/Version.h
+++ b/Marlin/src/inc/Version.h
@@ -21,77 +21,102 @@
*/
#pragma once
-#include "../core/macros.h" // for ENABLED
+/**
+ * Release version. Leave the Marlin version or apply a custom scheme.
+ */
+#ifndef SHORT_BUILD_VERSION
+ #define SHORT_BUILD_VERSION "bugfix-2.0.x"
+#endif
/**
- * This file is the standard Marlin version identifier file.
- * Use -DUSE_AUTOMATIC_VERSIONING=1 and a custom _Version.h
- * to override these values.
+ * Verbose version identifier containing a unique identifier, such as the
+ * vendor name, download location, GitHub account, etc.
+ */
+#ifndef DETAILED_BUILD_VERSION
+ #define DETAILED_BUILD_VERSION SHORT_BUILD_VERSION " (GitHub)"
+#endif
+
+/**
+ * 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.
+ */
+#ifndef STRING_DISTRIBUTION_DATE
+ #define STRING_DISTRIBUTION_DATE "2019-12-19"
+#endif
+
+/**
+ * Minimum Configuration.h and Configuration_adv.h file versions.
+ * Set based on the release version number. Used to catch an attempt to use
+ * older configurations. Override these if using a custom versioning scheme
+ * to alert users to major changes.
*/
-#if ENABLED(USE_AUTOMATIC_VERSIONING)
+#define MARLIN_HEX_VERSION 020000
+#ifndef REQUIRED_CONFIGURATION_H_VERSION
+ #define REQUIRED_CONFIGURATION_H_VERSION MARLIN_HEX_VERSION
+#endif
+#ifndef REQUIRED_CONFIGURATION_ADV_H_VERSION
+ #define REQUIRED_CONFIGURATION_ADV_H_VERSION MARLIN_HEX_VERSION
+#endif
- #include "_Version.h"
-
-#else
-
- /**
- * Marlin release version identifier
- */
- #define SHORT_BUILD_VERSION "bugfix-2.0.x"
-
- /**
- * 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 " (Github)"
-
- /**
- * 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-05"
-
- /**
- * Required minimum Configuration.h and Configuration_adv.h file versions.
- *
- * You must increment this version number for every significant change such as,
- * but not limited to: ADD, DELETE RENAME OR REPURPOSE any directive/option on
- * the configuration files.
- */
- #define REQUIRED_CONFIGURATION_H_VERSION 020000
- #define REQUIRED_CONFIGURATION_ADV_H_VERSION 020000
-
- /**
- * The protocol for communication to the host. Protocol indicates communication
- * standards such as the use of ASCII, "echo:" and "error:" line prefixes, etc.
- * (Other behaviors are given by the firmware version and capabilities report.)
- */
+/**
+ * The protocol for communication to the host. Protocol indicates communication
+ * standards such as the use of ASCII, "echo:" and "error:" line prefixes, etc.
+ * (Other behaviors are given by the firmware version and capabilities report.)
+ */
+#ifndef PROTOCOL_VERSION
#define PROTOCOL_VERSION "1.0"
+#endif
- /**
- * Defines a generic printer name to be output to the LCD after booting Marlin.
- */
+/**
+ * Define a generic printer name to be output to the LCD after booting Marlin.
+ */
+#ifndef MACHINE_NAME
#define MACHINE_NAME "3D Printer"
+#endif
- /**
- * 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.
- */
+/**
+ * Website where users can find Marlin source code for the binary installed on the
+ * device. Override this if you provide public source code download. (GPLv3 requires
+ * providing the source code to your customers.)
+ */
+#ifndef SOURCE_CODE_URL
#define SOURCE_CODE_URL "https://github.com/MarlinFirmware/Marlin"
+#endif
- /**
- * Default generic printer UUID.
- */
+/**
+ * Default generic printer UUID.
+ */
+#ifndef DEFAULT_MACHINE_UUID
#define DEFAULT_MACHINE_UUID "cede2a2f-41a2-4748-9b12-c55c62f367ff"
+#endif
/**
* The WEBSITE_URL is the location where users can get more information such as
* documentation about a specific Marlin release. Displayed in the Info Menu.
*/
+#ifndef WEBSITE_URL
#define WEBSITE_URL "http://marlinfw.org"
+#endif
-#endif // USE_AUTOMATIC_VERSIONING
+/**
+ * Set the vendor info the serial USB interface, if changable
+ * Currently only supported by DUE platform
+ */
+#ifndef USB_DEVICE_VENDOR_ID
+ #define USB_DEVICE_VENDOR_ID 0x03EB /* ATMEL VID */
+#endif
+#ifndef USB_DEVICE_PRODUCT_ID
+ #define USB_DEVICE_PRODUCT_ID 0x2424 /* MSC / CDC */
+#endif
+//! USB Device string definitions (Optional)
+#ifndef USB_DEVICE_MANUFACTURE_NAME
+ #define USB_DEVICE_MANUFACTURE_NAME WEBSITE_URL
+#endif
+#ifdef CUSTOM_MACHINE_NAME
+ #define USB_DEVICE_PRODUCT_NAME CUSTOM_MACHINE_NAME
+#else
+ #define USB_DEVICE_PRODUCT_NAME MACHINE_NAME
+#endif
+#define USB_DEVICE_SERIAL_NAME "123985739853"
diff --git a/Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp b/Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp
index af1fa56460..2c8c029e73 100644
--- a/Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp
+++ b/Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp
@@ -17,7 +17,7 @@
#if HAS_CHARACTER_LCD
#include "../ultralcd.h"
-#include "../../Marlin.h"
+#include "../../MarlinCore.h"
#include "ultralcd_HD44780.h"
diff --git a/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp b/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp
index 819a5c5bc6..d6ce8bfdd6 100644
--- a/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp
+++ b/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp
@@ -111,6 +111,12 @@ static void createChar_P(const char c, const byte * const ptr) {
#define LCD_STR_PROGRESS "\x03\x04\x05"
#endif
+#if ENABLED(LCD_USE_I2C_BUZZER)
+ void MarlinUI::buzz(const long duration, const uint16_t freq) {
+ lcd.buzz(duration, freq);
+ }
+#endif
+
void MarlinUI::set_custom_characters(const HD44780CharSet screen_charset/*=CHARSET_INFO*/) {
#if NONE(LCD_PROGRESS_BAR, SHOW_BOOTSCREEN)
UNUSED(screen_charset);
@@ -464,7 +470,8 @@ void MarlinUI::clear_lcd() { lcd.clear(); }
// Show the Marlin logo and short build version
// After a delay show the website URL
//
- logo_lines(PSTR(""));
+ extern const char NUL_STR[];
+ logo_lines(NUL_STR);
CENTER_OR_SCROLL(SHORT_BUILD_VERSION, 1500);
CENTER_OR_SCROLL(MARLIN_WEBSITE_URL, 1500);
#ifdef STRING_SPLASH_LINE3
@@ -484,9 +491,9 @@ void MarlinUI::draw_kill_screen() {
lcd_put_u8str(0, 0, status_message);
lcd_uint_t y = 2;
#if LCD_HEIGHT >= 4
- lcd_put_u8str_P(0, y++, PSTR(MSG_HALTED));
+ lcd_put_u8str_P(0, y++, GET_TEXT(MSG_HALTED));
#endif
- lcd_put_u8str_P(0, y, PSTR(MSG_PLEASE_RESET));
+ lcd_put_u8str_P(0, y, GET_TEXT(MSG_PLEASE_RESET));
}
//
@@ -566,7 +573,7 @@ FORCE_INLINE void _draw_bed_status(const bool blink) {
#if HAS_PRINT_PROGRESS
FORCE_INLINE void _draw_print_progress() {
- const uint8_t progress = ui.get_progress();
+ const uint8_t progress = ui.get_progress_percent();
lcd_put_u8str_P(PSTR(
#if ENABLED(SDSUPPORT)
"SD"
@@ -613,7 +620,7 @@ void MarlinUI::draw_status_message(const bool blink) {
// Draw the progress bar if the message has shown long enough
// or if there is no message set.
if (ELAPSED(millis(), progress_bar_ms + PROGRESS_BAR_MSG_TIME) || !has_status()) {
- const uint8_t progress = get_progress();
+ const uint8_t progress = get_progress_percent();
if (progress > 2) return draw_progress_bar(progress);
}
@@ -815,14 +822,28 @@ void MarlinUI::draw_status_screen() {
sprintf_P(mixer_messages, PSTR("%s %d;%d%% "), mix_label, int(mixer.mix[0]), int(mixer.mix[1]));
lcd_put_u8str(mixer_messages);
- #else
+ #else // !DUAL_MIXING_EXTRUDER
- xy_pos_t lpos = current_position; toLogical(lpos);
- _draw_axis_value(X_AXIS, ftostr4sign(lpos.x), blink);
- lcd_put_wchar(' ');
- _draw_axis_value(Y_AXIS, ftostr4sign(lpos.y), blink);
+ if (true
+ #if ENABLED(LCD_SHOW_E_TOTAL)
+ && !printingIsActive()
+ #endif
+ ) {
+ xy_pos_t lpos = current_position; toLogical(lpos);
+ _draw_axis_value(X_AXIS, ftostr4sign(lpos.x), blink);
+ lcd_put_wchar(' ');
+ _draw_axis_value(Y_AXIS, ftostr4sign(lpos.y), blink);
+ }
+ else {
+ #if ENABLED(LCD_SHOW_E_TOTAL)
+ char tmp[20];
+ const uint8_t escale = e_move_accumulator >= 100000.0f ? 10 : 1; // After 100m switch to cm
+ sprintf_P(tmp, PSTR("E %ld%cm "), uint32_t(_MAX(e_move_accumulator, 0.0f)) / escale, escale == 10 ? 'c' : 'm'); // 1234567mm
+ lcd_put_u8str(tmp);
+ #endif
+ }
- #endif
+ #endif // !DUAL_MIXING_EXTRUDER
#endif // HOTENDS <= 2 && (HOTENDS <= 1 || !HAS_HEATED_BED)
@@ -861,7 +882,7 @@ void MarlinUI::draw_status_screen() {
uint16_t per;
#if HAS_FAN0
if (true
- #if EXTRUDERS
+ #if EXTRUDERS && ENABLED(ADAPTIVE_FAN_SLOWING)
&& (blink || thermalManager.fan_speed_scaler[0] < 128)
#endif
) {
@@ -977,49 +998,55 @@ void MarlinUI::draw_status_screen() {
#endif // ADVANCED_PAUSE_FEATURE
- void draw_menu_item_static(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_CENTER*/, const char * const valstr/*=nullptr*/) {
+ // Draw a static item with no left-right margin required. Centered by default.
+ void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const valstr/*=nullptr*/) {
int8_t n = LCD_WIDTH;
lcd_moveto(0, row);
if ((style & SS_CENTER) && !valstr) {
int8_t pad = (LCD_WIDTH - utf8_strlen_P(pstr)) / 2;
while (--pad >= 0) { lcd_put_wchar(' '); n--; }
}
- n -= lcd_put_u8str_max_P(pstr, n);
+ n = lcd_put_u8str_ind_P(pstr, itemIndex, n);
if (valstr) n -= lcd_put_u8str_max(valstr, n);
for (; n > 0; --n) lcd_put_wchar(' ');
}
- void draw_menu_item(const bool sel, const uint8_t row, PGM_P pstr, const char pre_char, const char post_char) {
- uint8_t n = LCD_WIDTH - 2;
+ // Draw a generic menu item with pre_char (if selected) and post_char
+ void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, const char pre_char, const char post_char) {
lcd_put_wchar(0, row, sel ? pre_char : ' ');
- n -= lcd_put_u8str_max_P(pstr, n);
+ uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, LCD_WIDTH - 2);
for (; n; --n) lcd_put_wchar(' ');
lcd_put_wchar(post_char);
}
- void _draw_menu_item_edit(const bool sel, const uint8_t row, PGM_P pstr, const char* const data, const bool pgm) {
- uint8_t n = LCD_WIDTH - 2 - (pgm ? utf8_strlen_P(data) : utf8_strlen(data));
+ // Draw a menu item with a (potentially) editable value
+ void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char* const data, const bool pgm) {
+ const uint8_t vlen = data ? (pgm ? utf8_strlen_P(data) : utf8_strlen(data)) : 0;
lcd_put_wchar(0, row, sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
- n -= lcd_put_u8str_max_P(pstr, n);
- lcd_put_wchar(':');
- for (; n; --n) lcd_put_wchar(' ');
- if (pgm) lcd_put_u8str_P(data); else lcd_put_u8str(data);
+ uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, LCD_WIDTH - 2 - vlen);
+ if (vlen) {
+ lcd_put_wchar(':');
+ for (; n; --n) lcd_put_wchar(' ');
+ if (pgm) lcd_put_u8str_P(data); else lcd_put_u8str(data);
+ }
}
- void draw_edit_screen(PGM_P const pstr, const char* const value/*=nullptr*/) {
+ // Low-level draw_edit_screen can be used to draw an edit screen from anyplace
+ void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char* const value/*=nullptr*/) {
ui.encoder_direction_normal();
- lcd_put_u8str_P(0, 1, pstr);
+ uint8_t n = lcd_put_u8str_ind_P(0, 1, pstr, itemIndex, LCD_WIDTH - 1);
if (value != nullptr) {
lcd_put_wchar(':');
int len = utf8_strlen(value);
- const lcd_uint_t valrow = (utf8_strlen_P(pstr) + 1 + len + 1) > (LCD_WIDTH - 2) ? 2 : 1; // Value on the next row if it won't fit
- lcd_put_wchar((LCD_WIDTH - 1) - (len + 1), valrow, ' '); // Right-justified, padded, add a leading space
+ const lcd_uint_t valrow = (n < len + 1) ? 2 : 1; // Value on the next row if it won't fit
+ lcd_put_wchar((LCD_WIDTH - 1) - (len + 1), valrow, ' '); // Right-justified, padded, leading space
lcd_put_u8str(value);
}
}
- void draw_select_screen(PGM_P const yes, PGM_P const no, const bool yesno, PGM_P const pref, const char * const string, PGM_P const suff) {
+ // The Select Screen presents a prompt and two "buttons"
+ void MenuItem_confirm::draw_select_screen(PGM_P const yes, PGM_P const no, const bool yesno, PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/) {
ui.draw_select_screen_prompt(pref, string, suff);
SETCURSOR(0, LCD_HEIGHT - 1);
lcd_put_wchar(yesno ? ' ' : '['); lcd_put_u8str_P(no); lcd_put_wchar(yesno ? ' ' : ']');
@@ -1029,9 +1056,7 @@ void MarlinUI::draw_status_screen() {
#if ENABLED(SDSUPPORT)
- void draw_sd_menu_item(const bool sel, const uint8_t row, PGM_P const pstr, CardReader &theCard, const bool isDir) {
- UNUSED(pstr);
-
+ void MenuItem_sdbase::draw(const bool sel, const uint8_t row, PGM_P const, CardReader &theCard, const bool isDir) {
lcd_put_wchar(0, row, sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
constexpr uint8_t maxlen = LCD_WIDTH - 2;
uint8_t n = maxlen - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), maxlen);
@@ -1039,7 +1064,7 @@ void MarlinUI::draw_status_screen() {
lcd_put_wchar(isDir ? LCD_STR_FOLDER[0] : ' ');
}
- #endif // SDSUPPORT
+ #endif
#if ENABLED(LCD_HAS_STATUS_INDICATORS)
@@ -1048,9 +1073,13 @@ void MarlinUI::draw_status_screen() {
static uint8_t ledsprev = 0;
uint8_t leds = 0;
- if (thermalManager.degTargetBed() > 0) leds |= LED_A;
+ #if HAS_HEATED_BED
+ if (thermalManager.degTargetBed() > 0) leds |= LED_A;
+ #endif
- if (thermalManager.degTargetHotend(0) > 0) leds |= LED_B;
+ #if HOTENDS
+ if (thermalManager.degTargetHotend(0) > 0) leds |= LED_B;
+ #endif
#if FAN_COUNT > 0
if (0
diff --git a/Marlin/src/lcd/dogm/dogm_Statusscreen.h b/Marlin/src/lcd/dogm/dogm_Statusscreen.h
index d0de7da976..fbc7a8128a 100644
--- a/Marlin/src/lcd/dogm/dogm_Statusscreen.h
+++ b/Marlin/src/lcd/dogm/dogm_Statusscreen.h
@@ -598,6 +598,105 @@
#endif // !STATUS_HEATERS_WIDTH && !STATUS_HOTEND1_WIDTH
+// LASER / SPINDLE
+#if !STATUS_CUTTER_WIDTH && HAS_CUTTER
+ #define STATUS_CUTTER_WIDTH 24
+ #define STATUS_CUTTER_X 80
+ #if ENABLED(LASER_FEATURE)
+ #ifdef STATUS_CUTTER_ANIM
+ const unsigned char status_cutter_on_bmp[] PROGMEM = {
+ B00000000,B00100100,B00000000,
+ B00000000,B01100110,B00000000,
+ B00000000,B11000011,B00000000,
+ B00000001,B10011001,B10000000,
+ B00000011,B00100100,B11000000,
+ B00000000,B01000010,B00000000,
+ B00000000,B01000010,B00000000,
+ B00000011,B00100100,B11000000,
+ B00000001,B10011001,B10000000,
+ B00000000,B11000011,B00000000,
+ B00000000,B01100110,B00000000,
+ B00000000,B00100100,B00000000
+ };
+ const unsigned char status_cutter_bmp[] PROGMEM = {
+ B00000000,B00100100,B00000000,
+ B00000000,B01100110,B00000000,
+ B00000000,B00000000,B00000000,
+ B00000001,B00000000,B10000000,
+ B00000011,B00000000,B11000000,
+ B00000000,B00011000,B00000000,
+ B00000000,B00011000,B00000000,
+ B00000011,B00000000,B11000000,
+ B00000001,B00000000,B10000000,
+ B00000000,B00000000,B00000000,
+ B00000000,B01100110,B00000000,
+ B00000000,B00100100,B00000000
+ };
+ #else
+ const unsigned char status_cutter_bmp[] PROGMEM = {
+ B00000000,B00100100,B00000000,
+ B00000000,B01100110,B00000000,
+ B00000000,B11000011,B00000000,
+ B00000001,B10000001,B10000000,
+ B00000011,B00000000,B11000000,
+ B00000000,B00000000,B00000000,
+ B00000000,B00000000,B00000000,
+ B00000011,B00000000,B11000000,
+ B00000001,B10000001,B10000000,
+ B00000000,B11000011,B00000000,
+ B00000000,B01100110,B00000000,
+ B00000000,B00100100,B00000000
+ };
+ #endif
+ #else
+ #ifdef STATUS_CUTTER_ANIM
+ const unsigned char status_cutter_on_bmp[] PROGMEM = {
+ B00000001,B11111110,B10000000,
+ B00000000,B11000000,B00000000,
+ B00000001,B10000000,B10000000,
+ B00000001,B00000000,B10000000,
+ B00000001,B11111100,B10000000,
+ B00000000,B11100000,B00000000,
+ B00000001,B11000000,B10000000,
+ B00000000,B10000001,B00000000,
+ B00000000,B01111010,B00000000,
+ B00000000,B00110100,B00000000,
+ B00000000,B00011000,B00000000,
+ B00000000,B00000000,B00000000
+ };
+ const unsigned char status_cutter_bmp[] PROGMEM = {
+ B00000001,B11111110,B10000000,
+ B00000000,B11000000,B00000000,
+ B00000001,B10000000,B10000000,
+ B00000001,B00000000,B10000000,
+ B00000001,B11111100,B10000000,
+ B00000000,B11100000,B00000000,
+ B00000001,B11000000,B10000000,
+ B00000000,B10000001,B00000000,
+ B00000000,B01111010,B00000000,
+ B00000000,B00110100,B00000000,
+ B00000000,B00011000,B00000000,
+ B00000000,B00000000,B00000000
+ };
+ #else
+ const unsigned char status_cutter_bmp[] PROGMEM = {
+ B00000001,B11000010,B10000000,
+ B00000001,B00011100,B10000000,
+ B00000000,B11100001,B00000000,
+ B00000001,B00001110,B10000000,
+ B00000001,B01110000,B10000000,
+ B00000000,B10000111,B10000000,
+ B00000001,B00111111,B10000000,
+ B00000000,B11111111,B00000000,
+ B00000000,B01111110,B00000000,
+ B00000000,B00111100,B00000000,
+ B00000000,B00011000,B00000000,
+ B00000000,B00000000,B00000000
+ };
+ #endif
+ #endif
+#endif // LASER / SPINDLE
+
//
// Default Status Screen Bed bitmaps
//
@@ -1269,7 +1368,7 @@
#define STATUS_LOGO_X 0
#endif
#ifndef STATUS_LOGO_Y
- #define STATUS_LOGO_Y _MIN(0, 10 - (STATUS_LOGO_HEIGHT) / 2)
+ #define STATUS_LOGO_Y _MIN(0U, (10 - (STATUS_LOGO_HEIGHT) / 2))
#endif
#ifndef STATUS_LOGO_HEIGHT
#define STATUS_LOGO_HEIGHT (sizeof(status_logo_bmp) / (STATUS_LOGO_BYTEWIDTH))
@@ -1462,7 +1561,53 @@
#else // HOTENDS == 0
- //#error "Incomplete status header"
+ #define STATUS_HOTEND_TEXT_X(N) 0
+ #define STATUS_HEATERS_Y 0
+
+#endif
+
+//
+// Cutter Bitmap Properties
+//
+#ifndef STATUS_CUTTER_BYTEWIDTH
+ #define STATUS_CUTTER_BYTEWIDTH BW(STATUS_CUTTER_WIDTH)
+#endif
+#if STATUS_CUTTER_WIDTH
+
+ #ifndef STATUS_CUTTER_X
+ #define STATUS_CUTTER_X (LCD_PIXEL_WIDTH - (STATUS_CUTTER_BYTEWIDTH + STATUS_CUTTER_BYTEWIDTH) * 8)
+ #endif
+
+ #ifndef STATUS_CUTTER_HEIGHT
+ #ifdef STATUS_CUTTER_ANIM
+ #define STATUS_CUTTER_HEIGHT(S) ((S) ? sizeof(status_cutter_on_bmp) / (STATUS_CUTTER_BYTEWIDTH) : sizeof(status_cutter_bmp) / (STATUS_CUTTER_BYTEWIDTH))
+ #else
+ #define STATUS_CUTTER_HEIGHT(S) (sizeof(status_cutter_bmp) / (STATUS_CUTTER_BYTEWIDTH))
+ #endif
+ #endif
+
+ #ifndef STATUS_CUTTER_Y
+ #define STATUS_CUTTER_Y(S) 4
+ #endif
+
+ #ifndef STATUS_CUTTER_TEXT_X
+ #define STATUS_CUTTER_TEXT_X (STATUS_CUTTER_X -1)
+ #endif
+
+ #ifndef STATUS_CUTTER_TEXT_Y
+ #define STATUS_CUTTER_TEXT_Y 28
+ #endif
+
+ static_assert(
+ sizeof(status_cutter_bmp) == (STATUS_CUTTER_BYTEWIDTH) * (STATUS_CUTTER_HEIGHT(0)),
+ "Status cutter bitmap (status_cutter_bmp) dimensions don't match data."
+ );
+ #ifdef STATUS_CUTTER_ANIM
+ static_assert(
+ sizeof(status_cutter_on_bmp) == (STATUS_CUTTER_BYTEWIDTH) * (STATUS_CUTTER_HEIGHT(1)),
+ "Status cutter bitmap (status_cutter_on_bmp) dimensions don't match data."
+ );
+ #endif
#endif
@@ -1581,3 +1726,17 @@
#endif
#endif
#endif
+
+#define DO_DRAW_LOGO (STATUS_LOGO_WIDTH && ENABLED(CUSTOM_STATUS_SCREEN_IMAGE))
+#define DO_DRAW_HOTENDS (HOTENDS > 0)
+#define DO_DRAW_CUTTER (HAS_CUTTER)
+#define DO_DRAW_BED (HAS_HEATED_BED && STATUS_BED_WIDTH && HOTENDS <= 4)
+#define DO_DRAW_CHAMBER (HAS_TEMP_CHAMBER && STATUS_CHAMBER_WIDTH && HOTENDS <= 4)
+#define DO_DRAW_FAN (HAS_FAN0 && STATUS_FAN_WIDTH && HOTENDS <= 4 && defined(STATUS_FAN_FRAMES))
+
+#define ANIM_HOTEND (HOTENDS && ENABLED(STATUS_HOTEND_ANIM))
+#define ANIM_BED (DO_DRAW_BED && ENABLED(STATUS_BED_ANIM))
+#define ANIM_CHAMBER (DO_DRAW_CHAMBER && ENABLED(STATUS_CHAMBER_ANIM))
+#define ANIM_CUTTER (DO_DRAW_CUTTER && ENABLED(STATUS_CUTTER_ANIM))
+
+#define ANIM_HBCC (ANIM_HOTEND || ANIM_BED || ANIM_CHAMBER || ANIM_CUTTER)
diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_el-gr.h b/Marlin/src/lcd/dogm/fontdata/langdata_el_gr.h
similarity index 100%
rename from Marlin/src/lcd/dogm/fontdata/langdata_el-gr.h
rename to Marlin/src/lcd/dogm/fontdata/langdata_el_gr.h
diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_jp-kana.h b/Marlin/src/lcd/dogm/fontdata/langdata_jp_kana.h
similarity index 100%
rename from Marlin/src/lcd/dogm/fontdata/langdata_jp-kana.h
rename to Marlin/src/lcd/dogm/fontdata/langdata_jp_kana.h
diff --git a/Marlin/src/lcd/dogm/fontdata/langdata_pt-br.h b/Marlin/src/lcd/dogm/fontdata/langdata_pt_br.h
similarity index 100%
rename from Marlin/src/lcd/dogm/fontdata/langdata_pt-br.h
rename to Marlin/src/lcd/dogm/fontdata/langdata_pt_br.h
diff --git a/Marlin/src/lcd/dogm/lcdprint_u8g.cpp b/Marlin/src/lcd/dogm/lcdprint_u8g.cpp
index 0ad5e998ab..c9a55a16e3 100644
--- a/Marlin/src/lcd/dogm/lcdprint_u8g.cpp
+++ b/Marlin/src/lcd/dogm/lcdprint_u8g.cpp
@@ -14,7 +14,7 @@
#include "ultralcd_DOGM.h"
#include "../ultralcd.h"
-#include "../../Marlin.h"
+#include "../../MarlinCore.h"
#include "../fontutils.h"
#include "u8g_fontutf8.h"
diff --git a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp
index 34d0140086..bf2804d3a8 100644
--- a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp
+++ b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp
@@ -44,6 +44,10 @@
#include "../../gcode/parser.h"
#endif
+#if HAS_CUTTER
+ #include "../../feature/spindle_laser.h"
+#endif
+
#if ENABLED(SDSUPPORT)
#include "../../sd/cardreader.h"
#endif
@@ -63,48 +67,45 @@
#define EXTRAS_BASELINE (40 + INFO_FONT_ASCENT)
#define STATUS_BASELINE (LCD_PIXEL_HEIGHT - INFO_FONT_DESCENT)
-#define DO_DRAW_LOGO (STATUS_LOGO_WIDTH && ENABLED(CUSTOM_STATUS_SCREEN_IMAGE))
-#define DO_DRAW_BED (HAS_HEATED_BED && STATUS_BED_WIDTH && HOTENDS <= 4)
-#define DO_DRAW_CHAMBER (HAS_TEMP_CHAMBER && STATUS_CHAMBER_WIDTH && HOTENDS <= 4)
-#define DO_DRAW_FAN (HAS_FAN0 && STATUS_FAN_WIDTH && HOTENDS <= 4 && defined(STATUS_FAN_FRAMES))
-
-#define ANIM_HOTEND (HOTENDS && ENABLED(STATUS_HOTEND_ANIM))
-#define ANIM_BED (DO_DRAW_BED && ENABLED(STATUS_BED_ANIM))
-#define ANIM_CHAMBER (DO_DRAW_CHAMBER && ENABLED(STATUS_CHAMBER_ANIM))
-
-#define ANIM_HBC (ANIM_HOTEND || ANIM_BED || ANIM_CHAMBER)
-
-#if ANIM_HBC
- uint8_t heat_bits;
+#if ANIM_HBCC
+ enum HeatBits : uint8_t {
+ HEATBIT_HOTEND,
+ HEATBIT_BED = HOTENDS,
+ HEATBIT_CHAMBER,
+ HEATBIT_CUTTER
+ };
+ IF<(HEATBIT_CUTTER > 7), uint16_t, uint8_t>::type heat_bits;
#endif
+
#if ANIM_HOTEND
- #define HOTEND_ALT(N) TEST(heat_bits, N)
+ #define HOTEND_ALT(N) TEST(heat_bits, HEATBIT_HOTEND + N)
#else
#define HOTEND_ALT(N) false
#endif
#if ANIM_BED
- #define BED_ALT() TEST(heat_bits, 7)
+ #define BED_ALT() TEST(heat_bits, HEATBIT_BED)
#else
#define BED_ALT() false
#endif
#if ANIM_CHAMBER
- #define CHAMBER_ALT() TEST(heat_bits, 6)
+ #define CHAMBER_ALT() TEST(heat_bits, HEATBIT_CHAMBER)
#else
#define CHAMBER_ALT() false
#endif
-
-#if HOTENDS
- #define MAX_HOTEND_DRAW _MIN(HOTENDS, ((LCD_PIXEL_WIDTH - (STATUS_LOGO_BYTEWIDTH + STATUS_FAN_BYTEWIDTH) * 8) / (STATUS_HEATERS_XSPACE)))
-#endif
-
-#define STATUS_HEATERS_BOT (STATUS_HEATERS_Y + STATUS_HEATERS_HEIGHT - 1)
-
-#if ENABLED(MARLIN_DEV_MODE)
- #define SHOW_ON_STATE READ(X_MIN_PIN)
+#if ANIM_CUTTER
+ #define CUTTER_ALT(N) TEST(heat_bits, HEATBIT_CUTTER)
#else
- #define SHOW_ON_STATE false
+ #define CUTTER_ALT() false
#endif
+#if DO_DRAW_HOTENDS
+ #define MAX_HOTEND_DRAW _MIN(HOTENDS, ((LCD_PIXEL_WIDTH - (STATUS_LOGO_BYTEWIDTH + STATUS_FAN_BYTEWIDTH) * 8) / (STATUS_HEATERS_XSPACE)))
+ #define STATUS_HEATERS_BOT (STATUS_HEATERS_Y + STATUS_HEATERS_HEIGHT - 1)
+#endif
+
+#define PROGRESS_BAR_X 54
+#define PROGRESS_BAR_WIDTH (LCD_PIXEL_WIDTH - PROGRESS_BAR_X)
+
FORCE_INLINE void _draw_centered_temp(const int16_t temp, const uint8_t tx, const uint8_t ty) {
const char *str = i16tostr3(temp);
const uint8_t len = str[0] != ' ' ? 3 : str[1] != ' ' ? 2 : 1;
@@ -112,95 +113,68 @@ FORCE_INLINE void _draw_centered_temp(const int16_t temp, const uint8_t tx, cons
lcd_put_wchar(LCD_STR_DEGREE[0]);
}
-FORCE_INLINE void _draw_heater_status(const heater_ind_t heater, const bool blink) {
- #if !HEATER_IDLE_HANDLER
- UNUSED(blink);
- #endif
+#if DO_DRAW_HOTENDS
- #if DO_DRAW_BED && DISABLED(STATUS_COMBINE_HEATERS) || (HAS_HEATED_BED && ENABLED(STATUS_COMBINE_HEATERS) && HOTENDS <= 4)
- const bool isBed = heater < 0;
- #define IFBED(A,B) (isBed ? (A) : (B))
- #else
- #define IFBED(A,B) (B)
- #endif
-
- #if ENABLED(MARLIN_DEV_MODE)
- constexpr bool isHeat = true;
- #else
- const bool isHeat = IFBED(BED_ALT(), HOTEND_ALT(heater));
- #endif
-
- #ifndef STATUS_HOTEND_TEXT_X
- #define STATUS_HOTEND_TEXT_X(N) 0
- #define STATUS_HEATERS_Y 0
- #endif
-
- const uint8_t tx = IFBED(STATUS_BED_TEXT_X, STATUS_HOTEND_TEXT_X(heater));
-
- #if ENABLED(MARLIN_DEV_MODE)
- const float temp = 20 + (millis() >> 8) % IFBED(100, 200),
- target = IFBED(100, 200);
- #else
- const float temp = IFBED(thermalManager.degBed(), thermalManager.degHotend(heater)),
- target = IFBED(thermalManager.degTargetBed(), thermalManager.degTargetHotend(heater));
- #endif
-
- #if DISABLED(STATUS_HOTEND_ANIM)
- #define STATIC_HOTEND true
- #define HOTEND_DOT isHeat
- #else
- #define STATIC_HOTEND false
- #define HOTEND_DOT false
- #endif
-
- #if DO_DRAW_BED && DISABLED(STATUS_BED_ANIM)
- #define STATIC_BED true
- #define BED_DOT isHeat
- #else
- #define STATIC_BED false
- #define BED_DOT false
- #endif
-
- #if ANIM_HOTEND && BOTH(STATUS_HOTEND_INVERTED, STATUS_HOTEND_NUMBERLESS)
- #define OFF_BMP(N) status_hotend_b_bmp
- #define ON_BMP(N) status_hotend_a_bmp
- #elif ANIM_HOTEND && DISABLED(STATUS_HOTEND_INVERTED) && ENABLED(STATUS_HOTEND_NUMBERLESS)
- #define OFF_BMP(N) status_hotend_a_bmp
- #define ON_BMP(N) status_hotend_b_bmp
- #elif ANIM_HOTEND && ENABLED(STATUS_HOTEND_INVERTED)
- #define OFF_BMP(N) status_hotend##N##_b_bmp
- #define ON_BMP(N) status_hotend##N##_a_bmp
- #else
- #define OFF_BMP(N) status_hotend##N##_a_bmp
- #define ON_BMP(N) status_hotend##N##_b_bmp
- #endif
-
- #if STATUS_HOTEND_BITMAPS > 1
- static const unsigned char* const status_hotend_gfx[STATUS_HOTEND_BITMAPS] PROGMEM = ARRAY_N(STATUS_HOTEND_BITMAPS, OFF_BMP(1), OFF_BMP(2), OFF_BMP(3), OFF_BMP(4), OFF_BMP(5), OFF_BMP(6));
- #if ANIM_HOTEND
- static const unsigned char* const status_hotend_on_gfx[STATUS_HOTEND_BITMAPS] PROGMEM = ARRAY_N(STATUS_HOTEND_BITMAPS, ON_BMP(1), ON_BMP(2), ON_BMP(3), ON_BMP(4), ON_BMP(5), ON_BMP(6));
- #define HOTEND_BITMAP(N,S) (unsigned char*)pgm_read_ptr((S) ? &status_hotend_on_gfx[(N) % (STATUS_HOTEND_BITMAPS)] : &status_hotend_gfx[(N) % (STATUS_HOTEND_BITMAPS)])
- #else
- #define HOTEND_BITMAP(N,S) (unsigned char*)pgm_read_ptr(&status_hotend_gfx[(N) % (STATUS_HOTEND_BITMAPS)])
+ // Draw hotend bitmap with current and target temperatures
+ FORCE_INLINE void _draw_hotend_status(const heater_ind_t heater, const bool blink) {
+ #if !HEATER_IDLE_HANDLER
+ UNUSED(blink);
#endif
- #elif ANIM_HOTEND
- #define HOTEND_BITMAP(N,S) ((S) ? ON_BMP() : OFF_BMP())
- #else
- #define HOTEND_BITMAP(N,S) status_hotend_a_bmp
- #endif
- if (PAGE_CONTAINS(STATUS_HEATERS_Y, STATUS_HEATERS_BOT)) {
+ const bool isHeat = HOTEND_ALT(heater);
- #define BAR_TALL (STATUS_HEATERS_HEIGHT - 2)
+ const uint8_t tx = STATUS_HOTEND_TEXT_X(heater);
- const float prop = target - 20,
- perc = prop > 0 && temp >= 20 ? (temp - 20) / prop : 0;
- uint8_t tall = uint8_t(perc * BAR_TALL + 0.5f);
- NOMORE(tall, BAR_TALL);
+ const float temp = thermalManager.degHotend(heater),
+ target = thermalManager.degTargetHotend(heater);
- #if ANIM_HOTEND
- // Draw hotend bitmap, either whole or split by the heating percent
- if (IFBED(0, 1)) {
+ #if DISABLED(STATUS_HOTEND_ANIM)
+ #define STATIC_HOTEND true
+ #define HOTEND_DOT isHeat
+ #else
+ #define STATIC_HOTEND false
+ #define HOTEND_DOT false
+ #endif
+
+ #if ANIM_HOTEND && BOTH(STATUS_HOTEND_INVERTED, STATUS_HOTEND_NUMBERLESS)
+ #define OFF_BMP(N) status_hotend_b_bmp
+ #define ON_BMP(N) status_hotend_a_bmp
+ #elif ANIM_HOTEND && DISABLED(STATUS_HOTEND_INVERTED) && ENABLED(STATUS_HOTEND_NUMBERLESS)
+ #define OFF_BMP(N) status_hotend_a_bmp
+ #define ON_BMP(N) status_hotend_b_bmp
+ #elif ANIM_HOTEND && ENABLED(STATUS_HOTEND_INVERTED)
+ #define OFF_BMP(N) status_hotend##N##_b_bmp
+ #define ON_BMP(N) status_hotend##N##_a_bmp
+ #else
+ #define OFF_BMP(N) status_hotend##N##_a_bmp
+ #define ON_BMP(N) status_hotend##N##_b_bmp
+ #endif
+
+ #if STATUS_HOTEND_BITMAPS > 1
+ static const unsigned char* const status_hotend_gfx[STATUS_HOTEND_BITMAPS] PROGMEM = ARRAY_N(STATUS_HOTEND_BITMAPS, OFF_BMP(1), OFF_BMP(2), OFF_BMP(3), OFF_BMP(4), OFF_BMP(5), OFF_BMP(6));
+ #if ANIM_HOTEND
+ static const unsigned char* const status_hotend_on_gfx[STATUS_HOTEND_BITMAPS] PROGMEM = ARRAY_N(STATUS_HOTEND_BITMAPS, ON_BMP(1), ON_BMP(2), ON_BMP(3), ON_BMP(4), ON_BMP(5), ON_BMP(6));
+ #define HOTEND_BITMAP(N,S) (unsigned char*)pgm_read_ptr((S) ? &status_hotend_on_gfx[(N) % (STATUS_HOTEND_BITMAPS)] : &status_hotend_gfx[(N) % (STATUS_HOTEND_BITMAPS)])
+ #else
+ #define HOTEND_BITMAP(N,S) (unsigned char*)pgm_read_ptr(&status_hotend_gfx[(N) % (STATUS_HOTEND_BITMAPS)])
+ #endif
+ #elif ANIM_HOTEND
+ #define HOTEND_BITMAP(N,S) ((S) ? ON_BMP() : OFF_BMP())
+ #else
+ #define HOTEND_BITMAP(N,S) status_hotend_a_bmp
+ #endif
+
+ if (PAGE_CONTAINS(STATUS_HEATERS_Y, STATUS_HEATERS_BOT)) {
+
+ #define BAR_TALL (STATUS_HEATERS_HEIGHT - 2)
+
+ const float prop = target - 20,
+ perc = prop > 0 && temp >= 20 ? (temp - 20) / prop : 0;
+ uint8_t tall = uint8_t(perc * BAR_TALL + 0.5f);
+ NOMORE(tall, BAR_TALL);
+
+ #if ANIM_HOTEND
+ // Draw hotend bitmap, either whole or split by the heating percent
const uint8_t hx = STATUS_HOTEND_X(heater),
bw = STATUS_HOTEND_BYTEWIDTH(heater);
#if ENABLED(STATUS_HEAT_PERCENT)
@@ -212,79 +186,130 @@ FORCE_INLINE void _draw_heater_status(const heater_ind_t heater, const bool blin
else
#endif
u8g.drawBitmapP(hx, STATUS_HEATERS_Y, bw, STATUS_HEATERS_HEIGHT, HOTEND_BITMAP(heater, isHeat));
- }
- #endif
-
- // Draw a heating progress bar, if specified
- #if DO_DRAW_BED && ENABLED(STATUS_HEAT_PERCENT)
-
- if (IFBED(true, STATIC_HOTEND) && isHeat) {
- const uint8_t bx = IFBED(STATUS_BED_X + STATUS_BED_WIDTH - 1, STATUS_HOTEND_X(heater) + STATUS_HOTEND_WIDTH(heater)) + 1;
- u8g.drawFrame(bx, STATUS_HEATERS_Y, 3, STATUS_HEATERS_HEIGHT);
- if (tall) {
- const uint8_t ph = STATUS_HEATERS_HEIGHT - 1 - tall;
- if (PAGE_OVER(STATUS_HEATERS_Y + ph))
- u8g.drawVLine(bx + 1, STATUS_HEATERS_Y + ph, tall);
- }
- }
-
- #endif
-
- } // PAGE_CONTAINS
-
- if (PAGE_UNDER(7)) {
- #if HEATER_IDLE_HANDLER
- const bool is_idle = IFBED(thermalManager.bed_idle.timed_out, thermalManager.hotend_idle[heater].timed_out),
- dodraw = (blink || !is_idle);
- #else
- constexpr bool dodraw = true;
- #endif
- if (dodraw) _draw_centered_temp(target + 0.5, tx, 7);
- }
-
- if (PAGE_CONTAINS(28 - INFO_FONT_ASCENT, 28 - 1))
- _draw_centered_temp(temp + 0.5f, tx, 28);
-
- if (IFBED(STATIC_BED && BED_DOT, STATIC_HOTEND && HOTEND_DOT) && PAGE_CONTAINS(17, 19)) {
- u8g.setColorIndex(0); // set to white on black
- u8g.drawBox(tx, IFBED(20-2, 20-3), 2, 2);
- u8g.setColorIndex(1); // restore black on white
- }
-
-}
-
-#if DO_DRAW_CHAMBER
-
- FORCE_INLINE void _draw_chamber_status(const bool blink) {
- #if ENABLED(MARLIN_DEV_MODE)
- const float temp = 10 + (millis() >> 8) % CHAMBER_MAXTEMP,
- target = CHAMBER_MAXTEMP;
- #else
- const float temp = thermalManager.degChamber();
- #if HAS_HEATED_CHAMBER
- const float target = thermalManager.degTargetChamber();
#endif
- #endif
+ // Draw a heating progress bar, if specified
+ #if DO_DRAW_BED && ENABLED(STATUS_HEAT_PERCENT)
+
+ if (STATIC_HOTEND && isHeat) {
+ const uint8_t bx = STATUS_HOTEND_X(heater) + STATUS_HOTEND_WIDTH(heater) + 1;
+ u8g.drawFrame(bx, STATUS_HEATERS_Y, 3, STATUS_HEATERS_HEIGHT);
+ if (tall) {
+ const uint8_t ph = STATUS_HEATERS_HEIGHT - 1 - tall;
+ if (PAGE_OVER(STATUS_HEATERS_Y + ph))
+ u8g.drawVLine(bx + 1, STATUS_HEATERS_Y + ph, tall);
+ }
+ }
+
+ #endif
+
+ } // PAGE_CONTAINS
+
+ if (PAGE_UNDER(7)) {
+ #if HEATER_IDLE_HANDLER
+ const bool dodraw = (blink || !thermalManager.hotend_idle[heater].timed_out);
+ #else
+ constexpr bool dodraw = true;
+ #endif
+ if (dodraw) _draw_centered_temp(target + 0.5, tx, 7);
+ }
+
+ if (PAGE_CONTAINS(28 - INFO_FONT_ASCENT, 28 - 1))
+ _draw_centered_temp(temp + 0.5f, tx, 28);
+
+ if (STATIC_HOTEND && HOTEND_DOT && PAGE_CONTAINS(17, 19)) {
+ u8g.setColorIndex(0); // set to white on black
+ u8g.drawBox(tx, 20 - 3, 2, 2);
+ u8g.setColorIndex(1); // restore black on white
+ }
+
+ }
+
+#endif // DO_DRAW_HOTENDS
+
+#if DO_DRAW_BED
+
+ // Draw bed bitmap with current and target temperatures
+ FORCE_INLINE void _draw_bed_status(const bool blink) {
#if !HEATER_IDLE_HANDLER
UNUSED(blink);
#endif
+ const uint8_t tx = STATUS_BED_TEXT_X;
+
+ const float temp = thermalManager.degBed(),
+ target = thermalManager.degTargetBed();
+
+ #if ENABLED(STATUS_HEAT_PERCENT) || (DO_DRAW_BED && DISABLED(STATUS_BED_ANIM))
+ const bool isHeat = BED_ALT();
+ #endif
+
+ #if DO_DRAW_BED && DISABLED(STATUS_BED_ANIM)
+ #define STATIC_BED true
+ #define BED_DOT isHeat
+ #else
+ #define STATIC_BED false
+ #define BED_DOT false
+ #endif
+
+ if (PAGE_CONTAINS(STATUS_HEATERS_Y, STATUS_HEATERS_BOT)) {
+
+ #define BAR_TALL (STATUS_HEATERS_HEIGHT - 2)
+
+ const float prop = target - 20,
+ perc = prop > 0 && temp >= 20 ? (temp - 20) / prop : 0;
+ uint8_t tall = uint8_t(perc * BAR_TALL + 0.5f);
+ NOMORE(tall, BAR_TALL);
+
+ // Draw a heating progress bar, if specified
+ #if ENABLED(STATUS_HEAT_PERCENT)
+
+ if (isHeat) {
+ const uint8_t bx = STATUS_BED_X + STATUS_BED_WIDTH;
+ u8g.drawFrame(bx, STATUS_HEATERS_Y, 3, STATUS_HEATERS_HEIGHT);
+ if (tall) {
+ const uint8_t ph = STATUS_HEATERS_HEIGHT - 1 - tall;
+ if (PAGE_OVER(STATUS_HEATERS_Y + ph))
+ u8g.drawVLine(bx + 1, STATUS_HEATERS_Y + ph, tall);
+ }
+ }
+
+ #endif
+
+ } // PAGE_CONTAINS
+
if (PAGE_UNDER(7)) {
#if HEATER_IDLE_HANDLER
- const bool is_idle = false, // thermalManager.chamber_idle.timed_out,
- dodraw = (blink || !is_idle);
+ const bool dodraw = (blink || !thermalManager.bed_idle.timed_out);
#else
constexpr bool dodraw = true;
#endif
- #if HAS_HEATED_CHAMBER
- if (dodraw) _draw_centered_temp(target + 0.5, STATUS_CHAMBER_TEXT_X, 7);
- #else
- UNUSED(dodraw);
- #endif
+ if (dodraw) _draw_centered_temp(target + 0.5, tx, 7);
}
+
if (PAGE_CONTAINS(28 - INFO_FONT_ASCENT, 28 - 1))
- _draw_centered_temp(temp + 0.5f, STATUS_CHAMBER_TEXT_X, 28);
+ _draw_centered_temp(temp + 0.5f, tx, 28);
+
+ if (STATIC_BED && BED_DOT && PAGE_CONTAINS(17, 19)) {
+ u8g.setColorIndex(0); // set to white on black
+ u8g.drawBox(tx, 20 - 2, 2, 2);
+ u8g.setColorIndex(1); // restore black on white
+ }
+
+ }
+
+#endif // DO_DRAW_BED
+
+#if DO_DRAW_CHAMBER
+
+ FORCE_INLINE void _draw_chamber_status() {
+ #if HAS_HEATED_CHAMBER
+ if (PAGE_UNDER(7))
+ _draw_centered_temp(thermalManager.degTargetChamber() + 0.5f, STATUS_CHAMBER_TEXT_X, 7);
+ #endif
+
+ if (PAGE_CONTAINS(28 - INFO_FONT_ASCENT, 28 - 1))
+ _draw_centered_temp(thermalManager.degChamber() + 0.5f, STATUS_CHAMBER_TEXT_X, 28);
}
#endif // DO_DRAW_CHAMBER
@@ -295,8 +320,14 @@ FORCE_INLINE void _draw_heater_status(const heater_ind_t heater, const bool blin
// Homed and known, display constantly.
//
FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const bool blink) {
- const uint8_t offs = (XYZ_SPACING) * axis;
- lcd_put_wchar(X_LABEL_POS + offs, XYZ_BASELINE, 'X' + axis);
+ const AxisEnum a = (
+ #if ENABLED(LCD_SHOW_E_TOTAL)
+ axis == E_AXIS ? X_AXIS :
+ #endif
+ axis
+ );
+ const uint8_t offs = (XYZ_SPACING) * a;
+ lcd_put_wchar(X_LABEL_POS + offs, XYZ_BASELINE, axis_codes[axis]);
lcd_moveto(X_VALUE_POS + offs, XYZ_BASELINE);
if (blink)
lcd_put_u8str(value);
@@ -314,45 +345,156 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
}
}
-#if ENABLED(MARLIN_DEV_MODE)
- uint16_t count_renders = 0;
- uint32_t total_cycles = 0;
-#endif
-
void MarlinUI::draw_status_screen() {
- #if ENABLED(MARLIN_DEV_MODE)
- if (first_page) count_renders++;
- #endif
-
- static char xstring[5], ystring[5], zstring[8];
+ static char xstring[5
+ #if ENABLED(LCD_SHOW_E_TOTAL)
+ + 7
+ #endif
+ ], ystring[5], zstring[8];
#if ENABLED(FILAMENT_LCD_DISPLAY)
static char wstring[5], mstring[4];
#endif
+ #if HAS_PRINT_PROGRESS
+ #if DISABLED(DOGM_SD_PERCENT)
+ #define _SD_INFO_X(len) (PROGRESS_BAR_X + (PROGRESS_BAR_WIDTH) / 2 - (len) * (MENU_FONT_WIDTH) / 2)
+ #else
+ #define _SD_INFO_X(len) (LCD_PIXEL_WIDTH - (len) * (MENU_FONT_WIDTH))
+ #endif
+
+ #if ENABLED(DOGM_SD_PERCENT)
+ static char progress_string[5];
+ #endif
+ static uint8_t lastElapsed = 0xFF, lastProgress = 0xFF;
+ static u8g_uint_t elapsed_x_pos = 0, progress_bar_solid_width = 0;
+ static char elapsed_string[16];
+ #if ENABLED(SHOW_REMAINING_TIME)
+ static u8g_uint_t estimation_x_pos = 0;
+ static char estimation_string[10];
+ #if BOTH(DOGM_SD_PERCENT, ROTATE_PROGRESS_DISPLAY)
+ static u8g_uint_t progress_x_pos = 0;
+ static uint8_t progress_state = 0;
+ static bool prev_blink = 0;
+ #endif
+ #endif
+ #endif
+
+ const bool showxy = (true
+ #if ENABLED(LCD_SHOW_E_TOTAL)
+ && !printingIsActive()
+ #endif
+ );
+
// At the first page, generate new display values
if (first_page) {
- #if ANIM_HBC
+ #if ANIM_HBCC
uint8_t new_bits = 0;
#if ANIM_HOTEND
- HOTEND_LOOP() if (thermalManager.isHeatingHotend(e) ^ SHOW_ON_STATE) SBI(new_bits, e);
+ HOTEND_LOOP() if (thermalManager.isHeatingHotend(e)) SBI(new_bits, HEATBIT_HOTEND + e);
#endif
#if ANIM_BED
- if (thermalManager.isHeatingBed() ^ SHOW_ON_STATE) SBI(new_bits, 7);
+ if (thermalManager.isHeatingBed()) SBI(new_bits, HEATBIT_BED);
#endif
#if DO_DRAW_CHAMBER && HAS_HEATED_CHAMBER
- if (thermalManager.isHeatingChamber() ^ SHOW_ON_STATE) SBI(new_bits, 6);
+ if (thermalManager.isHeatingChamber()) SBI(new_bits, HEATBIT_CHAMBER);
+ #endif
+ #if ANIM_CUTTER
+ if (cutter.enabled()) SBI(new_bits, HEATBIT_CUTTER);
#endif
heat_bits = new_bits;
#endif
+
const xyz_pos_t lpos = current_position.asLogical();
- strcpy(xstring, ftostr4sign(lpos.x));
- strcpy(ystring, ftostr4sign(lpos.y));
- strcpy(zstring, ftostr52sp( lpos.z));
+ strcpy(zstring, ftostr52sp(lpos.z));
+
+ if (showxy) {
+ strcpy(xstring, ftostr4sign(lpos.x));
+ strcpy(ystring, ftostr4sign(lpos.y));
+ }
+ else {
+ #if ENABLED(LCD_SHOW_E_TOTAL)
+ const uint8_t escale = e_move_accumulator >= 100000.0f ? 10 : 1; // After 100m switch to cm
+ sprintf_P(xstring, PSTR("%ld%cm"), uint32_t(_MAX(e_move_accumulator, 0.0f)) / escale, escale == 10 ? 'c' : 'm'); // 1234567mm
+ #endif
+ }
+
#if ENABLED(FILAMENT_LCD_DISPLAY)
strcpy(wstring, ftostr12ns(filwidth.measured_mm));
strcpy(mstring, i16tostr3(planner.volumetric_percent(parser.volumetric_enabled)));
#endif
+
+ // Progress / elapsed / estimation updates and string formatting to avoid float math on each LCD draw
+ #if HAS_PRINT_PROGRESS
+ const progress_t progress =
+ #if HAS_PRINT_PROGRESS_PERMYRIAD
+ get_progress_permyriad()
+ #else
+ get_progress_percent()
+ #endif
+ ;
+ duration_t elapsed = print_job_timer.duration();
+ const uint8_t p = progress & 0xFF, ev = elapsed.value & 0xFF;
+ if (p != lastProgress) {
+ lastProgress = p;
+
+ progress_bar_solid_width = u8g_uint_t((PROGRESS_BAR_WIDTH - 2) * progress / (PROGRESS_SCALE) * 0.01f);
+
+ #if ENABLED(DOGM_SD_PERCENT)
+ if (progress == 0) {
+ progress_string[0] = '\0';
+ #if ENABLED(SHOW_REMAINING_TIME)
+ estimation_string[0] = '\0';
+ estimation_x_pos = _SD_INFO_X(0);
+ #endif
+ }
+ else {
+ strcpy(progress_string, (
+ #if ENABLED(PRINT_PROGRESS_SHOW_DECIMALS)
+ permyriadtostr4(progress)
+ #else
+ ui8tostr3(progress / (PROGRESS_SCALE))
+ #endif
+ ));
+ }
+ #if BOTH(SHOW_REMAINING_TIME, ROTATE_PROGRESS_DISPLAY) // Tri-state progress display mode
+ progress_x_pos = _SD_INFO_X(strlen(progress_string) + 1);
+ #endif
+ #endif
+ }
+
+ if (ev != lastElapsed) {
+ lastElapsed = ev;
+ const bool has_days = (elapsed.value >= 60*60*24L);
+ const uint8_t len = elapsed.toDigital(elapsed_string, has_days);
+ elapsed_x_pos = _SD_INFO_X(len);
+
+ #if ENABLED(SHOW_REMAINING_TIME)
+ if (!(ev & 0x3)) {
+ uint32_t timeval = (0
+ #if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME)
+ + get_remaining_time()
+ #endif
+ );
+ if (!timeval && progress > 0) timeval = elapsed.value * (100 * (PROGRESS_SCALE) - progress) / progress;
+ if (!timeval) {
+ estimation_string[0] = '\0';
+ estimation_x_pos = _SD_INFO_X(0);
+ }
+ else {
+ duration_t estimation = timeval;
+ const bool has_days = (estimation.value >= 60*60*24L);
+ const uint8_t len = estimation.toDigital(estimation_string, has_days);
+ estimation_x_pos = _SD_INFO_X(len
+ #if !BOTH(DOGM_SD_PERCENT, ROTATE_PROGRESS_DISPLAY)
+ + 1
+ #endif
+ );
+ }
+ }
+ #endif
+ }
+ #endif
}
const bool blink = get_blink();
@@ -360,10 +502,6 @@ void MarlinUI::draw_status_screen() {
// Status Menu Font
set_font(FONT_STATUSMENU);
- #if ENABLED(MARLIN_DEV_MODE)
- TCNT5 = 0;
- #endif
-
#if DO_DRAW_LOGO
if (PAGE_CONTAINS(STATUS_LOGO_Y, STATUS_LOGO_Y + STATUS_LOGO_HEIGHT - 1))
u8g.drawBitmapP(STATUS_LOGO_X, STATUS_LOGO_Y, STATUS_LOGO_BYTEWIDTH, STATUS_LOGO_HEIGHT, status_logo_bmp);
@@ -375,6 +513,18 @@ void MarlinUI::draw_status_screen() {
u8g.drawBitmapP(STATUS_HEATERS_X, STATUS_HEATERS_Y, STATUS_HEATERS_BYTEWIDTH, STATUS_HEATERS_HEIGHT, status_heaters_bmp);
#endif
+ #if DO_DRAW_CUTTER
+ #if ANIM_CUTTER
+ #define CUTTER_BITMAP(S) ((S) ? status_cutter_on_bmp : status_cutter_bmp)
+ #else
+ #define CUTTER_BITMAP(S) status_cutter_bmp
+ #endif
+ const uint8_t cuttery = STATUS_CUTTER_Y(CUTTER_ALT()),
+ cutterh = STATUS_CUTTER_HEIGHT(CUTTER_ALT());
+ if (PAGE_CONTAINS(cuttery, cuttery + cutterh - 1))
+ u8g.drawBitmapP(STATUS_CUTTER_X, cuttery, STATUS_CUTTER_BYTEWIDTH, cutterh, CUTTER_BITMAP(CUTTER_ALT()));
+ #endif
+
#if DO_DRAW_BED && DISABLED(STATUS_COMBINE_HEATERS)
#if ANIM_BED
#define BED_BITMAP(S) ((S) ? status_bed_on_bmp : status_bed_bmp)
@@ -428,18 +578,27 @@ void MarlinUI::draw_status_screen() {
//
if (PAGE_UNDER(6 + 1 + 12 + 1 + 6 + 1)) {
// Extruders
- #if HOTENDS
+ #if DO_DRAW_HOTENDS
for (uint8_t e = 0; e < MAX_HOTEND_DRAW; ++e)
- _draw_heater_status((heater_ind_t)e, blink);
+ _draw_hotend_status((heater_ind_t)e, blink);
#endif
- // Heated bed
- #if DO_DRAW_BED && DISABLED(STATUS_COMBINE_HEATERS) || (HAS_HEATED_BED && ENABLED(STATUS_COMBINE_HEATERS) && HOTENDS <= 4)
- _draw_heater_status(H_BED, blink);
+ // Laser / Spindle
+ #if DO_DRAW_CUTTER
+ if (cutter.power && PAGE_CONTAINS(STATUS_CUTTER_TEXT_Y - INFO_FONT_ASCENT, STATUS_CUTTER_TEXT_Y - 1)) {
+ lcd_put_u8str(STATUS_CUTTER_TEXT_X, STATUS_CUTTER_TEXT_Y, i16tostr3(cutter.powerPercent(cutter.power)));
+ lcd_put_wchar('%');
+ }
#endif
+ // Heated Bed
+ #if DO_DRAW_BED
+ _draw_bed_status(blink);
+ #endif
+
+ // Heated Chamber
#if DO_DRAW_CHAMBER
- _draw_chamber_status(blink);
+ _draw_chamber_status();
#endif
// Fan, if a bitmap was provided
@@ -461,10 +620,6 @@ void MarlinUI::draw_status_screen() {
#endif
}
- #if ENABLED(MARLIN_DEV_MODE)
- total_cycles += TCNT5;
- #endif
-
#if ENABLED(SDSUPPORT)
//
// SD Card Symbol
@@ -485,55 +640,68 @@ void MarlinUI::draw_status_screen() {
//
// Progress bar frame
//
- #define PROGRESS_BAR_X 54
- #define PROGRESS_BAR_WIDTH (LCD_PIXEL_WIDTH - PROGRESS_BAR_X)
if (PAGE_CONTAINS(49, 52))
u8g.drawFrame(PROGRESS_BAR_X, 49, PROGRESS_BAR_WIDTH, 4);
- const uint8_t progress = get_progress();
-
- if (progress > 1) {
-
- //
- // Progress bar solid part
- //
-
- if (PAGE_CONTAINS(50, 51)) // 50-51 (or just 50)
- u8g.drawBox(
- PROGRESS_BAR_X + 1, 50,
- (uint16_t)((PROGRESS_BAR_WIDTH - 2) * progress * 0.01), 2
- );
-
- //
- // SD Percent Complete
- //
-
- #if ENABLED(DOGM_SD_PERCENT)
- if (PAGE_CONTAINS(41, 48)) {
- // Percent complete
- lcd_put_u8str(55, 48, ui8tostr3(progress));
- lcd_put_wchar('%');
- }
- #endif
- }
-
//
- // Elapsed Time
+ // Progress bar solid part
//
- #if DISABLED(DOGM_SD_PERCENT)
- #define SD_DURATION_X (PROGRESS_BAR_X + (PROGRESS_BAR_WIDTH / 2) - len * (MENU_FONT_WIDTH / 2))
- #else
- #define SD_DURATION_X (LCD_PIXEL_WIDTH - len * MENU_FONT_WIDTH)
- #endif
+ if (PAGE_CONTAINS(50, 51)) // 50-51 (or just 50)
+ u8g.drawBox(PROGRESS_BAR_X + 1, 50, progress_bar_solid_width, 2);
if (PAGE_CONTAINS(EXTRAS_BASELINE - INFO_FONT_ASCENT, EXTRAS_BASELINE - 1)) {
- char buffer[13];
- duration_t elapsed = print_job_timer.duration();
- bool has_days = (elapsed.value >= 60*60*24L);
- uint8_t len = elapsed.toDigital(buffer, has_days);
- lcd_put_u8str(SD_DURATION_X, EXTRAS_BASELINE, buffer);
+
+ #if ALL(DOGM_SD_PERCENT, SHOW_REMAINING_TIME, ROTATE_PROGRESS_DISPLAY)
+
+ if (prev_blink != blink) {
+ prev_blink = blink;
+ if (++progress_state >= 3) progress_state = 0;
+ }
+
+ if (progress_state == 0) {
+ if (progress_string[0]) {
+ lcd_put_u8str(progress_x_pos, EXTRAS_BASELINE, progress_string);
+ lcd_put_wchar('%');
+ }
+ }
+ else if (progress_state == 2 && estimation_string[0]) {
+ lcd_put_u8str(PROGRESS_BAR_X, EXTRAS_BASELINE, "R:");
+ lcd_put_u8str(estimation_x_pos, EXTRAS_BASELINE, estimation_string);
+ }
+ else if (elapsed_string[0]) {
+ lcd_put_u8str(PROGRESS_BAR_X, EXTRAS_BASELINE, "E:");
+ lcd_put_u8str(elapsed_x_pos, EXTRAS_BASELINE, elapsed_string);
+ }
+
+ #else // !DOGM_SD_PERCENT || !SHOW_REMAINING_TIME || !ROTATE_PROGRESS_DISPLAY
+
+ //
+ // SD Percent Complete
+ //
+
+ #if ENABLED(DOGM_SD_PERCENT)
+ if (progress_string[0]) {
+ lcd_put_u8str(55, 48, progress_string); // Percent complete
+ lcd_put_wchar('%');
+ }
+ #endif
+
+ //
+ // Elapsed Time
+ //
+
+ #if ENABLED(SHOW_REMAINING_TIME)
+ if (blink && estimation_string[0]) {
+ lcd_put_wchar(estimation_x_pos, EXTRAS_BASELINE, 'R');
+ lcd_put_u8str(estimation_string);
+ }
+ else
+ #endif
+ lcd_put_u8str(elapsed_x_pos, EXTRAS_BASELINE, elapsed_string);
+
+ #endif // !DOGM_SD_PERCENT || !SHOW_REMAINING_TIME || !ROTATE_PROGRESS_DISPLAY
}
#endif // HAS_PRINT_PROGRESS
@@ -586,8 +754,14 @@ void MarlinUI::draw_status_screen() {
#else
- _draw_axis_value(X_AXIS, xstring, blink);
- _draw_axis_value(Y_AXIS, ystring, blink);
+ if (showxy) {
+ _draw_axis_value(X_AXIS, xstring, blink);
+ _draw_axis_value(Y_AXIS, ystring, blink);
+ }
+ else {
+ _draw_axis_value(E_AXIS, xstring, true);
+ lcd_put_u8str_P(PSTR(" "));
+ }
#endif
@@ -650,17 +824,6 @@ void MarlinUI::draw_status_screen() {
void MarlinUI::draw_status_message(const bool blink) {
- #if ENABLED(MARLIN_DEV_MODE)
- if (PAGE_CONTAINS(64-8, 64-1)) {
- lcd_put_int(total_cycles);
- lcd_put_wchar('/');
- lcd_put_int(count_renders);
- lcd_put_wchar('=');
- lcd_put_int(int(total_cycles / count_renders));
- return;
- }
- #endif
-
// Get the UTF8 character count of the string
uint8_t slen = utf8_strlen(status_message);
diff --git a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp
index 5e73ba8bf3..f5931917ae 100644
--- a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp
+++ b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp
@@ -59,6 +59,10 @@
#include "../../sd/cardreader.h"
#endif
+#if ENABLED(LCD_SHOW_E_TOTAL)
+ #include "../../MarlinCore.h" // for printingIsActive
+#endif
+
#define TEXT_MODE_LCD_WIDTH 16
#define BUFFER_WIDTH 256
@@ -660,7 +664,7 @@ void ST7920_Lite_Status_Screen::draw_status_message() {
#endif
}
-void ST7920_Lite_Status_Screen::draw_position(const xyz_pos_t &pos, const bool position_known) {
+void ST7920_Lite_Status_Screen::draw_position(const xyze_pos_t &pos, const bool position_known) {
char str[7];
set_ddram_address(DDRAM_LINE_4);
begin_data();
@@ -668,11 +672,25 @@ void ST7920_Lite_Status_Screen::draw_position(const xyz_pos_t &pos, const bool p
// If position is unknown, flash the labels.
const unsigned char alt_label = position_known ? 0 : (ui.get_blink() ? ' ' : 0);
- write_byte(alt_label ? alt_label : 'X');
- write_str(dtostrf(pos.x, -4, 0, str), 4);
+ if (true
+ #if ENABLED(LCD_SHOW_E_TOTAL)
+ && !printingIsActive()
+ #endif
+ ) {
+ write_byte(alt_label ? alt_label : 'X');
+ write_str(dtostrf(pos.x, -4, 0, str), 4);
- write_byte(alt_label ? alt_label : 'Y');
- write_str(dtostrf(pos.y, -4, 0, str), 4);
+ write_byte(alt_label ? alt_label : 'Y');
+ write_str(dtostrf(pos.y, -4, 0, str), 4);
+ }
+ else {
+ #if ENABLED(LCD_SHOW_E_TOTAL)
+ char tmp[15];
+ const uint8_t escale = e_move_accumulator >= 100000.0f ? 10 : 1; // After 100m switch to cm
+ sprintf_P(tmp, PSTR("E%-7ld%cm "), uint32_t(_MAX(e_move_accumulator, 0.0f)) / escale, escale == 10 ? 'c' : 'm'); // 1234567mm
+ write_str(tmp);
+ #endif
+ }
write_byte(alt_label ? alt_label : 'Z');
write_str(dtostrf(pos.z, -5, 1, str), 5);
@@ -850,7 +868,7 @@ void ST7920_Lite_Status_Screen::update_progress(const bool forceUpdate) {
// when an update is actually necessary.
static uint8_t last_progress = 0;
- const uint8_t progress = ui.get_progress();
+ const uint8_t progress = ui.get_progress_percent();
if (forceUpdate || last_progress != progress) {
last_progress = progress;
draw_progress_bar(progress);
@@ -894,7 +912,7 @@ void ST7920_Lite_Status_Screen::on_exit() {
ncs();
}
-// This is called prior to the KILL screen to
+// Called prior to the KILL screen to
// clear the screen, preventing a garbled display.
void ST7920_Lite_Status_Screen::clear_text_buffer() {
cs();
diff --git a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.h b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.h
index 754c9933e7..bc18c43f10 100644
--- a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.h
+++ b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.h
@@ -87,7 +87,7 @@ class ST7920_Lite_Status_Screen {
static void draw_print_time(const duration_t &elapsed);
static void draw_feedrate_percentage(const uint16_t percentage);
static void draw_status_message();
- static void draw_position(const xyz_pos_t &pos, bool position_known = true);
+ static void draw_position(const xyze_pos_t &pos, bool position_known = true);
static bool indicators_changed();
static bool position_changed();
diff --git a/Marlin/src/lcd/dogm/u8g_dev_st7920_128x64_HAL.cpp b/Marlin/src/lcd/dogm/u8g_dev_st7920_128x64_HAL.cpp
index 1b9a80f9d2..87094eb804 100644
--- a/Marlin/src/lcd/dogm/u8g_dev_st7920_128x64_HAL.cpp
+++ b/Marlin/src/lcd/dogm/u8g_dev_st7920_128x64_HAL.cpp
@@ -74,7 +74,7 @@ static const uint8_t u8g_dev_st7920_128x64_HAL_init_seq[] PROGMEM = {
0x038, // 8 Bit interface (DL=1), basic instruction set (RE=0)
0x00C, // display on, cursor & blink off; 0x08: all off
- 0x006, // Entry mode: Cursor move to right ,DDRAM address counter (AC) plus 1, no shift
+ 0x006, // Entry mode: Cursor move to right, DDRAM address counter (AC) plus 1, no shift
0x002, // disable scroll, enable CGRAM adress
0x001, // clear RAM, needs 1.6 ms
U8G_ESC_DLY(100), // delay 100 ms
@@ -201,7 +201,7 @@ u8g_dev_t u8g_dev_st7920_128x64_HAL_4x_sw_spi = { u8g_dev_st7920_128x64_HAL_4x_f
U8G_PB_DEV(u8g_dev_st7920_128x64_HAL_hw_spi, LCD_PIXEL_WIDTH, LCD_PIXEL_HEIGHT, PAGE_HEIGHT, u8g_dev_st7920_128x64_HAL_fn, U8G_COM_ST7920_HAL_HW_SPI);
u8g_dev_t u8g_dev_st7920_128x64_HAL_4x_hw_spi = { u8g_dev_st7920_128x64_HAL_4x_fn, &u8g_dev_st7920_128x64_HAL_4x_pb, U8G_COM_ST7920_HAL_HW_SPI };
-#if NONE(__AVR__, ARDUINO_ARCH_STM32) || defined(U8G_HAL_LINKS)
+#if NONE(__AVR__, ARDUINO_ARCH_STM32, ARDUINO_ARCH_ESP32) || defined(U8G_HAL_LINKS)
// Also use this device for HAL version of rrd class. This results in the same device being used
// for the ST7920 for HAL systems no matter what is selected in ultralcd_impl_DOGM.h.
u8g_dev_t u8g_dev_st7920_128x64_rrd_sw_spi = { u8g_dev_st7920_128x64_HAL_4x_fn, &u8g_dev_st7920_128x64_HAL_4x_pb, U8G_COM_ST7920_HAL_SW_SPI };
diff --git a/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp b/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp
index 8c1dfa3ffe..39e0c43cdd 100644
--- a/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp
+++ b/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp
@@ -65,6 +65,8 @@
#include
#if ENABLED(LCD_USE_DMA_FSMC)
+ extern void LCD_IO_WriteReg(uint16_t Reg);
+ extern void LCD_IO_WriteData(uint16_t RegValue);
extern void LCD_IO_WriteSequence(uint16_t *data, uint16_t length);
extern void LCD_IO_WriteSequence_Async(uint16_t *data, uint16_t length);
extern void LCD_IO_WaitSequence_Async();
@@ -80,10 +82,6 @@
#define X_HI (X_LO + 2 * WIDTH - 1)
#define Y_HI (Y_LO + 2 * HEIGHT - 1)
-#define LCD_COLUMN 0x2A /* Colomn address register */
-#define LCD_ROW 0x2B /* Row address register */
-#define LCD_WRITE_RAM 0x2C
-
// see https://ee-programming-notepad.blogspot.com/2016/10/16-bit-color-generator-picker.html
#define COLOR_BLACK 0x0000 // #000000
@@ -133,113 +131,254 @@
static uint32_t lcd_id = 0;
-#define U8G_ESC_DATA(x) (uint8_t)(x >> 8), (uint8_t)(x & 0xFF)
+#define ST7789V_CASET 0x2A /* Column address register */
+#define ST7789V_RASET 0x2B /* Row address register */
+#define ST7789V_WRITE_RAM 0x2C /* Write data to GRAM */
-static const uint8_t page_first_sequence[] = {
- U8G_ESC_ADR(0), LCD_COLUMN, U8G_ESC_ADR(1), U8G_ESC_DATA(X_LO), U8G_ESC_DATA(X_HI),
- U8G_ESC_ADR(0), LCD_ROW, U8G_ESC_ADR(1), U8G_ESC_DATA(Y_LO), U8G_ESC_DATA(Y_HI),
- U8G_ESC_ADR(0), LCD_WRITE_RAM, U8G_ESC_ADR(1),
- U8G_ESC_END
-};
-static const uint8_t clear_screen_sequence[] = {
- U8G_ESC_ADR(0), LCD_COLUMN, U8G_ESC_ADR(1), 0x00, 0x00, U8G_ESC_DATA(LCD_FULL_PIXEL_WIDTH),
- U8G_ESC_ADR(0), LCD_ROW, U8G_ESC_ADR(1), 0x00, 0x00, U8G_ESC_DATA(LCD_FULL_PIXEL_HEIGHT),
- U8G_ESC_ADR(0), LCD_WRITE_RAM, U8G_ESC_ADR(1),
- U8G_ESC_END
-};
+/* Mind the mess: with landscape screen orientation 'Horizontal' is Y and 'Vertical' is X */
+#define ILI9328_HASET 0x20 /* Horizontal GRAM address register (0-255) */
+#define ILI9328_VASET 0x21 /* Vertical GRAM address register (0-511)*/
+#define ILI9328_WRITE_RAM 0x22 /* Write data to GRAM */
-#if ENABLED(TOUCH_BUTTONS)
+#define ILI9328_HASTART 0x50 /* Horizontal address start position (0-255) */
+#define ILI9328_HAEND 0x51 /* Horizontal address end position (0-255) */
+#define ILI9328_VASTART 0x52 /* Vertical address start position (0-511) */
+#define ILI9328_VAEND 0x53 /* Vertical address end position (0-511) */
- static const uint8_t separation_line_sequence_left[] = {
- U8G_ESC_ADR(0), LCD_COLUMN, U8G_ESC_ADR(1), U8G_ESC_DATA(10), U8G_ESC_DATA(159),
- U8G_ESC_ADR(0), LCD_ROW, U8G_ESC_ADR(1), U8G_ESC_DATA(170), U8G_ESC_DATA(173),
- U8G_ESC_ADR(0), LCD_WRITE_RAM, U8G_ESC_ADR(1),
- U8G_ESC_END
- };
- static const uint8_t separation_line_sequence_right[] = {
- U8G_ESC_ADR(0), LCD_COLUMN, U8G_ESC_ADR(1), U8G_ESC_DATA(160), U8G_ESC_DATA(309),
- U8G_ESC_ADR(0), LCD_ROW, U8G_ESC_ADR(1), U8G_ESC_DATA(170), U8G_ESC_DATA(173),
- U8G_ESC_ADR(0), LCD_WRITE_RAM, U8G_ESC_ADR(1),
- U8G_ESC_END
- };
+static void setWindow_ili9328(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) {
+ #ifdef LCD_USE_DMA_FSMC
+ LCD_IO_WriteReg(ILI9328_HASTART);
+ LCD_IO_WriteData(Ymin);
+ LCD_IO_WriteReg(ILI9328_HAEND);
+ LCD_IO_WriteData(Ymax);
+ LCD_IO_WriteReg(ILI9328_VASTART);
+ LCD_IO_WriteData(Xmin);
+ LCD_IO_WriteReg(ILI9328_VAEND);
+ LCD_IO_WriteData(Xmax);
- static const uint8_t buttonD_sequence[] = {
- U8G_ESC_ADR(0), LCD_COLUMN, U8G_ESC_ADR(1), U8G_ESC_DATA(14), U8G_ESC_DATA(77),
- U8G_ESC_ADR(0), LCD_ROW, U8G_ESC_ADR(1), U8G_ESC_DATA(185), U8G_ESC_DATA(224),
- U8G_ESC_ADR(0), LCD_WRITE_RAM, U8G_ESC_ADR(1),
- U8G_ESC_END
- };
+ LCD_IO_WriteReg(ILI9328_HASET);
+ LCD_IO_WriteData(Ymin);
+ LCD_IO_WriteReg(ILI9328_VASET);
+ LCD_IO_WriteData(Xmin);
- static const uint8_t buttonA_sequence[] = {
- U8G_ESC_ADR(0), LCD_COLUMN, U8G_ESC_ADR(1), U8G_ESC_DATA(90), U8G_ESC_DATA(153),
- U8G_ESC_ADR(0), LCD_ROW, U8G_ESC_ADR(1), U8G_ESC_DATA(185), U8G_ESC_DATA(224),
- U8G_ESC_ADR(0), LCD_WRITE_RAM, U8G_ESC_ADR(1),
- U8G_ESC_END
- };
+ LCD_IO_WriteReg(ILI9328_WRITE_RAM);
+ #else
+ u8g_SetAddress(u8g, dev, 0);
- static const uint8_t buttonB_sequence[] = {
- U8G_ESC_ADR(0), LCD_COLUMN, U8G_ESC_ADR(1), U8G_ESC_DATA(166), U8G_ESC_DATA(229),
- U8G_ESC_ADR(0), LCD_ROW, U8G_ESC_ADR(1), U8G_ESC_DATA(185), U8G_ESC_DATA(224),
- U8G_ESC_ADR(0), LCD_WRITE_RAM, U8G_ESC_ADR(1),
- U8G_ESC_END
- };
+ u8g_WriteByte(u8g, dev, ILI9328_HASTART);
+ u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Ymin);
+ u8g_WriteByte(u8g, dev, ILI9328_HAEND);
+ u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Ymax);
+ u8g_WriteByte(u8g, dev, ILI9328_VASTART);
+ u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Xmin);
+ u8g_WriteByte(u8g, dev, ILI9328_VAEND);
+ u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Xmax);
- static const uint8_t buttonC_sequence[] = {
- U8G_ESC_ADR(0), LCD_COLUMN, U8G_ESC_ADR(1), U8G_ESC_DATA(242), U8G_ESC_DATA(305),
- U8G_ESC_ADR(0), LCD_ROW, U8G_ESC_ADR(1), U8G_ESC_DATA(185), U8G_ESC_DATA(224),
- U8G_ESC_ADR(0), LCD_WRITE_RAM, U8G_ESC_ADR(1),
- U8G_ESC_END
- };
+ u8g_WriteByte(u8g, dev, ILI9328_HASET);
+ u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Ymin);
+ u8g_WriteByte(u8g, dev, ILI9328_VASET);
+ u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Xmin);
+ u8g_WriteByte(u8g, dev, ILI9328_WRITE_RAM);
+ u8g_SetAddress(u8g, dev, 1);
+ #endif
+}
+
+static void setWindow_st7789v(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) {
+ #ifdef LCD_USE_DMA_FSMC
+ LCD_IO_WriteReg(ST7789V_CASET);
+ LCD_IO_WriteData((Xmin >> 8) & 0xFF);
+ LCD_IO_WriteData(Xmin & 0xFF);
+ LCD_IO_WriteData((Xmax >> 8) & 0xFF);
+ LCD_IO_WriteData(Xmax & 0xFF);
+
+ LCD_IO_WriteReg(ST7789V_RASET);
+ LCD_IO_WriteData((Ymin >> 8) & 0xFF);
+ LCD_IO_WriteData(Ymin & 0xFF);
+ LCD_IO_WriteData((Ymax >> 8) & 0xFF);
+ LCD_IO_WriteData(Ymax & 0xFF);
+
+ LCD_IO_WriteReg(ST7789V_WRITE_RAM);
+ #else
+ u8g_SetAddress(u8g, dev, 0); u8g_WriteByte(u8g, dev, ST7789V_CASET); u8g_SetAddress(u8g, dev, 1);
+ u8g_WriteByte(u8g, dev, (Xmin >> 8) & 0xFF);
+ u8g_WriteByte(u8g, dev, Xmin & 0xFF);
+ u8g_WriteByte(u8g, dev, (Xmax >> 8) & 0xFF);
+ u8g_WriteByte(u8g, dev, Xmax & 0xFF);
+
+ u8g_SetAddress(u8g, dev, 0); u8g_WriteByte(u8g, dev, ST7789V_RASET); u8g_SetAddress(u8g, dev, 1);
+ u8g_WriteByte(u8g, dev, (Ymin >> 8) & 0xFF);
+ u8g_WriteByte(u8g, dev, Ymin & 0xFF);
+ u8g_WriteByte(u8g, dev, (Ymax >> 8) & 0xFF);
+ u8g_WriteByte(u8g, dev, Ymax & 0xFF);
+
+ u8g_SetAddress(u8g, dev, 0); u8g_WriteByte(u8g, dev, ST7789V_WRITE_RAM); u8g_SetAddress(u8g, dev, 1);
+ #endif
+}
+
+static void setWindow_none(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) {}
+void (*setWindow)(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) = setWindow_none;
+
+
+#define ESC_REG(x) 0xFFFF, 0x00FF & (uint16_t)x
+#define ESC_DELAY(x) 0xFFFF, 0x8000 | (x & 0x7FFF)
+#define ESC_END 0xFFFF, 0x7FFF
+#define ESC_FFFF 0xFFFF, 0xFFFF
+
+#ifdef LCD_USE_DMA_FSMC
+ void writeEscSequence(const uint16_t *sequence) {
+ uint16_t data;
+ for (;;) {
+ data = *sequence++;
+ if (data != 0xFFFF) {
+ LCD_IO_WriteData(data);
+ continue;
+ }
+ data = *sequence++;
+ if (data == 0x7FFF) return;
+ if (data == 0xFFFF) {
+ LCD_IO_WriteData(data);
+ } else if (data & 0x8000) {
+ delay(data & 0x7FFF);
+ } else if ((data & 0xFF00) == 0) {
+ LCD_IO_WriteReg(data);
+ }
+ }
+ }
+#else
+ void writeEscSequence8(u8g_t *u8g, u8g_dev_t *dev, const uint16_t *sequence) {
+ uint16_t data;
+ u8g_SetAddress(u8g, dev, 1);
+ for (;;) {
+ data = *sequence++;
+ if (data != 0xFFFF) {
+ u8g_WriteByte(u8g, dev, data & 0xFF);
+ continue;
+ }
+ data = *sequence++;
+ if (data == 0x7FFF) return;
+ if (data == 0xFFFF) {
+ u8g_WriteByte(u8g, dev, data & 0xFF);
+ } else if (data & 0x8000) {
+ delay(data & 0x7FFF);
+ } else if ((data & 0xFF00) == 0) {
+ u8g_SetAddress(u8g, dev, 0);
+ u8g_WriteByte(u8g, dev, data & 0xFF);
+ u8g_SetAddress(u8g, dev, 1);
+ }
+ }
+ }
+
+ void writeEscSequence16(u8g_t *u8g, u8g_dev_t *dev, const uint16_t *sequence) {
+ uint16_t data;
+ u8g_SetAddress(u8g, dev, 0);
+ for (;;) {
+ data = *sequence++;
+ if (data != 0xFFFF) {
+ u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&data);
+ continue;
+ }
+ data = *sequence++;
+ if (data == 0x7FFF) return;
+ if (data == 0xFFFF) {
+ u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&data);
+ } else if (data & 0x8000) {
+ delay(data & 0x7FFF);
+ } else if ((data & 0xFF00) == 0) {
+ u8g_WriteByte(u8g, dev, data & 0xFF);
+ }
+ }
+ u8g_SetAddress(u8g, dev, 1);
+ }
#endif
-static const uint8_t st7789v_init_sequence[] = { // 0x8552 - ST7789V
- U8G_ESC_ADR(0),
- 0x10,
- U8G_ESC_DLY(10),
- 0x01,
- U8G_ESC_DLY(100), U8G_ESC_DLY(100),
- 0x11,
- U8G_ESC_DLY(120),
- 0x36, U8G_ESC_ADR(1), 0xA0,
- U8G_ESC_ADR(0), 0x3A, U8G_ESC_ADR(1), 0x05,
- U8G_ESC_ADR(0), LCD_COLUMN, U8G_ESC_ADR(1), 0x00, 0x00, 0x01, 0x3F,
- U8G_ESC_ADR(0), LCD_ROW, U8G_ESC_ADR(1), 0x00, 0x00, 0x00, 0xEF,
- U8G_ESC_ADR(0), 0xB2, U8G_ESC_ADR(1), 0x0C, 0x0C, 0x00, 0x33, 0x33,
- U8G_ESC_ADR(0), 0xB7, U8G_ESC_ADR(1), 0x35,
- U8G_ESC_ADR(0), 0xBB, U8G_ESC_ADR(1), 0x1F,
- U8G_ESC_ADR(0), 0xC0, U8G_ESC_ADR(1), 0x2C,
- U8G_ESC_ADR(0), 0xC2, U8G_ESC_ADR(1), 0x01, 0xC3,
- U8G_ESC_ADR(0), 0xC4, U8G_ESC_ADR(1), 0x20,
- U8G_ESC_ADR(0), 0xC6, U8G_ESC_ADR(1), 0x0F,
- U8G_ESC_ADR(0), 0xD0, U8G_ESC_ADR(1), 0xA4, 0xA1,
- U8G_ESC_ADR(0), 0xE0, U8G_ESC_ADR(1), 0xD0, 0x08, 0x11, 0x08, 0x0C, 0x15, 0x39, 0x33, 0x50, 0x36, 0x13, 0x14, 0x29, 0x2D,
- U8G_ESC_ADR(0), 0xE1, U8G_ESC_ADR(1), 0xD0, 0x08, 0x10, 0x08, 0x06, 0x06, 0x39, 0x44, 0x51, 0x0B, 0x16, 0x14, 0x2F, 0x31,
- U8G_ESC_ADR(0), 0x29, 0x11, 0x35, U8G_ESC_ADR(1), 0x00,
- U8G_ESC_END
+static const uint16_t st7789v_init[] = {
+ ESC_REG(0x0010), ESC_DELAY(10),
+ ESC_REG(0x0001), ESC_DELAY(200),
+ ESC_REG(0x0011), ESC_DELAY(120),
+ ESC_REG(0x0036), 0x00A0,
+ ESC_REG(0x003A), 0x0055,
+ ESC_REG(0x002A), 0x0000, 0x0000, 0x0001, 0x003F,
+ ESC_REG(0x002B), 0x0000, 0x0000, 0x0000, 0x00EF,
+ ESC_REG(0x00B2), 0x000C, 0x000C, 0x0000, 0x0033, 0x0033,
+ ESC_REG(0x00B7), 0x0035,
+ ESC_REG(0x00BB), 0x001F,
+ ESC_REG(0x00C0), 0x002C,
+ ESC_REG(0x00C2), 0x0001, 0x00C3,
+ ESC_REG(0x00C4), 0x0020,
+ ESC_REG(0x00C6), 0x000F,
+ ESC_REG(0x00D0), 0x00A4, 0x00A1,
+ ESC_REG(0x0029),
+ ESC_REG(0x0011),
+ ESC_END
};
-static const uint8_t ili9341_init_sequence[] = { // 0x9341 - ILI9341
- U8G_ESC_ADR(0),
- 0x10,
- U8G_ESC_DLY(10),
- 0x01,
- U8G_ESC_DLY(100), U8G_ESC_DLY(100),
- 0x36, U8G_ESC_ADR(1), 0xE8,
- U8G_ESC_ADR(0), 0x3A, U8G_ESC_ADR(1), 0x55,
- U8G_ESC_ADR(0), LCD_COLUMN, U8G_ESC_ADR(1), 0x00, 0x00, 0x01, 0x3F,
- U8G_ESC_ADR(0), LCD_ROW, U8G_ESC_ADR(1), 0x00, 0x00, 0x00, 0xEF,
- U8G_ESC_ADR(0), 0xC5, U8G_ESC_ADR(1), 0x3E, 0x28,
- U8G_ESC_ADR(0), 0xC7, U8G_ESC_ADR(1), 0x86,
- U8G_ESC_ADR(0), 0xB1, U8G_ESC_ADR(1), 0x00, 0x18,
- U8G_ESC_ADR(0), 0xC0, U8G_ESC_ADR(1), 0x23,
- U8G_ESC_ADR(0), 0xC1, U8G_ESC_ADR(1), 0x10,
- U8G_ESC_ADR(0), 0x29,
- U8G_ESC_ADR(0), 0x11,
- U8G_ESC_DLY(100),
- U8G_ESC_END
+static const uint16_t ili9328_init[] = {
+ ESC_REG(0x0001), 0x0100,
+ ESC_REG(0x0002), 0x0400,
+ ESC_REG(0x0003), 0x1038,
+ ESC_REG(0x0004), 0x0000,
+ ESC_REG(0x0008), 0x0202,
+ ESC_REG(0x0009), 0x0000,
+ ESC_REG(0x000A), 0x0000,
+ ESC_REG(0x000C), 0x0000,
+ ESC_REG(0x000D), 0x0000,
+ ESC_REG(0x000F), 0x0000,
+ ESC_REG(0x0010), 0x0000,
+ ESC_REG(0x0011), 0x0007,
+ ESC_REG(0x0012), 0x0000,
+ ESC_REG(0x0013), 0x0000,
+ ESC_REG(0x0007), 0x0001,
+ ESC_DELAY(200),
+ ESC_REG(0x0010), 0x1690,
+ ESC_REG(0x0011), 0x0227,
+ ESC_DELAY(50),
+ ESC_REG(0x0012), 0x008C,
+ ESC_DELAY(50),
+ ESC_REG(0x0013), 0x1500,
+ ESC_REG(0x0029), 0x0004,
+ ESC_REG(0x002B), 0x000D,
+ ESC_DELAY(50),
+ ESC_REG(0x0050), 0x0000,
+ ESC_REG(0x0051), 0x00EF,
+ ESC_REG(0x0052), 0x0000,
+ ESC_REG(0x0053), 0x013F,
+ ESC_REG(0x0020), 0x0000,
+ ESC_REG(0x0021), 0x0000,
+ ESC_REG(0x0060), 0x2700,
+ ESC_REG(0x0061), 0x0001,
+ ESC_REG(0x006A), 0x0000,
+ ESC_REG(0x0080), 0x0000,
+ ESC_REG(0x0081), 0x0000,
+ ESC_REG(0x0082), 0x0000,
+ ESC_REG(0x0083), 0x0000,
+ ESC_REG(0x0084), 0x0000,
+ ESC_REG(0x0085), 0x0000,
+ ESC_REG(0x0090), 0x0010,
+ ESC_REG(0x0092), 0x0600,
+ ESC_REG(0x0007), 0x0133,
+ ESC_REG(0x0022),
+ ESC_END
+};
+
+static const uint16_t ili9341_init[] = {
+ ESC_REG(0x0010), ESC_DELAY(10),
+ ESC_REG(0x0001), ESC_DELAY(200),
+ ESC_REG(0x0036), 0x00E8,
+ ESC_REG(0x003A), 0x0055,
+ ESC_REG(0x002A), 0x0000, 0x0000, 0x0001, 0x003F,
+ ESC_REG(0x002B), 0x0000, 0x0000, 0x0000, 0x00EF,
+ ESC_REG(0x00C5), 0x003E, 0x0028,
+ ESC_REG(0x00C7), 0x0086,
+ ESC_REG(0x00B1), 0x0000, 0x0018,
+ ESC_REG(0x00C0), 0x0023,
+ ESC_REG(0x00C1), 0x0010,
+ ESC_REG(0x0029),
+ ESC_REG(0x0011),
+ ESC_DELAY(100),
+ ESC_END
};
#if ENABLED(TOUCH_BUTTONS)
@@ -439,23 +578,55 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u
switch (msg) {
case U8G_DEV_MSG_INIT:
dev->com_fn(u8g, U8G_COM_MSG_INIT, U8G_SPI_CLK_CYCLE_NONE, &lcd_id);
- if (lcd_id == 0x040404) return 0; // No connected display on FSMC
- if (lcd_id == 0xFFFFFF) return 0; // No connected display on SPI
- if ((lcd_id & 0xFFFF) == 0x8552) // ST7789V
- u8g_WriteEscSeqP(u8g, dev, st7789v_init_sequence);
- if ((lcd_id & 0xFFFF) == 0x9341) // ILI9341
- u8g_WriteEscSeqP(u8g, dev, ili9341_init_sequence);
+ switch(lcd_id & 0xFFFF) {
+ case 0x8552: // ST7789V
+ #ifdef LCD_USE_DMA_FSMC
+ writeEscSequence(st7789v_init);
+ #else
+ writeEscSequence8(u8g, dev, st7789v_init);
+ #endif
+ setWindow = setWindow_st7789v;
+ break;
+ case 0x9328: // ILI9328
+ #ifdef LCD_USE_DMA_FSMC
+ writeEscSequence(ili9328_init);
+ #else
+ writeEscSequence16(u8g, dev, ili9328_init);
+ #endif
+ setWindow = setWindow_ili9328;
+ break;
+ case 0x9341: // ILI9341
+ #ifdef LCD_USE_DMA_FSMC
+ writeEscSequence(ili9341_init);
+ #else
+ writeEscSequence8(u8g, dev, ili9341_init);
+ #endif
+ setWindow = setWindow_st7789v;
+ break;
+ case 0x0404: // No connected display on FSMC
+ lcd_id = 0;
+ return 0;
+ case 0xFFFF: // No connected display on SPI
+ lcd_id = 0;
+ return 0;
+ default:
+ if (lcd_id && 0xFF000000)
+ setWindow = setWindow_st7789v;
+ else
+ setWindow = setWindow_ili9328;
+ break;
+ }
if (preinit) {
preinit = false;
return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg);
}
- // Clear Screen Sequence
- u8g_WriteEscSeqP(u8g, dev, clear_screen_sequence);
+ // Clear Screen
+ setWindow(u8g, dev, 0, 0, LCD_FULL_PIXEL_WIDTH - 1, LCD_FULL_PIXEL_HEIGHT - 1);
#ifdef LCD_USE_DMA_FSMC
- LCD_IO_WriteMultiple(TFT_MARLINBG_COLOR, (320*240));
+ LCD_IO_WriteMultiple(TFT_MARLINBG_COLOR, LCD_FULL_PIXEL_WIDTH * LCD_FULL_PIXEL_HEIGHT);
#else
memset2(buffer, TFT_MARLINBG_COLOR, 160);
for (uint16_t i = 0; i < 960; i++)
@@ -465,31 +636,25 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u
// bottom line and buttons
#if ENABLED(TOUCH_BUTTONS)
+ setWindow(u8g, dev, 10, 170, 309, 171);
#ifdef LCD_USE_DMA_FSMC
- u8g_WriteEscSeqP(u8g, dev, separation_line_sequence_left);
- LCD_IO_WriteMultiple(TFT_DISABLED_COLOR, 300);
- u8g_WriteEscSeqP(u8g, dev, separation_line_sequence_right);
- LCD_IO_WriteMultiple(TFT_DISABLED_COLOR, 300);
+ LCD_IO_WriteMultiple(TFT_DISABLED_COLOR, 600);
#else
memset2(buffer, TFT_DISABLED_COLOR, 150);
- u8g_WriteEscSeqP(u8g, dev, separation_line_sequence_left);
- for (uint8_t i = 4; i--;)
- u8g_WriteSequence(u8g, dev, 150, (uint8_t *)buffer);
- u8g_WriteEscSeqP(u8g, dev, separation_line_sequence_right);
- for (uint8_t i = 4; i--;)
+ for (uint8_t i = 8; i--;)
u8g_WriteSequence(u8g, dev, 150, (uint8_t *)buffer);
#endif
- u8g_WriteEscSeqP(u8g, dev, buttonD_sequence);
+ setWindow(u8g, dev, 14, 185, 77, 224);
drawImage(buttonD, u8g, dev, 32, 20, TFT_BTCANCEL_COLOR);
- u8g_WriteEscSeqP(u8g, dev, buttonA_sequence);
+ setWindow(u8g, dev, 90, 185, 153, 224);
drawImage(buttonA, u8g, dev, 32, 20, TFT_BTARROWS_COLOR);
- u8g_WriteEscSeqP(u8g, dev, buttonB_sequence);
+ setWindow(u8g, dev, 166, 185, 229, 224);
drawImage(buttonB, u8g, dev, 32, 20, TFT_BTARROWS_COLOR);
- u8g_WriteEscSeqP(u8g, dev, buttonC_sequence);
+ setWindow(u8g, dev, 242, 185, 305, 224);
drawImage(buttonC, u8g, dev, 32, 20, TFT_BTOKMENU_COLOR);
#endif // TOUCH_BUTTONS
@@ -499,7 +664,7 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u
case U8G_DEV_MSG_PAGE_FIRST:
page = 0;
- u8g_WriteEscSeqP(u8g, dev, page_first_sequence);
+ setWindow(u8g, dev, X_LO, Y_LO, X_HI, Y_HI);
break;
case U8G_DEV_MSG_PAGE_NEXT:
diff --git a/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp b/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp
index 7f9376fbc1..ae9614d677 100644
--- a/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp
+++ b/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp
@@ -244,48 +244,51 @@ bool MarlinUI::detected() { return true; }
// Initialize or re-initialize the LCD
void MarlinUI::init_lcd() {
+ #if DISABLED(MKS_LCD12864B)
- #if PIN_EXISTS(LCD_BACKLIGHT)
- OUT_WRITE(LCD_BACKLIGHT_PIN, (
- #if ENABLED(DELAYED_BACKLIGHT_INIT)
- LOW // Illuminate after reset
- #else
- HIGH // Illuminate right away
- #endif
- ));
- #endif
-
- #if EITHER(MKS_12864OLED, MKS_12864OLED_SSD1306)
- SET_OUTPUT(LCD_PINS_DC);
- #ifndef LCD_RESET_PIN
- #define LCD_RESET_PIN LCD_PINS_RS
+ #if PIN_EXISTS(LCD_BACKLIGHT)
+ OUT_WRITE(LCD_BACKLIGHT_PIN, (
+ #if ENABLED(DELAYED_BACKLIGHT_INIT)
+ LOW // Illuminate after reset
+ #else
+ HIGH // Illuminate right away
+ #endif
+ ));
#endif
- #endif
- #if PIN_EXISTS(LCD_RESET)
- // Perform a clean hardware reset with needed delays
- OUT_WRITE(LCD_RESET_PIN, LOW);
- _delay_ms(5);
- WRITE(LCD_RESET_PIN, HIGH);
- _delay_ms(5);
- u8g.begin();
- #endif
+ #if EITHER(MKS_12864OLED, MKS_12864OLED_SSD1306)
+ SET_OUTPUT(LCD_PINS_DC);
+ #ifndef LCD_RESET_PIN
+ #define LCD_RESET_PIN LCD_PINS_RS
+ #endif
+ #endif
- #if PIN_EXISTS(LCD_BACKLIGHT) && ENABLED(DELAYED_BACKLIGHT_INIT)
- WRITE(LCD_BACKLIGHT_PIN, HIGH);
- #endif
+ #if PIN_EXISTS(LCD_RESET)
+ // Perform a clean hardware reset with needed delays
+ OUT_WRITE(LCD_RESET_PIN, LOW);
+ _delay_ms(5);
+ WRITE(LCD_RESET_PIN, HIGH);
+ _delay_ms(5);
+ u8g.begin();
+ #endif
- #if HAS_LCD_CONTRAST
- refresh_contrast();
- #endif
+ #if PIN_EXISTS(LCD_BACKLIGHT) && ENABLED(DELAYED_BACKLIGHT_INIT)
+ WRITE(LCD_BACKLIGHT_PIN, HIGH);
+ #endif
- #if ENABLED(LCD_SCREEN_ROT_90)
- u8g.setRot90();
- #elif ENABLED(LCD_SCREEN_ROT_180)
- u8g.setRot180();
- #elif ENABLED(LCD_SCREEN_ROT_270)
- u8g.setRot270();
- #endif
+ #if HAS_LCD_CONTRAST
+ refresh_contrast();
+ #endif
+
+ #if ENABLED(LCD_SCREEN_ROT_90)
+ u8g.setRot90();
+ #elif ENABLED(LCD_SCREEN_ROT_180)
+ u8g.setRot180();
+ #elif ENABLED(LCD_SCREEN_ROT_270)
+ u8g.setRot270();
+ #endif
+
+ #endif // !MKS_LCD12864B
uxg_SetUtf8Fonts(g_fontinfo, COUNT(g_fontinfo));
}
@@ -300,8 +303,8 @@ void MarlinUI::draw_kill_screen() {
do {
set_font(FONT_MENU);
lcd_put_u8str(0, h4 * 1, status_message);
- lcd_put_u8str_P(0, h4 * 2, PSTR(MSG_HALTED));
- lcd_put_u8str_P(0, h4 * 3, PSTR(MSG_PLEASE_RESET));
+ lcd_put_u8str_P(0, h4 * 2, GET_TEXT(MSG_HALTED));
+ lcd_put_u8str_P(0, h4 * 3, GET_TEXT(MSG_PLEASE_RESET));
} while (u8g.nextPage());
}
@@ -363,9 +366,9 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
}
// Draw a static line of text in the same idiom as a menu item
- void draw_menu_item_static(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_CENTER*/, const char * const valstr/*=nullptr*/) {
+ void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const valstr/*=nullptr*/) {
- if (mark_as_selected(row, (style & SS_INVERT))) {
+ if (mark_as_selected(row, style & SS_INVERT)) {
u8g_uint_t n = LCD_PIXEL_WIDTH; // pixel width of string allowed
@@ -373,19 +376,16 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
int8_t pad = (LCD_WIDTH - utf8_strlen_P(pstr)) / 2;
while (--pad >= 0) { lcd_put_wchar(' '); n--; }
}
- n -= lcd_put_u8str_max_P(pstr, n);
+ n = lcd_put_u8str_ind_P(pstr, itemIndex, LCD_WIDTH) * (MENU_FONT_WIDTH);
if (valstr) n -= lcd_put_u8str_max(valstr, n);
while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' ');
}
}
// Draw a generic menu item
- void draw_menu_item(const bool sel, const uint8_t row, PGM_P const pstr, const char pre_char, const char post_char) {
- UNUSED(pre_char);
-
+ void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, const char, const char post_char) {
if (mark_as_selected(row, sel)) {
- u8g_uint_t n = (LCD_WIDTH - 2) * (MENU_FONT_WIDTH);
- n -= lcd_put_u8str_max_P(pstr, n);
+ u8g_uint_t n = lcd_put_u8str_ind_P(pstr, itemIndex, LCD_WIDTH - 2) * (MENU_FONT_WIDTH);
while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' ');
lcd_put_wchar(LCD_PIXEL_WIDTH - (MENU_FONT_WIDTH), row_y2, post_char);
lcd_put_wchar(' ');
@@ -393,19 +393,20 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
}
// Draw a menu item with an editable value
- void _draw_menu_item_edit(const bool sel, const uint8_t row, PGM_P const pstr, const char* const data, const bool pgm) {
+ void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char* const data, const bool pgm) {
if (mark_as_selected(row, sel)) {
const uint8_t vallen = (pgm ? utf8_strlen_P(data) : utf8_strlen((char*)data));
- u8g_uint_t n = (LCD_WIDTH - 2 - vallen) * (MENU_FONT_WIDTH);
- n -= lcd_put_u8str_max_P(pstr, n);
- lcd_put_wchar(':');
- while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' ');
- lcd_moveto(LCD_PIXEL_WIDTH - (MENU_FONT_WIDTH) * vallen, row_y2);
- if (pgm) lcd_put_u8str_P(data); else lcd_put_u8str((char*)data);
+ u8g_uint_t n = lcd_put_u8str_ind_P(pstr, itemIndex, LCD_WIDTH - 2 - vallen) * (MENU_FONT_WIDTH);
+ if (vallen) {
+ lcd_put_wchar(':');
+ while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' ');
+ lcd_moveto(LCD_PIXEL_WIDTH - (MENU_FONT_WIDTH) * vallen, row_y2);
+ if (pgm) lcd_put_u8str_P(data); else lcd_put_u8str((char*)data);
+ }
}
}
- void draw_edit_screen(PGM_P const pstr, const char* const value/*=nullptr*/) {
+ void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char* const value/*=nullptr*/) {
ui.encoder_direction_normal();
const u8g_uint_t labellen = utf8_strlen_P(pstr), vallen = utf8_strlen(value);
@@ -437,7 +438,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
// Assume the label is alpha-numeric (with a descender)
bool onpage = PAGE_CONTAINS(baseline - (EDIT_FONT_ASCENT - 1), baseline + EDIT_FONT_DESCENT);
- if (onpage) lcd_put_u8str_P(0, baseline, pstr);
+ if (onpage) lcd_put_u8str_ind_P(0, baseline, pstr, itemIndex);
// If a value is included, print a colon, then print the value right-justified
if (value != nullptr) {
@@ -466,7 +467,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
if (inv) u8g.setColorIndex(1);
}
- void draw_select_screen(PGM_P const yes, PGM_P const no, const bool yesno, PGM_P const pref, const char * const string, PGM_P const suff) {
+ void MenuItem_confirm::draw_select_screen(PGM_P const yes, PGM_P const no, const bool yesno, PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/) {
ui.draw_select_screen_prompt(pref, string, suff);
draw_boxed_string(1, LCD_HEIGHT - 1, no, !yesno);
draw_boxed_string(LCD_WIDTH - (utf8_strlen_P(yes) + 1), LCD_HEIGHT - 1, yes, yesno);
@@ -474,9 +475,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
#if ENABLED(SDSUPPORT)
- void draw_sd_menu_item(const bool sel, const uint8_t row, PGM_P const pstr, CardReader &theCard, const bool isDir) {
- UNUSED(pstr);
-
+ void MenuItem_sdbase::draw(const bool sel, const uint8_t row, PGM_P const, CardReader &theCard, const bool isDir) {
if (mark_as_selected(row, sel)) {
if (isDir) lcd_put_wchar(LCD_STR_FOLDER[0]);
constexpr uint8_t maxlen = LCD_WIDTH - 1;
@@ -578,20 +577,20 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
#if EITHER(BABYSTEP_ZPROBE_GFX_OVERLAY, MESH_EDIT_GFX_OVERLAY)
const unsigned char cw_bmp[] PROGMEM = {
- B00000001,B11111100,B00000000,
- B00000111,B11111111,B00000000,
- B00001111,B00000111,B10000000,
- B00001110,B00000001,B11000000,
- B00000000,B00000001,B11000000,
+ B00000000,B11111110,B00000000,
+ B00000011,B11111111,B10000000,
+ B00000111,B11000111,B11000000,
+ B00000111,B00000001,B11100000,
B00000000,B00000000,B11100000,
- B00001000,B00000000,B11100000,
- B00011100,B00000000,B11100000,
- B00111110,B00000000,B11100000,
- B01111111,B00000000,B11100000,
- B00011100,B00000000,B11100000,
+ B00000000,B00000000,B11110000,
+ B00000000,B00000000,B01110000,
+ B00000100,B00000000,B01110000,
+ B00001110,B00000000,B01110000,
+ B00011111,B00000000,B01110000,
+ B00111111,B10000000,B11110000,
B00001110,B00000000,B11100000,
- B00001110,B00000001,B11000000,
- B00000111,B10000011,B11000000,
+ B00001111,B00000001,B11100000,
+ B00000111,B11000111,B11000000,
B00000011,B11111111,B10000000,
B00000000,B11111110,B00000000
};
@@ -599,20 +598,20 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
const unsigned char ccw_bmp[] PROGMEM = {
B00000000,B11111110,B00000000,
B00000011,B11111111,B10000000,
- B00000111,B10000011,B11000000,
- B00001110,B00000001,B11000000,
+ B00000111,B11000111,B11000000,
+ B00001111,B00000001,B11100000,
B00001110,B00000000,B11100000,
- B00011100,B00000000,B11100000,
- B01111111,B00000000,B11100000,
- B00111110,B00000000,B11100000,
- B00011100,B00000000,B11100000,
- B00001000,B00000000,B11100000,
+ B00111111,B10000000,B11110000,
+ B00011111,B00000000,B01110000,
+ B00001110,B00000000,B01110000,
+ B00000100,B00000000,B01110000,
+ B00000000,B00000000,B01110000,
+ B00000000,B00000000,B11110000,
B00000000,B00000000,B11100000,
- B00000000,B00000001,B11000000,
- B00001110,B00000001,B11000000,
- B00001111,B00000111,B10000000,
- B00000111,B11111111,B00000000,
- B00000001,B11111100,B00000000
+ B00000111,B00000001,B11100000,
+ B00000111,B11000111,B11000000,
+ B00000011,B11111111,B10000000,
+ B00000000,B11111110,B00000000
};
const unsigned char up_arrow_bmp[] PROGMEM = {
diff --git a/Marlin/src/lcd/dogm/ultralcd_DOGM.h b/Marlin/src/lcd/dogm/ultralcd_DOGM.h
index e8d1b8a1e3..8ff2dbc85b 100644
--- a/Marlin/src/lcd/dogm/ultralcd_DOGM.h
+++ b/Marlin/src/lcd/dogm/ultralcd_DOGM.h
@@ -82,7 +82,7 @@
// MaKrPanel, Mini Viki, Viki 2.0, AZSMZ 12864 ST7565 controller
- #define SMART_RAMPS (MB(RAMPS_SMART_EFB) || MB(RAMPS_SMART_EEB) || MB(RAMPS_SMART_EFF) || MB(RAMPS_SMART_EEF) || MB(RAMPS_SMART_SF))
+ #define SMART_RAMPS MB(RAMPS_SMART_EFB, RAMPS_SMART_EEB, RAMPS_SMART_EFF, RAMPS_SMART_EEF, RAMPS_SMART_SF)
#define U8G_CLASS U8GLIB_64128N_2X_HAL // 4 stripes (HW-SPI)
#if SMART_RAMPS || DOGLCD_SCK != SCK_PIN || DOGLCD_MOSI != MOSI_PIN
#define FORCE_SOFT_SPI // SW-SPI
diff --git a/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp b/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp
index 2187185146..8c4d1cf297 100644
--- a/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp
+++ b/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp
@@ -25,7 +25,7 @@
#include "../../inc/MarlinConfigPre.h"
-#if !defined(U8G_HAL_LINKS) && ANY(__AVR__, ARDUINO_ARCH_STM32)
+#if !defined(U8G_HAL_LINKS) && ANY(__AVR__, ARDUINO_ARCH_STM32, ARDUINO_ARCH_ESP32)
#include "../../inc/MarlinConfig.h"
diff --git a/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.h b/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.h
index 960375ae43..858cbe8824 100644
--- a/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.h
+++ b/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.h
@@ -49,11 +49,11 @@
#define CPU_ST7920_DELAY_1 DELAY_NS(0)
#define CPU_ST7920_DELAY_2 DELAY_NS(0)
#define CPU_ST7920_DELAY_3 DELAY_NS(50)
-#elif MB(3DRAG) || MB(K8200) || MB(K8400) || MB(SILVER_GATE)
+#elif MB(3DRAG, K8200, K8400, SILVER_GATE)
#define CPU_ST7920_DELAY_1 DELAY_NS(0)
#define CPU_ST7920_DELAY_2 DELAY_NS(188)
#define CPU_ST7920_DELAY_3 DELAY_NS(0)
-#elif MB(MINIRAMBO) || MB(EINSY_RAMBO) || MB(EINSY_RETRO)
+#elif MB(MINIRAMBO, EINSY_RAMBO, EINSY_RETRO)
#define CPU_ST7920_DELAY_1 DELAY_NS(0)
#define CPU_ST7920_DELAY_2 DELAY_NS(250)
#define CPU_ST7920_DELAY_3 DELAY_NS(0)
diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.cpp b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.cpp
index 1fb3783b2d..a9ba108e14 100644
--- a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.cpp
+++ b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.cpp
@@ -32,7 +32,7 @@
#include "../../ui_api.h"
-#include "../../../../Marlin.h"
+#include "../../../../MarlinCore.h"
#include "../../../../module/temperature.h"
#include "../../../../module/motion.h"
#include "../../../../gcode/queue.h"
@@ -289,11 +289,11 @@ void DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM(DGUS_VP_Variable
// Don't let the user in the dark why there is no reaction.
if (!ExtUI::isMediaInserted()) {
- setstatusmessagePGM(PSTR(MSG_NO_MEDIA));
+ setstatusmessagePGM(GET_TEXT(MSG_NO_MEDIA));
return;
}
if (card.flag.abort_sd_printing) {
- setstatusmessagePGM(PSTR(MSG_MEDIA_ABORTING));
+ setstatusmessagePGM(GET_TEXT(MSG_MEDIA_ABORTING));
return;
}
}
@@ -472,13 +472,13 @@ void DGUSScreenVariableHandler::HandleTemperatureChanged(DGUS_VP_Variable &var,
switch (var.VP) {
default: return;
#if HOTENDS >= 1
- case VP_T_E1_Set:
+ case VP_T_E0_Set:
thermalManager.setTargetHotend(newvalue, 0);
acceptedvalue = thermalManager.temp_hotend[0].target;
break;
#endif
#if HOTENDS >= 2
- case VP_T_E2_Set:
+ case VP_T_E1_Set:
thermalManager.setTargetHotend(newvalue, 1);
acceptedvalue = thermalManager.temp_hotend[1].target;
break;
@@ -503,10 +503,10 @@ void DGUSScreenVariableHandler::HandleFlowRateChanged(DGUS_VP_Variable &var, voi
switch (var.VP) {
default: return;
#if (HOTENDS >= 1)
- case VP_Flowrate_E1: target_extruder = 0; break;
+ case VP_Flowrate_E0: target_extruder = 0; break;
#endif
#if (HOTENDS >= 2)
- case VP_Flowrate_E2: target_extruder = 1; break;
+ case VP_Flowrate_E1: target_extruder = 1; break;
#endif
}
@@ -526,11 +526,11 @@ void DGUSScreenVariableHandler::HandleManualExtrude(DGUS_VP_Variable &var, void
ExtUI::extruder_t target_extruder;
switch (var.VP) {
- #if HOTENDS >=1
- case VP_MOVE_E1: target_extruder = ExtUI::extruder_t::E0; break;
+ #if HOTENDS >= 1
+ case VP_MOVE_E0: target_extruder = ExtUI::extruder_t::E0; break;
#endif
- #if HOTENDS >=2
- case VP_MOVE_E2: target_extruder = ExtUI::extruder_t::E1; break
+ #if HOTENDS >= 2
+ case VP_MOVE_E1: target_extruder = ExtUI::extruder_t::E1; break
#endif
default: return;
}
diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.h b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.h
index 46d451a1d9..91a92c7482 100644
--- a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.h
+++ b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplay.h
@@ -25,7 +25,7 @@
#include "../../../../inc/MarlinConfigPre.h"
-#include "../../../../Marlin.h"
+#include "../../../../MarlinCore.h"
#include "DGUSVPVariable.h"
enum DGUSLCD_Screens : uint8_t;
diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinition.cpp b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinition.cpp
index bc1296f2f5..de15d54597 100644
--- a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinition.cpp
+++ b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinition.cpp
@@ -46,10 +46,10 @@ const uint16_t VPList_Main[] PROGMEM = {
const uint16_t VPList_Temp[] PROGMEM = {
#if HOTENDS >= 1
- VP_T_E1_Is, VP_T_E1_Set,
+ VP_T_E0_Is, VP_T_E0_Set,
#endif
#if HOTENDS >= 2
- VP_T_E2_I, VP_T_E2_S,
+ VP_T_E1_I, VP_T_E1_S,
#endif
#if HAS_HEATED_BED
VP_T_Bed_Is, VP_T_Bed_Set,
@@ -60,10 +60,10 @@ const uint16_t VPList_Temp[] PROGMEM = {
const uint16_t VPList_Status[] PROGMEM = {
/* VP_M117, for completeness, but it cannot be auto-uploaded */
#if HOTENDS >= 1
- VP_T_E1_Is, VP_T_E1_Set,
+ VP_T_E0_Is, VP_T_E0_Set,
#endif
#if HOTENDS >= 2
- VP_T_E2_I, VP_T_E2_S,
+ VP_T_E1_I, VP_T_E1_S,
#endif
#if HAS_HEATED_BED
VP_T_Bed_Is, VP_T_Bed_Set,
@@ -81,10 +81,10 @@ const uint16_t VPList_Status[] PROGMEM = {
const uint16_t VPList_Status2[] PROGMEM = {
/* VP_M117, for completeness, but it cannot be auto-uploaded */
#if HOTENDS >= 1
- VP_Flowrate_E1,
+ VP_Flowrate_E0,
#endif
#if HOTENDS >= 2
- VP_Flowrate_E2,
+ VP_Flowrate_E1,
#endif
VP_PrintProgress_Percentage,
VP_PrintTime,
@@ -107,7 +107,7 @@ const uint16_t VPList_FanAndFeedrate[] PROGMEM = {
};
const uint16_t VPList_SD_FlowRates[] PROGMEM = {
- VP_Flowrate_E1, VP_Flowrate_E2,
+ VP_Flowrate_E0, VP_Flowrate_E1,
0x0000
};
@@ -166,17 +166,17 @@ const struct DGUS_VP_Variable ListOfVP[] PROGMEM = {
// Temperature Data
#if HOTENDS >= 1
- VPHELPER(VP_T_E1_Is, &thermalManager.temp_hotend[0].celsius, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<0>),
- VPHELPER(VP_T_E1_Set, &thermalManager.temp_hotend[0].target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
- VPHELPER(VP_Flowrate_E1, nullptr, DGUSScreenVariableHandler::HandleFlowRateChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
+ VPHELPER(VP_T_E0_Is, &thermalManager.temp_hotend[0].celsius, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<0>),
+ VPHELPER(VP_T_E0_Set, &thermalManager.temp_hotend[0].target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
+ VPHELPER(VP_Flowrate_E0, nullptr, DGUSScreenVariableHandler::HandleFlowRateChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
VPHELPER(VP_EPos, &destination.e, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>),
- VPHELPER(VP_MOVE_E1, nullptr, &DGUSScreenVariableHandler::HandleManualExtrude, nullptr),
+ VPHELPER(VP_MOVE_E0, nullptr, &DGUSScreenVariableHandler::HandleManualExtrude, nullptr),
#endif
#if HOTENDS >= 2
- VPHELPER(VP_T_E2_I, &thermalManager.temp_hotend[1].celsius, nullptr, DGUSLCD_SendFloatAsLongValueToDisplay<0>),
- VPHELPER(VP_T_E2_S, &thermalManager.temp_hotend[1].target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
- VPHELPER(VP_Flowrate_E2, nullptr, DGUSScreenVariableHandler::HandleFlowRateChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
- VPHELPER(VP_MOVE_E2, nullptr, &DGUSScreenVariableHandler::HandleManualExtrude, nullptr),
+ VPHELPER(VP_T_E1_I, &thermalManager.temp_hotend[1].celsius, nullptr, DGUSLCD_SendFloatAsLongValueToDisplay<0>),
+ VPHELPER(VP_T_E1_S, &thermalManager.temp_hotend[1].target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
+ VPHELPER(VP_Flowrate_E1, nullptr, DGUSScreenVariableHandler::HandleFlowRateChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
+ VPHELPER(VP_MOVE_E1, nullptr, &DGUSScreenVariableHandler::HandleManualExtrude, nullptr),
#endif
#if HOTENDS >= 3
#error More than 2 Hotends currently not implemented on the Display UI design.
@@ -200,7 +200,7 @@ const struct DGUS_VP_Variable ListOfVP[] PROGMEM = {
VPHELPER(VP_ZPos, ¤t_position.z, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>),
// Print Progress.
- VPHELPER(VP_PrintProgress_Percentage, &ui.progress_bar_percent, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay ),
+ VPHELPER(VP_PrintProgress_Percentage, &ui.progress_override, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay ),
// Print Time
VPHELPER_STR(VP_PrintTime, nullptr, VP_PrintTime_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintTimeToDisplay ),
diff --git a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinition.h b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinition.h
index f54a2938ec..f90cfa948b 100644
--- a/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinition.h
+++ b/Marlin/src/lcd/extensible_ui/lib/dgus/DGUSDisplayDefinition.h
@@ -109,12 +109,12 @@ constexpr uint16_t VP_SD_AbortPrintConfirmed = 0x2028; // Abort print confirmati
constexpr uint16_t VP_MOVE_X = 0x2100;
constexpr uint16_t VP_MOVE_Y = 0x2102;
constexpr uint16_t VP_MOVE_Z = 0x2104;
-constexpr uint16_t VP_MOVE_E1 = 0x2110;
-constexpr uint16_t VP_MOVE_E2 = 0x2112;
-//constexpr uint16_t VP_MOVE_E3 = 0x2114;
-//constexpr uint16_t VP_MOVE_E4 = 0x2116;
-//constexpr uint16_t VP_MOVE_E5 = 0x2118;
-//constexpr uint16_t VP_MOVE_E6 = 0x211A;
+constexpr uint16_t VP_MOVE_E0 = 0x2110;
+constexpr uint16_t VP_MOVE_E1 = 0x2112;
+//constexpr uint16_t VP_MOVE_E2 = 0x2114;
+//constexpr uint16_t VP_MOVE_E3 = 0x2116;
+//constexpr uint16_t VP_MOVE_E4 = 0x2118;
+//constexpr uint16_t VP_MOVE_E5 = 0x211A;
constexpr uint16_t VP_HOME_ALL = 0x2120;
// Firmware version on the boot screen.
@@ -126,34 +126,34 @@ constexpr uint16_t VP_M117 = 0x3020;
constexpr uint8_t VP_M117_LEN = 0x20;
// Temperatures.
-constexpr uint16_t VP_T_E1_Is = 0x3060; // 4 Byte Integer
-constexpr uint16_t VP_T_E1_Set = 0x3062; // 2 Byte Integer
-constexpr uint16_t VP_T_E2_Is = 0x3064; // 4 Byte Integer
+constexpr uint16_t VP_T_E0_Is = 0x3060; // 4 Byte Integer
+constexpr uint16_t VP_T_E0_Set = 0x3062; // 2 Byte Integer
+constexpr uint16_t VP_T_E1_Is = 0x3064; // 4 Byte Integer
// reserved to support up to 6 Extruders:
-//constexpr uint16_t VP_T_E2_Set = 0x3066; // 2 Byte Integer
-//constexpr uint16_t VP_T_E3_Is = 0x3068; // 4 Byte Integer
-//constexpr uint16_t VP_T_E3_Set = 0x306A; // 2 Byte Integer
-//constexpr uint16_t VP_T_E4_Is = 0x306C; // 4 Byte Integer
-//constexpr uint16_t VP_T_E4_Set = 0x306E; // 2 Byte Integer
-//constexpr uint16_t VP_T_E5_Is = 0x3070; // 4 Byte Integer
-//constexpr uint16_t VP_T_E5_Set = 0x3072; // 2 Byte Integer
-//constexpr uint16_t VP_T_E5_Is = 0x3074; // 4 Byte Integer
-//constexpr uint16_t VP_T_E5_Set = 0x3076; // 2 Byte Integer
-//constexpr uint16_t VP_T_E6_Is = 0x3078; // 4 Byte Integer
-//constexpr uint16_t VP_T_E6_Set = 0x307A; // 2 Byte Integer
+//constexpr uint16_t VP_T_E1_Set = 0x3066; // 2 Byte Integer
+//constexpr uint16_t VP_T_E2_Is = 0x3068; // 4 Byte Integer
+//constexpr uint16_t VP_T_E2_Set = 0x306A; // 2 Byte Integer
+//constexpr uint16_t VP_T_E3_Is = 0x306C; // 4 Byte Integer
+//constexpr uint16_t VP_T_E3_Set = 0x306E; // 2 Byte Integer
+//constexpr uint16_t VP_T_E4_Is = 0x3070; // 4 Byte Integer
+//constexpr uint16_t VP_T_E4_Set = 0x3072; // 2 Byte Integer
+//constexpr uint16_t VP_T_E4_Is = 0x3074; // 4 Byte Integer
+//constexpr uint16_t VP_T_E4_Set = 0x3076; // 2 Byte Integer
+//constexpr uint16_t VP_T_E5_Is = 0x3078; // 4 Byte Integer
+//constexpr uint16_t VP_T_E5_Set = 0x307A; // 2 Byte Integer
constexpr uint16_t VP_T_Bed_Is = 0x3080; // 4 Byte Integer
constexpr uint16_t VP_T_Bed_Set = 0x3082; // 2 Byte Integer
-constexpr uint16_t VP_Flowrate_E1 = 0x3090; // 2 Byte Integer
-constexpr uint16_t VP_Flowrate_E2 = 0x3092; // 2 Byte Integer
+constexpr uint16_t VP_Flowrate_E0 = 0x3090; // 2 Byte Integer
+constexpr uint16_t VP_Flowrate_E1 = 0x3092; // 2 Byte Integer
// reserved for up to 6 Extruders:
-//constexpr uint16_t VP_Flowrate_E3 = 0x3094;
-//constexpr uint16_t VP_Flowrate_E4 = 0x3096;
-//constexpr uint16_t VP_Flowrate_E5 = 0x3098;
-//constexpr uint16_t VP_Flowrate_E6 = 0x309A;
+//constexpr uint16_t VP_Flowrate_E2 = 0x3094;
+//constexpr uint16_t VP_Flowrate_E3 = 0x3096;
+//constexpr uint16_t VP_Flowrate_E4 = 0x3098;
+//constexpr uint16_t VP_Flowrate_E5 = 0x309A;
constexpr uint16_t VP_Fan_Percentage = 0x3100; // 2 Byte Integer (0..100)
constexpr uint16_t VP_Feedrate_Percentage = 0x3102; // 2 Byte Integer (0..100)
@@ -182,9 +182,9 @@ constexpr uint16_t VP_SD_FileName4 = 0x3280;
// located at 0x5000 and up
// Not used yet!
// This can be used e.g to make controls / data display invisible
-constexpr uint16_t SP_T_E1_Is = 0x5000;
-constexpr uint16_t SP_T_E1_Set = 0x5010;
-constexpr uint16_t SP_T_E2_Is = 0x5020;
+constexpr uint16_t SP_T_E0_Is = 0x5000;
+constexpr uint16_t SP_T_E0_Set = 0x5010;
+constexpr uint16_t SP_T_E1_Is = 0x5020;
constexpr uint16_t SP_T_Bed_Is = 0x5030;
constexpr uint16_t SP_T_Bed_Set = 0x5040;
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/archim2-flash/flash_storage.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.cpp
similarity index 99%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/archim2-flash/flash_storage.cpp
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.cpp
index 360f2562a1..c8cc6e8e9d 100644
--- a/Marlin/src/lcd/extensible_ui/lib/lulzbot/archim2-flash/flash_storage.cpp
+++ b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.cpp
@@ -22,7 +22,7 @@
#include "../compat.h"
-#if ENABLED(LULZBOT_TOUCH_UI)
+#if ENABLED(TOUCH_UI_FTDI_EVE)
#include "../ftdi_eve_lib/ftdi_eve_lib.h"
@@ -556,4 +556,4 @@ bool UIFlashStorage::is_present = false;
int16_t UIFlashStorage::BootMediaReader::read(void *, const size_t) {return -1;}
int16_t UIFlashStorage::BootMediaReader::read(void *, void *, const size_t) {return -1;}
#endif // SPI_FLASH_SS
-#endif // LULZBOT_TOUCH_UI
+#endif // TOUCH_UI_FTDI_EVE
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/archim2-flash/flash_storage.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.h
similarity index 98%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/archim2-flash/flash_storage.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.h
index d211f48b38..2917cb0b1e 100644
--- a/Marlin/src/lcd/extensible_ui/lib/lulzbot/archim2-flash/flash_storage.h
+++ b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/flash_storage.h
@@ -68,7 +68,7 @@ class UIFlashStorage : private SPIFlash {
static void set_media_file_size(uint8_t slot, uint32_t size);
static uint32_t get_media_file_size(uint8_t slot);
- static constexpr uint32_t delimiter = 0x4C554C5A; // 'LULZ'
+ static constexpr uint32_t delimiter = 0x4D524C4E; // 'MRLN'
public:
enum error_t {
SUCCESS,
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/archim2-flash/media_file_reader.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/media_file_reader.cpp
similarity index 97%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/archim2-flash/media_file_reader.cpp
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/media_file_reader.cpp
index 82ceba0552..68886166c2 100644
--- a/Marlin/src/lcd/extensible_ui/lib/lulzbot/archim2-flash/media_file_reader.cpp
+++ b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/media_file_reader.cpp
@@ -22,7 +22,7 @@
#include "../compat.h"
-#if ENABLED(LULZBOT_TOUCH_UI)
+#if ENABLED(TOUCH_UI_FTDI_EVE)
#include "media_file_reader.h"
#if ENABLED(SDSUPPORT)
@@ -60,4 +60,4 @@
void MediaFileReader::rewind() {}
int16_t MediaFileReader::read(void *, void *, size_t) {return 0;}
#endif
-#endif // LULZBOT_TOUCH_UI
+#endif // TOUCH_UI_FTDI_EVE
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/archim2-flash/media_file_reader.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/media_file_reader.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/archim2-flash/media_file_reader.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/archim2-flash/media_file_reader.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/compat.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/compat.h
similarity index 91%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/compat.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/compat.h
index 7e051be75a..90fd615a5d 100644
--- a/Marlin/src/lcd/extensible_ui/lib/lulzbot/compat.h
+++ b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/compat.h
@@ -38,11 +38,6 @@
// __MARLIN_FIRMWARE__ exists when compiled within Marlin.
#include "pin_mappings.h"
#else
- // Messages that are declared in Marlin
- #define WELCOME_MSG "Printer Ready"
- #define MSG_MEDIA_INSERTED "Media Inserted"
- #define MSG_MEDIA_REMOVED "Media Removed"
-
namespace UI {
static inline uint32_t safe_millis() {return millis();};
static inline void yield() {};
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/config.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/config.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/config.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/config.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/LICENSE.txt b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/LICENSE.txt
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/LICENSE.txt
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/LICENSE.txt
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/README.md b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/README.md
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/README.md
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/README.md
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/boards.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/boards.h
similarity index 98%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/boards.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/boards.h
index 85e12238f2..854b8897b3 100644
--- a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/boards.h
+++ b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/boards.h
@@ -179,5 +179,5 @@
#else
- #error Unknown or no LULZBOT_TOUCH_UI board specified. To add a new board, modify "ftdi_eve_boards.h"
+ #error "Unknown or no TOUCH_UI_FTDI_EVE board specified. To add a new board, modify 'ftdi_eve_boards.h'."
#endif
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/commands.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.cpp
similarity index 99%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/commands.cpp
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.cpp
index 9a04c9e835..c4bf02a87a 100644
--- a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/commands.cpp
+++ b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.cpp
@@ -1015,8 +1015,8 @@ template bool CLCD::CommandFifo::write(T data, uint16_t len) {
if (Command_Space < (len + padding)) {
#if ENABLED(TOUCH_UI_DEBUG)
SERIAL_ECHO_START();
- SERIAL_ECHOPAIR("Waiting for ", len + padding,
- " bytes in command queue, now free: ", Command_Space);
+ SERIAL_ECHOPAIR("Waiting for ", len + padding);
+ SERIAL_ECHOLNPAIR(" bytes in command queue, now free: ", Command_Space);
#endif
do {
Command_Space = mem_read_32(REG::CMDB_SPACE) & 0x0FFF;
@@ -1179,7 +1179,7 @@ void CLCD::default_display_orientation() {
#endif
}
#elif ANY(TOUCH_UI_PORTRAIT, TOUCH_UI_MIRRORED)
- #error PORTRAIT or MIRRORED orientation not supported on the FT800
+ #error "PORTRAIT or MIRRORED orientation not supported on the FT800."
#elif ENABLED(TOUCH_UI_INVERTED)
mem_write_32(REG::ROTATE, 1);
#endif
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/commands.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/commands.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/constants.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/constants.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/constants.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/constants.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/display_list.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/display_list.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/display_list.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/display_list.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/ftdi_basic.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/ftdi_basic.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/ftdi_basic.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/ftdi_basic.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/registers_ft800.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft800.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/registers_ft800.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft800.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/registers_ft810.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft810.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/registers_ft810.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft810.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/resolutions.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/resolutions.h
similarity index 97%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/resolutions.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/resolutions.h
index c7fb0c37fc..471530cadf 100644
--- a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/resolutions.h
+++ b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/resolutions.h
@@ -124,5 +124,5 @@
}
#else
- #error Unknown or no LULZBOT_TOUCH_UI display resolution specified. To add a display resolution, modify "ftdi_eve_resolutions.h"
+ #error "Unknown or no TOUCH_UI_FTDI_EVE display resolution specified. To add a display resolution, modify 'ftdi_eve_resolutions.h'."
#endif
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/spi.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.cpp
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/spi.cpp
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.cpp
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/spi.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/basic/spi.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/compat.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/compat.h
similarity index 97%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/compat.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/compat.h
index 18d0a5a1a8..ef2b23a3a2 100644
--- a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/compat.h
+++ b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/compat.h
@@ -22,7 +22,7 @@
#ifdef __MARLIN_FIRMWARE__
// Marlin will define the I/O functions for us
- #if ENABLED(LULZBOT_TOUCH_UI)
+ #if ENABLED(TOUCH_UI_FTDI_EVE)
#define FTDI_BASIC
#define FTDI_EXTENDED
#endif
@@ -197,6 +197,7 @@
#define SERIAL_ECHO_START()
#define SERIAL_ECHOLNPGM(str) Serial.println(F(str))
#define SERIAL_ECHOPGM(str) Serial.print(F(str))
+ #define SERIAL_ECHO_MSG(str) Serial.println(str)
#define SERIAL_ECHOLNPAIR(str, val) {Serial.print(F(str)); Serial.println(val);}
#define SERIAL_ECHOPAIR(str, val) {Serial.print(F(str)); Serial.print(val);}
@@ -209,7 +210,9 @@
#define ENABLED(b) _CAT(SWITCH_ENABLED_, b)
#define DISABLED(b) !ENABLED(b)
#define ANY(A,B) (ENABLED(A) || ENABLED(B))
+ #define EITHER(A,B) (ENABLED(A) || ENABLED(B))
#define BOTH(A,B) (ENABLED(A) && ENABLED(B))
+ #define NONE(A,B) (DISABLED(A) && DISABLED(B))
// Remove compiler warning on an unused variable
#ifndef UNUSED
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/bitmap_info.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/bitmap_info.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/bitmap_info.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/bitmap_info.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/command_processor.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.cpp
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/command_processor.cpp
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.cpp
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/command_processor.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.h
similarity index 99%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/command_processor.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.h
index a770ebbd24..b045ca203a 100644
--- a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/command_processor.h
+++ b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.h
@@ -132,7 +132,7 @@ class CommandProcessor : public CLCD::CommandFifo {
inline CommandProcessor& font (int16_t font) {_font = font; return *this;}
- inline CommandProcessor& enabled (bool enabled) {
+ inline CommandProcessor& enabled (bool enabled=false) {
if (enabled)
_style &= ~STYLE_DISABLED;
else
@@ -310,7 +310,9 @@ class CommandProcessor : public CLCD::CommandFifo {
int8_t apply_fit_text(int16_t w, int16_t h, T text) {
using namespace FTDI;
int8_t font = _font;
- const bool is_utf8 = has_utf8_chars(text);
+ #ifdef TOUCH_UI_USE_UTF8
+ const bool is_utf8 = has_utf8_chars(text);
+ #endif
for (;font >= 26;) {
int16_t width, height;
#ifdef TOUCH_UI_USE_UTF8
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/dl_cache.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.cpp
similarity index 92%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/dl_cache.cpp
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.cpp
index 5e7377e1a0..9a55c55ae6 100644
--- a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/dl_cache.cpp
+++ b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.cpp
@@ -129,15 +129,15 @@ bool DLCache::store(uint32_t num_bytes /* = 0*/) {
// Not enough memory to cache the display list.
#if ENABLED(TOUCH_UI_DEBUG)
SERIAL_ECHO_START();
- SERIAL_ECHOLNPAIR("Not enough space in GRAM to cache display list, free space: ", free_space,
- " Required: ", dl_size);
+ SERIAL_ECHOPAIR ("Not enough space in GRAM to cache display list, free space: ", free_space);
+ SERIAL_ECHOLNPAIR(" Required: ", dl_size);
#endif
return false;
} else {
#if ENABLED(TOUCH_UI_DEBUG)
SERIAL_ECHO_START();
- SERIAL_ECHOLNPAIR("Saving DL to RAMG cache, bytes: ", dl_size,
- " Free space: ", free_space);
+ SERIAL_ECHOPAIR ("Saving DL to RAMG cache, bytes: ", dl_size);
+ SERIAL_ECHOLNPAIR(" Free space: ", free_space);
#endif
cmd.memcpy(dl_addr, MAP::RAM_DL, dl_size);
cmd.execute();
@@ -167,8 +167,8 @@ void DLCache::append() {
cmd.execute();
wait_until_idle();
SERIAL_ECHO_START();
- SERIAL_ECHOLNPAIR("Appending to DL from RAMG cache, bytes: ", dl_size,
- " REG_CMD_DL: ", CLCD::mem_read_32(REG::CMD_DL));
+ SERIAL_ECHOPAIR ("Appending to DL from RAMG cache, bytes: ", dl_size);
+ SERIAL_ECHOLNPAIR(" REG_CMD_DL: ", CLCD::mem_read_32(REG::CMD_DL));
#endif
}
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/dl_cache.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/dl_cache.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/event_loop.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.cpp
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/event_loop.cpp
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.cpp
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/event_loop.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/event_loop.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/ftdi_extended.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/ftdi_extended.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/ftdi_extended.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/ftdi_extended.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/grid_layout.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/grid_layout.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/grid_layout.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/grid_layout.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/polygon.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/polygon.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/polygon.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/polygon.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/rgb_t.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/rgb_t.h
new file mode 100644
index 0000000000..fde5052873
--- /dev/null
+++ b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/rgb_t.h
@@ -0,0 +1,84 @@
+/***********
+ * rgb_t.h *
+ ***********/
+
+/****************************************************************************
+ * Written By Marcio Teixeira 2018 - 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: . *
+ ****************************************************************************/
+
+#pragma once
+
+/**
+ * Implementation of hsl_to_rgb as constexpr functions based on:
+ *
+ * https://www.rapidtables.com/convert/color/hsl-to-rgb.html
+ */
+
+constexpr float _hsl_fmod(float x, float y) {
+ return x - int(x/y)*y;
+}
+
+constexpr float _hsl_c(float, float S, float L) {
+ return (1.0f - fabs(2*L-1.0f)) * S;
+}
+
+constexpr float _hsl_x(float H, float S, float L) {
+ return _hsl_c(H,S,L) * (1.0f - fabs(_hsl_fmod(H/60, 2) - 1));
+}
+
+constexpr float _hsl_m(float H, float S, float L) {
+ return L - _hsl_c(H,S,L)/2;
+}
+
+constexpr float _hsl_rgb(float H, float S, float L, float r, float g, float b) {
+ return ((uint32_t((r + _hsl_m(H,S,L))*255+0.5) << 16) |
+ (uint32_t((g + _hsl_m(H,S,L))*255+0.5) << 8) |
+ (uint32_t((b + _hsl_m(H,S,L))*255+0.5) << 0));
+}
+
+constexpr uint32_t hsl_to_rgb(float H, float S, float L) {
+ return (H < 60) ? _hsl_rgb(H,S,L,_hsl_c(H,S,L), _hsl_x(H,S,L), 0) :
+ (H < 120) ? _hsl_rgb(H,S,L,_hsl_x(H,S,L), _hsl_c(H,S,L), 0) :
+ (H < 180) ? _hsl_rgb(H,S,L, 0, _hsl_c(H,S,L), _hsl_x(H,S,L)) :
+ (H < 240) ? _hsl_rgb(H,S,L, 0, _hsl_x(H,S,L), _hsl_c(H,S,L)) :
+ (H < 300) ? _hsl_rgb(H,S,L,_hsl_x(H,S,L), 0, _hsl_c(H,S,L)) :
+ _hsl_rgb(H,S,L,_hsl_c(H,S,L), 0, _hsl_x(H,S,L));
+}
+
+/**
+ * Structure for RGB colors
+ */
+struct rgb_t {
+ union {
+ struct {
+ uint8_t b,g,r,a;
+ };
+ uint32_t packed;
+ };
+
+ rgb_t() : packed(0) {}
+ rgb_t(uint32_t rgb) : packed(rgb) {}
+ rgb_t(uint8_t r, uint8_t g, uint8_t b) : b(b), g(g), r(r), a(0) {}
+ operator uint32_t() const {return packed;};
+
+ static void lerp(float t, const rgb_t a, const rgb_t b, rgb_t &c) {
+ c.r = a.r + t * (b.r - a.r);
+ c.g = a.g + t * (b.g - a.g);
+ c.b = a.b + t * (b.b - a.b);
+ }
+
+ uint8_t luminance() const {return 0.299*r + 0.587*g + 0.114*b;}
+};
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/screen_types.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.cpp
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/screen_types.cpp
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.cpp
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/screen_types.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/screen_types.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/sound_list.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_list.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/sound_list.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_list.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/sound_player.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.cpp
similarity index 97%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/sound_player.cpp
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.cpp
index 0011d69118..a6d84dde5f 100644
--- a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/sound_player.cpp
+++ b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.cpp
@@ -38,7 +38,8 @@ namespace FTDI {
#if ENABLED(TOUCH_UI_DEBUG)
SERIAL_ECHO_START();
- SERIAL_ECHOLNPAIR("Playing note ", int(note), ", instrument ", int(effect));
+ SERIAL_ECHOPAIR ("Playing note ", int(note));
+ SERIAL_ECHOLNPAIR(", instrument ", int(effect));
#endif
// Play the note
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/sound_player.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/sound_player.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/text_box.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.cpp
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/text_box.cpp
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.cpp
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/text_box.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/text_box.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/tiny_timer.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.cpp
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/tiny_timer.cpp
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.cpp
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/tiny_timer.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/tiny_timer.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/README.txt b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/README.txt
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/README.txt
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/README.txt
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/font_bitmaps.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.cpp
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/font_bitmaps.cpp
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.cpp
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/font_bitmaps.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/font_bitmaps.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/font_bitmaps/romfont_31.pbm b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/romfont_31.pbm
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/font_bitmaps/romfont_31.pbm
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/romfont_31.pbm
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.png b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.png
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.png
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.png
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.svg b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.svg
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.svg
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.svg
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/font_size_t.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.cpp
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/font_size_t.cpp
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.cpp
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/font_size_t.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/font_size_t.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/standard_char_set.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.cpp
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/standard_char_set.cpp
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.cpp
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/standard_char_set.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/standard_char_set.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/unicode.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.cpp
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/unicode.cpp
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.cpp
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/unicode.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/unicode.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/western_char_set.cpp b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.cpp
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/western_char_set.cpp
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.cpp
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/western_char_set.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/western_char_set.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/western_char_set_bitmap_31.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set_bitmap_31.h
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extended/unicode/western_char_set_bitmap_31.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set_bitmap_31.h
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extras/bitmap2cpp.py b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/bitmap2cpp.py
old mode 100755
new mode 100644
similarity index 100%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extras/bitmap2cpp.py
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/bitmap2cpp.py
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extras/circular_progress.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/circular_progress.h
similarity index 88%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extras/circular_progress.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/circular_progress.h
index 412da5b361..da6a2bc325 100644
--- a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extras/circular_progress.h
+++ b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/circular_progress.h
@@ -23,10 +23,11 @@
/* This function draws a circular progress "ring" */
-void draw_circular_progress(CommandProcessor& cmd, int x, int y, int w, int h, uint8_t percent, uint32_t bgcolor, uint32_t fgcolor, float rim = 0.3) {
+void draw_circular_progress(CommandProcessor& cmd, int x, int y, int w, int h, float percent, char *text, uint32_t bgcolor, uint32_t fgcolor) {
using namespace FTDI;
- const float a = float(percent)/100.0*2.0*PI;
+ const float rim = 0.3;
+ const float a = percent/100.0*2.0*PI;
const float a1 = min(PI/2, a);
const float a2 = min(PI/2, a-a1);
const float a3 = min(PI/2, a-a1-a2);
@@ -90,11 +91,15 @@ void draw_circular_progress(CommandProcessor& cmd, int x, int y, int w, int h, u
cmd.cmd(RESTORE_CONTEXT());
// Draw the text
- char str[5];
- sprintf(str,"%d\%%",percent);
cmd.cmd(SAVE_CONTEXT());
cmd.cmd(COLOR_RGB(fgcolor));
- cmd.text(x,y,w,h,str, OPT_CENTERX | OPT_CENTERY);
+ cmd.text(x,y,w,h,text, OPT_CENTERX | OPT_CENTERY);
cmd.cmd(RESTORE_CONTEXT());
}
+
+void draw_circular_progress(CommandProcessor& cmd, int x, int y, int w, int h, float percent, uint32_t bgcolor, uint32_t fgcolor) {
+ char str[5];
+ sprintf(str,"%d\%%",int(percent));
+ draw_circular_progress(cmd, x, y, w, h, percent, str, bgcolor, fgcolor);
+}
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extras/poly_ui.h b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/poly_ui.h
similarity index 98%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extras/poly_ui.h
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/poly_ui.h
index 52146510c5..9f531146e1 100644
--- a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extras/poly_ui.h
+++ b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/poly_ui.h
@@ -53,9 +53,10 @@
*/
class PolyReader {
- private:
+ public:
typedef uint16_t type_t;
+ private:
static constexpr type_t eol = 0xFFFF;
const type_t *p, *top, *end;
@@ -321,10 +322,10 @@ class GenericPolyUI {
int16_t x_max = INT16_MIN;
int16_t y_max = INT16_MIN;
for(r.start(); r.has_more(); r.next()) {
- x_min = min(x_min, r.x);
- x_max = max(x_max, r.x);
- y_min = min(y_min, r.y);
- y_max = max(y_max, r.y);
+ x_min = min(x_min, int16_t(r.x));
+ x_max = max(x_max, int16_t(r.x));
+ y_min = min(y_min, int16_t(r.y));
+ y_max = max(y_max, int16_t(r.y));
}
x = x_min;
y = y_min;
diff --git a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extras/svg2cpp.py b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/svg2cpp.py
old mode 100755
new mode 100644
similarity index 96%
rename from Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extras/svg2cpp.py
rename to Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/svg2cpp.py
index 6a8d074916..2778f94d98
--- a/Marlin/src/lcd/extensible_ui/lib/lulzbot/ftdi_eve_lib/extras/svg2cpp.py
+++ b/Marlin/src/lcd/extensible_ui/lib/ftdi_eve_touch_ui/ftdi_eve_lib/extras/svg2cpp.py
@@ -60,7 +60,7 @@ header = '''
****************************************************************************/
/**
- * This file was auto-generated using "svg2cpp.pl"
+ * This file was auto-generated using "svg2cpp.py"
*
* The encoding consists of x,y pairs with the min and max scaled to
* 0x0000 and 0xFFFE. A single 0xFFFF in the data stream indicates the
@@ -101,10 +101,11 @@ class ComputeBoundingBox:
pass
def write(self):
- print("constexpr float x_min = %f;\n" % self.x_min)
- print("constexpr float x_max = %f;\n" % self.x_max)
- print("constexpr float y_min = %f;\n" % self.y_min)
- print("constexpr float y_max = %f;\n" % self.y_max)
+ print("constexpr float x_min = %f;" % self.x_min)
+ print("constexpr float x_max = %f;" % self.x_max)
+ print("constexpr float y_min = %f;" % self.y_min)
+ print("constexpr float y_max = %f;" % self.y_max)
+ print()
def from_svg_view_box(self, svg):
s = re.search('